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
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* TS2413). These functions find the signatures that cover another key the checker rejects.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { isAssignableToTemplate, type TemplateShape } from "./template-key-match.js";
|
|
10
|
+
|
|
9
11
|
/** A placeholder of a template literal type, by the type it stands for. */
|
|
10
12
|
export type PathPlaceholder = "string" | "number" | "boolean";
|
|
11
13
|
|
|
@@ -21,89 +23,176 @@ export type PathKey =
|
|
|
21
23
|
|
|
22
24
|
const BOOLEAN_TEXTS: readonly string[] = ["true", "false"];
|
|
23
25
|
|
|
24
|
-
/** The
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
/** The shapes after one more part; a boolean placeholder doubles them, as TypeScript does. */
|
|
27
|
+
function withPart(shapes: readonly TemplateShape[], part: PathKeyPart): TemplateShape[] {
|
|
28
|
+
return shapes.flatMap((shape): TemplateShape[] => {
|
|
29
|
+
const lead = shape.texts.slice(0, -1);
|
|
30
|
+
// A shape has one text more than it has placeholders, so it always has a last text.
|
|
31
|
+
const last = shape.texts[shape.texts.length - 1] as string;
|
|
32
|
+
if (part.kind === "text") {
|
|
33
|
+
return [{ texts: [...lead, last + part.text], types: shape.types }];
|
|
34
|
+
}
|
|
35
|
+
if (part.type === "boolean") {
|
|
36
|
+
return BOOLEAN_TEXTS.map((text) => ({ texts: [...lead, last + text], types: shape.types }));
|
|
37
|
+
}
|
|
38
|
+
return [{ texts: [...shape.texts, ""], types: [...shape.types, part.type] }];
|
|
39
|
+
});
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
/**
|
|
43
|
+
* The key types TypeScript makes of a key: a literal is one text; a template is one shape, or a
|
|
44
|
+
* union of shapes when `${boolean}` is in it (`` `/a/${boolean}` `` is `"/a/true" | "/a/false"`).
|
|
45
|
+
*/
|
|
46
|
+
function shapesOf(key: PathKey): readonly TemplateShape[] {
|
|
47
|
+
if (key.kind === "literal") {
|
|
48
|
+
return [{ texts: [key.url], types: [] }];
|
|
39
49
|
}
|
|
40
|
-
return
|
|
50
|
+
return key.parts.reduce<TemplateShape[]>(withPart, [{ texts: [""], types: [] }]);
|
|
41
51
|
}
|
|
42
52
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Whether a signature checks the covered key: every type of the covered key is assignable to one
|
|
55
|
+
* of the signature's types. A shape without placeholders (a boolean-only template) is a string
|
|
56
|
+
* literal, which is no signature, so the targets leave it out.
|
|
57
|
+
*/
|
|
58
|
+
function isCoveredBy(
|
|
59
|
+
sources: readonly TemplateShape[],
|
|
60
|
+
targets: readonly TemplateShape[],
|
|
49
61
|
): boolean {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
return (
|
|
63
|
+
sources.length > 0 &&
|
|
64
|
+
sources.every((source) => targets.some((target) => isAssignableToTemplate(source, target)))
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Whether TypeScript rejects the key at `covered` for the signature at `covering`. */
|
|
69
|
+
export type CoverRejection = (covering: number, covered: number) => boolean;
|
|
70
|
+
|
|
71
|
+
/** Without type information every covered key counts. */
|
|
72
|
+
const EVERY_COVER_REJECTED: CoverRejection = () => true;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The key types TypeScript checks against a signature: a literal's, or a template's signature
|
|
76
|
+
* types. A boolean-only template is no signature (TS1337), so the checker neither checks it nor
|
|
77
|
+
* checks anything against it; a repeated one is still reported (TS2374, see `repeatedTemplates`).
|
|
78
|
+
*/
|
|
79
|
+
function checkedShapes(key: PathKey): readonly TemplateShape[] {
|
|
80
|
+
const shapes = shapesOf(key);
|
|
81
|
+
return key.kind === "literal" ? shapes : shapes.filter((shape) => shape.types.length > 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** A checked key: the key, the shapes TypeScript checks, and its template identity. */
|
|
85
|
+
interface CheckedKey {
|
|
86
|
+
readonly key: PathKey;
|
|
87
|
+
readonly shapes: readonly TemplateShape[];
|
|
88
|
+
/** The key types written as one string, for templates; null for a literal. */
|
|
89
|
+
readonly template: string | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function checkedKeyOf(key: PathKey): CheckedKey {
|
|
93
|
+
const template = key.kind === "template" ? JSON.stringify(shapesOf(key)) : null;
|
|
94
|
+
return { key, shapes: checkedShapes(key), template };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The templates written more than once, as paths that differ only in parameter names give
|
|
99
|
+
* (`/a/{id}`, `/a/{name}`). OpenAPI forbids such paths, and one object with both signatures fails
|
|
100
|
+
* to compile whatever their types (TS2374), so each always counts as covering the other.
|
|
101
|
+
*/
|
|
102
|
+
function repeatedTemplates(checked: readonly CheckedKey[]): ReadonlySet<string> {
|
|
103
|
+
const seen = new Set<string>();
|
|
104
|
+
const repeated = new Set<string>();
|
|
105
|
+
for (const { template } of checked) {
|
|
106
|
+
if (template !== null) {
|
|
107
|
+
(seen.has(template) ? repeated : seen).add(template);
|
|
66
108
|
}
|
|
67
109
|
}
|
|
68
|
-
return
|
|
110
|
+
return repeated;
|
|
69
111
|
}
|
|
70
112
|
|
|
71
113
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
114
|
+
* The checked keys by the first text of each of their shapes, sorted. A key type is assignable to
|
|
115
|
+
* a template only when its first text starts with the template's first text (both branches of
|
|
116
|
+
* `isAssignableToTemplate`), so the keys a template can cover are one run of this list. Without
|
|
117
|
+
* it the check compares every pair of keys, which takes minutes for 10 000 paths.
|
|
75
118
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
119
|
+
interface StartTextIndex {
|
|
120
|
+
readonly starts: readonly string[];
|
|
121
|
+
readonly keyIndexes: readonly number[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Code unit order: in it the strings that start with one prefix are adjacent. */
|
|
125
|
+
function compareCodeUnits(left: string, right: string): number {
|
|
126
|
+
if (left === right) {
|
|
127
|
+
return 0;
|
|
79
128
|
}
|
|
80
|
-
return
|
|
81
|
-
.map((part) => (part.kind === "text" ? part.text : SAMPLE_TEXTS[part.type]))
|
|
82
|
-
.join("");
|
|
129
|
+
return left < right ? -1 : 1;
|
|
83
130
|
}
|
|
84
131
|
|
|
85
|
-
|
|
86
|
-
|
|
132
|
+
function startTextIndexOf(checked: readonly CheckedKey[]): StartTextIndex {
|
|
133
|
+
const entries = checked.flatMap(({ shapes }, keyIndex) =>
|
|
134
|
+
shapes.map((shape) => ({ start: shape.texts[0] as string, keyIndex })),
|
|
135
|
+
);
|
|
136
|
+
entries.sort((left, right) => compareCodeUnits(left.start, right.start));
|
|
137
|
+
return {
|
|
138
|
+
starts: entries.map((entry) => entry.start),
|
|
139
|
+
keyIndexes: entries.map((entry) => entry.keyIndex),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
87
142
|
|
|
88
|
-
/**
|
|
89
|
-
|
|
143
|
+
/** The indexes of the keys with a shape whose first text starts with one of the prefixes. */
|
|
144
|
+
function keysStartingWith(index: StartTextIndex, prefixes: readonly string[]): Set<number> {
|
|
145
|
+
const found = new Set<number>();
|
|
146
|
+
for (const prefix of prefixes) {
|
|
147
|
+
let low = 0;
|
|
148
|
+
let high = index.starts.length;
|
|
149
|
+
while (low < high) {
|
|
150
|
+
const middle = (low + high) >> 1;
|
|
151
|
+
if ((index.starts[middle] as string) < prefix) {
|
|
152
|
+
low = middle + 1;
|
|
153
|
+
} else {
|
|
154
|
+
high = middle;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
for (let at = low; at < index.starts.length; at += 1) {
|
|
158
|
+
if (!(index.starts[at] as string).startsWith(prefix)) {
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
found.add(index.keyIndexes[at] as number);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return found;
|
|
165
|
+
}
|
|
90
166
|
|
|
91
|
-
/**
|
|
167
|
+
/**
|
|
168
|
+
* The indexes of the template keys that cover another key of the list, where it is rejected, or
|
|
169
|
+
* that repeat another template key. A template covers the keys TypeScript checks against it, the
|
|
170
|
+
* ones its own matching accepts (see `template-key-match.ts`), not every string it stands for:
|
|
171
|
+
* `` `/a/b/${number}` `` is no `` `/${string}/${number}` `` to the checker, which does not
|
|
172
|
+
* backtrack, so that pair is never checked.
|
|
173
|
+
*/
|
|
92
174
|
export function coveringTemplateKeys(
|
|
93
175
|
keys: readonly PathKey[],
|
|
94
176
|
isRejected: CoverRejection = EVERY_COVER_REJECTED,
|
|
95
177
|
): ReadonlySet<number> {
|
|
178
|
+
const checked = keys.map(checkedKeyOf);
|
|
179
|
+
const repeated = repeatedTemplates(checked);
|
|
180
|
+
const startTexts = startTextIndexOf(checked);
|
|
96
181
|
const covering = new Set<number>();
|
|
97
|
-
|
|
98
|
-
if (
|
|
182
|
+
checked.forEach(({ template, shapes: targets }, index) => {
|
|
183
|
+
if (template === null) {
|
|
99
184
|
return;
|
|
100
185
|
}
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
186
|
+
const prefixes = targets.map((target) => target.texts[0] as string);
|
|
187
|
+
const candidates = [...keysStartingWith(startTexts, prefixes)].sort((a, b) => a - b);
|
|
188
|
+
const isCovering =
|
|
189
|
+
repeated.has(template) ||
|
|
190
|
+
candidates.some(
|
|
191
|
+
(otherIndex) =>
|
|
192
|
+
otherIndex !== index &&
|
|
193
|
+
isCoveredBy((checked[otherIndex] as CheckedKey).shapes, targets) &&
|
|
194
|
+
isRejected(index, otherIndex),
|
|
195
|
+
);
|
|
107
196
|
if (isCovering) {
|
|
108
197
|
covering.add(index);
|
|
109
198
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { PathKeyPart, PathPlaceholder } from "./path-key-overlaps.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `--path-params-as-types` key as the original builds it: each `{name}` match, in URL order,
|
|
5
|
+
* replaces the first occurrence of its text in the key so far. A parameter named `number`,
|
|
6
|
+
* `string` or `boolean` can so hit the `${number}` an earlier parameter got: of
|
|
7
|
+
* `/a/{id}/b/{number}` the original makes `/a/$${number}/b/{number}`. That output compiles, so it
|
|
8
|
+
* stays the default (ADR-021); the `path-param-type-names` fix gives every match its own
|
|
9
|
+
* placeholder.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** One `{name}` of the URL and the placeholder of its parameter's type. */
|
|
13
|
+
export interface PathParameterMatch {
|
|
14
|
+
readonly match: string;
|
|
15
|
+
readonly type: PathPlaceholder;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* One UTF-16 code unit of the key so far (`indexOf` counts those): URL text, or a unit of the
|
|
20
|
+
* placeholder that the match at `owner` inserted.
|
|
21
|
+
*/
|
|
22
|
+
interface KeyUnit {
|
|
23
|
+
readonly unit: string;
|
|
24
|
+
readonly owner: number | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const URL_TEXT = null;
|
|
28
|
+
|
|
29
|
+
/** `${type}`: the text of a template literal type placeholder. */
|
|
30
|
+
export function placeholderText(type: PathPlaceholder): string {
|
|
31
|
+
return `\${${type}}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The key's units after each match replaced the first occurrence of its text. */
|
|
35
|
+
function replacedUnits(url: string, matches: readonly PathParameterMatch[]): readonly KeyUnit[] {
|
|
36
|
+
const units: KeyUnit[] = url.split("").map((unit) => ({ unit, owner: URL_TEXT }));
|
|
37
|
+
matches.forEach(({ match, type }, owner) => {
|
|
38
|
+
const at = units
|
|
39
|
+
.map(({ unit }) => unit)
|
|
40
|
+
.join("")
|
|
41
|
+
.indexOf(match);
|
|
42
|
+
if (at >= 0) {
|
|
43
|
+
const inserted = placeholderText(type)
|
|
44
|
+
.split("")
|
|
45
|
+
.map((unit) => ({ unit, owner }));
|
|
46
|
+
units.splice(at, match.length, ...inserted);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return units;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The placeholders, by match, that no later match cut into. */
|
|
53
|
+
function intactPlaceholders(
|
|
54
|
+
units: readonly KeyUnit[],
|
|
55
|
+
matches: readonly PathParameterMatch[],
|
|
56
|
+
): ReadonlyMap<number, PathPlaceholder> {
|
|
57
|
+
const intact = new Map<number, PathPlaceholder>();
|
|
58
|
+
matches.forEach(({ type }, owner) => {
|
|
59
|
+
const left = units.filter((unit) => unit.owner === owner).length;
|
|
60
|
+
if (left === placeholderText(type).length) {
|
|
61
|
+
intact.set(owner, type);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return intact;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The key as parts. What is left of a placeholder that a later match cut into (the `$` of
|
|
69
|
+
* `$${number}`) is text, as TypeScript reads it.
|
|
70
|
+
*/
|
|
71
|
+
export function replacedTemplateParts(
|
|
72
|
+
url: string,
|
|
73
|
+
matches: readonly PathParameterMatch[],
|
|
74
|
+
): PathKeyPart[] {
|
|
75
|
+
const units = replacedUnits(url, matches);
|
|
76
|
+
const intact = intactPlaceholders(units, matches);
|
|
77
|
+
const parts: PathKeyPart[] = [];
|
|
78
|
+
let text = "";
|
|
79
|
+
units.forEach(({ unit, owner }, index) => {
|
|
80
|
+
const type = owner === URL_TEXT ? undefined : intact.get(owner);
|
|
81
|
+
if (type === undefined) {
|
|
82
|
+
text += unit;
|
|
83
|
+
} else if (units[index - 1]?.owner !== owner) {
|
|
84
|
+
parts.push({ kind: "text", text }, { kind: "placeholder", type });
|
|
85
|
+
text = "";
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
parts.push({ kind: "text", text });
|
|
89
|
+
return parts;
|
|
90
|
+
}
|
|
@@ -14,20 +14,29 @@ import {
|
|
|
14
14
|
pathItemOperations,
|
|
15
15
|
} from "../../../domain/openapi/path-item-object.js";
|
|
16
16
|
import type { ReferenceSchema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
17
|
+
import { OutputFix } from "../../../domain/output-fixes.js";
|
|
17
18
|
import { documentEntries } from "../document-entries.js";
|
|
18
19
|
import { refType } from "../ref-type.js";
|
|
19
20
|
import type { TransformContext } from "../transform-context.js";
|
|
21
|
+
import { type DeclaredTypeLookup, NO_DECLARED_TYPES } from "./declared-types.js";
|
|
20
22
|
import { documentMember } from "./document-member.js";
|
|
21
23
|
import { pathItemType } from "./path-item.js";
|
|
22
|
-
import { isCoveredPathItemRejected } from "./path-item-conflicts.js";
|
|
23
24
|
import {
|
|
25
|
+
type CoverRejection,
|
|
24
26
|
coveringTemplateKeys,
|
|
25
27
|
type PathKey,
|
|
26
28
|
type PathKeyPart,
|
|
27
29
|
type PathPlaceholder,
|
|
28
30
|
} from "./path-key-overlaps.js";
|
|
31
|
+
import {
|
|
32
|
+
type PathParameterMatch,
|
|
33
|
+
placeholderText,
|
|
34
|
+
replacedTemplateParts,
|
|
35
|
+
} from "./path-template-replace.js";
|
|
36
|
+
import { assignabilityProof } from "./type-assignability.js";
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */
|
|
39
|
+
const PATH_PARAMETER_RE = /\{[^{}]+\}/g;
|
|
31
40
|
|
|
32
41
|
/** Placeholders by parameter schema type; anything else is a string placeholder. */
|
|
33
42
|
const PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([
|
|
@@ -37,11 +46,6 @@ const PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([
|
|
|
37
46
|
]);
|
|
38
47
|
const STRING_PLACEHOLDER: PathPlaceholder = "string";
|
|
39
48
|
|
|
40
|
-
/** `${type}`: the text of a template literal type placeholder. */
|
|
41
|
-
function placeholderText(type: PathPlaceholder): string {
|
|
42
|
-
return `\${${type}}`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
49
|
function resolvedParameter(
|
|
46
50
|
parameter: ParameterOrReference,
|
|
47
51
|
context: TransformContext,
|
|
@@ -80,29 +84,37 @@ function pathParameters(
|
|
|
80
84
|
return byName;
|
|
81
85
|
}
|
|
82
86
|
|
|
87
|
+
/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */
|
|
88
|
+
function splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {
|
|
89
|
+
return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {
|
|
90
|
+
const type = matches[index]?.type;
|
|
91
|
+
const textPart: PathKeyPart = { kind: "text", text };
|
|
92
|
+
return type === undefined ? [textPart] : [textPart, { kind: "placeholder", type }];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
83
96
|
/**
|
|
84
97
|
* `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for
|
|
85
|
-
* its parameter's type
|
|
98
|
+
* its parameter's type, the way the original replaces them unless the `path-param-type-names` fix
|
|
99
|
+
* is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.
|
|
86
100
|
*/
|
|
87
101
|
function pathTemplateParts(
|
|
88
102
|
url: string,
|
|
89
103
|
pathItem: PathItemObject,
|
|
90
104
|
context: TransformContext,
|
|
91
105
|
): PathKeyPart[] | null {
|
|
92
|
-
const
|
|
93
|
-
if (!
|
|
106
|
+
const found = url.match(PATH_PARAMETER_RE);
|
|
107
|
+
if (!found) {
|
|
94
108
|
return null;
|
|
95
109
|
}
|
|
96
110
|
const parameters = pathParameters(pathItem, context);
|
|
97
|
-
const
|
|
111
|
+
const matches = found.map((match): PathParameterMatch => {
|
|
98
112
|
const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;
|
|
99
|
-
return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;
|
|
100
|
-
});
|
|
101
|
-
return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {
|
|
102
|
-
const type = placeholders[index];
|
|
103
|
-
const textPart: PathKeyPart = { kind: "text", text };
|
|
104
|
-
return type === undefined ? [textPart] : [textPart, { kind: "placeholder", type }];
|
|
113
|
+
return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
|
|
105
114
|
});
|
|
115
|
+
return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)
|
|
116
|
+
? splitTemplateParts(url, matches)
|
|
117
|
+
: replacedTemplateParts(url, matches);
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
/**
|
|
@@ -120,7 +132,8 @@ function templateText(parts: readonly PathKeyPart[]): string {
|
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
/** A path's member, its key and its path item type for the overlap check. */
|
|
123
|
-
interface PathMember {
|
|
135
|
+
export interface PathMember {
|
|
136
|
+
readonly url: string;
|
|
124
137
|
readonly member: IrMember;
|
|
125
138
|
readonly key: PathKey;
|
|
126
139
|
readonly type: IrType;
|
|
@@ -139,7 +152,7 @@ function pathItemMember(
|
|
|
139
152
|
: null;
|
|
140
153
|
if (parts === null) {
|
|
141
154
|
const member = irProperty(toPropertyName(url), type, { isReadonly });
|
|
142
|
-
return { member, key: literalKey(url), type };
|
|
155
|
+
return { url, member, key: literalKey(url), type };
|
|
143
156
|
}
|
|
144
157
|
const member: IrMember = {
|
|
145
158
|
kind: "indexSignature",
|
|
@@ -149,33 +162,75 @@ function pathItemMember(
|
|
|
149
162
|
isReadonly,
|
|
150
163
|
comments: [],
|
|
151
164
|
};
|
|
152
|
-
return { member, key: { kind: "template", parts }, type };
|
|
165
|
+
return { url, member, key: { kind: "template", parts }, type };
|
|
153
166
|
}
|
|
154
167
|
|
|
155
168
|
function literalKey(url: string): PathKey {
|
|
156
169
|
return { kind: "literal", url };
|
|
157
170
|
}
|
|
158
171
|
|
|
172
|
+
const PATHS_TYPE_NAME = "paths";
|
|
173
|
+
|
|
174
|
+
/** The URL of `paths["/apps/{id}"]`, or null for any other type. */
|
|
175
|
+
function pathsIndexOf(type: IrType): string | null {
|
|
176
|
+
if (type.kind !== "indexedAccess" || type.index.kind !== "stringLiteral") {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const { object } = type;
|
|
180
|
+
const isPaths =
|
|
181
|
+
object.kind === "reference" &&
|
|
182
|
+
object.name === PATHS_TYPE_NAME &&
|
|
183
|
+
object.typeArguments.length === 0;
|
|
184
|
+
return isPaths ? type.index.value : null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The lookup, and `paths["/apps/{id}"]` as that path's item. The declarations cannot read it: a
|
|
189
|
+
* templated path is no property of `paths`, and TypeScript finds it through the signature.
|
|
190
|
+
*/
|
|
191
|
+
function withPathItems(
|
|
192
|
+
paths: readonly PathMember[],
|
|
193
|
+
lookup: DeclaredTypeLookup,
|
|
194
|
+
): DeclaredTypeLookup {
|
|
195
|
+
const byUrl = new Map(paths.map((path) => [path.url, path.type]));
|
|
196
|
+
return (type) => {
|
|
197
|
+
const url = pathsIndexOf(type);
|
|
198
|
+
return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The rejection of a covered path item: only one proven not assignable to the signature's type
|
|
204
|
+
* counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well
|
|
205
|
+
* compile (`Record<string, never>` fits `{ [key: string]: unknown }`).
|
|
206
|
+
*/
|
|
207
|
+
function rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {
|
|
208
|
+
const relate = assignabilityProof(withPathItems(paths, lookup));
|
|
209
|
+
return (coveringIndex, coveredIndex) => {
|
|
210
|
+
const coveringPath = paths[coveringIndex];
|
|
211
|
+
const coveredPath = paths[coveredIndex];
|
|
212
|
+
return (
|
|
213
|
+
coveringPath !== undefined &&
|
|
214
|
+
coveredPath !== undefined &&
|
|
215
|
+
relate(coveredPath.type, coveringPath.type) === "rejected"
|
|
216
|
+
);
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
159
220
|
/**
|
|
160
221
|
* The members as one object type. When an index signature covers another key, TypeScript checks
|
|
161
222
|
* the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such
|
|
162
223
|
* signature gets an object of its own in an intersection: an intersection does not check its parts
|
|
163
224
|
* against each other, and every key has the type it had in the one object. Output that compiles
|
|
164
|
-
* keeps the one object.
|
|
225
|
+
* keeps the one object. The lookup reads the types that path items reference; without it, a
|
|
226
|
+
* reference decides nothing.
|
|
165
227
|
*/
|
|
166
|
-
function pathsObjectType(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return (
|
|
173
|
-
coveringPath !== undefined &&
|
|
174
|
-
coveredPath !== undefined &&
|
|
175
|
-
isCoveredPathItemRejected(coveredPath.type, coveringPath.type)
|
|
176
|
-
);
|
|
177
|
-
},
|
|
178
|
-
);
|
|
228
|
+
export function pathsObjectType(
|
|
229
|
+
paths: readonly PathMember[],
|
|
230
|
+
lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,
|
|
231
|
+
): IrType {
|
|
232
|
+
const keys = paths.map(({ key }) => key);
|
|
233
|
+
const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));
|
|
179
234
|
if (covering.size === 0) {
|
|
180
235
|
return irObject(paths.map(({ member }) => member));
|
|
181
236
|
}
|
|
@@ -186,8 +241,8 @@ function pathsObjectType(paths: readonly PathMember[]): IrType {
|
|
|
186
241
|
return irIntersection([irObject(rest), ...own]);
|
|
187
242
|
}
|
|
188
243
|
|
|
189
|
-
/** The `paths` interface
|
|
190
|
-
export function
|
|
244
|
+
/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */
|
|
245
|
+
export function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {
|
|
191
246
|
const members: PathMember[] = [];
|
|
192
247
|
for (const [url, pathItem] of documentEntries(paths, context.options)) {
|
|
193
248
|
if (!pathItem || typeof pathItem !== "object") {
|
|
@@ -196,7 +251,7 @@ export function pathsType(paths: PathsObject, context: TransformContext): IrType
|
|
|
196
251
|
if ("$ref" in pathItem) {
|
|
197
252
|
const options = { isReadonly: context.options.immutable };
|
|
198
253
|
const member = documentMember(url, refType(pathItem.$ref), pathItem, options);
|
|
199
|
-
members.push({ member, key: literalKey(url), type: member.type });
|
|
254
|
+
members.push({ url, member, key: literalKey(url), type: member.type });
|
|
200
255
|
continue;
|
|
201
256
|
}
|
|
202
257
|
const startedAt = context.diagnostics.now();
|
|
@@ -207,5 +262,13 @@ export function pathsType(paths: PathsObject, context: TransformContext): IrType
|
|
|
207
262
|
context.diagnostics.debug(`Transformed path "${url}"`, context.diagnostics.now() - startedAt);
|
|
208
263
|
}
|
|
209
264
|
}
|
|
210
|
-
return
|
|
265
|
+
return members;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* The `paths` interface body, with only the path items' own types for the overlap check. The
|
|
270
|
+
* document transform checks the overlaps again once the referenced types are declared.
|
|
271
|
+
*/
|
|
272
|
+
export function pathsType(paths: PathsObject, context: TransformContext): IrType {
|
|
273
|
+
return pathsObjectType(pathMembers(paths, context));
|
|
211
274
|
}
|
|
@@ -2,6 +2,7 @@ import { irRaw } from "../../../domain/ir/constructors.js";
|
|
|
2
2
|
import type { IrDeclaration, IrTypeAliasDeclaration } from "../../../domain/ir/nodes.js";
|
|
3
3
|
import { escapeSingleQuotedText } from "../../../domain/ir/raw-text-escapes.js";
|
|
4
4
|
import type { ComponentKind } from "../../../domain/openapi/components-object.js";
|
|
5
|
+
import { globalTypeReferences } from "./global-type-references.js";
|
|
5
6
|
|
|
6
7
|
/** The `--root-types` aliases: `export type Pet = components['schemas']['Pet'];`. */
|
|
7
8
|
|
|
@@ -66,37 +67,37 @@ function freeName(name: string, taken: ReadonlySet<string>): string {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
70
|
+
* Rename each root alias whose name an enum or a helper type of the footer also declares, or that
|
|
71
|
+
* shadows a TypeScript global type the output refers to (`Record` in `Record<string, never>`), to
|
|
72
|
+
* the next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The
|
|
73
|
+
* footer and the globals keep their names, because the generated types refer to them. Before, the
|
|
74
|
+
* output did not compile (enums: upstream #2099, #2341, #2206; helpers: a schema named
|
|
75
|
+
* `WithRequired`, roadmap R11; globals: TS2315). Other declarations are returned unchanged.
|
|
76
|
+
*
|
|
77
|
+
* With the `root-type-numbering` fix (ADR-021, roadmap R13, backlog 30) the body also holds the
|
|
78
|
+
* aliases a later schema of one exported name took the name from, after the other aliases and
|
|
79
|
+
* under that same name. Each gets the next free number in body order, after the alias that kept
|
|
80
|
+
* the name got its own: so the fix only adds exports, and every other alias keeps the name it has
|
|
81
|
+
* without the fix.
|
|
72
82
|
*/
|
|
73
|
-
export function
|
|
74
|
-
|
|
75
|
-
kept: readonly IrTypeAliasDeclaration[],
|
|
76
|
-
): IrTypeAliasDeclaration[] {
|
|
77
|
-
const taken = new Set(kept.map((alias) => alias.name));
|
|
78
|
-
return displaced.map((alias) => {
|
|
79
|
-
const name = freeName(alias.name, taken);
|
|
80
|
-
taken.add(name);
|
|
81
|
-
return { ...alias, name };
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Rename each root alias whose name an enum or a helper type of the footer also declares, to the
|
|
87
|
-
* next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The
|
|
88
|
-
* footer keeps its names, because the generated types refer to them. Before, both were declared
|
|
89
|
-
* under one name, which does not compile (enums: upstream #2099, #2341, #2206; helpers: a schema
|
|
90
|
-
* named `WithRequired`, roadmap R11). Other declarations are returned unchanged.
|
|
91
|
-
*/
|
|
92
|
-
export function renameAliasesTakenByFooter(
|
|
93
|
-
body: readonly IrDeclaration[],
|
|
83
|
+
export function renameTakenAliases<T extends IrDeclaration>(
|
|
84
|
+
body: readonly T[],
|
|
94
85
|
footer: readonly IrDeclaration[],
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
86
|
+
closing: readonly IrDeclaration[] = [],
|
|
87
|
+
): T[] {
|
|
88
|
+
const reserved = footerTypeNames(footer);
|
|
89
|
+
for (const name of globalTypeReferences([...body, ...footer, ...closing])) {
|
|
90
|
+
reserved.add(name);
|
|
91
|
+
}
|
|
92
|
+
const taken = declaredNames([...body, ...footer, ...closing]);
|
|
93
|
+
const aliasNames = new Set<string>();
|
|
98
94
|
return body.map((declaration) => {
|
|
99
|
-
if (!isRootTypeAlias(declaration)
|
|
95
|
+
if (!isRootTypeAlias(declaration)) {
|
|
96
|
+
return declaration;
|
|
97
|
+
}
|
|
98
|
+
const isRepeated = aliasNames.has(declaration.name);
|
|
99
|
+
aliasNames.add(declaration.name);
|
|
100
|
+
if (!isRepeated && !reserved.has(declaration.name)) {
|
|
100
101
|
return declaration;
|
|
101
102
|
}
|
|
102
103
|
const name = freeName(declaration.name, taken);
|