openapi-typesafe 1.0.0-rc.2 → 1.0.0-rc.3

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.
Files changed (139) hide show
  1. package/dist/adapters/node-deprecations/node-deprecations.cjs +14 -0
  2. package/dist/adapters/node-deprecations/node-deprecations.cjs.map +1 -0
  3. package/dist/adapters/node-deprecations/node-deprecations.mjs +12 -0
  4. package/dist/adapters/node-deprecations/node-deprecations.mjs.map +1 -0
  5. package/dist/api/default-ports.cjs +5 -0
  6. package/dist/api/default-ports.cjs.map +1 -1
  7. package/dist/api/default-ports.mjs +5 -1
  8. package/dist/api/default-ports.mjs.map +1 -1
  9. package/dist/api/discriminator-conflict-warnings.cjs +1 -1
  10. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -1
  11. package/dist/api/discriminator-conflict-warnings.mjs +2 -2
  12. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -1
  13. package/dist/api/discriminator-patch.cjs +3 -3
  14. package/dist/api/discriminator-patch.cjs.map +1 -1
  15. package/dist/api/discriminator-patch.mjs +4 -4
  16. package/dist/api/discriminator-patch.mjs.map +1 -1
  17. package/dist/api/discriminator-scan.cjs +2 -2
  18. package/dist/api/discriminator-scan.cjs.map +1 -1
  19. package/dist/api/discriminator-scan.mjs +3 -3
  20. package/dist/api/discriminator-scan.mjs.map +1 -1
  21. package/dist/api/document-run.cjs +2 -1
  22. package/dist/api/document-run.cjs.map +1 -1
  23. package/dist/api/document-run.mjs +2 -1
  24. package/dist/api/document-run.mjs.map +1 -1
  25. package/dist/api/legacy-callback-warning.cjs +7 -4
  26. package/dist/api/legacy-callback-warning.cjs.map +1 -1
  27. package/dist/api/legacy-callback-warning.mjs +8 -5
  28. package/dist/api/legacy-callback-warning.mjs.map +1 -1
  29. package/dist/api/openapi-ts.cjs +1 -1
  30. package/dist/api/openapi-ts.cjs.map +1 -1
  31. package/dist/api/openapi-ts.mjs +2 -2
  32. package/dist/api/openapi-ts.mjs.map +1 -1
  33. package/dist/api/string-to-ast.cjs +7 -9
  34. package/dist/api/string-to-ast.cjs.map +1 -1
  35. package/dist/api/string-to-ast.mjs +8 -9
  36. package/dist/api/string-to-ast.mjs.map +1 -1
  37. package/dist/api/transform-schema.cjs +2 -2
  38. package/dist/api/transform-schema.cjs.map +1 -1
  39. package/dist/api/transform-schema.mjs +3 -3
  40. package/dist/api/transform-schema.mjs.map +1 -1
  41. package/dist/application/transform/document/components.cjs +1 -1
  42. package/dist/application/transform/document/components.cjs.map +1 -1
  43. package/dist/application/transform/document/components.mjs +2 -2
  44. package/dist/application/transform/document/components.mjs.map +1 -1
  45. package/dist/application/transform/document/parameters.cjs +1 -1
  46. package/dist/application/transform/document/parameters.cjs.map +1 -1
  47. package/dist/application/transform/document/parameters.mjs +2 -2
  48. package/dist/application/transform/document/parameters.mjs.map +1 -1
  49. package/dist/application/transform/document/paths.cjs +1 -1
  50. package/dist/application/transform/document/paths.cjs.map +1 -1
  51. package/dist/application/transform/document/paths.mjs +2 -2
  52. package/dist/application/transform/document/paths.mjs.map +1 -1
  53. package/dist/application/transform/ref-pointer/pointer-type.cjs +1 -1
  54. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
  55. package/dist/application/transform/ref-pointer/pointer-type.mjs +2 -2
  56. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
  57. package/dist/application/transform/schema/access-flags.cjs +1 -1
  58. package/dist/application/transform/schema/access-flags.cjs.map +1 -1
  59. package/dist/application/transform/schema/access-flags.mjs +2 -2
  60. package/dist/application/transform/schema/access-flags.mjs.map +1 -1
  61. package/dist/application/transform/schema/array-type.cjs +2 -2
  62. package/dist/application/transform/schema/array-type.cjs.map +1 -1
  63. package/dist/application/transform/schema/array-type.mjs +3 -3
  64. package/dist/application/transform/schema/array-type.mjs.map +1 -1
  65. package/dist/application/transform/schema/composition-type.cjs +3 -3
  66. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  67. package/dist/application/transform/schema/composition-type.mjs +4 -4
  68. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  69. package/dist/application/transform/schema/enum-rule.cjs +3 -5
  70. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  71. package/dist/application/transform/schema/enum-rule.mjs +4 -6
  72. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  73. package/dist/application/transform/schema/presence-members.cjs +1 -1
  74. package/dist/application/transform/schema/presence-members.cjs.map +1 -1
  75. package/dist/application/transform/schema/presence-members.mjs +2 -2
  76. package/dist/application/transform/schema/presence-members.mjs.map +1 -1
  77. package/dist/application/transform/schema/required-variants.cjs +2 -2
  78. package/dist/application/transform/schema/required-variants.cjs.map +1 -1
  79. package/dist/application/transform/schema/required-variants.mjs +3 -3
  80. package/dist/application/transform/schema/required-variants.mjs.map +1 -1
  81. package/dist/application/transform/schema/unevaluated-properties.cjs +1 -1
  82. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
  83. package/dist/application/transform/schema/unevaluated-properties.mjs +2 -2
  84. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
  85. package/dist/application/transform/schema-comment.cjs +1 -1
  86. package/dist/application/transform/schema-comment.cjs.map +1 -1
  87. package/dist/application/transform/schema-comment.mjs +2 -2
  88. package/dist/application/transform/schema-comment.mjs.map +1 -1
  89. package/dist/domain/deprecations.cjs +11 -0
  90. package/dist/domain/deprecations.cjs.map +1 -0
  91. package/dist/domain/deprecations.mjs +9 -0
  92. package/dist/domain/deprecations.mjs.map +1 -0
  93. package/dist/domain/errors.cjs.map +1 -1
  94. package/dist/domain/errors.mjs.map +1 -1
  95. package/dist/domain/output-fixes.cjs +11 -14
  96. package/dist/domain/output-fixes.cjs.map +1 -1
  97. package/dist/domain/output-fixes.mjs +11 -13
  98. package/dist/domain/output-fixes.mjs.map +1 -1
  99. package/dist/domain/warnings.cjs +0 -1
  100. package/dist/domain/warnings.cjs.map +1 -1
  101. package/dist/domain/warnings.mjs +0 -1
  102. package/dist/domain/warnings.mjs.map +1 -1
  103. package/dist/index.cjs +2 -3
  104. package/dist/index.cjs.map +1 -1
  105. package/dist/index.d.cts +35 -16
  106. package/dist/index.d.mts +35 -16
  107. package/dist/index.d.ts +35 -16
  108. package/dist/index.mjs +3 -2
  109. package/dist/index.mjs.map +1 -1
  110. package/package.json +2 -2
  111. package/src/adapters/node-deprecations/node-deprecations.ts +14 -0
  112. package/src/api/default-ports.ts +7 -0
  113. package/src/api/discriminator-conflict-warnings.ts +2 -2
  114. package/src/api/discriminator-patch.ts +4 -5
  115. package/src/api/discriminator-scan.ts +3 -3
  116. package/src/api/document-run.ts +5 -0
  117. package/src/api/legacy-callback-warning.ts +13 -6
  118. package/src/api/openapi-ts.ts +6 -2
  119. package/src/api/run-context.ts +3 -0
  120. package/src/api/string-to-ast.ts +11 -15
  121. package/src/api/transform-schema.ts +3 -3
  122. package/src/application/ports/deprecation-reporter.ts +9 -0
  123. package/src/application/transform/document/components.ts +2 -2
  124. package/src/application/transform/document/parameters.ts +2 -2
  125. package/src/application/transform/document/paths.ts +2 -2
  126. package/src/application/transform/ref-pointer/pointer-type.ts +2 -4
  127. package/src/application/transform/schema/access-flags.ts +2 -2
  128. package/src/application/transform/schema/array-type.ts +3 -5
  129. package/src/application/transform/schema/composition-type.ts +4 -4
  130. package/src/application/transform/schema/enum-rule.ts +4 -6
  131. package/src/application/transform/schema/presence-members.ts +2 -2
  132. package/src/application/transform/schema/required-variants.ts +3 -3
  133. package/src/application/transform/schema/unevaluated-properties.ts +2 -2
  134. package/src/application/transform/schema-comment.ts +2 -2
  135. package/src/domain/deprecations.ts +15 -0
  136. package/src/domain/errors.ts +8 -2
  137. package/src/domain/output-fixes.ts +16 -16
  138. package/src/domain/warnings.ts +0 -1
  139. package/src/index.ts +2 -6
