openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.2
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/README.md +12 -5
- package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
- 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 +34 -11
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +33 -10
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-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/default-ports.cjs +9 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +8 -1
- package/dist/api/default-ports.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 +92 -0
- package/dist/api/discriminator-patch.cjs.map +1 -0
- package/dist/api/discriminator-patch.mjs +86 -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-refs.cjs +15 -12
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +15 -12
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +21 -4
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +22 -5
- 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/footer-sink.cjs +25 -2
- package/dist/api/footer-sink.cjs.map +1 -1
- package/dist/api/footer-sink.mjs +25 -2
- package/dist/api/footer-sink.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +4 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +4 -1
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/legacy-ts-helpers.cjs.map +1 -1
- package/dist/api/legacy-ts-helpers.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +2 -1
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +3 -2
- package/dist/api/openapi-ts.mjs.map +1 -1
- 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 +4 -2
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +4 -2
- 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 +7 -1
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +7 -1
- 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 +41 -9
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +42 -10
- 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 +55 -29
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +54 -30
- 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 +42 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/evaluation.mjs +33 -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 +138 -0
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.mjs +136 -0
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.cjs +107 -0
- package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.mjs +105 -0
- package/dist/application/transform/footer/type-indexing.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/api-settings.cjs +78 -0
- package/dist/cli/api-settings.cjs.map +1 -0
- package/dist/cli/api-settings.mjs +73 -0
- package/dist/cli/api-settings.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +12 -3
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +12 -4
- 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/help-text.cjs +3 -3
- package/dist/cli/help-text.cjs.map +1 -1
- package/dist/cli/help-text.mjs +3 -3
- package/dist/cli/help-text.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 +15 -7
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +15 -7
- 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 +20 -3
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +21 -4
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/errors.cjs +6 -1
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +6 -1
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +7 -1
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +6 -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/url-credentials.cjs +10 -0
- package/dist/domain/url-credentials.cjs.map +1 -0
- package/dist/domain/url-credentials.mjs +8 -0
- package/dist/domain/url-credentials.mjs.map +1 -0
- package/dist/domain/warnings.cjs +23 -0
- package/dist/domain/warnings.cjs.map +1 -0
- package/dist/domain/warnings.mjs +20 -0
- package/dist/domain/warnings.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1182 -46
- package/dist/index.d.mts +1182 -46
- package/dist/index.d.ts +1182 -46
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- 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/dist/transform/path-item-object.cjs.map +1 -1
- package/dist/transform/path-item-object.mjs.map +1 -1
- package/package.json +6 -5
- package/src/adapters/redocly-loader/configured-headers.ts +65 -0
- package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +44 -13
- package/src/adapters/redocly-loader/ref-access.ts +60 -5
- package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
- package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
- package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
- package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
- package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +5 -1
- package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
- package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
- package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
- package/src/api/default-ports.ts +16 -0
- 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 +152 -0
- package/src/api/discriminator-scan.ts +78 -90
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +32 -11
- package/src/api/enum-values-warnings.ts +21 -0
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +7 -3
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +2 -0
- package/src/api/path-template-warnings.ts +27 -0
- package/src/api/run-context.ts +34 -0
- package/src/api/transform-context.ts +17 -9
- package/src/api/transform-schema.ts +90 -5
- 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 +8 -1
- 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 +78 -12
- 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 +101 -38
- 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 +57 -0
- package/src/application/transform/footer/shared-enum-names.ts +86 -0
- package/src/application/transform/footer/type-evaluation.ts +167 -0
- package/src/application/transform/footer/type-indexing.ts +152 -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/api-settings.ts +109 -0
- package/src/cli/cli-arguments.ts +18 -5
- 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/help-text.ts +4 -4
- package/src/cli/main.ts +6 -0
- package/src/cli/redocly-apis.ts +21 -11
- package/src/cli/ref-limits.ts +2 -2
- package/src/cli/run-cli.ts +25 -4
- package/src/domain/errors.ts +10 -2
- package/src/domain/ir/constructors.ts +9 -1
- package/src/domain/ir/nodes.ts +11 -7
- 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 +32 -0
- package/src/domain/openapi/schema-object.ts +2 -0
- package/src/domain/output-fixes.ts +43 -2
- package/src/domain/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +28 -0
- package/src/index.ts +1 -0
- package/src/transform/components-object.ts +3 -1
- package/src/transform/path-item-object.ts +6 -2
- package/src/types/generator-options.ts +12 -21
- package/src/types/openapi-common.ts +1 -0
- package/src/types/openapi-request.ts +3 -0
- package/src/types/openapi-schema.ts +2 -0
- package/src/types/openapi-security.ts +1 -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
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { Logger } from "../application/ports/logger.js";
|
|
2
|
+
import { OutputFix } from "../domain/output-fixes.js";
|
|
3
|
+
import { WARNING_CODES, warningText } from "../domain/warnings.js";
|
|
4
|
+
import type { DiscriminatorObject, OpenAPI3, SchemaObject } from "../types.js";
|
|
5
|
+
import { addEnumProperty, declaresValues, type EnumPatch } from "./discriminator-enum.js";
|
|
6
|
+
import {
|
|
7
|
+
type DiscriminatorOwner,
|
|
8
|
+
type EnumParent,
|
|
9
|
+
enumParentOf,
|
|
10
|
+
} from "./discriminator-enum-parent.js";
|
|
11
|
+
import { resolveDocumentRef } from "./document-refs.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The state of the discriminator pre-pass and the in-place patch of a mapped schema: the enum
|
|
15
|
+
* property that the generated union narrows by. Two discriminators of one property may patch one
|
|
16
|
+
* schema; how they combine is the `discriminator-values` fix (ADR-021, roadmap R12).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** How to scan: the warnings, and the output fixes of the run (ADR-021). */
|
|
20
|
+
export interface DiscriminatorScanOptions {
|
|
21
|
+
readonly silent: boolean;
|
|
22
|
+
readonly logger: Logger;
|
|
23
|
+
readonly fixes: ReadonlySet<OutputFix>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** What the two passes share: the document they patch and what they found so far. */
|
|
27
|
+
export interface ScanState extends DiscriminatorScanOptions {
|
|
28
|
+
readonly schema: OpenAPI3;
|
|
29
|
+
readonly objects: Record<string, DiscriminatorObject>;
|
|
30
|
+
/** The schemas that define a discriminator themselves (pass 1), not by inheritance. */
|
|
31
|
+
readonly owners: Set<string>;
|
|
32
|
+
readonly refsHandled: string[];
|
|
33
|
+
/** With the fix: the enum added to each schema, by schema and property, so values merge. */
|
|
34
|
+
readonly patchedEnums: Map<string, SchemaObject>;
|
|
35
|
+
/** With the fix: schema-name values, applied after both passes where no mapping names one. */
|
|
36
|
+
readonly inferredPatches: EnumPatch[];
|
|
37
|
+
/** With the fix: schema-name values of other properties (`inheritOtherOwners`). */
|
|
38
|
+
readonly otherInferredPatches: EnumPatch[];
|
|
39
|
+
/** With the fix: the other properties each schema got a value of (`inheritOtherOwners`). */
|
|
40
|
+
readonly otherProperties: Record<string, string[]>;
|
|
41
|
+
/** With `discriminator-values`: the enum keys that a schema declares itself. */
|
|
42
|
+
readonly declaredKeys: Set<string>;
|
|
43
|
+
/** With `discriminator-values`: the owner's enum of each added enum, by that enum. */
|
|
44
|
+
readonly enumParents: Map<object, EnumParent>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Whether `discriminator-values` is on: values of two discriminators merge into one enum. */
|
|
48
|
+
export function mergesValues(state: ScanState): boolean {
|
|
49
|
+
return state.fixes.has(OutputFix.DISCRIMINATOR_VALUES);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function patchedSchema(state: ScanState, patch: EnumPatch): SchemaObject | undefined {
|
|
53
|
+
const { silent, logger } = state;
|
|
54
|
+
return resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* With `discriminator-values`: the schema at `patch.ref` requires the property with
|
|
59
|
+
* exactly these values already, so a patch would only repeat it (#2124).
|
|
60
|
+
*/
|
|
61
|
+
function isDeclared(state: ScanState, patch: EnumPatch): boolean {
|
|
62
|
+
return (
|
|
63
|
+
state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) &&
|
|
64
|
+
declaresValues(patchedSchema(state, patch), patch)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* With `discriminator-values`: the enum of the owner's property, for `key`: an enum the scan
|
|
70
|
+
* added, or a discriminator object that a schema inherited.
|
|
71
|
+
*/
|
|
72
|
+
export function recordEnumParent(state: ScanState, owner: DiscriminatorOwner, key: object): void {
|
|
73
|
+
if (!state.fixes.has(OutputFix.DISCRIMINATOR_VALUES)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const { silent, logger } = state;
|
|
77
|
+
const parent = enumParentOf(owner, (ref) =>
|
|
78
|
+
resolveDocumentRef(state.schema, ref, { silent, logger }),
|
|
79
|
+
);
|
|
80
|
+
if (parent !== undefined) {
|
|
81
|
+
state.enumParents.set(key, parent);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */
|
|
86
|
+
function addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {
|
|
87
|
+
const added = addEnumProperty(patchedSchema(state, patch), patch);
|
|
88
|
+
if (added === null) {
|
|
89
|
+
warnInvalidMapping(patch, state.logger);
|
|
90
|
+
} else {
|
|
91
|
+
recordEnumParent(state, patch, added);
|
|
92
|
+
}
|
|
93
|
+
return added;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** One schema and discriminator property; two discriminators of one property share an enum. */
|
|
97
|
+
export function enumKey(patch: EnumPatch): string {
|
|
98
|
+
return `${patch.ref}\n${patch.discriminator.propertyName}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** With the fix, a second discriminator of the same property adds its values to the first enum. */
|
|
102
|
+
function mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {
|
|
103
|
+
const patched = state.patchedEnums.get(key);
|
|
104
|
+
if (patched === undefined) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const merged = patched.enum as unknown[];
|
|
108
|
+
merged.push(...values.filter((value) => !merged.includes(value)));
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a
|
|
114
|
+
* warning, when that schema is neither an `allOf` nor an object schema. Without the fix every
|
|
115
|
+
* patch adds a property, so two discriminators with different values intersect to `never`.
|
|
116
|
+
*/
|
|
117
|
+
export function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {
|
|
118
|
+
if (isDeclared(state, patch)) {
|
|
119
|
+
state.declaredKeys.add(enumKey(patch));
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (!mergesValues(state)) {
|
|
123
|
+
return addDiscriminatorEnum(state, patch) !== null;
|
|
124
|
+
}
|
|
125
|
+
const key = enumKey(patch);
|
|
126
|
+
if (mergeIntoPatchedEnum(state, key, patch.values)) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
const added = addDiscriminatorEnum(state, patch);
|
|
130
|
+
if (added !== null) {
|
|
131
|
+
state.patchedEnums.set(key, added);
|
|
132
|
+
}
|
|
133
|
+
return added !== null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function markHandled(state: ScanState, ref: string): void {
|
|
137
|
+
if (!state.refsHandled.includes(ref)) {
|
|
138
|
+
state.refsHandled.push(ref);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function warnInvalidMapping(patch: EnumPatch, logger: Logger): void {
|
|
143
|
+
const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
|
|
144
|
+
logger.warn(
|
|
145
|
+
warningText(
|
|
146
|
+
"Discriminator mapping has an invalid schema " +
|
|
147
|
+
"(neither an object schema nor an allOf array): " +
|
|
148
|
+
`${mapped} (Discriminator: ${patch.discriminatorRef})`,
|
|
149
|
+
WARNING_CODES.DISCRIMINATOR_MAPPING_INVALID,
|
|
150
|
+
),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Logger } from "../application/ports/logger.js";
|
|
2
|
+
import { isUnionMember, unionAt } from "../domain/openapi/discriminated-union.js";
|
|
3
|
+
import { OutputFix } from "../domain/output-fixes.js";
|
|
2
4
|
import type {
|
|
3
5
|
DiscriminatorObject,
|
|
4
6
|
GeneratorOptions,
|
|
@@ -7,7 +9,18 @@ import type {
|
|
|
7
9
|
SchemaObject,
|
|
8
10
|
} from "../types.js";
|
|
9
11
|
import { defaultLogger } from "./default-ports.js";
|
|
10
|
-
import {
|
|
12
|
+
import type { EnumPatch } from "./discriminator-enum.js";
|
|
13
|
+
import type { EnumParent } from "./discriminator-enum-parent.js";
|
|
14
|
+
import { applyOtherInferredPatches, inheritOtherOwners } from "./discriminator-other-owners.js";
|
|
15
|
+
import {
|
|
16
|
+
type DiscriminatorScanOptions,
|
|
17
|
+
enumKey,
|
|
18
|
+
markHandled,
|
|
19
|
+
mergesValues,
|
|
20
|
+
patchDiscriminatorEnum,
|
|
21
|
+
recordEnumParent,
|
|
22
|
+
type ScanState,
|
|
23
|
+
} from "./discriminator-patch.js";
|
|
11
24
|
import { resolveDocumentRef, walkDocument } from "./document-refs.js";
|
|
12
25
|
import { createRef } from "./legacy-utils.js";
|
|
13
26
|
|
|
@@ -19,85 +32,6 @@ import { createRef } from "./legacy-utils.js";
|
|
|
19
32
|
|
|
20
33
|
type DiscriminatorMapping = Record<string, { inferred?: string; defined?: string[] }>;
|
|
21
34
|
|
|
22
|
-
/** How to scan; `fixesValueConflicts` is the `discriminator-values` fix (ADR-021, roadmap R12). */
|
|
23
|
-
export interface DiscriminatorScanOptions {
|
|
24
|
-
readonly silent: boolean;
|
|
25
|
-
readonly logger: Logger;
|
|
26
|
-
readonly fixesValueConflicts: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** What the two passes share: the document they patch and what they found so far. */
|
|
30
|
-
interface ScanState extends DiscriminatorScanOptions {
|
|
31
|
-
readonly schema: OpenAPI3;
|
|
32
|
-
readonly objects: Record<string, DiscriminatorObject>;
|
|
33
|
-
readonly refsHandled: string[];
|
|
34
|
-
/** With the fix: the enum added to each schema, by schema and property, so values merge. */
|
|
35
|
-
readonly patchedEnums: Map<string, SchemaObject>;
|
|
36
|
-
/** With the fix: schema-name values, applied after both passes where no mapping names one. */
|
|
37
|
-
readonly inferredPatches: EnumPatch[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */
|
|
41
|
-
function addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {
|
|
42
|
-
const { silent, logger } = state;
|
|
43
|
-
const resolved = resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });
|
|
44
|
-
const added = addEnumProperty(resolved, patch);
|
|
45
|
-
if (added === null) {
|
|
46
|
-
warnInvalidMapping(patch, state.logger);
|
|
47
|
-
}
|
|
48
|
-
return added;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** One schema and discriminator property; two discriminators of one property share an enum. */
|
|
52
|
-
function enumKey(patch: EnumPatch): string {
|
|
53
|
-
return `${patch.ref}\n${patch.discriminator.propertyName}`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** With the fix, a second discriminator of the same property adds its values to the first enum. */
|
|
57
|
-
function mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {
|
|
58
|
-
const patched = state.patchedEnums.get(key);
|
|
59
|
-
if (patched === undefined) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
const merged = patched.enum as unknown[];
|
|
63
|
-
merged.push(...values.filter((value) => !merged.includes(value)));
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a
|
|
69
|
-
* warning, when that schema is neither an `allOf` nor an object schema. Without the fix every
|
|
70
|
-
* patch adds a property, so two discriminators with different values intersect to `never`.
|
|
71
|
-
*/
|
|
72
|
-
function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {
|
|
73
|
-
if (!state.fixesValueConflicts) {
|
|
74
|
-
return addDiscriminatorEnum(state, patch) !== null;
|
|
75
|
-
}
|
|
76
|
-
const key = enumKey(patch);
|
|
77
|
-
if (mergeIntoPatchedEnum(state, key, patch.values)) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
const added = addDiscriminatorEnum(state, patch);
|
|
81
|
-
if (added !== null) {
|
|
82
|
-
state.patchedEnums.set(key, added);
|
|
83
|
-
}
|
|
84
|
-
return added !== null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function markHandled(state: ScanState, ref: string): void {
|
|
88
|
-
if (!state.refsHandled.includes(ref)) {
|
|
89
|
-
state.refsHandled.push(ref);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function warnInvalidMapping(patch: EnumPatch, logger: Logger): void {
|
|
94
|
-
const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
|
|
95
|
-
logger.warn(
|
|
96
|
-
"Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): " +
|
|
97
|
-
`${mapped} (Discriminator: ${patch.discriminatorRef})`,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
35
|
/** The schema name at the end of each `oneOf` `$ref` is the inferred discriminator value. */
|
|
102
36
|
function inferredMapping(oneOf: (SchemaObject | ReferenceObject)[]): DiscriminatorMapping {
|
|
103
37
|
const mapping: DiscriminatorMapping = {};
|
|
@@ -116,9 +50,9 @@ function inferredMapping(oneOf: (SchemaObject | ReferenceObject)[]): Discriminat
|
|
|
116
50
|
/** Values defined in `discriminator.mapping` replace inferred ones for the same schema. */
|
|
117
51
|
function addDefinedMapping(
|
|
118
52
|
mapping: DiscriminatorMapping,
|
|
119
|
-
|
|
53
|
+
defined: Readonly<Record<string, string>>,
|
|
120
54
|
): void {
|
|
121
|
-
for (const [mappedValue, mappedRef] of Object.entries(
|
|
55
|
+
for (const [mappedValue, mappedRef] of Object.entries(defined)) {
|
|
122
56
|
if (!mappedRef) {
|
|
123
57
|
continue;
|
|
124
58
|
}
|
|
@@ -135,13 +69,13 @@ function patchMappedSchemas(
|
|
|
135
69
|
discriminator: Omit<EnumPatch, "ref" | "values">,
|
|
136
70
|
): void {
|
|
137
71
|
for (const [ref, { inferred, defined }] of Object.entries(mapping)) {
|
|
138
|
-
const isSkipped = !state
|
|
72
|
+
const isSkipped = !mergesValues(state) && state.refsHandled.includes(ref);
|
|
139
73
|
if (isSkipped || (!inferred && !defined)) {
|
|
140
74
|
continue;
|
|
141
75
|
}
|
|
142
76
|
// A defined value wins: the schema name may not be the value the API sends.
|
|
143
77
|
const values = defined ?? [inferred as string];
|
|
144
|
-
if (state
|
|
78
|
+
if (mergesValues(state) && defined === undefined) {
|
|
145
79
|
// A mapping found later, in this pass or the next, may name the schema.
|
|
146
80
|
state.inferredPatches.push({ ...discriminator, ref, values });
|
|
147
81
|
} else if (patchDiscriminatorEnum(state, { ...discriminator, ref, values })) {
|
|
@@ -162,12 +96,13 @@ function collectDiscriminator(
|
|
|
162
96
|
}
|
|
163
97
|
const discriminatorRef = createRef(path);
|
|
164
98
|
state.objects[discriminatorRef] = discriminator;
|
|
99
|
+
state.owners.add(discriminatorRef);
|
|
165
100
|
if (!Array.isArray(value.oneOf)) {
|
|
166
101
|
return;
|
|
167
102
|
}
|
|
168
103
|
const mapping = inferredMapping(value.oneOf);
|
|
169
104
|
if (discriminator.mapping) {
|
|
170
|
-
addDefinedMapping(mapping, discriminator);
|
|
105
|
+
addDefinedMapping(mapping, discriminator.mapping);
|
|
171
106
|
}
|
|
172
107
|
patchMappedSchemas(state, mapping, { discriminator, discriminatorRef });
|
|
173
108
|
}
|
|
@@ -179,6 +114,41 @@ function valuesMappedTo(discriminator: DiscriminatorObject, ref: string): string
|
|
|
179
114
|
.map(([mappedValue]) => mappedValue);
|
|
180
115
|
}
|
|
181
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Whether the schema at `ref` takes the discriminator of its `allOf` parent at `parentRef`. With
|
|
119
|
+
* `allof-discriminated-union`, a schema that `allOf`s a discriminated union that does not contain
|
|
120
|
+
* it is that union, not one of its members, so it gets no value of its own (#1464, #1690). A
|
|
121
|
+
* schema that the union's mapping names is a member.
|
|
122
|
+
*/
|
|
123
|
+
function inheritsDiscriminator(state: ScanState, parentRef: string, ref: string): boolean {
|
|
124
|
+
if (!state.fixes.has(OutputFix.ALLOF_DISCRIMINATED_UNION)) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
const resolve = (target: string) => resolveDocumentRef(state.schema, target, state);
|
|
128
|
+
const union = unionAt(parentRef, resolve);
|
|
129
|
+
return union === undefined || isUnionMember(union, ref, resolve);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The schema at `ref` inherits `discriminator`. With `discriminator-values`, a schema that
|
|
134
|
+
* defines a discriminator keeps it: the inherited one replaced its mapping, so the members walked
|
|
135
|
+
* after this schema got their schema name instead of the mapped value (#2200). `ownerRef` is the
|
|
136
|
+
* schema that declares the discriminator property, whose enum `--enum` values use (#1700).
|
|
137
|
+
*/
|
|
138
|
+
function recordInherited(
|
|
139
|
+
state: ScanState,
|
|
140
|
+
ref: string,
|
|
141
|
+
discriminator: DiscriminatorObject,
|
|
142
|
+
ownerRef: string,
|
|
143
|
+
): void {
|
|
144
|
+
if (state.fixes.has(OutputFix.DISCRIMINATOR_VALUES) && state.owners.has(ref)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const inherited = { ...discriminator };
|
|
148
|
+
state.objects[ref] = inherited;
|
|
149
|
+
recordEnumParent(state, { discriminator, discriminatorRef: ownerRef }, inherited);
|
|
150
|
+
}
|
|
151
|
+
|
|
182
152
|
/**
|
|
183
153
|
* An `allOf` item that is a `$ref` to a discriminator owner: the schema at `ref` inherits the
|
|
184
154
|
* discriminator, and gets its enum when the parent's mapping names it. Returns false when the
|
|
@@ -194,7 +164,12 @@ function inheritFromRef(state: ScanState, parentRef: string, ref: string): boole
|
|
|
194
164
|
if (values.length > 0 && patchDiscriminatorEnum(state, patch)) {
|
|
195
165
|
markHandled(state, ref);
|
|
196
166
|
}
|
|
197
|
-
state
|
|
167
|
+
if (inheritsDiscriminator(state, parentRef, ref)) {
|
|
168
|
+
recordInherited(state, ref, discriminator, parentRef);
|
|
169
|
+
if (mergesValues(state)) {
|
|
170
|
+
inheritOtherOwners(state, parentRef, ref);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
198
173
|
return true;
|
|
199
174
|
}
|
|
200
175
|
|
|
@@ -213,7 +188,8 @@ function inheritDiscriminators(
|
|
|
213
188
|
return;
|
|
214
189
|
}
|
|
215
190
|
} else if (item.discriminator?.propertyName) {
|
|
216
|
-
|
|
191
|
+
// The inline item is typed at the schema's own location.
|
|
192
|
+
recordInherited(state, createRef(path), item.discriminator, createRef(path));
|
|
217
193
|
}
|
|
218
194
|
}
|
|
219
195
|
}
|
|
@@ -222,6 +198,10 @@ function inheritDiscriminators(
|
|
|
222
198
|
export interface DiscriminatorScan {
|
|
223
199
|
objects: Record<string, DiscriminatorObject>;
|
|
224
200
|
refsHandled: string[];
|
|
201
|
+
/** With `discriminator-values`: the owner's enum of each enum the scan added. */
|
|
202
|
+
enumParents: ReadonlyMap<object, EnumParent>;
|
|
203
|
+
/** With `discriminator-values`: the properties of the other discriminators a schema inherits. */
|
|
204
|
+
otherProperties: Readonly<Record<string, readonly string[]>>;
|
|
225
205
|
}
|
|
226
206
|
|
|
227
207
|
/**
|
|
@@ -229,12 +209,14 @@ export interface DiscriminatorScan {
|
|
|
229
209
|
* Every enum patched so far came from a mapping, since schema-name values wait for this step.
|
|
230
210
|
*/
|
|
231
211
|
function applyInferredPatches(state: ScanState): void {
|
|
232
|
-
|
|
212
|
+
// A value that a schema declares itself came from a mapping as well.
|
|
213
|
+
const mapped = new Set([...state.patchedEnums.keys(), ...state.declaredKeys]);
|
|
233
214
|
for (const patch of state.inferredPatches) {
|
|
234
215
|
if (!mapped.has(enumKey(patch)) && patchDiscriminatorEnum(state, patch)) {
|
|
235
216
|
markHandled(state, patch.ref);
|
|
236
217
|
}
|
|
237
218
|
}
|
|
219
|
+
applyOtherInferredPatches(state, mapped);
|
|
238
220
|
}
|
|
239
221
|
|
|
240
222
|
/** Find every discriminator in `schema`; warnings go to `logger` unless `silent`. */
|
|
@@ -246,15 +228,21 @@ export function findDiscriminators(
|
|
|
246
228
|
...options,
|
|
247
229
|
schema,
|
|
248
230
|
objects: {},
|
|
231
|
+
owners: new Set(),
|
|
249
232
|
refsHandled: [],
|
|
250
233
|
patchedEnums: new Map(),
|
|
251
234
|
inferredPatches: [],
|
|
235
|
+
otherInferredPatches: [],
|
|
236
|
+
otherProperties: {},
|
|
237
|
+
declaredKeys: new Set(),
|
|
238
|
+
enumParents: new Map(),
|
|
252
239
|
};
|
|
253
240
|
walkDocument(schema, (value, path) => collectDiscriminator(state, value, path));
|
|
254
241
|
// A second pass, because an `allOf` may name a discriminator that is defined later.
|
|
255
242
|
walkDocument(schema, (value, path) => inheritDiscriminators(state, value, path));
|
|
256
243
|
applyInferredPatches(state);
|
|
257
|
-
|
|
244
|
+
const { objects, refsHandled, enumParents, otherProperties } = state;
|
|
245
|
+
return { objects, refsHandled, enumParents, otherProperties };
|
|
258
246
|
}
|
|
259
247
|
|
|
260
248
|
/**
|
|
@@ -268,5 +256,5 @@ export function scanDiscriminators(
|
|
|
268
256
|
logger: Logger = defaultLogger(options.silent ?? false),
|
|
269
257
|
): DiscriminatorScan {
|
|
270
258
|
const silent = options.silent ?? false;
|
|
271
|
-
return findDiscriminators(schema, { silent, logger,
|
|
259
|
+
return findDiscriminators(schema, { silent, logger, fixes: new Set() });
|
|
272
260
|
}
|
package/src/api/document-refs.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js";
|
|
2
2
|
import type { Logger } from "../application/ports/logger.js";
|
|
3
|
+
import { WARNING_CODES, warningText } from "../domain/warnings.js";
|
|
3
4
|
import { defaultLogger } from "./default-ports.js";
|
|
4
5
|
|
|
5
6
|
/** `$ref` resolution and the document walk that the generator's pre-pass uses. */
|
|
@@ -11,9 +12,13 @@ export interface ResolveRefOptions {
|
|
|
11
12
|
logger?: Logger;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
function isObject(value: unknown): value is Record<string, unknown> {
|
|
16
|
+
return typeof value === "object" && value !== null;
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
/** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */
|
|
15
20
|
export function resolveDocumentRef<T>(
|
|
16
|
-
schema:
|
|
21
|
+
schema: unknown,
|
|
17
22
|
$ref: string,
|
|
18
23
|
options: ResolveRefOptions,
|
|
19
24
|
): T | undefined {
|
|
@@ -23,30 +28,29 @@ export function resolveDocumentRef<T>(
|
|
|
23
28
|
if (!pointer.length) {
|
|
24
29
|
return undefined;
|
|
25
30
|
}
|
|
26
|
-
let node = schema;
|
|
31
|
+
let node: unknown = schema;
|
|
27
32
|
for (const key of pointer) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
logger.warn(`Could not resolve $ref "${$ref}"`);
|
|
33
|
+
const child = isObject(node) ? node[key] : undefined;
|
|
34
|
+
if (!child) {
|
|
35
|
+
logger.warn(warningText(`Could not resolve $ref "${$ref}"`, WARNING_CODES.REF_NOT_FOUND));
|
|
32
36
|
return undefined;
|
|
33
37
|
}
|
|
38
|
+
node = child;
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
// if this is also a $ref, keep tracing
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const next = isObject(node) ? node.$ref : undefined;
|
|
43
|
+
if (typeof next === "string" && next) {
|
|
44
|
+
if (visited.includes(next)) {
|
|
45
|
+
logger.warn(
|
|
46
|
+
warningText(`Could not resolve circular $ref "${$ref}"`, WARNING_CODES.REF_CIRCULAR),
|
|
47
|
+
);
|
|
40
48
|
return undefined;
|
|
41
49
|
}
|
|
42
|
-
return resolveDocumentRef(schema,
|
|
43
|
-
...options,
|
|
44
|
-
logger,
|
|
45
|
-
visited: [...visited, node.$ref],
|
|
46
|
-
});
|
|
50
|
+
return resolveDocumentRef(schema, next, { ...options, logger, visited: [...visited, next] });
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
return node;
|
|
53
|
+
return node as T;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
/** Call `cb` for every object in a JSON-serializable (non-circular) value, depth first. */
|
package/src/api/document-run.ts
CHANGED
|
@@ -7,13 +7,18 @@ import type { RefAccess, SchemaLoader } from "../application/ports/schema-loader
|
|
|
7
7
|
import { withStackOverflowReported } from "../application/stack-overflow.js";
|
|
8
8
|
import {
|
|
9
9
|
ineffectiveFixNotices,
|
|
10
|
-
OutputFix,
|
|
10
|
+
type OutputFix,
|
|
11
11
|
outputFixNamesOf,
|
|
12
12
|
resolveOutputFixes,
|
|
13
13
|
} from "../domain/output-fixes.js";
|
|
14
|
-
import
|
|
14
|
+
import { WARNING_CODES, warningText } from "../domain/warnings.js";
|
|
15
|
+
import type { GeneratorOptions, OpenAPI3, SchemaSource } from "../types.js";
|
|
16
|
+
import { processCwd } from "./default-ports.js";
|
|
17
|
+
import { warnDiscriminatorValueConflicts } from "./discriminator-conflict-warnings.js";
|
|
15
18
|
import { findDiscriminators } from "./discriminator-scan.js";
|
|
16
19
|
import { resolveDocumentRef } from "./document-refs.js";
|
|
20
|
+
import { warnIdenticalPathTemplates } from "./path-template-warnings.js";
|
|
21
|
+
import type { RunContext } from "./run-context.js";
|
|
17
22
|
import { warnUnsupportedFeatures } from "./unsupported-feature-warnings.js";
|
|
18
23
|
|
|
19
24
|
/** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */
|
|
@@ -29,12 +34,12 @@ export interface GeneratorPorts {
|
|
|
29
34
|
/** A validated, bundled document and the context of one generator run. */
|
|
30
35
|
export interface DocumentRun {
|
|
31
36
|
readonly schema: OpenAPI3;
|
|
32
|
-
readonly ctx:
|
|
37
|
+
readonly ctx: RunContext;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
/** The context fields that are user flags, with the original defaults. */
|
|
36
41
|
type ContextFlags = Omit<
|
|
37
|
-
|
|
42
|
+
RunContext,
|
|
38
43
|
| "discriminators"
|
|
39
44
|
| "injectFooter"
|
|
40
45
|
| "redoc"
|
|
@@ -45,10 +50,17 @@ type ContextFlags = Omit<
|
|
|
45
50
|
| "fix"
|
|
46
51
|
>;
|
|
47
52
|
|
|
53
|
+
/**
|
|
54
|
+
* The directory that relative `$ref`s of an inline source resolve against, as a URL that ends in
|
|
55
|
+
* a slash. A path is resolved and encoded (`#`, `%`, spaces); a URL without the slash gets one.
|
|
56
|
+
*/
|
|
48
57
|
function sourceCwd(options: GeneratorOptions): URL {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
: new URL(
|
|
58
|
+
const { cwd } = options;
|
|
59
|
+
if (cwd instanceof URL) {
|
|
60
|
+
return cwd.pathname.endsWith("/") ? cwd : new URL(`${cwd.pathname}/`, cwd);
|
|
61
|
+
}
|
|
62
|
+
const directory = path.resolve(cwd === undefined ? processCwd() : cwd.toString());
|
|
63
|
+
return pathToFileURL(path.join(directory, path.sep));
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
/** The `$ref` limits of the options; a relative local root resolves against the cwd. */
|
|
@@ -110,11 +122,20 @@ function contextFlags(options: GeneratorOptions): ContextFlags {
|
|
|
110
122
|
function outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {
|
|
111
123
|
const names = outputFixNamesOf(options.fix ?? []);
|
|
112
124
|
for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {
|
|
113
|
-
logger.warn(notice);
|
|
125
|
+
logger.warn(warningText(notice, WARNING_CODES.FIX_NEEDS_OPTION));
|
|
114
126
|
}
|
|
115
127
|
return [...resolveOutputFixes(names)];
|
|
116
128
|
}
|
|
117
129
|
|
|
130
|
+
/** The warnings about the loaded document itself, before it is transformed. */
|
|
131
|
+
function warnAboutDocument(schema: OpenAPI3, fix: readonly OutputFix[], logger: Logger): void {
|
|
132
|
+
withStackOverflowReported("transform", () => warnUnsupportedFeatures(schema, logger));
|
|
133
|
+
withStackOverflowReported("transform", () =>
|
|
134
|
+
warnDiscriminatorValueConflicts(schema, fix, logger),
|
|
135
|
+
);
|
|
136
|
+
warnIdenticalPathTemplates(schema, logger);
|
|
137
|
+
}
|
|
138
|
+
|
|
118
139
|
/**
|
|
119
140
|
* Load the source through the ports, then build the run's context from the options. The fix names
|
|
120
141
|
* are checked first, so a typo fails before the document is read.
|
|
@@ -137,8 +158,8 @@ export async function createDocumentRun(
|
|
|
137
158
|
shouldLint: options.lint ?? true,
|
|
138
159
|
refAccess: refAccessOf(options, cwd),
|
|
139
160
|
});
|
|
140
|
-
|
|
141
|
-
const ctx:
|
|
161
|
+
warnAboutDocument(schema, fix, logger);
|
|
162
|
+
const ctx: RunContext = {
|
|
142
163
|
...contextFlags(options),
|
|
143
164
|
fix,
|
|
144
165
|
// The scan walks every schema before the transform does, so on a larger stack, where loading
|
|
@@ -147,7 +168,7 @@ export async function createDocumentRun(
|
|
|
147
168
|
findDiscriminators(schema, {
|
|
148
169
|
silent,
|
|
149
170
|
logger,
|
|
150
|
-
|
|
171
|
+
fixes: new Set(fix),
|
|
151
172
|
}),
|
|
152
173
|
),
|
|
153
174
|
injectFooter: [],
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { WARNING_CODES, warningText } from "../domain/warnings.js";
|
|
2
|
+
|
|
3
|
+
const DOCS_BASE_URL = "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs";
|
|
4
|
+
const DOCS_URL = `${DOCS_BASE_URL}/advanced.md#enum-values-arrays`;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The warning for an `--enum-values` array whose schema's location in the generated types admits
|
|
8
|
+
* none or only some of its values (ADR-027): the schema contradicts itself, for example an `allOf`
|
|
9
|
+
* of enums with different values or a discriminator value that the property enum does not list.
|
|
10
|
+
*/
|
|
11
|
+
export function excludedValuesWarning(name: string, excluded: readonly unknown[]): string {
|
|
12
|
+
const values = excluded.map((value) => JSON.stringify(value)).join(", ");
|
|
13
|
+
return warningText(
|
|
14
|
+
`${name}: the generated type at the location of this enum does not admit ${values}; ` +
|
|
15
|
+
"other keywords of the document exclude these values (an allOf of enums with other " +
|
|
16
|
+
"values, or a discriminator value the enum does not list). The array is typed by its own " +
|
|
17
|
+
"values. " +
|
|
18
|
+
`See ${DOCS_URL}`,
|
|
19
|
+
WARNING_CODES.ENUM_VALUES_EXCLUDED,
|
|
20
|
+
);
|
|
21
|
+
}
|
package/src/api/footer-sink.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { FooterSink } from "../application/transform/footer/document-footer
|
|
|
4
4
|
import type {
|
|
5
5
|
IrDeclaration,
|
|
6
6
|
IrInterfaceDeclaration,
|
|
7
|
+
IrMember,
|
|
7
8
|
IrPropertySignature,
|
|
8
9
|
} from "../domain/ir/nodes.js";
|
|
9
10
|
import { declaresTypeAlias, type FooterEntry, isIrDeclaration } from "./footer-entry.js";
|
|
@@ -16,6 +17,12 @@ const OPERATIONS_NAME = "operations";
|
|
|
16
17
|
*/
|
|
17
18
|
export class ContextFooterSink implements FooterSink {
|
|
18
19
|
private readonly footer: FooterEntry[];
|
|
20
|
+
/**
|
|
21
|
+
* The IR `operations` entry this sink wrote last, with its members array that only this sink
|
|
22
|
+
* holds. Adding to it in place keeps a run linear: copying the members on every operation was
|
|
23
|
+
* quadratic (about 0.4 s on Microsoft Graph beta).
|
|
24
|
+
*/
|
|
25
|
+
private owned: OwnedOperations | null = null;
|
|
19
26
|
|
|
20
27
|
constructor(footer: FooterEntry[]) {
|
|
21
28
|
this.footer = footer;
|
|
@@ -35,6 +42,11 @@ export class ContextFooterSink implements FooterSink {
|
|
|
35
42
|
* the member in place, as in the original.
|
|
36
43
|
*/
|
|
37
44
|
addOperation(build: () => IrPropertySignature): void {
|
|
45
|
+
const owned = this.currentOwnedOperations();
|
|
46
|
+
if (owned !== null) {
|
|
47
|
+
owned.members.push(build());
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
38
50
|
const existing = this.findOperations();
|
|
39
51
|
if (existing !== null && !isIrDeclaration(existing.entry)) {
|
|
40
52
|
const ts = loadTypeScript();
|
|
@@ -45,9 +57,23 @@ export class ContextFooterSink implements FooterSink {
|
|
|
45
57
|
return;
|
|
46
58
|
}
|
|
47
59
|
const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;
|
|
48
|
-
|
|
60
|
+
this.takeOwnership(index).members.push(build());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The owned entry, unless user code replaced or moved it in the footer since. */
|
|
64
|
+
private currentOwnedOperations(): OwnedOperations | null {
|
|
65
|
+
const owned = this.owned;
|
|
66
|
+
return owned !== null && this.footer[owned.index] === owned.entry ? owned : null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Replace the IR entry at `index` with a copy whose members array only this sink holds. */
|
|
70
|
+
private takeOwnership(index: number): OwnedOperations {
|
|
49
71
|
const operations = this.footer[index] as IrInterfaceDeclaration;
|
|
50
|
-
|
|
72
|
+
const members: IrMember[] = [...operations.members];
|
|
73
|
+
const entry: IrInterfaceDeclaration = { ...operations, members };
|
|
74
|
+
this.footer[index] = entry;
|
|
75
|
+
this.owned = { entry, members, index };
|
|
76
|
+
return this.owned;
|
|
51
77
|
}
|
|
52
78
|
|
|
53
79
|
/** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */
|
|
@@ -62,6 +88,12 @@ export class ContextFooterSink implements FooterSink {
|
|
|
62
88
|
}
|
|
63
89
|
}
|
|
64
90
|
|
|
91
|
+
interface OwnedOperations {
|
|
92
|
+
readonly entry: IrInterfaceDeclaration;
|
|
93
|
+
readonly members: IrMember[];
|
|
94
|
+
readonly index: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
65
97
|
function emptyOperations(): IrInterfaceDeclaration {
|
|
66
98
|
return { kind: "interface", name: OPERATIONS_NAME, isExported: true, members: [], comments: [] };
|
|
67
99
|
}
|