typed-openapi 2.2.4 → 2.2.6
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/chunk-MAZKDIN3.js +61 -0
- package/dist/{chunk-ZM3UP6UJ.js → chunk-S3NICEHD.js} +125 -56
- package/dist/{chunk-62WASHT2.js → chunk-WTE26U5C.js} +30 -9
- package/dist/cli.js +6 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1 -2
- package/dist/node.export.d.ts +6 -4
- package/dist/node.export.js +3 -3
- package/dist/pretty.export.d.ts +7 -2
- package/dist/pretty.export.js +1 -1
- package/dist/{types-BOJSTQwz.d.ts → types-DjwHsNyZ.d.ts} +3 -3
- package/package.json +19 -19
- package/src/cli.ts +4 -0
- package/src/format.ts +68 -13
- package/src/generate-client-files.ts +32 -9
- package/src/generator.ts +132 -43
- package/src/node.export.ts +1 -1
- package/src/openapi-schema-to-ts.ts +4 -12
- package/src/ref-resolver.ts +22 -5
- package/src/string-utils.ts +2 -2
- package/src/tanstack-query.generator.ts +1 -2
- package/src/ts-factory.ts +8 -3
- package/dist/chunk-KAEXXJ7X.js +0 -21
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/format.ts
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import { dirname, join } from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
var defaultFilePath = "generated.ts";
|
|
7
|
+
var require2 = createRequire(import.meta.url);
|
|
8
|
+
async function formatWithBundledOxfmt(filePath, input, options) {
|
|
9
|
+
const packageJsonPath = require2.resolve("oxfmt/package.json");
|
|
10
|
+
const packageRoot = dirname(packageJsonPath);
|
|
11
|
+
const indexSource = await readFile(join(packageRoot, "dist", "index.js"), "utf8");
|
|
12
|
+
const match = indexSource.match(/from ["']\.\/(apis-[^"']+\.js)["']/);
|
|
13
|
+
const internalFile = match?.[1];
|
|
14
|
+
if (!internalFile) {
|
|
15
|
+
throw new Error("Unable to locate oxfmt's bundled JS formatter");
|
|
16
|
+
}
|
|
17
|
+
const internalUrl = pathToFileURL(join(packageRoot, "dist", internalFile)).href;
|
|
18
|
+
const { r: formatFile } = await import(internalUrl);
|
|
19
|
+
return formatFile({
|
|
20
|
+
code: input,
|
|
21
|
+
options: {
|
|
22
|
+
printWidth: 120,
|
|
23
|
+
trailingComma: "all",
|
|
24
|
+
...options,
|
|
25
|
+
filepath: filePath
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function maybePretty(input, options) {
|
|
30
|
+
const { enabled, filePath = defaultFilePath, ...formatOptions } = options ?? {};
|
|
31
|
+
if (enabled === false) {
|
|
32
|
+
return input;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const { format } = await import("oxfmt");
|
|
36
|
+
const result = await format(filePath, input, {
|
|
37
|
+
printWidth: 120,
|
|
38
|
+
trailingComma: "all",
|
|
39
|
+
...formatOptions
|
|
40
|
+
});
|
|
41
|
+
if (result.errors.length > 0) {
|
|
42
|
+
console.warn(`Failed to format code in ${filePath}`);
|
|
43
|
+
console.warn(result.errors);
|
|
44
|
+
return input;
|
|
45
|
+
}
|
|
46
|
+
return result.code;
|
|
47
|
+
} catch {
|
|
48
|
+
try {
|
|
49
|
+
return await formatWithBundledOxfmt(filePath, input, formatOptions);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.warn(`Failed to format code in ${filePath}`);
|
|
52
|
+
console.warn(err);
|
|
53
|
+
return input;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
var prettify = (str, options) => maybePretty(str, options);
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
prettify
|
|
61
|
+
};
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
prettify
|
|
3
|
-
} from "./chunk-KAEXXJ7X.js";
|
|
4
|
-
|
|
5
1
|
// src/asserts.ts
|
|
6
2
|
var isPrimitiveType = (type2) => primitiveTypeList.includes(type2);
|
|
7
3
|
var primitiveTypeList = ["string", "number", "integer", "boolean", "null"];
|
|
@@ -17,10 +13,10 @@ function normalizeString(text) {
|
|
|
17
13
|
const prefixed = prefixStringStartingWithNumberIfNeeded(text);
|
|
18
14
|
return prefixed.normalize("NFKD").trim().replace(/\s+/g, "_").replace(/-+/g, "_").replace(/[^\w\-]+/g, "_").replace(/--+/g, "-");
|
|
19
15
|
}
|
|
20
|
-
var
|
|
16
|
+
var barePropertyNameRegex = /^(?:[A-Za-z_]\w*|\d+)$/;
|
|
21
17
|
var wrapWithQuotesIfNeeded = (str) => {
|
|
22
18
|
if (str[0] === '"' && str[str.length - 1] === '"') return str;
|
|
23
|
-
if (
|
|
19
|
+
if (barePropertyNameRegex.test(str)) {
|
|
24
20
|
return str;
|
|
25
21
|
}
|
|
26
22
|
return `"${str}"`;
|
|
@@ -132,9 +128,9 @@ var openApiSchemaToTs = ({ schema, meta: _inheritedMeta, ctx }) => {
|
|
|
132
128
|
}
|
|
133
129
|
if (schemaType === "object" || schema.properties || schema.additionalProperties) {
|
|
134
130
|
if (!schema.properties) {
|
|
135
|
-
if (schema.additionalProperties &&
|
|
131
|
+
if (schema.additionalProperties && typeof schema.additionalProperties !== "boolean") {
|
|
136
132
|
const valueSchema = openApiSchemaToTs({ schema: schema.additionalProperties, ctx, meta });
|
|
137
|
-
return t.
|
|
133
|
+
return t.reference("Record", [t.string(), valueSchema]);
|
|
138
134
|
}
|
|
139
135
|
return t.literal("Record<string, unknown>");
|
|
140
136
|
}
|
|
@@ -150,9 +146,7 @@ var openApiSchemaToTs = ({ schema, meta: _inheritedMeta, ctx }) => {
|
|
|
150
146
|
meta
|
|
151
147
|
});
|
|
152
148
|
}
|
|
153
|
-
additionalProperties = t.
|
|
154
|
-
`Record<string, ${additionalPropertiesType ? additionalPropertiesType.value : t.any().value}>`
|
|
155
|
-
);
|
|
149
|
+
additionalProperties = t.reference("Record", [t.string(), additionalPropertiesType ?? t.any()]);
|
|
156
150
|
}
|
|
157
151
|
const hasRequiredArray = schema.required && schema.required.length > 0;
|
|
158
152
|
const isPartial = !schema.required?.length;
|
|
@@ -171,9 +165,7 @@ var openApiSchemaToTs = ({ schema, meta: _inheritedMeta, ctx }) => {
|
|
|
171
165
|
return isPartial ? t.reference("Partial", [objectType]) : objectType;
|
|
172
166
|
}
|
|
173
167
|
if (!schemaType) {
|
|
174
|
-
const nullableKey = Object.keys(schema).filter(
|
|
175
|
-
(key) => !["nullable"].includes(key)
|
|
176
|
-
);
|
|
168
|
+
const nullableKey = Object.keys(schema).filter((key) => !["nullable"].includes(key));
|
|
177
169
|
if (nullableKey.length === 0 && schema.nullable) {
|
|
178
170
|
return t.literal("null");
|
|
179
171
|
}
|
|
@@ -201,6 +193,7 @@ var Box = class _Box {
|
|
|
201
193
|
this.schema = definition.schema;
|
|
202
194
|
this.ctx = definition.ctx;
|
|
203
195
|
}
|
|
196
|
+
definition;
|
|
204
197
|
type;
|
|
205
198
|
value;
|
|
206
199
|
params;
|
|
@@ -386,13 +379,28 @@ var replacerByRuntime = {
|
|
|
386
379
|
"$1$2("
|
|
387
380
|
)
|
|
388
381
|
};
|
|
382
|
+
var shouldRenderDescriptionComments = (ctx) => ctx.jsdoc && ctx.runtime === "none";
|
|
383
|
+
var escapeCommentText = (text) => text.replace(/\*\//g, "*\\/");
|
|
384
|
+
var renderDescriptionComment = (description, indent = "") => {
|
|
385
|
+
const lines = description.trim().split(/\r?\n/);
|
|
386
|
+
return `${indent}/**
|
|
387
|
+
${lines.map((line) => `${indent} * ${escapeCommentText(line)}`).join("\n")}
|
|
388
|
+
${indent} */`;
|
|
389
|
+
};
|
|
390
|
+
var getSchemaDescription = (schema) => {
|
|
391
|
+
if (!schema || typeof schema !== "object") return void 0;
|
|
392
|
+
if ("description" in schema && typeof schema.description === "string") return schema.description;
|
|
393
|
+
return void 0;
|
|
394
|
+
};
|
|
395
|
+
var indentMultiline = (value, indent = " ") => value.includes("\n") ? value.split("\n").map((line, index) => index === 0 ? line : `${indent}${line}`).join("\n") : value;
|
|
389
396
|
var generateFile = (options) => {
|
|
390
397
|
const ctx = {
|
|
391
398
|
...options,
|
|
392
399
|
runtime: options.runtime ?? "none",
|
|
393
400
|
successStatusCodes: options.successStatusCodes ?? DEFAULT_SUCCESS_STATUS_CODES,
|
|
394
401
|
errorStatusCodes: options.errorStatusCodes ?? DEFAULT_ERROR_STATUS_CODES,
|
|
395
|
-
includeClient: options.includeClient ?? true
|
|
402
|
+
includeClient: options.includeClient ?? true,
|
|
403
|
+
jsdoc: options.jsdoc ?? false
|
|
396
404
|
};
|
|
397
405
|
const schemaList = generateSchemaList(ctx);
|
|
398
406
|
const endpointSchemaList = options.schemasOnly ? "" : generateEndpointSchemaList(ctx);
|
|
@@ -422,7 +430,8 @@ var generateFile = (options) => {
|
|
|
422
430
|
`;
|
|
423
431
|
return file;
|
|
424
432
|
};
|
|
425
|
-
var generateSchemaList = (
|
|
433
|
+
var generateSchemaList = (ctx) => {
|
|
434
|
+
const { refs, runtime } = ctx;
|
|
426
435
|
let file = `
|
|
427
436
|
${runtime === "none" ? "export namespace Schemas {" : ""}
|
|
428
437
|
// <Schemas>
|
|
@@ -430,7 +439,10 @@ var generateSchemaList = ({ refs, runtime }) => {
|
|
|
430
439
|
refs.getOrderedSchemas().forEach(([schema, infos]) => {
|
|
431
440
|
if (!infos?.name) return;
|
|
432
441
|
if (infos.kind !== "schemas") return;
|
|
433
|
-
|
|
442
|
+
const description = shouldRenderDescriptionComments(ctx) ? getSchemaDescription(schema.schema) : void 0;
|
|
443
|
+
const schemaValue = shouldRenderDescriptionComments(ctx) && !Box.isReference(schema) ? boxToString(schema, ctx, { prefixRefsWithSchemas: false }) : schema.value;
|
|
444
|
+
file += `${description ? `${renderDescriptionComment(description)}
|
|
445
|
+
` : ""}export type ${infos.normalized} = ${schemaValue}
|
|
434
446
|
`;
|
|
435
447
|
});
|
|
436
448
|
return file + `
|
|
@@ -438,29 +450,79 @@ var generateSchemaList = ({ refs, runtime }) => {
|
|
|
438
450
|
${runtime === "none" ? "}" : ""}
|
|
439
451
|
`;
|
|
440
452
|
};
|
|
453
|
+
var boxToString = (box, ctx, options = {}) => {
|
|
454
|
+
const prefixRefsWithSchemas = options.prefixRefsWithSchemas ?? true;
|
|
455
|
+
if (ctx.runtime !== "none") {
|
|
456
|
+
return box.value;
|
|
457
|
+
}
|
|
458
|
+
const renderValue = (value) => {
|
|
459
|
+
if (typeof value === "string") {
|
|
460
|
+
return value;
|
|
461
|
+
}
|
|
462
|
+
if (Box.isBox(value)) {
|
|
463
|
+
return boxToString(value, ctx, options);
|
|
464
|
+
}
|
|
465
|
+
return value.value;
|
|
466
|
+
};
|
|
467
|
+
if (Box.isUnion(box)) {
|
|
468
|
+
return `(${box.params.types.map((type2) => renderValue(type2)).join(" | ")})`;
|
|
469
|
+
}
|
|
470
|
+
if (Box.isIntersection(box)) {
|
|
471
|
+
return `(${box.params.types.map((type2) => renderValue(type2)).join(" & ")})`;
|
|
472
|
+
}
|
|
473
|
+
if (Box.isArray(box)) {
|
|
474
|
+
return `Array<${renderValue(box.params.type)}>`;
|
|
475
|
+
}
|
|
476
|
+
if (Box.isOptional(box)) {
|
|
477
|
+
return `${renderValue(box.params.type)} | undefined`;
|
|
478
|
+
}
|
|
479
|
+
if (Box.isObject(box)) {
|
|
480
|
+
const renderedProps = Object.entries(box.params.props).map(([prop, type2]) => {
|
|
481
|
+
const isOptional = typeof type2 !== "string" && Box.isBox(type2) && Box.isOptional(type2);
|
|
482
|
+
const renderedValue = indentMultiline(renderValue(type2));
|
|
483
|
+
const description = shouldRenderDescriptionComments(ctx) && typeof type2 !== "string" && Box.isBox(type2) ? getSchemaDescription(type2.schema) : void 0;
|
|
484
|
+
return {
|
|
485
|
+
description,
|
|
486
|
+
line: `${wrapWithQuotesIfNeeded(prop)}${isOptional ? "?" : ""}: ${renderedValue};`
|
|
487
|
+
};
|
|
488
|
+
});
|
|
489
|
+
const shouldRenderMultiline = shouldRenderDescriptionComments(ctx) && renderedProps.some(({ description, line }) => description || line.includes("\n"));
|
|
490
|
+
if (!shouldRenderMultiline) {
|
|
491
|
+
const propsString2 = renderedProps.map(({ line }) => line.slice(0, -1)).join(", ");
|
|
492
|
+
return `{ ${propsString2} }`;
|
|
493
|
+
}
|
|
494
|
+
const propsString = renderedProps.map(({ description, line }) => {
|
|
495
|
+
const comment = description ? `${renderDescriptionComment(description, " ")}
|
|
496
|
+
` : "";
|
|
497
|
+
return `${comment} ${line}`;
|
|
498
|
+
}).join("\n");
|
|
499
|
+
return `{
|
|
500
|
+
${propsString}
|
|
501
|
+
}`;
|
|
502
|
+
}
|
|
503
|
+
if (Box.isReference(box)) {
|
|
504
|
+
if (!box.params.generics) {
|
|
505
|
+
return box.value === "null" ? box.value : prefixRefsWithSchemas ? `Schemas.${box.value}` : box.value;
|
|
506
|
+
}
|
|
507
|
+
return `${box.params.name}<${box.params.generics.map((type2) => renderValue(type2)).join(", ")}>`;
|
|
508
|
+
}
|
|
509
|
+
return box.value;
|
|
510
|
+
};
|
|
441
511
|
var parameterObjectToString = (parameters, ctx) => {
|
|
442
512
|
if (parameters instanceof Box) {
|
|
443
|
-
|
|
444
|
-
return parameters.recompute((box) => {
|
|
445
|
-
if (Box.isReference(box) && !box.params.generics && box.value !== "null") {
|
|
446
|
-
box.value = `Schemas.${box.value}`;
|
|
447
|
-
}
|
|
448
|
-
return box;
|
|
449
|
-
}).value;
|
|
450
|
-
}
|
|
451
|
-
return parameters.value;
|
|
513
|
+
return boxToString(parameters, ctx);
|
|
452
514
|
}
|
|
453
515
|
let str = "{";
|
|
454
516
|
for (const [key, box] of Object.entries(parameters)) {
|
|
455
|
-
str += `${wrapWithQuotesIfNeeded(key)}${box.type === "optional" ? "?" : ""}: ${box
|
|
517
|
+
str += `${wrapWithQuotesIfNeeded(key)}${box.type === "optional" ? "?" : ""}: ${indentMultiline(boxToString(box, ctx))},
|
|
456
518
|
`;
|
|
457
519
|
}
|
|
458
520
|
return str + "}";
|
|
459
521
|
};
|
|
460
|
-
var responseHeadersObjectToString = (responseHeaders) => {
|
|
522
|
+
var responseHeadersObjectToString = (responseHeaders, ctx) => {
|
|
461
523
|
let str = "{";
|
|
462
524
|
for (const [key, responseHeader] of Object.entries(responseHeaders)) {
|
|
463
|
-
str += `${wrapWithQuotesIfNeeded(key.toLowerCase())}: ${responseHeader
|
|
525
|
+
str += `${wrapWithQuotesIfNeeded(key.toLowerCase())}: ${indentMultiline(boxToString(responseHeader, ctx))},
|
|
464
526
|
`;
|
|
465
527
|
}
|
|
466
528
|
return str + "}";
|
|
@@ -468,12 +530,7 @@ var responseHeadersObjectToString = (responseHeaders) => {
|
|
|
468
530
|
var generateResponsesObject = (responses, ctx) => {
|
|
469
531
|
let str = "{";
|
|
470
532
|
for (const [statusCode, responseType] of Object.entries(responses)) {
|
|
471
|
-
const value =
|
|
472
|
-
if (Box.isReference(box) && !box.params.generics && box.value !== "null") {
|
|
473
|
-
box.value = `Schemas.${box.value}`;
|
|
474
|
-
}
|
|
475
|
-
return box;
|
|
476
|
-
}).value : responseType.value;
|
|
533
|
+
const value = indentMultiline(boxToString(responseType, ctx));
|
|
477
534
|
str += `${wrapWithQuotesIfNeeded(statusCode)}: ${value},
|
|
478
535
|
`;
|
|
479
536
|
}
|
|
@@ -487,7 +544,9 @@ var generateEndpointSchemaList = (ctx) => {
|
|
|
487
544
|
`;
|
|
488
545
|
ctx.endpointList.map((endpoint) => {
|
|
489
546
|
const parameters = endpoint.parameters ?? {};
|
|
490
|
-
|
|
547
|
+
const description = shouldRenderDescriptionComments(ctx) ? endpoint.operation.description : void 0;
|
|
548
|
+
file += `${description ? `${renderDescriptionComment(description)}
|
|
549
|
+
` : ""}export type ${endpoint.meta.alias} = {
|
|
491
550
|
method: "${endpoint.method.toUpperCase()}",
|
|
492
551
|
path: "${endpoint.path}",
|
|
493
552
|
requestFormat: "${endpoint.requestFormat}",
|
|
@@ -495,18 +554,10 @@ var generateEndpointSchemaList = (ctx) => {
|
|
|
495
554
|
${parameters.query ? `query: ${parameterObjectToString(parameters.query, ctx)},` : ""}
|
|
496
555
|
${parameters.path ? `path: ${parameterObjectToString(parameters.path, ctx)},` : ""}
|
|
497
556
|
${parameters.header ? `header: ${parameterObjectToString(parameters.header, ctx)},` : ""}
|
|
498
|
-
${parameters.body ? `body: ${parameterObjectToString(
|
|
499
|
-
ctx.runtime === "none" ? parameters.body.recompute((box) => {
|
|
500
|
-
if (Box.isReference(box) && !box.params.generics) {
|
|
501
|
-
box.value = `Schemas.${box.value}`;
|
|
502
|
-
}
|
|
503
|
-
return box;
|
|
504
|
-
}) : parameters.body,
|
|
505
|
-
ctx
|
|
506
|
-
)},` : ""}
|
|
557
|
+
${parameters.body ? `body: ${parameterObjectToString(parameters.body, ctx)},` : ""}
|
|
507
558
|
}` : "parameters: never,"}
|
|
508
559
|
${endpoint.responses ? `responses: ${generateResponsesObject(endpoint.responses, ctx)},` : ""}
|
|
509
|
-
${endpoint.responseHeaders ? `responseHeaders: ${responseHeadersObjectToString(endpoint.responseHeaders)},` : ""}
|
|
560
|
+
${endpoint.responseHeaders ? `responseHeaders: ${responseHeadersObjectToString(endpoint.responseHeaders, ctx)},` : ""}
|
|
510
561
|
}
|
|
511
562
|
`;
|
|
512
563
|
});
|
|
@@ -584,7 +635,7 @@ export type Endpoint<TConfig extends DefaultEndpoint = DefaultEndpoint> = {
|
|
|
584
635
|
|
|
585
636
|
export interface Fetcher {
|
|
586
637
|
decodePathParams?: (path: string, pathParams: Record<string, string>) => string
|
|
587
|
-
|
|
638
|
+
encodeSearchParams?: (searchParams: Record<string, unknown> | undefined) => URLSearchParams
|
|
588
639
|
//
|
|
589
640
|
fetch: (input: {
|
|
590
641
|
method: Method;
|
|
@@ -1026,15 +1077,28 @@ var createRefResolver = (doc, factory2, nameTransform) => {
|
|
|
1026
1077
|
const path = split.slice(1, -1).join("/");
|
|
1027
1078
|
const normalizedPath = path.replace("#/", "").replace("#", "").replaceAll("/", ".");
|
|
1028
1079
|
const map = get(doc, normalizedPath) ?? {};
|
|
1080
|
+
const existingInfo = byRef.get(correctRef);
|
|
1081
|
+
if (existingInfo) {
|
|
1082
|
+
return map[split[split.length - 1]];
|
|
1083
|
+
}
|
|
1029
1084
|
const name = split[split.length - 1];
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1085
|
+
const kind = normalizedPath.split(".")[1];
|
|
1086
|
+
const baseNormalized = sanitizeName(
|
|
1087
|
+
nameTransform?.transformSchemaName ? nameTransform.transformSchemaName(normalizeString(name)) : normalizeString(name),
|
|
1088
|
+
"schema"
|
|
1089
|
+
);
|
|
1090
|
+
let normalized = baseNormalized;
|
|
1091
|
+
if (refByName.has(normalized) && refByName.get(normalized) !== correctRef) {
|
|
1092
|
+
const kindSuffix = `${baseNormalized}_${kind}`;
|
|
1093
|
+
normalized = kindSuffix;
|
|
1094
|
+
let suffix = 2;
|
|
1095
|
+
while (refByName.has(normalized) && refByName.get(normalized) !== correctRef) {
|
|
1096
|
+
normalized = `${kindSuffix}_${suffix++}`;
|
|
1097
|
+
}
|
|
1033
1098
|
}
|
|
1034
|
-
normalized = sanitizeName(normalized, "schema");
|
|
1035
1099
|
nameByRef.set(correctRef, normalized);
|
|
1036
1100
|
refByName.set(normalized, correctRef);
|
|
1037
|
-
const infos = { ref: correctRef, name, normalized, kind
|
|
1101
|
+
const infos = { ref: correctRef, name, normalized, kind };
|
|
1038
1102
|
byRef.set(infos.ref, infos);
|
|
1039
1103
|
byNormalized.set(infos.normalized, infos);
|
|
1040
1104
|
const schema = map[name];
|
|
@@ -1154,12 +1218,17 @@ var getTransitiveDependencies = (directDependencies) => {
|
|
|
1154
1218
|
|
|
1155
1219
|
// src/ts-factory.ts
|
|
1156
1220
|
var tsFactory = createFactory({
|
|
1157
|
-
union: (types) => `(${types.map(unwrap).join(" | ")})
|
|
1158
|
-
intersection: (types) => `(${types.map(unwrap).join(" & ")})
|
|
1221
|
+
union: (types) => types.length ? `(${types.map(unwrap).join(" | ")})` : "never",
|
|
1222
|
+
intersection: (types) => types.length ? `(${types.map(unwrap).join(" & ")})` : "unknown",
|
|
1159
1223
|
array: (type2) => `Array<${unwrap(type2)}>`,
|
|
1160
1224
|
optional: (type2) => `${unwrap(type2)} | undefined`,
|
|
1161
1225
|
reference: (name, typeArgs) => `${name}${typeArgs ? `<${typeArgs.map(unwrap).join(", ")}>` : ""}`,
|
|
1162
|
-
literal: (value) =>
|
|
1226
|
+
literal: (value) => {
|
|
1227
|
+
if (typeof value === "string") return value;
|
|
1228
|
+
if (Box.isBox(value)) return unwrap(value);
|
|
1229
|
+
if (Array.isArray(value) || typeof value === "object") return JSON.stringify(value);
|
|
1230
|
+
return String(value);
|
|
1231
|
+
},
|
|
1163
1232
|
string: () => "string",
|
|
1164
1233
|
number: () => "number",
|
|
1165
1234
|
boolean: () => "boolean",
|
|
@@ -1546,7 +1615,7 @@ var generateTanstackQueryFile = async (ctx) => {
|
|
|
1546
1615
|
// </ApiClient.request>
|
|
1547
1616
|
}
|
|
1548
1617
|
`;
|
|
1549
|
-
return
|
|
1618
|
+
return file;
|
|
1550
1619
|
};
|
|
1551
1620
|
|
|
1552
1621
|
export {
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
generateFile,
|
|
6
6
|
generateTanstackQueryFile,
|
|
7
7
|
mapOpenApiEndpoints
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-S3NICEHD.js";
|
|
9
9
|
import {
|
|
10
10
|
prettify
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MAZKDIN3.js";
|
|
12
12
|
|
|
13
13
|
// src/generate-client-files.ts
|
|
14
14
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
@@ -100,6 +100,7 @@ async function ensureDir(dirPath) {
|
|
|
100
100
|
var optionsSchema = type({
|
|
101
101
|
"output?": "string",
|
|
102
102
|
runtime: allowedRuntimes,
|
|
103
|
+
"format?": "boolean | 'true' | 'false'",
|
|
103
104
|
tanstack: "boolean | string",
|
|
104
105
|
"defaultFetcher?": type({
|
|
105
106
|
"envApiBaseUrl?": "string",
|
|
@@ -109,38 +110,47 @@ var optionsSchema = type({
|
|
|
109
110
|
}),
|
|
110
111
|
schemasOnly: "boolean",
|
|
111
112
|
"includeClient?": "boolean | 'true' | 'false'",
|
|
113
|
+
"jsdoc?": "boolean | 'true' | 'false'",
|
|
112
114
|
"successStatusCodes?": "string",
|
|
113
115
|
"errorStatusCodes?": "string"
|
|
114
116
|
});
|
|
117
|
+
function parseBooleanOption(value) {
|
|
118
|
+
if (value === "false") {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
if (value === "true") {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
115
126
|
async function generateClientFiles(input, options) {
|
|
116
127
|
const openApiDoc = await SwaggerParser.bundle(input);
|
|
117
128
|
const ctx = mapOpenApiEndpoints(openApiDoc, options);
|
|
118
129
|
console.log(`Found ${ctx.endpointList.length} endpoints`);
|
|
119
130
|
const successStatusCodes = options.successStatusCodes ? options.successStatusCodes.split(",").map((code) => parseInt(code.trim(), 10)) : void 0;
|
|
120
131
|
const errorStatusCodes = options.errorStatusCodes ? options.errorStatusCodes.split(",").map((code) => parseInt(code.trim(), 10)) : void 0;
|
|
121
|
-
const includeClient = options.includeClient
|
|
132
|
+
const includeClient = parseBooleanOption(options.includeClient);
|
|
133
|
+
const jsdoc = parseBooleanOption(options.jsdoc) ?? true;
|
|
134
|
+
const shouldFormat = parseBooleanOption(options.format) ?? false;
|
|
122
135
|
const generatorOptions = {
|
|
123
136
|
...ctx,
|
|
124
137
|
runtime: options.runtime,
|
|
125
138
|
schemasOnly: options.schemasOnly,
|
|
126
139
|
nameTransform: options.nameTransform,
|
|
127
140
|
includeClient: includeClient ?? true,
|
|
141
|
+
jsdoc,
|
|
128
142
|
successStatusCodes: successStatusCodes ?? DEFAULT_SUCCESS_STATUS_CODES,
|
|
129
143
|
errorStatusCodes: errorStatusCodes ?? DEFAULT_ERROR_STATUS_CODES
|
|
130
144
|
};
|
|
131
|
-
const content = await prettify(generateFile(generatorOptions));
|
|
132
145
|
const outputPath = join(
|
|
133
146
|
cwd,
|
|
134
147
|
options.output ?? input + `.${options.runtime === "none" ? "client" : options.runtime}.ts`
|
|
135
148
|
);
|
|
149
|
+
const content = await prettify(generateFile(generatorOptions), { enabled: shouldFormat, filePath: outputPath });
|
|
136
150
|
console.log("Generating client...", outputPath);
|
|
137
151
|
await ensureDir(dirname(outputPath));
|
|
138
152
|
await writeFile(outputPath, content);
|
|
139
153
|
if (options.tanstack) {
|
|
140
|
-
const tanstackContent = await generateTanstackQueryFile({
|
|
141
|
-
...generatorOptions,
|
|
142
|
-
relativeApiClientPath: "./" + basename(outputPath)
|
|
143
|
-
});
|
|
144
154
|
let tanstackOutputPath;
|
|
145
155
|
if (typeof options.tanstack === "string" && isAbsolute(options.tanstack)) {
|
|
146
156
|
tanstackOutputPath = options.tanstack;
|
|
@@ -150,6 +160,13 @@ async function generateClientFiles(input, options) {
|
|
|
150
160
|
typeof options.tanstack === "string" ? options.tanstack : `tanstack.client.ts`
|
|
151
161
|
);
|
|
152
162
|
}
|
|
163
|
+
const tanstackContent = await prettify(
|
|
164
|
+
await generateTanstackQueryFile({
|
|
165
|
+
...generatorOptions,
|
|
166
|
+
relativeApiClientPath: "./" + basename(outputPath)
|
|
167
|
+
}),
|
|
168
|
+
{ enabled: shouldFormat, filePath: tanstackOutputPath }
|
|
169
|
+
);
|
|
153
170
|
console.log("Generating tanstack client...", tanstackOutputPath);
|
|
154
171
|
await ensureDir(dirname(tanstackOutputPath));
|
|
155
172
|
await writeFile(tanstackOutputPath, tanstackContent);
|
|
@@ -170,9 +187,13 @@ async function generateClientFiles(input, options) {
|
|
|
170
187
|
typeof options.defaultFetcher === "string" ? options.defaultFetcher : `api.client.ts`
|
|
171
188
|
);
|
|
172
189
|
}
|
|
190
|
+
const formattedDefaultFetcherContent = await prettify(defaultFetcherContent, {
|
|
191
|
+
enabled: shouldFormat,
|
|
192
|
+
filePath: defaultFetcherOutputPath
|
|
193
|
+
});
|
|
173
194
|
console.log("Generating default fetcher...", defaultFetcherOutputPath);
|
|
174
195
|
await ensureDir(dirname(defaultFetcherOutputPath));
|
|
175
|
-
await writeFile(defaultFetcherOutputPath,
|
|
196
|
+
await writeFile(defaultFetcherOutputPath, formattedDefaultFetcherContent);
|
|
176
197
|
}
|
|
177
198
|
console.log(`Done in ${(/* @__PURE__ */ new Date()).getTime() - now.getTime()}ms !`);
|
|
178
199
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClientFiles
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WTE26U5C.js";
|
|
4
4
|
import {
|
|
5
5
|
allowedRuntimes
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-S3NICEHD.js";
|
|
7
|
+
import "./chunk-MAZKDIN3.js";
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
10
10
|
import { cac } from "cac";
|
|
@@ -15,7 +15,9 @@ cli.command("<input>", "Generate").option("-o, --output <path>", "Output path fo
|
|
|
15
15
|
"-r, --runtime <n>",
|
|
16
16
|
`Runtime to use for validation; defaults to \`none\`; available: ${allowedRuntimes.toString()}`,
|
|
17
17
|
{ default: "none" }
|
|
18
|
-
).option("--schemas-only", "Only generate schemas, skipping client generation (defaults to false)", { default: false }).option("--include-client", "Include API client types and implementation (defaults to true)", { default: true }).option(
|
|
18
|
+
).option("--format", "Format generated files with oxfmt (defaults to false)", { default: false }).option("--schemas-only", "Only generate schemas, skipping client generation (defaults to false)", { default: false }).option("--include-client", "Include API client types and implementation (defaults to true)", { default: true }).option("--jsdoc", "Emit OpenAPI descriptions as JSDoc comments (defaults to false)", {
|
|
19
|
+
default: true
|
|
20
|
+
}).option(
|
|
19
21
|
"--success-status-codes <codes>",
|
|
20
22
|
"Comma-separated list of success status codes (defaults to 2xx and 3xx ranges)"
|
|
21
23
|
).option("--error-status-codes <codes>", "Comma-separated list of error status codes (defaults to 4xx and 5xx ranges)").option(
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReferenceObject } from 'openapi3-ts/oas31';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
4
|
-
import * as
|
|
2
|
+
import { L as LibSchemaObject, O as OpenapiSchemaConvertContext, B as BoxFactory, S as StringOrBox, m as mapOpenApiEndpoints, N as NameTransformOptions, a as OpenapiSchemaConvertArgs, b as Box, A as AnyBoxDef } from './types-DjwHsNyZ.js';
|
|
3
|
+
export { c as AnyBox, d as BoxArray, e as BoxDefinition, f as BoxIntersection, g as BoxKeyword, h as BoxLiteral, i as BoxObject, j as BoxOptional, k as BoxParams, l as BoxRef, n as BoxUnion, E as Endpoint, o as EndpointParameters, F as FactoryCreator, G as GenericFactory, M as Method, R as RefInfo, p as RefResolver, W as WithSchema, q as createRefResolver } from './types-DjwHsNyZ.js';
|
|
4
|
+
import * as arktype_internal_variants_string_ts from 'arktype/internal/variants/string.ts';
|
|
5
5
|
import * as Codegen from '@sinclair/typebox-codegen';
|
|
6
6
|
import 'openapi3-ts/oas30';
|
|
7
7
|
|
|
@@ -19,8 +19,9 @@ type GeneratorOptions$1 = ReturnType<typeof mapOpenApiEndpoints> & {
|
|
|
19
19
|
successStatusCodes?: readonly number[];
|
|
20
20
|
errorStatusCodes?: readonly number[];
|
|
21
21
|
includeClient?: boolean;
|
|
22
|
+
jsdoc?: boolean;
|
|
22
23
|
};
|
|
23
|
-
declare const allowedRuntimes:
|
|
24
|
+
declare const allowedRuntimes: arktype_internal_variants_string_ts.StringType<"none" | "arktype" | "io-ts" | "typebox" | "valibot" | "yup" | "zod", {}>;
|
|
24
25
|
type OutputRuntime = typeof allowedRuntimes.infer;
|
|
25
26
|
declare const runtimeValidationGenerator: {
|
|
26
27
|
arktype: typeof Codegen.ModelToArkType.Generate;
|
package/dist/index.js
CHANGED
package/dist/node.export.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { N as NameTransformOptions } from './types-
|
|
1
|
+
import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
|
|
2
|
+
import { N as NameTransformOptions } from './types-DjwHsNyZ.js';
|
|
3
3
|
import 'openapi3-ts/oas31';
|
|
4
4
|
import 'openapi3-ts/oas30';
|
|
5
5
|
|
|
6
|
-
declare const optionsSchema:
|
|
6
|
+
declare const optionsSchema: arktype_internal_variants_object_ts.ObjectType<{
|
|
7
7
|
runtime: "none" | "arktype" | "io-ts" | "typebox" | "valibot" | "yup" | "zod";
|
|
8
8
|
tanstack: string | boolean;
|
|
9
9
|
schemasOnly: boolean;
|
|
10
10
|
output?: string;
|
|
11
|
+
format?: boolean | "false" | "true";
|
|
11
12
|
defaultFetcher?: {
|
|
12
13
|
envApiBaseUrl?: string;
|
|
13
14
|
clientPath?: string;
|
|
@@ -15,6 +16,7 @@ declare const optionsSchema: arktype_internal_methods_object_ts.ObjectType<{
|
|
|
15
16
|
apiName?: string;
|
|
16
17
|
};
|
|
17
18
|
includeClient?: boolean | "false" | "true";
|
|
19
|
+
jsdoc?: boolean | "false" | "true";
|
|
18
20
|
successStatusCodes?: string;
|
|
19
21
|
errorStatusCodes?: string;
|
|
20
22
|
}, {}>;
|
|
@@ -23,4 +25,4 @@ type GenerateClientFilesOptions = typeof optionsSchema.infer & {
|
|
|
23
25
|
};
|
|
24
26
|
declare function generateClientFiles(input: string, options: GenerateClientFilesOptions): Promise<void>;
|
|
25
27
|
|
|
26
|
-
export { generateClientFiles };
|
|
28
|
+
export { type GenerateClientFilesOptions, generateClientFiles };
|
package/dist/node.export.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClientFiles
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-WTE26U5C.js";
|
|
4
|
+
import "./chunk-S3NICEHD.js";
|
|
5
|
+
import "./chunk-MAZKDIN3.js";
|
|
6
6
|
export {
|
|
7
7
|
generateClientFiles
|
|
8
8
|
};
|
package/dist/pretty.export.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as oxfmt from 'oxfmt';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type OxcFormatOptions = oxfmt.FormatConfig;
|
|
4
|
+
type PrettifyOptions = OxcFormatOptions & {
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
filePath?: string;
|
|
7
|
+
};
|
|
8
|
+
declare const prettify: (str: string, options?: PrettifyOptions | null) => Promise<string>;
|
|
4
9
|
|
|
5
10
|
export { prettify };
|
package/dist/pretty.export.js
CHANGED
|
@@ -43,7 +43,7 @@ type RefInfo = {
|
|
|
43
43
|
kind: "schemas" | "responses" | "parameters" | "requestBodies" | "headers";
|
|
44
44
|
};
|
|
45
45
|
declare const createRefResolver: (doc: OpenAPIObject, factory: GenericFactory, nameTransform?: NameTransformOptions) => {
|
|
46
|
-
get: <T = LibSchemaObject>(ref: string) =>
|
|
46
|
+
get: <T = LibSchemaObject>(ref: string) => T;
|
|
47
47
|
unwrap: <T extends ReferenceObject | {}>(component: T) => Exclude<T, ReferenceObject>;
|
|
48
48
|
getInfosByRef: (ref: string) => RefInfo;
|
|
49
49
|
infos: Map<string, RefInfo>;
|
|
@@ -63,7 +63,7 @@ declare const mapOpenApiEndpoints: (doc: OpenAPIObject, options?: {
|
|
|
63
63
|
}) => {
|
|
64
64
|
doc: OpenAPIObject;
|
|
65
65
|
refs: {
|
|
66
|
-
get: <T = LibSchemaObject>(ref: string) =>
|
|
66
|
+
get: <T = LibSchemaObject>(ref: string) => T;
|
|
67
67
|
unwrap: <T extends openapi3_ts_oas31.ReferenceObject | {}>(component: T) => Exclude<T, openapi3_ts_oas31.ReferenceObject>;
|
|
68
68
|
getInfosByRef: (ref: string) => RefInfo;
|
|
69
69
|
infos: Map<string, RefInfo>;
|
|
@@ -239,4 +239,4 @@ type GenericFactory = {
|
|
|
239
239
|
never: () => string;
|
|
240
240
|
};
|
|
241
241
|
|
|
242
|
-
export { type AnyBoxDef as A, type BoxFactory as B, type
|
|
242
|
+
export { type AnyBoxDef as A, type BoxFactory as B, type Endpoint as E, type FactoryCreator as F, type GenericFactory as G, type LibSchemaObject as L, type Method as M, type NameTransformOptions as N, type OpenapiSchemaConvertContext as O, type RefInfo as R, type StringOrBox as S, type WithSchema as W, type OpenapiSchemaConvertArgs as a, Box as b, type AnyBox as c, type BoxArray as d, type BoxDefinition as e, type BoxIntersection as f, type BoxKeyword as g, type BoxLiteral as h, type BoxObject as i, type BoxOptional as j, type BoxParams as k, type BoxRef as l, mapOpenApiEndpoints as m, type BoxUnion as n, type EndpointParameters as o, type RefResolver as p, createRefResolver as q };
|