@@ -3,7 +3,7 @@ import { withIdentifierParts, hasIdentifierStart, isReservedTypeName } from '../
3
3
  import { toPropertyName } from '../../../domain/ir/property-name.mjs';
4
4
  import { DECLARED_COMPONENT_KINDS, COMPONENT_KINDS, isEnumSchema, singularizeComponentKind } from '../../../domain/openapi/components-object.mjs';
5
5
  import { createRef } from '../../../domain/openapi/json-pointer.mjs';
6
- import { OutputFix } from '../../../domain/output-fixes.mjs';
6
+ import { FIX } from '../../../domain/output-fixes.mjs';
7
7
  import { documentEntries } from '../document-entries.mjs';
8
8
  import { transformSchema } from '../schema/schema-transform.mjs';
9
9
  import { withSchemaComment, schemaCommentOptionsOf } from '../schema-comment.mjs';
@@ -84,7 +84,7 @@ function kindMember(kind, request, context) {
84
84
  }
85
85
  function componentsType(components, context, kept = /* @__PURE__ */ new Set()) {
86
86
  const aliases = {};
87
- const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;
87
+ const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;
88
88
  const isKept = (item) => kept.has(item);
89
89
  const request = { components, isKept, aliases, displaced };
90
90
  const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["alias"],"mappings":";;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAA,GAA4E;AAAA,EAChF,OAAA,EAAS,eAAA;AAAA,EACT,SAAA,EAAW,YAAA;AAAA,EACX,UAAA,EAAY,aAAA;AAAA,EACZ,aAAA,EAAe,eAAA;AAAA,EACf,OAAA,EAAS,UAAA;AAAA,EACT,SAAA,EAAW,YAAA;AAAA,EACX,UAAA,EAAY;AACd,CAAA;AASA,SAAS,eAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,QAAA,GAAW,EAAE,IAAA,EAAM,SAAA,CAAU,CAAC,YAAA,EAAc,IAAA,EAAM,IAAI,CAAC,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAC7E,EAAA,MAAM,OAAO,oBAAA,CAAqB,IAAI,CAAA,CAAE,IAAA,EAAe,UAAU,OAAO,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,SAAA,CAAU,MAAM,QAAQ,CAAA;AACzD,EAAA,MAAM,WAAW,UAAA,CAAW,cAAA,CAAe,IAAI,CAAA,EAAG,MAAA,EAAQ,QAAQ,IAAA,EAAM;AAAA,IACtE,UAAA,EAAY,QAAQ,UAAA,IAAc,KAAA;AAAA,IAClC,UAAA,EAAY,QAAQ,OAAA,CAAQ;AAAA,GAC7B,CAAA;AACD,EAAA,OAAO,kBAAkB,QAAA,EAAU,IAAA,EAAM,uBAAuB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA;AACxF;AAaA,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,OAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,OAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,wBAAA,CAAyB,IAAI,CAAC,CAAA;AAC/D,EAAA,MAAM,WAAW,IAAA,KAAS,SAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,mBAAA;AAAA,IACX,QAAQ,mBAAA,IAAuB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAO,WAAW,IAAI;AAAA,GACzE;AACA,EAAA,MAAM,YAAA,GAAe,CAACA,MAAAA,KAA0B;AAC9C,IAAA,MAAM,UAAA,GAAaA,MAAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC3C,IAAA,MAAM,YAAA,GAAe,QAAQ,uBAAA,IAA2B,QAAA;AACxD,IAAA,MAAM,aAAa,kBAAA,CAAmB,UAAU,CAAA,IAAK,CAAC,mBAAmB,UAAU,CAAA;AACnF,IAAA,OAAO,YAAA,IAAgB,aAAa,UAAA,GAAaA,MAAAA;AAAA,EACnD,CAAA;AACA,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA;AAC5B,EAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,KAAM,QAAW,OAAA,EAAA,EAAW;AAC7D,IAAA,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,IAAI,OAAO,CAAA,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,aAAa,KAAK,CAAA;AAC3B;AASA,SAAS,YAAA,CAAa,SAA4B,KAAA,EAAqC;AACrF,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,OAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AACnC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,EACzB;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AACxB;AAGA,SAAS,WAAA,CAAY,IAAA,EAAqB,IAAA,EAAe,OAAA,EAAoC;AAC3F,EAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,EAAA,OAAO,OAAA,CAAQ,aAAa,EAAE,OAAA,CAAQ,QAAQ,IAAA,KAAS,SAAA,IAAa,aAAa,IAAI,CAAA,CAAA;AACvF;AAWA,SAAS,UAAA,CACP,IAAA,EACA,OAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,EAAE,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAQ,GAAI,OAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI;AAC1C,EAAA,MAAM,QAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,eAAA,CAAgB,UAAA,CAAW,IAAI,CAAA,IAAK,EAAC,EAAG,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA,EAAG;AAC3F,IAAA,KAAA,CAAM,KAAK,eAAA,CAAgB,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC,CAAA;AACrD,IAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA,EAAG;AACpC,MAAA,YAAA,CAAa,OAAA,EAAS,aAAA,CAAc,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,SAAS,OAAO,CAAA,EAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,IAC7F;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,GAAS,CAAA,GAAI,SAAS,KAAK,CAAA,GAAI,UAAU,OAAO,CAAA;AACnE,EAAA,OAAA,CAAQ,WAAA,CAAY,KAAA;AAAA,IAClB,iCAA4B,IAAI,CAAA,CAAA;AAAA,IAChC,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI,GAAI;AAAA,GAC9B;AACA,EAAA,OAAO,UAAA,CAAW,cAAA,CAAe,IAAI,CAAA,EAAG,IAAI,CAAA;AAC9C;AAOO,SAAS,eACd,UAAA,EACA,OAAA,EACA,IAAA,mBAA4B,IAAI,KAAI,EAClB;AAGlB,EAAA,MAAM,UAAkD,EAAC;AACzD,EAAA,MAAM,SAAA,GAAY,QAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,SAAA,CAAU,mBAAmB,CAAA,GAAI,EAAC,GAAI,IAAA;AAClF,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAkB,IAAA,CAAK,IAAI,IAAc,CAAA;AACzD,EAAA,MAAM,OAAA,GAAU,EAAE,UAAA,EAAY,MAAA,EAAQ,SAAS,SAAA,EAAU;AACzD,EAAA,MAAM,aAAA,GAAgB,yBAAyB,MAAA,CAAO,CAAC,SAAS,UAAA,CAAW,IAAI,MAAM,MAAS,CAAA;AAC9F,EAAA,MAAM,UAAU,CAAC,GAAG,eAAA,EAAiB,GAAG,aAAa,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,IAAA,KAC1D,UAAA,CAAW,IAAA,EAAM,SAAS,OAAO;AAAA,GACnC;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAS,OAAO,CAAA;AAAA,IACtB,WAAW,CAAC,GAAG,WAAW,GAAI,SAAA,IAAa,EAAG;AAAA,GAChD;AACF;;"}
