zenko 0.1.3 → 0.1.5
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/dist/cli.cjs +233 -91
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +233 -91
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +218 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +218 -89
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -202,7 +202,7 @@ function isErrorStatus(status) {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
// src/zenko.ts
|
|
205
|
-
function
|
|
205
|
+
function generateWithMetadata(spec, options = {}) {
|
|
206
206
|
const output = [];
|
|
207
207
|
const generatedTypes = /* @__PURE__ */ new Set();
|
|
208
208
|
const { strictDates = false, strictNumeric = false } = options;
|
|
@@ -235,8 +235,11 @@ function generate(spec, options = {}) {
|
|
|
235
235
|
const pathParamNames = op.pathParams.map((p) => p.name);
|
|
236
236
|
const hasPathParams = pathParamNames.length > 0;
|
|
237
237
|
const hasQueryParams = op.queryParams.length > 0;
|
|
238
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
238
239
|
if (!hasPathParams && !hasQueryParams) {
|
|
239
|
-
output.push(
|
|
240
|
+
output.push(
|
|
241
|
+
` ${formatPropertyName(camelCaseOperationId)}: () => "${op.path}",`
|
|
242
|
+
);
|
|
240
243
|
continue;
|
|
241
244
|
}
|
|
242
245
|
const allParamNames = [
|
|
@@ -259,11 +262,13 @@ function generate(spec, options = {}) {
|
|
|
259
262
|
const pathWithParams = op.path.replace(/{([^}]+)}/g, "${$1}");
|
|
260
263
|
if (!hasQueryParams) {
|
|
261
264
|
output.push(
|
|
262
|
-
` ${
|
|
265
|
+
` ${formatPropertyName(camelCaseOperationId)}: (${signature}) => \`${pathWithParams}\`,`
|
|
263
266
|
);
|
|
264
267
|
continue;
|
|
265
268
|
}
|
|
266
|
-
output.push(
|
|
269
|
+
output.push(
|
|
270
|
+
` ${formatPropertyName(camelCaseOperationId)}: (${signature}) => {`
|
|
271
|
+
);
|
|
267
272
|
output.push(" const params = new URLSearchParams()");
|
|
268
273
|
for (const param of op.queryParams) {
|
|
269
274
|
const propertyKey = formatPropertyName(param.name);
|
|
@@ -308,83 +313,57 @@ function generate(spec, options = {}) {
|
|
|
308
313
|
}
|
|
309
314
|
output.push("} as const;");
|
|
310
315
|
output.push("");
|
|
311
|
-
output.push("// Header
|
|
312
|
-
output.push("export const
|
|
316
|
+
output.push("// Header Schemas");
|
|
317
|
+
output.push("export const headerSchemas = {");
|
|
313
318
|
for (const op of operations) {
|
|
319
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
314
320
|
if (!op.requestHeaders || op.requestHeaders.length === 0) {
|
|
315
|
-
output.push(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const typeEntries = op.requestHeaders.map(
|
|
319
|
-
(header) => `${formatPropertyName(header.name)}${header.required ? "" : "?"}: ${mapHeaderType(
|
|
320
|
-
header
|
|
321
|
-
)}`
|
|
322
|
-
).join(", ");
|
|
323
|
-
const requiredHeaders = op.requestHeaders.filter(
|
|
324
|
-
(header) => header.required
|
|
325
|
-
);
|
|
326
|
-
const optionalHeaders = op.requestHeaders.filter(
|
|
327
|
-
(header) => !header.required
|
|
328
|
-
);
|
|
329
|
-
const hasRequired = requiredHeaders.length > 0;
|
|
330
|
-
const signature = hasRequired ? `(params: { ${typeEntries} })` : `(params: { ${typeEntries} } = {})`;
|
|
331
|
-
if (optionalHeaders.length === 0) {
|
|
332
|
-
output.push(` ${op.operationId}: ${signature} => ({`);
|
|
333
|
-
for (const header of requiredHeaders) {
|
|
334
|
-
const propertyKey = formatPropertyName(header.name);
|
|
335
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
336
|
-
output.push(` ${propertyKey}: ${accessor},`);
|
|
337
|
-
}
|
|
338
|
-
output.push(" }),");
|
|
321
|
+
output.push(
|
|
322
|
+
` ${formatPropertyName(camelCaseOperationId)}: z.object({}),`
|
|
323
|
+
);
|
|
339
324
|
continue;
|
|
340
325
|
}
|
|
341
|
-
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
326
|
+
const schemaFields = op.requestHeaders.map((header) => {
|
|
327
|
+
const zodType = mapHeaderToZodType(header);
|
|
328
|
+
const optional = header.required ? "" : ".optional()";
|
|
329
|
+
return ` ${formatPropertyName(header.name)}: ${zodType}${optional},`;
|
|
330
|
+
}).join("\n");
|
|
331
|
+
output.push(` ${formatPropertyName(camelCaseOperationId)}: z.object({`);
|
|
332
|
+
output.push(schemaFields);
|
|
333
|
+
output.push(" }),");
|
|
334
|
+
}
|
|
335
|
+
output.push("} as const;");
|
|
336
|
+
output.push("");
|
|
337
|
+
output.push("// Header Functions");
|
|
338
|
+
output.push("export const headers = {");
|
|
339
|
+
for (const op of operations) {
|
|
340
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
341
|
+
if (!op.requestHeaders || op.requestHeaders.length === 0) {
|
|
346
342
|
output.push(
|
|
347
|
-
`
|
|
343
|
+
` ${formatPropertyName(camelCaseOperationId)}: () => ${isValidJSIdentifier(camelCaseOperationId) ? `headerSchemas.${camelCaseOperationId}` : `headerSchemas[${formatPropertyName(camelCaseOperationId)}]`}.parse({}),`
|
|
348
344
|
);
|
|
349
345
|
continue;
|
|
350
346
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
354
|
-
output.push(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
for (const header of requiredHeaders) {
|
|
358
|
-
const propertyKey = formatPropertyName(header.name);
|
|
359
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
360
|
-
output.push(` ${propertyKey}: ${accessor},`);
|
|
361
|
-
}
|
|
362
|
-
output.push(" }");
|
|
363
|
-
} else {
|
|
364
|
-
output.push(` const headers: Record<string, ${valueTypes}> = {}`);
|
|
365
|
-
}
|
|
366
|
-
for (const header of optionalHeaders) {
|
|
367
|
-
const propertyKey = formatPropertyName(header.name);
|
|
368
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
369
|
-
const assignment = isValidJSIdentifier(header.name) ? `headers.${header.name}` : `headers[${propertyKey}]`;
|
|
370
|
-
output.push(` if (${accessor} !== undefined) {`);
|
|
371
|
-
output.push(` ${assignment} = ${accessor}`);
|
|
372
|
-
output.push(" }");
|
|
373
|
-
}
|
|
374
|
-
output.push(" return headers");
|
|
347
|
+
output.push(
|
|
348
|
+
` ${formatPropertyName(camelCaseOperationId)}: (params: z.input<${isValidJSIdentifier(camelCaseOperationId) ? `typeof headerSchemas.${camelCaseOperationId}` : `(typeof headerSchemas)[${formatPropertyName(camelCaseOperationId)}]`}>) => {`
|
|
349
|
+
);
|
|
350
|
+
output.push(
|
|
351
|
+
` return ${isValidJSIdentifier(camelCaseOperationId) ? `headerSchemas.${camelCaseOperationId}` : `headerSchemas[${formatPropertyName(camelCaseOperationId)}]`}.parse(params)`
|
|
352
|
+
);
|
|
375
353
|
output.push(" },");
|
|
376
354
|
}
|
|
377
355
|
output.push("} as const;");
|
|
378
356
|
output.push("");
|
|
379
357
|
output.push("// Operation Objects");
|
|
380
358
|
for (const op of operations) {
|
|
381
|
-
|
|
359
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
360
|
+
output.push(`export const ${camelCaseOperationId} = {`);
|
|
382
361
|
output.push(` method: "${op.method}",`);
|
|
383
|
-
output.push(` path: paths.${
|
|
362
|
+
output.push(` path: paths.${camelCaseOperationId},`);
|
|
384
363
|
appendOperationField(output, "request", op.requestType);
|
|
385
364
|
appendOperationField(output, "response", op.responseType);
|
|
386
365
|
if (op.requestHeaders && op.requestHeaders.length > 0) {
|
|
387
|
-
output.push(` headers: headers.${
|
|
366
|
+
output.push(` headers: headers.${camelCaseOperationId},`);
|
|
388
367
|
}
|
|
389
368
|
if (op.errors && hasAnyErrors(op.errors)) {
|
|
390
369
|
output.push(" errors: {");
|
|
@@ -398,7 +377,19 @@ function generate(spec, options = {}) {
|
|
|
398
377
|
output.push("");
|
|
399
378
|
}
|
|
400
379
|
generateOperationTypes(output, operations, typesConfig);
|
|
401
|
-
|
|
380
|
+
const result = {
|
|
381
|
+
output: output.join("\n")
|
|
382
|
+
};
|
|
383
|
+
if (typesConfig.emit && typesConfig.helpers === "file" && typesConfig.helpersOutput) {
|
|
384
|
+
result.helperFile = {
|
|
385
|
+
path: typesConfig.helpersOutput,
|
|
386
|
+
content: generateHelperFile()
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
function generate(spec, options = {}) {
|
|
392
|
+
return generateWithMetadata(spec, options).output;
|
|
402
393
|
}
|
|
403
394
|
function appendOperationField(buffer, key, value) {
|
|
404
395
|
if (!value) return;
|
|
@@ -435,6 +426,36 @@ function isRequestMethod(method) {
|
|
|
435
426
|
return false;
|
|
436
427
|
}
|
|
437
428
|
}
|
|
429
|
+
var CONTENT_TYPE_MAP = {
|
|
430
|
+
"application/json": "unknown",
|
|
431
|
+
// Will use schema when available
|
|
432
|
+
"text/csv": "string",
|
|
433
|
+
"text/plain": "string",
|
|
434
|
+
// Binary/ambiguous types default to unknown for cross-platform compatibility
|
|
435
|
+
"application/octet-stream": "unknown",
|
|
436
|
+
"application/pdf": "unknown"
|
|
437
|
+
};
|
|
438
|
+
function findContentType(content) {
|
|
439
|
+
const contentTypes = Object.keys(content);
|
|
440
|
+
if (contentTypes.includes("application/json")) {
|
|
441
|
+
return "application/json";
|
|
442
|
+
}
|
|
443
|
+
for (const contentType of contentTypes) {
|
|
444
|
+
if (contentType in CONTENT_TYPE_MAP) {
|
|
445
|
+
return contentType;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return contentTypes[0] || "";
|
|
449
|
+
}
|
|
450
|
+
function inferResponseType(contentType, statusCode) {
|
|
451
|
+
if (statusCode === "204" || /^3\d\d$/.test(statusCode)) {
|
|
452
|
+
return "undefined";
|
|
453
|
+
}
|
|
454
|
+
if (contentType in CONTENT_TYPE_MAP) {
|
|
455
|
+
return CONTENT_TYPE_MAP[contentType];
|
|
456
|
+
}
|
|
457
|
+
return "unknown";
|
|
458
|
+
}
|
|
438
459
|
function parseOperations(spec) {
|
|
439
460
|
const operations = [];
|
|
440
461
|
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
@@ -496,6 +517,9 @@ function appendHelperTypesImport(buffer, config) {
|
|
|
496
517
|
buffer.push(
|
|
497
518
|
"type HeaderFn<TArgs extends unknown[] = [], TResult = Record<string, unknown> | Record<string, never>> = (...args: TArgs) => TResult;"
|
|
498
519
|
);
|
|
520
|
+
buffer.push(
|
|
521
|
+
"type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown);"
|
|
522
|
+
);
|
|
499
523
|
buffer.push(
|
|
500
524
|
"type OperationErrors<TClient = unknown, TServer = unknown, TDefault = unknown, TOther = unknown> = {"
|
|
501
525
|
);
|
|
@@ -505,7 +529,7 @@ function appendHelperTypesImport(buffer, config) {
|
|
|
505
529
|
buffer.push(" otherErrors?: TOther;");
|
|
506
530
|
buffer.push("};");
|
|
507
531
|
buffer.push(
|
|
508
|
-
"type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends
|
|
532
|
+
"type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends AnyHeaderFn | undefined = undefined, TErrors extends OperationErrors | undefined = undefined> = {"
|
|
509
533
|
);
|
|
510
534
|
buffer.push(" method: TMethod;");
|
|
511
535
|
buffer.push(" path: TPath;");
|
|
@@ -521,15 +545,18 @@ function generateOperationTypes(buffer, operations, config) {
|
|
|
521
545
|
if (!config.emit) return;
|
|
522
546
|
buffer.push("// Operation Types");
|
|
523
547
|
for (const op of operations) {
|
|
524
|
-
const
|
|
548
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
549
|
+
const headerType = op.requestHeaders?.length ? isValidJSIdentifier(camelCaseOperationId) ? `typeof headers.${camelCaseOperationId}` : `(typeof headers)[${formatPropertyName(camelCaseOperationId)}]` : "undefined";
|
|
525
550
|
const requestType = wrapTypeReference(op.requestType);
|
|
526
551
|
const responseType = wrapTypeReference(op.responseType);
|
|
527
552
|
const errorsType = buildOperationErrorsType(op.errors);
|
|
528
553
|
buffer.push(
|
|
529
|
-
`export type ${capitalize(
|
|
554
|
+
`export type ${capitalize(camelCaseOperationId)}Operation = OperationDefinition<`
|
|
530
555
|
);
|
|
531
556
|
buffer.push(` "${op.method}",`);
|
|
532
|
-
buffer.push(
|
|
557
|
+
buffer.push(
|
|
558
|
+
` ${isValidJSIdentifier(camelCaseOperationId) ? `typeof paths.${camelCaseOperationId}` : `(typeof paths)[${formatPropertyName(camelCaseOperationId)}]`},`
|
|
559
|
+
);
|
|
533
560
|
buffer.push(` ${requestType},`);
|
|
534
561
|
buffer.push(` ${responseType},`);
|
|
535
562
|
buffer.push(` ${headerType},`);
|
|
@@ -573,26 +600,35 @@ var TYPE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
573
600
|
"bigint",
|
|
574
601
|
"symbol"
|
|
575
602
|
]);
|
|
603
|
+
var IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
576
604
|
function wrapTypeReference(typeName) {
|
|
577
605
|
if (!typeName) return "undefined";
|
|
578
|
-
|
|
579
|
-
if (
|
|
580
|
-
if (
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
606
|
+
const normalized = typeName.trim();
|
|
607
|
+
if (normalized === "undefined") return "undefined";
|
|
608
|
+
if (TYPE_KEYWORDS.has(normalized)) return normalized;
|
|
609
|
+
if (normalized.startsWith("typeof ")) return normalized;
|
|
610
|
+
const arrayMatch = normalized.match(/^z\.array\((.+)\)$/);
|
|
611
|
+
if (arrayMatch) {
|
|
612
|
+
return `z.ZodArray<${wrapTypeReference(arrayMatch[1])}>`;
|
|
584
613
|
}
|
|
585
|
-
|
|
614
|
+
if (IDENTIFIER_PATTERN.test(normalized)) {
|
|
615
|
+
return `typeof ${normalized}`;
|
|
616
|
+
}
|
|
617
|
+
return normalized;
|
|
586
618
|
}
|
|
587
619
|
function wrapErrorValueType(typeName) {
|
|
588
620
|
if (!typeName) return "unknown";
|
|
589
|
-
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
621
|
+
const normalized = typeName.trim();
|
|
622
|
+
if (TYPE_KEYWORDS.has(normalized)) return normalized;
|
|
623
|
+
if (normalized.startsWith("typeof ")) return normalized;
|
|
624
|
+
const arrayMatch = normalized.match(/^z\.array\((.+)\)$/);
|
|
625
|
+
if (arrayMatch) {
|
|
626
|
+
return `z.ZodArray<${wrapErrorValueType(arrayMatch[1])}>`;
|
|
594
627
|
}
|
|
595
|
-
|
|
628
|
+
if (IDENTIFIER_PATTERN.test(normalized)) {
|
|
629
|
+
return `typeof ${normalized}`;
|
|
630
|
+
}
|
|
631
|
+
return normalized;
|
|
596
632
|
}
|
|
597
633
|
function collectParameters(pathItem, operation, spec) {
|
|
598
634
|
const parametersMap = /* @__PURE__ */ new Map();
|
|
@@ -652,13 +688,39 @@ function getResponseTypes(operation, operationId) {
|
|
|
652
688
|
const successCodes = /* @__PURE__ */ new Map();
|
|
653
689
|
const errorEntries = [];
|
|
654
690
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
655
|
-
const
|
|
656
|
-
if (!
|
|
691
|
+
const content = response?.content;
|
|
692
|
+
if (!content || Object.keys(content).length === 0) {
|
|
693
|
+
if (statusCode === "204" || /^3\d\d$/.test(statusCode)) {
|
|
694
|
+
successCodes.set(statusCode, "undefined");
|
|
695
|
+
} else if (isErrorStatus(statusCode)) {
|
|
696
|
+
errorEntries.push({
|
|
697
|
+
code: statusCode,
|
|
698
|
+
schema: "undefined"
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
const contentType = findContentType(content);
|
|
704
|
+
const resolvedSchema = content[contentType]?.schema;
|
|
705
|
+
if (!resolvedSchema) {
|
|
706
|
+
const inferredType = inferResponseType(contentType, statusCode);
|
|
707
|
+
if (inferredType) {
|
|
708
|
+
if (isErrorStatus(statusCode)) {
|
|
709
|
+
errorEntries.push({
|
|
710
|
+
code: statusCode,
|
|
711
|
+
schema: inferredType
|
|
712
|
+
});
|
|
713
|
+
} else if (/^2\d\d$/.test(statusCode)) {
|
|
714
|
+
successCodes.set(statusCode, inferredType);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
657
719
|
if (isErrorStatus(statusCode)) {
|
|
658
720
|
errorEntries.push({ code: statusCode, schema: resolvedSchema });
|
|
659
721
|
continue;
|
|
660
722
|
}
|
|
661
|
-
if (/^2\d\d$/.test(statusCode)
|
|
723
|
+
if (/^2\d\d$/.test(statusCode)) {
|
|
662
724
|
successCodes.set(statusCode, resolvedSchema);
|
|
663
725
|
}
|
|
664
726
|
}
|
|
@@ -672,6 +734,9 @@ function selectSuccessResponse(responses, operationId) {
|
|
|
672
734
|
for (const code of preferredOrder) {
|
|
673
735
|
const schema = responses.get(code);
|
|
674
736
|
if (schema) {
|
|
737
|
+
if (typeof schema === "string") {
|
|
738
|
+
return schema;
|
|
739
|
+
}
|
|
675
740
|
return resolveResponseType(
|
|
676
741
|
schema,
|
|
677
742
|
`${capitalize(operationId)}Response${code}`
|
|
@@ -680,6 +745,9 @@ function selectSuccessResponse(responses, operationId) {
|
|
|
680
745
|
}
|
|
681
746
|
const [firstCode, firstSchema] = responses.entries().next().value ?? [];
|
|
682
747
|
if (!firstSchema) return void 0;
|
|
748
|
+
if (typeof firstSchema === "string") {
|
|
749
|
+
return firstSchema;
|
|
750
|
+
}
|
|
683
751
|
return resolveResponseType(
|
|
684
752
|
firstSchema,
|
|
685
753
|
`${capitalize(operationId)}Response${firstCode ?? "Default"}`
|
|
@@ -717,9 +785,16 @@ function buildErrorGroups(errors = [], operationId) {
|
|
|
717
785
|
return group;
|
|
718
786
|
}
|
|
719
787
|
function resolveResponseType(schema, fallbackName) {
|
|
788
|
+
if (typeof schema === "string") {
|
|
789
|
+
return schema;
|
|
790
|
+
}
|
|
720
791
|
if (schema.$ref) {
|
|
721
792
|
return extractRefName(schema.$ref);
|
|
722
793
|
}
|
|
794
|
+
if (schema.type === "array" && schema.items?.$ref) {
|
|
795
|
+
const itemRef = extractRefName(schema.items.$ref);
|
|
796
|
+
return `z.array(${itemRef})`;
|
|
797
|
+
}
|
|
723
798
|
return fallbackName;
|
|
724
799
|
}
|
|
725
800
|
function getRequestHeaders(parameters) {
|
|
@@ -750,16 +825,22 @@ function getQueryParams(parameters) {
|
|
|
750
825
|
}
|
|
751
826
|
return queryParams;
|
|
752
827
|
}
|
|
753
|
-
function
|
|
754
|
-
const
|
|
828
|
+
function mapHeaderToZodType(header) {
|
|
829
|
+
const schema = header.schema ?? {};
|
|
830
|
+
const schemaType = schema.type;
|
|
755
831
|
switch (schemaType) {
|
|
756
832
|
case "integer":
|
|
757
833
|
case "number":
|
|
758
|
-
return "number";
|
|
834
|
+
return "z.coerce.number()";
|
|
759
835
|
case "boolean":
|
|
760
|
-
return "boolean";
|
|
836
|
+
return "z.coerce.boolean()";
|
|
837
|
+
case "array": {
|
|
838
|
+
const items = schema.items ?? { type: "string" };
|
|
839
|
+
const itemType = items.type === "integer" || items.type === "number" ? "z.coerce.number()" : items.type === "boolean" ? "z.coerce.boolean()" : "z.string()";
|
|
840
|
+
return `z.array(${itemType})`;
|
|
841
|
+
}
|
|
761
842
|
default:
|
|
762
|
-
return "string";
|
|
843
|
+
return "z.string()";
|
|
763
844
|
}
|
|
764
845
|
}
|
|
765
846
|
function mapQueryType(param) {
|
|
@@ -963,6 +1044,54 @@ function applyNumericBounds(schema, builder) {
|
|
|
963
1044
|
}
|
|
964
1045
|
return builder;
|
|
965
1046
|
}
|
|
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
|
+
}
|
|
966
1095
|
function capitalize(str) {
|
|
967
1096
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
968
1097
|
}
|