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
|
@@ -1,48 +1,98 @@
|
|
|
1
|
+
import { isAssignableToTemplate } from './template-key-match.mjs';
|
|
2
|
+
|
|
1
3
|
const BOOLEAN_TEXTS = ["true", "false"];
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
return type === "boolean" ? BOOLEAN_TEXTS.includes(text) : true;
|
|
4
|
+
function withPart(shapes, part) {
|
|
5
|
+
return shapes.flatMap((shape) => {
|
|
6
|
+
const lead = shape.texts.slice(0, -1);
|
|
7
|
+
const last = shape.texts[shape.texts.length - 1];
|
|
8
|
+
if (part.kind === "text") {
|
|
9
|
+
return [{ texts: [...lead, last + part.text], types: shape.types }];
|
|
10
|
+
}
|
|
11
|
+
if (part.type === "boolean") {
|
|
12
|
+
return BOOLEAN_TEXTS.map((text) => ({ texts: [...lead, last + text], types: shape.types }));
|
|
13
|
+
}
|
|
14
|
+
return [{ texts: [...shape.texts, ""], types: [...shape.types, part.type] }];
|
|
15
|
+
});
|
|
15
16
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return start === text.length;
|
|
20
|
-
}
|
|
21
|
-
if (part.kind === "text") {
|
|
22
|
-
return text.startsWith(part.text, start) && matchesFrom(text, start + part.text.length, parts, index + 1);
|
|
17
|
+
function shapesOf(key) {
|
|
18
|
+
if (key.kind === "literal") {
|
|
19
|
+
return [{ texts: [key.url], types: [] }];
|
|
23
20
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
return key.parts.reduce(withPart, [{ texts: [""], types: [] }]);
|
|
22
|
+
}
|
|
23
|
+
function isCoveredBy(sources, targets) {
|
|
24
|
+
return sources.length > 0 && sources.every((source) => targets.some((target) => isAssignableToTemplate(source, target)));
|
|
25
|
+
}
|
|
26
|
+
const EVERY_COVER_REJECTED = () => true;
|
|
27
|
+
function checkedShapes(key) {
|
|
28
|
+
const shapes = shapesOf(key);
|
|
29
|
+
return key.kind === "literal" ? shapes : shapes.filter((shape) => shape.types.length > 0);
|
|
30
|
+
}
|
|
31
|
+
function checkedKeyOf(key) {
|
|
32
|
+
const template = key.kind === "template" ? JSON.stringify(shapesOf(key)) : null;
|
|
33
|
+
return { key, shapes: checkedShapes(key), template };
|
|
34
|
+
}
|
|
35
|
+
function repeatedTemplates(checked) {
|
|
36
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37
|
+
const repeated = /* @__PURE__ */ new Set();
|
|
38
|
+
for (const { template } of checked) {
|
|
39
|
+
if (template !== null) {
|
|
40
|
+
(seen.has(template) ? repeated : seen).add(template);
|
|
27
41
|
}
|
|
28
42
|
}
|
|
29
|
-
return
|
|
43
|
+
return repeated;
|
|
30
44
|
}
|
|
31
|
-
function
|
|
32
|
-
if (
|
|
33
|
-
return
|
|
45
|
+
function compareCodeUnits(left, right) {
|
|
46
|
+
if (left === right) {
|
|
47
|
+
return 0;
|
|
34
48
|
}
|
|
35
|
-
return
|
|
49
|
+
return left < right ? -1 : 1;
|
|
50
|
+
}
|
|
51
|
+
function startTextIndexOf(checked) {
|
|
52
|
+
const entries = checked.flatMap(
|
|
53
|
+
({ shapes }, keyIndex) => shapes.map((shape) => ({ start: shape.texts[0], keyIndex }))
|
|
54
|
+
);
|
|
55
|
+
entries.sort((left, right) => compareCodeUnits(left.start, right.start));
|
|
56
|
+
return {
|
|
57
|
+
starts: entries.map((entry) => entry.start),
|
|
58
|
+
keyIndexes: entries.map((entry) => entry.keyIndex)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function keysStartingWith(index, prefixes) {
|
|
62
|
+
const found = /* @__PURE__ */ new Set();
|
|
63
|
+
for (const prefix of prefixes) {
|
|
64
|
+
let low = 0;
|
|
65
|
+
let high = index.starts.length;
|
|
66
|
+
while (low < high) {
|
|
67
|
+
const middle = low + high >> 1;
|
|
68
|
+
if (index.starts[middle] < prefix) {
|
|
69
|
+
low = middle + 1;
|
|
70
|
+
} else {
|
|
71
|
+
high = middle;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (let at = low; at < index.starts.length; at += 1) {
|
|
75
|
+
if (!index.starts[at].startsWith(prefix)) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
found.add(index.keyIndexes[at]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return found;
|
|
36
82
|
}
|
|
37
|
-
const EVERY_COVER_REJECTED = () => true;
|
|
38
83
|
function coveringTemplateKeys(keys, isRejected = EVERY_COVER_REJECTED) {
|
|
84
|
+
const checked = keys.map(checkedKeyOf);
|
|
85
|
+
const repeated = repeatedTemplates(checked);
|
|
86
|
+
const startTexts = startTextIndexOf(checked);
|
|
39
87
|
const covering = /* @__PURE__ */ new Set();
|
|
40
|
-
|
|
41
|
-
if (
|
|
88
|
+
checked.forEach(({ template, shapes: targets }, index) => {
|
|
89
|
+
if (template === null) {
|
|
42
90
|
return;
|
|
43
91
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
92
|
+
const prefixes = targets.map((target) => target.texts[0]);
|
|
93
|
+
const candidates = [...keysStartingWith(startTexts, prefixes)].sort((a, b) => a - b);
|
|
94
|
+
const isCovering = repeated.has(template) || candidates.some(
|
|
95
|
+
(otherIndex) => otherIndex !== index && isCoveredBy(checked[otherIndex].shapes, targets) && isRejected(index, otherIndex)
|
|
46
96
|
);
|
|
47
97
|
if (isCovering) {
|
|
48
98
|
covering.add(index);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path-key-overlaps.mjs","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.mjs","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":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const URL_TEXT = null;
|
|
4
|
+
function placeholderText(type) {
|
|
5
|
+
return `\${${type}}`;
|
|
6
|
+
}
|
|
7
|
+
function replacedUnits(url, matches) {
|
|
8
|
+
const units = url.split("").map((unit) => ({ unit, owner: URL_TEXT }));
|
|
9
|
+
matches.forEach(({ match, type }, owner) => {
|
|
10
|
+
const at = units.map(({ unit }) => unit).join("").indexOf(match);
|
|
11
|
+
if (at >= 0) {
|
|
12
|
+
const inserted = placeholderText(type).split("").map((unit) => ({ unit, owner }));
|
|
13
|
+
units.splice(at, match.length, ...inserted);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return units;
|
|
17
|
+
}
|
|
18
|
+
function intactPlaceholders(units, matches) {
|
|
19
|
+
const intact = /* @__PURE__ */ new Map();
|
|
20
|
+
matches.forEach(({ type }, owner) => {
|
|
21
|
+
const left = units.filter((unit) => unit.owner === owner).length;
|
|
22
|
+
if (left === placeholderText(type).length) {
|
|
23
|
+
intact.set(owner, type);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return intact;
|
|
27
|
+
}
|
|
28
|
+
function replacedTemplateParts(url, matches) {
|
|
29
|
+
const units = replacedUnits(url, matches);
|
|
30
|
+
const intact = intactPlaceholders(units, matches);
|
|
31
|
+
const parts = [];
|
|
32
|
+
let text = "";
|
|
33
|
+
units.forEach(({ unit, owner }, index) => {
|
|
34
|
+
const type = owner === URL_TEXT ? void 0 : intact.get(owner);
|
|
35
|
+
if (type === void 0) {
|
|
36
|
+
text += unit;
|
|
37
|
+
} else if (units[index - 1]?.owner !== owner) {
|
|
38
|
+
parts.push({ kind: "text", text }, { kind: "placeholder", type });
|
|
39
|
+
text = "";
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
parts.push({ kind: "text", text });
|
|
43
|
+
return parts;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
exports.placeholderText = placeholderText;
|
|
47
|
+
exports.replacedTemplateParts = replacedTemplateParts;
|
|
48
|
+
//# sourceMappingURL=path-template-replace.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-template-replace.cjs","sources":["../../../../src/application/transform/document/path-template-replace.ts"],"sourcesContent":["import type { PathKeyPart, PathPlaceholder } from \"./path-key-overlaps.js\";\n\n/**\n * The `--path-params-as-types` key as the original builds it: each `{name}` match, in URL order,\n * replaces the first occurrence of its text in the key so far. A parameter named `number`,\n * `string` or `boolean` can so hit the `${number}` an earlier parameter got: of\n * `/a/{id}/b/{number}` the original makes `/a/$${number}/b/{number}`. That output compiles, so it\n * stays the default (ADR-021); the `path-param-type-names` fix gives every match its own\n * placeholder.\n */\n\n/** One `{name}` of the URL and the placeholder of its parameter's type. */\nexport interface PathParameterMatch {\n readonly match: string;\n readonly type: PathPlaceholder;\n}\n\n/**\n * One UTF-16 code unit of the key so far (`indexOf` counts those): URL text, or a unit of the\n * placeholder that the match at `owner` inserted.\n */\ninterface KeyUnit {\n readonly unit: string;\n readonly owner: number | null;\n}\n\nconst URL_TEXT = null;\n\n/** `${type}`: the text of a template literal type placeholder. */\nexport function placeholderText(type: PathPlaceholder): string {\n return `\\${${type}}`;\n}\n\n/** The key's units after each match replaced the first occurrence of its text. */\nfunction replacedUnits(url: string, matches: readonly PathParameterMatch[]): readonly KeyUnit[] {\n const units: KeyUnit[] = url.split(\"\").map((unit) => ({ unit, owner: URL_TEXT }));\n matches.forEach(({ match, type }, owner) => {\n const at = units\n .map(({ unit }) => unit)\n .join(\"\")\n .indexOf(match);\n if (at >= 0) {\n const inserted = placeholderText(type)\n .split(\"\")\n .map((unit) => ({ unit, owner }));\n units.splice(at, match.length, ...inserted);\n }\n });\n return units;\n}\n\n/** The placeholders, by match, that no later match cut into. */\nfunction intactPlaceholders(\n units: readonly KeyUnit[],\n matches: readonly PathParameterMatch[],\n): ReadonlyMap<number, PathPlaceholder> {\n const intact = new Map<number, PathPlaceholder>();\n matches.forEach(({ type }, owner) => {\n const left = units.filter((unit) => unit.owner === owner).length;\n if (left === placeholderText(type).length) {\n intact.set(owner, type);\n }\n });\n return intact;\n}\n\n/**\n * The key as parts. What is left of a placeholder that a later match cut into (the `$` of\n * `$${number}`) is text, as TypeScript reads it.\n */\nexport function replacedTemplateParts(\n url: string,\n matches: readonly PathParameterMatch[],\n): PathKeyPart[] {\n const units = replacedUnits(url, matches);\n const intact = intactPlaceholders(units, matches);\n const parts: PathKeyPart[] = [];\n let text = \"\";\n units.forEach(({ unit, owner }, index) => {\n const type = owner === URL_TEXT ? undefined : intact.get(owner);\n if (type === undefined) {\n text += unit;\n } else if (units[index - 1]?.owner !== owner) {\n parts.push({ kind: \"text\", text }, { kind: \"placeholder\", type });\n text = \"\";\n }\n });\n parts.push({ kind: \"text\", text });\n return parts;\n}\n"],"names":[],"mappings":";;AA0BA,MAAM,QAAA,GAAW,IAAA;AAGV,SAAS,gBAAgB,IAAA,EAA+B;AAC7D,EAAA,OAAO,MAAM,IAAI,CAAA,CAAA,CAAA;AACnB;AAGA,SAAS,aAAA,CAAc,KAAa,OAAA,EAA4D;AAC9F,EAAA,MAAM,KAAA,GAAmB,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,IAAA,EAAM,KAAA,EAAO,QAAA,EAAS,CAAE,CAAA;AAChF,EAAA,OAAA,CAAQ,QAAQ,CAAC,EAAE,KAAA,EAAO,IAAA,IAAQ,KAAA,KAAU;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAA,CACR,GAAA,CAAI,CAAC,EAAE,IAAA,EAAK,KAAM,IAAI,CAAA,CACtB,IAAA,CAAK,EAAE,CAAA,CACP,QAAQ,KAAK,CAAA;AAChB,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,IAAI,CAAA,CAClC,KAAA,CAAM,EAAE,CAAA,CACR,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,IAAA,EAAM,OAAM,CAAE,CAAA;AAClC,MAAA,KAAA,CAAM,MAAA,CAAO,EAAA,EAAI,KAAA,CAAM,MAAA,EAAQ,GAAG,QAAQ,CAAA;AAAA,IAC5C;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,kBAAA,CACP,OACA,OAAA,EACsC;AACtC,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA6B;AAChD,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,EAAE,IAAA,IAAQ,KAAA,KAAU;AACnC,IAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,CAAC,SAAS,IAAA,CAAK,KAAA,KAAU,KAAK,CAAA,CAAE,MAAA;AAC1D,IAAA,IAAI,IAAA,KAAS,eAAA,CAAgB,IAAI,CAAA,CAAE,MAAA,EAAQ;AACzC,MAAA,MAAA,CAAO,GAAA,CAAI,OAAO,IAAI,CAAA;AAAA,IACxB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,qBAAA,CACd,KACA,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,EAAK,OAAO,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AAChD,EAAA,MAAM,QAAuB,EAAC;AAC9B,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,KAAA,CAAM,QAAQ,CAAC,EAAE,IAAA,EAAM,KAAA,IAAS,KAAA,KAAU;AACxC,IAAA,MAAM,OAAO,KAAA,KAAU,QAAA,GAAW,MAAA,GAAY,MAAA,CAAO,IAAI,KAAK,CAAA;AAC9D,IAAA,IAAI,SAAS,MAAA,EAAW;AACtB,MAAA,IAAA,IAAQ,IAAA;AAAA,IACV,WAAW,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,UAAU,KAAA,EAAO;AAC5C,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,IAAQ,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,CAAA;AAChE,MAAA,IAAA,GAAO,EAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AACD,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAA;AACjC,EAAA,OAAO,KAAA;AACT;;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const URL_TEXT = null;
|
|
2
|
+
function placeholderText(type) {
|
|
3
|
+
return `\${${type}}`;
|
|
4
|
+
}
|
|
5
|
+
function replacedUnits(url, matches) {
|
|
6
|
+
const units = url.split("").map((unit) => ({ unit, owner: URL_TEXT }));
|
|
7
|
+
matches.forEach(({ match, type }, owner) => {
|
|
8
|
+
const at = units.map(({ unit }) => unit).join("").indexOf(match);
|
|
9
|
+
if (at >= 0) {
|
|
10
|
+
const inserted = placeholderText(type).split("").map((unit) => ({ unit, owner }));
|
|
11
|
+
units.splice(at, match.length, ...inserted);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
return units;
|
|
15
|
+
}
|
|
16
|
+
function intactPlaceholders(units, matches) {
|
|
17
|
+
const intact = /* @__PURE__ */ new Map();
|
|
18
|
+
matches.forEach(({ type }, owner) => {
|
|
19
|
+
const left = units.filter((unit) => unit.owner === owner).length;
|
|
20
|
+
if (left === placeholderText(type).length) {
|
|
21
|
+
intact.set(owner, type);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return intact;
|
|
25
|
+
}
|
|
26
|
+
function replacedTemplateParts(url, matches) {
|
|
27
|
+
const units = replacedUnits(url, matches);
|
|
28
|
+
const intact = intactPlaceholders(units, matches);
|
|
29
|
+
const parts = [];
|
|
30
|
+
let text = "";
|
|
31
|
+
units.forEach(({ unit, owner }, index) => {
|
|
32
|
+
const type = owner === URL_TEXT ? void 0 : intact.get(owner);
|
|
33
|
+
if (type === void 0) {
|
|
34
|
+
text += unit;
|
|
35
|
+
} else if (units[index - 1]?.owner !== owner) {
|
|
36
|
+
parts.push({ kind: "text", text }, { kind: "placeholder", type });
|
|
37
|
+
text = "";
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
parts.push({ kind: "text", text });
|
|
41
|
+
return parts;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { placeholderText, replacedTemplateParts };
|
|
45
|
+
//# sourceMappingURL=path-template-replace.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-template-replace.mjs","sources":["../../../../src/application/transform/document/path-template-replace.ts"],"sourcesContent":["import type { PathKeyPart, PathPlaceholder } from \"./path-key-overlaps.js\";\n\n/**\n * The `--path-params-as-types` key as the original builds it: each `{name}` match, in URL order,\n * replaces the first occurrence of its text in the key so far. A parameter named `number`,\n * `string` or `boolean` can so hit the `${number}` an earlier parameter got: of\n * `/a/{id}/b/{number}` the original makes `/a/$${number}/b/{number}`. That output compiles, so it\n * stays the default (ADR-021); the `path-param-type-names` fix gives every match its own\n * placeholder.\n */\n\n/** One `{name}` of the URL and the placeholder of its parameter's type. */\nexport interface PathParameterMatch {\n readonly match: string;\n readonly type: PathPlaceholder;\n}\n\n/**\n * One UTF-16 code unit of the key so far (`indexOf` counts those): URL text, or a unit of the\n * placeholder that the match at `owner` inserted.\n */\ninterface KeyUnit {\n readonly unit: string;\n readonly owner: number | null;\n}\n\nconst URL_TEXT = null;\n\n/** `${type}`: the text of a template literal type placeholder. */\nexport function placeholderText(type: PathPlaceholder): string {\n return `\\${${type}}`;\n}\n\n/** The key's units after each match replaced the first occurrence of its text. */\nfunction replacedUnits(url: string, matches: readonly PathParameterMatch[]): readonly KeyUnit[] {\n const units: KeyUnit[] = url.split(\"\").map((unit) => ({ unit, owner: URL_TEXT }));\n matches.forEach(({ match, type }, owner) => {\n const at = units\n .map(({ unit }) => unit)\n .join(\"\")\n .indexOf(match);\n if (at >= 0) {\n const inserted = placeholderText(type)\n .split(\"\")\n .map((unit) => ({ unit, owner }));\n units.splice(at, match.length, ...inserted);\n }\n });\n return units;\n}\n\n/** The placeholders, by match, that no later match cut into. */\nfunction intactPlaceholders(\n units: readonly KeyUnit[],\n matches: readonly PathParameterMatch[],\n): ReadonlyMap<number, PathPlaceholder> {\n const intact = new Map<number, PathPlaceholder>();\n matches.forEach(({ type }, owner) => {\n const left = units.filter((unit) => unit.owner === owner).length;\n if (left === placeholderText(type).length) {\n intact.set(owner, type);\n }\n });\n return intact;\n}\n\n/**\n * The key as parts. What is left of a placeholder that a later match cut into (the `$` of\n * `$${number}`) is text, as TypeScript reads it.\n */\nexport function replacedTemplateParts(\n url: string,\n matches: readonly PathParameterMatch[],\n): PathKeyPart[] {\n const units = replacedUnits(url, matches);\n const intact = intactPlaceholders(units, matches);\n const parts: PathKeyPart[] = [];\n let text = \"\";\n units.forEach(({ unit, owner }, index) => {\n const type = owner === URL_TEXT ? undefined : intact.get(owner);\n if (type === undefined) {\n text += unit;\n } else if (units[index - 1]?.owner !== owner) {\n parts.push({ kind: \"text\", text }, { kind: \"placeholder\", type });\n text = \"\";\n }\n });\n parts.push({ kind: \"text\", text });\n return parts;\n}\n"],"names":[],"mappings":"AA0BA,MAAM,QAAA,GAAW,IAAA;AAGV,SAAS,gBAAgB,IAAA,EAA+B;AAC7D,EAAA,OAAO,MAAM,IAAI,CAAA,CAAA,CAAA;AACnB;AAGA,SAAS,aAAA,CAAc,KAAa,OAAA,EAA4D;AAC9F,EAAA,MAAM,KAAA,GAAmB,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,IAAA,EAAM,KAAA,EAAO,QAAA,EAAS,CAAE,CAAA;AAChF,EAAA,OAAA,CAAQ,QAAQ,CAAC,EAAE,KAAA,EAAO,IAAA,IAAQ,KAAA,KAAU;AAC1C,IAAA,MAAM,EAAA,GAAK,KAAA,CACR,GAAA,CAAI,CAAC,EAAE,IAAA,EAAK,KAAM,IAAI,CAAA,CACtB,IAAA,CAAK,EAAE,CAAA,CACP,QAAQ,KAAK,CAAA;AAChB,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,IAAI,CAAA,CAClC,KAAA,CAAM,EAAE,CAAA,CACR,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,IAAA,EAAM,OAAM,CAAE,CAAA;AAClC,MAAA,KAAA,CAAM,MAAA,CAAO,EAAA,EAAI,KAAA,CAAM,MAAA,EAAQ,GAAG,QAAQ,CAAA;AAAA,IAC5C;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAGA,SAAS,kBAAA,CACP,OACA,OAAA,EACsC;AACtC,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA6B;AAChD,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,EAAE,IAAA,IAAQ,KAAA,KAAU;AACnC,IAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,CAAC,SAAS,IAAA,CAAK,KAAA,KAAU,KAAK,CAAA,CAAE,MAAA;AAC1D,IAAA,IAAI,IAAA,KAAS,eAAA,CAAgB,IAAI,CAAA,CAAE,MAAA,EAAQ;AACzC,MAAA,MAAA,CAAO,GAAA,CAAI,OAAO,IAAI,CAAA;AAAA,IACxB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,qBAAA,CACd,KACA,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,EAAK,OAAO,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,KAAA,EAAO,OAAO,CAAA;AAChD,EAAA,MAAM,QAAuB,EAAC;AAC9B,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,KAAA,CAAM,QAAQ,CAAC,EAAE,IAAA,EAAM,KAAA,IAAS,KAAA,KAAU;AACxC,IAAA,MAAM,OAAO,KAAA,KAAU,QAAA,GAAW,MAAA,GAAY,MAAA,CAAO,IAAI,KAAK,CAAA;AAC9D,IAAA,IAAI,SAAS,MAAA,EAAW;AACtB,MAAA,IAAA,IAAQ,IAAA;AAAA,IACV,WAAW,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,EAAG,UAAU,KAAA,EAAO;AAC5C,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,IAAQ,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,CAAA;AAChE,MAAA,IAAA,GAAO,EAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AACD,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAA;AACjC,EAAA,OAAO,KAAA;AACT;;"}
|
|
@@ -5,23 +5,23 @@ const propertyName = require('../../../domain/ir/property-name.cjs');
|
|
|
5
5
|
const rawTextEscapes = require('../../../domain/ir/raw-text-escapes.cjs');
|
|
6
6
|
const jsonPointer = require('../../../domain/openapi/json-pointer.cjs');
|
|
7
7
|
const pathItemObject = require('../../../domain/openapi/path-item-object.cjs');
|
|
8
|
+
const outputFixes = require('../../../domain/output-fixes.cjs');
|
|
8
9
|
const documentEntries = require('../document-entries.cjs');
|
|
9
10
|
const refType = require('../ref-type.cjs');
|
|
11
|
+
const declaredTypes = require('./declared-types.cjs');
|
|
10
12
|
const documentMember = require('./document-member.cjs');
|
|
11
13
|
const pathItem = require('./path-item.cjs');
|
|
12
|
-
const pathItemConflicts = require('./path-item-conflicts.cjs');
|
|
13
14
|
const pathKeyOverlaps = require('./path-key-overlaps.cjs');
|
|
15
|
+
const pathTemplateReplace = require('./path-template-replace.cjs');
|
|
16
|
+
const typeAssignability = require('./type-assignability.cjs');
|
|
14
17
|
|
|
15
|
-
const PATH_PARAMETER_RE = /\{[^}]+\}/g;
|
|
18
|
+
const PATH_PARAMETER_RE = /\{[^{}]+\}/g;
|
|
16
19
|
const PLACEHOLDERS = /* @__PURE__ */ new Map([
|
|
17
20
|
["number", "number"],
|
|
18
21
|
["integer", "number"],
|
|
19
22
|
["boolean", "boolean"]
|
|
20
23
|
]);
|
|
21
24
|
const STRING_PLACEHOLDER = "string";
|
|
22
|
-
function placeholderText(type) {
|
|
23
|
-
return `\${${type}}`;
|
|
24
|
-
}
|
|
25
25
|
function resolvedParameter(parameter, context) {
|
|
26
26
|
return "$ref" in parameter && parameter.$ref ? context.refs.resolve(parameter.$ref) : parameter;
|
|
27
27
|
}
|
|
@@ -42,25 +42,28 @@ function pathParameters(pathItem, context) {
|
|
|
42
42
|
}
|
|
43
43
|
return byName;
|
|
44
44
|
}
|
|
45
|
+
function splitTemplateParts(url, matches) {
|
|
46
|
+
return url.split(PATH_PARAMETER_RE).flatMap((text, index) => {
|
|
47
|
+
const type = matches[index]?.type;
|
|
48
|
+
const textPart = { kind: "text", text };
|
|
49
|
+
return type === void 0 ? [textPart] : [textPart, { kind: "placeholder", type }];
|
|
50
|
+
});
|
|
51
|
+
}
|
|
45
52
|
function pathTemplateParts(url, pathItem, context) {
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
53
|
+
const found = url.match(PATH_PARAMETER_RE);
|
|
54
|
+
if (!found) {
|
|
48
55
|
return null;
|
|
49
56
|
}
|
|
50
57
|
const parameters = pathParameters(pathItem, context);
|
|
51
|
-
const
|
|
58
|
+
const matches = found.map((match) => {
|
|
52
59
|
const schema = parameters.get(match.slice(1, -1))?.schema;
|
|
53
|
-
return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;
|
|
54
|
-
});
|
|
55
|
-
return url.split(PATH_PARAMETER_RE).flatMap((text, index) => {
|
|
56
|
-
const type = placeholders[index];
|
|
57
|
-
const textPart = { kind: "text", text };
|
|
58
|
-
return type === void 0 ? [textPart] : [textPart, { kind: "placeholder", type }];
|
|
60
|
+
return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
|
|
59
61
|
});
|
|
62
|
+
return context.options.fixes.has(outputFixes.OutputFix.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : pathTemplateReplace.replacedTemplateParts(url, matches);
|
|
60
63
|
}
|
|
61
64
|
function templateText(parts) {
|
|
62
65
|
const text = parts.map(
|
|
63
|
-
(part) => part.kind === "text" ? rawTextEscapes.escapeTemplateText(part.text) : placeholderText(part.type)
|
|
66
|
+
(part) => part.kind === "text" ? rawTextEscapes.escapeTemplateText(part.text) : pathTemplateReplace.placeholderText(part.type)
|
|
64
67
|
).join("");
|
|
65
68
|
return `\`${text}\``;
|
|
66
69
|
}
|
|
@@ -70,7 +73,7 @@ function pathItemMember(url, pathItem$1, context) {
|
|
|
70
73
|
const parts = context.options.pathParamsAsTypes && url.includes("{") ? pathTemplateParts(url, pathItem$1, context) : null;
|
|
71
74
|
if (parts === null) {
|
|
72
75
|
const member2 = constructors.irProperty(propertyName.toPropertyName(url), type, { isReadonly });
|
|
73
|
-
return { member: member2, key: literalKey(url), type };
|
|
76
|
+
return { url, member: member2, key: literalKey(url), type };
|
|
74
77
|
}
|
|
75
78
|
const member = {
|
|
76
79
|
kind: "indexSignature",
|
|
@@ -80,20 +83,38 @@ function pathItemMember(url, pathItem$1, context) {
|
|
|
80
83
|
isReadonly,
|
|
81
84
|
comments: []
|
|
82
85
|
};
|
|
83
|
-
return { member, key: { kind: "template", parts }, type };
|
|
86
|
+
return { url, member, key: { kind: "template", parts }, type };
|
|
84
87
|
}
|
|
85
88
|
function literalKey(url) {
|
|
86
89
|
return { kind: "literal", url };
|
|
87
90
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
const PATHS_TYPE_NAME = "paths";
|
|
92
|
+
function pathsIndexOf(type) {
|
|
93
|
+
if (type.kind !== "indexedAccess" || type.index.kind !== "stringLiteral") {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const { object } = type;
|
|
97
|
+
const isPaths = object.kind === "reference" && object.name === PATHS_TYPE_NAME && object.typeArguments.length === 0;
|
|
98
|
+
return isPaths ? type.index.value : null;
|
|
99
|
+
}
|
|
100
|
+
function withPathItems(paths, lookup) {
|
|
101
|
+
const byUrl = new Map(paths.map((path) => [path.url, path.type]));
|
|
102
|
+
return (type) => {
|
|
103
|
+
const url = pathsIndexOf(type);
|
|
104
|
+
return (url === null ? void 0 : byUrl.get(url)) ?? lookup(type);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function rejectionOf(paths, lookup) {
|
|
108
|
+
const relate = typeAssignability.assignabilityProof(withPathItems(paths, lookup));
|
|
109
|
+
return (coveringIndex, coveredIndex) => {
|
|
110
|
+
const coveringPath = paths[coveringIndex];
|
|
111
|
+
const coveredPath = paths[coveredIndex];
|
|
112
|
+
return coveringPath !== void 0 && coveredPath !== void 0 && relate(coveredPath.type, coveringPath.type) === "rejected";
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function pathsObjectType(paths, lookup = declaredTypes.NO_DECLARED_TYPES) {
|
|
116
|
+
const keys = paths.map(({ key }) => key);
|
|
117
|
+
const covering = pathKeyOverlaps.coveringTemplateKeys(keys, rejectionOf(paths, lookup));
|
|
97
118
|
if (covering.size === 0) {
|
|
98
119
|
return constructors.irObject(paths.map(({ member }) => member));
|
|
99
120
|
}
|
|
@@ -101,7 +122,7 @@ function pathsObjectType(paths) {
|
|
|
101
122
|
const own = paths.filter((_, index) => covering.has(index)).map(({ member }) => constructors.irObject([member]));
|
|
102
123
|
return constructors.irIntersection([constructors.irObject(rest), ...own]);
|
|
103
124
|
}
|
|
104
|
-
function
|
|
125
|
+
function pathMembers(paths, context) {
|
|
105
126
|
const members = [];
|
|
106
127
|
for (const [url, pathItem] of documentEntries.documentEntries(paths, context.options)) {
|
|
107
128
|
if (!pathItem || typeof pathItem !== "object") {
|
|
@@ -110,7 +131,7 @@ function pathsType(paths, context) {
|
|
|
110
131
|
if ("$ref" in pathItem) {
|
|
111
132
|
const options = { isReadonly: context.options.immutable };
|
|
112
133
|
const member = documentMember.documentMember(url, refType.refType(pathItem.$ref), pathItem, options);
|
|
113
|
-
members.push({ member, key: literalKey(url), type: member.type });
|
|
134
|
+
members.push({ url, member, key: literalKey(url), type: member.type });
|
|
114
135
|
continue;
|
|
115
136
|
}
|
|
116
137
|
const startedAt = context.diagnostics.now();
|
|
@@ -120,8 +141,13 @@ function pathsType(paths, context) {
|
|
|
120
141
|
context.diagnostics.debug(`Transformed path "${url}"`, context.diagnostics.now() - startedAt);
|
|
121
142
|
}
|
|
122
143
|
}
|
|
123
|
-
return
|
|
144
|
+
return members;
|
|
145
|
+
}
|
|
146
|
+
function pathsType(paths, context) {
|
|
147
|
+
return pathsObjectType(pathMembers(paths, context));
|
|
124
148
|
}
|
|
125
149
|
|
|
150
|
+
exports.pathMembers = pathMembers;
|
|
151
|
+
exports.pathsObjectType = pathsObjectType;
|
|
126
152
|
exports.pathsType = pathsType;
|
|
127
153
|
//# sourceMappingURL=paths.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { isCoveredPathItemRejected } from \"./path-item-conflicts.js\";\nimport {\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\n\nconst PATH_PARAMETER_RE = /\\{[^}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\n/** `${type}`: the text of a template literal type placeholder. */\nfunction placeholderText(type: PathPlaceholder): string {\n return `\\${${type}}`;\n}\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type. Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const matches = url.match(PATH_PARAMETER_RE);\n if (!matches) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const placeholders = matches.map((match) => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;\n });\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = placeholders[index];\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\ninterface PathMember {\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object.\n */\nfunction pathsObjectType(paths: readonly PathMember[]): IrType {\n const covering = coveringTemplateKeys(\n paths.map(({ key }) => key),\n (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n isCoveredPathItemRejected(coveredPath.type, coveringPath.type)\n );\n },\n );\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The `paths` interface body (OpenAPI 3.1 §4.8.8): one member per path, by URL. */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return pathsObjectType(members);\n}\n"],"names":["pathItemOperations","escapeTemplateText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","coveringTemplateKeys","isCoveredPathItemRejected","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\nconst PATH_PARAMETER_RE = /\\{[^{}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["pathItemOperations","OutputFix","replacedTemplateParts","escapeTemplateText","placeholderText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":";;;;;;;;;;;;;;;;;AAsCA,MAAM,iBAAA,GAAoB,aAAA;AAG1B,MAAM,YAAA,uBAA0D,GAAA,CAAI;AAAA,EAClE,CAAC,UAAU,QAAQ,CAAA;AAAA,EACnB,CAAC,WAAW,QAAQ,CAAA;AAAA,EACpB,CAAC,WAAW,SAAS;AACvB,CAAC,CAAA;AACD,MAAM,kBAAA,GAAsC,QAAA;AAE5C,SAAS,iBAAA,CACP,WACA,OAAA,EAC6B;AAC7B,EAAA,OAAO,MAAA,IAAU,aAAa,SAAA,CAAU,IAAA,GACnC,QAAQ,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,GACnC,SAAA;AACP;AAEA,SAAS,iBAAA,CACP,UAAA,EACA,MAAA,EACA,OAAA,EACM;AACN,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,SAAA,EAAW,OAAO,CAAA;AACrD,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,EAAA,KAAO,MAAA,EAAQ;AACtC,MAAA,MAAA,CAAO,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA;AAAA,IACpC;AAAA,EACF;AACF;AAGA,SAAS,cAAA,CACP,UACA,OAAA,EAC8B;AAC9B,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA6B;AAChD,EAAA,iBAAA,CAAkB,QAAA,CAAS,UAAA,IAAc,EAAC,EAAG,QAAQ,OAAO,CAAA;AAC5D,EAAA,KAAA,MAAW,EAAE,SAAA,EAAW,KAAA,EAAM,IAAKA,iCAAA,CAAmB,QAAQ,CAAA,EAAG;AAC/D,IAAA,MAAM,SAAA,GAAa,MAA0B,IAAA,GACxC,OAAA,CAAQ,KAAK,OAAA,CAAS,KAAA,CAA0B,IAAI,CAAA,GACpD,KAAA;AACL,IAAA,iBAAA,CAAkB,SAAA,EAAW,UAAA,IAAc,EAAC,EAAG,QAAQ,OAAO,CAAA;AAAA,EAChE;AACA,EAAA,OAAO,MAAA;AACT;AAGA,SAAS,kBAAA,CAAmB,KAAa,OAAA,EAAuD;AAC9F,EAAA,OAAO,IAAI,KAAA,CAAM,iBAAiB,EAAE,OAAA,CAAQ,CAAC,MAAM,KAAA,KAAyB;AAC1E,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAK,CAAA,EAAG,IAAA;AAC7B,IAAA,MAAM,QAAA,GAAwB,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AACnD,IAAA,OAAO,IAAA,KAAS,MAAA,GAAY,CAAC,QAAQ,CAAA,GAAI,CAAC,QAAA,EAAU,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,CAAA;AAAA,EACnF,CAAC,CAAA;AACH;AAOA,SAAS,iBAAA,CACP,GAAA,EACA,QAAA,EACA,OAAA,EACsB;AACtB,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,iBAAiB,CAAA;AACzC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,QAAA,EAAU,OAAO,CAAA;AACnD,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAA8B;AACvD,IAAA,MAAM,MAAA,GAAS,WAAW,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,MAAA;AACnD,IAAA,OAAO,EAAE,OAAO,IAAA,EAAM,YAAA,CAAa,IAAI,MAAA,EAAQ,IAAI,KAAK,kBAAA,EAAmB;AAAA,EAC7E,CAAC,CAAA;AACD,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAIC,qBAAA,CAAU,qBAAqB,CAAA,GAC5D,kBAAA,CAAmB,GAAA,EAAK,OAAO,CAAA,GAC/BC,yCAAA,CAAsB,KAAK,OAAO,CAAA;AACxC;AAOA,SAAS,aAAa,KAAA,EAAuC;AAC3D,EAAA,MAAM,OAAO,KAAA,CACV,GAAA;AAAA,IAAI,CAAC,IAAA,KACJ,IAAA,CAAK,IAAA,KAAS,MAAA,GAASC,iCAAA,CAAmB,IAAA,CAAK,IAAI,CAAA,GAAIC,mCAAA,CAAgB,IAAA,CAAK,IAAI;AAAA,GAClF,CACC,KAAK,EAAE,CAAA;AACV,EAAA,OAAO,KAAK,IAAI,CAAA,EAAA,CAAA;AAClB;AAUA,SAAS,cAAA,CACP,GAAA,EACAC,UAAA,EACA,OAAA,EACY;AACZ,EAAA,MAAM,UAAA,GAAa,QAAQ,OAAA,CAAQ,SAAA;AACnC,EAAA,MAAM,IAAA,GAAOC,qBAAA,CAAaD,UAAA,EAAU,EAAE,IAAA,EAAME,qBAAA,CAAU,CAAC,OAAA,EAAS,GAAG,CAAC,CAAA,EAAE,EAAG,OAAO,CAAA;AAChF,EAAA,MAAM,KAAA,GACJ,OAAA,CAAQ,OAAA,CAAQ,iBAAA,IAAqB,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GACjD,iBAAA,CAAkB,GAAA,EAAKF,UAAA,EAAU,OAAO,CAAA,GACxC,IAAA;AACN,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAMG,OAAAA,GAASC,wBAAWC,2BAAA,CAAe,GAAG,GAAG,IAAA,EAAM,EAAE,YAAY,CAAA;AACnE,IAAA,OAAO,EAAE,KAAK,MAAA,EAAAF,OAAAA,EAAQ,KAAK,UAAA,CAAW,GAAG,GAAG,IAAA,EAAK;AAAA,EACnD;AACA,EAAA,MAAM,MAAA,GAAmB;AAAA,IACvB,IAAA,EAAM,gBAAA;AAAA,IACN,aAAA,EAAe,MAAA;AAAA,IACf,aAAA,EAAeG,kBAAA,CAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,IACxC,IAAA;AAAA,IACA,UAAA;AAAA,IACA,UAAU;AAAC,GACb;AACA,EAAA,OAAO,EAAE,KAAK,MAAA,EAAQ,GAAA,EAAK,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAM,EAAG,IAAA,EAAK;AAC/D;AAEA,SAAS,WAAW,GAAA,EAAsB;AACxC,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,GAAA,EAAI;AAChC;AAEA,MAAM,eAAA,GAAkB,OAAA;AAGxB,SAAS,aAAa,IAAA,EAA6B;AACjD,EAAA,IAAI,KAAK,IAAA,KAAS,eAAA,IAAmB,IAAA,CAAK,KAAA,CAAM,SAAS,eAAA,EAAiB;AACxE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,IAAA;AACnB,EAAA,MAAM,OAAA,GACJ,OAAO,IAAA,KAAS,WAAA,IAChB,OAAO,IAAA,KAAS,eAAA,IAChB,MAAA,CAAO,aAAA,CAAc,MAAA,KAAW,CAAA;AAClC,EAAA,OAAO,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,IAAA;AACtC;AAMA,SAAS,aAAA,CACP,OACA,MAAA,EACoB;AACpB,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,CAAC,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA;AAChE,EAAA,OAAO,CAAC,IAAA,KAAS;AACf,IAAA,MAAM,GAAA,GAAM,aAAa,IAAI,CAAA;AAC7B,IAAA,OAAA,CAAQ,GAAA,KAAQ,OAAO,MAAA,GAAY,KAAA,CAAM,IAAI,GAAG,CAAA,KAAM,OAAO,IAAI,CAAA;AAAA,EACnE,CAAA;AACF;AAOA,SAAS,WAAA,CAAY,OAA8B,MAAA,EAA4C;AAC7F,EAAA,MAAM,MAAA,GAASC,oCAAA,CAAmB,aAAA,CAAc,KAAA,EAAO,MAAM,CAAC,CAAA;AAC9D,EAAA,OAAO,CAAC,eAAe,YAAA,KAAiB;AACtC,IAAA,MAAM,YAAA,GAAe,MAAM,aAAa,CAAA;AACxC,IAAA,MAAM,WAAA,GAAc,MAAM,YAAY,CAAA;AACtC,IAAA,OACE,YAAA,KAAiB,UACjB,WAAA,KAAgB,MAAA,IAChB,OAAO,WAAA,CAAY,IAAA,EAAM,YAAA,CAAa,IAAI,CAAA,KAAM,UAAA;AAAA,EAEpD,CAAA;AACF;AAUO,SAAS,eAAA,CACd,KAAA,EACA,MAAA,GAA6BC,+BAAA,EACrB;AACR,EAAA,MAAM,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,EAAE,GAAA,OAAU,GAAG,CAAA;AACvC,EAAA,MAAM,WAAWC,oCAAA,CAAqB,IAAA,EAAM,WAAA,CAAY,KAAA,EAAO,MAAM,CAAC,CAAA;AACtE,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,OAAOC,qBAAA,CAAS,MAAM,GAAA,CAAI,CAAC,EAAE,MAAA,EAAO,KAAM,MAAM,CAAC,CAAA;AAAA,EACnD;AACA,EAAA,MAAM,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,UAAU,CAAC,QAAA,CAAS,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,EAAE,MAAA,OAAa,MAAM,CAAA;AACxF,EAAA,MAAM,GAAA,GAAM,MACT,MAAA,CAAO,CAAC,GAAG,KAAA,KAAU,QAAA,CAAS,IAAI,KAAK,CAAC,EACxC,GAAA,CAAI,CAAC,EAAE,MAAA,EAAO,KAAMA,sBAAS,CAAC,MAAM,CAAC,CAAC,CAAA;AACzC,EAAA,OAAOC,4BAAe,CAACD,qBAAA,CAAS,IAAI,CAAA,EAAG,GAAG,GAAG,CAAC,CAAA;AAChD;AAGO,SAAS,WAAA,CAAY,OAAoB,OAAA,EAAyC;AACvF,EAAA,MAAM,UAAwB,EAAC;AAC/B,EAAA,KAAA,MAAW,CAAC,KAAK,QAAQ,CAAA,IAAKE,gCAAgB,KAAA,EAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AACrE,IAAA,IAAI,CAAC,QAAA,IAAY,OAAO,QAAA,KAAa,QAAA,EAAU;AAC7C,MAAA;AAAA,IACF;AACA,IAAA,IAAI,UAAU,QAAA,EAAU;AACtB,MAAA,MAAM,OAAA,GAAU,EAAE,UAAA,EAAY,OAAA,CAAQ,QAAQ,SAAA,EAAU;AACxD,MAAA,MAAM,MAAA,GAASC,8BAAe,GAAA,EAAKC,eAAA,CAAQ,SAAS,IAAI,CAAA,EAAG,UAAU,OAAO,CAAA;AAC5E,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,UAAA,CAAW,GAAG,CAAA,EAAG,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,CAAA;AACrE,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI;AAC1C,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,GAAA,EAAK,QAAA,EAAU,OAAO,CAAA;AAClD,IAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAEjB,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACnC,MAAA,OAAA,CAAQ,WAAA,CAAY,MAAM,CAAA,kBAAA,EAAqB,GAAG,KAAK,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI,GAAI,SAAS,CAAA;AAAA,IAC9F;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,SAAA,CAAU,OAAoB,OAAA,EAAmC;AAC/E,EAAA,OAAO,eAAA,CAAgB,WAAA,CAAY,KAAA,EAAO,OAAO,CAAC,CAAA;AACpD;;;;"}
|