openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +34 -11
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +33 -10
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
- package/dist/api/default-ports.cjs +9 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +8 -1
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs +25 -0
- package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
- package/dist/api/discriminator-conflict-warnings.mjs +23 -0
- package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
- package/dist/api/discriminator-enum-names.cjs +19 -0
- package/dist/api/discriminator-enum-names.cjs.map +1 -0
- package/dist/api/discriminator-enum-names.mjs +17 -0
- package/dist/api/discriminator-enum-names.mjs.map +1 -0
- package/dist/api/discriminator-enum-parent.cjs +59 -0
- package/dist/api/discriminator-enum-parent.cjs.map +1 -0
- package/dist/api/discriminator-enum-parent.mjs +57 -0
- package/dist/api/discriminator-enum-parent.mjs.map +1 -0
- package/dist/api/discriminator-enum.cjs +25 -0
- package/dist/api/discriminator-enum.cjs.map +1 -1
- package/dist/api/discriminator-enum.mjs +25 -1
- package/dist/api/discriminator-enum.mjs.map +1 -1
- package/dist/api/discriminator-other-owners.cjs +67 -0
- package/dist/api/discriminator-other-owners.cjs.map +1 -0
- package/dist/api/discriminator-other-owners.mjs +64 -0
- package/dist/api/discriminator-other-owners.mjs.map +1 -0
- package/dist/api/discriminator-patch.cjs +92 -0
- package/dist/api/discriminator-patch.cjs.map +1 -0
- package/dist/api/discriminator-patch.mjs +86 -0
- package/dist/api/discriminator-patch.mjs.map +1 -0
- package/dist/api/discriminator-scan.cjs +50 -65
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +44 -59
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-refs.cjs +15 -12
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +15 -12
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +21 -4
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +22 -5
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/enum-values-warnings.cjs +16 -0
- package/dist/api/enum-values-warnings.cjs.map +1 -0
- package/dist/api/enum-values-warnings.mjs +14 -0
- package/dist/api/enum-values-warnings.mjs.map +1 -0
- package/dist/api/footer-sink.cjs +25 -2
- package/dist/api/footer-sink.cjs.map +1 -1
- package/dist/api/footer-sink.mjs +25 -2
- package/dist/api/footer-sink.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +4 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +4 -1
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/legacy-ts-helpers.cjs.map +1 -1
- package/dist/api/legacy-ts-helpers.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +2 -1
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +3 -2
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/path-template-warnings.cjs +21 -0
- package/dist/api/path-template-warnings.cjs.map +1 -0
- package/dist/api/path-template-warnings.mjs +19 -0
- package/dist/api/path-template-warnings.mjs.map +1 -0
- package/dist/api/transform-context.cjs +4 -2
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +4 -2
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +52 -3
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +53 -4
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.cjs +6 -1
- package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.mjs +6 -1
- package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
- package/dist/application/print/type-printer.cjs +7 -1
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +7 -1
- package/dist/application/print/type-printer.mjs.map +1 -1
- package/dist/application/transform/document/assignability.cjs +144 -0
- package/dist/application/transform/document/assignability.cjs.map +1 -0
- package/dist/application/transform/document/assignability.mjs +138 -0
- package/dist/application/transform/document/assignability.mjs.map +1 -0
- package/dist/application/transform/document/components.cjs +2 -2
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +4 -4
- package/dist/application/transform/document/components.mjs.map +1 -1
- package/dist/application/transform/document/declared-types.cjs +66 -0
- package/dist/application/transform/document/declared-types.cjs.map +1 -0
- package/dist/application/transform/document/declared-types.mjs +63 -0
- package/dist/application/transform/document/declared-types.mjs.map +1 -0
- package/dist/application/transform/document/document.cjs +32 -9
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +34 -11
- package/dist/application/transform/document/document.mjs.map +1 -1
- package/dist/application/transform/document/exploded-query.cjs +46 -0
- package/dist/application/transform/document/exploded-query.cjs.map +1 -0
- package/dist/application/transform/document/exploded-query.mjs +43 -0
- package/dist/application/transform/document/exploded-query.mjs.map +1 -0
- package/dist/application/transform/document/global-type-references.cjs +63 -0
- package/dist/application/transform/document/global-type-references.cjs.map +1 -0
- package/dist/application/transform/document/global-type-references.mjs +61 -0
- package/dist/application/transform/document/global-type-references.mjs.map +1 -0
- package/dist/application/transform/document/list-assignability.cjs +54 -0
- package/dist/application/transform/document/list-assignability.cjs.map +1 -0
- package/dist/application/transform/document/list-assignability.mjs +52 -0
- package/dist/application/transform/document/list-assignability.mjs.map +1 -0
- package/dist/application/transform/document/parameters.cjs +41 -9
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +42 -10
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
- package/dist/application/transform/document/path-template-replace.cjs +48 -0
- package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
- package/dist/application/transform/document/path-template-replace.mjs +45 -0
- package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
- package/dist/application/transform/document/paths.cjs +55 -29
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +54 -30
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.cjs +15 -14
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.mjs +15 -13
- package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
- package/dist/application/transform/document/template-key-match.cjs +128 -0
- package/dist/application/transform/document/template-key-match.cjs.map +1 -0
- package/dist/application/transform/document/template-key-match.mjs +125 -0
- package/dist/application/transform/document/template-key-match.mjs.map +1 -0
- package/dist/application/transform/document/type-assignability.cjs +192 -0
- package/dist/application/transform/document/type-assignability.cjs.map +1 -0
- package/dist/application/transform/document/type-assignability.mjs +190 -0
- package/dist/application/transform/document/type-assignability.mjs.map +1 -0
- package/dist/application/transform/document/type-key.cjs +70 -0
- package/dist/application/transform/document/type-key.cjs.map +1 -0
- package/dist/application/transform/document/type-key.mjs +68 -0
- package/dist/application/transform/document/type-key.mjs.map +1 -0
- package/dist/application/transform/document/type-resolution.cjs +131 -0
- package/dist/application/transform/document/type-resolution.cjs.map +1 -0
- package/dist/application/transform/document/type-resolution.mjs +125 -0
- package/dist/application/transform/document/type-resolution.mjs.map +1 -0
- package/dist/application/transform/footer/document-footer.cjs +66 -4
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +67 -5
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.cjs +17 -0
- package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.mjs +17 -1
- package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
- package/dist/application/transform/footer/enum-values-check.cjs +129 -0
- package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
- package/dist/application/transform/footer/enum-values-check.mjs +127 -0
- package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
- package/dist/application/transform/footer/evaluation.cjs +42 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/evaluation.mjs +33 -0
- package/dist/application/transform/footer/evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
- package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
- package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.cjs +138 -0
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.mjs +136 -0
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.cjs +107 -0
- package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.mjs +105 -0
- package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
- package/dist/application/transform/footer/type-rules.cjs +172 -0
- package/dist/application/transform/footer/type-rules.cjs.map +1 -0
- package/dist/application/transform/footer/type-rules.mjs +166 -0
- package/dist/application/transform/footer/type-rules.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
- package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
- package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
- package/dist/application/transform/ref-type.cjs +7 -2
- package/dist/application/transform/ref-type.cjs.map +1 -1
- package/dist/application/transform/ref-type.mjs +3 -2
- package/dist/application/transform/ref-type.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs +38 -0
- package/dist/application/transform/schema/access-flags.cjs.map +1 -0
- package/dist/application/transform/schema/access-flags.mjs +36 -0
- package/dist/application/transform/schema/access-flags.mjs.map +1 -0
- package/dist/application/transform/schema/array-type.cjs +32 -1
- package/dist/application/transform/schema/array-type.cjs.map +1 -1
- package/dist/application/transform/schema/array-type.mjs +33 -2
- package/dist/application/transform/schema/array-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +50 -15
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +50 -15
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/core-type.cjs +3 -1
- package/dist/application/transform/schema/core-type.cjs.map +1 -1
- package/dist/application/transform/schema/core-type.mjs +3 -1
- package/dist/application/transform/schema/core-type.mjs.map +1 -1
- package/dist/application/transform/schema/discriminated-union.cjs +30 -0
- package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
- package/dist/application/transform/schema/discriminated-union.mjs +27 -0
- package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.cjs +3 -2
- package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
- package/dist/application/transform/schema/discriminator-property.mjs +3 -2
- package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +66 -10
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +67 -12
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
- package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +38 -25
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +39 -27
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- package/dist/application/transform/schema/required-variants.cjs +45 -0
- package/dist/application/transform/schema/required-variants.cjs.map +1 -0
- package/dist/application/transform/schema/required-variants.mjs +42 -0
- package/dist/application/transform/schema/required-variants.mjs.map +1 -0
- package/dist/application/transform/schema/schema-transform.cjs +2 -2
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +2 -2
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +51 -5
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +50 -6
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/application/transform/type-combinators.mjs +1 -1
- package/dist/cli/api-settings.cjs +78 -0
- package/dist/cli/api-settings.cjs.map +1 -0
- package/dist/cli/api-settings.mjs +73 -0
- package/dist/cli/api-settings.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +12 -3
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +12 -4
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/cli-errors.cjs +3 -2
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +3 -2
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-output.cjs +8 -3
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +9 -4
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/help-text.cjs +3 -3
- package/dist/cli/help-text.cjs.map +1 -1
- package/dist/cli/help-text.mjs +3 -3
- package/dist/cli/help-text.mjs.map +1 -1
- package/dist/cli/main.cjs +5 -0
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +5 -0
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +15 -7
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +15 -7
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/ref-limits.cjs +1 -1
- package/dist/cli/ref-limits.cjs.map +1 -1
- package/dist/cli/ref-limits.mjs +2 -2
- package/dist/cli/ref-limits.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +20 -3
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +21 -4
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/errors.cjs +6 -1
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +6 -1
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +7 -1
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +6 -2
- package/dist/domain/ir/constructors.mjs.map +1 -1
- package/dist/domain/openapi/admitted-values.cjs +75 -0
- package/dist/domain/openapi/admitted-values.cjs.map +1 -0
- package/dist/domain/openapi/admitted-values.mjs +72 -0
- package/dist/domain/openapi/admitted-values.mjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.cjs +68 -0
- package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.mjs +62 -0
- package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
- package/dist/domain/openapi/parameter-object.cjs.map +1 -1
- package/dist/domain/openapi/parameter-object.mjs.map +1 -1
- package/dist/domain/openapi/path-templates.cjs +23 -0
- package/dist/domain/openapi/path-templates.cjs.map +1 -0
- package/dist/domain/openapi/path-templates.mjs +21 -0
- package/dist/domain/openapi/path-templates.mjs.map +1 -0
- package/dist/domain/output-fixes.cjs +36 -1
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +36 -1
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/url-credentials.cjs +10 -0
- package/dist/domain/url-credentials.cjs.map +1 -0
- package/dist/domain/url-credentials.mjs +8 -0
- package/dist/domain/url-credentials.mjs.map +1 -0
- package/dist/domain/warnings.cjs +23 -0
- package/dist/domain/warnings.cjs.map +1 -0
- package/dist/domain/warnings.mjs +20 -0
- package/dist/domain/warnings.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1182 -46
- package/dist/index.d.mts +1182 -46
- package/dist/index.d.ts +1182 -46
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/transform/components-object.cjs +2 -1
- package/dist/transform/components-object.cjs.map +1 -1
- package/dist/transform/components-object.mjs +2 -1
- package/dist/transform/components-object.mjs.map +1 -1
- package/dist/transform/path-item-object.cjs.map +1 -1
- package/dist/transform/path-item-object.mjs.map +1 -1
- package/package.json +6 -5
- package/src/adapters/redocly-loader/configured-headers.ts +65 -0
- package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +44 -13
- package/src/adapters/redocly-loader/ref-access.ts +60 -5
- package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
- package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
- package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
- package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
- package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +5 -1
- package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
- package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
- package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
- package/src/api/default-ports.ts +16 -0
- package/src/api/discriminator-conflict-warnings.ts +43 -0
- package/src/api/discriminator-enum-names.ts +26 -0
- package/src/api/discriminator-enum-parent.ts +129 -0
- package/src/api/discriminator-enum.ts +39 -0
- package/src/api/discriminator-other-owners.ts +97 -0
- package/src/api/discriminator-patch.ts +152 -0
- package/src/api/discriminator-scan.ts +78 -90
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +32 -11
- package/src/api/enum-values-warnings.ts +21 -0
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +7 -3
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +2 -0
- package/src/api/path-template-warnings.ts +27 -0
- package/src/api/run-context.ts +34 -0
- package/src/api/transform-context.ts +17 -9
- package/src/api/transform-schema.ts +90 -5
- package/src/api/unsupported-feature-warnings.ts +8 -1
- package/src/application/ports/redocly-config-source.ts +5 -1
- package/src/application/print/type-printer.ts +8 -1
- package/src/application/transform/document/assignability.ts +203 -0
- package/src/application/transform/document/components.ts +6 -6
- package/src/application/transform/document/declared-types.ts +93 -0
- package/src/application/transform/document/document.ts +71 -13
- package/src/application/transform/document/exploded-query.ts +91 -0
- package/src/application/transform/document/global-type-references.ts +78 -0
- package/src/application/transform/document/list-assignability.ts +87 -0
- package/src/application/transform/document/parameters.ts +78 -12
- package/src/application/transform/document/path-key-overlaps.ts +148 -59
- package/src/application/transform/document/path-template-replace.ts +90 -0
- package/src/application/transform/document/paths.ts +101 -38
- package/src/application/transform/document/root-type-aliases.ts +29 -28
- package/src/application/transform/document/template-key-match.ts +183 -0
- package/src/application/transform/document/type-assignability.ts +268 -0
- package/src/application/transform/document/type-key.ts +80 -0
- package/src/application/transform/document/type-resolution.ts +163 -0
- package/src/application/transform/footer/document-footer.ts +91 -6
- package/src/application/transform/footer/enum-naming.ts +29 -0
- package/src/application/transform/footer/enum-values-check.ts +171 -0
- package/src/application/transform/footer/evaluation.ts +57 -0
- package/src/application/transform/footer/shared-enum-names.ts +86 -0
- package/src/application/transform/footer/type-evaluation.ts +167 -0
- package/src/application/transform/footer/type-indexing.ts +152 -0
- package/src/application/transform/footer/type-rules.ts +269 -0
- package/src/application/transform/ref-pointer/generated-location.ts +211 -0
- package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
- package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
- package/src/application/transform/ref-pointer/original-index.ts +95 -0
- package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
- package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
- package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
- package/src/application/transform/ref-type.ts +11 -6
- package/src/application/transform/schema/access-flags.ts +63 -0
- package/src/application/transform/schema/array-type.ts +66 -5
- package/src/application/transform/schema/composition-type.ts +96 -24
- package/src/application/transform/schema/core-type.ts +8 -4
- package/src/application/transform/schema/discriminated-union.ts +58 -0
- package/src/application/transform/schema/discriminator-property.ts +8 -3
- package/src/application/transform/schema/enum-rule.ts +136 -13
- package/src/application/transform/schema/inherited-discriminator.ts +54 -0
- package/src/application/transform/schema/object-type.ts +51 -33
- package/src/application/transform/schema/required-variants.ts +88 -0
- package/src/application/transform/schema/schema-context.ts +26 -0
- package/src/application/transform/schema/schema-transform.ts +2 -2
- package/src/application/transform/schema-comment.ts +84 -4
- package/src/cli/api-settings.ts +109 -0
- package/src/cli/cli-arguments.ts +18 -5
- package/src/cli/cli-dependencies.ts +5 -0
- package/src/cli/cli-errors.ts +4 -2
- package/src/cli/cli-output.ts +18 -4
- package/src/cli/help-text.ts +4 -4
- package/src/cli/main.ts +6 -0
- package/src/cli/redocly-apis.ts +21 -11
- package/src/cli/ref-limits.ts +2 -2
- package/src/cli/run-cli.ts +25 -4
- package/src/domain/errors.ts +10 -2
- package/src/domain/ir/constructors.ts +9 -1
- package/src/domain/ir/nodes.ts +11 -7
- package/src/domain/openapi/admitted-values.ts +113 -0
- package/src/domain/openapi/discriminated-union.ts +109 -0
- package/src/domain/openapi/discriminator-conflicts.ts +251 -0
- package/src/domain/openapi/parameter-object.ts +4 -0
- package/src/domain/openapi/path-templates.ts +32 -0
- package/src/domain/openapi/schema-object.ts +2 -0
- package/src/domain/output-fixes.ts +43 -2
- package/src/domain/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +28 -0
- package/src/index.ts +1 -0
- package/src/transform/components-object.ts +3 -1
- package/src/transform/path-item-object.ts +6 -2
- package/src/types/generator-options.ts +12 -21
- package/src/types/openapi-common.ts +1 -0
- package/src/types/openapi-request.ts +3 -0
- package/src/types/openapi-schema.ts +2 -0
- package/src/types/openapi-security.ts +1 -0
- package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
- package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
- package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
- package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
- package/src/application/transform/document/path-item-conflicts.ts +0 -79
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assignability = require('./assignability.cjs');
|
|
4
|
+
|
|
5
|
+
const UNDEFINED = { kind: "keyword", keyword: "undefined" };
|
|
6
|
+
function elementType(element) {
|
|
7
|
+
if (element.isRest && element.type.kind === "array") {
|
|
8
|
+
return element.type.element;
|
|
9
|
+
}
|
|
10
|
+
return element.isOptional ? { kind: "union", types: [element.type, UNDEFINED] } : element.type;
|
|
11
|
+
}
|
|
12
|
+
function isRequired(element) {
|
|
13
|
+
return !element.isRest && !element.isOptional;
|
|
14
|
+
}
|
|
15
|
+
function arrayToTuple(target) {
|
|
16
|
+
return target.elements.some(isRequired) ? "rejected" : "undecided";
|
|
17
|
+
}
|
|
18
|
+
function relateTuples(source, target, relate) {
|
|
19
|
+
if (source.elements.length !== target.elements.length) {
|
|
20
|
+
const isFixed = source.elements.every(isRequired) && target.elements.every(isRequired);
|
|
21
|
+
return isFixed ? "rejected" : "undecided";
|
|
22
|
+
}
|
|
23
|
+
return assignability.everyOf(source.elements, (element, index) => {
|
|
24
|
+
const other = target.elements[index];
|
|
25
|
+
if (element.isRest !== other.isRest) {
|
|
26
|
+
return "undecided";
|
|
27
|
+
}
|
|
28
|
+
if (element.isOptional && !other.isOptional) {
|
|
29
|
+
return "rejected";
|
|
30
|
+
}
|
|
31
|
+
return relate(element.type, other.type);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function relateMutableLists(source, target, relate) {
|
|
35
|
+
if (source.kind === "array") {
|
|
36
|
+
return target.kind === "array" ? relate(source.element, target.element) : arrayToTuple(target);
|
|
37
|
+
}
|
|
38
|
+
if (target.kind === "array") {
|
|
39
|
+
return assignability.everyOf(source.elements, (element) => relate(elementType(element), target.element));
|
|
40
|
+
}
|
|
41
|
+
return relateTuples(source, target, relate);
|
|
42
|
+
}
|
|
43
|
+
function relateLists(source, target, relate) {
|
|
44
|
+
if (source.kind === "readonly") {
|
|
45
|
+
return target.kind === "readonly" ? relate(source.type, target.type) : "rejected";
|
|
46
|
+
}
|
|
47
|
+
if (target.kind === "readonly") {
|
|
48
|
+
return relate(source, target.type);
|
|
49
|
+
}
|
|
50
|
+
return relateMutableLists(source, target, relate);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
exports.relateLists = relateLists;
|
|
54
|
+
//# sourceMappingURL=list-assignability.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-assignability.cjs","sources":["../../../../src/application/transform/document/list-assignability.ts"],"sourcesContent":["import type {\n IrArrayType,\n IrReadonlyType,\n IrTupleElement,\n IrTupleType,\n IrType,\n} from \"../../../domain/ir/nodes.js\";\nimport { type Assignability, everyOf } from \"./assignability.js\";\n\n/**\n * How the `--path-params-as-types` overlap check relates two lists: arrays, tuples and their\n * `readonly` forms. `relate` compares two item types with the whole check.\n */\n\ntype Relate = (source: IrType, target: IrType) => Assignability;\n\n/** The types of the `list` category of `assignability.ts`. */\nexport type IrListType = IrArrayType | IrTupleType | IrReadonlyType;\n\ntype IrMutableListType = IrArrayType | IrTupleType;\n\nconst UNDEFINED: IrType = { kind: \"keyword\", keyword: \"undefined\" };\n\n/**\n * The type of a tuple element's items: a rest element `...T[]` stands for its items, and an\n * optional element `T?` may be `undefined` (`[string?]` is no `string[]` under `strict`).\n */\nfunction elementType(element: IrTupleElement): IrType {\n if (element.isRest && element.type.kind === \"array\") {\n return element.type.element;\n }\n return element.isOptional ? { kind: \"union\", types: [element.type, UNDEFINED] } : element.type;\n}\n\nfunction isRequired(element: IrTupleElement): boolean {\n return !element.isRest && !element.isOptional;\n}\n\n/** A tuple with a required element rejects an array, which may be empty. */\nfunction arrayToTuple(target: IrTupleType): Assignability {\n return target.elements.some(isRequired) ? \"rejected\" : \"undecided\";\n}\n\n/** Tuples of the same shape compare element by element; fixed lengths must be the same. */\nfunction relateTuples(source: IrTupleType, target: IrTupleType, relate: Relate): Assignability {\n if (source.elements.length !== target.elements.length) {\n const isFixed = source.elements.every(isRequired) && target.elements.every(isRequired);\n return isFixed ? \"rejected\" : \"undecided\";\n }\n return everyOf(source.elements, (element, index) => {\n const other = target.elements[index] as IrTupleElement;\n if (element.isRest !== other.isRest) {\n return \"undecided\";\n }\n // An optional element may be missing where the target requires one.\n if (element.isOptional && !other.isOptional) {\n return \"rejected\";\n }\n return relate(element.type, other.type);\n });\n}\n\nfunction relateMutableLists(\n source: IrMutableListType,\n target: IrMutableListType,\n relate: Relate,\n): Assignability {\n if (source.kind === \"array\") {\n return target.kind === \"array\" ? relate(source.element, target.element) : arrayToTuple(target);\n }\n if (target.kind === \"array\") {\n return everyOf(source.elements, (element) => relate(elementType(element), target.element));\n }\n return relateTuples(source, target, relate);\n}\n\n/** Whether one list type fits another. */\nexport function relateLists(source: IrListType, target: IrListType, relate: Relate): Assignability {\n if (source.kind === \"readonly\") {\n // A readonly array is no mutable array (TS4104); to a readonly target it is the same type.\n return target.kind === \"readonly\" ? relate(source.type, target.type) : \"rejected\";\n }\n if (target.kind === \"readonly\") {\n return relate(source, target.type);\n }\n return relateMutableLists(source, target, relate);\n}\n"],"names":["everyOf"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { everyOf } from './assignability.mjs';
|
|
2
|
+
|
|
3
|
+
const UNDEFINED = { kind: "keyword", keyword: "undefined" };
|
|
4
|
+
function elementType(element) {
|
|
5
|
+
if (element.isRest && element.type.kind === "array") {
|
|
6
|
+
return element.type.element;
|
|
7
|
+
}
|
|
8
|
+
return element.isOptional ? { kind: "union", types: [element.type, UNDEFINED] } : element.type;
|
|
9
|
+
}
|
|
10
|
+
function isRequired(element) {
|
|
11
|
+
return !element.isRest && !element.isOptional;
|
|
12
|
+
}
|
|
13
|
+
function arrayToTuple(target) {
|
|
14
|
+
return target.elements.some(isRequired) ? "rejected" : "undecided";
|
|
15
|
+
}
|
|
16
|
+
function relateTuples(source, target, relate) {
|
|
17
|
+
if (source.elements.length !== target.elements.length) {
|
|
18
|
+
const isFixed = source.elements.every(isRequired) && target.elements.every(isRequired);
|
|
19
|
+
return isFixed ? "rejected" : "undecided";
|
|
20
|
+
}
|
|
21
|
+
return everyOf(source.elements, (element, index) => {
|
|
22
|
+
const other = target.elements[index];
|
|
23
|
+
if (element.isRest !== other.isRest) {
|
|
24
|
+
return "undecided";
|
|
25
|
+
}
|
|
26
|
+
if (element.isOptional && !other.isOptional) {
|
|
27
|
+
return "rejected";
|
|
28
|
+
}
|
|
29
|
+
return relate(element.type, other.type);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function relateMutableLists(source, target, relate) {
|
|
33
|
+
if (source.kind === "array") {
|
|
34
|
+
return target.kind === "array" ? relate(source.element, target.element) : arrayToTuple(target);
|
|
35
|
+
}
|
|
36
|
+
if (target.kind === "array") {
|
|
37
|
+
return everyOf(source.elements, (element) => relate(elementType(element), target.element));
|
|
38
|
+
}
|
|
39
|
+
return relateTuples(source, target, relate);
|
|
40
|
+
}
|
|
41
|
+
function relateLists(source, target, relate) {
|
|
42
|
+
if (source.kind === "readonly") {
|
|
43
|
+
return target.kind === "readonly" ? relate(source.type, target.type) : "rejected";
|
|
44
|
+
}
|
|
45
|
+
if (target.kind === "readonly") {
|
|
46
|
+
return relate(source, target.type);
|
|
47
|
+
}
|
|
48
|
+
return relateMutableLists(source, target, relate);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { relateLists };
|
|
52
|
+
//# sourceMappingURL=list-assignability.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-assignability.mjs","sources":["../../../../src/application/transform/document/list-assignability.ts"],"sourcesContent":["import type {\n IrArrayType,\n IrReadonlyType,\n IrTupleElement,\n IrTupleType,\n IrType,\n} from \"../../../domain/ir/nodes.js\";\nimport { type Assignability, everyOf } from \"./assignability.js\";\n\n/**\n * How the `--path-params-as-types` overlap check relates two lists: arrays, tuples and their\n * `readonly` forms. `relate` compares two item types with the whole check.\n */\n\ntype Relate = (source: IrType, target: IrType) => Assignability;\n\n/** The types of the `list` category of `assignability.ts`. */\nexport type IrListType = IrArrayType | IrTupleType | IrReadonlyType;\n\ntype IrMutableListType = IrArrayType | IrTupleType;\n\nconst UNDEFINED: IrType = { kind: \"keyword\", keyword: \"undefined\" };\n\n/**\n * The type of a tuple element's items: a rest element `...T[]` stands for its items, and an\n * optional element `T?` may be `undefined` (`[string?]` is no `string[]` under `strict`).\n */\nfunction elementType(element: IrTupleElement): IrType {\n if (element.isRest && element.type.kind === \"array\") {\n return element.type.element;\n }\n return element.isOptional ? { kind: \"union\", types: [element.type, UNDEFINED] } : element.type;\n}\n\nfunction isRequired(element: IrTupleElement): boolean {\n return !element.isRest && !element.isOptional;\n}\n\n/** A tuple with a required element rejects an array, which may be empty. */\nfunction arrayToTuple(target: IrTupleType): Assignability {\n return target.elements.some(isRequired) ? \"rejected\" : \"undecided\";\n}\n\n/** Tuples of the same shape compare element by element; fixed lengths must be the same. */\nfunction relateTuples(source: IrTupleType, target: IrTupleType, relate: Relate): Assignability {\n if (source.elements.length !== target.elements.length) {\n const isFixed = source.elements.every(isRequired) && target.elements.every(isRequired);\n return isFixed ? \"rejected\" : \"undecided\";\n }\n return everyOf(source.elements, (element, index) => {\n const other = target.elements[index] as IrTupleElement;\n if (element.isRest !== other.isRest) {\n return \"undecided\";\n }\n // An optional element may be missing where the target requires one.\n if (element.isOptional && !other.isOptional) {\n return \"rejected\";\n }\n return relate(element.type, other.type);\n });\n}\n\nfunction relateMutableLists(\n source: IrMutableListType,\n target: IrMutableListType,\n relate: Relate,\n): Assignability {\n if (source.kind === \"array\") {\n return target.kind === \"array\" ? relate(source.element, target.element) : arrayToTuple(target);\n }\n if (target.kind === \"array\") {\n return everyOf(source.elements, (element) => relate(elementType(element), target.element));\n }\n return relateTuples(source, target, relate);\n}\n\n/** Whether one list type fits another. */\nexport function relateLists(source: IrListType, target: IrListType, relate: Relate): Assignability {\n if (source.kind === \"readonly\") {\n // A readonly array is no mutable array (TS4104); to a readonly target it is the same type.\n return target.kind === \"readonly\" ? relate(source.type, target.type) : \"rejected\";\n }\n if (target.kind === \"readonly\") {\n return relate(source, target.type);\n }\n return relateMutableLists(source, target, relate);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,11 +4,13 @@ const constructors = require('../../../domain/ir/constructors.cjs');
|
|
|
4
4
|
const propertyName = require('../../../domain/ir/property-name.cjs');
|
|
5
5
|
const jsonPointer = require('../../../domain/openapi/json-pointer.cjs');
|
|
6
6
|
const parameterObject = require('../../../domain/openapi/parameter-object.cjs');
|
|
7
|
+
const outputFixes = require('../../../domain/output-fixes.cjs');
|
|
7
8
|
const refType = require('../ref-type.cjs');
|
|
8
9
|
const schemaComment = require('../schema-comment.cjs');
|
|
10
|
+
const explodedQuery = require('./exploded-query.cjs');
|
|
9
11
|
const parameter = require('./parameter.cjs');
|
|
10
12
|
|
|
11
|
-
const PATH_TEMPLATE_RE = /\{([^}]+)\}/g;
|
|
13
|
+
const PATH_TEMPLATE_RE = /\{([^{}]+)\}/g;
|
|
12
14
|
function resolveParameter(parameter, context) {
|
|
13
15
|
return "$ref" in parameter ? context.refs.resolve(parameter.$ref) : parameter;
|
|
14
16
|
}
|
|
@@ -85,16 +87,46 @@ function querystringMember(entries, location, context) {
|
|
|
85
87
|
});
|
|
86
88
|
return schemaComment.withSchemaComment(property, querystring.resolved);
|
|
87
89
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
function isExplodedEntry(entry, context) {
|
|
91
|
+
return context.options.fixes.has(outputFixes.OutputFix.EXPLODED_QUERY_OBJECTS) && explodedQuery.isExplodedQueryObject(entry.resolved, context.refs);
|
|
92
|
+
}
|
|
93
|
+
function explodedPart(entry, location, context) {
|
|
94
|
+
const type = entryType(entry, location, context);
|
|
95
|
+
return entry.resolved.required ? type : constructors.irReference("Partial", [type]);
|
|
96
|
+
}
|
|
97
|
+
function locationParts(entries, location, context) {
|
|
98
|
+
const members = [];
|
|
99
|
+
const exploded = [];
|
|
100
|
+
let isOptional = true;
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
if (isExplodedEntry(entry, context)) {
|
|
103
|
+
exploded.push(explodedPart(entry, location, context));
|
|
104
|
+
isOptional &&= !entry.resolved.required;
|
|
105
|
+
continue;
|
|
96
106
|
}
|
|
107
|
+
const member = parameterMember(entry, location, context);
|
|
108
|
+
members.push(member);
|
|
109
|
+
isOptional &&= member.isOptional;
|
|
110
|
+
}
|
|
111
|
+
return { members, exploded, isOptional };
|
|
112
|
+
}
|
|
113
|
+
function locationType({ members, exploded }) {
|
|
114
|
+
const types = [...members.length > 0 ? [constructors.irObject(members)] : [], ...exploded];
|
|
115
|
+
const [first] = types;
|
|
116
|
+
if (first === void 0) {
|
|
117
|
+
return constructors.irKeyword("never");
|
|
118
|
+
}
|
|
119
|
+
return types.length === 1 ? first : constructors.irIntersection(types);
|
|
120
|
+
}
|
|
121
|
+
function locationMember(parameterIn, entries, location, context) {
|
|
122
|
+
const located = entries.filter(
|
|
123
|
+
(entry) => entry.resolved?.in === parameterIn
|
|
97
124
|
);
|
|
125
|
+
const parts = locationParts(located, location, context);
|
|
126
|
+
return constructors.irProperty(propertyName.toPropertyName(parameterIn), locationType(parts), {
|
|
127
|
+
isOptional: parts.isOptional,
|
|
128
|
+
isReadonly: context.options.immutable
|
|
129
|
+
});
|
|
98
130
|
}
|
|
99
131
|
function parametersMember(parameters, location, context) {
|
|
100
132
|
const entries = parameterEntries(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parameters.cjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { parameterType } from \"./parameter.js\";\n\nconst PATH_TEMPLATE_RE = /\\{([^}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const members = entries\n .filter((entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn)\n .map((entry) => parameterMember(entry, location, context));\n return irProperty(\n toPropertyName(parameterIn),\n members.length > 0 ? irObject(members) : irKeyword(\"never\"),\n {\n isOptional: members.every((member) => member.isOptional),\n isReadonly: context.options.immutable,\n },\n );\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":["toPropertyName","refType","createRef","parameterType","irProperty","withSchemaComment","QUERYSTRING_LOCATION","irObject","irKeyword","PARAMETER_LOCATIONS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parameters.cjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":["toPropertyName","refType","createRef","parameterType","irProperty","withSchemaComment","QUERYSTRING_LOCATION","OutputFix","isExplodedQueryObject","irReference","irObject","irKeyword","irIntersection","PARAMETER_LOCATIONS"],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { irProperty, irObject, irKeyword } from '../../../domain/ir/constructors.mjs';
|
|
1
|
+
import { irProperty, irObject, irKeyword, irIntersection, irReference } from '../../../domain/ir/constructors.mjs';
|
|
2
2
|
import { toPropertyName } from '../../../domain/ir/property-name.mjs';
|
|
3
3
|
import { createRef } from '../../../domain/openapi/json-pointer.mjs';
|
|
4
4
|
import { PARAMETER_LOCATIONS, QUERYSTRING_LOCATION } from '../../../domain/openapi/parameter-object.mjs';
|
|
5
|
+
import { OutputFix } from '../../../domain/output-fixes.mjs';
|
|
5
6
|
import { refType } from '../ref-type.mjs';
|
|
6
7
|
import { withSchemaComment } from '../schema-comment.mjs';
|
|
8
|
+
import { isExplodedQueryObject } from './exploded-query.mjs';
|
|
7
9
|
import { parameterType } from './parameter.mjs';
|
|
8
10
|
|
|
9
|
-
const PATH_TEMPLATE_RE = /\{([^}]+)\}/g;
|
|
11
|
+
const PATH_TEMPLATE_RE = /\{([^{}]+)\}/g;
|
|
10
12
|
function resolveParameter(parameter, context) {
|
|
11
13
|
return "$ref" in parameter ? context.refs.resolve(parameter.$ref) : parameter;
|
|
12
14
|
}
|
|
@@ -83,16 +85,46 @@ function querystringMember(entries, location, context) {
|
|
|
83
85
|
});
|
|
84
86
|
return withSchemaComment(property, querystring.resolved);
|
|
85
87
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
function isExplodedEntry(entry, context) {
|
|
89
|
+
return context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) && isExplodedQueryObject(entry.resolved, context.refs);
|
|
90
|
+
}
|
|
91
|
+
function explodedPart(entry, location, context) {
|
|
92
|
+
const type = entryType(entry, location, context);
|
|
93
|
+
return entry.resolved.required ? type : irReference("Partial", [type]);
|
|
94
|
+
}
|
|
95
|
+
function locationParts(entries, location, context) {
|
|
96
|
+
const members = [];
|
|
97
|
+
const exploded = [];
|
|
98
|
+
let isOptional = true;
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
if (isExplodedEntry(entry, context)) {
|
|
101
|
+
exploded.push(explodedPart(entry, location, context));
|
|
102
|
+
isOptional &&= !entry.resolved.required;
|
|
103
|
+
continue;
|
|
94
104
|
}
|
|
105
|
+
const member = parameterMember(entry, location, context);
|
|
106
|
+
members.push(member);
|
|
107
|
+
isOptional &&= member.isOptional;
|
|
108
|
+
}
|
|
109
|
+
return { members, exploded, isOptional };
|
|
110
|
+
}
|
|
111
|
+
function locationType({ members, exploded }) {
|
|
112
|
+
const types = [...members.length > 0 ? [irObject(members)] : [], ...exploded];
|
|
113
|
+
const [first] = types;
|
|
114
|
+
if (first === void 0) {
|
|
115
|
+
return irKeyword("never");
|
|
116
|
+
}
|
|
117
|
+
return types.length === 1 ? first : irIntersection(types);
|
|
118
|
+
}
|
|
119
|
+
function locationMember(parameterIn, entries, location, context) {
|
|
120
|
+
const located = entries.filter(
|
|
121
|
+
(entry) => entry.resolved?.in === parameterIn
|
|
95
122
|
);
|
|
123
|
+
const parts = locationParts(located, location, context);
|
|
124
|
+
return irProperty(toPropertyName(parameterIn), locationType(parts), {
|
|
125
|
+
isOptional: parts.isOptional,
|
|
126
|
+
isReadonly: context.options.immutable
|
|
127
|
+
});
|
|
96
128
|
}
|
|
97
129
|
function parametersMember(parameters, location, context) {
|
|
98
130
|
const entries = parameterEntries(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parameters.mjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { parameterType } from \"./parameter.js\";\n\nconst PATH_TEMPLATE_RE = /\\{([^}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const members = entries\n .filter((entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn)\n .map((entry) => parameterMember(entry, location, context));\n return irProperty(\n toPropertyName(parameterIn),\n members.length > 0 ? irObject(members) : irKeyword(\"never\"),\n {\n isOptional: members.every((member) => member.isOptional),\n isReadonly: context.options.immutable,\n },\n );\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parameters.mjs","sources":["../../../../src/application/transform/document/parameters.ts"],"sourcesContent":["import {\n irIntersection,\n irKeyword,\n irObject,\n irProperty,\n irReference,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrPropertyName, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport {\n PARAMETER_LOCATIONS,\n type ParameterLocation,\n type ParameterObject,\n type ParameterOrReference,\n QUERYSTRING_LOCATION,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport type { SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { isExplodedQueryObject } from \"./exploded-query.js\";\nimport { parameterType } from \"./parameter.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_TEMPLATE_RE = /\\{([^{}]+)\\}/g;\n\n/** A parameter as written in the document, and the object its `$ref` points to. */\ninterface ParameterEntry {\n readonly original: ParameterOrReference;\n readonly resolved: ParameterObject | undefined;\n}\n\n/** An entry whose `$ref` resolved, so its location and name are known. */\ntype ResolvedEntry = ParameterEntry & { readonly resolved: ParameterObject };\n\nfunction resolveParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : parameter;\n}\n\n/** Required string parameters for every `{name}` in a path template. */\nfunction pathTemplateParameters(path: string): ParameterObject[] {\n return (path.match(PATH_TEMPLATE_RE) ?? []).map((match) => ({\n name: match.slice(1, -1),\n in: \"path\",\n required: true,\n schema: { type: \"string\" },\n }));\n}\n\n/** `--generate-path-params`: add the path template parameters the list does not define. */\nfunction withPathTemplateParameters(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): ParameterOrReference[] {\n const result = [...parameters];\n if (!context.options.generatePathParams || !location.path) {\n return result;\n }\n for (const parameter of pathTemplateParameters(location.path)) {\n const isDefined = result.some((candidate) => {\n const resolved = resolveParameter(candidate, context);\n return resolved?.in === \"path\" && resolved.name === parameter.name;\n });\n if (!isDefined) {\n result.push(parameter);\n }\n }\n return result;\n}\n\nfunction isDeprecatedParameter(parameter: ParameterObject | undefined): boolean {\n const schema = parameter?.schema as SchemaObject | undefined;\n return Boolean(parameter?.deprecated || schema?.deprecated);\n}\n\n/** Resolved parameters, sorted for `--alphabetize`, without deprecated ones if excluded. */\nfunction parameterEntries(\n parameters: readonly ParameterOrReference[],\n context: TransformContext,\n): ParameterEntry[] {\n const entries = parameters.map((original) => ({\n original,\n resolved: resolveParameter(original, context),\n }));\n if (context.options.alphabetize) {\n // Unlike map keys, the original sorts parameters with the default locale's `localeCompare`.\n entries.sort((left, right) =>\n (left.resolved?.name ?? \"\").localeCompare(right.resolved?.name ?? \"\"),\n );\n }\n return context.options.excludeDeprecated\n ? entries.filter(({ resolved }) => !isDeprecatedParameter(resolved))\n : entries;\n}\n\n/** The original quotes a name that is not text (a missing name prints as `\"undefined\"`). */\nfunction parameterName(name: unknown): IrPropertyName {\n return typeof name === \"string\" || typeof name === \"number\"\n ? toPropertyName(name)\n : { kind: \"string\", value: String(name) };\n}\n\nfunction referencedParameterType(ref: string, resolved: ParameterObject): IrType {\n // A `$ref` that resolves to another `$ref` is not a parameter object yet: index it as a path.\n const isParameter = !(resolved as { $ref?: unknown }).$ref;\n const parameter = isParameter ? { in: resolved.in, name: resolved.name } : null;\n return refType(ref, { parameter });\n}\n\nfunction entryType(\n { original, resolved }: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const path = createRef([location.path, \"parameters\", resolved.in, resolved.name]);\n return \"$ref\" in original\n ? referencedParameterType(original.$ref, resolved)\n : parameterType(resolved, { ...location, path }, context);\n}\n\nfunction parameterMember(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const { resolved } = entry;\n const property = irProperty(parameterName(resolved.name), entryType(entry, location, context), {\n isOptional: resolved.in !== \"path\" && !resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, resolved);\n}\n\n/**\n * The `query` member typed by an `in: querystring` parameter (OpenAPI 3.2, ADR-020): the parameter\n * is the whole query string. Null when there is none, or when `in: query` parameters sit next to\n * it, which 3.2 does not allow; those keep their types, and a warning names the parameter.\n */\nfunction querystringMember(\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature | null {\n const querystring = entries.find(\n (entry): entry is ResolvedEntry => entry.resolved?.in === QUERYSTRING_LOCATION,\n );\n if (!querystring || entries.some((entry) => entry.resolved?.in === \"query\")) {\n return null;\n }\n const property = irProperty(toPropertyName(\"query\"), entryType(querystring, location, context), {\n isOptional: !querystring.resolved.required,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, querystring.resolved);\n}\n\n/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */\nfunction isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {\n return (\n context.options.fixes.has(OutputFix.EXPLODED_QUERY_OBJECTS) &&\n isExplodedQueryObject(entry.resolved, context.refs)\n );\n}\n\n/**\n * An exploded object parameter's part of `query`: its object type. A parameter that may be left\n * out sends none of its keys then, so they are optional: `Partial<…>`.\n */\nfunction explodedPart(\n entry: ResolvedEntry,\n location: SchemaLocation,\n context: TransformContext,\n): IrType {\n const type = entryType(entry, location, context);\n return entry.resolved.required ? type : irReference(\"Partial\", [type]);\n}\n\n/** A location's parameters as members, and the object types of its exploded parameters. */\ninterface LocationParts {\n readonly members: readonly IrPropertySignature[];\n readonly exploded: readonly IrType[];\n readonly isOptional: boolean;\n}\n\n/** Each parameter in document order, so the declarations they add keep their order. */\nfunction locationParts(\n entries: readonly ResolvedEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): LocationParts {\n const members: IrPropertySignature[] = [];\n const exploded: IrType[] = [];\n let isOptional = true;\n for (const entry of entries) {\n if (isExplodedEntry(entry, context)) {\n exploded.push(explodedPart(entry, location, context));\n isOptional &&= !entry.resolved.required;\n continue;\n }\n const member = parameterMember(entry, location, context);\n members.push(member);\n isOptional &&= member.isOptional;\n }\n return { members, exploded, isOptional };\n}\n\n/** The members' object, intersected with the exploded parameters' types; `never` for none. */\nfunction locationType({ members, exploded }: LocationParts): IrType {\n const types = [...(members.length > 0 ? [irObject(members)] : []), ...exploded];\n const [first] = types;\n if (first === undefined) {\n return irKeyword(\"never\");\n }\n return types.length === 1 ? first : irIntersection(types);\n}\n\n/** One location's parameters; optional when all of them are, and `never` when there are none. */\nfunction locationMember(\n parameterIn: ParameterLocation,\n entries: readonly ParameterEntry[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const located = entries.filter(\n (entry): entry is ResolvedEntry => entry.resolved?.in === parameterIn,\n );\n const parts = locationParts(located, location, context);\n return irProperty(toPropertyName(parameterIn), locationType(parts), {\n isOptional: parts.isOptional,\n isReadonly: context.options.immutable,\n });\n}\n\n/**\n * The `parameters` property of an operation or path item: one member per location, each an object\n * of that location's parameters. `location.path` is the path template for\n * `--generate-path-params`.\n */\nexport function parametersMember(\n parameters: readonly ParameterOrReference[],\n location: SchemaLocation,\n context: TransformContext,\n): IrPropertySignature {\n const entries = parameterEntries(\n withPathTemplateParameters(parameters, location, context),\n context,\n );\n const querystring = querystringMember(entries, location, context);\n const members = PARAMETER_LOCATIONS.map((parameterIn) =>\n parameterIn === \"query\" && querystring\n ? querystring\n : locationMember(parameterIn, entries, location, context),\n );\n return irProperty(toPropertyName(\"parameters\"), irObject(members), {\n isReadonly: context.options.immutable,\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +1,100 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const templateKeyMatch = require('./template-key-match.cjs');
|
|
4
|
+
|
|
3
5
|
const BOOLEAN_TEXTS = ["true", "false"];
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return
|
|
15
|
-
}
|
|
16
|
-
return type === "boolean" ? BOOLEAN_TEXTS.includes(text) : true;
|
|
6
|
+
function withPart(shapes, part) {
|
|
7
|
+
return shapes.flatMap((shape) => {
|
|
8
|
+
const lead = shape.texts.slice(0, -1);
|
|
9
|
+
const last = shape.texts[shape.texts.length - 1];
|
|
10
|
+
if (part.kind === "text") {
|
|
11
|
+
return [{ texts: [...lead, last + part.text], types: shape.types }];
|
|
12
|
+
}
|
|
13
|
+
if (part.type === "boolean") {
|
|
14
|
+
return BOOLEAN_TEXTS.map((text) => ({ texts: [...lead, last + text], types: shape.types }));
|
|
15
|
+
}
|
|
16
|
+
return [{ texts: [...shape.texts, ""], types: [...shape.types, part.type] }];
|
|
17
|
+
});
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return start === text.length;
|
|
22
|
-
}
|
|
23
|
-
if (part.kind === "text") {
|
|
24
|
-
return text.startsWith(part.text, start) && matchesFrom(text, start + part.text.length, parts, index + 1);
|
|
19
|
+
function shapesOf(key) {
|
|
20
|
+
if (key.kind === "literal") {
|
|
21
|
+
return [{ texts: [key.url], types: [] }];
|
|
25
22
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
return key.parts.reduce(withPart, [{ texts: [""], types: [] }]);
|
|
24
|
+
}
|
|
25
|
+
function isCoveredBy(sources, targets) {
|
|
26
|
+
return sources.length > 0 && sources.every((source) => targets.some((target) => templateKeyMatch.isAssignableToTemplate(source, target)));
|
|
27
|
+
}
|
|
28
|
+
const EVERY_COVER_REJECTED = () => true;
|
|
29
|
+
function checkedShapes(key) {
|
|
30
|
+
const shapes = shapesOf(key);
|
|
31
|
+
return key.kind === "literal" ? shapes : shapes.filter((shape) => shape.types.length > 0);
|
|
32
|
+
}
|
|
33
|
+
function checkedKeyOf(key) {
|
|
34
|
+
const template = key.kind === "template" ? JSON.stringify(shapesOf(key)) : null;
|
|
35
|
+
return { key, shapes: checkedShapes(key), template };
|
|
36
|
+
}
|
|
37
|
+
function repeatedTemplates(checked) {
|
|
38
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39
|
+
const repeated = /* @__PURE__ */ new Set();
|
|
40
|
+
for (const { template } of checked) {
|
|
41
|
+
if (template !== null) {
|
|
42
|
+
(seen.has(template) ? repeated : seen).add(template);
|
|
29
43
|
}
|
|
30
44
|
}
|
|
31
|
-
return
|
|
45
|
+
return repeated;
|
|
32
46
|
}
|
|
33
|
-
function
|
|
34
|
-
if (
|
|
35
|
-
return
|
|
47
|
+
function compareCodeUnits(left, right) {
|
|
48
|
+
if (left === right) {
|
|
49
|
+
return 0;
|
|
36
50
|
}
|
|
37
|
-
return
|
|
51
|
+
return left < right ? -1 : 1;
|
|
52
|
+
}
|
|
53
|
+
function startTextIndexOf(checked) {
|
|
54
|
+
const entries = checked.flatMap(
|
|
55
|
+
({ shapes }, keyIndex) => shapes.map((shape) => ({ start: shape.texts[0], keyIndex }))
|
|
56
|
+
);
|
|
57
|
+
entries.sort((left, right) => compareCodeUnits(left.start, right.start));
|
|
58
|
+
return {
|
|
59
|
+
starts: entries.map((entry) => entry.start),
|
|
60
|
+
keyIndexes: entries.map((entry) => entry.keyIndex)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function keysStartingWith(index, prefixes) {
|
|
64
|
+
const found = /* @__PURE__ */ new Set();
|
|
65
|
+
for (const prefix of prefixes) {
|
|
66
|
+
let low = 0;
|
|
67
|
+
let high = index.starts.length;
|
|
68
|
+
while (low < high) {
|
|
69
|
+
const middle = low + high >> 1;
|
|
70
|
+
if (index.starts[middle] < prefix) {
|
|
71
|
+
low = middle + 1;
|
|
72
|
+
} else {
|
|
73
|
+
high = middle;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for (let at = low; at < index.starts.length; at += 1) {
|
|
77
|
+
if (!index.starts[at].startsWith(prefix)) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
found.add(index.keyIndexes[at]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return found;
|
|
38
84
|
}
|
|
39
|
-
const EVERY_COVER_REJECTED = () => true;
|
|
40
85
|
function coveringTemplateKeys(keys, isRejected = EVERY_COVER_REJECTED) {
|
|
86
|
+
const checked = keys.map(checkedKeyOf);
|
|
87
|
+
const repeated = repeatedTemplates(checked);
|
|
88
|
+
const startTexts = startTextIndexOf(checked);
|
|
41
89
|
const covering = /* @__PURE__ */ new Set();
|
|
42
|
-
|
|
43
|
-
if (
|
|
90
|
+
checked.forEach(({ template, shapes: targets }, index) => {
|
|
91
|
+
if (template === null) {
|
|
44
92
|
return;
|
|
45
93
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
94
|
+
const prefixes = targets.map((target) => target.texts[0]);
|
|
95
|
+
const candidates = [...keysStartingWith(startTexts, prefixes)].sort((a, b) => a - b);
|
|
96
|
+
const isCovering = repeated.has(template) || candidates.some(
|
|
97
|
+
(otherIndex) => otherIndex !== index && isCoveredBy(checked[otherIndex].shapes, targets) && isRejected(index, otherIndex)
|
|
48
98
|
);
|
|
49
99
|
if (isCovering) {
|
|
50
100
|
covering.add(index);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-key-overlaps.cjs","sources":["../../../../src/application/transform/document/path-key-overlaps.ts"],"sourcesContent":["/**\n * `--path-params-as-types` overlaps (roadmap R10.2, backlog 28). A path key with parameters is an\n * index signature over a template literal type, such as `` `/apps/${string}` ``. `${string}` also\n * matches `/`, so that signature covers `/apps/regions` and `` `/apps/${string}/restart` `` as\n * well, and TypeScript requires the covered keys' types to be assignable to its type (TS2411,\n * TS2413). These functions find the signatures that cover another key the checker rejects.\n */\n\n/** A placeholder of a template literal type, by the type it stands for. */\nexport type PathPlaceholder = \"string\" | \"number\" | \"boolean\";\n\n/** One part of a path key: text, or a placeholder. */\nexport type PathKeyPart =\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"placeholder\"; readonly type: PathPlaceholder };\n\n/** A path key: a URL written as a property, or a template literal type of an index signature. */\nexport type PathKey =\n | { readonly kind: \"literal\"; readonly url: string }\n | { readonly kind: \"template\"; readonly parts: readonly PathKeyPart[] };\n\nconst BOOLEAN_TEXTS: readonly string[] = [\"true\", \"false\"];\n\n/** The text one placeholder stands for in a sample of a template key. */\nconst SAMPLE_TEXTS: Readonly<Record<PathPlaceholder, string>> = {\n string: \"\",\n number: \"0\",\n boolean: \"true\",\n};\n\n/** TypeScript's rule for `${number}`: a text that converts to a finite number. */\nfunction isNumberText(text: string): boolean {\n return text !== \"\" && Number.isFinite(Number(text));\n}\n\nfunction isPlaceholderText(type: PathPlaceholder, text: string): boolean {\n if (type === \"number\") {\n return isNumberText(text);\n }\n return type === \"boolean\" ? BOOLEAN_TEXTS.includes(text) : true;\n}\n\n/** Whether `text` from `start` on is one of the strings the parts from `index` on describe. */\nfunction matchesFrom(\n text: string,\n start: number,\n parts: readonly PathKeyPart[],\n index: number,\n): boolean {\n const part = parts[index];\n if (part === undefined) {\n return start === text.length;\n }\n if (part.kind === \"text\") {\n return (\n text.startsWith(part.text, start) &&\n matchesFrom(text, start + part.text.length, parts, index + 1)\n );\n }\n for (let end = start; end <= text.length; end += 1) {\n if (\n isPlaceholderText(part.type, text.slice(start, end)) &&\n matchesFrom(text, end, parts, index + 1)\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * One string of the key. If a template key is covered, every string of it is, so a sample that is\n * not covered proves the key is not; a sample that is covered may over-report, which only moves a\n * signature that did not need it (the types stay the same, see `pathsObjectType`).\n */\nfunction sampleOf(key: PathKey): string {\n if (key.kind === \"literal\") {\n return key.url;\n }\n return key.parts\n .map((part) => (part.kind === \"text\" ? part.text : SAMPLE_TEXTS[part.type]))\n .join(\"\");\n}\n\n/** Whether TypeScript rejects the key at `covered` for the signature at `covering`. */\nexport type CoverRejection = (covering: number, covered: number) => boolean;\n\n/** Without type information every covered key counts. */\nconst EVERY_COVER_REJECTED: CoverRejection = () => true;\n\n/** The indexes of the template keys that cover another key of the list, where it is rejected. */\nexport function coveringTemplateKeys(\n keys: readonly PathKey[],\n isRejected: CoverRejection = EVERY_COVER_REJECTED,\n): ReadonlySet<number> {\n const covering = new Set<number>();\n keys.forEach((key, index) => {\n if (key.kind !== \"template\") {\n return;\n }\n const isCovering = keys.some(\n (other, otherIndex) =>\n otherIndex !== index &&\n matchesFrom(sampleOf(other), 0, key.parts, 0) &&\n isRejected(index, otherIndex),\n );\n if (isCovering) {\n covering.add(index);\n }\n });\n return covering;\n}\n"],"names":[],"mappings":";;AAqBA,MAAM,aAAA,GAAmC,CAAC,MAAA,EAAQ,OAAO,CAAA;AAGzD,MAAM,YAAA,GAA0D;AAAA,EAC9D,MAAA,EAAQ,EAAA;AAAA,EACR,MAAA,EAAQ,GAAA;AAAA,EACR,OAAA,EAAS;AACX,CAAA;AAGA,SAAS,aAAa,IAAA,EAAuB;AAC3C,EAAA,OAAO,SAAS,EAAA,IAAM,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,IAAI,CAAC,CAAA;AACpD;AAEA,SAAS,iBAAA,CAAkB,MAAuB,IAAA,EAAuB;AACvE,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,OAAO,aAAa,IAAI,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,IAAA,KAAS,SAAA,GAAY,aAAA,CAAc,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA;AAC7D;AAGA,SAAS,WAAA,CACP,IAAA,EACA,KAAA,EACA,KAAA,EACA,KAAA,EACS;AACT,EAAA,MAAM,IAAA,GAAO,MAAM,KAAK,CAAA;AACxB,EAAA,IAAI,SAAS,MAAA,EAAW;AACtB,IAAA,OAAO,UAAU,IAAA,CAAK,MAAA;AAAA,EACxB;AACA,EAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AACxB,IAAA,OACE,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,IAAA,EAAM,KAAK,CAAA,IAChC,WAAA,CAAY,IAAA,EAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAC,CAAA;AAAA,EAEhE;AACA,EAAA,KAAA,IAAS,MAAM,KAAA,EAAO,GAAA,IAAO,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,IACE,iBAAA,CAAkB,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,MAAM,KAAA,EAAO,GAAG,CAAC,CAAA,IACnD,YAAY,IAAA,EAAM,GAAA,EAAK,KAAA,EAAO,KAAA,GAAQ,CAAC,CAAA,EACvC;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAOA,SAAS,SAAS,GAAA,EAAsB;AACtC,EAAA,IAAI,GAAA,CAAI,SAAS,SAAA,EAAW;AAC1B,IAAA,OAAO,GAAA,CAAI,GAAA;AAAA,EACb;AACA,EAAA,OAAO,IAAI,KAAA,CACR,GAAA,CAAI,CAAC,IAAA,KAAU,KAAK,IAAA,KAAS,MAAA,GAAS,IAAA,CAAK,IAAA,GAAO,aAAa,IAAA,CAAK,IAAI,CAAE,CAAA,CAC1E,KAAK,EAAE,CAAA;AACZ;AAMA,MAAM,uBAAuC,MAAM,IAAA;AAG5C,SAAS,oBAAA,CACd,IAAA,EACA,UAAA,GAA6B,oBAAA,EACR;AACrB,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,EAAK,KAAA,KAAU;AAC3B,IAAA,IAAI,GAAA,CAAI,SAAS,UAAA,EAAY;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,aAAa,IAAA,CAAK,IAAA;AAAA,MACtB,CAAC,KAAA,EAAO,UAAA,KACN,UAAA,KAAe,KAAA,IACf,YAAY,QAAA,CAAS,KAAK,CAAA,EAAG,CAAA,EAAG,IAAI,KAAA,EAAO,CAAC,CAAA,IAC5C,UAAA,CAAW,OAAO,UAAU;AAAA,KAChC;AACA,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,QAAA,CAAS,IAAI,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,QAAA;AACT;;"}
|
|
1
|
+
{"version":3,"file":"path-key-overlaps.cjs","sources":["../../../../src/application/transform/document/path-key-overlaps.ts"],"sourcesContent":["/**\n * `--path-params-as-types` overlaps (roadmap R10.2, backlog 28). A path key with parameters is an\n * index signature over a template literal type, such as `` `/apps/${string}` ``. `${string}` also\n * matches `/`, so that signature covers `/apps/regions` and `` `/apps/${string}/restart` `` as\n * well, and TypeScript requires the covered keys' types to be assignable to its type (TS2411,\n * TS2413). These functions find the signatures that cover another key the checker rejects.\n */\n\nimport { isAssignableToTemplate, type TemplateShape } from \"./template-key-match.js\";\n\n/** A placeholder of a template literal type, by the type it stands for. */\nexport type PathPlaceholder = \"string\" | \"number\" | \"boolean\";\n\n/** One part of a path key: text, or a placeholder. */\nexport type PathKeyPart =\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"placeholder\"; readonly type: PathPlaceholder };\n\n/** A path key: a URL written as a property, or a template literal type of an index signature. */\nexport type PathKey =\n | { readonly kind: \"literal\"; readonly url: string }\n | { readonly kind: \"template\"; readonly parts: readonly PathKeyPart[] };\n\nconst BOOLEAN_TEXTS: readonly string[] = [\"true\", \"false\"];\n\n/** The shapes after one more part; a boolean placeholder doubles them, as TypeScript does. */\nfunction withPart(shapes: readonly TemplateShape[], part: PathKeyPart): TemplateShape[] {\n return shapes.flatMap((shape): TemplateShape[] => {\n const lead = shape.texts.slice(0, -1);\n // A shape has one text more than it has placeholders, so it always has a last text.\n const last = shape.texts[shape.texts.length - 1] as string;\n if (part.kind === \"text\") {\n return [{ texts: [...lead, last + part.text], types: shape.types }];\n }\n if (part.type === \"boolean\") {\n return BOOLEAN_TEXTS.map((text) => ({ texts: [...lead, last + text], types: shape.types }));\n }\n return [{ texts: [...shape.texts, \"\"], types: [...shape.types, part.type] }];\n });\n}\n\n/**\n * The key types TypeScript makes of a key: a literal is one text; a template is one shape, or a\n * union of shapes when `${boolean}` is in it (`` `/a/${boolean}` `` is `\"/a/true\" | \"/a/false\"`).\n */\nfunction shapesOf(key: PathKey): readonly TemplateShape[] {\n if (key.kind === \"literal\") {\n return [{ texts: [key.url], types: [] }];\n }\n return key.parts.reduce<TemplateShape[]>(withPart, [{ texts: [\"\"], types: [] }]);\n}\n\n/**\n * Whether a signature checks the covered key: every type of the covered key is assignable to one\n * of the signature's types. A shape without placeholders (a boolean-only template) is a string\n * literal, which is no signature, so the targets leave it out.\n */\nfunction isCoveredBy(\n sources: readonly TemplateShape[],\n targets: readonly TemplateShape[],\n): boolean {\n return (\n sources.length > 0 &&\n sources.every((source) => targets.some((target) => isAssignableToTemplate(source, target)))\n );\n}\n\n/** Whether TypeScript rejects the key at `covered` for the signature at `covering`. */\nexport type CoverRejection = (covering: number, covered: number) => boolean;\n\n/** Without type information every covered key counts. */\nconst EVERY_COVER_REJECTED: CoverRejection = () => true;\n\n/**\n * The key types TypeScript checks against a signature: a literal's, or a template's signature\n * types. A boolean-only template is no signature (TS1337), so the checker neither checks it nor\n * checks anything against it; a repeated one is still reported (TS2374, see `repeatedTemplates`).\n */\nfunction checkedShapes(key: PathKey): readonly TemplateShape[] {\n const shapes = shapesOf(key);\n return key.kind === \"literal\" ? shapes : shapes.filter((shape) => shape.types.length > 0);\n}\n\n/** A checked key: the key, the shapes TypeScript checks, and its template identity. */\ninterface CheckedKey {\n readonly key: PathKey;\n readonly shapes: readonly TemplateShape[];\n /** The key types written as one string, for templates; null for a literal. */\n readonly template: string | null;\n}\n\nfunction checkedKeyOf(key: PathKey): CheckedKey {\n const template = key.kind === \"template\" ? JSON.stringify(shapesOf(key)) : null;\n return { key, shapes: checkedShapes(key), template };\n}\n\n/**\n * The templates written more than once, as paths that differ only in parameter names give\n * (`/a/{id}`, `/a/{name}`). OpenAPI forbids such paths, and one object with both signatures fails\n * to compile whatever their types (TS2374), so each always counts as covering the other.\n */\nfunction repeatedTemplates(checked: readonly CheckedKey[]): ReadonlySet<string> {\n const seen = new Set<string>();\n const repeated = new Set<string>();\n for (const { template } of checked) {\n if (template !== null) {\n (seen.has(template) ? repeated : seen).add(template);\n }\n }\n return repeated;\n}\n\n/**\n * The checked keys by the first text of each of their shapes, sorted. A key type is assignable to\n * a template only when its first text starts with the template's first text (both branches of\n * `isAssignableToTemplate`), so the keys a template can cover are one run of this list. Without\n * it the check compares every pair of keys, which takes minutes for 10 000 paths.\n */\ninterface StartTextIndex {\n readonly starts: readonly string[];\n readonly keyIndexes: readonly number[];\n}\n\n/** Code unit order: in it the strings that start with one prefix are adjacent. */\nfunction compareCodeUnits(left: string, right: string): number {\n if (left === right) {\n return 0;\n }\n return left < right ? -1 : 1;\n}\n\nfunction startTextIndexOf(checked: readonly CheckedKey[]): StartTextIndex {\n const entries = checked.flatMap(({ shapes }, keyIndex) =>\n shapes.map((shape) => ({ start: shape.texts[0] as string, keyIndex })),\n );\n entries.sort((left, right) => compareCodeUnits(left.start, right.start));\n return {\n starts: entries.map((entry) => entry.start),\n keyIndexes: entries.map((entry) => entry.keyIndex),\n };\n}\n\n/** The indexes of the keys with a shape whose first text starts with one of the prefixes. */\nfunction keysStartingWith(index: StartTextIndex, prefixes: readonly string[]): Set<number> {\n const found = new Set<number>();\n for (const prefix of prefixes) {\n let low = 0;\n let high = index.starts.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if ((index.starts[middle] as string) < prefix) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n for (let at = low; at < index.starts.length; at += 1) {\n if (!(index.starts[at] as string).startsWith(prefix)) {\n break;\n }\n found.add(index.keyIndexes[at] as number);\n }\n }\n return found;\n}\n\n/**\n * The indexes of the template keys that cover another key of the list, where it is rejected, or\n * that repeat another template key. A template covers the keys TypeScript checks against it, the\n * ones its own matching accepts (see `template-key-match.ts`), not every string it stands for:\n * `` `/a/b/${number}` `` is no `` `/${string}/${number}` `` to the checker, which does not\n * backtrack, so that pair is never checked.\n */\nexport function coveringTemplateKeys(\n keys: readonly PathKey[],\n isRejected: CoverRejection = EVERY_COVER_REJECTED,\n): ReadonlySet<number> {\n const checked = keys.map(checkedKeyOf);\n const repeated = repeatedTemplates(checked);\n const startTexts = startTextIndexOf(checked);\n const covering = new Set<number>();\n checked.forEach(({ template, shapes: targets }, index) => {\n if (template === null) {\n return;\n }\n const prefixes = targets.map((target) => target.texts[0] as string);\n const candidates = [...keysStartingWith(startTexts, prefixes)].sort((a, b) => a - b);\n const isCovering =\n repeated.has(template) ||\n candidates.some(\n (otherIndex) =>\n otherIndex !== index &&\n isCoveredBy((checked[otherIndex] as CheckedKey).shapes, targets) &&\n isRejected(index, otherIndex),\n );\n if (isCovering) {\n covering.add(index);\n }\n });\n return covering;\n}\n"],"names":["isAssignableToTemplate"],"mappings":"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"}
|