repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

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);