@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.
@@ -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$2 = prefix ? `${prefix}.${key}` : key;
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$2, description);
129
- walkZodShape(unwrappedField, path$2, ctx);
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
- const mod = await import(pathToFileURL(resolvedPath).href);
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
- const target = resolveSchemaRef(items, schemas) ?? items;
246
- setNestedDescription({
247
- schema: target,
248
- pathParts: rest,
249
- description,
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: resolvedTarget,
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$1 = convertTypeToSchema(type, ctx, depth);
357
- if (!isSelfSchemaRef(schema$1, existingRef)) ctx.schemas[existingRef] = schema$1;
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
- const name = getTypeName(type) ?? "RecursiveType";
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
- const isTrue = checker.typeToString(type) === "true";
410
- return {
411
- type: "boolean",
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 members = type.types;
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 allHaveConst = schemas.every((s) => {
455
- const propSchema = s.properties?.[prop];
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
- const allLiterals = nonNull.every((m) => hasFlag(m, ts.TypeFlags.StringLiteral | ts.TypeFlags.NumberLiteral));
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
- const allSameKind = nonNull.every((m) => hasFlag(m, targetFlag));
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 hasPrimitiveMember = type.types.some(isPrimitive);
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: schemas,
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
- const isNamedUnregisteredType = tsName !== null && typeProps.length > 0 && !ctx.typeToRef.has(type);
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 (Object.keys(properties).length > 0) result.additionalProperties = false;
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 flags = type.getFlags();
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
- const isVoidOrUndefinedOrNever = hasFlag(inputType, ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never);
643
- if (isVoidOrUndefinedOrNever) return true;
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$2) {
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
- const fallbackName = path$2.split(".").filter(Boolean).map((segment) => segment.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")).join("");
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 parserType = checker.getTypeAtLocation(parserExpr);
689
- const standardSym = parserType.getProperty("~standard");
685
+ const standardSym = checker.getTypeAtLocation(parserExpr).getProperty("~standard");
690
686
  if (!standardSym) return;
691
- const standardType = checker.getTypeOfSymbolAtLocation(standardSym, parserExpr);
692
- const typesSym = standardType.getProperty("types");
687
+ const typesSym = checker.getTypeOfSymbolAtLocation(standardSym, parserExpr).getProperty("types");
693
688
  if (!typesSym) return;
694
- const typesType = checker.getNonNullableType(checker.getTypeOfSymbolAtLocation(typesSym, parserExpr));
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
- const isExternalNodeModulesDeclaration = declarations.length > 0 && declarations.every((declaration) => {
743
+ if (declarations.length > 0 && declarations.every((declaration) => {
750
744
  const sourceFile = declaration.getSourceFile();
751
745
  if (!sourceFile.isDeclarationFile) return false;
752
- const declarationPath = normalize(sourceFile.fileName);
753
- if (!declarationPath.includes("/node_modules/")) return false;
746
+ if (!normalize(sourceFile.fileName).includes("/node_modules/")) return false;
754
747
  try {
755
- const realPath = normalize(fs$1.realpathSync.native(sourceFile.fileName));
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 void 0;
763
- const text = parts.map((p) => p.text).join("");
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
- const isRouter = checker.typeToString(checker.getTypeOfSymbol(routerSym)) === "true";
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
- const recordType = checker.getTypeOfSymbol(recordSym);
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
- const propType = ctx.schemaCtx.checker.getTypeOfSymbol(prop);
806
- const fullPath = prefix ? `${prefix}.${prop.name}` : prop.name;
807
- const description = getJsDocComment(prop, ctx.schemaCtx.checker);
808
- walkType({
809
- type: propType,
810
- ctx,
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
- ...parsed.options,
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: resultSchema },
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$1.resolve(routerFilePath);
945
+ const resolvedPath = path.resolve(routerFilePath);
965
946
  const exportName = options.exportName ?? "AppRouter";
966
- const compilerOptions = loadCompilerOptions(path$1.dirname(resolvedPath));
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
- //#endregion
1114
+ //#endregion
1115
+ export {};
@@ -1,39 +1,28 @@
1
- const require_objectSpread2$1 = require('../objectSpread2-Cw30I7tb.cjs');
2
-
3
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutPropertiesLoose.js
4
- var require_objectWithoutPropertiesLoose = require_objectSpread2$1.__commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutPropertiesLoose.js"(exports, module) {
5
- function _objectWithoutPropertiesLoose(r, e) {
6
- if (null == r) return {};
7
- var t = {};
8
- for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
9
- if (e.includes(n)) continue;
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
- module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports;
15
- } });
16
-
11
+ return t;
12
+ }
17
13
  //#endregion
18
- //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutProperties.js
19
- var require_objectWithoutProperties = require_objectSpread2$1.__commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutProperties.js"(exports, module) {
20
- var objectWithoutPropertiesLoose = require_objectWithoutPropertiesLoose();
21
- function _objectWithoutProperties$1(e, t) {
22
- if (null == e) return {};
23
- var o, r, i = objectWithoutPropertiesLoose(e, t);
24
- if (Object.getOwnPropertySymbols) {
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
- module.exports = _objectWithoutProperties$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
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 (0, import_objectSpread2.default)({ querySerializer: (query) => {
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 = (0, import_objectWithoutProperties.default)(opts, _excluded);
118
+ const { transformer } = opts, heyConfig = _objectWithoutProperties(opts, _excluded);
132
119
  const trpcConfig = createTRPCHeyApiClientConfig({ transformer });
133
- client.setConfig((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, heyConfig), trpcConfig));
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;
@@ -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"],"sourcesContent":[],"mappings":";;;;KAMY,sBAAA,GACR,sBACA;UACa,uBAAA;EAHL,WAAA,CAAA,EAII,sBAJkB;;AAC9B,KAMQ,eAAA,GAAkB,OAAA,CAAQ,gBAAA,CAAiB,SANnD;AACA,KAOQ,YAAA,GAAe,UAPvB,CAQF,OAAA,CAAQ,iBAAA,CAAkB,MARxB,CAAA,WAAA,CAAA,CAAA;AAA2B,KAWnB,sBAAA,GAAyB,QAXN,CAY7B,IAZ6B,CAYxB,YAZwB,EAAA,iBAAA,CAAA,CAAA,GAc7B,IAd6B,CAcxB,YAdwB,EAAA,gBAAA,GAAA,qBAAA,CAAA;AAC/B;AAIA;AAEA;;;;AAAqC;AAIrC;;;;;;;AAGM;AA6BN;AAoBA;;AAAoD,iBApBpC,6BAAA,CAAA,CAoBoC,EApBH,eAoBG;;;AAMjB;AA2CnB,iBAjDA,4BAAA,CAkDG,IAAsB,CAAtB,EAlDiC,uBAkDX,CAAA,EAAA;EAgCzB,SAAA,cAAA,CAAA,EAAA,CAAA,CAAyB,IAAA,EAAA,OAAA,EAAA,GAAA,MAAA,CAAA,GAAA,SAAA;EAAA,SAAA,mBAAA,CAAA,EAAA,CAAA,CAAA,IAAA,EAAA,OAAA,EAAA,GAlDM,OAkDN,CAAA,OAAA,CAAA,CAAA,GAAA,SAAA;EAAA,SAC/B,eAAQ,EAAA,CAAA,KAAkB,EA7EP,MA6EO,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAAA,MAAA;CAAM;;;;AAElC,iBApCQ,0BAAA,CAoCR,eAAA,EAnCW,sBAmCX,CAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,GAAA,OAAA;;;;;;;;;;;;;;;;;;;;iBAHQ,yBAAA,SACN,OAAA,CAAQ,iBAAA,CAAkB,cAC5B,0BACJ,KAAK,oBAAoB"}
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"}