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.cjs
CHANGED
|
@@ -228,7 +228,7 @@ function isErrorStatus(status) {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
// src/zenko.ts
|
|
231
|
-
function
|
|
231
|
+
function generateWithMetadata(spec, options = {}) {
|
|
232
232
|
const output = [];
|
|
233
233
|
const generatedTypes = /* @__PURE__ */ new Set();
|
|
234
234
|
const { strictDates = false, strictNumeric = false } = options;
|
|
@@ -261,8 +261,11 @@ function generate(spec, options = {}) {
|
|
|
261
261
|
const pathParamNames = op.pathParams.map((p) => p.name);
|
|
262
262
|
const hasPathParams = pathParamNames.length > 0;
|
|
263
263
|
const hasQueryParams = op.queryParams.length > 0;
|
|
264
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
264
265
|
if (!hasPathParams && !hasQueryParams) {
|
|
265
|
-
output.push(
|
|
266
|
+
output.push(
|
|
267
|
+
` ${formatPropertyName(camelCaseOperationId)}: () => "${op.path}",`
|
|
268
|
+
);
|
|
266
269
|
continue;
|
|
267
270
|
}
|
|
268
271
|
const allParamNames = [
|
|
@@ -285,11 +288,13 @@ function generate(spec, options = {}) {
|
|
|
285
288
|
const pathWithParams = op.path.replace(/{([^}]+)}/g, "${$1}");
|
|
286
289
|
if (!hasQueryParams) {
|
|
287
290
|
output.push(
|
|
288
|
-
` ${
|
|
291
|
+
` ${formatPropertyName(camelCaseOperationId)}: (${signature}) => \`${pathWithParams}\`,`
|
|
289
292
|
);
|
|
290
293
|
continue;
|
|
291
294
|
}
|
|
292
|
-
output.push(
|
|
295
|
+
output.push(
|
|
296
|
+
` ${formatPropertyName(camelCaseOperationId)}: (${signature}) => {`
|
|
297
|
+
);
|
|
293
298
|
output.push(" const params = new URLSearchParams()");
|
|
294
299
|
for (const param of op.queryParams) {
|
|
295
300
|
const propertyKey = formatPropertyName(param.name);
|
|
@@ -334,83 +339,57 @@ function generate(spec, options = {}) {
|
|
|
334
339
|
}
|
|
335
340
|
output.push("} as const;");
|
|
336
341
|
output.push("");
|
|
337
|
-
output.push("// Header
|
|
338
|
-
output.push("export const
|
|
342
|
+
output.push("// Header Schemas");
|
|
343
|
+
output.push("export const headerSchemas = {");
|
|
339
344
|
for (const op of operations) {
|
|
345
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
340
346
|
if (!op.requestHeaders || op.requestHeaders.length === 0) {
|
|
341
|
-
output.push(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const typeEntries = op.requestHeaders.map(
|
|
345
|
-
(header) => `${formatPropertyName(header.name)}${header.required ? "" : "?"}: ${mapHeaderType(
|
|
346
|
-
header
|
|
347
|
-
)}`
|
|
348
|
-
).join(", ");
|
|
349
|
-
const requiredHeaders = op.requestHeaders.filter(
|
|
350
|
-
(header) => header.required
|
|
351
|
-
);
|
|
352
|
-
const optionalHeaders = op.requestHeaders.filter(
|
|
353
|
-
(header) => !header.required
|
|
354
|
-
);
|
|
355
|
-
const hasRequired = requiredHeaders.length > 0;
|
|
356
|
-
const signature = hasRequired ? `(params: { ${typeEntries} })` : `(params: { ${typeEntries} } = {})`;
|
|
357
|
-
if (optionalHeaders.length === 0) {
|
|
358
|
-
output.push(` ${op.operationId}: ${signature} => ({`);
|
|
359
|
-
for (const header of requiredHeaders) {
|
|
360
|
-
const propertyKey = formatPropertyName(header.name);
|
|
361
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
362
|
-
output.push(` ${propertyKey}: ${accessor},`);
|
|
363
|
-
}
|
|
364
|
-
output.push(" }),");
|
|
347
|
+
output.push(
|
|
348
|
+
` ${formatPropertyName(camelCaseOperationId)}: z.object({}),`
|
|
349
|
+
);
|
|
365
350
|
continue;
|
|
366
351
|
}
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
352
|
+
const schemaFields = op.requestHeaders.map((header) => {
|
|
353
|
+
const zodType = mapHeaderToZodType(header);
|
|
354
|
+
const optional = header.required ? "" : ".optional()";
|
|
355
|
+
return ` ${formatPropertyName(header.name)}: ${zodType}${optional},`;
|
|
356
|
+
}).join("\n");
|
|
357
|
+
output.push(` ${formatPropertyName(camelCaseOperationId)}: z.object({`);
|
|
358
|
+
output.push(schemaFields);
|
|
359
|
+
output.push(" }),");
|
|
360
|
+
}
|
|
361
|
+
output.push("} as const;");
|
|
362
|
+
output.push("");
|
|
363
|
+
output.push("// Header Functions");
|
|
364
|
+
output.push("export const headers = {");
|
|
365
|
+
for (const op of operations) {
|
|
366
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
367
|
+
if (!op.requestHeaders || op.requestHeaders.length === 0) {
|
|
372
368
|
output.push(
|
|
373
|
-
`
|
|
369
|
+
` ${formatPropertyName(camelCaseOperationId)}: () => ${isValidJSIdentifier(camelCaseOperationId) ? `headerSchemas.${camelCaseOperationId}` : `headerSchemas[${formatPropertyName(camelCaseOperationId)}]`}.parse({}),`
|
|
374
370
|
);
|
|
375
371
|
continue;
|
|
376
372
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
)
|
|
380
|
-
output.push(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
for (const header of requiredHeaders) {
|
|
384
|
-
const propertyKey = formatPropertyName(header.name);
|
|
385
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
386
|
-
output.push(` ${propertyKey}: ${accessor},`);
|
|
387
|
-
}
|
|
388
|
-
output.push(" }");
|
|
389
|
-
} else {
|
|
390
|
-
output.push(` const headers: Record<string, ${valueTypes}> = {}`);
|
|
391
|
-
}
|
|
392
|
-
for (const header of optionalHeaders) {
|
|
393
|
-
const propertyKey = formatPropertyName(header.name);
|
|
394
|
-
const accessor = isValidJSIdentifier(header.name) ? `params.${header.name}` : `params[${propertyKey}]`;
|
|
395
|
-
const assignment = isValidJSIdentifier(header.name) ? `headers.${header.name}` : `headers[${propertyKey}]`;
|
|
396
|
-
output.push(` if (${accessor} !== undefined) {`);
|
|
397
|
-
output.push(` ${assignment} = ${accessor}`);
|
|
398
|
-
output.push(" }");
|
|
399
|
-
}
|
|
400
|
-
output.push(" return headers");
|
|
373
|
+
output.push(
|
|
374
|
+
` ${formatPropertyName(camelCaseOperationId)}: (params: z.input<${isValidJSIdentifier(camelCaseOperationId) ? `typeof headerSchemas.${camelCaseOperationId}` : `(typeof headerSchemas)[${formatPropertyName(camelCaseOperationId)}]`}>) => {`
|
|
375
|
+
);
|
|
376
|
+
output.push(
|
|
377
|
+
` return ${isValidJSIdentifier(camelCaseOperationId) ? `headerSchemas.${camelCaseOperationId}` : `headerSchemas[${formatPropertyName(camelCaseOperationId)}]`}.parse(params)`
|
|
378
|
+
);
|
|
401
379
|
output.push(" },");
|
|
402
380
|
}
|
|
403
381
|
output.push("} as const;");
|
|
404
382
|
output.push("");
|
|
405
383
|
output.push("// Operation Objects");
|
|
406
384
|
for (const op of operations) {
|
|
407
|
-
|
|
385
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
386
|
+
output.push(`export const ${camelCaseOperationId} = {`);
|
|
408
387
|
output.push(` method: "${op.method}",`);
|
|
409
|
-
output.push(` path: paths.${
|
|
388
|
+
output.push(` path: paths.${camelCaseOperationId},`);
|
|
410
389
|
appendOperationField(output, "request", op.requestType);
|
|
411
390
|
appendOperationField(output, "response", op.responseType);
|
|
412
391
|
if (op.requestHeaders && op.requestHeaders.length > 0) {
|
|
413
|
-
output.push(` headers: headers.${
|
|
392
|
+
output.push(` headers: headers.${camelCaseOperationId},`);
|
|
414
393
|
}
|
|
415
394
|
if (op.errors && hasAnyErrors(op.errors)) {
|
|
416
395
|
output.push(" errors: {");
|
|
@@ -424,7 +403,19 @@ function generate(spec, options = {}) {
|
|
|
424
403
|
output.push("");
|
|
425
404
|
}
|
|
426
405
|
generateOperationTypes(output, operations, typesConfig);
|
|
427
|
-
|
|
406
|
+
const result = {
|
|
407
|
+
output: output.join("\n")
|
|
408
|
+
};
|
|
409
|
+
if (typesConfig.emit && typesConfig.helpers === "file" && typesConfig.helpersOutput) {
|
|
410
|
+
result.helperFile = {
|
|
411
|
+
path: typesConfig.helpersOutput,
|
|
412
|
+
content: generateHelperFile()
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
function generate(spec, options = {}) {
|
|
418
|
+
return generateWithMetadata(spec, options).output;
|
|
428
419
|
}
|
|
429
420
|
function appendOperationField(buffer, key, value) {
|
|
430
421
|
if (!value) return;
|
|
@@ -461,6 +452,36 @@ function isRequestMethod(method) {
|
|
|
461
452
|
return false;
|
|
462
453
|
}
|
|
463
454
|
}
|
|
455
|
+
var CONTENT_TYPE_MAP = {
|
|
456
|
+
"application/json": "unknown",
|
|
457
|
+
// Will use schema when available
|
|
458
|
+
"text/csv": "string",
|
|
459
|
+
"text/plain": "string",
|
|
460
|
+
// Binary/ambiguous types default to unknown for cross-platform compatibility
|
|
461
|
+
"application/octet-stream": "unknown",
|
|
462
|
+
"application/pdf": "unknown"
|
|
463
|
+
};
|
|
464
|
+
function findContentType(content) {
|
|
465
|
+
const contentTypes = Object.keys(content);
|
|
466
|
+
if (contentTypes.includes("application/json")) {
|
|
467
|
+
return "application/json";
|
|
468
|
+
}
|
|
469
|
+
for (const contentType of contentTypes) {
|
|
470
|
+
if (contentType in CONTENT_TYPE_MAP) {
|
|
471
|
+
return contentType;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return contentTypes[0] || "";
|
|
475
|
+
}
|
|
476
|
+
function inferResponseType(contentType, statusCode) {
|
|
477
|
+
if (statusCode === "204" || /^3\d\d$/.test(statusCode)) {
|
|
478
|
+
return "undefined";
|
|
479
|
+
}
|
|
480
|
+
if (contentType in CONTENT_TYPE_MAP) {
|
|
481
|
+
return CONTENT_TYPE_MAP[contentType];
|
|
482
|
+
}
|
|
483
|
+
return "unknown";
|
|
484
|
+
}
|
|
464
485
|
function parseOperations(spec) {
|
|
465
486
|
const operations = [];
|
|
466
487
|
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
@@ -522,6 +543,9 @@ function appendHelperTypesImport(buffer, config) {
|
|
|
522
543
|
buffer.push(
|
|
523
544
|
"type HeaderFn<TArgs extends unknown[] = [], TResult = Record<string, unknown> | Record<string, never>> = (...args: TArgs) => TResult;"
|
|
524
545
|
);
|
|
546
|
+
buffer.push(
|
|
547
|
+
"type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown);"
|
|
548
|
+
);
|
|
525
549
|
buffer.push(
|
|
526
550
|
"type OperationErrors<TClient = unknown, TServer = unknown, TDefault = unknown, TOther = unknown> = {"
|
|
527
551
|
);
|
|
@@ -531,7 +555,7 @@ function appendHelperTypesImport(buffer, config) {
|
|
|
531
555
|
buffer.push(" otherErrors?: TOther;");
|
|
532
556
|
buffer.push("};");
|
|
533
557
|
buffer.push(
|
|
534
|
-
"type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends
|
|
558
|
+
"type OperationDefinition<TMethod extends RequestMethod, TPath extends (...args: any[]) => string, TRequest = undefined, TResponse = undefined, THeaders extends AnyHeaderFn | undefined = undefined, TErrors extends OperationErrors | undefined = undefined> = {"
|
|
535
559
|
);
|
|
536
560
|
buffer.push(" method: TMethod;");
|
|
537
561
|
buffer.push(" path: TPath;");
|
|
@@ -547,15 +571,18 @@ function generateOperationTypes(buffer, operations, config) {
|
|
|
547
571
|
if (!config.emit) return;
|
|
548
572
|
buffer.push("// Operation Types");
|
|
549
573
|
for (const op of operations) {
|
|
550
|
-
const
|
|
574
|
+
const camelCaseOperationId = toCamelCase(op.operationId);
|
|
575
|
+
const headerType = op.requestHeaders?.length ? isValidJSIdentifier(camelCaseOperationId) ? `typeof headers.${camelCaseOperationId}` : `(typeof headers)[${formatPropertyName(camelCaseOperationId)}]` : "undefined";
|
|
551
576
|
const requestType = wrapTypeReference(op.requestType);
|
|
552
577
|
const responseType = wrapTypeReference(op.responseType);
|
|
553
578
|
const errorsType = buildOperationErrorsType(op.errors);
|
|
554
579
|
buffer.push(
|
|
555
|
-
`export type ${capitalize(
|
|
580
|
+
`export type ${capitalize(camelCaseOperationId)}Operation = OperationDefinition<`
|
|
556
581
|
);
|
|
557
582
|
buffer.push(` "${op.method}",`);
|
|
558
|
-
buffer.push(
|
|
583
|
+
buffer.push(
|
|
584
|
+
` ${isValidJSIdentifier(camelCaseOperationId) ? `typeof paths.${camelCaseOperationId}` : `(typeof paths)[${formatPropertyName(camelCaseOperationId)}]`},`
|
|
585
|
+
);
|
|
559
586
|
buffer.push(` ${requestType},`);
|
|
560
587
|
buffer.push(` ${responseType},`);
|
|
561
588
|
buffer.push(` ${headerType},`);
|
|
@@ -599,26 +626,35 @@ var TYPE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
599
626
|
"bigint",
|
|
600
627
|
"symbol"
|
|
601
628
|
]);
|
|
629
|
+
var IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
602
630
|
function wrapTypeReference(typeName) {
|
|
603
631
|
if (!typeName) return "undefined";
|
|
604
|
-
|
|
605
|
-
if (
|
|
606
|
-
if (
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
632
|
+
const normalized = typeName.trim();
|
|
633
|
+
if (normalized === "undefined") return "undefined";
|
|
634
|
+
if (TYPE_KEYWORDS.has(normalized)) return normalized;
|
|
635
|
+
if (normalized.startsWith("typeof ")) return normalized;
|
|
636
|
+
const arrayMatch = normalized.match(/^z\.array\((.+)\)$/);
|
|
637
|
+
if (arrayMatch) {
|
|
638
|
+
return `z.ZodArray<${wrapTypeReference(arrayMatch[1])}>`;
|
|
610
639
|
}
|
|
611
|
-
|
|
640
|
+
if (IDENTIFIER_PATTERN.test(normalized)) {
|
|
641
|
+
return `typeof ${normalized}`;
|
|
642
|
+
}
|
|
643
|
+
return normalized;
|
|
612
644
|
}
|
|
613
645
|
function wrapErrorValueType(typeName) {
|
|
614
646
|
if (!typeName) return "unknown";
|
|
615
|
-
|
|
616
|
-
if (
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
647
|
+
const normalized = typeName.trim();
|
|
648
|
+
if (TYPE_KEYWORDS.has(normalized)) return normalized;
|
|
649
|
+
if (normalized.startsWith("typeof ")) return normalized;
|
|
650
|
+
const arrayMatch = normalized.match(/^z\.array\((.+)\)$/);
|
|
651
|
+
if (arrayMatch) {
|
|
652
|
+
return `z.ZodArray<${wrapErrorValueType(arrayMatch[1])}>`;
|
|
620
653
|
}
|
|
621
|
-
|
|
654
|
+
if (IDENTIFIER_PATTERN.test(normalized)) {
|
|
655
|
+
return `typeof ${normalized}`;
|
|
656
|
+
}
|
|
657
|
+
return normalized;
|
|
622
658
|
}
|
|
623
659
|
function collectParameters(pathItem, operation, spec) {
|
|
624
660
|
const parametersMap = /* @__PURE__ */ new Map();
|
|
@@ -678,13 +714,39 @@ function getResponseTypes(operation, operationId) {
|
|
|
678
714
|
const successCodes = /* @__PURE__ */ new Map();
|
|
679
715
|
const errorEntries = [];
|
|
680
716
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
681
|
-
const
|
|
682
|
-
if (!
|
|
717
|
+
const content = response?.content;
|
|
718
|
+
if (!content || Object.keys(content).length === 0) {
|
|
719
|
+
if (statusCode === "204" || /^3\d\d$/.test(statusCode)) {
|
|
720
|
+
successCodes.set(statusCode, "undefined");
|
|
721
|
+
} else if (isErrorStatus(statusCode)) {
|
|
722
|
+
errorEntries.push({
|
|
723
|
+
code: statusCode,
|
|
724
|
+
schema: "undefined"
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
const contentType = findContentType(content);
|
|
730
|
+
const resolvedSchema = content[contentType]?.schema;
|
|
731
|
+
if (!resolvedSchema) {
|
|
732
|
+
const inferredType = inferResponseType(contentType, statusCode);
|
|
733
|
+
if (inferredType) {
|
|
734
|
+
if (isErrorStatus(statusCode)) {
|
|
735
|
+
errorEntries.push({
|
|
736
|
+
code: statusCode,
|
|
737
|
+
schema: inferredType
|
|
738
|
+
});
|
|
739
|
+
} else if (/^2\d\d$/.test(statusCode)) {
|
|
740
|
+
successCodes.set(statusCode, inferredType);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
683
745
|
if (isErrorStatus(statusCode)) {
|
|
684
746
|
errorEntries.push({ code: statusCode, schema: resolvedSchema });
|
|
685
747
|
continue;
|
|
686
748
|
}
|
|
687
|
-
if (/^2\d\d$/.test(statusCode)
|
|
749
|
+
if (/^2\d\d$/.test(statusCode)) {
|
|
688
750
|
successCodes.set(statusCode, resolvedSchema);
|
|
689
751
|
}
|
|
690
752
|
}
|
|
@@ -698,6 +760,9 @@ function selectSuccessResponse(responses, operationId) {
|
|
|
698
760
|
for (const code of preferredOrder) {
|
|
699
761
|
const schema = responses.get(code);
|
|
700
762
|
if (schema) {
|
|
763
|
+
if (typeof schema === "string") {
|
|
764
|
+
return schema;
|
|
765
|
+
}
|
|
701
766
|
return resolveResponseType(
|
|
702
767
|
schema,
|
|
703
768
|
`${capitalize(operationId)}Response${code}`
|
|
@@ -706,6 +771,9 @@ function selectSuccessResponse(responses, operationId) {
|
|
|
706
771
|
}
|
|
707
772
|
const [firstCode, firstSchema] = responses.entries().next().value ?? [];
|
|
708
773
|
if (!firstSchema) return void 0;
|
|
774
|
+
if (typeof firstSchema === "string") {
|
|
775
|
+
return firstSchema;
|
|
776
|
+
}
|
|
709
777
|
return resolveResponseType(
|
|
710
778
|
firstSchema,
|
|
711
779
|
`${capitalize(operationId)}Response${firstCode ?? "Default"}`
|
|
@@ -743,9 +811,16 @@ function buildErrorGroups(errors = [], operationId) {
|
|
|
743
811
|
return group;
|
|
744
812
|
}
|
|
745
813
|
function resolveResponseType(schema, fallbackName) {
|
|
814
|
+
if (typeof schema === "string") {
|
|
815
|
+
return schema;
|
|
816
|
+
}
|
|
746
817
|
if (schema.$ref) {
|
|
747
818
|
return extractRefName(schema.$ref);
|
|
748
819
|
}
|
|
820
|
+
if (schema.type === "array" && schema.items?.$ref) {
|
|
821
|
+
const itemRef = extractRefName(schema.items.$ref);
|
|
822
|
+
return `z.array(${itemRef})`;
|
|
823
|
+
}
|
|
749
824
|
return fallbackName;
|
|
750
825
|
}
|
|
751
826
|
function getRequestHeaders(parameters) {
|
|
@@ -776,16 +851,22 @@ function getQueryParams(parameters) {
|
|
|
776
851
|
}
|
|
777
852
|
return queryParams;
|
|
778
853
|
}
|
|
779
|
-
function
|
|
780
|
-
const
|
|
854
|
+
function mapHeaderToZodType(header) {
|
|
855
|
+
const schema = header.schema ?? {};
|
|
856
|
+
const schemaType = schema.type;
|
|
781
857
|
switch (schemaType) {
|
|
782
858
|
case "integer":
|
|
783
859
|
case "number":
|
|
784
|
-
return "number";
|
|
860
|
+
return "z.coerce.number()";
|
|
785
861
|
case "boolean":
|
|
786
|
-
return "boolean";
|
|
862
|
+
return "z.coerce.boolean()";
|
|
863
|
+
case "array": {
|
|
864
|
+
const items = schema.items ?? { type: "string" };
|
|
865
|
+
const itemType = items.type === "integer" || items.type === "number" ? "z.coerce.number()" : items.type === "boolean" ? "z.coerce.boolean()" : "z.string()";
|
|
866
|
+
return `z.array(${itemType})`;
|
|
867
|
+
}
|
|
787
868
|
default:
|
|
788
|
-
return "string";
|
|
869
|
+
return "z.string()";
|
|
789
870
|
}
|
|
790
871
|
}
|
|
791
872
|
function mapQueryType(param) {
|
|
@@ -989,6 +1070,54 @@ function applyNumericBounds(schema, builder) {
|
|
|
989
1070
|
}
|
|
990
1071
|
return builder;
|
|
991
1072
|
}
|
|
1073
|
+
function generateHelperFile() {
|
|
1074
|
+
const output = [];
|
|
1075
|
+
output.push("// Generated helper types for Zenko");
|
|
1076
|
+
output.push(
|
|
1077
|
+
"// This file provides type definitions for operation objects and path functions"
|
|
1078
|
+
);
|
|
1079
|
+
output.push("");
|
|
1080
|
+
output.push(
|
|
1081
|
+
"export type PathFn<TArgs extends unknown[] = []> = (...args: TArgs) => string"
|
|
1082
|
+
);
|
|
1083
|
+
output.push("");
|
|
1084
|
+
output.push(
|
|
1085
|
+
'export type RequestMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace"'
|
|
1086
|
+
);
|
|
1087
|
+
output.push("");
|
|
1088
|
+
output.push(
|
|
1089
|
+
"export type HeaderFn<TArgs extends unknown[] = [], TResult = Record<string, unknown> | Record<string, never>> = (...args: TArgs) => TResult"
|
|
1090
|
+
);
|
|
1091
|
+
output.push("");
|
|
1092
|
+
output.push(
|
|
1093
|
+
"export type AnyHeaderFn = HeaderFn<any, unknown> | (() => unknown)"
|
|
1094
|
+
);
|
|
1095
|
+
output.push("");
|
|
1096
|
+
output.push(
|
|
1097
|
+
"export type OperationErrors<TClient = unknown, TServer = unknown, TDefault = unknown, TOther = unknown> = {"
|
|
1098
|
+
);
|
|
1099
|
+
output.push(" clientErrors?: TClient");
|
|
1100
|
+
output.push(" serverErrors?: TServer");
|
|
1101
|
+
output.push(" defaultErrors?: TDefault");
|
|
1102
|
+
output.push(" otherErrors?: TOther");
|
|
1103
|
+
output.push("}");
|
|
1104
|
+
output.push("");
|
|
1105
|
+
output.push(
|
|
1106
|
+
"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> = {"
|
|
1107
|
+
);
|
|
1108
|
+
output.push(" method: TMethod");
|
|
1109
|
+
output.push(" path: TPath");
|
|
1110
|
+
output.push(" request?: TRequest");
|
|
1111
|
+
output.push(" response?: TResponse");
|
|
1112
|
+
output.push(" headers?: THeaders");
|
|
1113
|
+
output.push(" errors?: TErrors");
|
|
1114
|
+
output.push("}");
|
|
1115
|
+
output.push("");
|
|
1116
|
+
return output.join("\n");
|
|
1117
|
+
}
|
|
1118
|
+
function toCamelCase(str) {
|
|
1119
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1120
|
+
}
|
|
992
1121
|
function capitalize(str) {
|
|
993
1122
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
994
1123
|
}
|