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
|
@@ -31,6 +31,30 @@ function patchObjectSchema(schema, patch) {
|
|
|
31
31
|
function isObjectSchema(schema) {
|
|
32
32
|
return typeof schema === "object" && schema !== null && "type" in schema && schema.type === "object";
|
|
33
33
|
}
|
|
34
|
+
function listedValues(property) {
|
|
35
|
+
if (typeof property !== "object" || property === null) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const { const: constant, enum: values } = property;
|
|
39
|
+
if (constant !== void 0) {
|
|
40
|
+
return [constant];
|
|
41
|
+
}
|
|
42
|
+
return Array.isArray(values) ? values : null;
|
|
43
|
+
}
|
|
44
|
+
function requiresValues(schema, name, values) {
|
|
45
|
+
if (typeof schema !== "object" || schema === null || "$ref" in schema) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const { required, properties } = schema;
|
|
49
|
+
const listed = listedValues(properties?.[name]);
|
|
50
|
+
return Boolean(required?.includes(name)) && listed !== null && listed.length === values.length && values.every((value) => listed.includes(value));
|
|
51
|
+
}
|
|
52
|
+
function declaresValues(schema, patch) {
|
|
53
|
+
const name = patch.discriminator.propertyName;
|
|
54
|
+
return [schema, ...schema?.allOf ?? []].some(
|
|
55
|
+
(item) => requiresValues(item, name, patch.values)
|
|
56
|
+
);
|
|
57
|
+
}
|
|
34
58
|
function addEnumProperty(schema, patch) {
|
|
35
59
|
if (schema?.allOf) {
|
|
36
60
|
return patchAllOf(schema.allOf, patch);
|
|
@@ -38,5 +62,5 @@ function addEnumProperty(schema, patch) {
|
|
|
38
62
|
return isObjectSchema(schema) ? patchObjectSchema(schema, patch) : null;
|
|
39
63
|
}
|
|
40
64
|
|
|
41
|
-
export { addEnumProperty };
|
|
65
|
+
export { addEnumProperty, declaresValues };
|
|
42
66
|
//# sourceMappingURL=discriminator-enum.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discriminator-enum.mjs","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.mjs","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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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const discriminatorPatch = require('./discriminator-patch.cjs');
|
|
4
|
+
const documentRefs = require('./document-refs.cjs');
|
|
5
|
+
|
|
6
|
+
function allOfRefs(state, ref) {
|
|
7
|
+
const { silent, logger } = state;
|
|
8
|
+
const schema = documentRefs.resolveDocumentRef(state.schema, ref, { silent, logger });
|
|
9
|
+
const items = schema?.allOf ?? [];
|
|
10
|
+
return items.flatMap(
|
|
11
|
+
(item) => "$ref" in item && typeof item.$ref === "string" ? [item.$ref] : []
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
function otherOwners(state, parentRef) {
|
|
15
|
+
const own = state.objects[parentRef]?.propertyName;
|
|
16
|
+
const found = /* @__PURE__ */ new Map();
|
|
17
|
+
const visited = /* @__PURE__ */ new Set();
|
|
18
|
+
const queue = [parentRef];
|
|
19
|
+
for (let ref = queue.shift(); ref !== void 0; ref = queue.shift()) {
|
|
20
|
+
if (visited.has(ref)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
visited.add(ref);
|
|
24
|
+
const discriminator = state.owners.has(ref) ? state.objects[ref] : void 0;
|
|
25
|
+
const name = discriminator?.propertyName;
|
|
26
|
+
if (discriminator && name !== void 0 && name !== own && !found.has(name)) {
|
|
27
|
+
found.set(name, { discriminator, ownerRef: ref });
|
|
28
|
+
}
|
|
29
|
+
queue.push(...allOfRefs(state, ref));
|
|
30
|
+
}
|
|
31
|
+
return [...found.values()];
|
|
32
|
+
}
|
|
33
|
+
function recordOtherProperty(state, ref, propertyName) {
|
|
34
|
+
const names = state.otherProperties[ref] ?? [];
|
|
35
|
+
if (!names.includes(propertyName)) {
|
|
36
|
+
names.push(propertyName);
|
|
37
|
+
}
|
|
38
|
+
state.otherProperties[ref] = names;
|
|
39
|
+
}
|
|
40
|
+
function inheritOtherOwners(state, parentRef, ref) {
|
|
41
|
+
const childProperty = state.objects[ref]?.propertyName;
|
|
42
|
+
for (const { discriminator, ownerRef } of otherOwners(state, parentRef)) {
|
|
43
|
+
if (discriminator.propertyName === childProperty) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
recordOtherProperty(state, ref, discriminator.propertyName);
|
|
47
|
+
const mapped = Object.entries(discriminator.mapping ?? {}).filter(([, target]) => target === ref).map(([value]) => value);
|
|
48
|
+
const name = ref.slice(ref.lastIndexOf("/") + 1);
|
|
49
|
+
const patch = { ref, values: mapped, discriminator, discriminatorRef: ownerRef };
|
|
50
|
+
if (mapped.length > 0) {
|
|
51
|
+
discriminatorPatch.patchDiscriminatorEnum(state, patch);
|
|
52
|
+
} else {
|
|
53
|
+
state.otherInferredPatches.push({ ...patch, values: [name] });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function applyOtherInferredPatches(state, mapped) {
|
|
58
|
+
for (const patch of state.otherInferredPatches) {
|
|
59
|
+
if (!mapped.has(discriminatorPatch.enumKey(patch))) {
|
|
60
|
+
discriminatorPatch.patchDiscriminatorEnum(state, patch);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.applyOtherInferredPatches = applyOtherInferredPatches;
|
|
66
|
+
exports.inheritOtherOwners = inheritOtherOwners;
|
|
67
|
+
//# sourceMappingURL=discriminator-other-owners.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-other-owners.cjs","sources":["../../src/api/discriminator-other-owners.ts"],"sourcesContent":["import type { DiscriminatorObject, ReferenceObject, SchemaObject } from \"../types.js\";\nimport type { EnumPatch } from \"./discriminator-enum.js\";\nimport { enumKey, patchDiscriminatorEnum, type ScanState } from \"./discriminator-patch.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The `discriminator-values` fix: a schema inherits one discriminator per property. A schema that\n * owns a discriminator keeps its own (#2200), so the scan does not record the one it inherits for\n * another property (`Content` owns `subtype` and `allOf`s `Element`, which owns `contentType`).\n * Its members (`Video`) still get a value of that property, found here from the owners above.\n */\n\n/** A discriminator and the schema that defines it. */\ninterface OtherOwner {\n readonly discriminator: DiscriminatorObject;\n readonly ownerRef: string;\n}\n\n/** The `$ref`s of a schema's `allOf` items. */\nfunction allOfRefs(state: ScanState, ref: string): string[] {\n const { silent, logger } = state;\n const schema = resolveDocumentRef<SchemaObject>(state.schema, ref, { silent, logger });\n const items = (schema?.allOf ?? []) as (SchemaObject | ReferenceObject)[];\n return items.flatMap((item) =>\n \"$ref\" in item && typeof item.$ref === \"string\" ? [item.$ref] : [],\n );\n}\n\n/**\n * The owners' discriminators that the schema at `parentRef` and its `allOf` parents define, the\n * nearest one per property, except the property of `parentRef`'s own discriminator.\n */\nfunction otherOwners(state: ScanState, parentRef: string): OtherOwner[] {\n const own = state.objects[parentRef]?.propertyName;\n const found = new Map<string, OtherOwner>();\n const visited = new Set<string>();\n const queue = [parentRef];\n for (let ref = queue.shift(); ref !== undefined; ref = queue.shift()) {\n if (visited.has(ref)) {\n continue;\n }\n visited.add(ref);\n const discriminator = state.owners.has(ref) ? state.objects[ref] : undefined;\n const name = discriminator?.propertyName;\n if (discriminator && name !== undefined && name !== own && !found.has(name)) {\n found.set(name, { discriminator, ownerRef: ref });\n }\n queue.push(...allOfRefs(state, ref));\n }\n return [...found.values()];\n}\n\n/**\n * The child redefines this property, so its `allOf` items omit it: a parent may have a value of\n * its own, as `Content` has when `Element`'s mapping names it.\n */\nfunction recordOtherProperty(state: ScanState, ref: string, propertyName: string): void {\n const names = state.otherProperties[ref] ?? [];\n if (!names.includes(propertyName)) {\n names.push(propertyName);\n }\n state.otherProperties[ref] = names;\n}\n\n/**\n * The child at `ref` of the schema at `parentRef` gets a value of each other property: a mapped\n * one at once, else its schema name after both passes, where no mapping gives one. The schema's\n * own discriminator property is still added, so these patches do not mark it handled.\n */\nexport function inheritOtherOwners(state: ScanState, parentRef: string, ref: string): void {\n const childProperty = state.objects[ref]?.propertyName;\n for (const { discriminator, ownerRef } of otherOwners(state, parentRef)) {\n if (discriminator.propertyName === childProperty) {\n continue;\n }\n recordOtherProperty(state, ref, discriminator.propertyName);\n const mapped = Object.entries(discriminator.mapping ?? {})\n .filter(([, target]) => target === ref)\n .map(([value]) => value);\n const name = ref.slice(ref.lastIndexOf(\"/\") + 1);\n const patch: EnumPatch = { ref, values: mapped, discriminator, discriminatorRef: ownerRef };\n if (mapped.length > 0) {\n patchDiscriminatorEnum(state, patch);\n } else {\n state.otherInferredPatches.push({ ...patch, values: [name] });\n }\n }\n}\n\n/** The deferred schema-name values of other properties; see `inheritOtherOwners`. */\nexport function applyOtherInferredPatches(state: ScanState, mapped: ReadonlySet<string>): void {\n for (const patch of state.otherInferredPatches) {\n if (!mapped.has(enumKey(patch))) {\n patchDiscriminatorEnum(state, patch);\n }\n }\n}\n"],"names":["resolveDocumentRef","patchDiscriminatorEnum","enumKey"],"mappings":";;;;;AAmBA,SAAS,SAAA,CAAU,OAAkB,GAAA,EAAuB;AAC1D,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,KAAA;AAC3B,EAAA,MAAM,MAAA,GAASA,gCAAiC,KAAA,CAAM,MAAA,EAAQ,KAAK,EAAE,MAAA,EAAQ,QAAQ,CAAA;AACrF,EAAA,MAAM,KAAA,GAAS,MAAA,EAAQ,KAAA,IAAS,EAAC;AACjC,EAAA,OAAO,KAAA,CAAM,OAAA;AAAA,IAAQ,CAAC,IAAA,KACpB,MAAA,IAAU,IAAA,IAAQ,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,CAAC,IAAA,CAAK,IAAI,CAAA,GAAI;AAAC,GACnE;AACF;AAMA,SAAS,WAAA,CAAY,OAAkB,SAAA,EAAiC;AACtE,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,EAAG,YAAA;AACtC,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAwB;AAC1C,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,KAAA,GAAQ,CAAC,SAAS,CAAA;AACxB,EAAA,KAAA,IAAS,GAAA,GAAM,MAAM,KAAA,EAAM,EAAG,QAAQ,MAAA,EAAW,GAAA,GAAM,KAAA,CAAM,KAAA,EAAM,EAAG;AACpE,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACpB,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,IAAI,GAAG,CAAA;AACf,IAAA,MAAM,aAAA,GAAgB,MAAM,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,MAAA;AACnE,IAAA,MAAM,OAAO,aAAA,EAAe,YAAA;AAC5B,IAAA,IAAI,aAAA,IAAiB,SAAS,MAAA,IAAa,IAAA,KAAS,OAAO,CAAC,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AAC3E,MAAA,KAAA,CAAM,IAAI,IAAA,EAAM,EAAE,aAAA,EAAe,QAAA,EAAU,KAAK,CAAA;AAAA,IAClD;AACA,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,SAAA,CAAU,KAAA,EAAO,GAAG,CAAC,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,CAAC,GAAG,KAAA,CAAM,MAAA,EAAQ,CAAA;AAC3B;AAMA,SAAS,mBAAA,CAAoB,KAAA,EAAkB,GAAA,EAAa,YAAA,EAA4B;AACtF,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,eAAA,CAAgB,GAAG,KAAK,EAAC;AAC7C,EAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,YAAY,CAAA,EAAG;AACjC,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,EACzB;AACA,EAAA,KAAA,CAAM,eAAA,CAAgB,GAAG,CAAA,GAAI,KAAA;AAC/B;AAOO,SAAS,kBAAA,CAAmB,KAAA,EAAkB,SAAA,EAAmB,GAAA,EAAmB;AACzF,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG,YAAA;AAC1C,EAAA,KAAA,MAAW,EAAE,aAAA,EAAe,QAAA,MAAc,WAAA,CAAY,KAAA,EAAO,SAAS,CAAA,EAAG;AACvE,IAAA,IAAI,aAAA,CAAc,iBAAiB,aAAA,EAAe;AAChD,MAAA;AAAA,IACF;AACA,IAAA,mBAAA,CAAoB,KAAA,EAAO,GAAA,EAAK,aAAA,CAAc,YAAY,CAAA;AAC1D,IAAA,MAAM,MAAA,GAAS,OAAO,OAAA,CAAQ,aAAA,CAAc,WAAW,EAAE,CAAA,CACtD,MAAA,CAAO,CAAC,GAAG,MAAM,CAAA,KAAM,WAAW,GAAG,CAAA,CACrC,IAAI,CAAC,CAAC,KAAK,CAAA,KAAM,KAAK,CAAA;AACzB,IAAA,MAAM,OAAO,GAAA,CAAI,KAAA,CAAM,IAAI,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AAC/C,IAAA,MAAM,QAAmB,EAAE,GAAA,EAAK,QAAQ,MAAA,EAAQ,aAAA,EAAe,kBAAkB,QAAA,EAAS;AAC1F,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,MAAAC,yCAAA,CAAuB,OAAO,KAAK,CAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,oBAAA,CAAqB,KAAK,EAAE,GAAG,OAAO,MAAA,EAAQ,CAAC,IAAI,CAAA,EAAG,CAAA;AAAA,IAC9D;AAAA,EACF;AACF;AAGO,SAAS,yBAAA,CAA0B,OAAkB,MAAA,EAAmC;AAC7F,EAAA,KAAA,MAAW,KAAA,IAAS,MAAM,oBAAA,EAAsB;AAC9C,IAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAIC,0BAAA,CAAQ,KAAK,CAAC,CAAA,EAAG;AAC/B,MAAAD,yCAAA,CAAuB,OAAO,KAAK,CAAA;AAAA,IACrC;AAAA,EACF;AACF;;;"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { enumKey, patchDiscriminatorEnum } from './discriminator-patch.mjs';
|
|
2
|
+
import { resolveDocumentRef } from './document-refs.mjs';
|
|
3
|
+
|
|
4
|
+
function allOfRefs(state, ref) {
|
|
5
|
+
const { silent, logger } = state;
|
|
6
|
+
const schema = resolveDocumentRef(state.schema, ref, { silent, logger });
|
|
7
|
+
const items = schema?.allOf ?? [];
|
|
8
|
+
return items.flatMap(
|
|
9
|
+
(item) => "$ref" in item && typeof item.$ref === "string" ? [item.$ref] : []
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
function otherOwners(state, parentRef) {
|
|
13
|
+
const own = state.objects[parentRef]?.propertyName;
|
|
14
|
+
const found = /* @__PURE__ */ new Map();
|
|
15
|
+
const visited = /* @__PURE__ */ new Set();
|
|
16
|
+
const queue = [parentRef];
|
|
17
|
+
for (let ref = queue.shift(); ref !== void 0; ref = queue.shift()) {
|
|
18
|
+
if (visited.has(ref)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
visited.add(ref);
|
|
22
|
+
const discriminator = state.owners.has(ref) ? state.objects[ref] : void 0;
|
|
23
|
+
const name = discriminator?.propertyName;
|
|
24
|
+
if (discriminator && name !== void 0 && name !== own && !found.has(name)) {
|
|
25
|
+
found.set(name, { discriminator, ownerRef: ref });
|
|
26
|
+
}
|
|
27
|
+
queue.push(...allOfRefs(state, ref));
|
|
28
|
+
}
|
|
29
|
+
return [...found.values()];
|
|
30
|
+
}
|
|
31
|
+
function recordOtherProperty(state, ref, propertyName) {
|
|
32
|
+
const names = state.otherProperties[ref] ?? [];
|
|
33
|
+
if (!names.includes(propertyName)) {
|
|
34
|
+
names.push(propertyName);
|
|
35
|
+
}
|
|
36
|
+
state.otherProperties[ref] = names;
|
|
37
|
+
}
|
|
38
|
+
function inheritOtherOwners(state, parentRef, ref) {
|
|
39
|
+
const childProperty = state.objects[ref]?.propertyName;
|
|
40
|
+
for (const { discriminator, ownerRef } of otherOwners(state, parentRef)) {
|
|
41
|
+
if (discriminator.propertyName === childProperty) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
recordOtherProperty(state, ref, discriminator.propertyName);
|
|
45
|
+
const mapped = Object.entries(discriminator.mapping ?? {}).filter(([, target]) => target === ref).map(([value]) => value);
|
|
46
|
+
const name = ref.slice(ref.lastIndexOf("/") + 1);
|
|
47
|
+
const patch = { ref, values: mapped, discriminator, discriminatorRef: ownerRef };
|
|
48
|
+
if (mapped.length > 0) {
|
|
49
|
+
patchDiscriminatorEnum(state, patch);
|
|
50
|
+
} else {
|
|
51
|
+
state.otherInferredPatches.push({ ...patch, values: [name] });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function applyOtherInferredPatches(state, mapped) {
|
|
56
|
+
for (const patch of state.otherInferredPatches) {
|
|
57
|
+
if (!mapped.has(enumKey(patch))) {
|
|
58
|
+
patchDiscriminatorEnum(state, patch);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { applyOtherInferredPatches, inheritOtherOwners };
|
|
64
|
+
//# sourceMappingURL=discriminator-other-owners.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-other-owners.mjs","sources":["../../src/api/discriminator-other-owners.ts"],"sourcesContent":["import type { DiscriminatorObject, ReferenceObject, SchemaObject } from \"../types.js\";\nimport type { EnumPatch } from \"./discriminator-enum.js\";\nimport { enumKey, patchDiscriminatorEnum, type ScanState } from \"./discriminator-patch.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The `discriminator-values` fix: a schema inherits one discriminator per property. A schema that\n * owns a discriminator keeps its own (#2200), so the scan does not record the one it inherits for\n * another property (`Content` owns `subtype` and `allOf`s `Element`, which owns `contentType`).\n * Its members (`Video`) still get a value of that property, found here from the owners above.\n */\n\n/** A discriminator and the schema that defines it. */\ninterface OtherOwner {\n readonly discriminator: DiscriminatorObject;\n readonly ownerRef: string;\n}\n\n/** The `$ref`s of a schema's `allOf` items. */\nfunction allOfRefs(state: ScanState, ref: string): string[] {\n const { silent, logger } = state;\n const schema = resolveDocumentRef<SchemaObject>(state.schema, ref, { silent, logger });\n const items = (schema?.allOf ?? []) as (SchemaObject | ReferenceObject)[];\n return items.flatMap((item) =>\n \"$ref\" in item && typeof item.$ref === \"string\" ? [item.$ref] : [],\n );\n}\n\n/**\n * The owners' discriminators that the schema at `parentRef` and its `allOf` parents define, the\n * nearest one per property, except the property of `parentRef`'s own discriminator.\n */\nfunction otherOwners(state: ScanState, parentRef: string): OtherOwner[] {\n const own = state.objects[parentRef]?.propertyName;\n const found = new Map<string, OtherOwner>();\n const visited = new Set<string>();\n const queue = [parentRef];\n for (let ref = queue.shift(); ref !== undefined; ref = queue.shift()) {\n if (visited.has(ref)) {\n continue;\n }\n visited.add(ref);\n const discriminator = state.owners.has(ref) ? state.objects[ref] : undefined;\n const name = discriminator?.propertyName;\n if (discriminator && name !== undefined && name !== own && !found.has(name)) {\n found.set(name, { discriminator, ownerRef: ref });\n }\n queue.push(...allOfRefs(state, ref));\n }\n return [...found.values()];\n}\n\n/**\n * The child redefines this property, so its `allOf` items omit it: a parent may have a value of\n * its own, as `Content` has when `Element`'s mapping names it.\n */\nfunction recordOtherProperty(state: ScanState, ref: string, propertyName: string): void {\n const names = state.otherProperties[ref] ?? [];\n if (!names.includes(propertyName)) {\n names.push(propertyName);\n }\n state.otherProperties[ref] = names;\n}\n\n/**\n * The child at `ref` of the schema at `parentRef` gets a value of each other property: a mapped\n * one at once, else its schema name after both passes, where no mapping gives one. The schema's\n * own discriminator property is still added, so these patches do not mark it handled.\n */\nexport function inheritOtherOwners(state: ScanState, parentRef: string, ref: string): void {\n const childProperty = state.objects[ref]?.propertyName;\n for (const { discriminator, ownerRef } of otherOwners(state, parentRef)) {\n if (discriminator.propertyName === childProperty) {\n continue;\n }\n recordOtherProperty(state, ref, discriminator.propertyName);\n const mapped = Object.entries(discriminator.mapping ?? {})\n .filter(([, target]) => target === ref)\n .map(([value]) => value);\n const name = ref.slice(ref.lastIndexOf(\"/\") + 1);\n const patch: EnumPatch = { ref, values: mapped, discriminator, discriminatorRef: ownerRef };\n if (mapped.length > 0) {\n patchDiscriminatorEnum(state, patch);\n } else {\n state.otherInferredPatches.push({ ...patch, values: [name] });\n }\n }\n}\n\n/** The deferred schema-name values of other properties; see `inheritOtherOwners`. */\nexport function applyOtherInferredPatches(state: ScanState, mapped: ReadonlySet<string>): void {\n for (const patch of state.otherInferredPatches) {\n if (!mapped.has(enumKey(patch))) {\n patchDiscriminatorEnum(state, patch);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const outputFixes = require('../domain/output-fixes.cjs');
|
|
4
|
+
const discriminatorEnum = require('./discriminator-enum.cjs');
|
|
5
|
+
const discriminatorEnumParent = require('./discriminator-enum-parent.cjs');
|
|
6
|
+
const documentRefs = require('./document-refs.cjs');
|
|
7
|
+
|
|
8
|
+
function mergesValues(state) {
|
|
9
|
+
return state.fixes.has(outputFixes.OutputFix.DISCRIMINATOR_VALUES);
|
|
10
|
+
}
|
|
11
|
+
function patchedSchema(state, patch) {
|
|
12
|
+
const { silent, logger } = state;
|
|
13
|
+
return documentRefs.resolveDocumentRef(state.schema, patch.ref, { silent, logger });
|
|
14
|
+
}
|
|
15
|
+
function isDeclared(state, patch) {
|
|
16
|
+
return state.fixes.has(outputFixes.OutputFix.DISCRIMINATOR_VALUES) && discriminatorEnum.declaresValues(patchedSchema(state, patch), patch);
|
|
17
|
+
}
|
|
18
|
+
function recordEnumParent(state, owner, key) {
|
|
19
|
+
if (!state.fixes.has(outputFixes.OutputFix.DISCRIMINATOR_VALUES)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const { silent, logger } = state;
|
|
23
|
+
const parent = discriminatorEnumParent.enumParentOf(
|
|
24
|
+
owner,
|
|
25
|
+
(ref) => documentRefs.resolveDocumentRef(state.schema, ref, { silent, logger })
|
|
26
|
+
);
|
|
27
|
+
if (parent !== void 0) {
|
|
28
|
+
state.enumParents.set(key, parent);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function addDiscriminatorEnum(state, patch) {
|
|
32
|
+
const added = discriminatorEnum.addEnumProperty(patchedSchema(state, patch), patch);
|
|
33
|
+
if (added === null) {
|
|
34
|
+
warnInvalidMapping(patch, state.logger);
|
|
35
|
+
} else {
|
|
36
|
+
recordEnumParent(state, patch, added);
|
|
37
|
+
}
|
|
38
|
+
return added;
|
|
39
|
+
}
|
|
40
|
+
function enumKey(patch) {
|
|
41
|
+
return `${patch.ref}
|
|
42
|
+
${patch.discriminator.propertyName}`;
|
|
43
|
+
}
|
|
44
|
+
function mergeIntoPatchedEnum(state, key, values) {
|
|
45
|
+
const patched = state.patchedEnums.get(key);
|
|
46
|
+
if (patched === void 0) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const merged = patched.enum;
|
|
50
|
+
merged.push(...values.filter((value) => !merged.includes(value)));
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
function patchDiscriminatorEnum(state, patch) {
|
|
54
|
+
if (isDeclared(state, patch)) {
|
|
55
|
+
state.declaredKeys.add(enumKey(patch));
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (!mergesValues(state)) {
|
|
59
|
+
return addDiscriminatorEnum(state, patch) !== null;
|
|
60
|
+
}
|
|
61
|
+
const key = enumKey(patch);
|
|
62
|
+
if (mergeIntoPatchedEnum(state, key, patch.values)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
const added = addDiscriminatorEnum(state, patch);
|
|
66
|
+
if (added !== null) {
|
|
67
|
+
state.patchedEnums.set(key, added);
|
|
68
|
+
}
|
|
69
|
+
return added !== null;
|
|
70
|
+
}
|
|
71
|
+
function markHandled(state, ref) {
|
|
72
|
+
if (!state.refsHandled.includes(ref)) {
|
|
73
|
+
state.refsHandled.push(ref);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function warnInvalidMapping(patch, logger) {
|
|
77
|
+
const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
|
|
78
|
+
logger.warn(
|
|
79
|
+
`Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): ${mapped} (Discriminator: ${patch.discriminatorRef})`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.enumKey = enumKey;
|
|
84
|
+
exports.markHandled = markHandled;
|
|
85
|
+
exports.mergesValues = mergesValues;
|
|
86
|
+
exports.patchDiscriminatorEnum = patchDiscriminatorEnum;
|
|
87
|
+
exports.recordEnumParent = recordEnumParent;
|
|
88
|
+
//# sourceMappingURL=discriminator-patch.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-patch.cjs","sources":["../../src/api/discriminator-patch.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport type { DiscriminatorObject, OpenAPI3, SchemaObject } from \"../types.js\";\nimport { addEnumProperty, declaresValues, type EnumPatch } from \"./discriminator-enum.js\";\nimport {\n type DiscriminatorOwner,\n type EnumParent,\n enumParentOf,\n} from \"./discriminator-enum-parent.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The state of the discriminator pre-pass and the in-place patch of a mapped schema: the enum\n * property that the generated union narrows by. Two discriminators of one property may patch one\n * schema; how they combine is the `discriminator-values` fix (ADR-021, roadmap R12).\n */\n\n/** How to scan: the warnings, and the output fixes of the run (ADR-021). */\nexport interface DiscriminatorScanOptions {\n readonly silent: boolean;\n readonly logger: Logger;\n readonly fixes: ReadonlySet<OutputFix>;\n}\n\n/** What the two passes share: the document they patch and what they found so far. */\nexport interface ScanState extends DiscriminatorScanOptions {\n readonly schema: OpenAPI3;\n readonly objects: Record<string, DiscriminatorObject>;\n /** The schemas that define a discriminator themselves (pass 1), not by inheritance. */\n readonly owners: Set<string>;\n readonly refsHandled: string[];\n /** With the fix: the enum added to each schema, by schema and property, so values merge. */\n readonly patchedEnums: Map<string, SchemaObject>;\n /** With the fix: schema-name values, applied after both passes where no mapping names one. */\n readonly inferredPatches: EnumPatch[];\n /** With the fix: schema-name values of other properties (`inheritOtherOwners`). */\n readonly otherInferredPatches: EnumPatch[];\n /** With the fix: the other properties each schema got a value of (`inheritOtherOwners`). */\n readonly otherProperties: Record<string, string[]>;\n /** With `discriminator-values`: the enum keys that a schema declares itself. */\n readonly declaredKeys: Set<string>;\n /** With `discriminator-values`: the owner's enum of each added enum, by that enum. */\n readonly enumParents: Map<object, EnumParent>;\n}\n\n/** Whether `discriminator-values` is on: values of two discriminators merge into one enum. */\nexport function mergesValues(state: ScanState): boolean {\n return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);\n}\n\nfunction patchedSchema(state: ScanState, patch: EnumPatch): SchemaObject | undefined {\n const { silent, logger } = state;\n return resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });\n}\n\n/**\n * With `discriminator-values`: the schema at `patch.ref` requires the property with\n * exactly these values already, so a patch would only repeat it (#2124).\n */\nfunction isDeclared(state: ScanState, patch: EnumPatch): boolean {\n return (\n state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) &&\n declaresValues(patchedSchema(state, patch), patch)\n );\n}\n\n/**\n * With `discriminator-values`: the enum of the owner's property, for `key`: an enum the scan\n * added, or a discriminator object that a schema inherited.\n */\nexport function recordEnumParent(state: ScanState, owner: DiscriminatorOwner, key: object): void {\n if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {\n return;\n }\n const { silent, logger } = state;\n const parent = enumParentOf(owner, (ref) =>\n resolveDocumentRef(state.schema, ref, { silent, logger }),\n );\n if (parent !== undefined) {\n state.enumParents.set(key, parent);\n }\n}\n\n/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */\nfunction addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {\n const added = addEnumProperty(patchedSchema(state, patch), patch);\n if (added === null) {\n warnInvalidMapping(patch, state.logger);\n } else {\n recordEnumParent(state, patch, added);\n }\n return added;\n}\n\n/** One schema and discriminator property; two discriminators of one property share an enum. */\nexport function enumKey(patch: EnumPatch): string {\n return `${patch.ref}\\n${patch.discriminator.propertyName}`;\n}\n\n/** With the fix, a second discriminator of the same property adds its values to the first enum. */\nfunction mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {\n const patched = state.patchedEnums.get(key);\n if (patched === undefined) {\n return false;\n }\n const merged = patched.enum as unknown[];\n merged.push(...values.filter((value) => !merged.includes(value)));\n return true;\n}\n\n/**\n * Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a\n * warning, when that schema is neither an `allOf` nor an object schema. Without the fix every\n * patch adds a property, so two discriminators with different values intersect to `never`.\n */\nexport function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {\n if (isDeclared(state, patch)) {\n state.declaredKeys.add(enumKey(patch));\n return true;\n }\n if (!mergesValues(state)) {\n return addDiscriminatorEnum(state, patch) !== null;\n }\n const key = enumKey(patch);\n if (mergeIntoPatchedEnum(state, key, patch.values)) {\n return true;\n }\n const added = addDiscriminatorEnum(state, patch);\n if (added !== null) {\n state.patchedEnums.set(key, added);\n }\n return added !== null;\n}\n\nexport function markHandled(state: ScanState, ref: string): void {\n if (!state.refsHandled.includes(ref)) {\n state.refsHandled.push(ref);\n }\n}\n\nfunction warnInvalidMapping(patch: EnumPatch, logger: Logger): void {\n const mapped = `${patch.ref} => ${patch.values.join(\", \")}`;\n logger.warn(\n \"Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): \" +\n `${mapped} (Discriminator: ${patch.discriminatorRef})`,\n );\n}\n"],"names":["OutputFix","resolveDocumentRef","declaresValues","enumParentOf","addEnumProperty"],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { OutputFix } from '../domain/output-fixes.mjs';
|
|
2
|
+
import { declaresValues, addEnumProperty } from './discriminator-enum.mjs';
|
|
3
|
+
import { enumParentOf } from './discriminator-enum-parent.mjs';
|
|
4
|
+
import { resolveDocumentRef } from './document-refs.mjs';
|
|
5
|
+
|
|
6
|
+
function mergesValues(state) {
|
|
7
|
+
return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);
|
|
8
|
+
}
|
|
9
|
+
function patchedSchema(state, patch) {
|
|
10
|
+
const { silent, logger } = state;
|
|
11
|
+
return resolveDocumentRef(state.schema, patch.ref, { silent, logger });
|
|
12
|
+
}
|
|
13
|
+
function isDeclared(state, patch) {
|
|
14
|
+
return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) && declaresValues(patchedSchema(state, patch), patch);
|
|
15
|
+
}
|
|
16
|
+
function recordEnumParent(state, owner, key) {
|
|
17
|
+
if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const { silent, logger } = state;
|
|
21
|
+
const parent = enumParentOf(
|
|
22
|
+
owner,
|
|
23
|
+
(ref) => resolveDocumentRef(state.schema, ref, { silent, logger })
|
|
24
|
+
);
|
|
25
|
+
if (parent !== void 0) {
|
|
26
|
+
state.enumParents.set(key, parent);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function addDiscriminatorEnum(state, patch) {
|
|
30
|
+
const added = addEnumProperty(patchedSchema(state, patch), patch);
|
|
31
|
+
if (added === null) {
|
|
32
|
+
warnInvalidMapping(patch, state.logger);
|
|
33
|
+
} else {
|
|
34
|
+
recordEnumParent(state, patch, added);
|
|
35
|
+
}
|
|
36
|
+
return added;
|
|
37
|
+
}
|
|
38
|
+
function enumKey(patch) {
|
|
39
|
+
return `${patch.ref}
|
|
40
|
+
${patch.discriminator.propertyName}`;
|
|
41
|
+
}
|
|
42
|
+
function mergeIntoPatchedEnum(state, key, values) {
|
|
43
|
+
const patched = state.patchedEnums.get(key);
|
|
44
|
+
if (patched === void 0) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const merged = patched.enum;
|
|
48
|
+
merged.push(...values.filter((value) => !merged.includes(value)));
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
function patchDiscriminatorEnum(state, patch) {
|
|
52
|
+
if (isDeclared(state, patch)) {
|
|
53
|
+
state.declaredKeys.add(enumKey(patch));
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (!mergesValues(state)) {
|
|
57
|
+
return addDiscriminatorEnum(state, patch) !== null;
|
|
58
|
+
}
|
|
59
|
+
const key = enumKey(patch);
|
|
60
|
+
if (mergeIntoPatchedEnum(state, key, patch.values)) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
const added = addDiscriminatorEnum(state, patch);
|
|
64
|
+
if (added !== null) {
|
|
65
|
+
state.patchedEnums.set(key, added);
|
|
66
|
+
}
|
|
67
|
+
return added !== null;
|
|
68
|
+
}
|
|
69
|
+
function markHandled(state, ref) {
|
|
70
|
+
if (!state.refsHandled.includes(ref)) {
|
|
71
|
+
state.refsHandled.push(ref);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function warnInvalidMapping(patch, logger) {
|
|
75
|
+
const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
|
|
76
|
+
logger.warn(
|
|
77
|
+
`Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): ${mapped} (Discriminator: ${patch.discriminatorRef})`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { enumKey, markHandled, mergesValues, patchDiscriminatorEnum, recordEnumParent };
|
|
82
|
+
//# sourceMappingURL=discriminator-patch.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminator-patch.mjs","sources":["../../src/api/discriminator-patch.ts"],"sourcesContent":["import type { Logger } from \"../application/ports/logger.js\";\nimport { OutputFix } from \"../domain/output-fixes.js\";\nimport type { DiscriminatorObject, OpenAPI3, SchemaObject } from \"../types.js\";\nimport { addEnumProperty, declaresValues, type EnumPatch } from \"./discriminator-enum.js\";\nimport {\n type DiscriminatorOwner,\n type EnumParent,\n enumParentOf,\n} from \"./discriminator-enum-parent.js\";\nimport { resolveDocumentRef } from \"./document-refs.js\";\n\n/**\n * The state of the discriminator pre-pass and the in-place patch of a mapped schema: the enum\n * property that the generated union narrows by. Two discriminators of one property may patch one\n * schema; how they combine is the `discriminator-values` fix (ADR-021, roadmap R12).\n */\n\n/** How to scan: the warnings, and the output fixes of the run (ADR-021). */\nexport interface DiscriminatorScanOptions {\n readonly silent: boolean;\n readonly logger: Logger;\n readonly fixes: ReadonlySet<OutputFix>;\n}\n\n/** What the two passes share: the document they patch and what they found so far. */\nexport interface ScanState extends DiscriminatorScanOptions {\n readonly schema: OpenAPI3;\n readonly objects: Record<string, DiscriminatorObject>;\n /** The schemas that define a discriminator themselves (pass 1), not by inheritance. */\n readonly owners: Set<string>;\n readonly refsHandled: string[];\n /** With the fix: the enum added to each schema, by schema and property, so values merge. */\n readonly patchedEnums: Map<string, SchemaObject>;\n /** With the fix: schema-name values, applied after both passes where no mapping names one. */\n readonly inferredPatches: EnumPatch[];\n /** With the fix: schema-name values of other properties (`inheritOtherOwners`). */\n readonly otherInferredPatches: EnumPatch[];\n /** With the fix: the other properties each schema got a value of (`inheritOtherOwners`). */\n readonly otherProperties: Record<string, string[]>;\n /** With `discriminator-values`: the enum keys that a schema declares itself. */\n readonly declaredKeys: Set<string>;\n /** With `discriminator-values`: the owner's enum of each added enum, by that enum. */\n readonly enumParents: Map<object, EnumParent>;\n}\n\n/** Whether `discriminator-values` is on: values of two discriminators merge into one enum. */\nexport function mergesValues(state: ScanState): boolean {\n return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);\n}\n\nfunction patchedSchema(state: ScanState, patch: EnumPatch): SchemaObject | undefined {\n const { silent, logger } = state;\n return resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });\n}\n\n/**\n * With `discriminator-values`: the schema at `patch.ref` requires the property with\n * exactly these values already, so a patch would only repeat it (#2124).\n */\nfunction isDeclared(state: ScanState, patch: EnumPatch): boolean {\n return (\n state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) &&\n declaresValues(patchedSchema(state, patch), patch)\n );\n}\n\n/**\n * With `discriminator-values`: the enum of the owner's property, for `key`: an enum the scan\n * added, or a discriminator object that a schema inherited.\n */\nexport function recordEnumParent(state: ScanState, owner: DiscriminatorOwner, key: object): void {\n if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {\n return;\n }\n const { silent, logger } = state;\n const parent = enumParentOf(owner, (ref) =>\n resolveDocumentRef(state.schema, ref, { silent, logger }),\n );\n if (parent !== undefined) {\n state.enumParents.set(key, parent);\n }\n}\n\n/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */\nfunction addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {\n const added = addEnumProperty(patchedSchema(state, patch), patch);\n if (added === null) {\n warnInvalidMapping(patch, state.logger);\n } else {\n recordEnumParent(state, patch, added);\n }\n return added;\n}\n\n/** One schema and discriminator property; two discriminators of one property share an enum. */\nexport function enumKey(patch: EnumPatch): string {\n return `${patch.ref}\\n${patch.discriminator.propertyName}`;\n}\n\n/** With the fix, a second discriminator of the same property adds its values to the first enum. */\nfunction mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {\n const patched = state.patchedEnums.get(key);\n if (patched === undefined) {\n return false;\n }\n const merged = patched.enum as unknown[];\n merged.push(...values.filter((value) => !merged.includes(value)));\n return true;\n}\n\n/**\n * Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a\n * warning, when that schema is neither an `allOf` nor an object schema. Without the fix every\n * patch adds a property, so two discriminators with different values intersect to `never`.\n */\nexport function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {\n if (isDeclared(state, patch)) {\n state.declaredKeys.add(enumKey(patch));\n return true;\n }\n if (!mergesValues(state)) {\n return addDiscriminatorEnum(state, patch) !== null;\n }\n const key = enumKey(patch);\n if (mergeIntoPatchedEnum(state, key, patch.values)) {\n return true;\n }\n const added = addDiscriminatorEnum(state, patch);\n if (added !== null) {\n state.patchedEnums.set(key, added);\n }\n return added !== null;\n}\n\nexport function markHandled(state: ScanState, ref: string): void {\n if (!state.refsHandled.includes(ref)) {\n state.refsHandled.push(ref);\n }\n}\n\nfunction warnInvalidMapping(patch: EnumPatch, logger: Logger): void {\n const mapped = `${patch.ref} => ${patch.values.join(\", \")}`;\n logger.warn(\n \"Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): \" +\n `${mapped} (Discriminator: ${patch.discriminatorRef})`,\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,57 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const discriminatedUnion = require('../domain/openapi/discriminated-union.cjs');
|
|
4
|
+
const outputFixes = require('../domain/output-fixes.cjs');
|
|
3
5
|
const defaultPorts = require('./default-ports.cjs');
|
|
4
|
-
const
|
|
6
|
+
const discriminatorOtherOwners = require('./discriminator-other-owners.cjs');
|
|
7
|
+
const discriminatorPatch = require('./discriminator-patch.cjs');
|
|
5
8
|
const documentRefs = require('./document-refs.cjs');
|
|
6
9
|
const legacyUtils = require('./legacy-utils.cjs');
|
|
7
10
|
|
|
8
|
-
function addDiscriminatorEnum(state, patch) {
|
|
9
|
-
const { silent, logger } = state;
|
|
10
|
-
const resolved = documentRefs.resolveDocumentRef(state.schema, patch.ref, { silent, logger });
|
|
11
|
-
const added = discriminatorEnum.addEnumProperty(resolved, patch);
|
|
12
|
-
if (added === null) {
|
|
13
|
-
warnInvalidMapping(patch, state.logger);
|
|
14
|
-
}
|
|
15
|
-
return added;
|
|
16
|
-
}
|
|
17
|
-
function enumKey(patch) {
|
|
18
|
-
return `${patch.ref}
|
|
19
|
-
${patch.discriminator.propertyName}`;
|
|
20
|
-
}
|
|
21
|
-
function mergeIntoPatchedEnum(state, key, values) {
|
|
22
|
-
const patched = state.patchedEnums.get(key);
|
|
23
|
-
if (patched === void 0) {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
const merged = patched.enum;
|
|
27
|
-
merged.push(...values.filter((value) => !merged.includes(value)));
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
function patchDiscriminatorEnum(state, patch) {
|
|
31
|
-
if (!state.fixesValueConflicts) {
|
|
32
|
-
return addDiscriminatorEnum(state, patch) !== null;
|
|
33
|
-
}
|
|
34
|
-
const key = enumKey(patch);
|
|
35
|
-
if (mergeIntoPatchedEnum(state, key, patch.values)) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
const added = addDiscriminatorEnum(state, patch);
|
|
39
|
-
if (added !== null) {
|
|
40
|
-
state.patchedEnums.set(key, added);
|
|
41
|
-
}
|
|
42
|
-
return added !== null;
|
|
43
|
-
}
|
|
44
|
-
function markHandled(state, ref) {
|
|
45
|
-
if (!state.refsHandled.includes(ref)) {
|
|
46
|
-
state.refsHandled.push(ref);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function warnInvalidMapping(patch, logger) {
|
|
50
|
-
const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
|
|
51
|
-
logger.warn(
|
|
52
|
-
`Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): ${mapped} (Discriminator: ${patch.discriminatorRef})`
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
11
|
function inferredMapping(oneOf) {
|
|
56
12
|
const mapping = {};
|
|
57
13
|
for (const item of oneOf) {
|
|
@@ -65,8 +21,8 @@ function inferredMapping(oneOf) {
|
|
|
65
21
|
}
|
|
66
22
|
return mapping;
|
|
67
23
|
}
|
|
68
|
-
function addDefinedMapping(mapping,
|
|
69
|
-
for (const [mappedValue, mappedRef] of Object.entries(
|
|
24
|
+
function addDefinedMapping(mapping, defined) {
|
|
25
|
+
for (const [mappedValue, mappedRef] of Object.entries(defined)) {
|
|
70
26
|
if (!mappedRef) {
|
|
71
27
|
continue;
|
|
72
28
|
}
|
|
@@ -78,15 +34,15 @@ function addDefinedMapping(mapping, discriminator) {
|
|
|
78
34
|
}
|
|
79
35
|
function patchMappedSchemas(state, mapping, discriminator) {
|
|
80
36
|
for (const [ref, { inferred, defined }] of Object.entries(mapping)) {
|
|
81
|
-
const isSkipped = !state
|
|
37
|
+
const isSkipped = !discriminatorPatch.mergesValues(state) && state.refsHandled.includes(ref);
|
|
82
38
|
if (isSkipped || !inferred && !defined) {
|
|
83
39
|
continue;
|
|
84
40
|
}
|
|
85
41
|
const values = defined ?? [inferred];
|
|
86
|
-
if (state
|
|
42
|
+
if (discriminatorPatch.mergesValues(state) && defined === void 0) {
|
|
87
43
|
state.inferredPatches.push({ ...discriminator, ref, values });
|
|
88
|
-
} else if (patchDiscriminatorEnum(state, { ...discriminator, ref, values })) {
|
|
89
|
-
markHandled(state, ref);
|
|
44
|
+
} else if (discriminatorPatch.patchDiscriminatorEnum(state, { ...discriminator, ref, values })) {
|
|
45
|
+
discriminatorPatch.markHandled(state, ref);
|
|
90
46
|
}
|
|
91
47
|
}
|
|
92
48
|
}
|
|
@@ -97,18 +53,35 @@ function collectDiscriminator(state, value, path) {
|
|
|
97
53
|
}
|
|
98
54
|
const discriminatorRef = legacyUtils.createRef(path);
|
|
99
55
|
state.objects[discriminatorRef] = discriminator;
|
|
56
|
+
state.owners.add(discriminatorRef);
|
|
100
57
|
if (!Array.isArray(value.oneOf)) {
|
|
101
58
|
return;
|
|
102
59
|
}
|
|
103
60
|
const mapping = inferredMapping(value.oneOf);
|
|
104
61
|
if (discriminator.mapping) {
|
|
105
|
-
addDefinedMapping(mapping, discriminator);
|
|
62
|
+
addDefinedMapping(mapping, discriminator.mapping);
|
|
106
63
|
}
|
|
107
64
|
patchMappedSchemas(state, mapping, { discriminator, discriminatorRef });
|
|
108
65
|
}
|
|
109
66
|
function valuesMappedTo(discriminator, ref) {
|
|
110
67
|
return Object.entries(discriminator.mapping ?? {}).filter(([, mappedRef]) => mappedRef === ref).map(([mappedValue]) => mappedValue);
|
|
111
68
|
}
|
|
69
|
+
function inheritsDiscriminator(state, parentRef, ref) {
|
|
70
|
+
if (!state.fixes.has(outputFixes.OutputFix.ALLOF_DISCRIMINATED_UNION)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const resolve = (target) => documentRefs.resolveDocumentRef(state.schema, target, state);
|
|
74
|
+
const union = discriminatedUnion.unionAt(parentRef, resolve);
|
|
75
|
+
return union === void 0 || discriminatedUnion.isUnionMember(union, ref, resolve);
|
|
76
|
+
}
|
|
77
|
+
function recordInherited(state, ref, discriminator, ownerRef) {
|
|
78
|
+
if (state.fixes.has(outputFixes.OutputFix.DISCRIMINATOR_VALUES) && state.owners.has(ref)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const inherited = { ...discriminator };
|
|
82
|
+
state.objects[ref] = inherited;
|
|
83
|
+
discriminatorPatch.recordEnumParent(state, { discriminator, discriminatorRef: ownerRef }, inherited);
|
|
84
|
+
}
|
|
112
85
|
function inheritFromRef(state, parentRef, ref) {
|
|
113
86
|
const discriminator = state.objects[parentRef];
|
|
114
87
|
if (!discriminator) {
|
|
@@ -116,10 +89,15 @@ function inheritFromRef(state, parentRef, ref) {
|
|
|
116
89
|
}
|
|
117
90
|
const values = valuesMappedTo(discriminator, ref);
|
|
118
91
|
const patch = { ref, values, discriminator, discriminatorRef: parentRef };
|
|
119
|
-
if (values.length > 0 && patchDiscriminatorEnum(state, patch)) {
|
|
120
|
-
markHandled(state, ref);
|
|
92
|
+
if (values.length > 0 && discriminatorPatch.patchDiscriminatorEnum(state, patch)) {
|
|
93
|
+
discriminatorPatch.markHandled(state, ref);
|
|
94
|
+
}
|
|
95
|
+
if (inheritsDiscriminator(state, parentRef, ref)) {
|
|
96
|
+
recordInherited(state, ref, discriminator, parentRef);
|
|
97
|
+
if (discriminatorPatch.mergesValues(state)) {
|
|
98
|
+
discriminatorOtherOwners.inheritOtherOwners(state, parentRef, ref);
|
|
99
|
+
}
|
|
121
100
|
}
|
|
122
|
-
state.objects[ref] = { ...discriminator };
|
|
123
101
|
return true;
|
|
124
102
|
}
|
|
125
103
|
function inheritDiscriminators(state, value, path) {
|
|
@@ -132,35 +110,42 @@ function inheritDiscriminators(state, value, path) {
|
|
|
132
110
|
return;
|
|
133
111
|
}
|
|
134
112
|
} else if (item.discriminator?.propertyName) {
|
|
135
|
-
state
|
|
113
|
+
recordInherited(state, legacyUtils.createRef(path), item.discriminator, legacyUtils.createRef(path));
|
|
136
114
|
}
|
|
137
115
|
}
|
|
138
116
|
}
|
|
139
117
|
function applyInferredPatches(state) {
|
|
140
|
-
const mapped = new Set(state.patchedEnums.keys());
|
|
118
|
+
const mapped = /* @__PURE__ */ new Set([...state.patchedEnums.keys(), ...state.declaredKeys]);
|
|
141
119
|
for (const patch of state.inferredPatches) {
|
|
142
|
-
if (!mapped.has(enumKey(patch)) && patchDiscriminatorEnum(state, patch)) {
|
|
143
|
-
markHandled(state, patch.ref);
|
|
120
|
+
if (!mapped.has(discriminatorPatch.enumKey(patch)) && discriminatorPatch.patchDiscriminatorEnum(state, patch)) {
|
|
121
|
+
discriminatorPatch.markHandled(state, patch.ref);
|
|
144
122
|
}
|
|
145
123
|
}
|
|
124
|
+
discriminatorOtherOwners.applyOtherInferredPatches(state, mapped);
|
|
146
125
|
}
|
|
147
126
|
function findDiscriminators(schema, options) {
|
|
148
127
|
const state = {
|
|
149
128
|
...options,
|
|
150
129
|
schema,
|
|
151
130
|
objects: {},
|
|
131
|
+
owners: /* @__PURE__ */ new Set(),
|
|
152
132
|
refsHandled: [],
|
|
153
133
|
patchedEnums: /* @__PURE__ */ new Map(),
|
|
154
|
-
inferredPatches: []
|
|
134
|
+
inferredPatches: [],
|
|
135
|
+
otherInferredPatches: [],
|
|
136
|
+
otherProperties: {},
|
|
137
|
+
declaredKeys: /* @__PURE__ */ new Set(),
|
|
138
|
+
enumParents: /* @__PURE__ */ new Map()
|
|
155
139
|
};
|
|
156
140
|
documentRefs.walkDocument(schema, (value, path) => collectDiscriminator(state, value, path));
|
|
157
141
|
documentRefs.walkDocument(schema, (value, path) => inheritDiscriminators(state, value, path));
|
|
158
142
|
applyInferredPatches(state);
|
|
159
|
-
|
|
143
|
+
const { objects, refsHandled, enumParents, otherProperties } = state;
|
|
144
|
+
return { objects, refsHandled, enumParents, otherProperties };
|
|
160
145
|
}
|
|
161
146
|
function scanDiscriminators(schema, options, logger = defaultPorts.defaultLogger(options.silent ?? false)) {
|
|
162
147
|
const silent = options.silent ?? false;
|
|
163
|
-
return findDiscriminators(schema, { silent, logger,
|
|
148
|
+
return findDiscriminators(schema, { silent, logger, fixes: /* @__PURE__ */ new Set() });
|
|
164
149
|
}
|
|
165
150
|
|
|
166
151
|
exports.findDiscriminators = findDiscriminators;
|