zenko 0.1.6-beta.1 → 0.1.7-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/cli.cjs +437 -195
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +437 -195
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +435 -200
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -2
- package/dist/index.d.ts +46 -2
- package/dist/index.mjs +434 -197
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -6
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// src/utils/topological-sort.ts
|
|
2
2
|
function topologicalSort(schemas) {
|
|
3
3
|
const visited = /* @__PURE__ */ new Set();
|
|
4
4
|
const visiting = /* @__PURE__ */ new Set();
|
|
@@ -47,7 +47,7 @@ function extractRefName(ref) {
|
|
|
47
47
|
return ref.split("/").pop() || "Unknown";
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
//
|
|
50
|
+
// src/utils/property-name.ts
|
|
51
51
|
function isValidJSIdentifier(name) {
|
|
52
52
|
if (!name) return false;
|
|
53
53
|
const firstChar = name.at(0);
|
|
@@ -127,7 +127,15 @@ function formatPropertyName(name) {
|
|
|
127
127
|
return isValidJSIdentifier(name) ? name : `"${name}"`;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
//
|
|
130
|
+
// src/utils/string-utils.ts
|
|
131
|
+
function toCamelCase(str) {
|
|
132
|
+
return str.replace(/-([a-zA-Z])/g, (_, letter) => letter.toUpperCase()).replace(/-+$/, "");
|
|
133
|
+
}
|
|
134
|
+
function capitalize(str) {
|
|
135
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/utils/http-status.ts
|
|
131
139
|
var statusNameMap = {
|
|
132
140
|
"400": "badRequest",
|
|
133
141
|
"401": "unauthorized",
|
|
@@ -186,14 +194,6 @@ function mapStatusToIdentifier(status) {
|
|
|
186
194
|
if (!candidate) return "unknownError";
|
|
187
195
|
return /^[a-zA-Z_$]/.test(candidate) ? candidate : `status${candidate.charAt(0).toUpperCase()}${candidate.slice(1)}`;
|
|
188
196
|
}
|
|
189
|
-
function getStatusCategory(status) {
|
|
190
|
-
if (status === "default") return "default";
|
|
191
|
-
const code = Number(status);
|
|
192
|
-
if (!Number.isInteger(code)) return "unknown";
|
|
193
|
-
if (code >= 400 && code <= 499) return "client";
|
|
194
|
-
if (code >= 500 && code <= 599) return "server";
|
|
195
|
-
return "unknown";
|
|
196
|
-
}
|
|
197
197
|
function isErrorStatus(status) {
|
|
198
198
|
if (status === "default") return true;
|
|
199
199
|
const code = Number(status);
|
|
@@ -201,7 +201,170 @@ function isErrorStatus(status) {
|
|
|
201
201
|
return code >= 400;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
//
|
|
204
|
+
// src/utils/tree-shaking.ts
|
|
205
|
+
function analyzeZenkoUsage(operations) {
|
|
206
|
+
const usage = {
|
|
207
|
+
usesHeaderFn: false,
|
|
208
|
+
usesOperationDefinition: false,
|
|
209
|
+
usesOperationErrors: false
|
|
210
|
+
};
|
|
211
|
+
if (operations.length > 0) {
|
|
212
|
+
usage.usesOperationDefinition = true;
|
|
213
|
+
}
|
|
214
|
+
for (const op of operations) {
|
|
215
|
+
if (op.requestHeaders && op.requestHeaders.length > 0) {
|
|
216
|
+
usage.usesHeaderFn = true;
|
|
217
|
+
}
|
|
218
|
+
if (op.errors && hasAnyErrors(op.errors)) {
|
|
219
|
+
usage.usesOperationErrors = true;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (operations.length > 0 && !usage.usesOperationErrors) {
|
|
223
|
+
const hasDefaultErrors = operations.some(
|
|
224
|
+
(op) => !op.errors || !hasAnyErrors(op.errors)
|
|
225
|
+
);
|
|
226
|
+
if (hasDefaultErrors) {
|
|
227
|
+
usage.usesOperationErrors = true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return usage;
|
|
231
|
+
}
|
|
232
|
+
function generateZenkoImport(usage, mode, helpersOutput) {
|
|
233
|
+
const types = [];
|
|
234
|
+
if (usage.usesHeaderFn) types.push("HeaderFn");
|
|
235
|
+
if (usage.usesOperationDefinition) types.push("OperationDefinition");
|
|
236
|
+
if (usage.usesOperationErrors) types.push("OperationErrors");
|
|
237
|
+
if (types.length === 0) {
|
|
238
|
+
return "";
|
|
239
|
+
}
|
|
240
|
+
const importSource = mode === "package" ? '"zenko"' : `"${helpersOutput}"`;
|
|
241
|
+
return `import type { ${types.join(", ")} } from ${importSource};`;
|
|
242
|
+
}
|
|
243
|
+
function hasAnyErrors(errors) {
|
|
244
|
+
return Boolean(errors && Object.keys(errors).length > 0);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/utils/collect-inline-types.ts
|
|
248
|
+
function collectInlineRequestTypes(operations, spec) {
|
|
249
|
+
const requestTypesToGenerate = /* @__PURE__ */ new Map();
|
|
250
|
+
const operationLookup = /* @__PURE__ */ new Map();
|
|
251
|
+
for (const [, pathItem] of Object.entries(spec.paths || {})) {
|
|
252
|
+
for (const [, operation] of Object.entries(pathItem)) {
|
|
253
|
+
const op = operation;
|
|
254
|
+
if (op.operationId) {
|
|
255
|
+
operationLookup.set(op.operationId, op);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
for (const [, pathItem] of Object.entries(spec.webhooks || {})) {
|
|
260
|
+
for (const [, operation] of Object.entries(pathItem)) {
|
|
261
|
+
const op = operation;
|
|
262
|
+
if (op.operationId) {
|
|
263
|
+
operationLookup.set(op.operationId, op);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
for (const op of operations) {
|
|
268
|
+
const operation = operationLookup.get(op.operationId);
|
|
269
|
+
if (!operation) continue;
|
|
270
|
+
const requestBody = operation.requestBody;
|
|
271
|
+
if (requestBody && requestBody.content) {
|
|
272
|
+
const content = requestBody.content;
|
|
273
|
+
const jsonContent = content["application/json"];
|
|
274
|
+
if (jsonContent && jsonContent.schema) {
|
|
275
|
+
const schema = jsonContent.schema;
|
|
276
|
+
const typeName = `${capitalize(toCamelCase(op.operationId))}Request`;
|
|
277
|
+
if (!schema.$ref || schema.allOf || schema.oneOf || schema.anyOf) {
|
|
278
|
+
requestTypesToGenerate.set(typeName, schema);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return requestTypesToGenerate;
|
|
284
|
+
}
|
|
285
|
+
function collectInlineResponseTypes(operations, spec) {
|
|
286
|
+
const responseTypesToGenerate = /* @__PURE__ */ new Map();
|
|
287
|
+
const operationLookup = /* @__PURE__ */ new Map();
|
|
288
|
+
for (const [, pathItem] of Object.entries(spec.paths || {})) {
|
|
289
|
+
for (const [, operation] of Object.entries(pathItem)) {
|
|
290
|
+
const op = operation;
|
|
291
|
+
if (op.operationId) {
|
|
292
|
+
operationLookup.set(op.operationId, op);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
for (const [, pathItem] of Object.entries(spec.webhooks || {})) {
|
|
297
|
+
for (const [, operation] of Object.entries(pathItem)) {
|
|
298
|
+
const op = operation;
|
|
299
|
+
if (op.operationId) {
|
|
300
|
+
operationLookup.set(op.operationId, op);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
for (const op of operations) {
|
|
305
|
+
const operation = operationLookup.get(op.operationId);
|
|
306
|
+
if (!operation) continue;
|
|
307
|
+
const responses = operation.responses || {};
|
|
308
|
+
for (const [statusCode, response] of Object.entries(responses)) {
|
|
309
|
+
if (/^2\d\d$/.test(statusCode) && response.content) {
|
|
310
|
+
const content = response.content;
|
|
311
|
+
const jsonContent = content["application/json"];
|
|
312
|
+
if (jsonContent && jsonContent.schema) {
|
|
313
|
+
const schema = jsonContent.schema;
|
|
314
|
+
const typeName = `${capitalize(toCamelCase(op.operationId))}Response`;
|
|
315
|
+
if (!schema.$ref || schema.allOf || schema.oneOf || schema.anyOf) {
|
|
316
|
+
responseTypesToGenerate.set(typeName, schema);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return responseTypesToGenerate;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/utils/generate-helper-file.ts
|
|
326
|
+
function generateHelperFile() {
|
|
327
|
+
const output = [];
|
|
328
|
+
output.push("// Generated helper types for Zenko");
|
|
329
|
+
output.push(
|
|
330
|
+
"// This file provides type definitions for operation objects and path functions"
|
|
331
|
+
);
|
|
332
|
+
output.push("");
|
|
333
|
+
output.push(
|
|
334
|
+
"export type PathFn<TArgs extends unknown[] = []> = (...args: TArgs) => string"
|
|
335
|
+
);
|
|
336
|
+
output.push("");
|
|
337
|
+
output.push(
|
|
338
|
+
'export type RequestMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"'
|
|
339
|
+
);
|
|
340
|
+
output.push("");
|
|
341
|
+
output.push(
|
|
342
|
+
"export type HeaderFn<TArgs extends unknown[] = [], TResult = Record<string, unknown> | Record<string, never>> = (...args: TArgs) => TResult"
|
|
343
|
+
);
|
|
344
|
+
output.push("");
|
|
345
|
+
output.push(
|
|
346
|
+
"export type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown)"
|
|
347
|
+
);
|
|
348
|
+
output.push("");
|
|
349
|
+
output.push(
|
|
350
|
+
"export type OperationErrors<TError = unknown> = TError extends Record<string, unknown> ? TError : Record<string, TError>;"
|
|
351
|
+
);
|
|
352
|
+
output.push("");
|
|
353
|
+
output.push(
|
|
354
|
+
"export type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends AnyHeaderFn | undefined = undefined, TErrors extends OperationErrors | undefined = undefined> = {"
|
|
355
|
+
);
|
|
356
|
+
output.push(" method: TMethod");
|
|
357
|
+
output.push(" path: TPath");
|
|
358
|
+
output.push(" request?: TRequest");
|
|
359
|
+
output.push(" response?: TResponse");
|
|
360
|
+
output.push(" headers?: THeaders");
|
|
361
|
+
output.push(" errors?: TErrors");
|
|
362
|
+
output.push("}");
|
|
363
|
+
output.push("");
|
|
364
|
+
return output.join("\n");
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// src/zenko.ts
|
|
205
368
|
function generateWithMetadata(spec, options = {}) {
|
|
206
369
|
const output = [];
|
|
207
370
|
const generatedTypes = /* @__PURE__ */ new Set();
|
|
@@ -212,7 +375,14 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
212
375
|
strictNumeric
|
|
213
376
|
};
|
|
214
377
|
output.push('import { z } from "zod";');
|
|
215
|
-
|
|
378
|
+
const nameMap = /* @__PURE__ */ new Map();
|
|
379
|
+
if (spec.components?.schemas) {
|
|
380
|
+
for (const name of Object.keys(spec.components.schemas)) {
|
|
381
|
+
nameMap.set(name, toCamelCase(name));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const operations = parseOperations(spec, nameMap);
|
|
385
|
+
appendHelperTypesImport(output, typesConfig, operations);
|
|
216
386
|
output.push("");
|
|
217
387
|
if (spec.components?.schemas) {
|
|
218
388
|
output.push("// Generated Zod Schemas");
|
|
@@ -220,15 +390,23 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
220
390
|
const sortedSchemas = topologicalSort(spec.components.schemas);
|
|
221
391
|
for (const name of sortedSchemas) {
|
|
222
392
|
const schema = spec.components.schemas[name];
|
|
393
|
+
const sanitizedName = nameMap.get(name);
|
|
223
394
|
output.push(
|
|
224
|
-
generateZodSchema(
|
|
395
|
+
generateZodSchema(
|
|
396
|
+
sanitizedName,
|
|
397
|
+
schema,
|
|
398
|
+
generatedTypes,
|
|
399
|
+
schemaOptions,
|
|
400
|
+
nameMap
|
|
401
|
+
)
|
|
225
402
|
);
|
|
226
403
|
output.push("");
|
|
227
|
-
output.push(
|
|
404
|
+
output.push(
|
|
405
|
+
`export type ${sanitizedName} = z.infer<typeof ${sanitizedName}>;`
|
|
406
|
+
);
|
|
228
407
|
output.push("");
|
|
229
408
|
}
|
|
230
409
|
}
|
|
231
|
-
const operations = parseOperations(spec);
|
|
232
410
|
output.push("// Path Functions");
|
|
233
411
|
output.push("export const paths = {");
|
|
234
412
|
for (const op of operations) {
|
|
@@ -242,24 +420,37 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
242
420
|
);
|
|
243
421
|
continue;
|
|
244
422
|
}
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
423
|
+
const alias = (n) => {
|
|
424
|
+
if (isValidJSIdentifier(n)) return n;
|
|
425
|
+
let aliased = toCamelCase(n);
|
|
426
|
+
if (!isValidJSIdentifier(aliased)) {
|
|
427
|
+
aliased = `_${aliased}`;
|
|
428
|
+
}
|
|
429
|
+
return aliased;
|
|
430
|
+
};
|
|
431
|
+
const destructPieces = [];
|
|
432
|
+
const typePieces = [];
|
|
250
433
|
for (const param of op.pathParams) {
|
|
251
|
-
|
|
434
|
+
destructPieces.push(
|
|
435
|
+
isValidJSIdentifier(param.name) ? param.name : `${formatPropertyName(param.name)}: ${alias(param.name)}`
|
|
436
|
+
);
|
|
437
|
+
typePieces.push(`${formatPropertyName(param.name)}: string`);
|
|
252
438
|
}
|
|
253
439
|
for (const param of op.queryParams) {
|
|
254
|
-
|
|
255
|
-
|
|
440
|
+
destructPieces.push(
|
|
441
|
+
isValidJSIdentifier(param.name) ? param.name : `${formatPropertyName(param.name)}: ${alias(param.name)}`
|
|
442
|
+
);
|
|
443
|
+
typePieces.push(
|
|
444
|
+
`${formatPropertyName(param.name)}${param.required ? "" : "?"}: ${mapQueryType(param)}`
|
|
256
445
|
);
|
|
257
446
|
}
|
|
258
|
-
const signatureParams = signaturePieces.join(", ");
|
|
259
447
|
const needsDefaultObject = !hasPathParams && hasQueryParams && op.queryParams.every((param) => !param.required);
|
|
260
|
-
const signatureArgs =
|
|
261
|
-
const signature = `${signatureArgs}: { ${
|
|
262
|
-
const pathWithParams = op.path.replace(
|
|
448
|
+
const signatureArgs = destructPieces.length ? `{ ${destructPieces.join(", ")} }` : "{}";
|
|
449
|
+
const signature = `${signatureArgs}: { ${typePieces.join(", ")} }${needsDefaultObject ? " = {}" : ""}`;
|
|
450
|
+
const pathWithParams = op.path.replace(
|
|
451
|
+
/{([^}]+)}/g,
|
|
452
|
+
(_m, n) => `\${${alias(n)}}`
|
|
453
|
+
);
|
|
263
454
|
if (!hasQueryParams) {
|
|
264
455
|
output.push(
|
|
265
456
|
` ${formatPropertyName(camelCaseOperationId)}: (${signature}) => \`${pathWithParams}\`,`
|
|
@@ -271,8 +462,7 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
271
462
|
);
|
|
272
463
|
output.push(" const params = new URLSearchParams()");
|
|
273
464
|
for (const param of op.queryParams) {
|
|
274
|
-
const
|
|
275
|
-
const accessor = isValidJSIdentifier(param.name) ? param.name : propertyKey;
|
|
465
|
+
const accessor = isValidJSIdentifier(param.name) ? param.name : alias(toCamelCase(param.name));
|
|
276
466
|
const schema = param.schema ?? {};
|
|
277
467
|
if (schema?.type === "array") {
|
|
278
468
|
const itemValueExpression = convertQueryParamValue(
|
|
@@ -354,10 +544,14 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
354
544
|
}
|
|
355
545
|
output.push("} as const;");
|
|
356
546
|
output.push("");
|
|
547
|
+
generateRequestTypes(output, operations, spec, nameMap, schemaOptions);
|
|
548
|
+
generateResponseTypes(output, operations, spec, nameMap, schemaOptions);
|
|
549
|
+
generateOperationTypes(output, operations, typesConfig);
|
|
357
550
|
output.push("// Operation Objects");
|
|
358
551
|
for (const op of operations) {
|
|
359
552
|
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
360
|
-
|
|
553
|
+
const typeAnnotation = typesConfig.emit ? `: ${capitalize(camelCaseOperationId)}Operation` : "";
|
|
554
|
+
output.push(`export const ${camelCaseOperationId}${typeAnnotation} = {`);
|
|
361
555
|
output.push(` method: "${op.method}",`);
|
|
362
556
|
output.push(` path: paths.${camelCaseOperationId},`);
|
|
363
557
|
appendOperationField(output, "request", op.requestType);
|
|
@@ -365,18 +559,12 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
365
559
|
if (op.requestHeaders && op.requestHeaders.length > 0) {
|
|
366
560
|
output.push(` headers: headers.${camelCaseOperationId},`);
|
|
367
561
|
}
|
|
368
|
-
if (op.errors &&
|
|
369
|
-
output
|
|
370
|
-
appendErrorGroup(output, "clientErrors", op.errors.clientErrors);
|
|
371
|
-
appendErrorGroup(output, "serverErrors", op.errors.serverErrors);
|
|
372
|
-
appendErrorGroup(output, "defaultErrors", op.errors.defaultErrors);
|
|
373
|
-
appendErrorGroup(output, "otherErrors", op.errors.otherErrors);
|
|
374
|
-
output.push(" },");
|
|
562
|
+
if (op.errors && hasAnyErrors2(op.errors)) {
|
|
563
|
+
appendErrorGroup(output, "errors", op.errors);
|
|
375
564
|
}
|
|
376
565
|
output.push("} as const;");
|
|
377
566
|
output.push("");
|
|
378
567
|
}
|
|
379
|
-
generateOperationTypes(output, operations, typesConfig);
|
|
380
568
|
const result = {
|
|
381
569
|
output: output.join("\n")
|
|
382
570
|
};
|
|
@@ -388,6 +576,46 @@ function generateWithMetadata(spec, options = {}) {
|
|
|
388
576
|
}
|
|
389
577
|
return result;
|
|
390
578
|
}
|
|
579
|
+
function generateRequestTypes(output, operations, spec, nameMap, schemaOptions) {
|
|
580
|
+
const requestTypesToGenerate = collectInlineRequestTypes(operations, spec);
|
|
581
|
+
if (requestTypesToGenerate.size > 0) {
|
|
582
|
+
output.push("// Generated Request Types");
|
|
583
|
+
output.push("");
|
|
584
|
+
for (const [typeName, schema] of requestTypesToGenerate) {
|
|
585
|
+
const generatedSchema = generateZodSchema(
|
|
586
|
+
typeName,
|
|
587
|
+
schema,
|
|
588
|
+
/* @__PURE__ */ new Set(),
|
|
589
|
+
schemaOptions,
|
|
590
|
+
nameMap
|
|
591
|
+
);
|
|
592
|
+
output.push(generatedSchema);
|
|
593
|
+
output.push("");
|
|
594
|
+
output.push(`export type ${typeName} = z.infer<typeof ${typeName}>;`);
|
|
595
|
+
output.push("");
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function generateResponseTypes(output, operations, spec, nameMap, schemaOptions) {
|
|
600
|
+
const responseTypesToGenerate = collectInlineResponseTypes(operations, spec);
|
|
601
|
+
if (responseTypesToGenerate.size > 0) {
|
|
602
|
+
output.push("// Generated Response Types");
|
|
603
|
+
output.push("");
|
|
604
|
+
for (const [typeName, schema] of responseTypesToGenerate) {
|
|
605
|
+
const generatedSchema = generateZodSchema(
|
|
606
|
+
typeName,
|
|
607
|
+
schema,
|
|
608
|
+
/* @__PURE__ */ new Set(),
|
|
609
|
+
schemaOptions,
|
|
610
|
+
nameMap
|
|
611
|
+
);
|
|
612
|
+
output.push(generatedSchema);
|
|
613
|
+
output.push("");
|
|
614
|
+
output.push(`export type ${typeName} = z.infer<typeof ${typeName}>;`);
|
|
615
|
+
output.push("");
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
391
619
|
function generate(spec, options = {}) {
|
|
392
620
|
return generateWithMetadata(spec, options).output;
|
|
393
621
|
}
|
|
@@ -403,13 +631,8 @@ function appendErrorGroup(buffer, label, errors) {
|
|
|
403
631
|
}
|
|
404
632
|
buffer.push(" },");
|
|
405
633
|
}
|
|
406
|
-
function
|
|
407
|
-
return
|
|
408
|
-
group.clientErrors,
|
|
409
|
-
group.serverErrors,
|
|
410
|
-
group.defaultErrors,
|
|
411
|
-
group.otherErrors
|
|
412
|
-
].some((bucket) => bucket && Object.keys(bucket).length > 0);
|
|
634
|
+
function hasAnyErrors2(group) {
|
|
635
|
+
return Boolean(group && Object.keys(group).length > 0);
|
|
413
636
|
}
|
|
414
637
|
function isRequestMethod(method) {
|
|
415
638
|
switch (method) {
|
|
@@ -456,33 +679,70 @@ function inferResponseType(contentType, statusCode) {
|
|
|
456
679
|
}
|
|
457
680
|
return "unknown";
|
|
458
681
|
}
|
|
459
|
-
function parseOperations(spec) {
|
|
682
|
+
function parseOperations(spec, nameMap) {
|
|
460
683
|
const operations = [];
|
|
461
|
-
|
|
462
|
-
for (const [
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
684
|
+
if (spec.paths) {
|
|
685
|
+
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
686
|
+
for (const [method, operation] of Object.entries(pathItem)) {
|
|
687
|
+
const normalizedMethod = method.toLowerCase();
|
|
688
|
+
if (!isRequestMethod(normalizedMethod)) continue;
|
|
689
|
+
if (!operation.operationId) continue;
|
|
690
|
+
const pathParams = extractPathParams(path);
|
|
691
|
+
const requestType = getRequestType(operation);
|
|
692
|
+
const { successResponse, errors } = getResponseTypes(
|
|
693
|
+
operation,
|
|
694
|
+
operation.operationId,
|
|
695
|
+
nameMap
|
|
696
|
+
);
|
|
697
|
+
const resolvedParameters = collectParameters(pathItem, operation, spec);
|
|
698
|
+
const requestHeaders = getRequestHeaders(resolvedParameters);
|
|
699
|
+
const queryParams = getQueryParams(resolvedParameters);
|
|
700
|
+
operations.push({
|
|
701
|
+
operationId: operation.operationId,
|
|
702
|
+
path,
|
|
703
|
+
method: normalizedMethod,
|
|
704
|
+
pathParams,
|
|
705
|
+
queryParams,
|
|
706
|
+
requestType,
|
|
707
|
+
responseType: successResponse,
|
|
708
|
+
requestHeaders,
|
|
709
|
+
errors
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (spec.webhooks) {
|
|
715
|
+
for (const [webhookName, webhookItem] of Object.entries(spec.webhooks)) {
|
|
716
|
+
for (const [method, operation] of Object.entries(webhookItem)) {
|
|
717
|
+
const normalizedMethod = method.toLowerCase();
|
|
718
|
+
if (!isRequestMethod(normalizedMethod)) continue;
|
|
719
|
+
if (!operation.operationId) continue;
|
|
720
|
+
const path = webhookName;
|
|
721
|
+
const pathParams = extractPathParams(path);
|
|
722
|
+
const requestType = getRequestType(operation);
|
|
723
|
+
const { successResponse, errors } = getResponseTypes(
|
|
724
|
+
operation,
|
|
725
|
+
operation.operationId
|
|
726
|
+
);
|
|
727
|
+
const resolvedParameters = collectParameters(
|
|
728
|
+
webhookItem,
|
|
729
|
+
operation,
|
|
730
|
+
spec
|
|
731
|
+
);
|
|
732
|
+
const requestHeaders = getRequestHeaders(resolvedParameters);
|
|
733
|
+
const queryParams = getQueryParams(resolvedParameters);
|
|
734
|
+
operations.push({
|
|
735
|
+
operationId: operation.operationId,
|
|
736
|
+
path,
|
|
737
|
+
method: normalizedMethod,
|
|
738
|
+
pathParams,
|
|
739
|
+
queryParams,
|
|
740
|
+
requestType,
|
|
741
|
+
responseType: successResponse,
|
|
742
|
+
requestHeaders,
|
|
743
|
+
errors
|
|
744
|
+
});
|
|
745
|
+
}
|
|
486
746
|
}
|
|
487
747
|
}
|
|
488
748
|
return operations;
|
|
@@ -491,21 +751,42 @@ function normalizeTypesConfig(config) {
|
|
|
491
751
|
return {
|
|
492
752
|
emit: config?.emit ?? true,
|
|
493
753
|
helpers: config?.helpers ?? "package",
|
|
494
|
-
helpersOutput: config?.helpersOutput ?? "./zenko-types"
|
|
754
|
+
helpersOutput: config?.helpersOutput ?? "./zenko-types",
|
|
755
|
+
treeShake: config?.treeShake ?? true
|
|
495
756
|
};
|
|
496
757
|
}
|
|
497
|
-
function appendHelperTypesImport(buffer, config) {
|
|
758
|
+
function appendHelperTypesImport(buffer, config, operations) {
|
|
498
759
|
if (!config.emit) return;
|
|
499
760
|
switch (config.helpers) {
|
|
500
761
|
case "package":
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
762
|
+
if (config.treeShake) {
|
|
763
|
+
const usage = analyzeZenkoUsage(operations);
|
|
764
|
+
const importStatement = generateZenkoImport(usage, "package");
|
|
765
|
+
if (importStatement) {
|
|
766
|
+
buffer.push(importStatement);
|
|
767
|
+
}
|
|
768
|
+
} else {
|
|
769
|
+
buffer.push(
|
|
770
|
+
'import type { PathFn, HeaderFn, OperationDefinition, OperationErrors } from "zenko";'
|
|
771
|
+
);
|
|
772
|
+
}
|
|
504
773
|
return;
|
|
505
774
|
case "file":
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
775
|
+
if (config.treeShake) {
|
|
776
|
+
const usage = analyzeZenkoUsage(operations);
|
|
777
|
+
const importStatement = generateZenkoImport(
|
|
778
|
+
usage,
|
|
779
|
+
"file",
|
|
780
|
+
config.helpersOutput
|
|
781
|
+
);
|
|
782
|
+
if (importStatement) {
|
|
783
|
+
buffer.push(importStatement);
|
|
784
|
+
}
|
|
785
|
+
} else {
|
|
786
|
+
buffer.push(
|
|
787
|
+
`import type { PathFn, HeaderFn, OperationDefinition, OperationErrors } from "${config.helpersOutput}";`
|
|
788
|
+
);
|
|
789
|
+
}
|
|
509
790
|
return;
|
|
510
791
|
case "inline":
|
|
511
792
|
buffer.push(
|
|
@@ -521,24 +802,19 @@ function appendHelperTypesImport(buffer, config) {
|
|
|
521
802
|
"type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown);"
|
|
522
803
|
);
|
|
523
804
|
buffer.push(
|
|
524
|
-
"type OperationErrors<
|
|
805
|
+
"type OperationErrors<TError = unknown> = TError extends Record<string, unknown> ? TError : Record<string, TError>;"
|
|
525
806
|
);
|
|
526
|
-
buffer.push(" clientErrors?: TClient;");
|
|
527
|
-
buffer.push(" serverErrors?: TServer;");
|
|
528
|
-
buffer.push(" defaultErrors?: TDefault;");
|
|
529
|
-
buffer.push(" otherErrors?: TOther;");
|
|
530
|
-
buffer.push("};");
|
|
531
807
|
buffer.push(
|
|
532
808
|
"type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends AnyHeaderFn | undefined = undefined, TErrors extends OperationErrors | undefined = undefined> = {"
|
|
533
809
|
);
|
|
534
|
-
buffer.push(" method: TMethod
|
|
535
|
-
buffer.push(" path: TPath
|
|
536
|
-
buffer.push(" request?: TRequest
|
|
537
|
-
buffer.push(" response?: TResponse
|
|
538
|
-
buffer.push(" headers?: THeaders
|
|
539
|
-
buffer.push(" errors?: TErrors
|
|
540
|
-
buffer.push("}
|
|
541
|
-
|
|
810
|
+
buffer.push(" method: TMethod");
|
|
811
|
+
buffer.push(" path: TPath");
|
|
812
|
+
buffer.push(" request?: TRequest");
|
|
813
|
+
buffer.push(" response?: TResponse");
|
|
814
|
+
buffer.push(" headers?: THeaders");
|
|
815
|
+
buffer.push(" errors?: TErrors");
|
|
816
|
+
buffer.push("}");
|
|
817
|
+
buffer.push("");
|
|
542
818
|
}
|
|
543
819
|
}
|
|
544
820
|
function generateOperationTypes(buffer, operations, config) {
|
|
@@ -566,14 +842,11 @@ function generateOperationTypes(buffer, operations, config) {
|
|
|
566
842
|
}
|
|
567
843
|
}
|
|
568
844
|
function buildOperationErrorsType(errors) {
|
|
569
|
-
if (!errors || !
|
|
845
|
+
if (!errors || !hasAnyErrors2(errors)) {
|
|
570
846
|
return "OperationErrors";
|
|
571
847
|
}
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
const fallback = buildErrorBucket(errors.defaultErrors);
|
|
575
|
-
const other = buildErrorBucket(errors.otherErrors);
|
|
576
|
-
return `OperationErrors<${client}, ${server}, ${fallback}, ${other}>`;
|
|
848
|
+
const errorBucket = buildErrorBucket(errors);
|
|
849
|
+
return `OperationErrors<${errorBucket}>`;
|
|
577
850
|
}
|
|
578
851
|
function buildErrorBucket(bucket) {
|
|
579
852
|
if (!bucket || Object.keys(bucket).length === 0) {
|
|
@@ -680,10 +953,10 @@ function getRequestType(operation) {
|
|
|
680
953
|
if (requestBody.$ref) {
|
|
681
954
|
return extractRefName(requestBody.$ref);
|
|
682
955
|
}
|
|
683
|
-
const typeName = `${capitalize(operation.operationId)}Request`;
|
|
956
|
+
const typeName = `${capitalize(toCamelCase(operation.operationId))}Request`;
|
|
684
957
|
return typeName;
|
|
685
958
|
}
|
|
686
|
-
function getResponseTypes(operation, operationId) {
|
|
959
|
+
function getResponseTypes(operation, operationId, nameMap) {
|
|
687
960
|
const responses = operation.responses ?? {};
|
|
688
961
|
const successCodes = /* @__PURE__ */ new Map();
|
|
689
962
|
const errorEntries = [];
|
|
@@ -724,11 +997,15 @@ function getResponseTypes(operation, operationId) {
|
|
|
724
997
|
successCodes.set(statusCode, resolvedSchema);
|
|
725
998
|
}
|
|
726
999
|
}
|
|
727
|
-
const successResponse = selectSuccessResponse(
|
|
728
|
-
|
|
1000
|
+
const successResponse = selectSuccessResponse(
|
|
1001
|
+
successCodes,
|
|
1002
|
+
operationId,
|
|
1003
|
+
nameMap
|
|
1004
|
+
);
|
|
1005
|
+
const errors = buildErrorGroups(errorEntries, operationId, nameMap);
|
|
729
1006
|
return { successResponse, errors };
|
|
730
1007
|
}
|
|
731
|
-
function selectSuccessResponse(responses, operationId) {
|
|
1008
|
+
function selectSuccessResponse(responses, operationId, nameMap) {
|
|
732
1009
|
if (responses.size === 0) return void 0;
|
|
733
1010
|
const preferredOrder = ["200", "201", "204"];
|
|
734
1011
|
for (const code of preferredOrder) {
|
|
@@ -739,61 +1016,51 @@ function selectSuccessResponse(responses, operationId) {
|
|
|
739
1016
|
}
|
|
740
1017
|
return resolveResponseType(
|
|
741
1018
|
schema,
|
|
742
|
-
`${capitalize(operationId)}Response
|
|
1019
|
+
`${capitalize(toCamelCase(operationId))}Response`,
|
|
1020
|
+
nameMap
|
|
743
1021
|
);
|
|
744
1022
|
}
|
|
745
1023
|
}
|
|
746
|
-
const [
|
|
1024
|
+
const [, firstSchema] = responses.entries().next().value ?? [];
|
|
747
1025
|
if (!firstSchema) return void 0;
|
|
748
1026
|
if (typeof firstSchema === "string") {
|
|
749
1027
|
return firstSchema;
|
|
750
1028
|
}
|
|
751
1029
|
return resolveResponseType(
|
|
752
1030
|
firstSchema,
|
|
753
|
-
`${capitalize(operationId)}Response
|
|
1031
|
+
`${capitalize(toCamelCase(operationId))}Response`,
|
|
1032
|
+
nameMap
|
|
754
1033
|
);
|
|
755
1034
|
}
|
|
756
|
-
function buildErrorGroups(errors = [], operationId) {
|
|
1035
|
+
function buildErrorGroups(errors = [], operationId, nameMap) {
|
|
757
1036
|
if (!errors.length) return void 0;
|
|
758
1037
|
const group = {};
|
|
759
1038
|
for (const { code, schema } of errors) {
|
|
760
|
-
const category = getStatusCategory(code);
|
|
761
1039
|
const identifier = mapStatusToIdentifier(code);
|
|
762
1040
|
const typeName = resolveResponseType(
|
|
763
1041
|
schema,
|
|
764
|
-
`${capitalize(operationId)}${capitalize(identifier)}
|
|
1042
|
+
`${capitalize(toCamelCase(operationId))}${capitalize(identifier)}`,
|
|
1043
|
+
nameMap
|
|
765
1044
|
);
|
|
766
|
-
|
|
767
|
-
case "client":
|
|
768
|
-
group.clientErrors ??= {};
|
|
769
|
-
group.clientErrors[identifier] = typeName;
|
|
770
|
-
break;
|
|
771
|
-
case "server":
|
|
772
|
-
group.serverErrors ??= {};
|
|
773
|
-
group.serverErrors[identifier] = typeName;
|
|
774
|
-
break;
|
|
775
|
-
case "default":
|
|
776
|
-
group.defaultErrors ??= {};
|
|
777
|
-
group.defaultErrors[identifier] = typeName;
|
|
778
|
-
break;
|
|
779
|
-
default:
|
|
780
|
-
group.otherErrors ??= {};
|
|
781
|
-
group.otherErrors[identifier] = typeName;
|
|
782
|
-
break;
|
|
783
|
-
}
|
|
1045
|
+
group[identifier] = typeName;
|
|
784
1046
|
}
|
|
785
1047
|
return group;
|
|
786
1048
|
}
|
|
787
|
-
function resolveResponseType(schema, fallbackName) {
|
|
1049
|
+
function resolveResponseType(schema, fallbackName, nameMap) {
|
|
788
1050
|
if (typeof schema === "string") {
|
|
789
1051
|
return schema;
|
|
790
1052
|
}
|
|
791
1053
|
if (schema.$ref) {
|
|
792
|
-
|
|
1054
|
+
const refName = extractRefName(schema.$ref);
|
|
1055
|
+
return nameMap?.get(refName) || refName;
|
|
793
1056
|
}
|
|
794
1057
|
if (schema.type === "array" && schema.items?.$ref) {
|
|
795
1058
|
const itemRef = extractRefName(schema.items.$ref);
|
|
796
|
-
|
|
1059
|
+
const sanitizedItemRef = nameMap?.get(itemRef) || itemRef;
|
|
1060
|
+
return `z.array(${sanitizedItemRef})`;
|
|
1061
|
+
}
|
|
1062
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
1063
|
+
return fallbackName;
|
|
797
1064
|
}
|
|
798
1065
|
return fallbackName;
|
|
799
1066
|
}
|
|
@@ -876,19 +1143,30 @@ function convertQueryParamValue(schema, accessor) {
|
|
|
876
1143
|
return `String(${accessor})`;
|
|
877
1144
|
}
|
|
878
1145
|
}
|
|
879
|
-
function generateZodSchema(name, schema, generatedTypes, options) {
|
|
1146
|
+
function generateZodSchema(name, schema, generatedTypes, options, nameMap) {
|
|
880
1147
|
if (generatedTypes.has(name)) return "";
|
|
881
1148
|
generatedTypes.add(name);
|
|
882
1149
|
if (schema.enum) {
|
|
883
1150
|
const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
|
|
884
1151
|
return `export const ${name} = z.enum([${enumValues}]);`;
|
|
885
1152
|
}
|
|
1153
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
1154
|
+
const allOfParts = schema.allOf.map(
|
|
1155
|
+
(part) => getZodTypeFromSchema(part, options, nameMap)
|
|
1156
|
+
);
|
|
1157
|
+
if (allOfParts.length === 0) return `export const ${name} = z.object({});`;
|
|
1158
|
+
if (allOfParts.length === 1)
|
|
1159
|
+
return `export const ${name} = ${allOfParts[0]};`;
|
|
1160
|
+
const first = allOfParts[0];
|
|
1161
|
+
const rest = allOfParts.slice(1).map((part) => `.and(${part})`).join("");
|
|
1162
|
+
return `export const ${name} = ${first}${rest};`;
|
|
1163
|
+
}
|
|
886
1164
|
if (schema.type === "object" || schema.properties) {
|
|
887
|
-
return `export const ${name} = ${buildZodObject(schema, options)};`;
|
|
1165
|
+
return `export const ${name} = ${buildZodObject(schema, options, nameMap)};`;
|
|
888
1166
|
}
|
|
889
1167
|
if (schema.type === "array") {
|
|
890
1168
|
const itemSchema = schema.items ?? { type: "unknown" };
|
|
891
|
-
const itemType = getZodTypeFromSchema(itemSchema, options);
|
|
1169
|
+
const itemType = getZodTypeFromSchema(itemSchema, options, nameMap);
|
|
892
1170
|
const builder = applyStrictArrayBounds(
|
|
893
1171
|
schema,
|
|
894
1172
|
`z.array(${itemType})`,
|
|
@@ -897,18 +1175,29 @@ function generateZodSchema(name, schema, generatedTypes, options) {
|
|
|
897
1175
|
);
|
|
898
1176
|
return `export const ${name} = ${builder};`;
|
|
899
1177
|
}
|
|
900
|
-
return `export const ${name} = ${getZodTypeFromSchema(schema, options)};`;
|
|
1178
|
+
return `export const ${name} = ${getZodTypeFromSchema(schema, options, nameMap)};`;
|
|
901
1179
|
}
|
|
902
|
-
function getZodTypeFromSchema(schema, options) {
|
|
1180
|
+
function getZodTypeFromSchema(schema, options, nameMap) {
|
|
903
1181
|
if (schema.$ref) {
|
|
904
|
-
|
|
1182
|
+
const refName = extractRefName(schema.$ref);
|
|
1183
|
+
return nameMap?.get(refName) || refName;
|
|
905
1184
|
}
|
|
906
1185
|
if (schema.enum) {
|
|
907
1186
|
const enumValues = schema.enum.map((v) => `"${v}"`).join(", ");
|
|
908
1187
|
return `z.enum([${enumValues}])`;
|
|
909
1188
|
}
|
|
910
|
-
if (schema.
|
|
911
|
-
|
|
1189
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
1190
|
+
const allOfParts = schema.allOf.map(
|
|
1191
|
+
(part) => getZodTypeFromSchema(part, options, nameMap)
|
|
1192
|
+
);
|
|
1193
|
+
if (allOfParts.length === 0) return "z.object({})";
|
|
1194
|
+
if (allOfParts.length === 1) return allOfParts[0];
|
|
1195
|
+
const first = allOfParts[0];
|
|
1196
|
+
const rest = allOfParts.slice(1).map((part) => `.and(${part})`).join("");
|
|
1197
|
+
return `${first}${rest}`;
|
|
1198
|
+
}
|
|
1199
|
+
if (schema.type === "object" || schema.properties || schema.allOf || schema.oneOf || schema.anyOf) {
|
|
1200
|
+
return buildZodObject(schema, options, nameMap);
|
|
912
1201
|
}
|
|
913
1202
|
switch (schema.type) {
|
|
914
1203
|
case "string":
|
|
@@ -918,7 +1207,8 @@ function getZodTypeFromSchema(schema, options) {
|
|
|
918
1207
|
case "array":
|
|
919
1208
|
return `z.array(${getZodTypeFromSchema(
|
|
920
1209
|
schema.items ?? { type: "unknown" },
|
|
921
|
-
options
|
|
1210
|
+
options,
|
|
1211
|
+
nameMap
|
|
922
1212
|
)})`;
|
|
923
1213
|
case "null":
|
|
924
1214
|
return "z.null()";
|
|
@@ -930,13 +1220,13 @@ function getZodTypeFromSchema(schema, options) {
|
|
|
930
1220
|
return "z.unknown()";
|
|
931
1221
|
}
|
|
932
1222
|
}
|
|
933
|
-
function buildZodObject(schema, options) {
|
|
1223
|
+
function buildZodObject(schema, options, nameMap) {
|
|
934
1224
|
const properties = [];
|
|
935
1225
|
for (const [propName, propSchema] of Object.entries(
|
|
936
1226
|
schema.properties || {}
|
|
937
1227
|
)) {
|
|
938
1228
|
const isRequired = schema.required?.includes(propName) ?? false;
|
|
939
|
-
const zodType = getZodTypeFromSchema(propSchema, options);
|
|
1229
|
+
const zodType = getZodTypeFromSchema(propSchema, options, nameMap);
|
|
940
1230
|
const finalType = isRequired ? zodType : `${zodType}.optional()`;
|
|
941
1231
|
properties.push(` ${formatPropertyName(propName)}: ${finalType},`);
|
|
942
1232
|
}
|
|
@@ -1044,60 +1334,7 @@ function applyNumericBounds(schema, builder) {
|
|
|
1044
1334
|
}
|
|
1045
1335
|
return builder;
|
|
1046
1336
|
}
|
|
1047
|
-
function generateHelperFile() {
|
|
1048
|
-
const output = [];
|
|
1049
|
-
output.push("// Generated helper types for Zenko");
|
|
1050
|
-
output.push(
|
|
1051
|
-
"// This file provides type definitions for operation objects and path functions"
|
|
1052
|
-
);
|
|
1053
|
-
output.push("");
|
|
1054
|
-
output.push(
|
|
1055
|
-
"export type PathFn<TArgs extends unknown[] = []> = (...args: TArgs) => string"
|
|
1056
|
-
);
|
|
1057
|
-
output.push("");
|
|
1058
|
-
output.push(
|
|
1059
|
-
'export type RequestMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"'
|
|
1060
|
-
);
|
|
1061
|
-
output.push("");
|
|
1062
|
-
output.push(
|
|
1063
|
-
"export type HeaderFn<TArgs extends unknown[] = [], TResult = Record<string, unknown> | Record<string, never>> = (...args: TArgs) => TResult"
|
|
1064
|
-
);
|
|
1065
|
-
output.push("");
|
|
1066
|
-
output.push(
|
|
1067
|
-
"export type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown)"
|
|
1068
|
-
);
|
|
1069
|
-
output.push("");
|
|
1070
|
-
output.push(
|
|
1071
|
-
"export type OperationErrors<TClient = unknown, TServer = unknown, TDefault = unknown, TOther = unknown> = {"
|
|
1072
|
-
);
|
|
1073
|
-
output.push(" clientErrors?: TClient");
|
|
1074
|
-
output.push(" serverErrors?: TServer");
|
|
1075
|
-
output.push(" defaultErrors?: TDefault");
|
|
1076
|
-
output.push(" otherErrors?: TOther");
|
|
1077
|
-
output.push("}");
|
|
1078
|
-
output.push("");
|
|
1079
|
-
output.push(
|
|
1080
|
-
"export type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends AnyHeaderFn | undefined = undefined, TErrors extends OperationErrors | undefined = undefined> = {"
|
|
1081
|
-
);
|
|
1082
|
-
output.push(" method: TMethod");
|
|
1083
|
-
output.push(" path: TPath");
|
|
1084
|
-
output.push(" request?: TRequest");
|
|
1085
|
-
output.push(" response?: TResponse");
|
|
1086
|
-
output.push(" headers?: THeaders");
|
|
1087
|
-
output.push(" errors?: TErrors");
|
|
1088
|
-
output.push("}");
|
|
1089
|
-
output.push("");
|
|
1090
|
-
return output.join("\n");
|
|
1091
|
-
}
|
|
1092
|
-
function toCamelCase(str) {
|
|
1093
|
-
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1094
|
-
}
|
|
1095
|
-
function capitalize(str) {
|
|
1096
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1097
|
-
}
|
|
1098
1337
|
export {
|
|
1099
|
-
generate
|
|
1100
|
-
generateHelperFile,
|
|
1101
|
-
generateWithMetadata
|
|
1338
|
+
generate
|
|
1102
1339
|
};
|
|
1103
1340
|
//# sourceMappingURL=index.mjs.map
|