@sdk-it/core 0.39.0 → 0.41.0

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.
@@ -3,11 +3,19 @@ type Collector = Record<string, any>;
3
3
  export declare const deriveSymbol: unique symbol;
4
4
  export declare const $types: unique symbol;
5
5
  export declare const defaultTypesMap: Record<string, string>;
6
+ export declare function nodeLocation(node: ts.Node): string | undefined;
6
7
  export declare class TypeDeriver {
7
8
  readonly collector: Collector;
8
9
  readonly checker: ts.TypeChecker;
9
10
  readonly typesMap: Record<string, string>;
11
+ private trace;
12
+ private currentNode?;
10
13
  constructor(checker: ts.TypeChecker, typeMappings?: Record<string, string>);
14
+ setTrace(ctx: {
15
+ file?: string;
16
+ operation?: string;
17
+ }): void;
18
+ private warn;
11
19
  serializeType(type: ts.Type): any;
12
20
  serializeNode(node: ts.Node): any;
13
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deriver.d.ts","sourceRoot":"","sources":["../../src/lib/deriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,MAAM,YAAY,CAAC;AAKvD,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErC,eAAO,MAAM,YAAY,eAA0B,CAAC;AACpD,eAAO,MAAM,MAAM,eAAsB,CAAC;AAC1C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQlD,CAAC;AACF,qBAAa,WAAW;IACtB,SAAgB,SAAS,EAAE,SAAS,CAAM;IAC1C,SAAgB,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC;IACxC,SAAgB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAE/C,OAAO,EAAE,EAAE,CAAC,WAAW,EACvB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmB;IAMxD,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG;IAiSjC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG;CA8QlC"}
1
+ {"version":3,"file":"deriver.d.ts","sourceRoot":"","sources":["../../src/lib/deriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,MAAM,YAAY,CAAC;AAKvD,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErC,eAAO,MAAM,YAAY,eAA0B,CAAC;AACpD,eAAO,MAAM,MAAM,eAAsB,CAAC;AAC1C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQlD,CAAC;AAOF,wBAAgB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,GAAG,SAAS,CAW9D;AAED,qBAAa,WAAW;IACtB,SAAgB,SAAS,EAAE,SAAS,CAAM;IAC1C,SAAgB,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC;IACxC,SAAgB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,WAAW,CAAC,CAAU;gBAE5B,OAAO,EAAE,EAAE,CAAC,WAAW,EACvB,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmB;IAMxD,QAAQ,CAAC,GAAG,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAInD,OAAO,CAAC,IAAI;IAeZ,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG;IAkSjC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG;CA4QlC"}
@@ -12,14 +12,45 @@ const defaultTypesMap = {
12
12
  Int8ArrayConstructor: "any",
13
13
  Uint8Array: "any"
14
14
  };
15
+ function nodeLocation(node) {
16
+ try {
17
+ const sourceFile = node.getSourceFile();
18
+ if (!sourceFile) return void 0;
19
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(
20
+ node.getStart()
21
+ );
22
+ return `${sourceFile.fileName}:${line + 1}:${character + 1}`;
23
+ } catch {
24
+ return void 0;
25
+ }
26
+ }
15
27
  class TypeDeriver {
16
28
  collector = {};
17
29
  checker;
18
30
  typesMap;
31
+ trace = {};
32
+ currentNode;
19
33
  constructor(checker, typeMappings = defaultTypesMap) {
20
34
  this.checker = checker;
21
35
  this.typesMap = typeMappings;
22
36
  }
37
+ setTrace(ctx) {
38
+ this.trace = { ...ctx };
39
+ }
40
+ warn(message, node) {
41
+ const parts = [`\x1B[33m\u26A0 ${message}\x1B[0m`];
42
+ const resolvedNode = node ?? this.currentNode;
43
+ const location = resolvedNode ? nodeLocation(resolvedNode) : void 0;
44
+ if (location) {
45
+ parts.push(` at \x1B[36m${location}\x1B[0m`);
46
+ } else if (this.trace.file) {
47
+ parts.push(` at \x1B[36m${this.trace.file}\x1B[0m`);
48
+ }
49
+ if (this.trace.operation) {
50
+ parts.push(` in \x1B[2m${this.trace.operation}\x1B[0m`);
51
+ }
52
+ console.warn(parts.join("\n"));
53
+ }
23
54
  serializeType(type) {
24
55
  if (this.typesMap[type.aliasSymbol?.getName() || type.symbol?.getName()]) {
25
56
  return {
@@ -75,6 +106,8 @@ class TypeDeriver {
75
106
  return {
76
107
  [deriveSymbol]: true,
77
108
  optional: false,
109
+ kind: "literal",
110
+ value: this.checker.typeToString(type) === "true",
78
111
  [$types]: ["boolean"]
79
112
  };
80
113
  }
@@ -155,7 +188,7 @@ class TypeDeriver {
155
188
  const [argType] = this.checker.getTypeArguments(type);
156
189
  if (!argType) {
157
190
  const typeName = type.symbol?.getName() || "<unknown>";
158
- console.warn(
191
+ this.warn(
159
192
  `Could not find generic type argument for array type ${typeName}`
160
193
  );
161
194
  return {
@@ -280,7 +313,7 @@ class TypeDeriver {
280
313
  }
281
314
  return this.serializeNode(declaration);
282
315
  }
283
- console.warn(`Unhandled type: ${type.flags} ${ts.TypeFlags[type.flags]}`);
316
+ this.warn(`Unhandled type: ${type.flags} ${ts.TypeFlags[type.flags]}`);
284
317
  return {
285
318
  [deriveSymbol]: true,
286
319
  optional: false,
@@ -294,6 +327,7 @@ class TypeDeriver {
294
327
  };
295
328
  }
296
329
  serializeNode(node) {
330
+ this.currentNode = node;
297
331
  if (ts.isObjectLiteralExpression(node)) {
298
332
  const symbolType = this.checker.getTypeAtLocation(node);
299
333
  const props = {};
@@ -312,7 +346,7 @@ class TypeDeriver {
312
346
  if (ts.isPropertyAccessExpression(node)) {
313
347
  const symbol = this.checker.getSymbolAtLocation(node.name);
314
348
  if (!symbol) {
315
- console.warn(`No symbol found for ${node.name.getText()}`);
349
+ this.warn(`No symbol found for ${node.name.getText()}`, node);
316
350
  return null;
317
351
  }
318
352
  const type = this.checker.getTypeOfSymbol(symbol);
@@ -321,7 +355,7 @@ class TypeDeriver {
321
355
  if (ts.isPropertySignature(node)) {
322
356
  const symbol = this.checker.getSymbolAtLocation(node.name);
323
357
  if (!symbol) {
324
- console.warn(`No symbol found for ${node.name.getText()}`);
358
+ this.warn(`No symbol found for ${node.name.getText()}`, node);
325
359
  return null;
326
360
  }
327
361
  const type = this.checker.getTypeOfSymbol(symbol);
@@ -330,7 +364,7 @@ class TypeDeriver {
330
364
  if (ts.isPropertyDeclaration(node)) {
331
365
  const symbol = this.checker.getSymbolAtLocation(node.name);
332
366
  if (!symbol) {
333
- console.warn(`No symbol found for ${node.name.getText()}`);
367
+ this.warn(`No symbol found for ${node.name.getText()}`, node);
334
368
  return null;
335
369
  }
336
370
  const type = this.checker.getTypeOfSymbol(symbol);
@@ -390,11 +424,11 @@ class TypeDeriver {
390
424
  if (ts.isVariableDeclaration(node)) {
391
425
  const symbol = this.checker.getSymbolAtLocation(node.name);
392
426
  if (!symbol) {
393
- console.warn(`No symbol found for ${node.name.getText()}`);
427
+ this.warn(`No symbol found for ${node.name.getText()}`, node);
394
428
  return null;
395
429
  }
396
430
  if (!node.type) {
397
- console.warn(`No type found for ${node.name.getText()}`);
431
+ this.warn(`No type found for ${node.name.getText()}`, node);
398
432
  return "any";
399
433
  }
400
434
  const type = this.checker.getTypeFromTypeNode(node.type);
@@ -403,7 +437,7 @@ class TypeDeriver {
403
437
  if (ts.isIdentifier(node)) {
404
438
  const symbol = this.checker.getSymbolAtLocation(node);
405
439
  if (!symbol) {
406
- console.warn(`Identifer: No symbol found for ${node.getText()}`);
440
+ this.warn(`No symbol found for identifier ${node.getText()}`, node);
407
441
  return null;
408
442
  }
409
443
  const type = this.checker.getTypeAtLocation(node);
@@ -468,7 +502,7 @@ class TypeDeriver {
468
502
  }
469
503
  if (ts.isFunctionDeclaration(node)) {
470
504
  if (!node.name) {
471
- console.warn("Function declaration has no name");
505
+ this.warn("Function declaration has no name", node);
472
506
  return {
473
507
  [deriveSymbol]: true,
474
508
  optional: false,
@@ -525,16 +559,13 @@ class TypeDeriver {
525
559
  const type = this.checker.getTypeAtLocation(node);
526
560
  return this.serializeType(type);
527
561
  }
528
- console.warn(
529
- "Unhandled node details:",
530
- `Node kind: ${ts.SyntaxKind[node.kind]}`,
531
- `Node flags: ${node.flags}`,
532
- `Node text: ${node.getText()}`,
533
- `Node type: ${this.checker.typeToString(
562
+ this.warn(
563
+ `Unhandled node: ${ts.SyntaxKind[node.kind]} "${node.getText()}" (type: ${this.checker.typeToString(
534
564
  this.checker.getTypeAtLocation(node),
535
565
  void 0,
536
566
  ts.TypeFormatFlags.NoTruncation
537
- )}`
567
+ )})`,
568
+ node
538
569
  );
539
570
  return {
540
571
  [deriveSymbol]: true,
@@ -547,6 +578,7 @@ export {
547
578
  $types,
548
579
  TypeDeriver,
549
580
  defaultTypesMap,
550
- deriveSymbol
581
+ deriveSymbol,
582
+ nodeLocation
551
583
  };
552
584
  //# sourceMappingURL=deriver.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/deriver.ts"],
4
- "sourcesContent": ["import ts, { TypeFlags, symbolName } from 'typescript';\n\nimport { isInterfaceType } from './program.js';\nimport { sortObjectKeys } from './utils.js';\n\ntype Collector = Record<string, any>;\n\nexport const deriveSymbol = Symbol.for('serialize');\nexport const $types = Symbol.for('types');\nexport const defaultTypesMap: Record<string, string> = {\n Readable: 'any',\n ReadableStream: 'any',\n DateConstructor: 'string',\n ArrayBufferConstructor: 'any',\n SharedArrayBufferConstructor: 'any',\n Int8ArrayConstructor: 'any',\n Uint8Array: 'any',\n};\nexport class TypeDeriver {\n public readonly collector: Collector = {};\n public readonly checker: ts.TypeChecker;\n public readonly typesMap: Record<string, string>;\n constructor(\n checker: ts.TypeChecker,\n typeMappings: Record<string, string> = defaultTypesMap,\n ) {\n this.checker = checker;\n this.typesMap = typeMappings;\n }\n\n serializeType(type: ts.Type): any {\n if (this.typesMap[type.aliasSymbol?.getName() || type.symbol?.getName()]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.typesMap[type.aliasSymbol?.getName() || type.symbol?.getName()],\n ],\n };\n }\n const indexType = type.getStringIndexType();\n if (indexType) {\n return {\n [deriveSymbol]: true,\n kind: 'record',\n optional: false,\n [$types]: [this.serializeType(indexType)],\n };\n }\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.flags & TypeFlags.Unknown) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.isStringLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['string'],\n };\n }\n if (type.isNumberLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['number'],\n };\n }\n if (type.flags & TypeFlags.BooleanLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (type.flags & TypeFlags.TemplateLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.String) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.Number) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['number'],\n };\n }\n if (type.flags & ts.TypeFlags.Boolean) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (type.flags & TypeFlags.Null) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['null'],\n };\n }\n if (type.isIntersection()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const intersectionType of type.types) {\n if (optional === undefined) {\n optional = (intersectionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(intersectionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'intersection',\n optional,\n [$types]: types,\n };\n }\n if (type.isUnion()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n // ignore undefined\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'union',\n optional,\n [$types]: types,\n };\n }\n if (this.checker.isArrayLikeType(type)) {\n const [argType] = this.checker.getTypeArguments(type as ts.TypeReference);\n if (!argType) {\n const typeName = type.symbol?.getName() || '<unknown>';\n console.warn(\n `Could not find generic type argument for array type ${typeName}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: ['any'],\n };\n }\n const typeSymbol = argType.getSymbol();\n if (!typeSymbol) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: [this.serializeType(argType)],\n };\n }\n\n if (typeSymbol.valueDeclaration) {\n return {\n kind: 'array',\n [deriveSymbol]: true,\n [$types]: [this.serializeNode(typeSymbol.valueDeclaration)],\n };\n }\n const maybeDeclaration = typeSymbol.declarations?.[0];\n if (maybeDeclaration) {\n if (ts.isMappedTypeNode(maybeDeclaration)) {\n const resolvedType = sortObjectKeys(\n this.checker\n .getPropertiesOfType(argType)\n .reduce<Record<string, unknown>>((acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n }, {}),\n );\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: [resolvedType],\n };\n } else {\n return {\n kind: 'array',\n ...this.serializeNode(maybeDeclaration),\n };\n }\n }\n\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: ['any'],\n };\n }\n if (type.isClass()) {\n const declaration = type.symbol?.valueDeclaration;\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n if (isInterfaceType(type)) {\n const valueDeclaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!valueDeclaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(valueDeclaration);\n }\n if (type.flags & TypeFlags.Object) {\n if (this.typesMap[symbolName(type.symbol)]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[symbolName(type.symbol)]],\n };\n }\n const properties = this.checker.getPropertiesOfType(type);\n if (properties.length > 0) {\n const serializedProps: Record<string, any> = {};\n for (const prop of properties) {\n const propAssingment = (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertyAssignment(it),\n );\n // get literal properties values if any\n if (propAssingment) {\n const type = this.checker.getTypeAtLocation(\n propAssingment.initializer,\n );\n serializedProps[prop.name] = this.serializeType(type);\n } else if (\n (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertySignature(it),\n )\n ) {\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n } else {\n // SymbolObject props\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n }\n }\n return {\n [deriveSymbol]: true,\n kind: 'object',\n optional: false,\n [$types]: [sortObjectKeys(serializedProps)],\n };\n }\n const declaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n\n console.warn(`Unhandled type: ${type.flags} ${ts.TypeFlags[type.flags]}`);\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.checker.typeToString(\n type,\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n ),\n ],\n };\n }\n\n serializeNode(node: ts.Node): any {\n if (ts.isObjectLiteralExpression(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, any> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n\n // get literal properties values if any\n for (const prop of node.properties) {\n if (ts.isPropertyAssignment(prop)) {\n const type = this.checker.getTypeAtLocation(prop.initializer);\n props[prop.name.getText()] = this.serializeType(type);\n }\n }\n\n return sortObjectKeys(props);\n }\n if (ts.isPropertyAccessExpression(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertySignature(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertyDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isInterfaceDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Interface has no name');\n }\n if (this.typesMap[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[node.name.text]],\n };\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertySignature)) {\n members[member.name.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = sortObjectKeys(members);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (ts.isClassDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Class has no name');\n }\n if (this.typesMap[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[node.name.text]],\n };\n }\n\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, unknown> = {};\n for (const member of node.members.filter(ts.isPropertyDeclaration)) {\n members[member.name!.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = sortObjectKeys(members);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n $ref: `#/components/schemas/${node.name.text}`,\n };\n }\n if (ts.isVariableDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n if (!node.type) {\n console.warn(`No type found for ${node.name.getText()}`);\n return 'any';\n }\n const type = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(type);\n }\n if (ts.isIdentifier(node)) {\n const symbol = this.checker.getSymbolAtLocation(node);\n if (!symbol) {\n console.warn(`Identifer: No symbol found for ${node.getText()}`);\n return null;\n }\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAwaitExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isCallExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAsExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTypeLiteralNode(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, unknown> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [sortObjectKeys(props)],\n };\n }\n if (node.kind === ts.SyntaxKind.NullKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['null'],\n };\n }\n if (node.kind === ts.SyntaxKind.BooleanKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (node.kind === ts.SyntaxKind.TrueKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: true,\n [$types]: ['boolean'],\n };\n }\n if (node.kind === ts.SyntaxKind.FalseKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: false,\n [$types]: ['boolean'],\n };\n }\n if (ts.isFunctionDeclaration(node)) {\n if (!node.name) {\n console.warn('Function declaration has no name');\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n\n const functionName = node.name.text;\n if (this.typesMap[functionName]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[functionName]],\n };\n }\n\n if (node.type) {\n const returnType = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(returnType);\n }\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n if (ts.isArrayLiteralExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isStringLiteral(node) || ts.isNumericLiteral(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n // Handle template literals in expression position\n if (\n ts.isTemplateExpression(node) ||\n ts.isNoSubstitutionTemplateLiteral(node)\n ) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTaggedTemplateExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle binary expressions (||, &&, +, -, etc.)\n if (ts.isBinaryExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle conditional/ternary expressions (x ? y : z)\n if (ts.isConditionalExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle parenthesized expressions ((value))\n if (ts.isParenthesizedExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle non-null assertions (value!)\n if (ts.isNonNullExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n console.warn(\n 'Unhandled node details:',\n `Node kind: ${ts.SyntaxKind[node.kind]}`,\n `Node flags: ${node.flags}`,\n `Node text: ${node.getText()}`,\n `Node type: ${this.checker.typeToString(\n this.checker.getTypeAtLocation(node),\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n )}`,\n );\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import ts, { TypeFlags, symbolName } from 'typescript';\n\nimport { isInterfaceType } from './program.js';\nimport { sortObjectKeys } from './utils.js';\n\ntype Collector = Record<string, any>;\n\nexport const deriveSymbol = Symbol.for('serialize');\nexport const $types = Symbol.for('types');\nexport const defaultTypesMap: Record<string, string> = {\n Readable: 'any',\n ReadableStream: 'any',\n DateConstructor: 'string',\n ArrayBufferConstructor: 'any',\n SharedArrayBufferConstructor: 'any',\n Int8ArrayConstructor: 'any',\n Uint8Array: 'any',\n};\n\ninterface TraceContext {\n file?: string;\n operation?: string;\n}\n\nexport function nodeLocation(node: ts.Node): string | undefined {\n try {\n const sourceFile = node.getSourceFile();\n if (!sourceFile) return undefined;\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(\n node.getStart(),\n );\n return `${sourceFile.fileName}:${line + 1}:${character + 1}`;\n } catch {\n return undefined;\n }\n}\n\nexport class TypeDeriver {\n public readonly collector: Collector = {};\n public readonly checker: ts.TypeChecker;\n public readonly typesMap: Record<string, string>;\n private trace: TraceContext = {};\n private currentNode?: ts.Node;\n constructor(\n checker: ts.TypeChecker,\n typeMappings: Record<string, string> = defaultTypesMap,\n ) {\n this.checker = checker;\n this.typesMap = typeMappings;\n }\n\n setTrace(ctx: { file?: string; operation?: string }) {\n this.trace = { ...ctx };\n }\n\n private warn(message: string, node?: ts.Node) {\n const parts = [`\\x1b[33m\\u26a0 ${message}\\x1b[0m`];\n const resolvedNode = node ?? this.currentNode;\n const location = resolvedNode ? nodeLocation(resolvedNode) : undefined;\n if (location) {\n parts.push(` at \\x1b[36m${location}\\x1b[0m`);\n } else if (this.trace.file) {\n parts.push(` at \\x1b[36m${this.trace.file}\\x1b[0m`);\n }\n if (this.trace.operation) {\n parts.push(` in \\x1b[2m${this.trace.operation}\\x1b[0m`);\n }\n console.warn(parts.join('\\n'));\n }\n\n serializeType(type: ts.Type): any {\n if (this.typesMap[type.aliasSymbol?.getName() || type.symbol?.getName()]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.typesMap[type.aliasSymbol?.getName() || type.symbol?.getName()],\n ],\n };\n }\n const indexType = type.getStringIndexType();\n if (indexType) {\n return {\n [deriveSymbol]: true,\n kind: 'record',\n optional: false,\n [$types]: [this.serializeType(indexType)],\n };\n }\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.flags & TypeFlags.Unknown) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.isStringLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['string'],\n };\n }\n if (type.isNumberLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['number'],\n };\n }\n if (type.flags & TypeFlags.BooleanLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: this.checker.typeToString(type) === 'true',\n [$types]: ['boolean'],\n };\n }\n if (type.flags & TypeFlags.TemplateLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.String) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.Number) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['number'],\n };\n }\n if (type.flags & ts.TypeFlags.Boolean) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (type.flags & TypeFlags.Null) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['null'],\n };\n }\n if (type.isIntersection()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const intersectionType of type.types) {\n if (optional === undefined) {\n optional = (intersectionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(intersectionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'intersection',\n optional,\n [$types]: types,\n };\n }\n if (type.isUnion()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n // ignore undefined\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'union',\n optional,\n [$types]: types,\n };\n }\n if (this.checker.isArrayLikeType(type)) {\n const [argType] = this.checker.getTypeArguments(type as ts.TypeReference);\n if (!argType) {\n const typeName = type.symbol?.getName() || '<unknown>';\n this.warn(\n `Could not find generic type argument for array type ${typeName}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: ['any'],\n };\n }\n const typeSymbol = argType.getSymbol();\n if (!typeSymbol) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: [this.serializeType(argType)],\n };\n }\n\n if (typeSymbol.valueDeclaration) {\n return {\n kind: 'array',\n [deriveSymbol]: true,\n [$types]: [this.serializeNode(typeSymbol.valueDeclaration)],\n };\n }\n const maybeDeclaration = typeSymbol.declarations?.[0];\n if (maybeDeclaration) {\n if (ts.isMappedTypeNode(maybeDeclaration)) {\n const resolvedType = sortObjectKeys(\n this.checker\n .getPropertiesOfType(argType)\n .reduce<Record<string, unknown>>((acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n }, {}),\n );\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: [resolvedType],\n };\n } else {\n return {\n kind: 'array',\n ...this.serializeNode(maybeDeclaration),\n };\n }\n }\n\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: ['any'],\n };\n }\n if (type.isClass()) {\n const declaration = type.symbol?.valueDeclaration;\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n if (isInterfaceType(type)) {\n const valueDeclaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!valueDeclaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(valueDeclaration);\n }\n if (type.flags & TypeFlags.Object) {\n if (this.typesMap[symbolName(type.symbol)]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[symbolName(type.symbol)]],\n };\n }\n const properties = this.checker.getPropertiesOfType(type);\n if (properties.length > 0) {\n const serializedProps: Record<string, any> = {};\n for (const prop of properties) {\n const propAssingment = (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertyAssignment(it),\n );\n // get literal properties values if any\n if (propAssingment) {\n const type = this.checker.getTypeAtLocation(\n propAssingment.initializer,\n );\n serializedProps[prop.name] = this.serializeType(type);\n } else if (\n (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertySignature(it),\n )\n ) {\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n } else {\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n }\n }\n return {\n [deriveSymbol]: true,\n kind: 'object',\n optional: false,\n [$types]: [sortObjectKeys(serializedProps)],\n };\n }\n const declaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n\n this.warn(`Unhandled type: ${type.flags} ${ts.TypeFlags[type.flags]}`);\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.checker.typeToString(\n type,\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n ),\n ],\n };\n }\n\n serializeNode(node: ts.Node): any {\n this.currentNode = node;\n if (ts.isObjectLiteralExpression(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, any> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n\n // get literal properties values if any\n for (const prop of node.properties) {\n if (ts.isPropertyAssignment(prop)) {\n const type = this.checker.getTypeAtLocation(prop.initializer);\n props[prop.name.getText()] = this.serializeType(type);\n }\n }\n\n return sortObjectKeys(props);\n }\n if (ts.isPropertyAccessExpression(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n this.warn(`No symbol found for ${node.name.getText()}`, node);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertySignature(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n this.warn(`No symbol found for ${node.name.getText()}`, node);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertyDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n this.warn(`No symbol found for ${node.name.getText()}`, node);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isInterfaceDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Interface has no name');\n }\n if (this.typesMap[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[node.name.text]],\n };\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertySignature)) {\n members[member.name.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = sortObjectKeys(members);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (ts.isClassDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Class has no name');\n }\n if (this.typesMap[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[node.name.text]],\n };\n }\n\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, unknown> = {};\n for (const member of node.members.filter(ts.isPropertyDeclaration)) {\n members[member.name!.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = sortObjectKeys(members);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n $ref: `#/components/schemas/${node.name.text}`,\n };\n }\n if (ts.isVariableDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n this.warn(`No symbol found for ${node.name.getText()}`, node);\n return null;\n }\n if (!node.type) {\n this.warn(`No type found for ${node.name.getText()}`, node);\n return 'any';\n }\n const type = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(type);\n }\n if (ts.isIdentifier(node)) {\n const symbol = this.checker.getSymbolAtLocation(node);\n if (!symbol) {\n this.warn(`No symbol found for identifier ${node.getText()}`, node);\n return null;\n }\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAwaitExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isCallExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAsExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTypeLiteralNode(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, unknown> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [sortObjectKeys(props)],\n };\n }\n if (node.kind === ts.SyntaxKind.NullKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['null'],\n };\n }\n if (node.kind === ts.SyntaxKind.BooleanKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (node.kind === ts.SyntaxKind.TrueKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: true,\n [$types]: ['boolean'],\n };\n }\n if (node.kind === ts.SyntaxKind.FalseKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: false,\n [$types]: ['boolean'],\n };\n }\n if (ts.isFunctionDeclaration(node)) {\n if (!node.name) {\n this.warn('Function declaration has no name', node);\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n\n const functionName = node.name.text;\n if (this.typesMap[functionName]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [this.typesMap[functionName]],\n };\n }\n\n if (node.type) {\n const returnType = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(returnType);\n }\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n if (ts.isArrayLiteralExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isStringLiteral(node) || ts.isNumericLiteral(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n // Handle template literals in expression position\n if (\n ts.isTemplateExpression(node) ||\n ts.isNoSubstitutionTemplateLiteral(node)\n ) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTaggedTemplateExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle binary expressions (||, &&, +, -, etc.)\n if (ts.isBinaryExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle conditional/ternary expressions (x ? y : z)\n if (ts.isConditionalExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle parenthesized expressions ((value))\n if (ts.isParenthesizedExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n // Handle non-null assertions (value!)\n if (ts.isNonNullExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n this.warn(\n `Unhandled node: ${ts.SyntaxKind[node.kind]} \"${node.getText()}\" (type: ${this.checker.typeToString(\n this.checker.getTypeAtLocation(node),\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n )})`,\n node,\n );\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["type"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import type { OperationObject, PathsObject } from 'openapi3-ts/oas31';
1
+ import type { OperationObject, PathsObject, SchemaObject } from 'openapi3-ts/oas31';
2
2
  import { $types } from './deriver.js';
3
3
  import { type InjectImport } from './zod-jsonschema.js';
4
4
  export type OperationInfo = {
@@ -21,6 +21,7 @@ export interface ResponseItem {
21
21
  response?: DateType;
22
22
  contentType: string;
23
23
  headers: (string | Record<string, string[]>)[];
24
+ middlewareName?: string;
24
25
  }
25
26
  export type OnOperation = (sourceFile: string, method: Method, path: string, operation: OperationObject) => PathsObject;
26
27
  export declare class Paths {
@@ -31,6 +32,7 @@ export declare class Paths {
31
32
  });
32
33
  addPath(name: string, path: string, method: Method, contentType: string | undefined, selectors: Selector[], responses: ResponseItem[], sourceFile: string, info: OperationInfo): this;
33
34
  getTags(): string[];
35
+ getSharedSchemas(): Record<string, SchemaObject>;
34
36
  getPaths(): Promise<PathsObject>;
35
37
  }
36
38
  interface DateType {
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,YAAY,EAAW,MAAM,qBAAqB,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,MAAM,GACd,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;AAEX,eAAO,MAAM,OAAO,qEAQV,CAAC;AACX,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAQd,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;CAChD;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,eAAe,KACvB,WAAW,CAAC;AACjB,qBAAa,KAAK;;gBAcJ,MAAM,EAAE;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAK1E,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa;IA8GrB,OAAO,IAAI,MAAM,EAAE;IAcb,QAAQ;CA0Ef;AAED,UAAU,QAAQ;IAChB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CA0CxE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,MAAM,CAEzD"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,WAAW,EAGX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,YAAY,EAAW,MAAM,qBAAqB,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,MAAM,GACd,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;AAEX,eAAO,MAAM,OAAO,qEAQV,CAAC;AACX,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAQd,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,eAAe,KACvB,WAAW,CAAC;AACjB,qBAAa,KAAK;;gBAeJ,MAAM,EAAE;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAK1E,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa;IAyHrB,OAAO,IAAI,MAAM,EAAE;IAcnB,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IAI1C,QAAQ;CA0Ef;AAED,UAAU,QAAQ;IAChB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CA0CxE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,MAAM,CAEzD"}
package/dist/lib/paths.js CHANGED
@@ -19,6 +19,7 @@ const semanticSourceToOpenAPI = {
19
19
  class Paths {
20
20
  #imports = [];
21
21
  #onOperation;
22
+ #sharedResponses = /* @__PURE__ */ new Map();
22
23
  #operations = [];
23
24
  constructor(config) {
24
25
  this.#imports = config.imports;
@@ -42,7 +43,15 @@ class Paths {
42
43
  const responsesObject = {};
43
44
  for (const item of responses) {
44
45
  const ct = item.contentType;
45
- const schema = item.response ? toSchema(item.response) : {};
46
+ let schema = item.response ? toSchema(item.response) : {};
47
+ if (item.middlewareName) {
48
+ const sanitizedCt = ct.replace(/\//g, "_");
49
+ const sharedKey = `${item.middlewareName}${item.statusCode}_${sanitizedCt}`;
50
+ if (!this.#sharedResponses.has(sharedKey)) {
51
+ this.#sharedResponses.set(sharedKey, schema);
52
+ }
53
+ schema = { $ref: `#/components/schemas/${sharedKey}` };
54
+ }
46
55
  if (!responsesObject[item.statusCode]) {
47
56
  responsesObject[item.statusCode] = {
48
57
  description: `Response for ${item.statusCode}`,
@@ -125,6 +134,9 @@ class Paths {
125
134
  }
126
135
  return Array.from(tags);
127
136
  }
137
+ getSharedSchemas() {
138
+ return Object.fromEntries(this.#sharedResponses);
139
+ }
128
140
  async getPaths() {
129
141
  const operations = {};
130
142
  for (const operation of this.#operations) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/paths.ts"],
4
- "sourcesContent": ["import type {\n HeadersObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.js';\nimport { sortArray, sortObjectKeys } from './utils.js';\nimport { type InjectImport, evalZod } from './zod-jsonschema.js';\n\nexport type OperationInfo = {\n tool?: string;\n toolDescription?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n};\nexport type Method =\n | 'get'\n | 'post'\n | 'put'\n | 'patch'\n | 'delete'\n | 'trace'\n | 'head';\n\nexport const methods = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'trace',\n 'head',\n] as const;\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n against: string;\n source: SemanticSource;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: (string | Record<string, string[]>)[];\n}\n\nexport type OnOperation = (\n sourceFile: string,\n method: Method,\n path: string,\n operation: OperationObject,\n) => PathsObject;\nexport class Paths {\n #imports: InjectImport[] = [];\n #onOperation?: OnOperation;\n #operations: Array<{\n sourceFile: string;\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n contentType?: string;\n info: OperationInfo;\n }> = [];\n\n constructor(config: { imports: InjectImport[]; onOperation?: OnOperation }) {\n this.#imports = config.imports;\n this.#onOperation = config.onOperation;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n contentType: string | undefined,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n info: OperationInfo,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n\n this.#operations.push({\n name,\n path: this.#tunePath(path),\n sourceFile,\n contentType: contentType,\n method,\n selectors,\n responses: responsesObject,\n info,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = item.response ? toSchema(item.response) : {};\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content:\n ct !== 'empty'\n ? {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n }\n : undefined,\n headers: item.headers.length\n ? item.headers.reduce<HeadersObject>((acc, current) => {\n const headers =\n typeof current === 'string' ? { [current]: [] } : current;\n const sortedHeaders = Object.entries(sortObjectKeys(headers));\n return sortedHeaders.reduce<HeadersObject>(\n (subAcc, [key, value]) => {\n const header: HeadersObject = {\n [key]: {\n schema: {\n type: 'string',\n enum: value.length ? value : undefined,\n },\n },\n };\n return { ...subAcc, ...header };\n },\n acc,\n );\n }, {})\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<\n string,\n { required: boolean; schema: SchemaObject }\n > = {};\n for (const selector of selectors) {\n const { optional, schema } = await evalZod(\n selector.against,\n this.#imports,\n );\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = {\n required: !optional,\n schema,\n };\n continue;\n }\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: !optional,\n schema,\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n getTags(): string[] {\n const tags = new Set<string>();\n\n for (const operation of this.#operations) {\n if (operation.info.tags) {\n for (const tag of operation.info.tags) {\n tags.add(tag);\n }\n }\n }\n\n return Array.from(tags);\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const bodySchema: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const sortedBodySchemaProps = Object.entries(\n sortObjectKeys(bodySchemaProps),\n );\n for (const [key, value] of sortedBodySchemaProps) {\n if (value.required) {\n required.push(key);\n }\n bodySchema[key] = value.schema;\n }\n\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.info.tags,\n // || undefined would omit the value from final openapi spec\n description: operation.info.description || undefined,\n summary: operation.info.summary || undefined,\n 'x-tool': operation.info.tool\n ? {\n name: operation.info.tool || undefined,\n description: operation.info.toolDescription || undefined,\n }\n : undefined,\n requestBody: Object.keys(bodySchema).length\n ? {\n required: required.length ? true : false,\n content: {\n [operation.contentType || 'application/json']: {\n schema: {\n required: required.length ? sortArray(required) : undefined,\n type: 'object',\n properties: bodySchema,\n },\n },\n },\n }\n : undefined,\n responses:\n Object.keys(operation.responses).length === 0\n ? undefined\n : operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const paths = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, paths ?? {});\n }\n }\n return operations;\n }\n\n /**\n * Converts Express/Node.js style path parameters (/path/:param) to OpenAPI style (/path/{param})\n */\n #tunePath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\n }\n}\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n value?: string;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'literal') {\n return { enum: [data.value], type: data[$types][0] };\n } else if (data.kind === 'record') {\n return {\n type: 'object',\n additionalProperties: toSchema(data[$types][0]),\n };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { anyOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n const required: string[] = [];\n const sortedEntries = Object.entries(sortObjectKeys(data));\n for (const [key, value] of sortedEntries) {\n props[key] = toSchema(value as any);\n if (!(value as any).optional) {\n required.push(key);\n }\n }\n return {\n type: 'object',\n properties: props,\n required: sortArray(required),\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n HeadersObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.js';\nimport { sortArray, sortObjectKeys } from './utils.js';\nimport { type InjectImport, evalZod } from './zod-jsonschema.js';\n\nexport type OperationInfo = {\n tool?: string;\n toolDescription?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n};\nexport type Method =\n | 'get'\n | 'post'\n | 'put'\n | 'patch'\n | 'delete'\n | 'trace'\n | 'head';\n\nexport const methods = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'trace',\n 'head',\n] as const;\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n against: string;\n source: SemanticSource;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: (string | Record<string, string[]>)[];\n middlewareName?: string;\n}\n\nexport type OnOperation = (\n sourceFile: string,\n method: Method,\n path: string,\n operation: OperationObject,\n) => PathsObject;\nexport class Paths {\n #imports: InjectImport[] = [];\n #onOperation?: OnOperation;\n #sharedResponses = new Map<string, SchemaObject>();\n #operations: Array<{\n sourceFile: string;\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n contentType?: string;\n info: OperationInfo;\n }> = [];\n\n constructor(config: { imports: InjectImport[]; onOperation?: OnOperation }) {\n this.#imports = config.imports;\n this.#onOperation = config.onOperation;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n contentType: string | undefined,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n info: OperationInfo,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n\n this.#operations.push({\n name,\n path: this.#tunePath(path),\n sourceFile,\n contentType: contentType,\n method,\n selectors,\n responses: responsesObject,\n info,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n let schema = item.response ? toSchema(item.response) : {};\n\n // Deduplicate named middleware responses via $ref\n if (item.middlewareName) {\n const sanitizedCt = ct.replace(/\\//g, '_');\n const sharedKey = `${item.middlewareName}${item.statusCode}_${sanitizedCt}`;\n if (!this.#sharedResponses.has(sharedKey)) {\n this.#sharedResponses.set(sharedKey, schema);\n }\n schema = { $ref: `#/components/schemas/${sharedKey}` };\n }\n\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content:\n ct !== 'empty'\n ? {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n }\n : undefined,\n headers: item.headers.length\n ? item.headers.reduce<HeadersObject>((acc, current) => {\n const headers =\n typeof current === 'string' ? { [current]: [] } : current;\n const sortedHeaders = Object.entries(sortObjectKeys(headers));\n return sortedHeaders.reduce<HeadersObject>(\n (subAcc, [key, value]) => {\n const header: HeadersObject = {\n [key]: {\n schema: {\n type: 'string',\n enum: value.length ? value : undefined,\n },\n },\n };\n return { ...subAcc, ...header };\n },\n acc,\n );\n }, {})\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<\n string,\n { required: boolean; schema: SchemaObject }\n > = {};\n for (const selector of selectors) {\n const { optional, schema } = await evalZod(\n selector.against,\n this.#imports,\n );\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = {\n required: !optional,\n schema,\n };\n continue;\n }\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: !optional,\n schema,\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n getTags(): string[] {\n const tags = new Set<string>();\n\n for (const operation of this.#operations) {\n if (operation.info.tags) {\n for (const tag of operation.info.tags) {\n tags.add(tag);\n }\n }\n }\n\n return Array.from(tags);\n }\n\n getSharedSchemas(): Record<string, SchemaObject> {\n return Object.fromEntries(this.#sharedResponses);\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const bodySchema: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const sortedBodySchemaProps = Object.entries(\n sortObjectKeys(bodySchemaProps),\n );\n for (const [key, value] of sortedBodySchemaProps) {\n if (value.required) {\n required.push(key);\n }\n bodySchema[key] = value.schema;\n }\n\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.info.tags,\n // || undefined would omit the value from final openapi spec\n description: operation.info.description || undefined,\n summary: operation.info.summary || undefined,\n 'x-tool': operation.info.tool\n ? {\n name: operation.info.tool || undefined,\n description: operation.info.toolDescription || undefined,\n }\n : undefined,\n requestBody: Object.keys(bodySchema).length\n ? {\n required: required.length ? true : false,\n content: {\n [operation.contentType || 'application/json']: {\n schema: {\n required: required.length ? sortArray(required) : undefined,\n type: 'object',\n properties: bodySchema,\n },\n },\n },\n }\n : undefined,\n responses:\n Object.keys(operation.responses).length === 0\n ? undefined\n : operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const paths = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, paths ?? {});\n }\n }\n return operations;\n }\n\n /**\n * Converts Express/Node.js style path parameters (/path/:param) to OpenAPI style (/path/{param})\n */\n #tunePath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\n }\n}\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n value?: string;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'literal') {\n return { enum: [data.value], type: data[$types][0] };\n } else if (data.kind === 'record') {\n return {\n type: 'object',\n additionalProperties: toSchema(data[$types][0]),\n };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { anyOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n const required: string[] = [];\n const sortedEntries = Object.entries(sortObjectKeys(data));\n for (const [key, value] of sortedEntries) {\n props[key] = toSchema(value as any);\n if (!(value as any).optional) {\n required.push(key);\n }\n }\n return {\n type: 'object',\n properties: props,\n required: sortArray(required),\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"zod-jsonschema.d.ts","sourceRoot":"","sources":["../../src/lib/zod-jsonschema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAOF,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAY,EAAO,gBAoCzE"}
1
+ {"version":3,"file":"zod-jsonschema.d.ts","sourceRoot":"","sources":["../../src/lib/zod-jsonschema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAOF,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAY,EAAO,gBAmDzE"}
@@ -23,11 +23,26 @@ async function evalZod(schema, imports = []) {
23
23
  const { $schema, ...result } = toJsonSchema(def.innerType);
24
24
  return result;
25
25
  }
26
+ if (def.typeName === 'ZodDate') {
27
+ return {
28
+ type: 'string',
29
+ format: 'date-time',
30
+ 'x-zod-type': def.coerce ? 'coerce-date' : 'date',
31
+ };
32
+ }
26
33
  return ignoreOverride;
27
34
  },
28
35
  });
29
36
  }`,
30
- `const { $schema, ...result } = toJsonSchema(${removeUnsupportedMethods(schema)});`,
37
+ `const zodSchema = ${removeUnsupportedMethods(schema)};`,
38
+ `const { $schema, ...result } = toJsonSchema(zodSchema);`,
39
+ `let innerDef = zodSchema._def;
40
+ while (innerDef && (innerDef.typeName === 'ZodOptional' || innerDef.typeName === 'ZodDefault' || innerDef.typeName === 'ZodNullable')) {
41
+ innerDef = innerDef.innerType?._def;
42
+ }
43
+ if (innerDef?.coerce && !result['x-zod-type']) {
44
+ result['x-zod-type'] = 'coerce-' + innerDef.typeName.replace('Zod', '').toLowerCase();
45
+ }`,
31
46
  `export default {schema: result, optional}`
32
47
  ];
33
48
  const base64 = Buffer.from(lines.join("\n")).toString("base64");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/zod-jsonschema.ts"],
4
- "sourcesContent": ["export type InjectImport = {\n import: string;\n from: string;\n};\n\nfunction removeUnsupportedMethods(schema: string) {\n\t// fixme: use overrides to detect instanceOf\n return schema.replaceAll('.instanceof(File)', '.string().base64()');\n}\n\nexport async function evalZod(schema: string, imports: InjectImport[] = []) {\n // https://github.com/nodejs/node/issues/51956\n const lines = [\n `import { createRequire } from \"node:module\";`,\n `const filename = \"${import.meta.url}\";`,\n `const require = createRequire(filename);`,\n `const z = require(\"zod\");`,\n ...imports.map((imp) => `const ${imp.import} = require('${imp.from}');`),\n `const {zodToJsonSchema, ignoreOverride} = require('zod-to-json-schema');`,\n `let optional = false;`,\n `function toJsonSchema(schema) {\n return zodToJsonSchema(schema, {\n $refStrategy: 'root',\n basePath: ['#', 'components', 'schemas'],\n target: 'jsonSchema7',\n base64Strategy: 'format:binary',\n effectStrategy: 'input',\n override: (def) => {\n if (def.typeName === 'ZodOptional') {\n\t\t\t\t\t\toptional = true;\n\t\t\t\t\t\tconst { $schema, ...result } = toJsonSchema(def.innerType);\n return result;\n }\n return ignoreOverride;\n },\n });\n }`,\n `const { $schema, ...result } = toJsonSchema(${removeUnsupportedMethods(schema)});`,\n `export default {schema: result, optional}`,\n ];\n\n const base64 = Buffer.from(lines.join('\\n')).toString('base64');\n return import(\n /* @vite-ignore */\n `data:text/javascript;base64,${base64}`\n ).then((mod) => mod.default);\n}\n"],
5
- "mappings": "AAKA,SAAS,yBAAyB,QAAgB;AAEhD,SAAO,OAAO,WAAW,qBAAqB,oBAAoB;AACpE;AAEA,eAAsB,QAAQ,QAAgB,UAA0B,CAAC,GAAG;AAE1E,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,qBAAqB,YAAY,GAAG;AAAA,IACpC;AAAA,IACA;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,eAAe,IAAI,IAAI,KAAK;AAAA,IACvE;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiBA,+CAA+C,yBAAyB,MAAM,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,SAAS,QAAQ;AAC9D,SAAO;AAAA;AAAA,IAEL,+BAA+B,MAAM;AAAA,IACrC,KAAK,CAAC,QAAQ,IAAI,OAAO;AAC7B;",
4
+ "sourcesContent": ["export type InjectImport = {\n import: string;\n from: string;\n};\n\nfunction removeUnsupportedMethods(schema: string) {\n\t// fixme: use overrides to detect instanceOf\n return schema.replaceAll('.instanceof(File)', '.string().base64()');\n}\n\nexport async function evalZod(schema: string, imports: InjectImport[] = []) {\n // https://github.com/nodejs/node/issues/51956\n const lines = [\n `import { createRequire } from \"node:module\";`,\n `const filename = \"${import.meta.url}\";`,\n `const require = createRequire(filename);`,\n `const z = require(\"zod\");`,\n ...imports.map((imp) => `const ${imp.import} = require('${imp.from}');`),\n `const {zodToJsonSchema, ignoreOverride} = require('zod-to-json-schema');`,\n `let optional = false;`,\n `function toJsonSchema(schema) {\n return zodToJsonSchema(schema, {\n $refStrategy: 'root',\n basePath: ['#', 'components', 'schemas'],\n target: 'jsonSchema7',\n base64Strategy: 'format:binary',\n effectStrategy: 'input',\n override: (def) => {\n if (def.typeName === 'ZodOptional') {\n\t\t\t\t\t\toptional = true;\n\t\t\t\t\t\tconst { $schema, ...result } = toJsonSchema(def.innerType);\n return result;\n }\n if (def.typeName === 'ZodDate') {\n return {\n type: 'string',\n format: 'date-time',\n 'x-zod-type': def.coerce ? 'coerce-date' : 'date',\n };\n }\n return ignoreOverride;\n },\n });\n }`,\n `const zodSchema = ${removeUnsupportedMethods(schema)};`,\n `const { $schema, ...result } = toJsonSchema(zodSchema);`,\n `let innerDef = zodSchema._def;\n while (innerDef && (innerDef.typeName === 'ZodOptional' || innerDef.typeName === 'ZodDefault' || innerDef.typeName === 'ZodNullable')) {\n innerDef = innerDef.innerType?._def;\n }\n if (innerDef?.coerce && !result['x-zod-type']) {\n result['x-zod-type'] = 'coerce-' + innerDef.typeName.replace('Zod', '').toLowerCase();\n }`,\n `export default {schema: result, optional}`,\n ];\n\n const base64 = Buffer.from(lines.join('\\n')).toString('base64');\n return import(\n /* @vite-ignore */\n `data:text/javascript;base64,${base64}`\n ).then((mod) => mod.default);\n}\n"],
5
+ "mappings": "AAKA,SAAS,yBAAyB,QAAgB;AAEhD,SAAO,OAAO,WAAW,qBAAqB,oBAAoB;AACpE;AAEA,eAAsB,QAAQ,QAAgB,UAA0B,CAAC,GAAG;AAE1E,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,qBAAqB,YAAY,GAAG;AAAA,IACpC;AAAA,IACA;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,eAAe,IAAI,IAAI,KAAK;AAAA,IACvE;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwBA,qBAAqB,yBAAyB,MAAM,CAAC;AAAA,IACrD;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,SAAS,QAAQ;AAC9D,SAAO;AAAA;AAAA,IAEL,+BAA+B,MAAM;AAAA,IACrC,KAAK,CAAC,QAAQ,IAAI,OAAO;AAC7B;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/core",
3
- "version": "0.39.0",
3
+ "version": "0.41.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",