repos / starfx

a micro-mvc framework for react apps
git clone https://github.com/neurosnap/starfx.git

Eric Bower  ·  2025-06-06

api-type-template.mts

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