1
+ {"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["alias"],"mappings":";;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAA,GAA4E;AAAA,EAChF,OAAA,EAAS,eAAA;AAAA,EACT,SAAA,EAAW,YAAA;AAAA,EACX,UAAA,EAAY,aAAA;AAAA,EACZ,aAAA,EAAe,eAAA;AAAA,EACf,OAAA,EAAS,UAAA;AAAA,EACT,SAAA,EAAW,YAAA;AAAA,EACX,UAAA,EAAY;AACd,CAAA;AASA,SAAS,eAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,QAAA,GAAW,EAAE,IAAA,EAAM,SAAA,CAAU,CAAC,YAAA,EAAc,IAAA,EAAM,IAAI,CAAC,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAC7E,EAAA,MAAM,OAAO,oBAAA,CAAqB,IAAI,CAAA,CAAE,IAAA,EAAe,UAAU,OAAO,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,SAAA,CAAU,MAAM,QAAQ,CAAA;AACzD,EAAA,MAAM,WAAW,UAAA,CAAW,cAAA,CAAe,IAAI,CAAA,EAAG,MAAA,EAAQ,QAAQ,IAAA,EAAM;AAAA,IACtE,UAAA,EAAY,QAAQ,UAAA,IAAc,KAAA;AAAA,IAClC,UAAA,EAAY,QAAQ,OAAA,CAAQ;AAAA,GAC7B,CAAA;AACD,EAAA,OAAO,kBAAkB,QAAA,EAAU,IAAA,EAAM,uBAAuB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA;AACxF;AAaA,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,OAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,OAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,wBAAA,CAAyB,IAAI,CAAC,CAAA;AAC/D,EAAA,MAAM,WAAW,IAAA,KAAS,SAAA;AAC1B,EAAA,MAAM,IAAA,GAAO,mBAAA;AAAA,IACX,QAAQ,mBAAA,IAAuB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAO,WAAW,IAAI;AAAA,GACzE;AACA,EAAA,MAAM,YAAA,GAAe,CAACA,MAAAA,KAA0B;AAC9C,IAAA,MAAM,UAAA,GAAaA,MAAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC3C,IAAA,MAAM,YAAA,GAAe,QAAQ,uBAAA,IAA2B,QAAA;AACxD,IAAA,MAAM,aAAa,kBAAA,CAAmB,UAAU,CAAA,IAAK,CAAC,mBAAmB,UAAU,CAAA;AACnF,IAAA,OAAO,YAAA,IAAgB,aAAa,UAAA,GAAaA,MAAAA;AAAA,EACnD,CAAA;AACA,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA;AAC5B,EAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,KAAM,QAAW,OAAA,EAAA,EAAW;AAC7D,IAAA,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,IAAI,OAAO,CAAA,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,aAAa,KAAK,CAAA;AAC3B;AASA,SAAS,YAAA,CAAa,SAA4B,KAAA,EAAqC;AACrF,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,OAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AACnC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,EACzB;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AACxB;AAGA,SAAS,WAAA,CAAY,IAAA,EAAqB,IAAA,EAAe,OAAA,EAAoC;AAC3F,EAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,EAAA,OAAO,OAAA,CAAQ,aAAa,EAAE,OAAA,CAAQ,QAAQ,IAAA,KAAS,SAAA,IAAa,aAAa,IAAI,CAAA,CAAA;AACvF;AAWA,SAAS,UAAA,CACP,IAAA,EACA,OAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,EAAE,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAQ,GAAI,OAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI;AAC1C,EAAA,MAAM,QAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,eAAA,CAAgB,UAAA,CAAW,IAAI,CAAA,IAAK,EAAC,EAAG,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA,EAAG;AAC3F,IAAA,KAAA,CAAM,KAAK,eAAA,CAAgB,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC,CAAA;AACrD,IAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA,EAAG;AACpC,MAAA,YAAA,CAAa,OAAA,EAAS,aAAA,CAAc,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,SAAS,OAAO,CAAA,EAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,IAC7F;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,GAAS,CAAA,GAAI,SAAS,KAAK,CAAA,GAAI,UAAU,OAAO,CAAA;AACnE,EAAA,OAAA,CAAQ,WAAA,CAAY,KAAA;AAAA,IAClB,iCAA4B,IAAI,CAAA,CAAA;AAAA,IAChC,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI,GAAI;AAAA,GAC9B;AACA,EAAA,OAAO,UAAA,CAAW,cAAA,CAAe,IAAI,CAAA,EAAG,IAAI,CAAA;AAC9C;AAOO,SAAS,eACd,UAAA,EACA,OAAA,EACA,IAAA,mBAA4B,IAAI,KAAI,EAClB;AAGlB,EAAA,MAAM,UAAkD,EAAC;AACzD,EAAA,MAAM,SAAA,GAAY,QAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,GAAA,CAAI,mBAAmB,CAAA,GAAI,EAAC,GAAI,IAAA;AAC5E,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAkB,IAAA,CAAK,IAAI,IAAc,CAAA;AACzD,EAAA,MAAM,OAAA,GAAU,EAAE,UAAA,EAAY,MAAA,EAAQ,SAAS,SAAA,EAAU;AACzD,EAAA,MAAM,aAAA,GAAgB,yBAAyB,MAAA,CAAO,CAAC,SAAS,UAAA,CAAW,IAAI,MAAM,MAAS,CAAA;AAC9F,EAAA,MAAM,UAAU,CAAC,GAAG,eAAA,EAAiB,GAAG,aAAa,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,IAAA,KAC1D,UAAA,CAAW,IAAA,EAAM,SAAS,OAAO;AAAA,GACnC;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAS,OAAO,CAAA;AAAA,IACtB,WAAW,CAAC,GAAG,WAAW,GAAI,SAAA,IAAa,EAAG;AAAA,GAChD;AACF;;"}
@@ -88,7 +88,7 @@ function querystringMember(entries, location, context) {
88
88
  return schemaComment.withSchemaComment(property, querystring.resolved);
89
89
  }
90
90
  function isExplodedEntry(entry, context) {
91
- return context.options.fixes.has(outputFixes.OutputFix.EXPLODED_QUERY_OBJECTS) && explodedQuery.isExplodedQueryObject(entry.resolved, context.refs);
91
+ return context.options.fixes.has(outputFixes.FIX.EXPLODED_QUERY_OBJECTS) && explodedQuery.isExplodedQueryObject(entry.resolved, context.refs);
92
92
  }
93
93
  function explodedPart(entry, location, context) {
94
94
  const type = entryType(entry, location, context);
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.cjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":["toPropertyName","refType","createRef","parameterType","irProperty","withSchemaComment","QUERYSTRING_LOCATION","OutputFix","isExplodedQueryObject","irReference","irObject","irKeyword","irIntersection","PARAMETER_LOCATIONS"],"mappings":"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"}
1
+ {"version":3,"file":"parameters.cjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(FIX.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":["toPropertyName","refType","createRef","parameterType","irProperty","withSchemaComment","QUERYSTRING_LOCATION","FIX","isExplodedQueryObject","irReference","irObject","irKeyword","irIntersection","PARAMETER_LOCATIONS"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { irProperty, irObject, irKeyword, irIntersection, irReference } from '..
2
2
  import { toPropertyName } from '../../../domain/ir/property-name.mjs';
3
3
  import { createRef } from '../../../domain/openapi/json-pointer.mjs';
4
4
  import { PARAMETER_LOCATIONS, QUERYSTRING_LOCATION } from '../../../domain/openapi/parameter-object.mjs';
5
- import { OutputFix } from '../../../domain/output-fixes.mjs';
5
+ import { FIX } from '../../../domain/output-fixes.mjs';
6
6
  import { refType } from '../ref-type.mjs';
7
7
  import { withSchemaComment } from '../schema-comment.mjs';
8
8
  import { isExplodedQueryObject } from './exploded-query.mjs';
@@ -86,7 +86,7 @@ function querystringMember(entries, location, context) {
86
86
  return withSchemaComment(property, querystring.resolved);
87
87
  }
88
88
  function isExplodedEntry(entry, context) {
89
- return context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) && isExplodedQueryObject(entry.resolved, context.refs);
89
+ return context.options.fixes.has(FIX.EXPLODED_QUERY_OBJECTS) && isExplodedQueryObject(entry.resolved, context.refs);
90
90
  }
91
91
  function explodedPart(entry, location, context) {
92
92
  const type = entryType(entry, location, context);
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.mjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parameters.mjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(FIX.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":[],"mappings":"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"}
@@ -59,7 +59,7 @@ function pathTemplateParts(url, pathItem, context) {
59
59
  const schema = parameters.get(match.slice(1, -1))?.schema;
60
60
  return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
61
61
  });
62
- return context.options.fixes.has(outputFixes.OutputFix.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : pathTemplateReplace.replacedTemplateParts(url, matches);
62
+ return context.options.fixes.has(outputFixes.FIX.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : pathTemplateReplace.replacedTemplateParts(url, matches);
63
63
  }
64
64
  function templateText(parts) {
65
65
  const text = parts.map(
@@ -1 +1 @@
1
- {"version":3,"file":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_PARAMETER_RE = /\\{[^{}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["pathItemOperations","OutputFix","replacedTemplateParts","escapeTemplateText","placeholderText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
1
+ {"version":3,"file":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_PARAMETER_RE = /\\{[^{}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["pathItemOperations","FIX","replacedTemplateParts","escapeTemplateText","placeholderText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { toPropertyName } from '../../../domain/ir/property-name.mjs';
3
3
  import { escapeTemplateText } from '../../../domain/ir/raw-text-escapes.mjs';
4
4
  import { createRef } from '../../../domain/openapi/json-pointer.mjs';
5
5
  import { pathItemOperations } from '../../../domain/openapi/path-item-object.mjs';
6
- import { OutputFix } from '../../../domain/output-fixes.mjs';
6
+ import { FIX } from '../../../domain/output-fixes.mjs';
7
7
  import { documentEntries } from '../document-entries.mjs';
8
8
  import { refType } from '../ref-type.mjs';
9
9
  import { NO_DECLARED_TYPES } from './declared-types.mjs';
@@ -57,7 +57,7 @@ function pathTemplateParts(url, pathItem, context) {
57
57
  const schema = parameters.get(match.slice(1, -1))?.schema;
58
58
  return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
59
59
  });
60
- return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : replacedTemplateParts(url, matches);
60
+ return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : replacedTemplateParts(url, matches);
61
61
  }
62
62
  function templateText(parts) {
63
63
  const text = parts.map(
@@ -1 +1 @@
1
- {"version":3,"file":"paths.mjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_PARAMETER_RE = /\\{[^{}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["member"],"mappings":"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"}
1
+ {"version":3,"file":"paths.mjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_PARAMETER_RE = /\\{[^{}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["member"],"mappings":"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"}
@@ -39,7 +39,7 @@ function correctedType(ref, pointer, request, seen) {
39
39
  }
40
40
  function isCorrected(pointer, request) {
41
41
  const { options, refs } = request.context;
42
- return options.fixes.has(outputFixes.OutputFix.REF_POINTERS) || originalIndex.originalIndexFails({ pointer, options, refs });
42
+ return options.fixes.has(outputFixes.FIX.REF_POINTERS) || originalIndex.originalIndexFails({ pointer, options, refs });
43
43
  }
44
44
  function schemaRefType(ref, request, seen = []) {
45
45
  const pointer = pointerOf(ref);
@@ -1 +1 @@
1
- {"version":3,"file":"pointer-type.cjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return (\n options.fixes.has(OutputFix.REF_POINTERS) || originalIndexFails({ pointer, options, refs })\n );\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":["refPointerOf","InvalidRefError","pointerNode","isJsonObject","hasInlineCycle","generatedLocationOf","typedWalk","OutputFix","originalIndexFails","leadingSegmentsOf","refType","irReference"],"mappings":"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"}
1
+ {"version":3,"file":"pointer-type.cjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":["refPointerOf","InvalidRefError","pointerNode","isJsonObject","hasInlineCycle","generatedLocationOf","typedWalk","FIX","originalIndexFails","leadingSegmentsOf","refType","irReference"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { irReference } from '../../../domain/ir/constructors.mjs';
2
- import { OutputFix } from '../../../domain/output-fixes.mjs';
2
+ import { FIX } from '../../../domain/output-fixes.mjs';
3
3
  import { refType, InvalidRefError } from '../ref-type.mjs';
4
4
  import { generatedLocationOf } from './generated-location.mjs';
5
5
  import { isJsonObject } from './generated-shape.mjs';
@@ -37,7 +37,7 @@ function correctedType(ref, pointer, request, seen) {
37
37
  }
38
38
  function isCorrected(pointer, request) {
39
39
  const { options, refs } = request.context;
40
- return options.fixes.has(OutputFix.REF_POINTERS) || originalIndexFails({ pointer, options, refs });
40
+ return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });
41
41
  }
42
42
  function schemaRefType(ref, request, seen = []) {
43
43
  const pointer = pointerOf(ref);
@@ -1 +1 @@
1
- {"version":3,"file":"pointer-type.mjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return (\n options.fixes.has(OutputFix.REF_POINTERS) || originalIndexFails({ pointer, options, refs })\n );\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pointer-type.mjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@ function propertyAccessFlags(value, context) {
28
28
  if (typeof value !== "object") {
29
29
  return NO_FLAGS;
30
30
  }
31
- if (!context.options.fixes.has(outputFixes.OutputFix.READ_WRITE_REFS)) {
31
+ if (!context.options.fixes.has(outputFixes.FIX.READ_WRITE_REFS)) {
32
32
  return ownFlags(value);
33
33
  }
34
34
  return appliedFlags(value, context, /* @__PURE__ */ new Set());