@trpc/openapi 11.18.1-canary.9 → 11.19.0-alpha
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.js → cli.mjs} +104 -109
- package/dist/heyapi/index.cjs +24 -38
- package/dist/heyapi/index.d.cts +9 -12
- package/dist/heyapi/index.d.cts.map +1 -1
- package/dist/heyapi/index.d.mts +9 -12
- package/dist/heyapi/index.d.mts.map +1 -1
- package/dist/heyapi/index.mjs +23 -38
- package/dist/heyapi/index.mjs.map +1 -1
- package/dist/index.cjs +128 -108
- package/dist/index.d.cts +3 -8
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +89 -103
- package/dist/index.mjs.map +1 -1
- package/dist/objectSpread2-C2ceYbQe.cjs +67 -0
- package/dist/objectSpread2-Dh4InpQf.mjs +62 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/package.json +10 -10
- package/src/generate.ts +67 -8
- package/src/heyapi/index.ts +1 -2
- package/src/types.ts +9 -16
- package/dist/chunk-CJ2cON1m.mjs +0 -33
- package/dist/objectSpread2-Blgb1OZh.mjs +0 -90
- package/dist/objectSpread2-Blgb1OZh.mjs.map +0 -1
- package/dist/objectSpread2-Cw30I7tb.cjs +0 -131
package/dist/{cli.js → cli.mjs}
RENAMED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import * as fs$1 from "node:fs";
|
|
3
2
|
import * as fs from "node:fs";
|
|
4
|
-
import * as path$1 from "node:path";
|
|
5
3
|
import * as path from "node:path";
|
|
6
4
|
import { parseArgs } from "node:util";
|
|
7
5
|
import * as ts from "typescript";
|
|
8
6
|
import { pathToFileURL } from "node:url";
|
|
9
|
-
|
|
10
7
|
//#region src/schemaExtraction.ts
|
|
11
8
|
/**
|
|
12
9
|
* Zod v4 stores `.describe()` strings in `globalThis.__zod_globalRegistry`,
|
|
@@ -36,7 +33,7 @@ function zodArrayElement(schema) {
|
|
|
36
33
|
return null;
|
|
37
34
|
}
|
|
38
35
|
/** Wrapper def types whose inner schema is accessible via `innerType` or `in`. */
|
|
39
|
-
const wrapperDefTypes = new Set([
|
|
36
|
+
const wrapperDefTypes = /* @__PURE__ */ new Set([
|
|
40
37
|
"optional",
|
|
41
38
|
"nullable",
|
|
42
39
|
"nonoptional",
|
|
@@ -120,13 +117,13 @@ function walkZodShape(schema, prefix, ctx) {
|
|
|
120
117
|
const shape = zodObjectShape(unwrapped);
|
|
121
118
|
if (!shape) return;
|
|
122
119
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
123
|
-
const path
|
|
120
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
124
121
|
const meta = ctx.registry.get(fieldSchema);
|
|
125
122
|
const unwrappedField = unwrapZodSchema(fieldSchema);
|
|
126
123
|
const innerMeta = unwrappedField !== fieldSchema ? ctx.registry.get(unwrappedField) : void 0;
|
|
127
124
|
const description = meta?.description ?? innerMeta?.description;
|
|
128
|
-
if (description) ctx.map.properties.set(path
|
|
129
|
-
walkZodShape(unwrappedField, path
|
|
125
|
+
if (description) ctx.map.properties.set(path, description);
|
|
126
|
+
walkZodShape(unwrappedField, path, ctx);
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
129
|
/** Check whether a value looks like a tRPC router instance at runtime. */
|
|
@@ -158,8 +155,7 @@ function findRouterExport(mod, exportName) {
|
|
|
158
155
|
*/
|
|
159
156
|
async function tryImportRouter(resolvedPath, exportName) {
|
|
160
157
|
try {
|
|
161
|
-
|
|
162
|
-
return findRouterExport(mod, exportName);
|
|
158
|
+
return findRouterExport(await import(pathToFileURL(resolvedPath).href), exportName);
|
|
163
159
|
} catch {
|
|
164
160
|
return null;
|
|
165
161
|
}
|
|
@@ -241,15 +237,12 @@ function setNestedDescription({ schema, pathParts, description, schemas }) {
|
|
|
241
237
|
const items = getArrayItemsSchema(schema);
|
|
242
238
|
if (!items) return;
|
|
243
239
|
if (rest.length === 0) setLeafDescription(items, description);
|
|
244
|
-
else {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
schemas
|
|
251
|
-
});
|
|
252
|
-
}
|
|
240
|
+
else setNestedDescription({
|
|
241
|
+
schema: resolveSchemaRef(items, schemas) ?? items,
|
|
242
|
+
pathParts: rest,
|
|
243
|
+
description,
|
|
244
|
+
schemas
|
|
245
|
+
});
|
|
253
246
|
return;
|
|
254
247
|
}
|
|
255
248
|
const propSchema = getPropertySchema(schema, head);
|
|
@@ -257,16 +250,14 @@ function setNestedDescription({ schema, pathParts, description, schemas }) {
|
|
|
257
250
|
if (rest.length === 0) setLeafDescription(propSchema, description);
|
|
258
251
|
else {
|
|
259
252
|
const target = getArrayItemsSchema(propSchema) ?? propSchema;
|
|
260
|
-
const resolvedTarget = resolveSchemaRef(target, schemas) ?? target;
|
|
261
253
|
setNestedDescription({
|
|
262
|
-
schema:
|
|
254
|
+
schema: resolveSchemaRef(target, schemas) ?? target,
|
|
263
255
|
pathParts: rest,
|
|
264
256
|
description,
|
|
265
257
|
schemas
|
|
266
258
|
});
|
|
267
259
|
}
|
|
268
260
|
}
|
|
269
|
-
|
|
270
261
|
//#endregion
|
|
271
262
|
//#region src/generate.ts
|
|
272
263
|
const PRIMITIVE_FLAGS = ts.TypeFlags.String | ts.TypeFlags.Number | ts.TypeFlags.Boolean | ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral | ts.TypeFlags.BooleanLiteral;
|
|
@@ -279,6 +270,29 @@ function isPrimitive(type) {
|
|
|
279
270
|
function isObjectType(type) {
|
|
280
271
|
return hasFlag(type, ts.TypeFlags.Object);
|
|
281
272
|
}
|
|
273
|
+
const STANDARD_FUNCTION_INTERFACES = /* @__PURE__ */ new Set([
|
|
274
|
+
"Function",
|
|
275
|
+
"CallableFunction",
|
|
276
|
+
"NewableFunction"
|
|
277
|
+
]);
|
|
278
|
+
function isStandardFunctionInterface(type) {
|
|
279
|
+
const symbol = type.getSymbol();
|
|
280
|
+
const name = symbol?.getName();
|
|
281
|
+
if (!name || !STANDARD_FUNCTION_INTERFACES.has(name)) return false;
|
|
282
|
+
return symbol?.declarations?.some((d) => /(^|[\\/])lib\.[^\\/]*\.d\.ts$/.test(d.getSourceFile().fileName)) ?? false;
|
|
283
|
+
}
|
|
284
|
+
function isFunctionType(type) {
|
|
285
|
+
return type.getCallSignatures().length > 0 || type.getConstructSignatures().length > 0 || isStandardFunctionInterface(type);
|
|
286
|
+
}
|
|
287
|
+
function hasFunctionMember(type) {
|
|
288
|
+
if (isFunctionType(type)) return true;
|
|
289
|
+
return type.isUnion() && type.types.some(isFunctionType);
|
|
290
|
+
}
|
|
291
|
+
function isUnserialisableType(type) {
|
|
292
|
+
if (isFunctionType(type)) return true;
|
|
293
|
+
if (!type.isUnion() || !type.types.some(isFunctionType)) return false;
|
|
294
|
+
return !type.types.some((m) => !isFunctionType(m) && !hasFlag(m, ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null));
|
|
295
|
+
}
|
|
282
296
|
function isOptionalSymbol(sym) {
|
|
283
297
|
return (sym.flags & ts.SymbolFlags.Optional) !== 0;
|
|
284
298
|
}
|
|
@@ -294,7 +308,7 @@ function unwrapBrand(type) {
|
|
|
294
308
|
if (first && hasObject) return first;
|
|
295
309
|
return type;
|
|
296
310
|
}
|
|
297
|
-
const ANONYMOUS_NAMES = new Set([
|
|
311
|
+
const ANONYMOUS_NAMES = /* @__PURE__ */ new Set([
|
|
298
312
|
"__type",
|
|
299
313
|
"__object",
|
|
300
314
|
"Object",
|
|
@@ -353,8 +367,8 @@ function typeToJsonSchema(type, ctx, depth = 0) {
|
|
|
353
367
|
const storedSchema = ctx.schemas[existingRef];
|
|
354
368
|
if (storedSchema && (isNonEmptySchema(storedSchema) || ctx.visited.has(type))) return schemaRef(existingRef);
|
|
355
369
|
ctx.schemas[existingRef] = storedSchema ?? {};
|
|
356
|
-
const schema
|
|
357
|
-
if (!isSelfSchemaRef(schema
|
|
370
|
+
const schema = convertTypeToSchema(type, ctx, depth);
|
|
371
|
+
if (!isSelfSchemaRef(schema, existingRef)) ctx.schemas[existingRef] = schema;
|
|
358
372
|
return schemaRef(existingRef);
|
|
359
373
|
}
|
|
360
374
|
const schema = convertTypeToSchema(type, ctx, depth);
|
|
@@ -377,8 +391,7 @@ function typeToJsonSchema(type, ctx, depth = 0) {
|
|
|
377
391
|
function handleCyclicRef(type, ctx) {
|
|
378
392
|
let refName = ctx.typeToRef.get(type);
|
|
379
393
|
if (!refName) {
|
|
380
|
-
|
|
381
|
-
refName = ensureUniqueName(name, ctx.schemas);
|
|
394
|
+
refName = ensureUniqueName(getTypeName(type) ?? "RecursiveType", ctx.schemas);
|
|
382
395
|
ctx.typeToRef.set(type, refName);
|
|
383
396
|
ctx.schemas[refName] = {};
|
|
384
397
|
}
|
|
@@ -405,18 +418,14 @@ function convertPrimitiveOrLiteral(type, flags, checker) {
|
|
|
405
418
|
type: "number",
|
|
406
419
|
const: type.value
|
|
407
420
|
};
|
|
408
|
-
if (flags & ts.TypeFlags.BooleanLiteral) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
const: isTrue
|
|
413
|
-
};
|
|
414
|
-
}
|
|
421
|
+
if (flags & ts.TypeFlags.BooleanLiteral) return {
|
|
422
|
+
type: "boolean",
|
|
423
|
+
const: checker.typeToString(type) === "true"
|
|
424
|
+
};
|
|
415
425
|
return null;
|
|
416
426
|
}
|
|
417
427
|
function convertUnionType(type, ctx, depth) {
|
|
418
|
-
const
|
|
419
|
-
const defined = members.filter((m) => !hasFlag(m, ts.TypeFlags.Undefined | ts.TypeFlags.Void));
|
|
428
|
+
const defined = type.types.filter((m) => !hasFlag(m, ts.TypeFlags.Undefined | ts.TypeFlags.Void) && !isFunctionType(m));
|
|
420
429
|
if (defined.length === 0) return {};
|
|
421
430
|
const hasNull = defined.some((m) => hasFlag(m, ts.TypeFlags.Null));
|
|
422
431
|
const nonNull = defined.filter((m) => !hasFlag(m, ts.TypeFlags.Null));
|
|
@@ -450,13 +459,9 @@ function detectDiscriminatorProperty(schemas) {
|
|
|
450
459
|
const first = schemas[0];
|
|
451
460
|
if (!first?.properties) return null;
|
|
452
461
|
const firstProps = Object.keys(first.properties);
|
|
453
|
-
for (const prop of firstProps) {
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
return propSchema !== void 0 && propSchema.const !== void 0 && s.required?.includes(prop);
|
|
457
|
-
});
|
|
458
|
-
if (allHaveConst) return prop;
|
|
459
|
-
}
|
|
462
|
+
for (const prop of firstProps) if (schemas.every((s) => {
|
|
463
|
+
return (s.properties?.[prop])?.const !== void 0 && s.required?.includes(prop);
|
|
464
|
+
})) return prop;
|
|
460
465
|
return null;
|
|
461
466
|
}
|
|
462
467
|
/** A schema that is just `{ type: "somePrimitive" }` with no other keys. */
|
|
@@ -470,14 +475,12 @@ function isSimpleTypeSchema(s) {
|
|
|
470
475
|
*/
|
|
471
476
|
function tryCollapseLiteralUnion(nonNull, hasNull) {
|
|
472
477
|
if (nonNull.length <= 1) return null;
|
|
473
|
-
|
|
474
|
-
if (!allLiterals) return null;
|
|
478
|
+
if (!nonNull.every((m) => hasFlag(m, ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral))) return null;
|
|
475
479
|
const [first] = nonNull;
|
|
476
480
|
if (!first) return null;
|
|
477
481
|
const isString = hasFlag(first, ts.TypeFlags.StringLiteral);
|
|
478
482
|
const targetFlag = isString ? ts.TypeFlags.StringLiteral : ts.TypeFlags.NumberLiteral;
|
|
479
|
-
|
|
480
|
-
if (!allSameKind) return null;
|
|
483
|
+
if (!nonNull.every((m) => hasFlag(m, targetFlag))) return null;
|
|
481
484
|
const values = nonNull.map((m) => isString ? m.value : m.value);
|
|
482
485
|
const baseType = isString ? "string" : "number";
|
|
483
486
|
return {
|
|
@@ -486,9 +489,7 @@ function tryCollapseLiteralUnion(nonNull, hasNull) {
|
|
|
486
489
|
};
|
|
487
490
|
}
|
|
488
491
|
function convertIntersectionType(type, ctx, depth) {
|
|
489
|
-
const
|
|
490
|
-
const nonBrand = hasPrimitiveMember ? type.types.filter((m) => !isObjectType(m)) : type.types;
|
|
491
|
-
const schemas = nonBrand.map((m) => typeToJsonSchema(m, ctx, depth + 1)).filter(isNonEmptySchema);
|
|
492
|
+
const schemas = (type.types.some(isPrimitive) ? type.types.filter((m) => !isObjectType(m)) : type.types).map((m) => typeToJsonSchema(m, ctx, depth + 1)).filter(isNonEmptySchema);
|
|
492
493
|
if (schemas.length === 0) return {};
|
|
493
494
|
const [onlySchema] = schemas;
|
|
494
495
|
if (schemas.length === 1 && onlySchema !== void 0) return onlySchema;
|
|
@@ -547,10 +548,9 @@ function convertArrayType(type, ctx, depth) {
|
|
|
547
548
|
}
|
|
548
549
|
function convertTupleType(type, ctx, depth) {
|
|
549
550
|
const args = ctx.checker.getTypeArguments(type);
|
|
550
|
-
const schemas = args.map((a) => typeToJsonSchema(a, ctx, depth + 1));
|
|
551
551
|
return {
|
|
552
552
|
type: "array",
|
|
553
|
-
prefixItems:
|
|
553
|
+
prefixItems: args.map((a) => typeToJsonSchema(a, ctx, depth + 1)),
|
|
554
554
|
items: false,
|
|
555
555
|
minItems: args.length,
|
|
556
556
|
maxItems: args.length
|
|
@@ -566,8 +566,7 @@ function convertPlainObject(type, ctx, depth) {
|
|
|
566
566
|
};
|
|
567
567
|
let autoRegName = null;
|
|
568
568
|
const tsName = getTypeName(type);
|
|
569
|
-
|
|
570
|
-
if (isNamedUnregisteredType) {
|
|
569
|
+
if (tsName !== null && typeProps.length > 0 && !ctx.typeToRef.has(type)) {
|
|
571
570
|
autoRegName = ensureUniqueName(tsName, ctx.schemas);
|
|
572
571
|
ctx.typeToRef.set(type, autoRegName);
|
|
573
572
|
ctx.schemas[autoRegName] = {};
|
|
@@ -578,18 +577,19 @@ function convertPlainObject(type, ctx, depth) {
|
|
|
578
577
|
for (const prop of typeProps) {
|
|
579
578
|
if (shouldSkipPropertySymbol(prop)) continue;
|
|
580
579
|
const propType = checker.getTypeOfSymbol(prop);
|
|
580
|
+
if (isUnserialisableType(propType)) continue;
|
|
581
581
|
const propSchema = typeToJsonSchema(propType, ctx, depth + 1);
|
|
582
582
|
const jsDoc = getJsDocComment(prop, checker);
|
|
583
583
|
if (jsDoc && !propSchema.description && !propSchema.$ref) propSchema.description = jsDoc;
|
|
584
584
|
properties[prop.name] = propSchema;
|
|
585
|
-
if (!isOptionalSymbol(prop)) required.push(prop.name);
|
|
585
|
+
if (!isOptionalSymbol(prop) && !hasFunctionMember(propType)) required.push(prop.name);
|
|
586
586
|
}
|
|
587
587
|
ctx.visited.delete(type);
|
|
588
588
|
const result = { type: "object" };
|
|
589
589
|
if (Object.keys(properties).length > 0) result.properties = properties;
|
|
590
590
|
if (required.length > 0) result.required = required;
|
|
591
591
|
if (stringIndexType) result.additionalProperties = typeToJsonSchema(stringIndexType, ctx, depth + 1);
|
|
592
|
-
else if (
|
|
592
|
+
else if (typeProps.length > 0) result.additionalProperties = false;
|
|
593
593
|
const registeredName = autoRegName ?? ctx.typeToRef.get(type);
|
|
594
594
|
if (registeredName) {
|
|
595
595
|
ctx.schemas[registeredName] = result;
|
|
@@ -607,8 +607,7 @@ function convertObjectType(type, ctx, depth) {
|
|
|
607
607
|
/** Core type-to-schema conversion (no ref handling). */
|
|
608
608
|
function convertTypeToSchema(type, ctx, depth) {
|
|
609
609
|
if (ctx.visited.has(type)) return handleCyclicRef(type, ctx);
|
|
610
|
-
const
|
|
611
|
-
const primitive = convertPrimitiveOrLiteral(type, flags, ctx.checker);
|
|
610
|
+
const primitive = convertPrimitiveOrLiteral(type, type.getFlags(), ctx.checker);
|
|
612
611
|
if (primitive) return primitive;
|
|
613
612
|
if (type.isUnion()) {
|
|
614
613
|
ctx.visited.add(type);
|
|
@@ -622,6 +621,7 @@ function convertTypeToSchema(type, ctx, depth) {
|
|
|
622
621
|
ctx.visited.delete(type);
|
|
623
622
|
return result;
|
|
624
623
|
}
|
|
624
|
+
if (isFunctionType(type)) return {};
|
|
625
625
|
if (isObjectType(type)) return convertObjectType(type, ctx, depth);
|
|
626
626
|
return {};
|
|
627
627
|
}
|
|
@@ -639,23 +639,20 @@ function getProcedureTypeName(defType, checker) {
|
|
|
639
639
|
}
|
|
640
640
|
function isVoidLikeInput(inputType) {
|
|
641
641
|
if (!inputType) return true;
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
const isUnionOfVoids = inputType.isUnion() && inputType.types.every((t) => hasFlag(t, ts.TypeFlags.Void | ts.TypeFlags.Undefined));
|
|
645
|
-
return isUnionOfVoids;
|
|
642
|
+
if (hasFlag(inputType, ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never)) return true;
|
|
643
|
+
return inputType.isUnion() && inputType.types.every((t) => hasFlag(t, ts.TypeFlags.Void | ts.TypeFlags.Undefined));
|
|
646
644
|
}
|
|
647
645
|
function shouldIncludeProcedureInOpenAPI(type) {
|
|
648
646
|
return type !== "subscription";
|
|
649
647
|
}
|
|
650
|
-
function getProcedureInputTypeName(type, path
|
|
648
|
+
function getProcedureInputTypeName(type, path) {
|
|
651
649
|
const directName = getTypeName(type);
|
|
652
650
|
if (directName) return directName;
|
|
653
651
|
for (const sym of [type.aliasSymbol, type.getSymbol()].filter((candidate) => !!candidate)) for (const declaration of sym.declarations ?? []) {
|
|
654
652
|
const declarationName = ts.getNameOfDeclaration(declaration)?.getText();
|
|
655
653
|
if (declarationName && !ANONYMOUS_NAMES.has(declarationName) && !declarationName.startsWith("__")) return declarationName;
|
|
656
654
|
}
|
|
657
|
-
|
|
658
|
-
return `${fallbackName || "Procedure"}Input`;
|
|
655
|
+
return `${path.split(".").filter(Boolean).map((segment) => segment.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")).join("") || "Procedure"}Input`;
|
|
659
656
|
}
|
|
660
657
|
function isUnknownLikeType(type) {
|
|
661
658
|
return hasFlag(type, ts.TypeFlags.Unknown | ts.TypeFlags.Any);
|
|
@@ -685,14 +682,11 @@ function recoverProcedureInputType(def, checker) {
|
|
|
685
682
|
if (callee.name.text !== "input") return;
|
|
686
683
|
const [parserExpr] = expr.arguments;
|
|
687
684
|
if (!parserExpr) return;
|
|
688
|
-
const
|
|
689
|
-
const standardSym = parserType.getProperty("~standard");
|
|
685
|
+
const standardSym = checker.getTypeAtLocation(parserExpr).getProperty("~standard");
|
|
690
686
|
if (!standardSym) return;
|
|
691
|
-
const
|
|
692
|
-
const typesSym = standardType.getProperty("types");
|
|
687
|
+
const typesSym = checker.getTypeOfSymbolAtLocation(standardSym, parserExpr).getProperty("types");
|
|
693
688
|
if (!typesSym) return;
|
|
694
|
-
const
|
|
695
|
-
const outputSym = typesType.getProperty("output");
|
|
689
|
+
const outputSym = checker.getNonNullableType(checker.getTypeOfSymbolAtLocation(typesSym, parserExpr)).getProperty("output");
|
|
696
690
|
if (!outputSym) return;
|
|
697
691
|
const outputType = checker.getTypeOfSymbolAtLocation(outputSym, parserExpr);
|
|
698
692
|
if (!isUnknownLikeType(outputType)) recovered = outputType;
|
|
@@ -746,22 +740,18 @@ function extractProcedure(def, ctx) {
|
|
|
746
740
|
function getJsDocComment(sym, checker) {
|
|
747
741
|
const normalize = (filePath) => filePath.replace(/\\/g, "/");
|
|
748
742
|
const declarations = sym.declarations ?? [];
|
|
749
|
-
|
|
743
|
+
if (declarations.length > 0 && declarations.every((declaration) => {
|
|
750
744
|
const sourceFile = declaration.getSourceFile();
|
|
751
745
|
if (!sourceFile.isDeclarationFile) return false;
|
|
752
|
-
|
|
753
|
-
if (!declarationPath.includes("/node_modules/")) return false;
|
|
746
|
+
if (!normalize(sourceFile.fileName).includes("/node_modules/")) return false;
|
|
754
747
|
try {
|
|
755
|
-
|
|
756
|
-
if (!realPath.includes("/node_modules/")) return false;
|
|
748
|
+
if (!normalize(fs.realpathSync.native(sourceFile.fileName)).includes("/node_modules/")) return false;
|
|
757
749
|
} catch {}
|
|
758
750
|
return true;
|
|
759
|
-
});
|
|
760
|
-
if (isExternalNodeModulesDeclaration) return void 0;
|
|
751
|
+
})) return;
|
|
761
752
|
const parts = sym.getDocumentationComment(checker);
|
|
762
|
-
if (parts.length === 0) return
|
|
763
|
-
|
|
764
|
-
return text || void 0;
|
|
753
|
+
if (parts.length === 0) return;
|
|
754
|
+
return parts.map((p) => p.text).join("") || void 0;
|
|
765
755
|
}
|
|
766
756
|
function walkType(opts) {
|
|
767
757
|
const { type, ctx, currentPath, description, symbol } = opts;
|
|
@@ -791,28 +781,21 @@ function walkType(opts) {
|
|
|
791
781
|
}
|
|
792
782
|
const routerSym = defType.getProperty("router");
|
|
793
783
|
if (!routerSym) return;
|
|
794
|
-
|
|
795
|
-
if (!isRouter) return;
|
|
784
|
+
if (!(checker.typeToString(checker.getTypeOfSymbol(routerSym)) === "true")) return;
|
|
796
785
|
const recordSym = defType.getProperty("record");
|
|
797
786
|
if (!recordSym) return;
|
|
798
787
|
ctx.seen.add(type);
|
|
799
|
-
|
|
800
|
-
walkRecord(recordType, ctx, currentPath);
|
|
788
|
+
walkRecord(checker.getTypeOfSymbol(recordSym), ctx, currentPath);
|
|
801
789
|
ctx.seen.delete(type);
|
|
802
790
|
}
|
|
803
791
|
function walkRecord(recordType, ctx, prefix) {
|
|
804
|
-
for (const prop of recordType.getProperties()) {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
currentPath: fullPath,
|
|
812
|
-
description,
|
|
813
|
-
symbol: prop
|
|
814
|
-
});
|
|
815
|
-
}
|
|
792
|
+
for (const prop of recordType.getProperties()) walkType({
|
|
793
|
+
type: ctx.schemaCtx.checker.getTypeOfSymbol(prop),
|
|
794
|
+
ctx,
|
|
795
|
+
currentPath: prefix ? `${prefix}.${prop.name}` : prop.name,
|
|
796
|
+
description: getJsDocComment(prop, ctx.schemaCtx.checker),
|
|
797
|
+
symbol: prop
|
|
798
|
+
});
|
|
816
799
|
}
|
|
817
800
|
function loadCompilerOptions(startDir) {
|
|
818
801
|
const configPath = ts.findConfigFile(startDir, (f) => ts.sys.fileExists(f), "tsconfig.json");
|
|
@@ -823,9 +806,8 @@ function loadCompilerOptions(startDir) {
|
|
|
823
806
|
noEmit: true
|
|
824
807
|
};
|
|
825
808
|
const configFile = ts.readConfigFile(configPath, (f) => ts.sys.readFile(f));
|
|
826
|
-
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path$1.dirname(configPath));
|
|
827
809
|
const options = {
|
|
828
|
-
...
|
|
810
|
+
...ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath)).options,
|
|
829
811
|
noEmit: true
|
|
830
812
|
};
|
|
831
813
|
if (options.moduleResolution === void 0) {
|
|
@@ -880,14 +862,13 @@ const DEFAULT_ERROR_SCHEMA = {
|
|
|
880
862
|
*/
|
|
881
863
|
function wrapInSuccessEnvelope(outputSchema) {
|
|
882
864
|
const hasOutput = outputSchema !== null && isNonEmptySchema(outputSchema);
|
|
883
|
-
const resultSchema = {
|
|
884
|
-
type: "object",
|
|
885
|
-
properties: { ...hasOutput ? { data: outputSchema } : {} },
|
|
886
|
-
...hasOutput ? { required: ["data"] } : {}
|
|
887
|
-
};
|
|
888
865
|
return {
|
|
889
866
|
type: "object",
|
|
890
|
-
properties: { result:
|
|
867
|
+
properties: { result: {
|
|
868
|
+
type: "object",
|
|
869
|
+
properties: { ...hasOutput ? { data: outputSchema } : {} },
|
|
870
|
+
...hasOutput ? { required: ["data"] } : {}
|
|
871
|
+
} },
|
|
891
872
|
required: ["result"]
|
|
892
873
|
};
|
|
893
874
|
}
|
|
@@ -961,9 +942,9 @@ function buildOpenAPIDocument(procedures, options, meta = { errorSchema: null })
|
|
|
961
942
|
* @param options - Optional generation settings (export name, title, version).
|
|
962
943
|
*/
|
|
963
944
|
async function generateOpenAPIDocument(routerFilePath, options = {}) {
|
|
964
|
-
const resolvedPath = path
|
|
945
|
+
const resolvedPath = path.resolve(routerFilePath);
|
|
965
946
|
const exportName = options.exportName ?? "AppRouter";
|
|
966
|
-
const compilerOptions = loadCompilerOptions(path
|
|
947
|
+
const compilerOptions = loadCompilerOptions(path.dirname(resolvedPath));
|
|
967
948
|
const program = ts.createProgram([resolvedPath], compilerOptions);
|
|
968
949
|
const checker = program.getTypeChecker();
|
|
969
950
|
const sourceFile = program.getSourceFile(resolvedPath);
|
|
@@ -1005,9 +986,23 @@ async function generateOpenAPIDocument(routerFilePath, options = {}) {
|
|
|
1005
986
|
schemas: schemaCtx.schemas
|
|
1006
987
|
});
|
|
1007
988
|
}
|
|
1008
|
-
|
|
1009
989
|
//#endregion
|
|
1010
990
|
//#region src/cli.ts
|
|
991
|
+
/**
|
|
992
|
+
* trpc-openapi – CLI that generates an OpenAPI 3.1 document from a tRPC
|
|
993
|
+
* AppRouter type.
|
|
994
|
+
*
|
|
995
|
+
* Usage:
|
|
996
|
+
* trpc-openapi <router-file> [options]
|
|
997
|
+
*
|
|
998
|
+
* Options:
|
|
999
|
+
* --export, -e Name of the exported router symbol (default: AppRouter)
|
|
1000
|
+
* --output, -o Output file path (default: openapi.json)
|
|
1001
|
+
* --title OpenAPI info.title (default: tRPC API)
|
|
1002
|
+
* --version OpenAPI info.version (default: 0.0.0)
|
|
1003
|
+
* --server-url OpenAPI servers[].url (include any tRPC prefix)
|
|
1004
|
+
* --help, -h Show this help message
|
|
1005
|
+
*/
|
|
1011
1006
|
function parseArgs$1(argv) {
|
|
1012
1007
|
let parsed;
|
|
1013
1008
|
try {
|
|
@@ -1116,5 +1111,5 @@ async function main() {
|
|
|
1116
1111
|
console.log(`OpenAPI document written to: ${outputPath}`);
|
|
1117
1112
|
}
|
|
1118
1113
|
main();
|
|
1119
|
-
|
|
1120
|
-
|
|
1114
|
+
//#endregion
|
|
1115
|
+
export {};
|
package/dist/heyapi/index.cjs
CHANGED
|
@@ -1,39 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//#region
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
t[n] = r[n];
|
|
11
|
-
}
|
|
12
|
-
return t;
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objectSpread2 = require("../objectSpread2-C2ceYbQe.cjs");
|
|
3
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/objectWithoutPropertiesLoose.js
|
|
4
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
5
|
+
if (null == r) return {};
|
|
6
|
+
var t = {};
|
|
7
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
8
|
+
if (e.includes(n)) continue;
|
|
9
|
+
t[n] = r[n];
|
|
13
10
|
}
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
11
|
+
return t;
|
|
12
|
+
}
|
|
17
13
|
//#endregion
|
|
18
|
-
//#region
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
var s = Object.getOwnPropertySymbols(e);
|
|
26
|
-
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
27
|
-
}
|
|
28
|
-
return i;
|
|
14
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/objectWithoutProperties.js
|
|
15
|
+
function _objectWithoutProperties(e, t) {
|
|
16
|
+
if (null == e) return {};
|
|
17
|
+
var o, r, i = _objectWithoutPropertiesLoose(e, t);
|
|
18
|
+
if (Object.getOwnPropertySymbols) {
|
|
19
|
+
var s = Object.getOwnPropertySymbols(e);
|
|
20
|
+
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
29
21
|
}
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
22
|
+
return i;
|
|
23
|
+
}
|
|
33
24
|
//#endregion
|
|
34
25
|
//#region src/heyapi/index.ts
|
|
35
|
-
var import_objectSpread2 = require_objectSpread2$1.__toESM(require_objectSpread2$1.require_objectSpread2(), 1);
|
|
36
|
-
var import_objectWithoutProperties = require_objectSpread2$1.__toESM(require_objectWithoutProperties(), 1);
|
|
37
26
|
const _excluded = ["transformer"];
|
|
38
27
|
function resolveTransformer(transformer) {
|
|
39
28
|
if ("input" in transformer) return transformer;
|
|
@@ -64,11 +53,9 @@ function createTRPCHeyApiTypeResolvers() {
|
|
|
64
53
|
return {
|
|
65
54
|
string(ctx) {
|
|
66
55
|
if (ctx.schema.format === "date-time" || ctx.schema.format === "date") return ctx.$.type("Date");
|
|
67
|
-
return void 0;
|
|
68
56
|
},
|
|
69
57
|
number(ctx) {
|
|
70
58
|
if (ctx.schema.format === "bigint") return ctx.$.type("bigint");
|
|
71
|
-
return void 0;
|
|
72
59
|
}
|
|
73
60
|
};
|
|
74
61
|
}
|
|
@@ -77,7 +64,7 @@ function createTRPCHeyApiTypeResolvers() {
|
|
|
77
64
|
*/
|
|
78
65
|
function createTRPCHeyApiClientConfig(opts) {
|
|
79
66
|
const transformer = (opts === null || opts === void 0 ? void 0 : opts.transformer) ? resolveTransformer(opts.transformer) : void 0;
|
|
80
|
-
return
|
|
67
|
+
return require_objectSpread2._objectSpread2({ querySerializer: (query) => {
|
|
81
68
|
const params = new URLSearchParams();
|
|
82
69
|
for (const [key, value] of Object.entries(query)) {
|
|
83
70
|
if (value === void 0) continue;
|
|
@@ -128,14 +115,13 @@ function createTRPCErrorInterceptor(transformerOpts) {
|
|
|
128
115
|
* ```
|
|
129
116
|
*/
|
|
130
117
|
function configureTRPCHeyApiClient(client, opts) {
|
|
131
|
-
const { transformer } = opts, heyConfig = (
|
|
118
|
+
const { transformer } = opts, heyConfig = _objectWithoutProperties(opts, _excluded);
|
|
132
119
|
const trpcConfig = createTRPCHeyApiClientConfig({ transformer });
|
|
133
|
-
client.setConfig(
|
|
120
|
+
client.setConfig(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, heyConfig), trpcConfig));
|
|
134
121
|
if (transformer) client.interceptors.error.use(createTRPCErrorInterceptor(transformer));
|
|
135
122
|
}
|
|
136
|
-
|
|
137
123
|
//#endregion
|
|
138
124
|
exports.configureTRPCHeyApiClient = configureTRPCHeyApiClient;
|
|
139
125
|
exports.createTRPCErrorInterceptor = createTRPCErrorInterceptor;
|
|
140
126
|
exports.createTRPCHeyApiClientConfig = createTRPCHeyApiClientConfig;
|
|
141
|
-
exports.createTRPCHeyApiTypeResolvers = createTRPCHeyApiTypeResolvers;
|
|
127
|
+
exports.createTRPCHeyApiTypeResolvers = createTRPCHeyApiTypeResolvers;
|
package/dist/heyapi/index.d.cts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { Plugins } from "@hey-api/openapi-ts";
|
|
2
2
|
import { TRPCCombinedDataTransformer, TRPCDataTransformer } from "@trpc/server";
|
|
3
|
-
|
|
4
3
|
//#region src/heyapi/index.d.ts
|
|
5
|
-
type DataTransformerOptions = TRPCDataTransformer | TRPCCombinedDataTransformer;
|
|
6
|
-
interface TRPCHeyApiClientOptions {
|
|
4
|
+
export type DataTransformerOptions = TRPCDataTransformer | TRPCCombinedDataTransformer;
|
|
5
|
+
export interface TRPCHeyApiClientOptions {
|
|
7
6
|
transformer?: DataTransformerOptions;
|
|
8
7
|
}
|
|
9
|
-
type HeyAPIResolvers = Plugins.HeyApiTypeScript.Resolvers;
|
|
10
|
-
type HeyApiConfig = ReturnType<Plugins.HeyApiClientFetch.Client['getConfig']>;
|
|
11
|
-
type TRPCHeyApiClientConfig = Required<Pick<HeyApiConfig, 'querySerializer'>> & Pick<HeyApiConfig, 'bodySerializer' | 'responseTransformer'>;
|
|
8
|
+
export type HeyAPIResolvers = Plugins.HeyApiTypeScript.Resolvers;
|
|
9
|
+
export type HeyApiConfig = ReturnType<Plugins.HeyApiClientFetch.Client['getConfig']>;
|
|
10
|
+
export type TRPCHeyApiClientConfig = Required<Pick<HeyApiConfig, 'querySerializer'>> & Pick<HeyApiConfig, 'bodySerializer' | 'responseTransformer'>;
|
|
12
11
|
/**
|
|
13
12
|
* Returns the `~resolvers` object for the `@hey-api/typescript` plugin.
|
|
14
13
|
*
|
|
@@ -27,11 +26,11 @@ type TRPCHeyApiClientConfig = Required<Pick<HeyApiConfig, 'querySerializer'>> &
|
|
|
27
26
|
* });
|
|
28
27
|
* ```
|
|
29
28
|
*/
|
|
30
|
-
declare function createTRPCHeyApiTypeResolvers(): HeyAPIResolvers;
|
|
29
|
+
export declare function createTRPCHeyApiTypeResolvers(): HeyAPIResolvers;
|
|
31
30
|
/**
|
|
32
31
|
* @internal - Prefer `configureTRPCHeyApiClient`
|
|
33
32
|
*/
|
|
34
|
-
declare function createTRPCHeyApiClientConfig(opts?: TRPCHeyApiClientOptions): {
|
|
33
|
+
export declare function createTRPCHeyApiClientConfig(opts?: TRPCHeyApiClientOptions): {
|
|
35
34
|
readonly bodySerializer?: ((body: unknown) => string) | undefined;
|
|
36
35
|
readonly responseTransformer?: ((data: unknown) => Promise<unknown>) | undefined;
|
|
37
36
|
readonly querySerializer: (query: Record<string, unknown>) => string;
|
|
@@ -39,7 +38,7 @@ declare function createTRPCHeyApiClientConfig(opts?: TRPCHeyApiClientOptions): {
|
|
|
39
38
|
/**
|
|
40
39
|
* @internal - Prefer `configureTRPCHeyApiClient`
|
|
41
40
|
*/
|
|
42
|
-
declare function createTRPCErrorInterceptor(transformerOpts: DataTransformerOptions): (error: unknown) => unknown;
|
|
41
|
+
export declare function createTRPCErrorInterceptor(transformerOpts: DataTransformerOptions): (error: unknown) => unknown;
|
|
43
42
|
/**
|
|
44
43
|
* Configures a hey-api client for use with a tRPC OpenAPI backend.
|
|
45
44
|
*
|
|
@@ -59,8 +58,6 @@ declare function createTRPCErrorInterceptor(transformerOpts: DataTransformerOpti
|
|
|
59
58
|
* });
|
|
60
59
|
* ```
|
|
61
60
|
*/
|
|
62
|
-
declare function configureTRPCHeyApiClient(client: Plugins.HeyApiClientFetch.Client, opts: TRPCHeyApiClientOptions & Omit<HeyApiConfig, keyof TRPCHeyApiClientConfig>): void;
|
|
63
|
-
//# sourceMappingURL=index.d.ts.map
|
|
61
|
+
export declare function configureTRPCHeyApiClient(client: Plugins.HeyApiClientFetch.Client, opts: TRPCHeyApiClientOptions & Omit<HeyApiConfig, keyof TRPCHeyApiClientConfig>): void;
|
|
64
62
|
//#endregion
|
|
65
|
-
export { DataTransformerOptions, HeyAPIResolvers, HeyApiConfig, TRPCHeyApiClientConfig, TRPCHeyApiClientOptions, configureTRPCHeyApiClient, createTRPCErrorInterceptor, createTRPCHeyApiClientConfig, createTRPCHeyApiTypeResolvers };
|
|
66
63
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/heyapi/index.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/heyapi/index.ts"],"mappings":";;;YAMY,yBACV,sBAAsB;iBACP;EACf,cAAc;;YAGJ,kBAAkB,QAAQ,iBAAiB;YAE3C,eAAe,WACzB,QAAQ,kBAAkB;YAGhB,yBAAyB,SACnC,KAAK,oCAEL,KAAK;;;;;;;;;;;;;;;;;;;wBA6BS,iCAAiC;;;;wBAoBjC,6BAA6B,OAAO;WA4BvB,mBAAA;WAIW,wBAAA,kBAAO;WA1BlB,kBAAA,OAAA;;;;;wBA2Cb,2BACd,iBAAiB,0BAGT;;;;;;;;;;;;;;;;;;;;wBA6BM,0BACd,QAAQ,QAAQ,kBAAkB,QAClC,MAAM,0BACJ,KAAK,oBAAoB"}
|