openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +15 -5
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +15 -5
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +3 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +3 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs +25 -0
- package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
- package/dist/api/discriminator-conflict-warnings.mjs +23 -0
- package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
- package/dist/api/discriminator-enum-names.cjs +19 -0
- package/dist/api/discriminator-enum-names.cjs.map +1 -0
- package/dist/api/discriminator-enum-names.mjs +17 -0
- package/dist/api/discriminator-enum-names.mjs.map +1 -0
- package/dist/api/discriminator-enum-parent.cjs +59 -0
- package/dist/api/discriminator-enum-parent.cjs.map +1 -0
- package/dist/api/discriminator-enum-parent.mjs +57 -0
- package/dist/api/discriminator-enum-parent.mjs.map +1 -0
- package/dist/api/discriminator-enum.cjs +25 -0
- package/dist/api/discriminator-enum.cjs.map +1 -1
- package/dist/api/discriminator-enum.mjs +25 -1
- package/dist/api/discriminator-enum.mjs.map +1 -1
- package/dist/api/discriminator-other-owners.cjs +67 -0
- package/dist/api/discriminator-other-owners.cjs.map +1 -0
- package/dist/api/discriminator-other-owners.mjs +64 -0
- package/dist/api/discriminator-other-owners.mjs.map +1 -0
- package/dist/api/discriminator-patch.cjs +88 -0
- package/dist/api/discriminator-patch.cjs.map +1 -0
- package/dist/api/discriminator-patch.mjs +82 -0
- package/dist/api/discriminator-patch.mjs.map +1 -0
- package/dist/api/discriminator-scan.cjs +50 -65
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +44 -59
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-run.cjs +18 -3
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +19 -4
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/enum-values-warnings.cjs +16 -0
- package/dist/api/enum-values-warnings.cjs.map +1 -0
- package/dist/api/enum-values-warnings.mjs +14 -0
- package/dist/api/enum-values-warnings.mjs.map +1 -0
- package/dist/api/path-template-warnings.cjs +21 -0
- package/dist/api/path-template-warnings.cjs.map +1 -0
- package/dist/api/path-template-warnings.mjs +19 -0
- package/dist/api/path-template-warnings.mjs.map +1 -0
- package/dist/api/transform-context.cjs +3 -1
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +3 -1
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +52 -3
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +53 -4
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.cjs +6 -1
- package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.mjs +6 -1
- package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
- package/dist/application/print/type-printer.cjs +5 -0
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +5 -0
- package/dist/application/print/type-printer.mjs.map +1 -1
- package/dist/application/transform/document/assignability.cjs +144 -0
- package/dist/application/transform/document/assignability.cjs.map +1 -0
- package/dist/application/transform/document/assignability.mjs +138 -0
- package/dist/application/transform/document/assignability.mjs.map +1 -0
- package/dist/application/transform/document/components.cjs +2 -2
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +4 -4
- package/dist/application/transform/document/components.mjs.map +1 -1
- package/dist/application/transform/document/declared-types.cjs +66 -0
- package/dist/application/transform/document/declared-types.cjs.map +1 -0
- package/dist/application/transform/document/declared-types.mjs +63 -0
- package/dist/application/transform/document/declared-types.mjs.map +1 -0
- package/dist/application/transform/document/document.cjs +32 -9
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +34 -11
- package/dist/application/transform/document/document.mjs.map +1 -1
- package/dist/application/transform/document/exploded-query.cjs +46 -0
- package/dist/application/transform/document/exploded-query.cjs.map +1 -0
- package/dist/application/transform/document/exploded-query.mjs +43 -0
- package/dist/application/transform/document/exploded-query.mjs.map +1 -0
- package/dist/application/transform/document/global-type-references.cjs +63 -0
- package/dist/application/transform/document/global-type-references.cjs.map +1 -0
- package/dist/application/transform/document/global-type-references.mjs +61 -0
- package/dist/application/transform/document/global-type-references.mjs.map +1 -0
- package/dist/application/transform/document/list-assignability.cjs +54 -0
- package/dist/application/transform/document/list-assignability.cjs.map +1 -0
- package/dist/application/transform/document/list-assignability.mjs +52 -0
- package/dist/application/transform/document/list-assignability.mjs.map +1 -0
- package/dist/application/transform/document/parameters.cjs +40 -8
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +41 -9
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
- package/dist/application/transform/document/path-template-replace.cjs +48 -0
- package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
- package/dist/application/transform/document/path-template-replace.mjs +45 -0
- package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
- package/dist/application/transform/document/paths.cjs +54 -28
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +53 -29
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.cjs +15 -14
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.mjs +15 -13
- package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
- package/dist/application/transform/document/template-key-match.cjs +128 -0
- package/dist/application/transform/document/template-key-match.cjs.map +1 -0
- package/dist/application/transform/document/template-key-match.mjs +125 -0
- package/dist/application/transform/document/template-key-match.mjs.map +1 -0
- package/dist/application/transform/document/type-assignability.cjs +192 -0
- package/dist/application/transform/document/type-assignability.cjs.map +1 -0
- package/dist/application/transform/document/type-assignability.mjs +190 -0
- package/dist/application/transform/document/type-assignability.mjs.map +1 -0
- package/dist/application/transform/document/type-key.cjs +70 -0
- package/dist/application/transform/document/type-key.cjs.map +1 -0
- package/dist/application/transform/document/type-key.mjs +68 -0
- package/dist/application/transform/document/type-key.mjs.map +1 -0
- package/dist/application/transform/document/type-resolution.cjs +131 -0
- package/dist/application/transform/document/type-resolution.cjs.map +1 -0
- package/dist/application/transform/document/type-resolution.mjs +125 -0
- package/dist/application/transform/document/type-resolution.mjs.map +1 -0
- package/dist/application/transform/footer/document-footer.cjs +66 -4
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +67 -5
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.cjs +17 -0
- package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.mjs +17 -1
- package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
- package/dist/application/transform/footer/enum-values-check.cjs +129 -0
- package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
- package/dist/application/transform/footer/enum-values-check.mjs +127 -0
- package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
- package/dist/application/transform/footer/evaluation.cjs +33 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/evaluation.mjs +26 -0
- package/dist/application/transform/footer/evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
- package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
- package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.cjs +246 -0
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.mjs +244 -0
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/type-rules.cjs +172 -0
- package/dist/application/transform/footer/type-rules.cjs.map +1 -0
- package/dist/application/transform/footer/type-rules.mjs +166 -0
- package/dist/application/transform/footer/type-rules.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
- package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
- package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
- package/dist/application/transform/ref-type.cjs +7 -2
- package/dist/application/transform/ref-type.cjs.map +1 -1
- package/dist/application/transform/ref-type.mjs +3 -2
- package/dist/application/transform/ref-type.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs +38 -0
- package/dist/application/transform/schema/access-flags.cjs.map +1 -0
- package/dist/application/transform/schema/access-flags.mjs +36 -0
- package/dist/application/transform/schema/access-flags.mjs.map +1 -0
- package/dist/application/transform/schema/array-type.cjs +32 -1
- package/dist/application/transform/schema/array-type.cjs.map +1 -1
- package/dist/application/transform/schema/array-type.mjs +33 -2
- package/dist/application/transform/schema/array-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +50 -15
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +50 -15
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/core-type.cjs +3 -1
- package/dist/application/transform/schema/core-type.cjs.map +1 -1
- package/dist/application/transform/schema/core-type.mjs +3 -1
- package/dist/application/transform/schema/core-type.mjs.map +1 -1
- package/dist/application/transform/schema/discriminated-union.cjs +30 -0
- package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
- package/dist/application/transform/schema/discriminated-union.mjs +27 -0
- package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.cjs +3 -2
- package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
- package/dist/application/transform/schema/discriminator-property.mjs +3 -2
- package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +66 -10
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +67 -12
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
- package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +38 -25
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +39 -27
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- package/dist/application/transform/schema/required-variants.cjs +45 -0
- package/dist/application/transform/schema/required-variants.cjs.map +1 -0
- package/dist/application/transform/schema/required-variants.mjs +42 -0
- package/dist/application/transform/schema/required-variants.mjs.map +1 -0
- package/dist/application/transform/schema/schema-transform.cjs +2 -2
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +2 -2
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +51 -5
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +50 -6
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/application/transform/type-combinators.mjs +1 -1
- package/dist/cli/cli-arguments.cjs +11 -3
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +11 -3
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/cli-errors.cjs +3 -2
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +3 -2
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-output.cjs +8 -3
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +9 -4
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/main.cjs +5 -0
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +5 -0
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +7 -3
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +8 -4
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/ref-limits.cjs +1 -1
- package/dist/cli/ref-limits.cjs.map +1 -1
- package/dist/cli/ref-limits.mjs +2 -2
- package/dist/cli/ref-limits.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +15 -2
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +16 -3
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/errors.cjs +2 -0
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +2 -0
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +5 -1
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +5 -2
- package/dist/domain/ir/constructors.mjs.map +1 -1
- package/dist/domain/openapi/admitted-values.cjs +75 -0
- package/dist/domain/openapi/admitted-values.cjs.map +1 -0
- package/dist/domain/openapi/admitted-values.mjs +72 -0
- package/dist/domain/openapi/admitted-values.mjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.cjs +68 -0
- package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.mjs +62 -0
- package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
- package/dist/domain/openapi/parameter-object.cjs.map +1 -1
- package/dist/domain/openapi/parameter-object.mjs.map +1 -1
- package/dist/domain/openapi/path-templates.cjs +23 -0
- package/dist/domain/openapi/path-templates.cjs.map +1 -0
- package/dist/domain/openapi/path-templates.mjs +21 -0
- package/dist/domain/openapi/path-templates.mjs.map +1 -0
- package/dist/domain/output-fixes.cjs +36 -1
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +36 -1
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/warnings.cjs +15 -0
- package/dist/domain/warnings.cjs.map +1 -0
- package/dist/domain/warnings.mjs +12 -0
- package/dist/domain/warnings.mjs.map +1 -0
- package/dist/index.d.cts +29 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/transform/components-object.cjs +2 -1
- package/dist/transform/components-object.cjs.map +1 -1
- package/dist/transform/components-object.mjs +2 -1
- package/dist/transform/components-object.mjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -6
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +3 -0
- package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
- package/src/api/discriminator-conflict-warnings.ts +43 -0
- package/src/api/discriminator-enum-names.ts +26 -0
- package/src/api/discriminator-enum-parent.ts +129 -0
- package/src/api/discriminator-enum.ts +39 -0
- package/src/api/discriminator-other-owners.ts +97 -0
- package/src/api/discriminator-patch.ts +147 -0
- package/src/api/discriminator-scan.ts +78 -90
- package/src/api/document-run.ts +24 -6
- package/src/api/enum-values-warnings.ts +21 -0
- package/src/api/path-template-warnings.ts +27 -0
- package/src/api/transform-context.ts +7 -1
- package/src/api/transform-schema.ts +88 -4
- package/src/api/unsupported-feature-warnings.ts +8 -1
- package/src/application/ports/redocly-config-source.ts +5 -1
- package/src/application/print/type-printer.ts +6 -0
- package/src/application/transform/document/assignability.ts +203 -0
- package/src/application/transform/document/components.ts +6 -6
- package/src/application/transform/document/declared-types.ts +93 -0
- package/src/application/transform/document/document.ts +71 -13
- package/src/application/transform/document/exploded-query.ts +91 -0
- package/src/application/transform/document/global-type-references.ts +78 -0
- package/src/application/transform/document/list-assignability.ts +87 -0
- package/src/application/transform/document/parameters.ts +76 -11
- package/src/application/transform/document/path-key-overlaps.ts +148 -59
- package/src/application/transform/document/path-template-replace.ts +90 -0
- package/src/application/transform/document/paths.ts +99 -37
- package/src/application/transform/document/root-type-aliases.ts +29 -28
- package/src/application/transform/document/template-key-match.ts +183 -0
- package/src/application/transform/document/type-assignability.ts +268 -0
- package/src/application/transform/document/type-key.ts +80 -0
- package/src/application/transform/document/type-resolution.ts +163 -0
- package/src/application/transform/footer/document-footer.ts +91 -6
- package/src/application/transform/footer/enum-naming.ts +29 -0
- package/src/application/transform/footer/enum-values-check.ts +171 -0
- package/src/application/transform/footer/evaluation.ts +47 -0
- package/src/application/transform/footer/shared-enum-names.ts +86 -0
- package/src/application/transform/footer/type-evaluation.ts +294 -0
- package/src/application/transform/footer/type-rules.ts +269 -0
- package/src/application/transform/ref-pointer/generated-location.ts +211 -0
- package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
- package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
- package/src/application/transform/ref-pointer/original-index.ts +95 -0
- package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
- package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
- package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
- package/src/application/transform/ref-type.ts +11 -6
- package/src/application/transform/schema/access-flags.ts +63 -0
- package/src/application/transform/schema/array-type.ts +66 -5
- package/src/application/transform/schema/composition-type.ts +96 -24
- package/src/application/transform/schema/core-type.ts +8 -4
- package/src/application/transform/schema/discriminated-union.ts +58 -0
- package/src/application/transform/schema/discriminator-property.ts +8 -3
- package/src/application/transform/schema/enum-rule.ts +136 -13
- package/src/application/transform/schema/inherited-discriminator.ts +54 -0
- package/src/application/transform/schema/object-type.ts +51 -33
- package/src/application/transform/schema/required-variants.ts +88 -0
- package/src/application/transform/schema/schema-context.ts +26 -0
- package/src/application/transform/schema/schema-transform.ts +2 -2
- package/src/application/transform/schema-comment.ts +84 -4
- package/src/cli/cli-arguments.ts +13 -3
- package/src/cli/cli-dependencies.ts +5 -0
- package/src/cli/cli-errors.ts +4 -2
- package/src/cli/cli-output.ts +18 -4
- package/src/cli/main.ts +6 -0
- package/src/cli/redocly-apis.ts +8 -4
- package/src/cli/ref-limits.ts +2 -2
- package/src/cli/run-cli.ts +20 -3
- package/src/domain/errors.ts +2 -0
- package/src/domain/ir/constructors.ts +6 -1
- package/src/domain/ir/nodes.ts +2 -1
- package/src/domain/openapi/admitted-values.ts +113 -0
- package/src/domain/openapi/discriminated-union.ts +109 -0
- package/src/domain/openapi/discriminator-conflicts.ts +251 -0
- package/src/domain/openapi/parameter-object.ts +4 -0
- package/src/domain/openapi/path-templates.ts +31 -0
- package/src/domain/openapi/schema-object.ts +2 -0
- package/src/domain/output-fixes.ts +43 -2
- package/src/domain/warnings.ts +20 -0
- package/src/transform/components-object.ts +3 -1
- package/src/types/generator-options.ts +11 -0
- package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
- package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
- package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
- package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
- package/src/application/transform/document/path-item-conflicts.ts +0 -79
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript-to-ir.cjs","sources":["../../../src/adapters/type-ast-bridge/typescript-to-ir.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { irRaw } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport { asRaw, isIrNode, needsPrintedText } from \"./typescript-raw-text.js\";\n\n/**\n * Read TypeScript type nodes from user callbacks into IR (ADR-004, decision 3). Synthesized nodes\n * are mapped by structure. Anything the IR cannot express exactly is printed with the TypeScript\n * printer, the way the original output it, and kept as a `raw` node: parsed nodes, nodes with\n * comments, explicit parentheses, single-quoted strings, numbers not in canonical form, and syntax\n * the IR does not model. Every function takes the user's TypeScript module (ADR-004, decision 4):\n * `SyntaxKind` numbers differ between versions, so a node is read with the module that made it.\n */\n\nfunction keywordOf(ts: TypeScriptModule, kind: ts.SyntaxKind): IrKeyword | undefined {\n const keywords: ReadonlyMap<ts.SyntaxKind, IrKeyword> = new Map([\n [ts.SyntaxKind.StringKeyword, \"string\"],\n [ts.SyntaxKind.NumberKeyword, \"number\"],\n [ts.SyntaxKind.BooleanKeyword, \"boolean\"],\n [ts.SyntaxKind.UndefinedKeyword, \"undefined\"],\n [ts.SyntaxKind.UnknownKeyword, \"unknown\"],\n [ts.SyntaxKind.NeverKeyword, \"never\"],\n ]);\n return keywords.get(kind);\n}\n\nfunction isCanonicalNumber(text: string): boolean {\n return String(Number(text)) === text;\n}\n\nfunction fromNumber(ts: TypeScriptModule, literal: ts.Expression): IrType | null {\n if (ts.isNumericLiteral(literal)) {\n return isCanonicalNumber(literal.text)\n ? { kind: \"numberLiteral\", value: Number(literal.text) }\n : null;\n }\n const isNegative =\n ts.isPrefixUnaryExpression(literal) &&\n literal.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(literal.operand) &&\n isCanonicalNumber(literal.operand.text) &&\n Number(literal.operand.text) !== 0;\n return isNegative\n ? { kind: \"numberLiteral\", value: -Number((literal.operand as ts.NumericLiteral).text) }\n : null;\n}\n\nfunction fromLiteral(ts: TypeScriptModule, node: ts.LiteralTypeNode): IrType | null {\n const { literal } = node;\n if (ts.isStringLiteral(literal)) {\n const isSingleQuoted = (literal as { singleQuote?: boolean }).singleQuote === true;\n return isSingleQuoted\n ? null\n : { kind: \"stringLiteral\", value: literal.text, encoding: \"escaped\" };\n }\n if (literal.kind === ts.SyntaxKind.NullKeyword) {\n return { kind: \"keyword\", keyword: \"null\" };\n }\n if (literal.kind === ts.SyntaxKind.TrueKeyword || literal.kind === ts.SyntaxKind.FalseKeyword) {\n return { kind: \"booleanLiteral\", value: literal.kind === ts.SyntaxKind.TrueKeyword };\n }\n return fromNumber(ts, literal);\n}\n\n/** Converts the children of one node, which becomes their parent. */\nfunction childrenOf(ts: TypeScriptModule, parent: ts.Node): (child: ts.TypeNode) => IrType {\n return (child) => fromTypeNode(ts, child, parent);\n}\n\nfunction fromReference(ts: TypeScriptModule, node: ts.TypeReferenceNode): IrType | null {\n if (!ts.isIdentifier(node.typeName)) {\n return null;\n }\n const typeArguments = (node.typeArguments ?? []).map(childrenOf(ts, node));\n return { kind: \"reference\", name: ts.idText(node.typeName), typeArguments };\n}\n\nfunction fromTuple(ts: TypeScriptModule, node: ts.TupleTypeNode): IrType | null {\n const isPlain = node.elements.every(\n (element) => !ts.isNamedTupleMember(element) && !ts.isOptionalTypeNode(element),\n );\n if (!isPlain) {\n return null;\n }\n const convert = childrenOf(ts, node);\n const elements = node.elements.map((element) =>\n ts.isRestTypeNode(element)\n ? { type: convert(element.type), isRest: true }\n : { type: convert(element), isRest: false },\n );\n return { kind: \"tuple\", elements };\n}\n\n/**\n * Leading comments in order, or null when the IR cannot hold them: trailing comments, or a\n * comment without a line break after it (the IR always writes one).\n */\nfunction fromComments(ts: TypeScriptModule, node: ts.Node): IrComment[] | null {\n const comments = ts.getSyntheticLeadingComments(node) ?? [];\n const hasTrailing = (ts.getSyntheticTrailingComments(node)?.length ?? 0) > 0;\n if (hasTrailing || comments.some((comment) => !comment.hasTrailingNewLine)) {\n return null;\n }\n return comments.map((comment) => ({\n kind: comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? \"block\" : \"line\",\n text: comment.text,\n }));\n}\n\nfunction fromPropertyName(ts: TypeScriptModule, name: ts.PropertyName): IrPropertyName | null {\n if (ts.isIdentifier(name)) {\n return { kind: \"identifier\", text: ts.idText(name) };\n }\n if (ts.isStringLiteral(name) && (name as { singleQuote?: boolean }).singleQuote !== true) {\n return { kind: \"string\", value: name.text };\n }\n return ts.isNumericLiteral(name) ? { kind: \"number\", text: name.text } : null;\n}\n\n/** Only `readonly` is modeled; any other modifier makes the member unreadable as IR. */\nfunction readonlyFlag(ts: TypeScriptModule, node: ts.TypeElement): boolean | null {\n const modifiers = ts.canHaveModifiers(node) ? (ts.getModifiers(node) ?? []) : [];\n const isOnlyReadonly = modifiers.every(\n (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword,\n );\n return isOnlyReadonly ? modifiers.length > 0 : null;\n}\n\n/** A property signature as IR, or null when it uses syntax the IR does not model. */\nexport function fromPropertySignature(\n ts: TypeScriptModule,\n node: ts.PropertySignature,\n): IrPropertySignature | null {\n const name = fromPropertyName(ts, node.name);\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n if (name === null || comments === null || isReadonly === null || node.type === undefined) {\n return null;\n }\n return {\n kind: \"property\",\n name,\n type: fromTypeNode(ts, node.type, node),\n isOptional: node.questionToken !== undefined,\n isReadonly,\n comments,\n };\n}\n\nfunction fromIndexSignature(\n ts: TypeScriptModule,\n node: ts.IndexSignatureDeclaration,\n): IrMember | null {\n const [parameter, ...others] = node.parameters;\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n const isPlain =\n parameter?.type !== undefined && ts.isIdentifier(parameter.name) && others.length === 0;\n if (!isPlain || comments === null || isReadonly === null) {\n return null;\n }\n return {\n kind: \"indexSignature\",\n parameterName: ts.idText(parameter.name as ts.Identifier),\n parameterType: fromTypeNode(ts, parameter.type as ts.TypeNode, node),\n type: fromTypeNode(ts, node.type, node),\n isReadonly,\n comments,\n };\n}\n\nfunction fromMember(ts: TypeScriptModule, member: ts.TypeElement): IrMember | null {\n if (member.pos >= 0) {\n return null;\n }\n if (ts.isPropertySignature(member)) {\n return fromPropertySignature(ts, member);\n }\n return ts.isIndexSignatureDeclaration(member) ? fromIndexSignature(ts, member) : null;\n}\n\nfunction fromTypeLiteral(ts: TypeScriptModule, node: ts.TypeLiteralNode): IrType | null {\n const members = node.members.map((member) => fromMember(ts, member));\n const isReadable = members.every((member) => member !== null);\n return isReadable ? { kind: \"object\", members: members as IrMember[] } : null;\n}\n\nfunction fromComposite(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const convert = childrenOf(ts, node);\n if (ts.isArrayTypeNode(node)) {\n return { kind: \"array\", element: convert(node.elementType) };\n }\n if (ts.isUnionTypeNode(node)) {\n return { kind: \"union\", types: node.types.map(convert) };\n }\n if (ts.isIntersectionTypeNode(node)) {\n return { kind: \"intersection\", types: node.types.map(convert) };\n }\n if (ts.isIndexedAccessTypeNode(node)) {\n return {\n kind: \"indexedAccess\",\n object: convert(node.objectType),\n index: convert(node.indexType),\n };\n }\n if (ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return { kind: \"readonly\", type: convert(node.type) };\n }\n return ts.isTypeLiteralNode(node) ? fromTypeLiteral(ts, node) : null;\n}\n\nfunction fromStructure(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const keyword = keywordOf(ts, node.kind);\n if (keyword !== undefined) {\n return { kind: \"keyword\", keyword };\n }\n if (ts.isIdentifier(node)) {\n // The original writes JSON string literals and some references as bare identifiers.\n return irRaw(ts.idText(node));\n }\n if (ts.isLiteralTypeNode(node)) {\n return fromLiteral(ts, node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return fromReference(ts, node);\n }\n return ts.isTupleTypeNode(node) ? fromTuple(ts, node) : fromComposite(ts, node);\n}\n\n/**\n * Whether the factory's parenthesizer put these parentheses in (same rules as the IR printer):\n * unions, intersections and `readonly` types as array elements, indexed objects and `readonly`\n * operands; unions and intersections as members of other unions or intersections.\n */\nfunction isFactoryParenthesis(\n ts: TypeScriptModule,\n inner: ts.TypeNode,\n parent: ts.Node | undefined,\n): boolean {\n if (parent === undefined) {\n return false;\n }\n const isComposite = ts.isUnionTypeNode(inner) || ts.isIntersectionTypeNode(inner);\n const isPostfixOrReadonlyParent =\n ts.isArrayTypeNode(parent) ||\n ts.isIndexedAccessTypeNode(parent) ||\n ts.isTypeOperatorNode(parent);\n if (isPostfixOrReadonlyParent) {\n return isComposite || ts.isTypeOperatorNode(inner);\n }\n const isCompositeParent = ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent);\n return isCompositeParent && isComposite;\n}\n\n/**\n * Convert a type node. `parent` is the node that contains it: synthesized nodes have no `parent`\n * link, and it is needed to tell parentheses the factory inserted from ones the user wrote.\n */\nexport function fromTypeNode(ts: TypeScriptModule, node: ts.TypeNode, parent?: ts.Node): IrType {\n if (isIrNode(node)) {\n return node;\n }\n if (needsPrintedText(ts, node)) {\n return asRaw(ts, node);\n }\n if (ts.isParenthesizedTypeNode(node)) {\n return isFactoryParenthesis(ts, node.type, parent)\n ? fromTypeNode(ts, node.type, parent)\n : asRaw(ts, node);\n }\n return fromStructure(ts, node) ?? asRaw(ts, node);\n}\n"],"names":["irRaw","isIrNode","needsPrintedText","asRaw"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typescript-to-ir.cjs","sources":["../../../src/adapters/type-ast-bridge/typescript-to-ir.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { irRaw } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport { asRaw, isIrNode, needsPrintedText } from \"./typescript-raw-text.js\";\n\n/**\n * Read TypeScript type nodes from user callbacks into IR (ADR-004, decision 3). Synthesized nodes\n * are mapped by structure. Anything the IR cannot express exactly is printed with the TypeScript\n * printer, the way the original output it, and kept as a `raw` node: parsed nodes, nodes with\n * comments, explicit parentheses, single-quoted strings, numbers not in canonical form, and syntax\n * the IR does not model. Every function takes the user's TypeScript module (ADR-004, decision 4):\n * `SyntaxKind` numbers differ between versions, so a node is read with the module that made it.\n */\n\nfunction keywordOf(ts: TypeScriptModule, kind: ts.SyntaxKind): IrKeyword | undefined {\n const keywords: ReadonlyMap<ts.SyntaxKind, IrKeyword> = new Map([\n [ts.SyntaxKind.StringKeyword, \"string\"],\n [ts.SyntaxKind.NumberKeyword, \"number\"],\n [ts.SyntaxKind.BooleanKeyword, \"boolean\"],\n [ts.SyntaxKind.UndefinedKeyword, \"undefined\"],\n [ts.SyntaxKind.UnknownKeyword, \"unknown\"],\n [ts.SyntaxKind.NeverKeyword, \"never\"],\n ]);\n return keywords.get(kind);\n}\n\nfunction isCanonicalNumber(text: string): boolean {\n return String(Number(text)) === text;\n}\n\nfunction fromNumber(ts: TypeScriptModule, literal: ts.Expression): IrType | null {\n if (ts.isNumericLiteral(literal)) {\n return isCanonicalNumber(literal.text)\n ? { kind: \"numberLiteral\", value: Number(literal.text) }\n : null;\n }\n const isNegative =\n ts.isPrefixUnaryExpression(literal) &&\n literal.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(literal.operand) &&\n isCanonicalNumber(literal.operand.text) &&\n Number(literal.operand.text) !== 0;\n return isNegative\n ? { kind: \"numberLiteral\", value: -Number((literal.operand as ts.NumericLiteral).text) }\n : null;\n}\n\nfunction fromLiteral(ts: TypeScriptModule, node: ts.LiteralTypeNode): IrType | null {\n const { literal } = node;\n if (ts.isStringLiteral(literal)) {\n const isSingleQuoted = (literal as { singleQuote?: boolean }).singleQuote === true;\n return isSingleQuoted\n ? null\n : { kind: \"stringLiteral\", value: literal.text, encoding: \"escaped\" };\n }\n if (literal.kind === ts.SyntaxKind.NullKeyword) {\n return { kind: \"keyword\", keyword: \"null\" };\n }\n if (literal.kind === ts.SyntaxKind.TrueKeyword || literal.kind === ts.SyntaxKind.FalseKeyword) {\n return { kind: \"booleanLiteral\", value: literal.kind === ts.SyntaxKind.TrueKeyword };\n }\n return fromNumber(ts, literal);\n}\n\n/** Converts the children of one node, which becomes their parent. */\nfunction childrenOf(ts: TypeScriptModule, parent: ts.Node): (child: ts.TypeNode) => IrType {\n return (child) => fromTypeNode(ts, child, parent);\n}\n\nfunction fromReference(ts: TypeScriptModule, node: ts.TypeReferenceNode): IrType | null {\n if (!ts.isIdentifier(node.typeName)) {\n return null;\n }\n const typeArguments = (node.typeArguments ?? []).map(childrenOf(ts, node));\n return { kind: \"reference\", name: ts.idText(node.typeName), typeArguments };\n}\n\nfunction fromTupleElement(\n ts: TypeScriptModule,\n element: ts.TypeNode,\n convert: (node: ts.TypeNode) => IrType,\n): IrTupleElement {\n if (ts.isRestTypeNode(element)) {\n return { type: convert(element.type), isRest: true, isOptional: false };\n }\n if (ts.isOptionalTypeNode(element)) {\n // The `?` is the parent of the type: it decides which parentheses the factory put in.\n return { type: fromTypeNode(ts, element.type, element), isRest: false, isOptional: true };\n }\n return { type: convert(element), isRest: false, isOptional: false };\n}\n\n/** A tuple of plain, rest and optional elements; one with named members stays text. */\nfunction fromTuple(ts: TypeScriptModule, node: ts.TupleTypeNode): IrType | null {\n if (node.elements.some((element) => ts.isNamedTupleMember(element))) {\n return null;\n }\n const convert = childrenOf(ts, node);\n return {\n kind: \"tuple\",\n elements: node.elements.map((element) => fromTupleElement(ts, element, convert)),\n };\n}\n\n/**\n * Leading comments in order, or null when the IR cannot hold them: trailing comments, or a\n * comment without a line break after it (the IR always writes one).\n */\nfunction fromComments(ts: TypeScriptModule, node: ts.Node): IrComment[] | null {\n const comments = ts.getSyntheticLeadingComments(node) ?? [];\n const hasTrailing = (ts.getSyntheticTrailingComments(node)?.length ?? 0) > 0;\n if (hasTrailing || comments.some((comment) => !comment.hasTrailingNewLine)) {\n return null;\n }\n return comments.map((comment) => ({\n kind: comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? \"block\" : \"line\",\n text: comment.text,\n }));\n}\n\nfunction fromPropertyName(ts: TypeScriptModule, name: ts.PropertyName): IrPropertyName | null {\n if (ts.isIdentifier(name)) {\n return { kind: \"identifier\", text: ts.idText(name) };\n }\n if (ts.isStringLiteral(name) && (name as { singleQuote?: boolean }).singleQuote !== true) {\n return { kind: \"string\", value: name.text };\n }\n return ts.isNumericLiteral(name) ? { kind: \"number\", text: name.text } : null;\n}\n\n/** Only `readonly` is modeled; any other modifier makes the member unreadable as IR. */\nfunction readonlyFlag(ts: TypeScriptModule, node: ts.TypeElement): boolean | null {\n const modifiers = ts.canHaveModifiers(node) ? (ts.getModifiers(node) ?? []) : [];\n const isOnlyReadonly = modifiers.every(\n (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword,\n );\n return isOnlyReadonly ? modifiers.length > 0 : null;\n}\n\n/** A property signature as IR, or null when it uses syntax the IR does not model. */\nexport function fromPropertySignature(\n ts: TypeScriptModule,\n node: ts.PropertySignature,\n): IrPropertySignature | null {\n const name = fromPropertyName(ts, node.name);\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n if (name === null || comments === null || isReadonly === null || node.type === undefined) {\n return null;\n }\n return {\n kind: \"property\",\n name,\n type: fromTypeNode(ts, node.type, node),\n isOptional: node.questionToken !== undefined,\n isReadonly,\n comments,\n };\n}\n\nfunction fromIndexSignature(\n ts: TypeScriptModule,\n node: ts.IndexSignatureDeclaration,\n): IrMember | null {\n const [parameter, ...others] = node.parameters;\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n const isPlain =\n parameter?.type !== undefined && ts.isIdentifier(parameter.name) && others.length === 0;\n if (!isPlain || comments === null || isReadonly === null) {\n return null;\n }\n return {\n kind: \"indexSignature\",\n parameterName: ts.idText(parameter.name as ts.Identifier),\n parameterType: fromTypeNode(ts, parameter.type as ts.TypeNode, node),\n type: fromTypeNode(ts, node.type, node),\n isReadonly,\n comments,\n };\n}\n\nfunction fromMember(ts: TypeScriptModule, member: ts.TypeElement): IrMember | null {\n if (member.pos >= 0) {\n return null;\n }\n if (ts.isPropertySignature(member)) {\n return fromPropertySignature(ts, member);\n }\n return ts.isIndexSignatureDeclaration(member) ? fromIndexSignature(ts, member) : null;\n}\n\nfunction fromTypeLiteral(ts: TypeScriptModule, node: ts.TypeLiteralNode): IrType | null {\n const members = node.members.map((member) => fromMember(ts, member));\n const isReadable = members.every((member) => member !== null);\n return isReadable ? { kind: \"object\", members: members as IrMember[] } : null;\n}\n\nfunction fromComposite(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const convert = childrenOf(ts, node);\n if (ts.isArrayTypeNode(node)) {\n return { kind: \"array\", element: convert(node.elementType) };\n }\n if (ts.isUnionTypeNode(node)) {\n return { kind: \"union\", types: node.types.map(convert) };\n }\n if (ts.isIntersectionTypeNode(node)) {\n return { kind: \"intersection\", types: node.types.map(convert) };\n }\n if (ts.isIndexedAccessTypeNode(node)) {\n return {\n kind: \"indexedAccess\",\n object: convert(node.objectType),\n index: convert(node.indexType),\n };\n }\n if (ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return { kind: \"readonly\", type: convert(node.type) };\n }\n return ts.isTypeLiteralNode(node) ? fromTypeLiteral(ts, node) : null;\n}\n\nfunction fromStructure(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const keyword = keywordOf(ts, node.kind);\n if (keyword !== undefined) {\n return { kind: \"keyword\", keyword };\n }\n if (ts.isIdentifier(node)) {\n // The original writes JSON string literals and some references as bare identifiers.\n return irRaw(ts.idText(node));\n }\n if (ts.isLiteralTypeNode(node)) {\n return fromLiteral(ts, node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return fromReference(ts, node);\n }\n return ts.isTupleTypeNode(node) ? fromTuple(ts, node) : fromComposite(ts, node);\n}\n\n/**\n * Whether the factory's parenthesizer put these parentheses in (same rules as the IR printer):\n * unions, intersections and `readonly` types as array elements, indexed objects, optional tuple\n * elements and `readonly` operands; unions and intersections as members of other unions or\n * intersections.\n */\nfunction isFactoryParenthesis(\n ts: TypeScriptModule,\n inner: ts.TypeNode,\n parent: ts.Node | undefined,\n): boolean {\n if (parent === undefined) {\n return false;\n }\n const isComposite = ts.isUnionTypeNode(inner) || ts.isIntersectionTypeNode(inner);\n const isPostfixOrReadonlyParent =\n ts.isArrayTypeNode(parent) ||\n ts.isIndexedAccessTypeNode(parent) ||\n ts.isOptionalTypeNode(parent) ||\n ts.isTypeOperatorNode(parent);\n if (isPostfixOrReadonlyParent) {\n return isComposite || ts.isTypeOperatorNode(inner);\n }\n const isCompositeParent = ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent);\n return isCompositeParent && isComposite;\n}\n\n/**\n * Convert a type node. `parent` is the node that contains it: synthesized nodes have no `parent`\n * link, and it is needed to tell parentheses the factory inserted from ones the user wrote.\n */\nexport function fromTypeNode(ts: TypeScriptModule, node: ts.TypeNode, parent?: ts.Node): IrType {\n if (isIrNode(node)) {\n return node;\n }\n if (needsPrintedText(ts, node)) {\n return asRaw(ts, node);\n }\n if (ts.isParenthesizedTypeNode(node)) {\n return isFactoryParenthesis(ts, node.type, parent)\n ? fromTypeNode(ts, node.type, parent)\n : asRaw(ts, node);\n }\n return fromStructure(ts, node) ?? asRaw(ts, node);\n}\n"],"names":["irRaw","isIrNode","needsPrintedText","asRaw"],"mappings":"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"}
|
|
@@ -46,18 +46,24 @@ function fromReference(ts, node) {
|
|
|
46
46
|
const typeArguments = (node.typeArguments ?? []).map(childrenOf(ts, node));
|
|
47
47
|
return { kind: "reference", name: ts.idText(node.typeName), typeArguments };
|
|
48
48
|
}
|
|
49
|
+
function fromTupleElement(ts, element, convert) {
|
|
50
|
+
if (ts.isRestTypeNode(element)) {
|
|
51
|
+
return { type: convert(element.type), isRest: true, isOptional: false };
|
|
52
|
+
}
|
|
53
|
+
if (ts.isOptionalTypeNode(element)) {
|
|
54
|
+
return { type: fromTypeNode(ts, element.type, element), isRest: false, isOptional: true };
|
|
55
|
+
}
|
|
56
|
+
return { type: convert(element), isRest: false, isOptional: false };
|
|
57
|
+
}
|
|
49
58
|
function fromTuple(ts, node) {
|
|
50
|
-
|
|
51
|
-
(element) => !ts.isNamedTupleMember(element) && !ts.isOptionalTypeNode(element)
|
|
52
|
-
);
|
|
53
|
-
if (!isPlain) {
|
|
59
|
+
if (node.elements.some((element) => ts.isNamedTupleMember(element))) {
|
|
54
60
|
return null;
|
|
55
61
|
}
|
|
56
62
|
const convert = childrenOf(ts, node);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
return {
|
|
64
|
+
kind: "tuple",
|
|
65
|
+
elements: node.elements.map((element) => fromTupleElement(ts, element, convert))
|
|
66
|
+
};
|
|
61
67
|
}
|
|
62
68
|
function fromComments(ts, node) {
|
|
63
69
|
const comments = ts.getSyntheticLeadingComments(node) ?? [];
|
|
@@ -177,7 +183,7 @@ function isFactoryParenthesis(ts, inner, parent) {
|
|
|
177
183
|
return false;
|
|
178
184
|
}
|
|
179
185
|
const isComposite = ts.isUnionTypeNode(inner) || ts.isIntersectionTypeNode(inner);
|
|
180
|
-
const isPostfixOrReadonlyParent = ts.isArrayTypeNode(parent) || ts.isIndexedAccessTypeNode(parent) || ts.isTypeOperatorNode(parent);
|
|
186
|
+
const isPostfixOrReadonlyParent = ts.isArrayTypeNode(parent) || ts.isIndexedAccessTypeNode(parent) || ts.isOptionalTypeNode(parent) || ts.isTypeOperatorNode(parent);
|
|
181
187
|
if (isPostfixOrReadonlyParent) {
|
|
182
188
|
return isComposite || ts.isTypeOperatorNode(inner);
|
|
183
189
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript-to-ir.mjs","sources":["../../../src/adapters/type-ast-bridge/typescript-to-ir.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { irRaw } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport { asRaw, isIrNode, needsPrintedText } from \"./typescript-raw-text.js\";\n\n/**\n * Read TypeScript type nodes from user callbacks into IR (ADR-004, decision 3). Synthesized nodes\n * are mapped by structure. Anything the IR cannot express exactly is printed with the TypeScript\n * printer, the way the original output it, and kept as a `raw` node: parsed nodes, nodes with\n * comments, explicit parentheses, single-quoted strings, numbers not in canonical form, and syntax\n * the IR does not model. Every function takes the user's TypeScript module (ADR-004, decision 4):\n * `SyntaxKind` numbers differ between versions, so a node is read with the module that made it.\n */\n\nfunction keywordOf(ts: TypeScriptModule, kind: ts.SyntaxKind): IrKeyword | undefined {\n const keywords: ReadonlyMap<ts.SyntaxKind, IrKeyword> = new Map([\n [ts.SyntaxKind.StringKeyword, \"string\"],\n [ts.SyntaxKind.NumberKeyword, \"number\"],\n [ts.SyntaxKind.BooleanKeyword, \"boolean\"],\n [ts.SyntaxKind.UndefinedKeyword, \"undefined\"],\n [ts.SyntaxKind.UnknownKeyword, \"unknown\"],\n [ts.SyntaxKind.NeverKeyword, \"never\"],\n ]);\n return keywords.get(kind);\n}\n\nfunction isCanonicalNumber(text: string): boolean {\n return String(Number(text)) === text;\n}\n\nfunction fromNumber(ts: TypeScriptModule, literal: ts.Expression): IrType | null {\n if (ts.isNumericLiteral(literal)) {\n return isCanonicalNumber(literal.text)\n ? { kind: \"numberLiteral\", value: Number(literal.text) }\n : null;\n }\n const isNegative =\n ts.isPrefixUnaryExpression(literal) &&\n literal.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(literal.operand) &&\n isCanonicalNumber(literal.operand.text) &&\n Number(literal.operand.text) !== 0;\n return isNegative\n ? { kind: \"numberLiteral\", value: -Number((literal.operand as ts.NumericLiteral).text) }\n : null;\n}\n\nfunction fromLiteral(ts: TypeScriptModule, node: ts.LiteralTypeNode): IrType | null {\n const { literal } = node;\n if (ts.isStringLiteral(literal)) {\n const isSingleQuoted = (literal as { singleQuote?: boolean }).singleQuote === true;\n return isSingleQuoted\n ? null\n : { kind: \"stringLiteral\", value: literal.text, encoding: \"escaped\" };\n }\n if (literal.kind === ts.SyntaxKind.NullKeyword) {\n return { kind: \"keyword\", keyword: \"null\" };\n }\n if (literal.kind === ts.SyntaxKind.TrueKeyword || literal.kind === ts.SyntaxKind.FalseKeyword) {\n return { kind: \"booleanLiteral\", value: literal.kind === ts.SyntaxKind.TrueKeyword };\n }\n return fromNumber(ts, literal);\n}\n\n/** Converts the children of one node, which becomes their parent. */\nfunction childrenOf(ts: TypeScriptModule, parent: ts.Node): (child: ts.TypeNode) => IrType {\n return (child) => fromTypeNode(ts, child, parent);\n}\n\nfunction fromReference(ts: TypeScriptModule, node: ts.TypeReferenceNode): IrType | null {\n if (!ts.isIdentifier(node.typeName)) {\n return null;\n }\n const typeArguments = (node.typeArguments ?? []).map(childrenOf(ts, node));\n return { kind: \"reference\", name: ts.idText(node.typeName), typeArguments };\n}\n\nfunction fromTuple(ts: TypeScriptModule, node: ts.TupleTypeNode): IrType | null {\n const isPlain = node.elements.every(\n (element) => !ts.isNamedTupleMember(element) && !ts.isOptionalTypeNode(element),\n );\n if (!isPlain) {\n return null;\n }\n const convert = childrenOf(ts, node);\n const elements = node.elements.map((element) =>\n ts.isRestTypeNode(element)\n ? { type: convert(element.type), isRest: true }\n : { type: convert(element), isRest: false },\n );\n return { kind: \"tuple\", elements };\n}\n\n/**\n * Leading comments in order, or null when the IR cannot hold them: trailing comments, or a\n * comment without a line break after it (the IR always writes one).\n */\nfunction fromComments(ts: TypeScriptModule, node: ts.Node): IrComment[] | null {\n const comments = ts.getSyntheticLeadingComments(node) ?? [];\n const hasTrailing = (ts.getSyntheticTrailingComments(node)?.length ?? 0) > 0;\n if (hasTrailing || comments.some((comment) => !comment.hasTrailingNewLine)) {\n return null;\n }\n return comments.map((comment) => ({\n kind: comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? \"block\" : \"line\",\n text: comment.text,\n }));\n}\n\nfunction fromPropertyName(ts: TypeScriptModule, name: ts.PropertyName): IrPropertyName | null {\n if (ts.isIdentifier(name)) {\n return { kind: \"identifier\", text: ts.idText(name) };\n }\n if (ts.isStringLiteral(name) && (name as { singleQuote?: boolean }).singleQuote !== true) {\n return { kind: \"string\", value: name.text };\n }\n return ts.isNumericLiteral(name) ? { kind: \"number\", text: name.text } : null;\n}\n\n/** Only `readonly` is modeled; any other modifier makes the member unreadable as IR. */\nfunction readonlyFlag(ts: TypeScriptModule, node: ts.TypeElement): boolean | null {\n const modifiers = ts.canHaveModifiers(node) ? (ts.getModifiers(node) ?? []) : [];\n const isOnlyReadonly = modifiers.every(\n (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword,\n );\n return isOnlyReadonly ? modifiers.length > 0 : null;\n}\n\n/** A property signature as IR, or null when it uses syntax the IR does not model. */\nexport function fromPropertySignature(\n ts: TypeScriptModule,\n node: ts.PropertySignature,\n): IrPropertySignature | null {\n const name = fromPropertyName(ts, node.name);\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n if (name === null || comments === null || isReadonly === null || node.type === undefined) {\n return null;\n }\n return {\n kind: \"property\",\n name,\n type: fromTypeNode(ts, node.type, node),\n isOptional: node.questionToken !== undefined,\n isReadonly,\n comments,\n };\n}\n\nfunction fromIndexSignature(\n ts: TypeScriptModule,\n node: ts.IndexSignatureDeclaration,\n): IrMember | null {\n const [parameter, ...others] = node.parameters;\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n const isPlain =\n parameter?.type !== undefined && ts.isIdentifier(parameter.name) && others.length === 0;\n if (!isPlain || comments === null || isReadonly === null) {\n return null;\n }\n return {\n kind: \"indexSignature\",\n parameterName: ts.idText(parameter.name as ts.Identifier),\n parameterType: fromTypeNode(ts, parameter.type as ts.TypeNode, node),\n type: fromTypeNode(ts, node.type, node),\n isReadonly,\n comments,\n };\n}\n\nfunction fromMember(ts: TypeScriptModule, member: ts.TypeElement): IrMember | null {\n if (member.pos >= 0) {\n return null;\n }\n if (ts.isPropertySignature(member)) {\n return fromPropertySignature(ts, member);\n }\n return ts.isIndexSignatureDeclaration(member) ? fromIndexSignature(ts, member) : null;\n}\n\nfunction fromTypeLiteral(ts: TypeScriptModule, node: ts.TypeLiteralNode): IrType | null {\n const members = node.members.map((member) => fromMember(ts, member));\n const isReadable = members.every((member) => member !== null);\n return isReadable ? { kind: \"object\", members: members as IrMember[] } : null;\n}\n\nfunction fromComposite(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const convert = childrenOf(ts, node);\n if (ts.isArrayTypeNode(node)) {\n return { kind: \"array\", element: convert(node.elementType) };\n }\n if (ts.isUnionTypeNode(node)) {\n return { kind: \"union\", types: node.types.map(convert) };\n }\n if (ts.isIntersectionTypeNode(node)) {\n return { kind: \"intersection\", types: node.types.map(convert) };\n }\n if (ts.isIndexedAccessTypeNode(node)) {\n return {\n kind: \"indexedAccess\",\n object: convert(node.objectType),\n index: convert(node.indexType),\n };\n }\n if (ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return { kind: \"readonly\", type: convert(node.type) };\n }\n return ts.isTypeLiteralNode(node) ? fromTypeLiteral(ts, node) : null;\n}\n\nfunction fromStructure(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const keyword = keywordOf(ts, node.kind);\n if (keyword !== undefined) {\n return { kind: \"keyword\", keyword };\n }\n if (ts.isIdentifier(node)) {\n // The original writes JSON string literals and some references as bare identifiers.\n return irRaw(ts.idText(node));\n }\n if (ts.isLiteralTypeNode(node)) {\n return fromLiteral(ts, node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return fromReference(ts, node);\n }\n return ts.isTupleTypeNode(node) ? fromTuple(ts, node) : fromComposite(ts, node);\n}\n\n/**\n * Whether the factory's parenthesizer put these parentheses in (same rules as the IR printer):\n * unions, intersections and `readonly` types as array elements, indexed objects and `readonly`\n * operands; unions and intersections as members of other unions or intersections.\n */\nfunction isFactoryParenthesis(\n ts: TypeScriptModule,\n inner: ts.TypeNode,\n parent: ts.Node | undefined,\n): boolean {\n if (parent === undefined) {\n return false;\n }\n const isComposite = ts.isUnionTypeNode(inner) || ts.isIntersectionTypeNode(inner);\n const isPostfixOrReadonlyParent =\n ts.isArrayTypeNode(parent) ||\n ts.isIndexedAccessTypeNode(parent) ||\n ts.isTypeOperatorNode(parent);\n if (isPostfixOrReadonlyParent) {\n return isComposite || ts.isTypeOperatorNode(inner);\n }\n const isCompositeParent = ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent);\n return isCompositeParent && isComposite;\n}\n\n/**\n * Convert a type node. `parent` is the node that contains it: synthesized nodes have no `parent`\n * link, and it is needed to tell parentheses the factory inserted from ones the user wrote.\n */\nexport function fromTypeNode(ts: TypeScriptModule, node: ts.TypeNode, parent?: ts.Node): IrType {\n if (isIrNode(node)) {\n return node;\n }\n if (needsPrintedText(ts, node)) {\n return asRaw(ts, node);\n }\n if (ts.isParenthesizedTypeNode(node)) {\n return isFactoryParenthesis(ts, node.type, parent)\n ? fromTypeNode(ts, node.type, parent)\n : asRaw(ts, node);\n }\n return fromStructure(ts, node) ?? asRaw(ts, node);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typescript-to-ir.mjs","sources":["../../../src/adapters/type-ast-bridge/typescript-to-ir.ts"],"sourcesContent":["import type ts from \"typescript\";\nimport { irRaw } from \"../../domain/ir/constructors.js\";\nimport type {\n IrComment,\n IrKeyword,\n IrMember,\n IrPropertyName,\n IrPropertySignature,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport type { TypeScriptModule } from \"./load-typescript.js\";\nimport { asRaw, isIrNode, needsPrintedText } from \"./typescript-raw-text.js\";\n\n/**\n * Read TypeScript type nodes from user callbacks into IR (ADR-004, decision 3). Synthesized nodes\n * are mapped by structure. Anything the IR cannot express exactly is printed with the TypeScript\n * printer, the way the original output it, and kept as a `raw` node: parsed nodes, nodes with\n * comments, explicit parentheses, single-quoted strings, numbers not in canonical form, and syntax\n * the IR does not model. Every function takes the user's TypeScript module (ADR-004, decision 4):\n * `SyntaxKind` numbers differ between versions, so a node is read with the module that made it.\n */\n\nfunction keywordOf(ts: TypeScriptModule, kind: ts.SyntaxKind): IrKeyword | undefined {\n const keywords: ReadonlyMap<ts.SyntaxKind, IrKeyword> = new Map([\n [ts.SyntaxKind.StringKeyword, \"string\"],\n [ts.SyntaxKind.NumberKeyword, \"number\"],\n [ts.SyntaxKind.BooleanKeyword, \"boolean\"],\n [ts.SyntaxKind.UndefinedKeyword, \"undefined\"],\n [ts.SyntaxKind.UnknownKeyword, \"unknown\"],\n [ts.SyntaxKind.NeverKeyword, \"never\"],\n ]);\n return keywords.get(kind);\n}\n\nfunction isCanonicalNumber(text: string): boolean {\n return String(Number(text)) === text;\n}\n\nfunction fromNumber(ts: TypeScriptModule, literal: ts.Expression): IrType | null {\n if (ts.isNumericLiteral(literal)) {\n return isCanonicalNumber(literal.text)\n ? { kind: \"numberLiteral\", value: Number(literal.text) }\n : null;\n }\n const isNegative =\n ts.isPrefixUnaryExpression(literal) &&\n literal.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(literal.operand) &&\n isCanonicalNumber(literal.operand.text) &&\n Number(literal.operand.text) !== 0;\n return isNegative\n ? { kind: \"numberLiteral\", value: -Number((literal.operand as ts.NumericLiteral).text) }\n : null;\n}\n\nfunction fromLiteral(ts: TypeScriptModule, node: ts.LiteralTypeNode): IrType | null {\n const { literal } = node;\n if (ts.isStringLiteral(literal)) {\n const isSingleQuoted = (literal as { singleQuote?: boolean }).singleQuote === true;\n return isSingleQuoted\n ? null\n : { kind: \"stringLiteral\", value: literal.text, encoding: \"escaped\" };\n }\n if (literal.kind === ts.SyntaxKind.NullKeyword) {\n return { kind: \"keyword\", keyword: \"null\" };\n }\n if (literal.kind === ts.SyntaxKind.TrueKeyword || literal.kind === ts.SyntaxKind.FalseKeyword) {\n return { kind: \"booleanLiteral\", value: literal.kind === ts.SyntaxKind.TrueKeyword };\n }\n return fromNumber(ts, literal);\n}\n\n/** Converts the children of one node, which becomes their parent. */\nfunction childrenOf(ts: TypeScriptModule, parent: ts.Node): (child: ts.TypeNode) => IrType {\n return (child) => fromTypeNode(ts, child, parent);\n}\n\nfunction fromReference(ts: TypeScriptModule, node: ts.TypeReferenceNode): IrType | null {\n if (!ts.isIdentifier(node.typeName)) {\n return null;\n }\n const typeArguments = (node.typeArguments ?? []).map(childrenOf(ts, node));\n return { kind: \"reference\", name: ts.idText(node.typeName), typeArguments };\n}\n\nfunction fromTupleElement(\n ts: TypeScriptModule,\n element: ts.TypeNode,\n convert: (node: ts.TypeNode) => IrType,\n): IrTupleElement {\n if (ts.isRestTypeNode(element)) {\n return { type: convert(element.type), isRest: true, isOptional: false };\n }\n if (ts.isOptionalTypeNode(element)) {\n // The `?` is the parent of the type: it decides which parentheses the factory put in.\n return { type: fromTypeNode(ts, element.type, element), isRest: false, isOptional: true };\n }\n return { type: convert(element), isRest: false, isOptional: false };\n}\n\n/** A tuple of plain, rest and optional elements; one with named members stays text. */\nfunction fromTuple(ts: TypeScriptModule, node: ts.TupleTypeNode): IrType | null {\n if (node.elements.some((element) => ts.isNamedTupleMember(element))) {\n return null;\n }\n const convert = childrenOf(ts, node);\n return {\n kind: \"tuple\",\n elements: node.elements.map((element) => fromTupleElement(ts, element, convert)),\n };\n}\n\n/**\n * Leading comments in order, or null when the IR cannot hold them: trailing comments, or a\n * comment without a line break after it (the IR always writes one).\n */\nfunction fromComments(ts: TypeScriptModule, node: ts.Node): IrComment[] | null {\n const comments = ts.getSyntheticLeadingComments(node) ?? [];\n const hasTrailing = (ts.getSyntheticTrailingComments(node)?.length ?? 0) > 0;\n if (hasTrailing || comments.some((comment) => !comment.hasTrailingNewLine)) {\n return null;\n }\n return comments.map((comment) => ({\n kind: comment.kind === ts.SyntaxKind.MultiLineCommentTrivia ? \"block\" : \"line\",\n text: comment.text,\n }));\n}\n\nfunction fromPropertyName(ts: TypeScriptModule, name: ts.PropertyName): IrPropertyName | null {\n if (ts.isIdentifier(name)) {\n return { kind: \"identifier\", text: ts.idText(name) };\n }\n if (ts.isStringLiteral(name) && (name as { singleQuote?: boolean }).singleQuote !== true) {\n return { kind: \"string\", value: name.text };\n }\n return ts.isNumericLiteral(name) ? { kind: \"number\", text: name.text } : null;\n}\n\n/** Only `readonly` is modeled; any other modifier makes the member unreadable as IR. */\nfunction readonlyFlag(ts: TypeScriptModule, node: ts.TypeElement): boolean | null {\n const modifiers = ts.canHaveModifiers(node) ? (ts.getModifiers(node) ?? []) : [];\n const isOnlyReadonly = modifiers.every(\n (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword,\n );\n return isOnlyReadonly ? modifiers.length > 0 : null;\n}\n\n/** A property signature as IR, or null when it uses syntax the IR does not model. */\nexport function fromPropertySignature(\n ts: TypeScriptModule,\n node: ts.PropertySignature,\n): IrPropertySignature | null {\n const name = fromPropertyName(ts, node.name);\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n if (name === null || comments === null || isReadonly === null || node.type === undefined) {\n return null;\n }\n return {\n kind: \"property\",\n name,\n type: fromTypeNode(ts, node.type, node),\n isOptional: node.questionToken !== undefined,\n isReadonly,\n comments,\n };\n}\n\nfunction fromIndexSignature(\n ts: TypeScriptModule,\n node: ts.IndexSignatureDeclaration,\n): IrMember | null {\n const [parameter, ...others] = node.parameters;\n const comments = fromComments(ts, node);\n const isReadonly = readonlyFlag(ts, node);\n const isPlain =\n parameter?.type !== undefined && ts.isIdentifier(parameter.name) && others.length === 0;\n if (!isPlain || comments === null || isReadonly === null) {\n return null;\n }\n return {\n kind: \"indexSignature\",\n parameterName: ts.idText(parameter.name as ts.Identifier),\n parameterType: fromTypeNode(ts, parameter.type as ts.TypeNode, node),\n type: fromTypeNode(ts, node.type, node),\n isReadonly,\n comments,\n };\n}\n\nfunction fromMember(ts: TypeScriptModule, member: ts.TypeElement): IrMember | null {\n if (member.pos >= 0) {\n return null;\n }\n if (ts.isPropertySignature(member)) {\n return fromPropertySignature(ts, member);\n }\n return ts.isIndexSignatureDeclaration(member) ? fromIndexSignature(ts, member) : null;\n}\n\nfunction fromTypeLiteral(ts: TypeScriptModule, node: ts.TypeLiteralNode): IrType | null {\n const members = node.members.map((member) => fromMember(ts, member));\n const isReadable = members.every((member) => member !== null);\n return isReadable ? { kind: \"object\", members: members as IrMember[] } : null;\n}\n\nfunction fromComposite(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const convert = childrenOf(ts, node);\n if (ts.isArrayTypeNode(node)) {\n return { kind: \"array\", element: convert(node.elementType) };\n }\n if (ts.isUnionTypeNode(node)) {\n return { kind: \"union\", types: node.types.map(convert) };\n }\n if (ts.isIntersectionTypeNode(node)) {\n return { kind: \"intersection\", types: node.types.map(convert) };\n }\n if (ts.isIndexedAccessTypeNode(node)) {\n return {\n kind: \"indexedAccess\",\n object: convert(node.objectType),\n index: convert(node.indexType),\n };\n }\n if (ts.isTypeOperatorNode(node) && node.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return { kind: \"readonly\", type: convert(node.type) };\n }\n return ts.isTypeLiteralNode(node) ? fromTypeLiteral(ts, node) : null;\n}\n\nfunction fromStructure(ts: TypeScriptModule, node: ts.TypeNode): IrType | null {\n const keyword = keywordOf(ts, node.kind);\n if (keyword !== undefined) {\n return { kind: \"keyword\", keyword };\n }\n if (ts.isIdentifier(node)) {\n // The original writes JSON string literals and some references as bare identifiers.\n return irRaw(ts.idText(node));\n }\n if (ts.isLiteralTypeNode(node)) {\n return fromLiteral(ts, node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return fromReference(ts, node);\n }\n return ts.isTupleTypeNode(node) ? fromTuple(ts, node) : fromComposite(ts, node);\n}\n\n/**\n * Whether the factory's parenthesizer put these parentheses in (same rules as the IR printer):\n * unions, intersections and `readonly` types as array elements, indexed objects, optional tuple\n * elements and `readonly` operands; unions and intersections as members of other unions or\n * intersections.\n */\nfunction isFactoryParenthesis(\n ts: TypeScriptModule,\n inner: ts.TypeNode,\n parent: ts.Node | undefined,\n): boolean {\n if (parent === undefined) {\n return false;\n }\n const isComposite = ts.isUnionTypeNode(inner) || ts.isIntersectionTypeNode(inner);\n const isPostfixOrReadonlyParent =\n ts.isArrayTypeNode(parent) ||\n ts.isIndexedAccessTypeNode(parent) ||\n ts.isOptionalTypeNode(parent) ||\n ts.isTypeOperatorNode(parent);\n if (isPostfixOrReadonlyParent) {\n return isComposite || ts.isTypeOperatorNode(inner);\n }\n const isCompositeParent = ts.isUnionTypeNode(parent) || ts.isIntersectionTypeNode(parent);\n return isCompositeParent && isComposite;\n}\n\n/**\n * Convert a type node. `parent` is the node that contains it: synthesized nodes have no `parent`\n * link, and it is needed to tell parentheses the factory inserted from ones the user wrote.\n */\nexport function fromTypeNode(ts: TypeScriptModule, node: ts.TypeNode, parent?: ts.Node): IrType {\n if (isIrNode(node)) {\n return node;\n }\n if (needsPrintedText(ts, node)) {\n return asRaw(ts, node);\n }\n if (ts.isParenthesizedTypeNode(node)) {\n return isFactoryParenthesis(ts, node.type, parent)\n ? fromTypeNode(ts, node.type, parent)\n : asRaw(ts, node);\n }\n return fromStructure(ts, node) ?? asRaw(ts, node);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const discriminatorConflicts = require('../domain/openapi/discriminator-conflicts.cjs');
|
|
4
|
+
const outputFixes = require('../domain/output-fixes.cjs');
|
|
5
|
+
const warnings = require('../domain/warnings.cjs');
|
|
6
|
+
|
|
7
|
+
const DOCS_BASE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs";
|
|
8
|
+
const DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;
|
|
9
|
+
function listed(values) {
|
|
10
|
+
return values.map((value) => JSON.stringify(value)).join(", ");
|
|
11
|
+
}
|
|
12
|
+
function warningOf(conflict) {
|
|
13
|
+
const { member, owner, propertyName, values, allowed, isImplicit } = conflict;
|
|
14
|
+
const rule = isImplicit ? `A Discriminator Object without a mapping entry for a schema gives it its schema name as the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: "${member}".` : "The Discriminator Object maps these values to the schema; map the values it allows.";
|
|
15
|
+
return `${member}: the discriminator "${propertyName}" of ${owner} gives this schema the value ${listed(values)}, which its "${propertyName}" property does not allow (${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} See ${DOCS_URL}`;
|
|
16
|
+
}
|
|
17
|
+
function warnDiscriminatorValueConflicts(document, fixes, logger) {
|
|
18
|
+
const isUnionReused = fixes.includes(outputFixes.OutputFix.ALLOF_DISCRIMINATED_UNION);
|
|
19
|
+
for (const conflict of discriminatorConflicts.findDiscriminatorValueConflicts(document, { isUnionReused })) {
|
|
20
|
+
logger.warn(warnings.warningText(warningOf(conflict), warnings.WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
exports.warnDiscriminatorValueConflicts = warnDiscriminatorValueConflicts;
|
|
25
|
+
//# sourceMappingURL=discriminator-conflict-warnings.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-conflict-warnings.cjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(OutputFix.ALLOF_DISCRIMINATED_UNION);\n for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {\n logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));\n }\n}\n"],"names":["OutputFix","findDiscriminatorValueConflicts","warningText","WARNING_CODES"],"mappings":";;;;;;AAQA,MAAM,aAAA,GAAgB,qEAAA;AACtB,MAAM,QAAA,GAAW,GAAG,aAAa,CAAA,iCAAA,CAAA;AAEjC,SAAS,OAAO,MAAA,EAAoC;AAClD,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,IAAA,CAAK,UAAU,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC/D;AAEA,SAAS,UAAU,QAAA,EAA8C;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,cAAc,MAAA,EAAQ,OAAA,EAAS,YAAW,GAAI,QAAA;AACrE,EAAA,MAAM,IAAA,GAAO,UAAA,GACT,CAAA,+HAAA,EAC0C,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,GAAA,EAAM,MAAM,CAAA,EAAA,CAAA,GAChF,qFAAA;AACJ,EAAA,OACE,GAAG,MAAM,CAAA,qBAAA,EAAwB,YAAY,CAAA,KAAA,EAAQ,KAAK,gCACvD,MAAA,CAAO,MAAM,CAAC,CAAA,aAAA,EAAgB,YAAY,8BACzC,MAAA,CAAO,OAAO,CAAC,CAAA,wDAAA,EAA2D,IAAI,QAC3E,QAAQ,CAAA,CAAA;AAEnB;AAMO,SAAS,+BAAA,CACd,QAAA,EACA,KAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,QAAA,CAASA,qBAAA,CAAU,yBAAyB,CAAA;AACxE,EAAA,KAAA,MAAW,YAAYC,sDAAA,CAAgC,QAAA,EAAU,EAAE,aAAA,EAAe,CAAA,EAAG;AACnF,IAAA,MAAA,CAAO,KAAKC,oBAAA,CAAY,SAAA,CAAU,QAAQ,CAAA,EAAGC,sBAAA,CAAc,+BAA+B,CAAC,CAAA;AAAA,EAC7F;AACF;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { findDiscriminatorValueConflicts } from '../domain/openapi/discriminator-conflicts.mjs';
|
|
2
|
+
import { OutputFix } from '../domain/output-fixes.mjs';
|
|
3
|
+
import { warningText, WARNING_CODES } from '../domain/warnings.mjs';
|
|
4
|
+
|
|
5
|
+
const DOCS_BASE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs";
|
|
6
|
+
const DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;
|
|
7
|
+
function listed(values) {
|
|
8
|
+
return values.map((value) => JSON.stringify(value)).join(", ");
|
|
9
|
+
}
|
|
10
|
+
function warningOf(conflict) {
|
|
11
|
+
const { member, owner, propertyName, values, allowed, isImplicit } = conflict;
|
|
12
|
+
const rule = isImplicit ? `A Discriminator Object without a mapping entry for a schema gives it its schema name as the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: "${member}".` : "The Discriminator Object maps these values to the schema; map the values it allows.";
|
|
13
|
+
return `${member}: the discriminator "${propertyName}" of ${owner} gives this schema the value ${listed(values)}, which its "${propertyName}" property does not allow (${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} See ${DOCS_URL}`;
|
|
14
|
+
}
|
|
15
|
+
function warnDiscriminatorValueConflicts(document, fixes, logger) {
|
|
16
|
+
const isUnionReused = fixes.includes(OutputFix.ALLOF_DISCRIMINATED_UNION);
|
|
17
|
+
for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {
|
|
18
|
+
logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { warnDiscriminatorValueConflicts };
|
|
23
|
+
//# sourceMappingURL=discriminator-conflict-warnings.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-conflict-warnings.mjs","sources":["../../src/api/discriminator-conflict-warnings.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport {\n type DiscriminatorValueConflict,\n findDiscriminatorValueConflicts,\n} from \"../domain/openapi/discriminator-conflicts.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport { WARNING_CODES, warningText } from \"../domain/warnings.js\";\n\nconst DOCS_BASE_URL = \"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs\";\nconst DOCS_URL = `${DOCS_BASE_URL}/advanced.md#discriminator-values`;\n\nfunction listed(values: readonly unknown[]): string {\n return values.map((value) => JSON.stringify(value)).join(\", \");\n}\n\nfunction warningOf(conflict: DiscriminatorValueConflict): string {\n const { member, owner, propertyName, values, allowed, isImplicit } = conflict;\n const rule = isImplicit\n ? \"A Discriminator Object without a mapping entry for a schema gives it its schema name as \" +\n `the value; add a mapping entry such as ${JSON.stringify(allowed[0])}: \"${member}\".`\n : \"The Discriminator Object maps these values to the schema; map the values it allows.\";\n return (\n `${member}: the discriminator \"${propertyName}\" of ${owner} gives this schema the value ` +\n `${listed(values)}, which its \"${propertyName}\" property does not allow ` +\n `(${listed(allowed)}), so no value of the schema matches the discriminator. ${rule} ` +\n `See ${DOCS_URL}`\n );\n}\n\n/**\n * Warn once per discriminator member whose value its own property does not allow. The members\n * depend on the run's fixes (`allof-discriminated-union`).\n */\nexport function warnDiscriminatorValueConflicts(\n document: unknown,\n fixes: readonly OutputFix[],\n logger: Logger,\n): void {\n const isUnionReused = fixes.includes(OutputFix.ALLOF_DISCRIMINATED_UNION);\n for (const conflict of findDiscriminatorValueConflicts(document, { isUnionReused })) {\n logger.warn(warningText(warningOf(conflict), WARNING_CODES.DISCRIMINATOR_VALUE_NOT_ALLOWED));\n }\n}\n"],"names":[],"mappings":";;;;AAQA,MAAM,aAAA,GAAgB,qEAAA;AACtB,MAAM,QAAA,GAAW,GAAG,aAAa,CAAA,iCAAA,CAAA;AAEjC,SAAS,OAAO,MAAA,EAAoC;AAClD,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,IAAA,CAAK,UAAU,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC/D;AAEA,SAAS,UAAU,QAAA,EAA8C;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,cAAc,MAAA,EAAQ,OAAA,EAAS,YAAW,GAAI,QAAA;AACrE,EAAA,MAAM,IAAA,GAAO,UAAA,GACT,CAAA,+HAAA,EAC0C,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,GAAA,EAAM,MAAM,CAAA,EAAA,CAAA,GAChF,qFAAA;AACJ,EAAA,OACE,GAAG,MAAM,CAAA,qBAAA,EAAwB,YAAY,CAAA,KAAA,EAAQ,KAAK,gCACvD,MAAA,CAAO,MAAM,CAAC,CAAA,aAAA,EAAgB,YAAY,8BACzC,MAAA,CAAO,OAAO,CAAC,CAAA,wDAAA,EAA2D,IAAI,QAC3E,QAAQ,CAAA,CAAA;AAEnB;AAMO,SAAS,+BAAA,CACd,QAAA,EACA,KAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,QAAA,CAAS,SAAA,CAAU,yBAAyB,CAAA;AACxE,EAAA,KAAA,MAAW,YAAY,+BAAA,CAAgC,QAAA,EAAU,EAAE,aAAA,EAAe,CAAA,EAAG;AACnF,IAAA,MAAA,CAAO,KAAK,WAAA,CAAY,SAAA,CAAU,QAAQ,CAAA,EAAG,aAAA,CAAc,+BAA+B,CAAC,CAAA;AAAA,EAC7F;AACF;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class FirstSchemaNameRecorder {
|
|
4
|
+
names = /* @__PURE__ */ new Map();
|
|
5
|
+
nameOf(key, name, request) {
|
|
6
|
+
if (!request.isOwnerReference && !this.names.has(key)) {
|
|
7
|
+
this.names.set(key, name);
|
|
8
|
+
}
|
|
9
|
+
return name;
|
|
10
|
+
}
|
|
11
|
+
/** The recorded name of each shared enum, for the second pass. */
|
|
12
|
+
chosenNames() {
|
|
13
|
+
const chosen = new Map(this.names);
|
|
14
|
+
return { nameOf: (key, name) => chosen.get(key) ?? name };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.FirstSchemaNameRecorder = FirstSchemaNameRecorder;
|
|
19
|
+
//# sourceMappingURL=discriminator-enum-names.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-enum-names.cjs","sources":["../../src/api/discriminator-enum-names.ts"],"sourcesContent":["import type { SharedEnumNames } from \"../application/transform/footer/shared-enum-names.js\";\nimport type { EnumDeclarationRequest } from \"../application/transform/schema/schema-context.js\";\n\n/**\n * `--dedupe-enums` names a shared enum after the first schema that declares it. With\n * `discriminator-values` and `--enum`, a member's value refers to the owner's enum, which is then\n * declared when the member is typed, maybe before that first schema; the shared enum would take\n * the owner's name. A first pass records the names of the declaring schemas only, so the second\n * pass names each shared enum as the document order does (`OtherKind`, not `PetPetType`).\n */\nexport class FirstSchemaNameRecorder implements SharedEnumNames {\n private readonly names = new Map<string, string>();\n\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string {\n if (!request.isOwnerReference && !this.names.has(key)) {\n this.names.set(key, name);\n }\n return name;\n }\n\n /** The recorded name of each shared enum, for the second pass. */\n chosenNames(): SharedEnumNames {\n const chosen = new Map(this.names);\n return { nameOf: (key, name) => chosen.get(key) ?? name };\n }\n}\n"],"names":[],"mappings":";;AAUO,MAAM,uBAAA,CAAmD;AAAA,EAC7C,KAAA,uBAAY,GAAA,EAAoB;AAAA,EAEjD,MAAA,CAAO,GAAA,EAAa,IAAA,EAAc,OAAA,EAAyC;AACzE,IAAA,IAAI,CAAC,QAAQ,gBAAA,IAAoB,CAAC,KAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,EAAG;AACrD,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,IAC1B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,WAAA,GAA+B;AAC7B,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AACjC,IAAA,OAAO,EAAE,QAAQ,CAAC,GAAA,EAAK,SAAS,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA,EAAK;AAAA,EAC1D;AACF;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class FirstSchemaNameRecorder {
|
|
2
|
+
names = /* @__PURE__ */ new Map();
|
|
3
|
+
nameOf(key, name, request) {
|
|
4
|
+
if (!request.isOwnerReference && !this.names.has(key)) {
|
|
5
|
+
this.names.set(key, name);
|
|
6
|
+
}
|
|
7
|
+
return name;
|
|
8
|
+
}
|
|
9
|
+
/** The recorded name of each shared enum, for the second pass. */
|
|
10
|
+
chosenNames() {
|
|
11
|
+
const chosen = new Map(this.names);
|
|
12
|
+
return { nameOf: (key, name) => chosen.get(key) ?? name };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { FirstSchemaNameRecorder };
|
|
17
|
+
//# sourceMappingURL=discriminator-enum-names.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-enum-names.mjs","sources":["../../src/api/discriminator-enum-names.ts"],"sourcesContent":["import type { SharedEnumNames } from \"../application/transform/footer/shared-enum-names.js\";\nimport type { EnumDeclarationRequest } from \"../application/transform/schema/schema-context.js\";\n\n/**\n * `--dedupe-enums` names a shared enum after the first schema that declares it. With\n * `discriminator-values` and `--enum`, a member's value refers to the owner's enum, which is then\n * declared when the member is typed, maybe before that first schema; the shared enum would take\n * the owner's name. A first pass records the names of the declaring schemas only, so the second\n * pass names each shared enum as the document order does (`OtherKind`, not `PetPetType`).\n */\nexport class FirstSchemaNameRecorder implements SharedEnumNames {\n private readonly names = new Map<string, string>();\n\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string {\n if (!request.isOwnerReference && !this.names.has(key)) {\n this.names.set(key, name);\n }\n return name;\n }\n\n /** The recorded name of each shared enum, for the second pass. */\n chosenNames(): SharedEnumNames {\n const chosen = new Map(this.names);\n return { nameOf: (key, name) => chosen.get(key) ?? name };\n }\n}\n"],"names":[],"mappings":"AAUO,MAAM,uBAAA,CAAmD;AAAA,EAC7C,KAAA,uBAAY,GAAA,EAAoB;AAAA,EAEjD,MAAA,CAAO,GAAA,EAAa,IAAA,EAAc,OAAA,EAAyC;AACzE,IAAA,IAAI,CAAC,QAAQ,gBAAA,IAAoB,CAAC,KAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,EAAG;AACrD,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,IAC1B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,WAAA,GAA+B;AAC7B,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AACjC,IAAA,OAAO,EAAE,QAAQ,CAAC,GAAA,EAAK,SAAS,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA,EAAK;AAAA,EAC1D;AACF;;"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const jsonPointer = require('../domain/openapi/json-pointer.cjs');
|
|
4
|
+
|
|
5
|
+
const PROPERTIES_KEYWORD = "properties";
|
|
6
|
+
const ROOT_SEGMENTS = 3;
|
|
7
|
+
function typedAt(ref) {
|
|
8
|
+
const segments = jsonPointer.parseRefPointer(ref);
|
|
9
|
+
const nested = segments.slice(ROOT_SEGMENTS).filter((segment) => segment !== PROPERTIES_KEYWORD);
|
|
10
|
+
return jsonPointer.createRef([...segments.slice(0, ROOT_SEGMENTS), ...nested]);
|
|
11
|
+
}
|
|
12
|
+
function isSchemaObject(value) {
|
|
13
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
function ownProperty(item, ref, name) {
|
|
16
|
+
const property = ("properties" in item ? item.properties : void 0)?.[name];
|
|
17
|
+
return property === void 0 ? void 0 : { property, path: jsonPointer.createRef([ref, name]) };
|
|
18
|
+
}
|
|
19
|
+
function declaredProperty(ref, name, resolve, visited) {
|
|
20
|
+
const schema = resolve(ref);
|
|
21
|
+
if (visited.has(ref) || !isSchemaObject(schema)) {
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
visited.add(ref);
|
|
25
|
+
for (const item of [schema, ...schema.allOf ?? []]) {
|
|
26
|
+
if (!isSchemaObject(item)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const found = "$ref" in item ? declaredProperty(item.$ref, name, resolve, visited) : ownProperty(item, ref, name);
|
|
30
|
+
if (found !== void 0) {
|
|
31
|
+
return found;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
function inheritedProperty(ref, name, resolve) {
|
|
37
|
+
const schema = resolve(ref);
|
|
38
|
+
const visited = /* @__PURE__ */ new Set([ref]);
|
|
39
|
+
for (const item of isSchemaObject(schema) ? schema.allOf ?? [] : []) {
|
|
40
|
+
const found = isSchemaObject(item) && "$ref" in item ? declaredProperty(item.$ref, name, resolve, visited) : void 0;
|
|
41
|
+
if (found !== void 0) {
|
|
42
|
+
return found;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
function enumParentOf(patch, resolve) {
|
|
48
|
+
const name = patch.discriminator.propertyName;
|
|
49
|
+
const declared = declaredProperty(patch.discriminatorRef, name, resolve, /* @__PURE__ */ new Set()) ?? (patch.ref === void 0 ? void 0 : inheritedProperty(patch.ref, name, resolve));
|
|
50
|
+
if (declared === void 0 || !isSchemaObject(declared.property)) {
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
const ref = declared.property.$ref;
|
|
54
|
+
const parent = typeof ref === "string" ? { schema: resolve(ref), path: typedAt(ref) } : { schema: declared.property, path: declared.path };
|
|
55
|
+
return isSchemaObject(parent.schema) && Array.isArray(parent.schema.enum) ? { schema: parent.schema, path: parent.path } : void 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
exports.enumParentOf = enumParentOf;
|
|
59
|
+
//# sourceMappingURL=discriminator-enum-parent.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-enum-parent.cjs","sources":["../../src/api/discriminator-enum-parent.ts"],"sourcesContent":["import { createRef, parseRefPointer } from \"../domain/openapi/json-pointer.js\";\nimport type { SchemaObject } from \"../types.js\";\nimport type { EnumPatch } from \"./discriminator-enum.js\";\n\n/**\n * The `discriminator-values` fix (#1700). With `--enum`, the enum the scan adds to a member\n * (`petType: \"Cat\"`) is declared as an enum of its own (`CatPetType`), which is not assignable to\n * the parent's enum (`PetType`). The parent's enum is found here, so the member's property can be\n * typed with its members (`PetType.Cat`).\n */\n\n/** The parent's enum schema and the location it is typed at, which gives the enum its name. */\nexport interface EnumParent {\n readonly schema: SchemaObject;\n readonly path: string;\n}\n\ntype ResolveSchemaRef = (ref: string) => unknown;\n\n/** A declared property schema and the location the transformer types it at. */\ninterface DeclaredProperty {\n readonly property: unknown;\n readonly path: string;\n}\n\nconst PROPERTIES_KEYWORD = \"properties\";\n/** `components`, `schemas` and the schema name: the segments before the schema's own keywords. */\nconst ROOT_SEGMENTS = 3;\n\n/** The location a `$ref` is typed at: object properties are nested without `properties`. */\nfunction typedAt(ref: string): string {\n const segments = parseRefPointer(ref);\n const nested = segments.slice(ROOT_SEGMENTS).filter((segment) => segment !== PROPERTIES_KEYWORD);\n return createRef([...segments.slice(0, ROOT_SEGMENTS), ...nested]);\n}\n\nfunction isSchemaObject(value: unknown): value is SchemaObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The property `name` of a schema object typed at `ref`. */\nfunction ownProperty(item: SchemaObject, ref: string, name: string): DeclaredProperty | undefined {\n const property = (\"properties\" in item ? item.properties : undefined)?.[name];\n return property === undefined ? undefined : { property, path: createRef([ref, name]) };\n}\n\n/** The property `name` of the schema at `ref`, its own or from an `allOf` item, depth first. */\nfunction declaredProperty(\n ref: string,\n name: string,\n resolve: ResolveSchemaRef,\n visited: Set<string>,\n): DeclaredProperty | undefined {\n const schema = resolve(ref);\n if (visited.has(ref) || !isSchemaObject(schema)) {\n return undefined;\n }\n visited.add(ref);\n // An inline `allOf` item is typed at its parent's location, so both share the path.\n for (const item of [schema, ...(schema.allOf ?? [])]) {\n if (!isSchemaObject(item)) {\n continue;\n }\n const found =\n \"$ref\" in item\n ? declaredProperty(item.$ref as string, name, resolve, visited)\n : ownProperty(item, ref, name);\n if (found !== undefined) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * A discriminator and the `$ref` of the schema that declares its property; `ref` is the member\n * whose value the discriminator gives, where there is one.\n */\nexport type DiscriminatorOwner = Pick<EnumPatch, \"discriminator\" | \"discriminatorRef\"> &\n Partial<Pick<EnumPatch, \"ref\">>;\n\n/**\n * The property `name` that the member at `ref` inherits through its `allOf` `$ref`s. Its own\n * keywords and inline items are left out: the scan writes the added value there.\n */\nfunction inheritedProperty(\n ref: string,\n name: string,\n resolve: ResolveSchemaRef,\n): DeclaredProperty | undefined {\n const schema = resolve(ref);\n const visited = new Set([ref]);\n for (const item of isSchemaObject(schema) ? (schema.allOf ?? []) : []) {\n const found =\n isSchemaObject(item) && \"$ref\" in item\n ? declaredProperty(item.$ref as string, name, resolve, visited)\n : undefined;\n if (found !== undefined) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * The enum of the property that the discriminator owner declares, if it is one. An owner that\n * declares no such property (a `oneOf` with a mapping) leaves the member's type to the property\n * the member inherits, so that property's enum is the one.\n */\nexport function enumParentOf(\n patch: DiscriminatorOwner,\n resolve: ResolveSchemaRef,\n): EnumParent | undefined {\n const name = patch.discriminator.propertyName;\n const declared =\n declaredProperty(patch.discriminatorRef, name, resolve, new Set()) ??\n (patch.ref === undefined ? undefined : inheritedProperty(patch.ref, name, resolve));\n if (declared === undefined || !isSchemaObject(declared.property)) {\n return undefined;\n }\n const ref = (declared.property as { readonly $ref?: unknown }).$ref;\n const parent =\n typeof ref === \"string\"\n ? { schema: resolve(ref), path: typedAt(ref) }\n : { schema: declared.property, path: declared.path };\n return isSchemaObject(parent.schema) && Array.isArray(parent.schema.enum)\n ? { schema: parent.schema, path: parent.path }\n : undefined;\n}\n"],"names":["parseRefPointer","createRef"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { parseRefPointer, createRef } from '../domain/openapi/json-pointer.mjs';
|
|
2
|
+
|
|
3
|
+
const PROPERTIES_KEYWORD = "properties";
|
|
4
|
+
const ROOT_SEGMENTS = 3;
|
|
5
|
+
function typedAt(ref) {
|
|
6
|
+
const segments = parseRefPointer(ref);
|
|
7
|
+
const nested = segments.slice(ROOT_SEGMENTS).filter((segment) => segment !== PROPERTIES_KEYWORD);
|
|
8
|
+
return createRef([...segments.slice(0, ROOT_SEGMENTS), ...nested]);
|
|
9
|
+
}
|
|
10
|
+
function isSchemaObject(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function ownProperty(item, ref, name) {
|
|
14
|
+
const property = ("properties" in item ? item.properties : void 0)?.[name];
|
|
15
|
+
return property === void 0 ? void 0 : { property, path: createRef([ref, name]) };
|
|
16
|
+
}
|
|
17
|
+
function declaredProperty(ref, name, resolve, visited) {
|
|
18
|
+
const schema = resolve(ref);
|
|
19
|
+
if (visited.has(ref) || !isSchemaObject(schema)) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
visited.add(ref);
|
|
23
|
+
for (const item of [schema, ...schema.allOf ?? []]) {
|
|
24
|
+
if (!isSchemaObject(item)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const found = "$ref" in item ? declaredProperty(item.$ref, name, resolve, visited) : ownProperty(item, ref, name);
|
|
28
|
+
if (found !== void 0) {
|
|
29
|
+
return found;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
function inheritedProperty(ref, name, resolve) {
|
|
35
|
+
const schema = resolve(ref);
|
|
36
|
+
const visited = /* @__PURE__ */ new Set([ref]);
|
|
37
|
+
for (const item of isSchemaObject(schema) ? schema.allOf ?? [] : []) {
|
|
38
|
+
const found = isSchemaObject(item) && "$ref" in item ? declaredProperty(item.$ref, name, resolve, visited) : void 0;
|
|
39
|
+
if (found !== void 0) {
|
|
40
|
+
return found;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function enumParentOf(patch, resolve) {
|
|
46
|
+
const name = patch.discriminator.propertyName;
|
|
47
|
+
const declared = declaredProperty(patch.discriminatorRef, name, resolve, /* @__PURE__ */ new Set()) ?? (patch.ref === void 0 ? void 0 : inheritedProperty(patch.ref, name, resolve));
|
|
48
|
+
if (declared === void 0 || !isSchemaObject(declared.property)) {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
const ref = declared.property.$ref;
|
|
52
|
+
const parent = typeof ref === "string" ? { schema: resolve(ref), path: typedAt(ref) } : { schema: declared.property, path: declared.path };
|
|
53
|
+
return isSchemaObject(parent.schema) && Array.isArray(parent.schema.enum) ? { schema: parent.schema, path: parent.path } : void 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { enumParentOf };
|
|
57
|
+
//# sourceMappingURL=discriminator-enum-parent.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-enum-parent.mjs","sources":["../../src/api/discriminator-enum-parent.ts"],"sourcesContent":["import { createRef, parseRefPointer } from \"../domain/openapi/json-pointer.js\";\nimport type { SchemaObject } from \"../types.js\";\nimport type { EnumPatch } from \"./discriminator-enum.js\";\n\n/**\n * The `discriminator-values` fix (#1700). With `--enum`, the enum the scan adds to a member\n * (`petType: \"Cat\"`) is declared as an enum of its own (`CatPetType`), which is not assignable to\n * the parent's enum (`PetType`). The parent's enum is found here, so the member's property can be\n * typed with its members (`PetType.Cat`).\n */\n\n/** The parent's enum schema and the location it is typed at, which gives the enum its name. */\nexport interface EnumParent {\n readonly schema: SchemaObject;\n readonly path: string;\n}\n\ntype ResolveSchemaRef = (ref: string) => unknown;\n\n/** A declared property schema and the location the transformer types it at. */\ninterface DeclaredProperty {\n readonly property: unknown;\n readonly path: string;\n}\n\nconst PROPERTIES_KEYWORD = \"properties\";\n/** `components`, `schemas` and the schema name: the segments before the schema's own keywords. */\nconst ROOT_SEGMENTS = 3;\n\n/** The location a `$ref` is typed at: object properties are nested without `properties`. */\nfunction typedAt(ref: string): string {\n const segments = parseRefPointer(ref);\n const nested = segments.slice(ROOT_SEGMENTS).filter((segment) => segment !== PROPERTIES_KEYWORD);\n return createRef([...segments.slice(0, ROOT_SEGMENTS), ...nested]);\n}\n\nfunction isSchemaObject(value: unknown): value is SchemaObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The property `name` of a schema object typed at `ref`. */\nfunction ownProperty(item: SchemaObject, ref: string, name: string): DeclaredProperty | undefined {\n const property = (\"properties\" in item ? item.properties : undefined)?.[name];\n return property === undefined ? undefined : { property, path: createRef([ref, name]) };\n}\n\n/** The property `name` of the schema at `ref`, its own or from an `allOf` item, depth first. */\nfunction declaredProperty(\n ref: string,\n name: string,\n resolve: ResolveSchemaRef,\n visited: Set<string>,\n): DeclaredProperty | undefined {\n const schema = resolve(ref);\n if (visited.has(ref) || !isSchemaObject(schema)) {\n return undefined;\n }\n visited.add(ref);\n // An inline `allOf` item is typed at its parent's location, so both share the path.\n for (const item of [schema, ...(schema.allOf ?? [])]) {\n if (!isSchemaObject(item)) {\n continue;\n }\n const found =\n \"$ref\" in item\n ? declaredProperty(item.$ref as string, name, resolve, visited)\n : ownProperty(item, ref, name);\n if (found !== undefined) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * A discriminator and the `$ref` of the schema that declares its property; `ref` is the member\n * whose value the discriminator gives, where there is one.\n */\nexport type DiscriminatorOwner = Pick<EnumPatch, \"discriminator\" | \"discriminatorRef\"> &\n Partial<Pick<EnumPatch, \"ref\">>;\n\n/**\n * The property `name` that the member at `ref` inherits through its `allOf` `$ref`s. Its own\n * keywords and inline items are left out: the scan writes the added value there.\n */\nfunction inheritedProperty(\n ref: string,\n name: string,\n resolve: ResolveSchemaRef,\n): DeclaredProperty | undefined {\n const schema = resolve(ref);\n const visited = new Set([ref]);\n for (const item of isSchemaObject(schema) ? (schema.allOf ?? []) : []) {\n const found =\n isSchemaObject(item) && \"$ref\" in item\n ? declaredProperty(item.$ref as string, name, resolve, visited)\n : undefined;\n if (found !== undefined) {\n return found;\n }\n }\n return undefined;\n}\n\n/**\n * The enum of the property that the discriminator owner declares, if it is one. An owner that\n * declares no such property (a `oneOf` with a mapping) leaves the member's type to the property\n * the member inherits, so that property's enum is the one.\n */\nexport function enumParentOf(\n patch: DiscriminatorOwner,\n resolve: ResolveSchemaRef,\n): EnumParent | undefined {\n const name = patch.discriminator.propertyName;\n const declared =\n declaredProperty(patch.discriminatorRef, name, resolve, new Set()) ??\n (patch.ref === undefined ? undefined : inheritedProperty(patch.ref, name, resolve));\n if (declared === undefined || !isSchemaObject(declared.property)) {\n return undefined;\n }\n const ref = (declared.property as { readonly $ref?: unknown }).$ref;\n const parent =\n typeof ref === \"string\"\n ? { schema: resolve(ref), path: typedAt(ref) }\n : { schema: declared.property, path: declared.path };\n return isSchemaObject(parent.schema) && Array.isArray(parent.schema.enum)\n ? { schema: parent.schema, path: parent.path }\n : undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,30 @@ function patchObjectSchema(schema, patch) {
|
|
|
33
33
|
function isObjectSchema(schema) {
|
|
34
34
|
return typeof schema === "object" && schema !== null && "type" in schema && schema.type === "object";
|
|
35
35
|
}
|
|
36
|
+
function listedValues(property) {
|
|
37
|
+
if (typeof property !== "object" || property === null) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const { const: constant, enum: values } = property;
|
|
41
|
+
if (constant !== void 0) {
|
|
42
|
+
return [constant];
|
|
43
|
+
}
|
|
44
|
+
return Array.isArray(values) ? values : null;
|
|
45
|
+
}
|
|
46
|
+
function requiresValues(schema, name, values) {
|
|
47
|
+
if (typeof schema !== "object" || schema === null || "$ref" in schema) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const { required, properties } = schema;
|
|
51
|
+
const listed = listedValues(properties?.[name]);
|
|
52
|
+
return Boolean(required?.includes(name)) && listed !== null && listed.length === values.length && values.every((value) => listed.includes(value));
|
|
53
|
+
}
|
|
54
|
+
function declaresValues(schema, patch) {
|
|
55
|
+
const name = patch.discriminator.propertyName;
|
|
56
|
+
return [schema, ...schema?.allOf ?? []].some(
|
|
57
|
+
(item) => requiresValues(item, name, patch.values)
|
|
58
|
+
);
|
|
59
|
+
}
|
|
36
60
|
function addEnumProperty(schema, patch) {
|
|
37
61
|
if (schema?.allOf) {
|
|
38
62
|
return patchAllOf(schema.allOf, patch);
|
|
@@ -41,4 +65,5 @@ function addEnumProperty(schema, patch) {
|
|
|
41
65
|
}
|
|
42
66
|
|
|
43
67
|
exports.addEnumProperty = addEnumProperty;
|
|
68
|
+
exports.declaresValues = declaresValues;
|
|
44
69
|
//# sourceMappingURL=discriminator-enum.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discriminator-enum.cjs","sources":["../../src/api/discriminator-enum.ts"],"sourcesContent":["import type {\n DiscriminatorObject,\n ObjectSubtype,\n ReferenceObject,\n SchemaObject,\n} from \"../types.js\";\n\n/**\n * The in-place patch of the discriminator pre-pass: a mapped schema gets a required enum property\n * with its discriminator values, so that TypeScript can narrow the generated union.\n */\n\n/** One mapped schema to patch: `ref` is the schema; `discriminatorRef` owns the discriminator. */\nexport interface EnumPatch {\n readonly ref: string;\n readonly values: string[];\n readonly discriminator: DiscriminatorObject;\n readonly discriminatorRef: string;\n}\n\nfunction discriminatorEnum(values: string[], previous?: SchemaObject): SchemaObject {\n return {\n type: \"string\",\n enum: values,\n description: previous?.description\n ? `${previous.description} (enum property replaced by openapi-typesafe)`\n : \"discriminator enum property added by openapi-typesafe\",\n };\n}\n\n/** An `allOf` schema gets one more item that holds the required enum property. */\nfunction patchAllOf(allOf: (SchemaObject | ReferenceObject)[], patch: EnumPatch): SchemaObject {\n const added = discriminatorEnum(patch.values);\n allOf.push({\n type: \"object\",\n required: [patch.discriminator.propertyName],\n properties: { [patch.discriminator.propertyName]: added },\n });\n return added;\n}\n\n/** An object schema gets the enum property, which is always required, added or replaced. */\nfunction patchObjectSchema(schema: SchemaObject & ObjectSubtype, patch: EnumPatch): SchemaObject {\n const name = patch.discriminator.propertyName;\n if (!schema.properties) {\n schema.properties = {};\n }\n if (!schema.required) {\n schema.required = [name];\n } else if (!schema.required.includes(name)) {\n schema.required.push(name);\n }\n const added = discriminatorEnum(patch.values, schema.properties[name] as SchemaObject);\n schema.properties[name] = added;\n return added;\n}\n\nfunction isObjectSchema(schema: unknown): schema is SchemaObject & ObjectSubtype {\n return (\n typeof schema === \"object\" && schema !== null && \"type\" in schema && schema.type === \"object\"\n );\n}\n\n/**\n * Add or replace the enum property in `schema`, an `allOf` or object schema. Returns the added\n * enum schema, or null for another kind of schema, which is left as it is.\n */\nexport function addEnumProperty(\n schema: SchemaObject | undefined,\n patch: EnumPatch,\n): SchemaObject | null {\n if (schema?.allOf) {\n return patchAllOf(schema.allOf, patch);\n }\n return isObjectSchema(schema) ? patchObjectSchema(schema, patch) : null;\n}\n"],"names":[],"mappings":";;AAoBA,SAAS,iBAAA,CAAkB,QAAkB,QAAA,EAAuC;AAClF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,aAAa,QAAA,EAAU,WAAA,GACnB,CAAA,EAAG,QAAA,CAAS,WAAW,CAAA,6CAAA,CAAA,GACvB;AAAA,GACN;AACF;AAGA,SAAS,UAAA,CAAW,OAA2C,KAAA,EAAgC;AAC7F,EAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA;AAC5C,EAAA,KAAA,CAAM,IAAA,CAAK;AAAA,IACT,IAAA,EAAM,QAAA;AAAA,IACN,QAAA,EAAU,CAAC,KAAA,CAAM,aAAA,CAAc,YAAY,CAAA;AAAA,IAC3C,YAAY,EAAE,CAAC,MAAM,aAAA,CAAc,YAAY,GAAG,KAAA;AAAM,GACzD,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,iBAAA,CAAkB,QAAsC,KAAA,EAAgC;AAC/F,EAAA,MAAM,IAAA,GAAO,MAAM,aAAA,CAAc,YAAA;AACjC,EAAA,IAAI,CAAC,OAAO,UAAA,EAAY;AACtB,IAAA,MAAA,CAAO,aAAa,EAAC;AAAA,EACvB;AACA,EAAA,IAAI,CAAC,OAAO,QAAA,EAAU;AACpB,IAAA,MAAA,CAAO,QAAA,GAAW,CAAC,IAAI,CAAA;AAAA,EACzB,WAAW,CAAC,MAAA,CAAO,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1C,IAAA,MAAA,CAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,EAC3B;AACA,EAAA,MAAM,QAAQ,iBAAA,CAAkB,KAAA,CAAM,QAAQ,MAAA,CAAO,UAAA,CAAW,IAAI,CAAiB,CAAA;AACrF,EAAA,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA,GAAI,KAAA;AAC1B,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAe,MAAA,EAAyD;AAC/E,EAAA,OACE,OAAO,WAAW,QAAA,IAAY,MAAA,KAAW,QAAQ,MAAA,IAAU,MAAA,IAAU,OAAO,IAAA,KAAS,QAAA;AAEzF;AAMO,SAAS,eAAA,CACd,QACA,KAAA,EACqB;AACrB,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,OAAO,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,KAAK,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,eAAe,MAAM,CAAA,GAAI,iBAAA,CAAkB,MAAA,EAAQ,KAAK,CAAA,GAAI,IAAA;AACrE
|
|
1
|
+
{"version":3,"file":"discriminator-enum.cjs","sources":["../../src/api/discriminator-enum.ts"],"sourcesContent":["import type {\n DiscriminatorObject,\n ObjectSubtype,\n ReferenceObject,\n SchemaObject,\n} from \"../types.js\";\n\n/**\n * The in-place patch of the discriminator pre-pass: a mapped schema gets a required enum property\n * with its discriminator values, so that TypeScript can narrow the generated union.\n */\n\n/** One mapped schema to patch: `ref` is the schema; `discriminatorRef` owns the discriminator. */\nexport interface EnumPatch {\n readonly ref: string;\n readonly values: string[];\n readonly discriminator: DiscriminatorObject;\n readonly discriminatorRef: string;\n}\n\nfunction discriminatorEnum(values: string[], previous?: SchemaObject): SchemaObject {\n return {\n type: \"string\",\n enum: values,\n description: previous?.description\n ? `${previous.description} (enum property replaced by openapi-typesafe)`\n : \"discriminator enum property added by openapi-typesafe\",\n };\n}\n\n/** An `allOf` schema gets one more item that holds the required enum property. */\nfunction patchAllOf(allOf: (SchemaObject | ReferenceObject)[], patch: EnumPatch): SchemaObject {\n const added = discriminatorEnum(patch.values);\n allOf.push({\n type: \"object\",\n required: [patch.discriminator.propertyName],\n properties: { [patch.discriminator.propertyName]: added },\n });\n return added;\n}\n\n/** An object schema gets the enum property, which is always required, added or replaced. */\nfunction patchObjectSchema(schema: SchemaObject & ObjectSubtype, patch: EnumPatch): SchemaObject {\n const name = patch.discriminator.propertyName;\n if (!schema.properties) {\n schema.properties = {};\n }\n if (!schema.required) {\n schema.required = [name];\n } else if (!schema.required.includes(name)) {\n schema.required.push(name);\n }\n const added = discriminatorEnum(patch.values, schema.properties[name] as SchemaObject);\n schema.properties[name] = added;\n return added;\n}\n\nfunction isObjectSchema(schema: unknown): schema is SchemaObject & ObjectSubtype {\n return (\n typeof schema === \"object\" && schema !== null && \"type\" in schema && schema.type === \"object\"\n );\n}\n\n/** The values a property schema allows, from `const` or `enum`; null when it lists none. */\nfunction listedValues(property: unknown): readonly unknown[] | null {\n if (typeof property !== \"object\" || property === null) {\n return null;\n }\n const { const: constant, enum: values } = property as SchemaObject;\n if (constant !== undefined) {\n return [constant];\n }\n return Array.isArray(values) ? values : null;\n}\n\n/** Whether one schema object requires the property and allows exactly the values. */\nfunction requiresValues(schema: unknown, name: string, values: readonly string[]): boolean {\n if (typeof schema !== \"object\" || schema === null || \"$ref\" in schema) {\n return false;\n }\n const { required, properties } = schema as SchemaObject & ObjectSubtype;\n const listed = listedValues(properties?.[name]);\n return (\n Boolean(required?.includes(name)) &&\n listed !== null &&\n listed.length === values.length &&\n values.every((value) => listed.includes(value))\n );\n}\n\n/**\n * Whether `schema`, or an inline `allOf` item of it, already requires the discriminator property\n * with exactly the patch's values (the `discriminator-values` fix). Then a patch would\n * only repeat it (#2124).\n */\nexport function declaresValues(schema: SchemaObject | undefined, patch: EnumPatch): boolean {\n const name = patch.discriminator.propertyName;\n return [schema, ...(schema?.allOf ?? [])].some((item) =>\n requiresValues(item, name, patch.values),\n );\n}\n\n/**\n * Add or replace the enum property in `schema`, an `allOf` or object schema. Returns the added\n * enum schema, or null for another kind of schema, which is left as it is.\n */\nexport function addEnumProperty(\n schema: SchemaObject | undefined,\n patch: EnumPatch,\n): SchemaObject | null {\n if (schema?.allOf) {\n return patchAllOf(schema.allOf, patch);\n }\n return isObjectSchema(schema) ? patchObjectSchema(schema, patch) : null;\n}\n"],"names":[],"mappings":"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"}
|