openapi-typesafe 1.0.0-rc.4 → 1.0.0-rc.6
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/CHANGELOG.md +214 -0
- package/dist/adapters/node-file-system/node-file-system.cjs +7 -0
- package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
- package/dist/adapters/node-file-system/node-file-system.mjs +7 -0
- package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs +19 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs.map +1 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs +17 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +5 -32
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -1
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +6 -33
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -1
- package/dist/adapters/redocly-loader/component-schemas.cjs +17 -0
- package/dist/adapters/redocly-loader/component-schemas.cjs.map +1 -0
- package/dist/adapters/redocly-loader/component-schemas.mjs +14 -0
- package/dist/adapters/redocly-loader/component-schemas.mjs.map +1 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.cjs +22 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.cjs.map +1 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.mjs +20 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.mjs.map +1 -0
- package/dist/adapters/redocly-loader/query-document-names.cjs +50 -0
- package/dist/adapters/redocly-loader/query-document-names.cjs.map +1 -0
- package/dist/adapters/redocly-loader/query-document-names.mjs +48 -0
- package/dist/adapters/redocly-loader/query-document-names.mjs.map +1 -0
- package/dist/adapters/redocly-loader/query-named-components.cjs +129 -0
- package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -0
- package/dist/adapters/redocly-loader/query-named-components.mjs +126 -0
- package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs +3 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +4 -1
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +39 -18
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +40 -19
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +25 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +26 -5
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.cjs +52 -10
- package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.mjs +52 -11
- package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.cjs +20 -3
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +20 -4
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-node-limit.cjs +17 -3
- package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-node-limit.mjs +17 -3
- package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.cjs +7 -2
- package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.mjs +8 -3
- package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +7 -3
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +7 -3
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/api/cwd-option.cjs +58 -0
- package/dist/api/cwd-option.cjs.map +1 -0
- package/dist/api/cwd-option.mjs +52 -0
- package/dist/api/cwd-option.mjs.map +1 -0
- package/dist/api/default-ports.cjs +15 -7
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +14 -8
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/document-refs.cjs +16 -1
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +16 -1
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +6 -26
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +5 -21
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +1 -2
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +2 -3
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/option-errors.cjs +24 -0
- package/dist/api/option-errors.cjs.map +1 -0
- package/dist/api/option-errors.mjs +21 -0
- package/dist/api/option-errors.mjs.map +1 -0
- package/dist/api/ref-limit-options.cjs +58 -0
- package/dist/api/ref-limit-options.cjs.map +1 -0
- package/dist/api/ref-limit-options.mjs +52 -0
- package/dist/api/ref-limit-options.mjs.map +1 -0
- package/dist/api/transform-schema.cjs +12 -5
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +12 -5
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/application/transform/declared-value-types.cjs +36 -0
- package/dist/application/transform/declared-value-types.cjs.map +1 -0
- package/dist/application/transform/declared-value-types.mjs +34 -0
- package/dist/application/transform/declared-value-types.mjs.map +1 -0
- package/dist/application/transform/document/document.cjs +3 -1
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +3 -1
- package/dist/application/transform/document/document.mjs.map +1 -1
- package/dist/application/transform/document/exploded-query-values.cjs +63 -0
- package/dist/application/transform/document/exploded-query-values.cjs.map +1 -0
- package/dist/application/transform/document/exploded-query-values.mjs +59 -0
- package/dist/application/transform/document/exploded-query-values.mjs.map +1 -0
- package/dist/application/transform/document/header.cjs +11 -3
- package/dist/application/transform/document/header.cjs.map +1 -1
- package/dist/application/transform/document/header.mjs +10 -2
- package/dist/application/transform/document/header.mjs.map +1 -1
- package/dist/application/transform/document/parameter.cjs +1 -1
- package/dist/application/transform/document/parameter.cjs.map +1 -1
- package/dist/application/transform/document/parameter.mjs +1 -1
- package/dist/application/transform/document/parameter.mjs.map +1 -1
- package/dist/application/transform/document/parameters.cjs +23 -5
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +23 -5
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-item.cjs +4 -3
- package/dist/application/transform/document/path-item.cjs.map +1 -1
- package/dist/application/transform/document/path-item.mjs +4 -4
- package/dist/application/transform/document/path-item.mjs.map +1 -1
- package/dist/application/transform/document/path-template-key.cjs +84 -0
- package/dist/application/transform/document/path-template-key.cjs.map +1 -0
- package/dist/application/transform/document/path-template-key.mjs +79 -0
- package/dist/application/transform/document/path-template-key.mjs.map +1 -0
- package/dist/application/transform/document/path-template-refs.cjs +80 -0
- package/dist/application/transform/document/path-template-refs.cjs.map +1 -0
- package/dist/application/transform/document/path-template-refs.mjs +77 -0
- package/dist/application/transform/document/path-template-refs.mjs.map +1 -0
- package/dist/application/transform/document/paths-enum.cjs +7 -6
- package/dist/application/transform/document/paths-enum.cjs.map +1 -1
- package/dist/application/transform/document/paths-enum.mjs +7 -6
- package/dist/application/transform/document/paths-enum.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +38 -66
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +36 -66
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/webhooks.cjs +10 -3
- package/dist/application/transform/document/webhooks.cjs.map +1 -1
- package/dist/application/transform/document/webhooks.mjs +9 -2
- package/dist/application/transform/document/webhooks.mjs.map +1 -1
- package/dist/application/transform/footer/document-footer.cjs +6 -3
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +6 -3
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/helper-types.cjs +3 -3
- package/dist/application/transform/helper-types.cjs.map +1 -1
- package/dist/application/transform/helper-types.mjs +3 -3
- package/dist/application/transform/helper-types.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.cjs +4 -4
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.mjs +1 -1
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-shape.cjs +63 -64
- package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-shape.mjs +57 -53
- package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.cjs +2 -2
- package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.mjs +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/located-node.cjs +23 -0
- package/dist/application/transform/ref-pointer/located-node.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/located-node.mjs +18 -0
- package/dist/application/transform/ref-pointer/located-node.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.cjs +69 -14
- package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/original-index.mjs +71 -16
- package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.cjs +2 -2
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-walk.cjs +54 -13
- package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-walk.mjs +46 -7
- package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/property-shape.cjs +57 -0
- package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/property-shape.mjs +49 -0
- package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs +90 -22
- package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/typed-walk.mjs +87 -19
- package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs.map +1 -1
- package/dist/application/transform/schema/access-flags.mjs.map +1 -1
- package/dist/application/transform/schema/index-signature-type.cjs +21 -0
- package/dist/application/transform/schema/index-signature-type.cjs.map +1 -0
- package/dist/application/transform/schema/index-signature-type.mjs +19 -0
- package/dist/application/transform/schema/index-signature-type.mjs.map +1 -0
- package/dist/application/transform/schema/input-location.cjs +23 -0
- package/dist/application/transform/schema/input-location.cjs.map +1 -0
- package/dist/application/transform/schema/input-location.mjs +21 -0
- package/dist/application/transform/schema/input-location.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +15 -5
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +15 -5
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.cjs +2 -1
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +2 -1
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs +2 -30
- package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.mjs +3 -31
- package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
- package/dist/cli/api-logger.cjs +13 -0
- package/dist/cli/api-logger.cjs.map +1 -0
- package/dist/cli/api-logger.mjs +11 -0
- package/dist/cli/api-logger.mjs.map +1 -0
- package/dist/cli/api-settings.cjs +10 -17
- package/dist/cli/api-settings.cjs.map +1 -1
- package/dist/cli/api-settings.mjs +10 -17
- package/dist/cli/api-settings.mjs.map +1 -1
- package/dist/cli/api-writes.cjs +7 -1
- package/dist/cli/api-writes.cjs.map +1 -1
- package/dist/cli/api-writes.mjs +7 -1
- package/dist/cli/api-writes.mjs.map +1 -1
- package/dist/cli/cli-arguments.cjs +32 -74
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +28 -70
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/cli-errors.cjs +18 -0
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +18 -1
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-flag-names.cjs +77 -0
- package/dist/cli/cli-flag-names.cjs.map +1 -0
- package/dist/cli/cli-flag-names.mjs +64 -0
- package/dist/cli/cli-flag-names.mjs.map +1 -0
- package/dist/cli/cli-output.cjs +13 -6
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +14 -7
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/main.cjs +11 -5
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +11 -5
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +33 -12
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +35 -14
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/ref-limits.cjs +15 -1
- package/dist/cli/ref-limits.cjs.map +1 -1
- package/dist/cli/ref-limits.mjs +15 -2
- package/dist/cli/ref-limits.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +24 -7
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +25 -8
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/cli/written-flags.cjs +83 -0
- package/dist/cli/written-flags.cjs.map +1 -0
- package/dist/cli/written-flags.mjs +77 -0
- package/dist/cli/written-flags.mjs.map +1 -0
- package/dist/domain/cause-secrets.cjs +31 -16
- package/dist/domain/cause-secrets.cjs.map +1 -1
- package/dist/domain/cause-secrets.mjs +31 -16
- package/dist/domain/cause-secrets.mjs.map +1 -1
- package/dist/domain/errors.cjs +3 -0
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +3 -0
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/location-text.cjs +15 -0
- package/dist/domain/location-text.cjs.map +1 -0
- package/dist/domain/location-text.mjs +13 -0
- package/dist/domain/location-text.mjs.map +1 -0
- package/dist/domain/openapi/document-places.cjs +55 -0
- package/dist/domain/openapi/document-places.cjs.map +1 -0
- package/dist/domain/openapi/document-places.mjs +53 -0
- package/dist/domain/openapi/document-places.mjs.map +1 -0
- package/dist/domain/output-fixes.cjs +8 -2
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +8 -2
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/terminal-text.cjs +31 -0
- package/dist/domain/terminal-text.cjs.map +1 -0
- package/dist/domain/terminal-text.mjs +29 -0
- package/dist/domain/terminal-text.mjs.map +1 -0
- package/dist/domain/warnings.cjs +1 -0
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +1 -0
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.d.cts +29 -18
- package/dist/index.d.mts +29 -18
- package/dist/index.d.ts +29 -18
- package/package.json +1 -1
- package/src/adapters/node-file-system/node-file-system.ts +14 -1
- package/src/adapters/pipe-safe-writer/pipe-safe-writer.ts +29 -0
- package/src/adapters/redocly-loader/bundled-mapping-copies.ts +7 -42
- package/src/adapters/redocly-loader/component-schemas.ts +19 -0
- package/src/adapters/redocly-loader/mapping-schema-names.ts +25 -0
- package/src/adapters/redocly-loader/query-document-names.ts +79 -0
- package/src/adapters/redocly-loader/query-named-components.ts +200 -0
- package/src/adapters/redocly-loader/redocly-config-source.ts +11 -1
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +63 -17
- package/src/adapters/redocly-loader/ref-access.ts +32 -5
- package/src/adapters/redocly-loader/ref-holders.ts +75 -14
- package/src/adapters/redocly-loader/remote-fetch.ts +37 -2
- package/src/adapters/redocly-loader/remote-node-limit.ts +44 -4
- package/src/adapters/redocly-loader/schema-source.ts +15 -3
- package/src/adapters/terminal-logger/terminal-logger.ts +10 -4
- package/src/api/cwd-option.ts +76 -0
- package/src/api/default-ports.ts +33 -10
- package/src/api/document-refs.ts +29 -1
- package/src/api/document-run.ts +7 -32
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +20 -4
- package/src/api/option-errors.ts +22 -0
- package/src/api/ref-limit-options.ts +69 -0
- package/src/api/transform-schema.ts +20 -5
- package/src/application/ports/file-system.ts +8 -0
- package/src/application/ports/redocly-config-source.ts +5 -0
- package/src/application/transform/declared-value-types.ts +42 -0
- package/src/application/transform/document/document.ts +4 -2
- package/src/application/transform/document/exploded-query-values.ts +88 -0
- package/src/application/transform/document/header.ts +25 -5
- package/src/application/transform/document/parameter.ts +4 -4
- package/src/application/transform/document/parameters.ts +45 -10
- package/src/application/transform/document/path-item.ts +3 -3
- package/src/application/transform/document/path-template-key.ts +152 -0
- package/src/application/transform/document/path-template-refs.ts +127 -0
- package/src/application/transform/document/paths-enum.ts +23 -9
- package/src/application/transform/document/paths.ts +53 -123
- package/src/application/transform/document/webhooks.ts +18 -5
- package/src/application/transform/footer/document-footer.ts +18 -8
- package/src/application/transform/helper-types.ts +4 -4
- package/src/application/transform/ref-pointer/generated-location.ts +1 -1
- package/src/application/transform/ref-pointer/generated-shape.ts +115 -83
- package/src/application/transform/ref-pointer/inline-cycles.ts +1 -1
- package/src/application/transform/ref-pointer/located-node.ts +38 -0
- package/src/application/transform/ref-pointer/original-index.ts +106 -20
- package/src/application/transform/ref-pointer/pointer-type.ts +1 -1
- package/src/application/transform/ref-pointer/pointer-walk.ts +82 -8
- package/src/application/transform/ref-pointer/property-shape.ts +106 -0
- package/src/application/transform/ref-pointer/typed-walk.ts +143 -29
- package/src/application/transform/schema/access-flags.ts +5 -2
- package/src/application/transform/schema/index-signature-type.ts +31 -0
- package/src/application/transform/schema/input-location.ts +35 -0
- package/src/application/transform/schema/object-type.ts +18 -8
- package/src/application/transform/schema/schema-transform.ts +2 -1
- package/src/application/transform/schema/unevaluated-properties.ts +4 -44
- package/src/cli/api-logger.ts +17 -0
- package/src/cli/api-settings.ts +12 -20
- package/src/cli/api-writes.ts +11 -3
- package/src/cli/cli-arguments.ts +57 -92
- package/src/cli/cli-dependencies.ts +7 -2
- package/src/cli/cli-errors.ts +23 -0
- package/src/cli/cli-flag-names.ts +99 -0
- package/src/cli/cli-output.ts +31 -16
- package/src/cli/main.ts +12 -5
- package/src/cli/redocly-apis.ts +56 -20
- package/src/cli/ref-limits.ts +21 -2
- package/src/cli/run-cli.ts +39 -7
- package/src/cli/written-flags.ts +131 -0
- package/src/domain/cause-secrets.ts +59 -25
- package/src/domain/errors.ts +3 -0
- package/src/domain/location-text.ts +27 -0
- package/src/domain/openapi/document-places.ts +78 -0
- package/src/domain/output-fixes.ts +9 -2
- package/src/domain/terminal-text.ts +44 -0
- package/src/domain/warnings.ts +1 -0
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
withEnumsRenamed,
|
|
7
7
|
} from "../application/transform/document/enum-names-given-back.js";
|
|
8
8
|
import { operationKeysWritten } from "../application/transform/document/operation-keys-written.js";
|
|
9
|
+
import {
|
|
10
|
+
unmatchedTemplateKeys,
|
|
11
|
+
withTemplatePathRefs,
|
|
12
|
+
} from "../application/transform/document/path-template-refs.js";
|
|
9
13
|
import { renameTakenAliases } from "../application/transform/document/root-type-aliases.js";
|
|
10
14
|
import { RunFooter, type RunFooterNames } from "../application/transform/footer/document-footer.js";
|
|
11
15
|
import { EnumNameClaims } from "../application/transform/footer/enum-name-claims.js";
|
|
@@ -144,6 +148,20 @@ function enumValuesChecked(
|
|
|
144
148
|
return checked.footer;
|
|
145
149
|
}
|
|
146
150
|
|
|
151
|
+
/** The document with its references into templated paths indexed by their templates. */
|
|
152
|
+
function withTemplateRefs(
|
|
153
|
+
{ body, footer, closing }: TransformedDocument,
|
|
154
|
+
keys: ReadonlyMap<string, string>,
|
|
155
|
+
): TransformedDocument {
|
|
156
|
+
return {
|
|
157
|
+
body: withTemplatePathRefs(body, keys),
|
|
158
|
+
footer: footer.map((entry) =>
|
|
159
|
+
isIrDeclaration(entry) ? (withTemplatePathRefs([entry], keys)[0] ?? entry) : entry,
|
|
160
|
+
),
|
|
161
|
+
closing: withTemplatePathRefs(closing, keys),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
147
165
|
/** @internal Root types, the footer, then the closing declarations (Phase 5, step 6). */
|
|
148
166
|
export function transformDocument(schema: OpenAPI3, ctx: RunContext): TransformedDocument {
|
|
149
167
|
const document = schema as DocumentObject;
|
|
@@ -160,11 +178,8 @@ export function transformDocument(schema: OpenAPI3, ctx: RunContext): Transforme
|
|
|
160
178
|
const rawClosing = documentClosing(document, context, rawFooter.some(isOperations));
|
|
161
179
|
const parts = { body: rawBody, footer: rawFooter, closing: rawClosing };
|
|
162
180
|
const { body, footer, closing } = withEnumNamesGivenBack(parts, names);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
footer,
|
|
166
|
-
closing,
|
|
167
|
-
};
|
|
181
|
+
const named = { body: renameTakenAliases(body, footer.filter(isIrDeclaration), closing), footer };
|
|
182
|
+
return withTemplateRefs({ ...named, closing }, unmatchedTemplateKeys(document.paths, context));
|
|
168
183
|
}
|
|
169
184
|
|
|
170
185
|
/**
|
|
@@ -29,6 +29,14 @@ export interface DirectoryCheck {
|
|
|
29
29
|
isDirectory(file: URL): boolean;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Whether a `file:` location is an existing file. A schema argument with a `*` is a glob pattern
|
|
34
|
+
* only when no file has that name.
|
|
35
|
+
*/
|
|
36
|
+
export interface FileCheck {
|
|
37
|
+
isFile(file: URL): boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
/**
|
|
33
41
|
* An output file that exists before its content is written: the claim created it, empty, when it
|
|
34
42
|
* was missing, so the file system has given it its own identity.
|
|
@@ -17,4 +17,9 @@ export interface RedoclyConfigSource {
|
|
|
17
17
|
* when the ignore file of the working directory is bad.
|
|
18
18
|
*/
|
|
19
19
|
createDefault(): Promise<RedoclyConfig>;
|
|
20
|
+
/**
|
|
21
|
+
* The config one API of `config` is linted with: the API's own `rules` (and other lint
|
|
22
|
+
* settings) under `apis.<name>` in place of the root's, as `redocly lint <name>` reads them.
|
|
23
|
+
*/
|
|
24
|
+
forApi(config: RedoclyConfig, apiName: string): RedoclyConfig;
|
|
20
25
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { irKeyword, irReference } from "../../domain/ir/constructors.js";
|
|
2
|
+
import type { IrMember, IrType } from "../../domain/ir/nodes.js";
|
|
3
|
+
import { HELPER_TYPES } from "./helper-types.js";
|
|
4
|
+
import type { FooterDeclarations } from "./schema/schema-context.js";
|
|
5
|
+
|
|
6
|
+
/** The footer part that declares the `PropertyValues` helper type. */
|
|
7
|
+
export type PropertyValuesFooter = Pick<FooterDeclarations, "requirePropertyValues">;
|
|
8
|
+
|
|
9
|
+
function memberValueTypes(member: IrMember): IrType[] {
|
|
10
|
+
if (member.kind === "indexSignature") {
|
|
11
|
+
return [member.type];
|
|
12
|
+
}
|
|
13
|
+
return member.isOptional ? [member.type, irKeyword("undefined")] : [member.type];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The value types a key of the type can have, read from its IR: the members of object types,
|
|
18
|
+
* through unions and intersections. A reference (a `$ref`, `Omit`, `WithRequired`) or a raw
|
|
19
|
+
* type is read with `PropertyValues`. Primitives, literals and arrays declare no keys.
|
|
20
|
+
*/
|
|
21
|
+
export function declaredValueTypes(type: IrType, footer: PropertyValuesFooter): IrType[] {
|
|
22
|
+
switch (type.kind) {
|
|
23
|
+
case "object":
|
|
24
|
+
return type.members.flatMap(memberValueTypes);
|
|
25
|
+
case "union":
|
|
26
|
+
case "intersection":
|
|
27
|
+
return type.types.flatMap((member) => declaredValueTypes(member, footer));
|
|
28
|
+
case "reference":
|
|
29
|
+
case "indexedAccess":
|
|
30
|
+
case "raw":
|
|
31
|
+
footer.requirePropertyValues();
|
|
32
|
+
return [irReference(HELPER_TYPES.propertyValues.name, [type])];
|
|
33
|
+
case "keyword":
|
|
34
|
+
case "stringLiteral":
|
|
35
|
+
case "numberLiteral":
|
|
36
|
+
case "booleanLiteral":
|
|
37
|
+
case "array":
|
|
38
|
+
case "tuple":
|
|
39
|
+
case "readonly":
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -9,13 +9,14 @@ import type {
|
|
|
9
9
|
} from "../../../domain/ir/nodes.js";
|
|
10
10
|
import type { ComponentsObject } from "../../../domain/openapi/components-object.js";
|
|
11
11
|
import type { DocumentObject } from "../../../domain/openapi/document-object.js";
|
|
12
|
-
import type { PathsObject } from "../../../domain/openapi/path-item-object.js";
|
|
12
|
+
import type { OperationEntry, PathsObject } from "../../../domain/openapi/path-item-object.js";
|
|
13
13
|
import { READ_WRITE_MARKER_TYPES } from "../helper-types.js";
|
|
14
14
|
import type { TransformContext, TransformOptions } from "../transform-context.js";
|
|
15
15
|
import { componentsType } from "./components.js";
|
|
16
16
|
import { type DeclaredTypeLookup, declaredTypeLookup } from "./declared-types.js";
|
|
17
17
|
import { defsRootType } from "./defs-root.js";
|
|
18
18
|
import { keptDeprecatedComponents } from "./kept-deprecated.js";
|
|
19
|
+
import { isIncludedOperation } from "./path-item.js";
|
|
19
20
|
import { pathMembers, pathsObjectType } from "./paths.js";
|
|
20
21
|
import { apiPathsEnumDeclaration } from "./paths-enum.js";
|
|
21
22
|
import { webhooksType } from "./webhooks.js";
|
|
@@ -210,7 +211,8 @@ export function documentClosing(
|
|
|
210
211
|
declarations.push(emptyAlias(OPERATIONS_NAME));
|
|
211
212
|
}
|
|
212
213
|
if (context.options.makePathsEnum && document.paths) {
|
|
213
|
-
|
|
214
|
+
const isIncluded = (operation: OperationEntry) => isIncludedOperation(operation, context);
|
|
215
|
+
declarations.push(apiPathsEnumDeclaration(document.paths, isIncluded));
|
|
214
216
|
}
|
|
215
217
|
return declarations;
|
|
216
218
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { IrMember, IrType } from "../../../domain/ir/nodes.js";
|
|
2
|
+
import type { Schema } from "../../../domain/openapi/schema-object.js";
|
|
3
|
+
import { transformSchema } from "../schema/schema-transform.js";
|
|
4
|
+
import type { TransformContext } from "../transform-context.js";
|
|
5
|
+
import { unionOf } from "../type-combinators.js";
|
|
6
|
+
import type { ResolvedEntry } from "./parameter-entries.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `exploded-query-objects` and index signatures. The keys of an exploded object are keys of
|
|
10
|
+
* `query`, next to the other parameters. TypeScript checks an index signature against every key
|
|
11
|
+
* of a value, so `{ page?: number } & { [key: string]: string }` admits no `page`, and no value
|
|
12
|
+
* with another parameter at all. An index signature of an exploded object therefore also takes
|
|
13
|
+
* the value types of the other keys of `query`: those keys carry their own values.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
function refOf(value: unknown): string | undefined {
|
|
17
|
+
const ref = (value as { $ref?: unknown } | undefined)?.$ref;
|
|
18
|
+
return typeof ref === "string" ? ref : undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** A schema `$ref` chain followed to its end, with the pointer where that schema is declared. */
|
|
22
|
+
function declaredSchema(schema: Schema | undefined, ref: string, context: TransformContext) {
|
|
23
|
+
let declared = { schema, path: ref };
|
|
24
|
+
const seen = new Set<string>();
|
|
25
|
+
for (let next = refOf(schema); next !== undefined && !seen.has(next); ) {
|
|
26
|
+
seen.add(next);
|
|
27
|
+
declared = { schema: context.refs.resolve(next) as Schema | undefined, path: next };
|
|
28
|
+
next = refOf(declared.schema);
|
|
29
|
+
}
|
|
30
|
+
return declared;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The type of an exploded parameter whose own type is a reference (its `$ref`, or the `$ref` of
|
|
35
|
+
* its schema), written out where its schema is declared: the index signature of a referenced type
|
|
36
|
+
* cannot be changed. The location is the one `components` types it at, so the enums it declares
|
|
37
|
+
* are the ones the reference names. Null when no `$ref` is involved.
|
|
38
|
+
*/
|
|
39
|
+
export function declaredObjectType(entry: ResolvedEntry, context: TransformContext): IrType | null {
|
|
40
|
+
const { original, resolved } = entry;
|
|
41
|
+
const schemaRef = refOf(resolved.schema);
|
|
42
|
+
if (schemaRef !== undefined) {
|
|
43
|
+
const { schema, path } = declaredSchema(resolved.schema, schemaRef, context);
|
|
44
|
+
return transformSchema(schema, { path, schema }, context);
|
|
45
|
+
}
|
|
46
|
+
const parameterRef = refOf(original);
|
|
47
|
+
return parameterRef === undefined
|
|
48
|
+
? null
|
|
49
|
+
: transformSchema(resolved.schema, { path: parameterRef, schema: resolved }, context);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isIndexSignature(member: IrMember): boolean {
|
|
53
|
+
return member.kind === "indexSignature";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Whether the type has an index signature in its objects, through unions and intersections. */
|
|
57
|
+
export function hasIndexSignature(type: IrType): boolean {
|
|
58
|
+
switch (type.kind) {
|
|
59
|
+
case "object":
|
|
60
|
+
return type.members.some(isIndexSignature);
|
|
61
|
+
case "union":
|
|
62
|
+
case "intersection":
|
|
63
|
+
return type.types.some(hasIndexSignature);
|
|
64
|
+
default:
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function widenedMember(member: IrMember, values: readonly IrType[]): IrMember {
|
|
70
|
+
// `unknown` takes every value already.
|
|
71
|
+
const isUnknown = member.type.kind === "keyword" && member.type.keyword === "unknown";
|
|
72
|
+
return isIndexSignature(member) && !isUnknown
|
|
73
|
+
? { ...member, type: unionOf([member.type, ...values]) }
|
|
74
|
+
: member;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The type with the values added to each index signature of its objects. */
|
|
78
|
+
export function withIndexValues(type: IrType, values: readonly IrType[]): IrType {
|
|
79
|
+
switch (type.kind) {
|
|
80
|
+
case "object":
|
|
81
|
+
return { ...type, members: type.members.map((member) => widenedMember(member, values)) };
|
|
82
|
+
case "union":
|
|
83
|
+
case "intersection":
|
|
84
|
+
return { ...type, types: type.types.map((member) => withIndexValues(member, values)) };
|
|
85
|
+
default:
|
|
86
|
+
return type;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -2,6 +2,8 @@ import { irObject } from "../../../domain/ir/constructors.js";
|
|
|
2
2
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
3
3
|
import type { HeaderObject } from "../../../domain/openapi/header-object.js";
|
|
4
4
|
import { escapePointerSegment } from "../../../domain/openapi/json-pointer.js";
|
|
5
|
+
import type { ContentMap } from "../../../domain/openapi/media-type-object.js";
|
|
6
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
5
7
|
import { documentEntries } from "../document-entries.js";
|
|
6
8
|
import type { SchemaContext, SchemaLocation } from "../schema/schema-context.js";
|
|
7
9
|
import { transformSchema } from "../schema/schema-transform.js";
|
|
@@ -10,8 +12,10 @@ import { documentMember } from "./document-member.js";
|
|
|
10
12
|
import { contentEntryType } from "./media-type.js";
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
|
-
* A header's type (OpenAPI 3.1 §4.8.21): its schema, else
|
|
14
|
-
*
|
|
15
|
+
* A header's type (OpenAPI 3.1 §4.8.21): its schema, else the type of its `content`, else
|
|
16
|
+
* `unknown`. `content` holds one media type whose schema describes the value; the original typed
|
|
17
|
+
* it as an object with one property per media type, which the `parameter-header-content` fix
|
|
18
|
+
* replaces by the media type's type, as for a parameter.
|
|
15
19
|
*/
|
|
16
20
|
export function headerType(
|
|
17
21
|
header: HeaderObject,
|
|
@@ -24,11 +28,27 @@ export function headerType(
|
|
|
24
28
|
if (!header.content) {
|
|
25
29
|
return UNKNOWN_TYPE;
|
|
26
30
|
}
|
|
31
|
+
if (context.options.fixes.has(FIX.PARAMETER_HEADER_CONTENT)) {
|
|
32
|
+
// The first media type in document order, as for a parameter: `--alphabetize` sorts only
|
|
33
|
+
// the members it writes.
|
|
34
|
+
const first = Object.entries(header.content)[0];
|
|
35
|
+
return first === undefined ? UNKNOWN_TYPE : mediaType(...first, location, context);
|
|
36
|
+
}
|
|
27
37
|
const members = documentEntries(header.content, context.options).map(([contentType, entry]) => {
|
|
28
|
-
|
|
29
|
-
const path = `${location.path ?? "#"}/${escapePointerSegment(contentType)}`;
|
|
30
|
-
const type = contentEntryType(entry, { ...location, path }, context);
|
|
38
|
+
const type = mediaType(contentType, entry, location, context);
|
|
31
39
|
return documentMember(contentType, type, entry, { isReadonly: context.options.immutable });
|
|
32
40
|
});
|
|
33
41
|
return irObject(members);
|
|
34
42
|
}
|
|
43
|
+
|
|
44
|
+
/** The type of one media type of a header, at the path the original gave it. */
|
|
45
|
+
function mediaType(
|
|
46
|
+
contentType: string,
|
|
47
|
+
entry: ContentMap[string],
|
|
48
|
+
location: SchemaLocation,
|
|
49
|
+
context: SchemaContext,
|
|
50
|
+
): IrType {
|
|
51
|
+
// Unlike other content maps, the original joins this path by hand: a missing path is `#`.
|
|
52
|
+
const path = `${location.path ?? "#"}/${escapePointerSegment(contentType)}`;
|
|
53
|
+
return contentEntryType(entry, { ...location, path }, context);
|
|
54
|
+
}
|
|
@@ -13,7 +13,7 @@ import { contentEntryType } from "./media-type.js";
|
|
|
13
13
|
/**
|
|
14
14
|
* A parameter typed by the schema of its one `content` media type. An `in: querystring` parameter
|
|
15
15
|
* (OpenAPI 3.2) is the whole query string (ADR-020); without a media type it is `string`, the
|
|
16
|
-
* query string as text. With the `parameter-content` fix, any other parameter with `content`
|
|
16
|
+
* query string as text. With the `parameter-header-content` fix, any other parameter with `content`
|
|
17
17
|
* (OpenAPI 3.0 and later, for a JSON value in a query parameter) is typed the same way.
|
|
18
18
|
*/
|
|
19
19
|
function contentParameterType(
|
|
@@ -34,14 +34,14 @@ function isTypedByContent(parameter: ParameterObject, context: SchemaContext): b
|
|
|
34
34
|
return true;
|
|
35
35
|
}
|
|
36
36
|
const hasContent = parameter.schema === undefined && parameter.content !== undefined;
|
|
37
|
-
return hasContent && context.options.fixes.has(FIX.
|
|
37
|
+
return hasContent && context.options.fixes.has(FIX.PARAMETER_HEADER_CONTENT);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* A parameter's type (OpenAPI 3.2 §4.8.12). Without a schema it is `string`, not `unknown`:
|
|
42
42
|
* query, path, header and cookie values all arrive as text. `content` is read for
|
|
43
|
-
* `in: querystring`, and with the `parameter-content` fix for every parameter; without
|
|
44
|
-
* other parameters with `content` keep the original's `string`.
|
|
43
|
+
* `in: querystring`, and with the `parameter-header-content` fix for every parameter; without
|
|
44
|
+
* the fix other parameters with `content` keep the original's `string`.
|
|
45
45
|
*/
|
|
46
46
|
export function parameterType(
|
|
47
47
|
parameter: ParameterObject,
|
|
@@ -16,10 +16,12 @@ import {
|
|
|
16
16
|
QUERYSTRING_LOCATION,
|
|
17
17
|
} from "../../../domain/openapi/parameter-object.js";
|
|
18
18
|
import { FIX } from "../../../domain/output-fixes.js";
|
|
19
|
+
import { declaredValueTypes } from "../declared-value-types.js";
|
|
19
20
|
import type { SchemaLocation } from "../schema/schema-context.js";
|
|
20
21
|
import { withSchemaComment } from "../schema-comment.js";
|
|
21
22
|
import type { TransformContext } from "../transform-context.js";
|
|
22
23
|
import { isExplodedQueryObject } from "./exploded-query.js";
|
|
24
|
+
import { declaredObjectType, hasIndexSignature, withIndexValues } from "./exploded-query-values.js";
|
|
23
25
|
import { parameterType } from "./parameter.js";
|
|
24
26
|
import {
|
|
25
27
|
type ParameterEntry,
|
|
@@ -126,17 +128,50 @@ function isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boole
|
|
|
126
128
|
);
|
|
127
129
|
}
|
|
128
130
|
|
|
131
|
+
/** An exploded object parameter with its type, typed in document order. */
|
|
132
|
+
interface ExplodedEntry {
|
|
133
|
+
readonly entry: ResolvedEntry;
|
|
134
|
+
readonly type: IrType;
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
138
|
+
* The object type of an exploded parameter, written out when it is a reference to a type with an
|
|
139
|
+
* index signature and `query` has other keys, which that signature must then admit. Without
|
|
140
|
+
* other keys the reference is kept.
|
|
132
141
|
*/
|
|
133
|
-
function
|
|
134
|
-
entry:
|
|
135
|
-
|
|
142
|
+
function explodedObjectType(
|
|
143
|
+
{ entry, type }: ExplodedEntry,
|
|
144
|
+
hasOtherKeys: boolean,
|
|
136
145
|
context: TransformContext,
|
|
137
146
|
): IrType {
|
|
138
|
-
|
|
139
|
-
|
|
147
|
+
if (!hasOtherKeys) {
|
|
148
|
+
return type;
|
|
149
|
+
}
|
|
150
|
+
const declared = declaredObjectType(entry, context);
|
|
151
|
+
return declared !== null && hasIndexSignature(declared) ? declared : type;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The exploded object parameters' parts of `query`: their object types, each index signature
|
|
156
|
+
* widened by the value types of the other keys (see `exploded-query-values.ts`). A parameter that
|
|
157
|
+
* may be left out sends none of its keys then, so they are optional: `Partial<…>`.
|
|
158
|
+
*/
|
|
159
|
+
function explodedParts(
|
|
160
|
+
exploded: readonly ExplodedEntry[],
|
|
161
|
+
members: readonly IrPropertySignature[],
|
|
162
|
+
context: TransformContext,
|
|
163
|
+
): IrType[] {
|
|
164
|
+
const hasOtherKeys = members.length > 0 || exploded.length > 1;
|
|
165
|
+
const types = exploded.map((part) => explodedObjectType(part, hasOtherKeys, context));
|
|
166
|
+
const others = (index: number) => [
|
|
167
|
+
...(members.length > 0 ? [irObject(members)] : []),
|
|
168
|
+
...types.filter((_type, other) => other !== index),
|
|
169
|
+
];
|
|
170
|
+
return types.map((type, index) => {
|
|
171
|
+
const values = others(index).flatMap((other) => declaredValueTypes(other, context.footer));
|
|
172
|
+
const widened = withIndexValues(type, values);
|
|
173
|
+
return exploded[index]?.entry.resolved.required ? widened : irReference("Partial", [widened]);
|
|
174
|
+
});
|
|
140
175
|
}
|
|
141
176
|
|
|
142
177
|
/** A location's parameters as members, and the object types of its exploded parameters. */
|
|
@@ -153,11 +188,11 @@ function locationParts(
|
|
|
153
188
|
context: TransformContext,
|
|
154
189
|
): LocationParts {
|
|
155
190
|
const members: IrPropertySignature[] = [];
|
|
156
|
-
const exploded:
|
|
191
|
+
const exploded: ExplodedEntry[] = [];
|
|
157
192
|
let isOptional = true;
|
|
158
193
|
for (const entry of entries) {
|
|
159
194
|
if (isExplodedEntry(entry, context)) {
|
|
160
|
-
exploded.push(
|
|
195
|
+
exploded.push({ entry, type: entryType(entry, location, context) });
|
|
161
196
|
isOptional &&= !entry.resolved.required;
|
|
162
197
|
continue;
|
|
163
198
|
}
|
|
@@ -165,7 +200,7 @@ function locationParts(
|
|
|
165
200
|
members.push(member);
|
|
166
201
|
isOptional &&= member.isOptional;
|
|
167
202
|
}
|
|
168
|
-
return { members, exploded, isOptional };
|
|
203
|
+
return { members, exploded: explodedParts(exploded, members, context), isOptional };
|
|
169
204
|
}
|
|
170
205
|
|
|
171
206
|
/** The members' object, intersected with the exploded parameters' types; `never` for none. */
|
|
@@ -29,7 +29,7 @@ export function operationKeyOf(operationId: string): string {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/** Whether the method has an operation, not removed by `--exclude-deprecated`. */
|
|
32
|
-
function
|
|
32
|
+
export function isIncludedOperation(
|
|
33
33
|
operation: OperationEntry | undefined,
|
|
34
34
|
context: TransformContext,
|
|
35
35
|
): operation is OperationEntry {
|
|
@@ -94,7 +94,7 @@ function methodMember(
|
|
|
94
94
|
context: TransformContext,
|
|
95
95
|
): IrPropertySignature {
|
|
96
96
|
const operation = pathItem[method];
|
|
97
|
-
if (!
|
|
97
|
+
if (!isIncludedOperation(operation, context)) {
|
|
98
98
|
const isReadonly = context.options.immutable;
|
|
99
99
|
return irProperty(toPropertyName(method), irKeyword("never"), { isOptional: true, isReadonly });
|
|
100
100
|
}
|
|
@@ -113,7 +113,7 @@ function additionalOperationsMember(
|
|
|
113
113
|
): IrPropertySignature | null {
|
|
114
114
|
const entries = documentEntries(pathItem.additionalOperations ?? {}, context.options);
|
|
115
115
|
const members = entries
|
|
116
|
-
.filter(([, operation]) =>
|
|
116
|
+
.filter(([, operation]) => isIncludedOperation(operation, context))
|
|
117
117
|
.map(([method, operation]) => {
|
|
118
118
|
const path = appendPointer(location.path, [ADDITIONAL_OPERATIONS_KEY, method]);
|
|
119
119
|
return operationMember({ name: method, operation, path }, pathItem, location, context);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { escapeTemplateText } from "../../../domain/ir/raw-text-escapes.js";
|
|
2
|
+
import type { OperationObject } from "../../../domain/openapi/operation-object.js";
|
|
3
|
+
import type {
|
|
4
|
+
ParameterObject,
|
|
5
|
+
ParameterOrReference,
|
|
6
|
+
} from "../../../domain/openapi/parameter-object.js";
|
|
7
|
+
import {
|
|
8
|
+
type PathItemObject,
|
|
9
|
+
pathItemOperations,
|
|
10
|
+
} from "../../../domain/openapi/path-item-object.js";
|
|
11
|
+
import type { ReferenceSchema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
12
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
13
|
+
import type { TransformContext } from "../transform-context.js";
|
|
14
|
+
import type { PathKeyPart, PathPlaceholder } from "./path-key-overlaps.js";
|
|
15
|
+
import {
|
|
16
|
+
type PathParameterMatch,
|
|
17
|
+
placeholderText,
|
|
18
|
+
replacedTemplateParts,
|
|
19
|
+
} from "./path-template-replace.js";
|
|
20
|
+
|
|
21
|
+
/** The `--path-params-as-types` key of a path: its URL with a placeholder per parameter. */
|
|
22
|
+
|
|
23
|
+
/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */
|
|
24
|
+
const PATH_PARAMETER_RE = /\{[^{}]+\}/g;
|
|
25
|
+
|
|
26
|
+
/** Placeholders by parameter schema type; anything else is a string placeholder. */
|
|
27
|
+
const PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([
|
|
28
|
+
["number", "number"],
|
|
29
|
+
["integer", "number"],
|
|
30
|
+
["boolean", "boolean"],
|
|
31
|
+
]);
|
|
32
|
+
const STRING_PLACEHOLDER: PathPlaceholder = "string";
|
|
33
|
+
|
|
34
|
+
function resolvedParameter(
|
|
35
|
+
parameter: ParameterOrReference,
|
|
36
|
+
context: TransformContext,
|
|
37
|
+
): ParameterObject | undefined {
|
|
38
|
+
return "$ref" in parameter && parameter.$ref
|
|
39
|
+
? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)
|
|
40
|
+
: (parameter as ParameterObject);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function addPathParameters(
|
|
44
|
+
parameters: readonly ParameterOrReference[],
|
|
45
|
+
byName: Map<string, ParameterObject>,
|
|
46
|
+
context: TransformContext,
|
|
47
|
+
): void {
|
|
48
|
+
for (const parameter of parameters) {
|
|
49
|
+
const resolved = resolvedParameter(parameter, context);
|
|
50
|
+
if (resolved && resolved.in === "path") {
|
|
51
|
+
byName.set(resolved.name, resolved);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Path parameters of the path item and of its operations; later definitions win. */
|
|
57
|
+
function pathParameters(
|
|
58
|
+
pathItem: PathItemObject,
|
|
59
|
+
context: TransformContext,
|
|
60
|
+
): Map<string, ParameterObject> {
|
|
61
|
+
const byName = new Map<string, ParameterObject>();
|
|
62
|
+
addPathParameters(pathItem.parameters ?? [], byName, context);
|
|
63
|
+
for (const { operation: entry } of pathItemOperations(pathItem)) {
|
|
64
|
+
const operation = (entry as ReferenceSchema).$ref
|
|
65
|
+
? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)
|
|
66
|
+
: (entry as OperationObject);
|
|
67
|
+
addPathParameters(operation?.parameters ?? [], byName, context);
|
|
68
|
+
}
|
|
69
|
+
return byName;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */
|
|
73
|
+
function splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {
|
|
74
|
+
return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {
|
|
75
|
+
const type = matches[index]?.type;
|
|
76
|
+
const textPart: PathKeyPart = { kind: "text", text };
|
|
77
|
+
return type === undefined ? [textPart] : [textPart, { kind: "placeholder", type }];
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for
|
|
83
|
+
* its parameter's type, the way the original replaces them unless the `path-param-type-names` fix
|
|
84
|
+
* is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.
|
|
85
|
+
*/
|
|
86
|
+
export function pathTemplateParts(
|
|
87
|
+
url: string,
|
|
88
|
+
pathItem: PathItemObject,
|
|
89
|
+
context: TransformContext,
|
|
90
|
+
): PathKeyPart[] | null {
|
|
91
|
+
const found = url.match(PATH_PARAMETER_RE);
|
|
92
|
+
if (!found) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const parameters = pathParameters(pathItem, context);
|
|
96
|
+
const matches = found.map((match): PathParameterMatch => {
|
|
97
|
+
const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;
|
|
98
|
+
return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
|
|
99
|
+
});
|
|
100
|
+
return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES)
|
|
101
|
+
? splitTemplateParts(url, matches)
|
|
102
|
+
: replacedTemplateParts(url, matches);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The template literal type of the parts. The original escaped only backticks: a backslash or
|
|
107
|
+
* `${` in the URL could end the literal or open a placeholder, and add code to the generated file
|
|
108
|
+
* (intentional fix). So the text parts are escaped.
|
|
109
|
+
*/
|
|
110
|
+
export function templateText(parts: readonly PathKeyPart[]): string {
|
|
111
|
+
const text = parts
|
|
112
|
+
.map((part) =>
|
|
113
|
+
part.kind === "text" ? escapeTemplateText(part.text) : placeholderText(part.type),
|
|
114
|
+
)
|
|
115
|
+
.join("");
|
|
116
|
+
return `\`${text}\``;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const BOOLEAN_TEXTS = ["true", "false"] as const;
|
|
120
|
+
|
|
121
|
+
const isBooleanPlaceholder = (part: PathKeyPart): boolean =>
|
|
122
|
+
part.kind === "placeholder" && part.type === "boolean";
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The keys of a template whose only placeholders are `${boolean}`, with each written as `true`
|
|
126
|
+
* and as `false`. Such a template is a union of literals, and an index signature takes none
|
|
127
|
+
* (TS1337), so the original's `` [path: `/flags/${boolean}`] `` did not compile. A path with n
|
|
128
|
+
* boolean parameters gets 2ⁿ plain URLs (`/flags/true`), all with the same path item type. Next to
|
|
129
|
+
* another placeholder the template is a pattern, a valid signature that admits the same URLs, so
|
|
130
|
+
* those parts stay one key.
|
|
131
|
+
*/
|
|
132
|
+
export function booleanExpandedKeys(parts: readonly PathKeyPart[]): PathKeyPart[][] {
|
|
133
|
+
const isBooleanOnly = parts.every((part) => part.kind === "text" || isBooleanPlaceholder(part));
|
|
134
|
+
if (!isBooleanOnly) {
|
|
135
|
+
return [[...parts]];
|
|
136
|
+
}
|
|
137
|
+
return parts.reduce<PathKeyPart[][]>(
|
|
138
|
+
(keys, part) => {
|
|
139
|
+
const choices: readonly PathKeyPart[] = isBooleanPlaceholder(part)
|
|
140
|
+
? BOOLEAN_TEXTS.map((text) => ({ kind: "text", text }))
|
|
141
|
+
: [part];
|
|
142
|
+
return keys.flatMap((key) => choices.map((choice) => [...key, choice]));
|
|
143
|
+
},
|
|
144
|
+
[[]],
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** The URL of parts without placeholders; null when one is left. */
|
|
149
|
+
export function plainUrlOf(parts: readonly PathKeyPart[]): string | null {
|
|
150
|
+
const texts = parts.map((part) => (part.kind === "text" ? part.text : null));
|
|
151
|
+
return texts.includes(null) ? null : texts.join("");
|
|
152
|
+
}
|