Eric Bower
·
19 Jan 24
api-type-template.ts
1function createQueryApi() {
2 const methods = [
3 "get",
4 "post",
5 "put",
6 "patch",
7 "delete",
8 "options",
9 "head",
10 "connect",
11 "trace",
12 ];
13
14 const uriTmpl = (method: string) =>
15 `/**
16 * Options only
17 */
18${method}(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
19${method}<P>(
20 req: { supervisor?: Supervisor }
21): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
22${method}<P extends never, ApiSuccess, ApiError = unknown>(
23 req: { supervisor?: Supervisor }
24): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
25${method}<P, ApiSuccess, ApiError = unknown>(req: {
26 supervisor?: Supervisor;
27}): CreateActionWithPayload<
28 Omit<Ctx, 'payload' | 'json'> &
29 Payload<P> &
30 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
31 P,
32 ApiSuccess
33>;
34
35/**
36* Middleware only
37*/
38${method}(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
39${method}<Gtx extends Ctx = Ctx>(
40 fn: MiddlewareApiCo<Gtx>,
41): CreateAction<Gtx>;
42${method}<P>(
43 fn: MiddlewareApiCo<Omit<Ctx, 'payload'> & Payload<P>>,
44): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
45${method}<P, Gtx extends Ctx = Ctx>(
46 fn: MiddlewareApiCo<Gtx>,
47): CreateActionWithPayload<Gtx, P>;
48${method}<P extends never, ApiSuccess, ApiError = unknown>(
49 fn: MiddlewareApiCo<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>>,
50): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
51${method}<P, ApiSuccess, ApiError = unknown>(
52 fn: MiddlewareApiCo<Ctx>,
53): CreateActionWithPayload<
54 Omit<Ctx, 'payload' | 'json'> &
55 Payload<P> &
56 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
57 P,
58 ApiSuccess
59>;
60
61/**
62* Options and Middleware
63*/
64${method}(req: { supervisor?: Supervisor }, fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
65${method}<Gtx extends Ctx = Ctx>(
66 req: { supervisor?: Supervisor },
67 fn: MiddlewareApiCo<Gtx>,
68): CreateAction<Gtx>;
69${method}<P>(
70 req: { supervisor?: Supervisor },
71 fn: MiddlewareApiCo<Omit<Ctx, 'payload'> & Payload<P>>,
72): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
73${method}<P, Gtx extends Ctx = Ctx>(
74 req: { supervisor?: Supervisor },
75 fn: MiddlewareApiCo<Gtx>,
76): CreateActionWithPayload<Gtx, P>;
77${method}<P extends never, ApiSuccess, ApiError = unknown>(
78 req: { supervisor?: Supervisor },
79 fn: MiddlewareApiCo<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>>,
80): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
81${method}<P, ApiSuccess, ApiError = unknown>(
82 req: { supervisor?: Supervisor },
83 fn: MiddlewareApiCo<Ctx>,
84): CreateActionWithPayload<
85 Omit<Ctx, 'payload' | 'json'> &
86 Payload<P> &
87 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
88 P,
89 ApiSuccess
90>;`;
91 const uriMethods = methods.map((m) => uriTmpl(m)).join("\n\n");
92
93 const methodTmpl = (method: string) =>
94 `/**
95 * Only name
96 */
97${method}(name: ApiName): CreateAction<Ctx>;
98${method}<P>(
99 name: ApiName,
100): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
101${method}<P extends never, ApiSuccess, ApiError = unknown>(
102 name: ApiName,
103): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
104${method}<P, ApiSuccess, ApiError = unknown>(
105 name: ApiName,
106): CreateActionWithPayload<
107 Omit<Ctx, 'payload' | 'json'> &
108 Payload<P> &
109 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
110 P,
111 ApiSuccess
112>;
113
114/**
115 * Name and options
116 */
117${method}(name: ApiName, req: { supervisor?: Supervisor }): CreateAction<Ctx>;
118${method}<P>(
119 name: ApiName,
120 req: { supervisor?: Supervisor }
121): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
122${method}<P, Gtx extends Ctx = Ctx>(
123 name: ApiName,
124 req: { supervisor?: Supervisor }
125): CreateActionWithPayload<Gtx, P>;
126${method}<P extends never, ApiSuccess, ApiError = unknown>(
127 name: ApiName,
128 req: { supervisor?: Supervisor }
129): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
130${method}<P, ApiSuccess, ApiError = unknown>(
131 name: ApiName,
132 req: { supervisor?: Supervisor },
133): CreateActionWithPayload<
134 Omit<Ctx, 'payload' | 'json'> &
135 Payload<P> &
136 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
137 P,
138 ApiSuccess
139>;
140
141/**
142 * Name and middleware
143 */
144${method}(name: ApiName, fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
145${method}<Gtx extends Ctx = Ctx>(
146 name: ApiName,
147 fn: MiddlewareApiCo<Gtx>,
148): CreateAction<Gtx>;
149${method}<P>(
150 name: ApiName,
151 fn: MiddlewareApiCo<Omit<Ctx, 'payload'> & Payload<P>>,
152): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
153${method}<P, Gtx extends Ctx = Ctx>(
154 name: ApiName,
155 fn: MiddlewareApiCo<Gtx>,
156): CreateActionWithPayload<Gtx, P>;
157${method}<P extends never, ApiSuccess, ApiError = unknown>(
158 name: ApiName,
159 fn: MiddlewareApiCo<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>>,
160): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
161${method}<P, ApiSuccess, ApiError = unknown>(
162 name: ApiName,
163 fn: MiddlewareApiCo<
164 Omit<Ctx, 'payload' | 'json'> &
165 Payload<P> &
166 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
167 >,
168): CreateActionWithPayload<
169 Omit<Ctx, 'payload' | 'json'> &
170 Payload<P> &
171 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
172 P,
173 ApiSuccess
174>;
175
176/**
177 * Name, options, and middleware
178 */
179${method}(
180 name: ApiName,
181 req: { supervisor?: Supervisor },
182 fn: MiddlewareApiCo<Ctx>,
183): CreateAction<Ctx>;
184${method}<Gtx extends Ctx = Ctx>(
185 name: ApiName,
186 req: { supervisor?: Supervisor },
187 fn: MiddlewareApiCo<Gtx>,
188): CreateAction<Gtx>;
189${method}<P>(
190 name: ApiName,
191 req: { supervisor?: Supervisor },
192 fn: MiddlewareApiCo<Omit<Ctx, 'payload'> & Payload<P>>,
193): CreateActionWithPayload<Omit<Ctx, 'payload'> & Payload<P>, P>;
194${method}<P, Gtx extends Ctx = Ctx>(
195 name: ApiName,
196 req: { supervisor?: Supervisor },
197 fn: MiddlewareApiCo<Gtx>,
198): CreateActionWithPayload<Gtx, P>;
199${method}<P extends never, ApiSuccess, ApiError = unknown>(
200 name: ApiName,
201 req: { supervisor?: Supervisor },
202 fn: MiddlewareApiCo<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>>,
203): CreateAction<Omit<Ctx, 'json'> & FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>, ApiSuccess>;
204${method}<P, ApiSuccess, ApiError = unknown>(
205 name: ApiName,
206 req: { supervisor?: Supervisor },
207 fn: MiddlewareApiCo<
208 Omit<Ctx, 'payload' | 'json'> &
209 Payload<P> &
210 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>
211 >,
212): CreateActionWithPayload<
213 Omit<Ctx, 'payload' | 'json'> &
214 Payload<P> &
215 FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
216 P,
217 ApiSuccess
218>;`;
219 const regMethods = methods.map((m) => methodTmpl(m)).join("\n\n");
220
221 const tmpl = `/**
222* This is an auto-generated file, do not edit directly!
223* Run "yarn template" to generate this file.
224*/
225import type { ThunksApi } from "./thunk.ts";
226import type {
227 ApiCtx,
228 CreateAction,
229 CreateActionWithPayload,
230 FetchJson,
231 MiddlewareApiCo,
232 Supervisor,
233} from "./types.ts";
234import type { Next, Payload } from "../types.ts";
235import type { Operation } from "../deps.ts";
236
237export type ApiName = string | string[];
238
239export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
240 request: (
241 r: Partial<RequestInit>,
242 ) => (ctx: Ctx, next: Next) => Operation<unknown>;
243 cache: () => (ctx: Ctx, next: Next) => Operation<unknown>;
244
245 uri: (uri: string) => {
246 ${uriMethods}
247 }
248
249${regMethods}
250}`;
251
252 return tmpl;
253}
254
255async function createTemplateFile(tmpl: string) {
256 try {
257 await Deno.writeTextFile("./query/api-types.ts", tmpl);
258 } catch (err) {
259 console.error(err);
260 }
261}
262
263createTemplateFile(createQueryApi()).then(console.log).catch(console.error);