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
|
@@ -23,7 +23,7 @@ import { OutputFix } from "../../../domain/output-fixes.js";
|
|
|
23
23
|
import { type DeprecatedEntryFilter, documentEntries } from "../document-entries.js";
|
|
24
24
|
import type { SchemaLocation } from "../schema/schema-context.js";
|
|
25
25
|
import { transformSchema } from "../schema/schema-transform.js";
|
|
26
|
-
import { withSchemaComment } from "../schema-comment.js";
|
|
26
|
+
import { schemaCommentOptionsOf, withSchemaComment } from "../schema-comment.js";
|
|
27
27
|
import type { TransformContext } from "../transform-context.js";
|
|
28
28
|
import { headerType } from "./header.js";
|
|
29
29
|
import { contentEntryType } from "./media-type.js";
|
|
@@ -31,7 +31,7 @@ import { parameterType } from "./parameter.js";
|
|
|
31
31
|
import { pathItemType } from "./path-item.js";
|
|
32
32
|
import { requestBodyType } from "./request-body.js";
|
|
33
33
|
import { responseType } from "./response.js";
|
|
34
|
-
import {
|
|
34
|
+
import { rootTypeAlias } from "./root-type-aliases.js";
|
|
35
35
|
|
|
36
36
|
type ComponentTransform = (
|
|
37
37
|
item: never,
|
|
@@ -69,7 +69,7 @@ function componentMember(
|
|
|
69
69
|
isOptional: custom?.isOptional ?? false,
|
|
70
70
|
isReadonly: context.options.immutable,
|
|
71
71
|
});
|
|
72
|
-
return withSchemaComment(property, item);
|
|
72
|
+
return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/**
|
|
@@ -112,8 +112,8 @@ function rootTypeName(
|
|
|
112
112
|
* Add a root alias. When its exported name is taken (two schemas of one PascalCase name without
|
|
113
113
|
* the prefix), the later schema takes the name, as in the original. Without the
|
|
114
114
|
* `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number
|
|
115
|
-
* for it would change it (backlog 30). With the fix the earlier alias is kept aside and
|
|
116
|
-
*
|
|
115
|
+
* for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows
|
|
116
|
+
* the others under the same name; `renameTakenAliases` numbers it once every name is known.
|
|
117
117
|
*/
|
|
118
118
|
function addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {
|
|
119
119
|
const { aliases, displaced } = request;
|
|
@@ -184,6 +184,6 @@ export function componentsType(
|
|
|
184
184
|
const rootTypes = Object.values(aliases);
|
|
185
185
|
return {
|
|
186
186
|
type: irObject(members),
|
|
187
|
-
rootTypes: [...rootTypes, ...
|
|
187
|
+
rootTypes: [...rootTypes, ...(displaced ?? [])],
|
|
188
188
|
};
|
|
189
189
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { IrDeclaration, IrMember, IrType } from "../../../domain/ir/nodes.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The type a reference of the generated file names, read from the file's declarations: the
|
|
5
|
+
* `--path-params-as-types` overlap check compares two path items through the operations and
|
|
6
|
+
* components they reference (upstream #1752).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** The declared type a reference names, or null when the type is no such reference. */
|
|
10
|
+
export type DeclaredTypeLookup = (type: IrType) => IrType | null;
|
|
11
|
+
|
|
12
|
+
/** Knows no declaration: every reference stays unresolved. */
|
|
13
|
+
export const NO_DECLARED_TYPES: DeclaredTypeLookup = () => null;
|
|
14
|
+
|
|
15
|
+
/** A reference without type arguments and the string keys indexing it: `components["schemas"]`. */
|
|
16
|
+
interface IndexedName {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly keys: readonly string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function indexedNameOf(type: IrType): IndexedName | null {
|
|
22
|
+
if (type.kind === "reference") {
|
|
23
|
+
return type.typeArguments.length === 0 ? { name: type.name, keys: [] } : null;
|
|
24
|
+
}
|
|
25
|
+
if (type.kind !== "indexedAccess" || type.index.kind !== "stringLiteral") {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const object = indexedNameOf(type.object);
|
|
29
|
+
return object === null ? null : { ...object, keys: [...object.keys, type.index.value] };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function memberName(member: IrMember): string | null {
|
|
33
|
+
if (member.kind !== "property") {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return member.name.kind === "string" ? member.name.value : member.name.text;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The type of the required property `key`. An optional one is `T | undefined` when indexed, which
|
|
41
|
+
* is not the declared type, so it is not followed.
|
|
42
|
+
*/
|
|
43
|
+
function propertyType(type: IrType, key: string): IrType | null {
|
|
44
|
+
if (type.kind !== "object") {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const member = type.members.find((candidate) => memberName(candidate) === key);
|
|
48
|
+
return member?.kind === "property" && !member.isOptional ? member.type : null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function declarationType(declaration: IrDeclaration): IrType | null {
|
|
52
|
+
switch (declaration.kind) {
|
|
53
|
+
case "interface":
|
|
54
|
+
return { kind: "object", members: declaration.members };
|
|
55
|
+
case "typeAlias":
|
|
56
|
+
return declaration.type;
|
|
57
|
+
case "enum":
|
|
58
|
+
case "constArray":
|
|
59
|
+
case "rawDeclaration":
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A lookup over the declarations. Only a name declared once is read: a second declaration of an
|
|
66
|
+
* interface merges with the first, which this lookup does not model.
|
|
67
|
+
*/
|
|
68
|
+
export function declaredTypeLookup(declarations: readonly IrDeclaration[]): DeclaredTypeLookup {
|
|
69
|
+
const byName = new Map<string, IrType | null>();
|
|
70
|
+
for (const declaration of declarations) {
|
|
71
|
+
if ("name" in declaration && declaration.name !== undefined) {
|
|
72
|
+
const isRepeated = byName.has(declaration.name);
|
|
73
|
+
byName.set(declaration.name, isRepeated ? null : declarationType(declaration));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// References being resolved: a reference that indexes into itself names no type.
|
|
77
|
+
const resolving = new Set<IrType>();
|
|
78
|
+
const lookup: DeclaredTypeLookup = (type) => {
|
|
79
|
+
const indexed = indexedNameOf(type);
|
|
80
|
+
if (indexed === null || indexed.keys.length === 0 || resolving.has(type)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
resolving.add(type);
|
|
84
|
+
// A key may index a property whose type is a reference again (`paths["/a"]["get"]`).
|
|
85
|
+
const declared = indexed.keys.reduce<IrType | null>((object, key) => {
|
|
86
|
+
const named = object === null || object.kind === "object" ? object : lookup(object);
|
|
87
|
+
return named === null ? null : propertyType(named, key);
|
|
88
|
+
}, byName.get(indexed.name) ?? null);
|
|
89
|
+
resolving.delete(type);
|
|
90
|
+
return declared;
|
|
91
|
+
};
|
|
92
|
+
return lookup;
|
|
93
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { irKeyword, irRecord } from "../../../domain/ir/constructors.js";
|
|
1
|
+
import { irKeyword, irObject, irRecord } from "../../../domain/ir/constructors.js";
|
|
2
2
|
import type {
|
|
3
3
|
IrDeclaration,
|
|
4
4
|
IrIntersectionType,
|
|
@@ -12,9 +12,10 @@ import type { PathsObject } from "../../../domain/openapi/path-item-object.js";
|
|
|
12
12
|
import { READ_WRITE_MARKER_TYPES } from "../helper-types.js";
|
|
13
13
|
import type { TransformContext, TransformOptions } from "../transform-context.js";
|
|
14
14
|
import { componentsType } from "./components.js";
|
|
15
|
+
import { type DeclaredTypeLookup, declaredTypeLookup } from "./declared-types.js";
|
|
15
16
|
import { defsRootType } from "./defs-root.js";
|
|
16
17
|
import { keptDeprecatedComponents } from "./kept-deprecated.js";
|
|
17
|
-
import {
|
|
18
|
+
import { pathMembers, pathsObjectType } from "./paths.js";
|
|
18
19
|
import { apiPathsEnumDeclaration } from "./paths-enum.js";
|
|
19
20
|
import { webhooksType } from "./webhooks.js";
|
|
20
21
|
|
|
@@ -30,6 +31,11 @@ const EMPTY_ROOT_TYPE = irRecord(irKeyword("string"), irKeyword("never"));
|
|
|
30
31
|
interface RootResult {
|
|
31
32
|
readonly type: IrType;
|
|
32
33
|
readonly aliases: readonly IrTypeAliasDeclaration[];
|
|
34
|
+
/**
|
|
35
|
+
* The root's final type, for a root that reads the types the whole file declares (`paths`, whose
|
|
36
|
+
* overlap check follows references). `type` then only tells whether the root has members.
|
|
37
|
+
*/
|
|
38
|
+
readonly withDeclaredTypes?: (lookup: DeclaredTypeLookup) => IrType;
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
type RootTransform = (
|
|
@@ -46,7 +52,14 @@ function keptDeprecated(document: DocumentObject, context: TransformContext): Re
|
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
const ROOT_TRANSFORMS: Readonly<Record<RootKey, RootTransform>> = {
|
|
49
|
-
paths: (node, context) =>
|
|
55
|
+
paths: (node, context) => {
|
|
56
|
+
const members = pathMembers(node as PathsObject, context);
|
|
57
|
+
return {
|
|
58
|
+
type: irObject(members.map(({ member }) => member)),
|
|
59
|
+
aliases: [],
|
|
60
|
+
withDeclaredTypes: (lookup) => pathsObjectType(members, lookup),
|
|
61
|
+
};
|
|
62
|
+
},
|
|
50
63
|
webhooks: (node, context) => ({ type: webhooksType(node as PathsObject, context), aliases: [] }),
|
|
51
64
|
components: (node, context, document) => {
|
|
52
65
|
const kept = keptDeprecated(document, context);
|
|
@@ -84,6 +97,15 @@ function rootDeclaration(
|
|
|
84
97
|
: { kind: "interface", name, isExported: true, members: type.members, comments: [] };
|
|
85
98
|
}
|
|
86
99
|
|
|
100
|
+
/**
|
|
101
|
+
* The declarations of one root: its type, then its aliases. `finish` gives the root's declaration
|
|
102
|
+
* again from the types the whole file declares, for a root with `withDeclaredTypes`.
|
|
103
|
+
*/
|
|
104
|
+
interface RootDeclarations {
|
|
105
|
+
readonly declarations: readonly IrDeclaration[];
|
|
106
|
+
readonly finish?: (lookup: DeclaredTypeLookup) => IrDeclaration;
|
|
107
|
+
}
|
|
108
|
+
|
|
87
109
|
/**
|
|
88
110
|
* The declarations of one root. A root that is missing, or whose type has no members, is
|
|
89
111
|
* `Record<string, never>`. Only an object type (or the `paths` intersection) counts as having
|
|
@@ -93,21 +115,51 @@ function rootDeclarations(
|
|
|
93
115
|
root: RootKey,
|
|
94
116
|
document: DocumentObject,
|
|
95
117
|
context: TransformContext,
|
|
96
|
-
):
|
|
118
|
+
): RootDeclarations {
|
|
97
119
|
const node: unknown = document[root];
|
|
98
120
|
if (!node || typeof node !== "object") {
|
|
99
121
|
context.diagnostics.debug(`${root} done (skipped)`, 0);
|
|
100
|
-
return [emptyAlias(root)];
|
|
122
|
+
return { declarations: [emptyAlias(root)] };
|
|
101
123
|
}
|
|
102
124
|
const startedAt = context.diagnostics.now();
|
|
103
|
-
const { type, aliases } = ROOT_TRANSFORMS[root](node, context, document);
|
|
125
|
+
const { type, aliases, withDeclaredTypes } = ROOT_TRANSFORMS[root](node, context, document);
|
|
104
126
|
if (!isRootBody(type)) {
|
|
105
127
|
context.diagnostics.debug(`${root} done (skipped)`, 0);
|
|
106
|
-
return [emptyAlias(root), ...aliases];
|
|
128
|
+
return { declarations: [emptyAlias(root), ...aliases] };
|
|
107
129
|
}
|
|
108
130
|
const declaration = rootDeclaration(root, type, context.options);
|
|
109
131
|
context.diagnostics.debug(`${root} done`, context.diagnostics.now() - startedAt);
|
|
110
|
-
|
|
132
|
+
const finish =
|
|
133
|
+
withDeclaredTypes &&
|
|
134
|
+
((lookup: DeclaredTypeLookup) => {
|
|
135
|
+
const finished = withDeclaredTypes(lookup);
|
|
136
|
+
return isRootBody(finished) ? rootDeclaration(root, finished, context.options) : declaration;
|
|
137
|
+
});
|
|
138
|
+
return { declarations: [declaration, ...aliases], ...(finish ? { finish } : {}) };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Every root's declarations in output order. A root with `finish` gets its declaration from the
|
|
143
|
+
* types of the other roots and of the footer (the `operations` interface), which exist only once
|
|
144
|
+
* every root is transformed.
|
|
145
|
+
*/
|
|
146
|
+
function rootsDeclarations(
|
|
147
|
+
document: DocumentObject,
|
|
148
|
+
context: TransformContext,
|
|
149
|
+
footer: () => readonly IrDeclaration[],
|
|
150
|
+
): IrDeclaration[] {
|
|
151
|
+
const roots = ROOT_KEYS.map((root) => rootDeclarations(root, document, context));
|
|
152
|
+
const transformed = roots.flatMap(({ declarations }) => declarations);
|
|
153
|
+
if (roots.every(({ finish }) => finish === undefined)) {
|
|
154
|
+
return transformed;
|
|
155
|
+
}
|
|
156
|
+
const lookup = declaredTypeLookup([...transformed, ...footer()]);
|
|
157
|
+
return roots.flatMap(({ declarations, finish }) => {
|
|
158
|
+
const [declaration, ...aliases] = declarations;
|
|
159
|
+
return finish === undefined || declaration === undefined
|
|
160
|
+
? declarations
|
|
161
|
+
: [finish(lookup), ...aliases];
|
|
162
|
+
});
|
|
111
163
|
}
|
|
112
164
|
|
|
113
165
|
/**
|
|
@@ -118,11 +170,19 @@ function withoutBlankLinesAround(text: string): string {
|
|
|
118
170
|
return text.replace(/^(?:[ \t]*\r?\n)+/, "").trimEnd();
|
|
119
171
|
}
|
|
120
172
|
|
|
173
|
+
/** No footer declarations: the roots' references to `operations` stay unresolved. */
|
|
174
|
+
const NO_FOOTER = (): readonly IrDeclaration[] => [];
|
|
175
|
+
|
|
121
176
|
/**
|
|
122
177
|
* The document's declarations before the footer: helper types, injected code, then one root type
|
|
123
|
-
* per root key with the aliases that follow it.
|
|
178
|
+
* per root key with the aliases that follow it. `footer` reads the footer's declarations once the
|
|
179
|
+
* roots are transformed.
|
|
124
180
|
*/
|
|
125
|
-
export function documentBody(
|
|
181
|
+
export function documentBody(
|
|
182
|
+
document: DocumentObject,
|
|
183
|
+
context: TransformContext,
|
|
184
|
+
footer: () => readonly IrDeclaration[] = NO_FOOTER,
|
|
185
|
+
): IrDeclaration[] {
|
|
126
186
|
const declarations: IrDeclaration[] = [];
|
|
127
187
|
if (context.options.readWriteMarkers) {
|
|
128
188
|
declarations.push({ kind: "rawDeclaration", text: READ_WRITE_MARKER_TYPES });
|
|
@@ -131,9 +191,7 @@ export function documentBody(document: DocumentObject, context: TransformContext
|
|
|
131
191
|
if (inject !== "") {
|
|
132
192
|
declarations.push({ kind: "rawDeclaration", text: inject });
|
|
133
193
|
}
|
|
134
|
-
|
|
135
|
-
declarations.push(...rootDeclarations(root, document, context));
|
|
136
|
-
}
|
|
194
|
+
declarations.push(...rootsDeclarations(document, context, footer));
|
|
137
195
|
return declarations;
|
|
138
196
|
}
|
|
139
197
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ParameterObject } from "../../../domain/openapi/parameter-object.js";
|
|
2
|
+
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
3
|
+
import type { RefResolver } from "../schema/schema-context.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Exploded object query parameters (OpenAPI 3.2 §4.8.12.4, upstream #2361). A query parameter has
|
|
7
|
+
* `style: form` and, with it, `explode: true` by default. An object value is then sent as its own
|
|
8
|
+
* `key=value` pairs, `?page=1&limit=10`: the parameter's name is not in the URL. So with the
|
|
9
|
+
* `exploded-query-objects` fix, the object's properties are keys of `query`, not one key named
|
|
10
|
+
* after the parameter.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const FORM_STYLE = "form";
|
|
14
|
+
|
|
15
|
+
/** Whether a `$ref` chain has been followed already, so a cycle ends. */
|
|
16
|
+
type SeenRefs = ReadonlySet<string>;
|
|
17
|
+
|
|
18
|
+
function resolvedSchema(schema: Schema, refs: RefResolver, seen: SeenRefs): SchemaObject | null {
|
|
19
|
+
if (typeof schema !== "object" || schema === null) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (!("$ref" in schema)) {
|
|
23
|
+
return schema;
|
|
24
|
+
}
|
|
25
|
+
if (seen.has(schema.$ref)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const target = refs.resolve(schema.$ref) as Schema | undefined;
|
|
29
|
+
return target === undefined
|
|
30
|
+
? null
|
|
31
|
+
: resolvedSchema(target, refs, new Set([...seen, schema.$ref]));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The types of a `type` keyword other than `null`; empty when it has none. */
|
|
35
|
+
function nonNullTypes(schema: SchemaObject): readonly unknown[] {
|
|
36
|
+
const types = Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
37
|
+
return types.filter((type) => type !== undefined && type !== null && type !== "null");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Whether every member of a composition is an object schema; false for an empty list. */
|
|
41
|
+
function isObjectComposition(
|
|
42
|
+
members: readonly Schema[] | undefined,
|
|
43
|
+
refs: RefResolver,
|
|
44
|
+
seen: SeenRefs,
|
|
45
|
+
): boolean {
|
|
46
|
+
return (
|
|
47
|
+
members !== undefined &&
|
|
48
|
+
members.length > 0 &&
|
|
49
|
+
members.every((member) => isObjectSchemaWith(member, refs, seen))
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isObjectSchemaWith(schema: Schema, refs: RefResolver, seen: SeenRefs): boolean {
|
|
54
|
+
const resolved = resolvedSchema(schema, refs, seen);
|
|
55
|
+
if (resolved === null) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const types = nonNullTypes(resolved);
|
|
59
|
+
if (types.length > 0) {
|
|
60
|
+
return types.every((type) => type === "object");
|
|
61
|
+
}
|
|
62
|
+
return (
|
|
63
|
+
resolved.properties !== undefined ||
|
|
64
|
+
resolved.additionalProperties !== undefined ||
|
|
65
|
+
resolved.patternProperties !== undefined ||
|
|
66
|
+
isObjectComposition(resolved.allOf, refs, seen) ||
|
|
67
|
+
isObjectComposition(resolved.oneOf, refs, seen) ||
|
|
68
|
+
isObjectComposition(resolved.anyOf, refs, seen)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Whether the schema describes only objects: `type: object` (with `null` or not), or no `type`
|
|
74
|
+
* and object keywords, or a composition of such schemas. A `$ref` is followed.
|
|
75
|
+
*/
|
|
76
|
+
export function isObjectSchema(schema: Schema, refs: RefResolver): boolean {
|
|
77
|
+
return isObjectSchemaWith(schema, refs, new Set());
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Whether an `in: query` parameter sends its object value as the object's own keys. */
|
|
81
|
+
export function isExplodedQueryObject(parameter: ParameterObject, refs: RefResolver): boolean {
|
|
82
|
+
const style = parameter.style ?? FORM_STYLE;
|
|
83
|
+
const explode = parameter.explode ?? style === FORM_STYLE;
|
|
84
|
+
return (
|
|
85
|
+
parameter.in === "query" &&
|
|
86
|
+
style === FORM_STYLE &&
|
|
87
|
+
explode &&
|
|
88
|
+
parameter.schema !== undefined &&
|
|
89
|
+
isObjectSchema(parameter.schema, refs)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { IrDeclaration } from "../../../domain/ir/nodes.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The TypeScript global types that generated code can refer to: in references (`Record<string,
|
|
5
|
+
* never>`, `Omit<…>`, the `Blob` of `--binary-as-blob`) and in the text of footer helpers
|
|
6
|
+
* (`Exclude<…>`, `Readonly<…>`). A module declaration of the same name shadows the global: every
|
|
7
|
+
* use of it then fails to compile, or silently names the module's type (`Blob`).
|
|
8
|
+
*/
|
|
9
|
+
const GLOBAL_TYPE_NAMES: ReadonlySet<string> = new Set([
|
|
10
|
+
"Array",
|
|
11
|
+
"Blob",
|
|
12
|
+
"Exclude",
|
|
13
|
+
"Extract",
|
|
14
|
+
"NonNullable",
|
|
15
|
+
"Omit",
|
|
16
|
+
"Partial",
|
|
17
|
+
"Pick",
|
|
18
|
+
"Readonly",
|
|
19
|
+
"ReadonlyArray",
|
|
20
|
+
"Record",
|
|
21
|
+
"Required",
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
const GENERIC_USE = /\b([A-Z][A-Za-z]*)\s*</g;
|
|
25
|
+
|
|
26
|
+
/** `origin` holds the outside node a raw type was printed from; it is not part of the output. */
|
|
27
|
+
const SKIPPED_KEYS: ReadonlySet<string> = new Set(["origin", "comments"]);
|
|
28
|
+
|
|
29
|
+
function isObject(value: unknown): value is Readonly<Record<string, unknown>> {
|
|
30
|
+
return typeof value === "object" && value !== null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function addTextUses(text: string, used: Set<string>): void {
|
|
34
|
+
for (const match of text.matchAll(GENERIC_USE)) {
|
|
35
|
+
const name = match[1] ?? "";
|
|
36
|
+
if (GLOBAL_TYPE_NAMES.has(name)) {
|
|
37
|
+
used.add(name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function addNodeUses(node: Readonly<Record<string, unknown>>, used: Set<string>): void {
|
|
43
|
+
if (node.kind === "reference" && typeof node.name === "string") {
|
|
44
|
+
if (GLOBAL_TYPE_NAMES.has(node.name)) {
|
|
45
|
+
used.add(node.name);
|
|
46
|
+
}
|
|
47
|
+
} else if (
|
|
48
|
+
(node.kind === "raw" || node.kind === "rawDeclaration") &&
|
|
49
|
+
typeof node.text === "string"
|
|
50
|
+
) {
|
|
51
|
+
addTextUses(node.text, used);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function visit(value: unknown, used: Set<string>): void {
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
for (const item of value) {
|
|
58
|
+
visit(item, used);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (!isObject(value)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
addNodeUses(value, used);
|
|
66
|
+
for (const [key, child] of Object.entries(value)) {
|
|
67
|
+
if (!SKIPPED_KEYS.has(key)) {
|
|
68
|
+
visit(child, used);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The TypeScript global type names that the declarations refer to. */
|
|
74
|
+
export function globalTypeReferences(declarations: readonly IrDeclaration[]): Set<string> {
|
|
75
|
+
const used = new Set<string>();
|
|
76
|
+
visit(declarations, used);
|
|
77
|
+
return used;
|
|
78
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IrArrayType,
|
|
3
|
+
IrReadonlyType,
|
|
4
|
+
IrTupleElement,
|
|
5
|
+
IrTupleType,
|
|
6
|
+
IrType,
|
|
7
|
+
} from "../../../domain/ir/nodes.js";
|
|
8
|
+
import { type Assignability, everyOf } from "./assignability.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* How the `--path-params-as-types` overlap check relates two lists: arrays, tuples and their
|
|
12
|
+
* `readonly` forms. `relate` compares two item types with the whole check.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
type Relate = (source: IrType, target: IrType) => Assignability;
|
|
16
|
+
|
|
17
|
+
/** The types of the `list` category of `assignability.ts`. */
|
|
18
|
+
export type IrListType = IrArrayType | IrTupleType | IrReadonlyType;
|
|
19
|
+
|
|
20
|
+
type IrMutableListType = IrArrayType | IrTupleType;
|
|
21
|
+
|
|
22
|
+
const UNDEFINED: IrType = { kind: "keyword", keyword: "undefined" };
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The type of a tuple element's items: a rest element `...T[]` stands for its items, and an
|
|
26
|
+
* optional element `T?` may be `undefined` (`[string?]` is no `string[]` under `strict`).
|
|
27
|
+
*/
|
|
28
|
+
function elementType(element: IrTupleElement): IrType {
|
|
29
|
+
if (element.isRest && element.type.kind === "array") {
|
|
30
|
+
return element.type.element;
|
|
31
|
+
}
|
|
32
|
+
return element.isOptional ? { kind: "union", types: [element.type, UNDEFINED] } : element.type;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isRequired(element: IrTupleElement): boolean {
|
|
36
|
+
return !element.isRest && !element.isOptional;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A tuple with a required element rejects an array, which may be empty. */
|
|
40
|
+
function arrayToTuple(target: IrTupleType): Assignability {
|
|
41
|
+
return target.elements.some(isRequired) ? "rejected" : "undecided";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Tuples of the same shape compare element by element; fixed lengths must be the same. */
|
|
45
|
+
function relateTuples(source: IrTupleType, target: IrTupleType, relate: Relate): Assignability {
|
|
46
|
+
if (source.elements.length !== target.elements.length) {
|
|
47
|
+
const isFixed = source.elements.every(isRequired) && target.elements.every(isRequired);
|
|
48
|
+
return isFixed ? "rejected" : "undecided";
|
|
49
|
+
}
|
|
50
|
+
return everyOf(source.elements, (element, index) => {
|
|
51
|
+
const other = target.elements[index] as IrTupleElement;
|
|
52
|
+
if (element.isRest !== other.isRest) {
|
|
53
|
+
return "undecided";
|
|
54
|
+
}
|
|
55
|
+
// An optional element may be missing where the target requires one.
|
|
56
|
+
if (element.isOptional && !other.isOptional) {
|
|
57
|
+
return "rejected";
|
|
58
|
+
}
|
|
59
|
+
return relate(element.type, other.type);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function relateMutableLists(
|
|
64
|
+
source: IrMutableListType,
|
|
65
|
+
target: IrMutableListType,
|
|
66
|
+
relate: Relate,
|
|
67
|
+
): Assignability {
|
|
68
|
+
if (source.kind === "array") {
|
|
69
|
+
return target.kind === "array" ? relate(source.element, target.element) : arrayToTuple(target);
|
|
70
|
+
}
|
|
71
|
+
if (target.kind === "array") {
|
|
72
|
+
return everyOf(source.elements, (element) => relate(elementType(element), target.element));
|
|
73
|
+
}
|
|
74
|
+
return relateTuples(source, target, relate);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Whether one list type fits another. */
|
|
78
|
+
export function relateLists(source: IrListType, target: IrListType, relate: Relate): Assignability {
|
|
79
|
+
if (source.kind === "readonly") {
|
|
80
|
+
// A readonly array is no mutable array (TS4104); to a readonly target it is the same type.
|
|
81
|
+
return target.kind === "readonly" ? relate(source.type, target.type) : "rejected";
|
|
82
|
+
}
|
|
83
|
+
if (target.kind === "readonly") {
|
|
84
|
+
return relate(source, target.type);
|
|
85
|
+
}
|
|
86
|
+
return relateMutableLists(source, target, relate);
|
|
87
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
irIntersection,
|
|
3
|
+
irKeyword,
|
|
4
|
+
irObject,
|
|
5
|
+
irProperty,
|
|
6
|
+
irReference,
|
|
7
|
+
} from "../../../domain/ir/constructors.js";
|
|
2
8
|
import type { IrPropertyName, IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
|
|
3
9
|
import { toPropertyName } from "../../../domain/ir/property-name.js";
|
|
4
10
|
import { createRef } from "../../../domain/openapi/json-pointer.js";
|
|
@@ -10,13 +16,16 @@ import {
|
|
|
10
16
|
QUERYSTRING_LOCATION,
|
|
11
17
|
} from "../../../domain/openapi/parameter-object.js";
|
|
12
18
|
import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
19
|
+
import { OutputFix } from "../../../domain/output-fixes.js";
|
|
13
20
|
import { refType } from "../ref-type.js";
|
|
14
21
|
import type { SchemaLocation } from "../schema/schema-context.js";
|
|
15
22
|
import { withSchemaComment } from "../schema-comment.js";
|
|
16
23
|
import type { TransformContext } from "../transform-context.js";
|
|
24
|
+
import { isExplodedQueryObject } from "./exploded-query.js";
|
|
17
25
|
import { parameterType } from "./parameter.js";
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */
|
|
28
|
+
const PATH_TEMPLATE_RE = /\{([^{}]+)\}/g;
|
|
20
29
|
|
|
21
30
|
/** A parameter as written in the document, and the object its `$ref` points to. */
|
|
22
31
|
interface ParameterEntry {
|
|
@@ -154,6 +163,66 @@ function querystringMember(
|
|
|
154
163
|
return withSchemaComment(property, querystring.resolved);
|
|
155
164
|
}
|
|
156
165
|
|
|
166
|
+
/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */
|
|
167
|
+
function isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {
|
|
168
|
+
return (
|
|
169
|
+
context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) &&
|
|
170
|
+
isExplodedQueryObject(entry.resolved, context.refs)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* An exploded object parameter's part of `query`: its object type. A parameter that may be left
|
|
176
|
+
* out sends none of its keys then, so they are optional: `Partial<…>`.
|
|
177
|
+
*/
|
|
178
|
+
function explodedPart(
|
|
179
|
+
entry: ResolvedEntry,
|
|
180
|
+
location: SchemaLocation,
|
|
181
|
+
context: TransformContext,
|
|
182
|
+
): IrType {
|
|
183
|
+
const type = entryType(entry, location, context);
|
|
184
|
+
return entry.resolved.required ? type : irReference("Partial", [type]);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** A location's parameters as members, and the object types of its exploded parameters. */
|
|
188
|
+
interface LocationParts {
|
|
189
|
+
readonly members: readonly IrPropertySignature[];
|
|
190
|
+
readonly exploded: readonly IrType[];
|
|
191
|
+
readonly isOptional: boolean;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Each parameter in document order, so the declarations they add keep their order. */
|
|
195
|
+
function locationParts(
|
|
196
|
+
entries: readonly ResolvedEntry[],
|
|
197
|
+
location: SchemaLocation,
|
|
198
|
+
context: TransformContext,
|
|
199
|
+
): LocationParts {
|
|
200
|
+
const members: IrPropertySignature[] = [];
|
|
201
|
+
const exploded: IrType[] = [];
|
|
202
|
+
let isOptional = true;
|
|
203
|
+
for (const entry of entries) {
|
|
204
|
+
if (isExplodedEntry(entry, context)) {
|
|
205
|
+
exploded.push(explodedPart(entry, location, context));
|
|
206
|
+
isOptional &&= !entry.resolved.required;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const member = parameterMember(entry, location, context);
|
|
210
|
+
members.push(member);
|
|
211
|
+
isOptional &&= member.isOptional;
|
|
212
|
+
}
|
|
213
|
+
return { members, exploded, isOptional };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** The members' object, intersected with the exploded parameters' types; `never` for none. */
|
|
217
|
+
function locationType({ members, exploded }: LocationParts): IrType {
|
|
218
|
+
const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];
|
|
219
|
+
const [first] = types;
|
|
220
|
+
if (first === undefined) {
|
|
221
|
+
return irKeyword("never");
|
|
222
|
+
}
|
|
223
|
+
return types.length === 1 ? first : irIntersection(types);
|
|
224
|
+
}
|
|
225
|
+
|
|
157
226
|
/** One location's parameters; optional when all of them are, and `never` when there are none. */
|
|
158
227
|
function locationMember(
|
|
159
228
|
parameterIn: ParameterLocation,
|
|
@@ -161,17 +230,14 @@ function locationMember(
|
|
|
161
230
|
location: SchemaLocation,
|
|
162
231
|
context: TransformContext,
|
|
163
232
|
): IrPropertySignature {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
.map((entry) => parameterMember(entry, location, context));
|
|
167
|
-
return irProperty(
|
|
168
|
-
toPropertyName(parameterIn),
|
|
169
|
-
members.length > 0 ? irObject(members) : irKeyword("never"),
|
|
170
|
-
{
|
|
171
|
-
isOptional: members.every((member) => member.isOptional),
|
|
172
|
-
isReadonly: context.options.immutable,
|
|
173
|
-
},
|
|
233
|
+
const located = entries.filter(
|
|
234
|
+
(entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,
|
|
174
235
|
);
|
|
236
|
+
const parts = locationParts(located, location, context);
|
|
237
|
+
return irProperty(toPropertyName(parameterIn), locationType(parts), {
|
|
238
|
+
isOptional: parts.isOptional,
|
|
239
|
+
isReadonly: context.options.immutable,
|
|
240
|
+
});
|
|
175
241
|
}
|
|
176
242
|
|
|
177
243
|
/**
|