openapi-typesafe 1.0.0-rc.3 → 1.0.0-rc.4
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 +1831 -0
- package/dist/adapters/node-file-system/file-claims.cjs +105 -0
- package/dist/adapters/node-file-system/file-claims.cjs.map +1 -0
- package/dist/adapters/node-file-system/file-claims.mjs +95 -0
- package/dist/adapters/node-file-system/file-claims.mjs.map +1 -0
- package/dist/adapters/node-file-system/file-identity.cjs +82 -0
- package/dist/adapters/node-file-system/file-identity.cjs.map +1 -0
- package/dist/adapters/node-file-system/file-identity.mjs +74 -0
- package/dist/adapters/node-file-system/file-identity.mjs.map +1 -0
- package/dist/adapters/node-file-system/node-file-system.cjs +90 -14
- package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
- package/dist/adapters/node-file-system/node-file-system.mjs +90 -14
- package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +75 -0
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +72 -0
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +1 -1
- package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -1
- package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +2 -2
- package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -1
- package/dist/adapters/redocly-loader/loaded-documents.cjs +28 -0
- package/dist/adapters/redocly-loader/loaded-documents.cjs.map +1 -0
- package/dist/adapters/redocly-loader/loaded-documents.mjs +21 -0
- package/dist/adapters/redocly-loader/loaded-documents.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +14 -15
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +12 -13
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +31 -3
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +31 -3
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.cjs +2 -2
- package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.mjs +3 -3
- package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-body-limit.cjs +50 -0
- package/dist/adapters/redocly-loader/remote-body-limit.cjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-body-limit.mjs +48 -0
- package/dist/adapters/redocly-loader/remote-body-limit.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +35 -6
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +35 -6
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-node-limit.cjs +47 -0
- package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-node-limit.mjs +44 -0
- package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -0
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +32 -8
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +32 -9
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.cjs +11 -7
- package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.mjs +12 -8
- package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +3 -5
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +3 -5
- 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/api/default-ports.cjs +14 -2
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +14 -2
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/discriminator-enum-parent.cjs +2 -2
- package/dist/api/discriminator-enum-parent.cjs.map +1 -1
- package/dist/api/discriminator-enum-parent.mjs +3 -3
- package/dist/api/discriminator-enum-parent.mjs.map +1 -1
- package/dist/api/discriminator-other-owners.cjs +5 -3
- package/dist/api/discriminator-other-owners.cjs.map +1 -1
- package/dist/api/discriminator-other-owners.mjs +5 -3
- package/dist/api/discriminator-other-owners.mjs.map +1 -1
- package/dist/api/discriminator-patch.cjs +5 -1
- package/dist/api/discriminator-patch.cjs.map +1 -1
- package/dist/api/discriminator-patch.mjs +5 -1
- package/dist/api/discriminator-patch.mjs.map +1 -1
- package/dist/api/discriminator-scan.cjs +15 -8
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +15 -8
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-run.cjs +2 -2
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +2 -2
- package/dist/api/document-run.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 +8 -4
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +8 -5
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/schema-callbacks.cjs +36 -12
- package/dist/api/schema-callbacks.cjs.map +1 -1
- package/dist/api/schema-callbacks.mjs +36 -12
- package/dist/api/schema-callbacks.mjs.map +1 -1
- package/dist/api/transform-context.cjs +7 -3
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +7 -3
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +40 -10
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +41 -11
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/application/print/text-writer.cjs +10 -3
- package/dist/application/print/text-writer.cjs.map +1 -1
- package/dist/application/print/text-writer.mjs +10 -3
- package/dist/application/print/text-writer.mjs.map +1 -1
- package/dist/application/stack-overflow.cjs +2 -1
- package/dist/application/stack-overflow.cjs.map +1 -1
- package/dist/application/stack-overflow.mjs +2 -1
- package/dist/application/stack-overflow.mjs.map +1 -1
- package/dist/application/transform/document/components.cjs +1 -1
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +2 -2
- package/dist/application/transform/document/components.mjs.map +1 -1
- package/dist/application/transform/document/declared-type-names.cjs +23 -0
- package/dist/application/transform/document/declared-type-names.cjs.map +1 -0
- package/dist/application/transform/document/declared-type-names.mjs +20 -0
- package/dist/application/transform/document/declared-type-names.mjs.map +1 -0
- package/dist/application/transform/document/defs-root.cjs +1 -1
- package/dist/application/transform/document/defs-root.cjs.map +1 -1
- package/dist/application/transform/document/defs-root.mjs +2 -2
- package/dist/application/transform/document/defs-root.mjs.map +1 -1
- package/dist/application/transform/document/document.cjs +4 -1
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +3 -2
- package/dist/application/transform/document/document.mjs.map +1 -1
- package/dist/application/transform/document/enum-names-given-back.cjs +62 -0
- package/dist/application/transform/document/enum-names-given-back.cjs.map +1 -0
- package/dist/application/transform/document/enum-names-given-back.mjs +58 -0
- package/dist/application/transform/document/enum-names-given-back.mjs.map +1 -0
- package/dist/application/transform/document/global-type-references.cjs +1 -0
- package/dist/application/transform/document/global-type-references.cjs.map +1 -1
- package/dist/application/transform/document/global-type-references.mjs +1 -1
- package/dist/application/transform/document/global-type-references.mjs.map +1 -1
- package/dist/application/transform/document/media-type.cjs +2 -2
- package/dist/application/transform/document/media-type.cjs.map +1 -1
- package/dist/application/transform/document/media-type.mjs +3 -3
- package/dist/application/transform/document/media-type.mjs.map +1 -1
- package/dist/application/transform/document/operation-keys-written.cjs +26 -0
- package/dist/application/transform/document/operation-keys-written.cjs.map +1 -0
- package/dist/application/transform/document/operation-keys-written.mjs +24 -0
- package/dist/application/transform/document/operation-keys-written.mjs.map +1 -0
- package/dist/application/transform/document/operation.cjs +1 -1
- package/dist/application/transform/document/operation.cjs.map +1 -1
- package/dist/application/transform/document/operation.mjs +2 -2
- package/dist/application/transform/document/operation.mjs.map +1 -1
- package/dist/application/transform/document/parameter-entries.cjs +34 -0
- package/dist/application/transform/document/parameter-entries.cjs.map +1 -0
- package/dist/application/transform/document/parameter-entries.mjs +30 -0
- package/dist/application/transform/document/parameter-entries.mjs.map +1 -0
- package/dist/application/transform/document/parameter.cjs +12 -4
- package/dist/application/transform/document/parameter.cjs.map +1 -1
- package/dist/application/transform/document/parameter.mjs +13 -5
- package/dist/application/transform/document/parameter.mjs.map +1 -1
- package/dist/application/transform/document/parameters.cjs +6 -29
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +6 -29
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-item.cjs +11 -14
- package/dist/application/transform/document/path-item.cjs.map +1 -1
- package/dist/application/transform/document/path-item.mjs +12 -16
- package/dist/application/transform/document/path-item.mjs.map +1 -1
- package/dist/application/transform/document/paths-enum.cjs +1 -0
- package/dist/application/transform/document/paths-enum.cjs.map +1 -1
- package/dist/application/transform/document/paths-enum.mjs +1 -1
- package/dist/application/transform/document/paths-enum.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +5 -1
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +6 -2
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/referenced-parameter.cjs +80 -0
- package/dist/application/transform/document/referenced-parameter.cjs.map +1 -0
- package/dist/application/transform/document/referenced-parameter.mjs +78 -0
- package/dist/application/transform/document/referenced-parameter.mjs.map +1 -0
- package/dist/application/transform/document/request-body.cjs +1 -1
- package/dist/application/transform/document/request-body.cjs.map +1 -1
- package/dist/application/transform/document/request-body.mjs +2 -2
- package/dist/application/transform/document/request-body.mjs.map +1 -1
- package/dist/application/transform/document/response.cjs +2 -2
- package/dist/application/transform/document/response.cjs.map +1 -1
- package/dist/application/transform/document/response.mjs +3 -3
- package/dist/application/transform/document/response.mjs.map +1 -1
- package/dist/application/transform/document/responses.cjs +1 -1
- package/dist/application/transform/document/responses.cjs.map +1 -1
- package/dist/application/transform/document/responses.mjs +2 -2
- package/dist/application/transform/document/responses.mjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.cjs +8 -23
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.mjs +8 -24
- package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
- package/dist/application/transform/document/type-resolution.cjs +3 -1
- package/dist/application/transform/document/type-resolution.cjs.map +1 -1
- package/dist/application/transform/document/type-resolution.mjs +3 -1
- package/dist/application/transform/document/type-resolution.mjs.map +1 -1
- package/dist/application/transform/document/webhooks.cjs +1 -1
- package/dist/application/transform/document/webhooks.cjs.map +1 -1
- package/dist/application/transform/document/webhooks.mjs +2 -2
- package/dist/application/transform/document/webhooks.mjs.map +1 -1
- package/dist/application/transform/footer/document-footer.cjs +10 -2
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +10 -2
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/footer/enum-name-claims.cjs +48 -0
- package/dist/application/transform/footer/enum-name-claims.cjs.map +1 -0
- package/dist/application/transform/footer/enum-name-claims.mjs +46 -0
- package/dist/application/transform/footer/enum-name-claims.mjs.map +1 -0
- package/dist/application/transform/footer/operation-keys.cjs +23 -0
- package/dist/application/transform/footer/operation-keys.cjs.map +1 -0
- package/dist/application/transform/footer/operation-keys.mjs +21 -0
- package/dist/application/transform/footer/operation-keys.mjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.cjs +4 -4
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
- package/dist/application/transform/footer/type-evaluation.mjs +4 -4
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
- package/dist/application/transform/helper-types.cjs +1 -1
- package/dist/application/transform/helper-types.cjs.map +1 -1
- package/dist/application/transform/helper-types.mjs +1 -1
- package/dist/application/transform/helper-types.mjs.map +1 -1
- package/dist/application/transform/numbered-names.cjs +9 -0
- package/dist/application/transform/numbered-names.cjs.map +1 -1
- package/dist/application/transform/numbered-names.mjs +9 -1
- package/dist/application/transform/numbered-names.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.cjs +1 -1
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.mjs +2 -2
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
- package/dist/application/transform/ref-type.cjs +2 -1
- package/dist/application/transform/ref-type.cjs.map +1 -1
- package/dist/application/transform/ref-type.mjs +2 -1
- package/dist/application/transform/ref-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +1 -1
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +2 -2
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +1 -1
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +2 -2
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- package/dist/application/transform/schema/object-type.cjs +3 -3
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +4 -4
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- package/dist/application/transform/schema/ref-siblings.cjs +47 -0
- package/dist/application/transform/schema/ref-siblings.cjs.map +1 -0
- package/dist/application/transform/schema/ref-siblings.mjs +45 -0
- package/dist/application/transform/schema/ref-siblings.mjs.map +1 -0
- package/dist/application/transform/schema/schema-transform.cjs +4 -2
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +4 -2
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +5 -1
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +5 -1
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/cli/api-settings.cjs +62 -6
- package/dist/cli/api-settings.cjs.map +1 -1
- package/dist/cli/api-settings.mjs +60 -7
- package/dist/cli/api-settings.mjs.map +1 -1
- package/dist/cli/api-writes.cjs +72 -0
- package/dist/cli/api-writes.cjs.map +1 -0
- package/dist/cli/api-writes.mjs +69 -0
- package/dist/cli/api-writes.mjs.map +1 -0
- package/dist/cli/cli-errors.cjs +12 -1
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +12 -1
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-output.cjs +106 -1
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +99 -2
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/main.cjs +5 -1
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +6 -2
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +82 -36
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +85 -39
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +13 -7
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +14 -8
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/append-all.cjs +10 -0
- package/dist/domain/append-all.cjs.map +1 -0
- package/dist/domain/append-all.mjs +8 -0
- package/dist/domain/append-all.mjs.map +1 -0
- package/dist/domain/cause-secrets.cjs +37 -0
- package/dist/domain/cause-secrets.cjs.map +1 -0
- package/dist/domain/cause-secrets.mjs +35 -0
- package/dist/domain/cause-secrets.mjs.map +1 -0
- package/dist/domain/errors.cjs +9 -3
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +9 -3
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/identifier-text.cjs.map +1 -1
- package/dist/domain/ir/identifier-text.mjs +1 -1
- package/dist/domain/ir/identifier-text.mjs.map +1 -1
- package/dist/domain/ir/ir-shape.cjs +187 -0
- package/dist/domain/ir/ir-shape.cjs.map +1 -0
- package/dist/domain/ir/ir-shape.mjs +184 -0
- package/dist/domain/ir/ir-shape.mjs.map +1 -0
- package/dist/domain/ir/newer-identifier-ranges.cjs +182 -29
- package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -1
- package/dist/domain/ir/newer-identifier-ranges.mjs +182 -29
- package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -1
- package/dist/domain/openapi/alias-expansion.cjs +3 -1
- package/dist/domain/openapi/alias-expansion.cjs.map +1 -1
- package/dist/domain/openapi/alias-expansion.mjs +3 -1
- package/dist/domain/openapi/alias-expansion.mjs.map +1 -1
- package/dist/domain/openapi/discriminated-union.cjs +3 -3
- package/dist/domain/openapi/discriminated-union.cjs.map +1 -1
- package/dist/domain/openapi/discriminated-union.mjs +4 -4
- package/dist/domain/openapi/discriminated-union.mjs.map +1 -1
- package/dist/domain/openapi/discriminator-conflicts.cjs +10 -6
- package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -1
- package/dist/domain/openapi/discriminator-conflicts.mjs +11 -7
- package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -1
- package/dist/domain/openapi/json-pointer.cjs +43 -1
- package/dist/domain/openapi/json-pointer.cjs.map +1 -1
- package/dist/domain/openapi/json-pointer.mjs +40 -2
- package/dist/domain/openapi/json-pointer.mjs.map +1 -1
- package/dist/domain/openapi/schema-dialect.cjs +15 -0
- package/dist/domain/openapi/schema-dialect.cjs.map +1 -0
- package/dist/domain/openapi/schema-dialect.mjs +12 -0
- package/dist/domain/openapi/schema-dialect.mjs.map +1 -0
- package/dist/domain/openapi/unsupported-features.cjs +1 -1
- package/dist/domain/openapi/unsupported-features.cjs.map +1 -1
- package/dist/domain/openapi/unsupported-features.mjs +2 -2
- package/dist/domain/openapi/unsupported-features.mjs.map +1 -1
- package/dist/domain/output-fixes.cjs +14 -0
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +14 -0
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/url-secrets.cjs +48 -0
- package/dist/domain/url-secrets.cjs.map +1 -0
- package/dist/domain/url-secrets.mjs +45 -0
- package/dist/domain/url-secrets.mjs.map +1 -0
- package/dist/index.d.cts +22 -4
- package/dist/index.d.mts +22 -4
- package/dist/index.d.ts +22 -4
- package/package.json +4 -5
- package/src/adapters/node-file-system/file-claims.ts +138 -0
- package/src/adapters/node-file-system/file-identity.ts +137 -0
- package/src/adapters/node-file-system/node-file-system.ts +145 -18
- package/src/adapters/redocly-loader/bundled-mapping-copies.ts +95 -0
- package/src/adapters/redocly-loader/bundled-ref-repair.ts +2 -2
- package/src/adapters/redocly-loader/loaded-documents.ts +46 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +18 -24
- package/src/adapters/redocly-loader/ref-access.ts +37 -3
- package/src/adapters/redocly-loader/ref-holders.ts +3 -3
- package/src/adapters/redocly-loader/remote-body-limit.ts +66 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +74 -11
- package/src/adapters/redocly-loader/remote-node-limit.ts +62 -0
- package/src/adapters/redocly-loader/schema-load-errors.ts +52 -13
- package/src/adapters/redocly-loader/schema-source.ts +20 -8
- package/src/adapters/redocly-loader/unsupported-keys.ts +3 -7
- package/src/adapters/terminal-logger/terminal-logger.ts +10 -5
- package/src/api/default-ports.ts +33 -4
- package/src/api/discriminator-enum-parent.ts +3 -3
- package/src/api/discriminator-other-owners.ts +5 -3
- package/src/api/discriminator-patch.ts +5 -1
- package/src/api/discriminator-scan.ts +16 -8
- package/src/api/document-run.ts +4 -3
- package/src/api/legacy-utils.ts +5 -1
- package/src/api/openapi-ts.ts +20 -5
- package/src/api/run-context.ts +3 -0
- package/src/api/schema-callbacks.ts +60 -17
- package/src/api/transform-context.ts +7 -3
- package/src/api/transform-schema.ts +64 -12
- package/src/application/ports/file-system.ts +39 -0
- package/src/application/ports/schema-loader.ts +11 -1
- package/src/application/print/text-writer.ts +10 -3
- package/src/application/stack-overflow.ts +9 -5
- package/src/application/transform/document/components.ts +2 -2
- package/src/application/transform/document/declared-type-names.ts +36 -0
- package/src/application/transform/document/defs-root.ts +2 -2
- package/src/application/transform/document/document.ts +4 -3
- package/src/application/transform/document/enum-names-given-back.ts +91 -0
- package/src/application/transform/document/global-type-references.ts +1 -1
- package/src/application/transform/document/media-type.ts +4 -3
- package/src/application/transform/document/operation-keys-written.ts +27 -0
- package/src/application/transform/document/operation.ts +2 -2
- package/src/application/transform/document/parameter-entries.ts +70 -0
- package/src/application/transform/document/parameter.ts +21 -9
- package/src/application/transform/document/parameters.ts +11 -56
- package/src/application/transform/document/path-item.ts +13 -31
- package/src/application/transform/document/paths-enum.ts +1 -1
- package/src/application/transform/document/paths.ts +6 -2
- package/src/application/transform/document/referenced-parameter.ts +146 -0
- package/src/application/transform/document/request-body.ts +2 -2
- package/src/application/transform/document/response.ts +3 -3
- package/src/application/transform/document/responses.ts +2 -2
- package/src/application/transform/document/root-type-aliases.ts +17 -38
- package/src/application/transform/document/type-resolution.ts +2 -1
- package/src/application/transform/document/webhooks.ts +2 -2
- package/src/application/transform/footer/document-footer.ts +18 -1
- package/src/application/transform/footer/enum-name-claims.ts +62 -0
- package/src/application/transform/footer/operation-keys.ts +28 -0
- package/src/application/transform/footer/type-evaluation.ts +4 -4
- package/src/application/transform/helper-types.ts +6 -5
- package/src/application/transform/numbered-names.ts +15 -0
- package/src/application/transform/ref-pointer/generated-location.ts +2 -2
- package/src/application/transform/ref-type.ts +2 -1
- package/src/application/transform/schema/composition-type.ts +2 -2
- package/src/application/transform/schema/enum-rule.ts +6 -2
- package/src/application/transform/schema/object-type.ts +4 -4
- package/src/application/transform/schema/ref-siblings.ts +76 -0
- package/src/application/transform/schema/schema-context.ts +3 -0
- package/src/application/transform/schema/schema-transform.ts +4 -2
- package/src/application/transform/schema-comment.ts +5 -1
- package/src/application/transform/transform-context.ts +5 -0
- package/src/cli/api-settings.ts +82 -7
- package/src/cli/api-writes.ts +117 -0
- package/src/cli/cli-dependencies.ts +21 -4
- package/src/cli/cli-errors.ts +20 -1
- package/src/cli/cli-output.ts +186 -7
- package/src/cli/main.ts +6 -3
- package/src/cli/redocly-apis.ts +153 -48
- package/src/cli/run-cli.ts +37 -8
- package/src/domain/append-all.ts +10 -0
- package/src/domain/cause-secrets.ts +52 -0
- package/src/domain/errors.ts +14 -5
- package/src/domain/ir/identifier-text.ts +6 -5
- package/src/domain/ir/ir-shape.ts +299 -0
- package/src/domain/ir/newer-identifier-ranges.ts +183 -30
- package/src/domain/openapi/alias-expansion.ts +4 -1
- package/src/domain/openapi/discriminated-union.ts +6 -4
- package/src/domain/openapi/discriminator-conflicts.ts +21 -7
- package/src/domain/openapi/document-object.ts +2 -0
- package/src/domain/openapi/json-pointer.ts +96 -7
- package/src/domain/openapi/schema-dialect.ts +22 -0
- package/src/domain/openapi/unsupported-features.ts +2 -2
- package/src/domain/output-fixes.ts +21 -2
- package/src/domain/url-secrets.ts +72 -0
- package/src/types/generator-options.ts +1 -1
- package/dist/cli/main.d.cts +0 -2
- package/dist/cli/main.d.mts +0 -2
- package/dist/cli/main.d.ts +0 -2
- package/dist/domain/url-credentials.cjs +0 -10
- package/dist/domain/url-credentials.cjs.map +0 -1
- package/dist/domain/url-credentials.mjs +0 -8
- package/dist/domain/url-credentials.mjs.map +0 -1
- package/src/domain/url-credentials.ts +0 -18
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { irObject, irProperty } from "../../../domain/ir/constructors.js";
|
|
2
2
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
3
3
|
import { toPropertyName } from "../../../domain/ir/property-name.js";
|
|
4
|
-
import {
|
|
4
|
+
import { appendPointer, ROOT_POINTER } from "../../../domain/openapi/json-pointer.js";
|
|
5
5
|
import type { PathItemObject, PathsObject } from "../../../domain/openapi/path-item-object.js";
|
|
6
6
|
import { documentEntries } from "../document-entries.js";
|
|
7
7
|
import type { TransformContext } from "../transform-context.js";
|
|
@@ -14,7 +14,7 @@ import { pathItemType } from "./path-item.js";
|
|
|
14
14
|
*/
|
|
15
15
|
export function webhooksType(webhooks: PathsObject, context: TransformContext): IrType {
|
|
16
16
|
const members = documentEntries(webhooks, context.options).map(([name, pathItem]) => {
|
|
17
|
-
const location = { path:
|
|
17
|
+
const location = { path: appendPointer(ROOT_POINTER, ["webhooks", name]) };
|
|
18
18
|
const type = pathItemType(pathItem as PathItemObject, location, context);
|
|
19
19
|
return irProperty(toPropertyName(name), type, { isReadonly: context.options.immutable });
|
|
20
20
|
});
|
|
@@ -12,12 +12,14 @@ import type {
|
|
|
12
12
|
EnumValuesRequest,
|
|
13
13
|
} from "../schema/schema-context.js";
|
|
14
14
|
import type { DocumentFooter } from "../transform-context.js";
|
|
15
|
+
import { EnumNameClaims } from "./enum-name-claims.js";
|
|
15
16
|
import {
|
|
16
17
|
type DeclaredMembers,
|
|
17
18
|
EnumNaming,
|
|
18
19
|
enumDeclaration,
|
|
19
20
|
withoutDeclaredMembers,
|
|
20
21
|
} from "./enum-naming.js";
|
|
22
|
+
import { OperationKeys } from "./operation-keys.js";
|
|
21
23
|
import { FIRST_SCHEMA_NAMES, type SharedEnumNames } from "./shared-enum-names.js";
|
|
22
24
|
|
|
23
25
|
/** Where footer declarations go, in order: the run's `ctx.injectFooter`, open to user code. */
|
|
@@ -62,6 +64,12 @@ function declarationKey(name: string, request: EnumDeclarationRequest): string {
|
|
|
62
64
|
return JSON.stringify([name, request.values, request.metadata]);
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
/** The naming state a run's footer shares with the rest of the run. */
|
|
68
|
+
export interface RunFooterNames {
|
|
69
|
+
readonly enums: EnumNameClaims;
|
|
70
|
+
readonly operations: OperationKeys;
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
/**
|
|
66
74
|
* The footer of one run: enums (deduplicated with `--dedupe-enums`), `--enum-values` arrays, the
|
|
67
75
|
* helper types they need, and the `operations` interface. Replaces the original's module-level
|
|
@@ -83,15 +91,18 @@ export class RunFooter implements DocumentFooter {
|
|
|
83
91
|
private readonly sink: FooterSink;
|
|
84
92
|
private readonly isDedupingEnums: boolean;
|
|
85
93
|
private readonly sharedNames: SharedEnumNames;
|
|
94
|
+
private readonly names: RunFooterNames;
|
|
86
95
|
|
|
87
96
|
constructor(
|
|
88
97
|
sink: FooterSink,
|
|
89
98
|
isDedupingEnums: boolean,
|
|
90
99
|
sharedNames: SharedEnumNames = FIRST_SCHEMA_NAMES,
|
|
100
|
+
names: RunFooterNames = { enums: new EnumNameClaims(), operations: new OperationKeys() },
|
|
91
101
|
) {
|
|
92
102
|
this.sink = sink;
|
|
93
103
|
this.isDedupingEnums = isDedupingEnums;
|
|
94
104
|
this.sharedNames = sharedNames;
|
|
105
|
+
this.names = names;
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
addEnum(request: EnumDeclarationRequest): string {
|
|
@@ -99,11 +110,13 @@ export class RunFooter implements DocumentFooter {
|
|
|
99
110
|
const ownName = this.naming.enumName(request.name);
|
|
100
111
|
const key = this.isDedupingEnums ? dedupeKey(request) : null;
|
|
101
112
|
// Every schema of a shared enum goes to `sharedNames`, the later ones too.
|
|
102
|
-
const
|
|
113
|
+
const sharedName = key === null ? ownName : this.sharedNames.nameOf(key, ownName, request);
|
|
103
114
|
const known = key === null ? undefined : this.enumNamesByKey.get(key);
|
|
104
115
|
if (known !== undefined) {
|
|
105
116
|
return known;
|
|
106
117
|
}
|
|
118
|
+
// The owner is the schema location: its requests share one enum, with `--dedupe-enums` too.
|
|
119
|
+
const name = this.names.enums.nameFor(sharedName, request.name);
|
|
107
120
|
// Only a repeated member fails to compile; two empty declarations merge, so they stay.
|
|
108
121
|
const declared = request.values.length > 0 ? declarationKey(name, request) : null;
|
|
109
122
|
if (declared !== null && this.declaredEnums.has(declared)) {
|
|
@@ -200,6 +213,10 @@ export class RunFooter implements DocumentFooter {
|
|
|
200
213
|
this.sink.addOperation(build);
|
|
201
214
|
}
|
|
202
215
|
|
|
216
|
+
operationKey(operationId: string): string {
|
|
217
|
+
return this.names.operations.keyFor(operationId);
|
|
218
|
+
}
|
|
219
|
+
|
|
203
220
|
private require(helper: HelperType): void {
|
|
204
221
|
if (!this.sink.hasTypeAlias(helper.name)) {
|
|
205
222
|
this.sink.add({ kind: "rawDeclaration", name: helper.name, text: helper.text });
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { freeNumberedName } from "../numbered-names.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The names of the `--enum` declarations of one run, unique across the enums and apart from the
|
|
5
|
+
* names the rest of the output may need.
|
|
6
|
+
*
|
|
7
|
+
* Every enum has an owner: the schema location it is named after, or with `--dedupe-enums` its
|
|
8
|
+
* members. Two owners whose names come out the same (`status` and `Status`) merged into one enum
|
|
9
|
+
* before, so each accepted the values of the other (upstream behavior). Now the first owner keeps
|
|
10
|
+
* the name and each later one gets the next free `Name_2`, `Name_3`, …; requests of one owner (a
|
|
11
|
+
* property and an inline `allOf` item of one schema) still share one enum.
|
|
12
|
+
*
|
|
13
|
+
* An enum also gives way to a name the output may need, which is only known at the end: a global
|
|
14
|
+
* type the output refers to (the `Blob` of `--binary-as-blob`, the `Record` of
|
|
15
|
+
* `Record<string, never>`), a helper type, or `ApiPaths`. Until then it takes the numbered name;
|
|
16
|
+
* `givenBack` lists the ones whose own name the output turned out not to need, so output that
|
|
17
|
+
* compiled before keeps its names (ADR-021).
|
|
18
|
+
*/
|
|
19
|
+
export class EnumNameClaims {
|
|
20
|
+
private readonly mayBeNeeded: ReadonlySet<string>;
|
|
21
|
+
/** The first owner of each name an enum asked for. */
|
|
22
|
+
private readonly owners = new Map<string, string>();
|
|
23
|
+
/** The name given to each owner, by name asked for and owner. */
|
|
24
|
+
private readonly given = new Map<string, string>();
|
|
25
|
+
/** Every name given, and every name the output may need. */
|
|
26
|
+
private readonly taken: Set<string>;
|
|
27
|
+
/** A numbered name given only because the output may need the name asked for: that name. */
|
|
28
|
+
private readonly standIns = new Map<string, string>();
|
|
29
|
+
|
|
30
|
+
/** `mayBeNeeded`: the names an enum avoids until the end of the run; empty outside a run. */
|
|
31
|
+
constructor(mayBeNeeded: ReadonlySet<string> = new Set()) {
|
|
32
|
+
this.mayBeNeeded = mayBeNeeded;
|
|
33
|
+
this.taken = new Set(mayBeNeeded);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The declaration name of the enum `owner` asks to name `name`; the same for every request. */
|
|
37
|
+
nameFor(name: string, owner: string): string {
|
|
38
|
+
const key = JSON.stringify([name, owner]);
|
|
39
|
+
const known = this.given.get(key);
|
|
40
|
+
if (known !== undefined) {
|
|
41
|
+
return known;
|
|
42
|
+
}
|
|
43
|
+
const isFirstOwner = (this.owners.get(name) ?? owner) === owner;
|
|
44
|
+
this.owners.set(name, this.owners.get(name) ?? owner);
|
|
45
|
+
const isFree = isFirstOwner && !this.taken.has(name);
|
|
46
|
+
const declared = isFree ? name : freeNumberedName(name, this.taken);
|
|
47
|
+
if (isFirstOwner && this.mayBeNeeded.has(name)) {
|
|
48
|
+
this.standIns.set(declared, name);
|
|
49
|
+
}
|
|
50
|
+
this.taken.add(declared);
|
|
51
|
+
this.given.set(key, declared);
|
|
52
|
+
return declared;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The numbered names to rename back to the name asked for, because `needed` (the names the
|
|
57
|
+
* finished output declares or refers to) does not hold that name.
|
|
58
|
+
*/
|
|
59
|
+
givenBack(needed: ReadonlySet<string>): ReadonlyMap<string, string> {
|
|
60
|
+
return new Map([...this.standIns].filter(([, name]) => !needed.has(name)));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys of the `operations` interface in one run. A repeated `operationId` (Redocly warns
|
|
3
|
+
* about it) gave the interface two members of one name, which did not compile (TS2300). Now the
|
|
4
|
+
* first operation with an ID keeps it, and each later one gets the lowest number from 2 whose key
|
|
5
|
+
* no operation of the document has: the second `listItems` is `listItems2`, the name
|
|
6
|
+
* `--make-paths-enum` gives it in `ApiPaths` too. Keys follow the order the operations are
|
|
7
|
+
* transformed in, which is the document order (or the `--alphabetize` order).
|
|
8
|
+
*/
|
|
9
|
+
export class OperationKeys {
|
|
10
|
+
private readonly written: ReadonlySet<string>;
|
|
11
|
+
private readonly taken = new Set<string>();
|
|
12
|
+
|
|
13
|
+
/** `written`: every operation key of the document; empty outside a document run. */
|
|
14
|
+
constructor(written: ReadonlySet<string> = new Set()) {
|
|
15
|
+
this.written = written;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** The key of the next operation with this key, written or numbered. */
|
|
19
|
+
keyFor(key: string): string {
|
|
20
|
+
let unique = key;
|
|
21
|
+
for (let count = 2; this.taken.has(unique); count += 1) {
|
|
22
|
+
const candidate = `${key}${count}`;
|
|
23
|
+
unique = this.written.has(candidate) ? unique : candidate;
|
|
24
|
+
}
|
|
25
|
+
this.taken.add(unique);
|
|
26
|
+
return unique;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -22,7 +22,7 @@ import { extracted, markerObject, omitted } from "./type-rules.js";
|
|
|
22
22
|
|
|
23
23
|
/** How many references one evaluation expands; a deeper one is opaque. */
|
|
24
24
|
const MAX_EXPANSIONS = 200;
|
|
25
|
-
const
|
|
25
|
+
const DEEP_HELPER = "FlattenedDeepRequired";
|
|
26
26
|
/** How many members distributing an intersection may give; more is opaque. */
|
|
27
27
|
const MAX_DISTRIBUTED = 64;
|
|
28
28
|
|
|
@@ -75,15 +75,15 @@ export class TypeEvaluator {
|
|
|
75
75
|
if (this.expansions++ > MAX_EXPANSIONS) {
|
|
76
76
|
return OPAQUE;
|
|
77
77
|
}
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const [first, second] = args;
|
|
79
|
+
if (name === DEEP_HELPER && first?.kind === "reference" && first.typeArguments.length === 0) {
|
|
80
|
+
const root = this.declared.get(first.name);
|
|
80
81
|
return root === undefined ? OPAQUE : this.expand({ kind: "type", type: root, deep: true });
|
|
81
82
|
}
|
|
82
83
|
const declared = args.length === 0 ? this.declared.get(name) : undefined;
|
|
83
84
|
if (declared !== undefined) {
|
|
84
85
|
return this.expand({ ...value, type: declared });
|
|
85
86
|
}
|
|
86
|
-
const [first, second] = args;
|
|
87
87
|
if (first === undefined) {
|
|
88
88
|
return OPAQUE;
|
|
89
89
|
}
|
|
@@ -51,9 +51,10 @@ export const HELPER_TYPES = {
|
|
|
51
51
|
/**
|
|
52
52
|
* The `--read-write-markers` helper types, written before the root types. Task 7.6 replaces the
|
|
53
53
|
* original text on purpose (ADR-014): primitives (also branded), readonly arrays, tuples,
|
|
54
|
-
* intersected arrays
|
|
55
|
-
* #2717, #2765). The declarations equal `Readable` / `Writable`
|
|
56
|
-
* (`test/api/read-write-marker-types.test.ts`); the text is what
|
|
54
|
+
* intersected arrays, null-only and `any` properties keep their types (upstream #2615, #2620,
|
|
55
|
+
* #2632, #2717, #2765). The declarations equal the `Readable` / `Writable` that
|
|
56
|
+
* openapi-typesafe-fetch declares (`test/api/read-write-marker-types.test.ts`); the text is what
|
|
57
|
+
* the TypeScript printer prints.
|
|
57
58
|
*/
|
|
58
59
|
export const READ_WRITE_MARKER_TYPES = lines(
|
|
59
60
|
"export type $Read<T> = {",
|
|
@@ -65,8 +66,8 @@ export const READ_WRITE_MARKER_TYPES = lines(
|
|
|
65
66
|
"type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;",
|
|
66
67
|
"type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);",
|
|
67
68
|
"type ReadWriteMarkedKeys<T, Marker> = {",
|
|
68
|
-
" [K in keyof T]-?:
|
|
69
|
-
"extends Marker ? K : never;",
|
|
69
|
+
" [K in keyof T]-?: 0 extends 1 & T[K] ? never : NonNullable<T[K]> extends never ? never : " +
|
|
70
|
+
"NonNullable<T[K]> extends Marker ? K : never;",
|
|
70
71
|
"}[keyof T];",
|
|
71
72
|
'type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | ' +
|
|
72
73
|
'"write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], ' +
|
|
@@ -18,3 +18,18 @@ export function withNumberedRepeats(names: readonly string[], numbered: Numbered
|
|
|
18
18
|
return unique;
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
/** Separates a repeated declaration name from its number: `Status` → `Status_2`. */
|
|
23
|
+
const DECLARATION_NUMBER_SEPARATOR = "_";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The first of `Name_2`, `Name_3`, … that `taken` does not hold: the suffix `--root-types` uses for
|
|
27
|
+
* its own conflicts, and every other declaration that must give way to another name.
|
|
28
|
+
*/
|
|
29
|
+
export function freeNumberedName(name: string, taken: ReadonlySet<string>): string {
|
|
30
|
+
let count = 2;
|
|
31
|
+
while (taken.has(`${name}${DECLARATION_NUMBER_SEPARATOR}${count}`)) {
|
|
32
|
+
count += 1;
|
|
33
|
+
}
|
|
34
|
+
return `${name}${DECLARATION_NUMBER_SEPARATOR}${count}`;
|
|
35
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { appendPointer, ROOT_POINTER } from "../../../domain/openapi/json-pointer.js";
|
|
2
2
|
import type { RefResolver } from "../schema/schema-context.js";
|
|
3
3
|
import { isJsonObject } from "./generated-shape.js";
|
|
4
4
|
import {
|
|
@@ -205,7 +205,7 @@ function walkTo(ref: string, refs: RefResolver, seen: readonly string[]): Locati
|
|
|
205
205
|
export function generatedLocationOf(ref: string, refs: RefResolver): GeneratedLocation {
|
|
206
206
|
const walk = walkTo(ref, refs, []);
|
|
207
207
|
return {
|
|
208
|
-
path: walk === null ? ref :
|
|
208
|
+
path: walk === null ? ref : appendPointer(ROOT_POINTER, walk.path),
|
|
209
209
|
isFromAdditionalProperties: walk?.isFromAdditionalProperties ?? false,
|
|
210
210
|
};
|
|
211
211
|
}
|
|
@@ -68,7 +68,8 @@ export function indexKeyword(type: IrType, segment: string, isLast: boolean): Ir
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export function rootType(rootSegment: string, isDeep: boolean): IrType {
|
|
71
|
-
|
|
71
|
+
const root = irReference(rootSegment);
|
|
72
|
+
return isDeep ? irReference("FlattenedDeepRequired", [root]) : root;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { irKeyword, irRecord } from "../../../domain/ir/constructors.js";
|
|
2
2
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
3
|
-
import {
|
|
3
|
+
import { appendPointer } from "../../../domain/openapi/json-pointer.js";
|
|
4
4
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
5
5
|
import { FIX } from "../../../domain/output-fixes.js";
|
|
6
6
|
import { requirableRefType } from "../ref-pointer/pointer-type.js";
|
|
@@ -29,7 +29,7 @@ function variantTypes(
|
|
|
29
29
|
return variants.map((variant, index) =>
|
|
30
30
|
request.transformNested(variant, {
|
|
31
31
|
...request.location,
|
|
32
|
-
path:
|
|
32
|
+
path: appendPointer(request.location.path, [keyword, index]),
|
|
33
33
|
}),
|
|
34
34
|
);
|
|
35
35
|
}
|
|
@@ -6,7 +6,11 @@ import {
|
|
|
6
6
|
irString,
|
|
7
7
|
} from "../../../domain/ir/constructors.js";
|
|
8
8
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
appendPointer,
|
|
11
|
+
parseRefPointer,
|
|
12
|
+
ROOT_POINTER,
|
|
13
|
+
} from "../../../domain/openapi/json-pointer.js";
|
|
10
14
|
import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
11
15
|
import { FIX } from "../../../domain/output-fixes.js";
|
|
12
16
|
import { literalType } from "../literal-type.js";
|
|
@@ -228,7 +232,7 @@ function enumValuesPointer(path: string | undefined): { ref: string; extract: st
|
|
|
228
232
|
: pointer
|
|
229
233
|
.slice(firstVariantStart)
|
|
230
234
|
.filter((segment) => !UNION_KEYWORDS.has(segment) && !INDEX_RE.test(segment));
|
|
231
|
-
return { ref:
|
|
235
|
+
return { ref: appendPointer(ROOT_POINTER, kept), extract };
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
function addEnumValues(schema: SchemaObject, request: SchemaRequest): void {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "../../../domain/ir/constructors.js";
|
|
8
8
|
import type { IrMember, IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
|
|
9
9
|
import { toPropertyName } from "../../../domain/ir/property-name.js";
|
|
10
|
-
import {
|
|
10
|
+
import { appendPointer } from "../../../domain/openapi/json-pointer.js";
|
|
11
11
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
12
12
|
import { documentEntries } from "../document-entries.js";
|
|
13
13
|
import { schemaRefType } from "../ref-pointer/pointer-type.js";
|
|
@@ -117,7 +117,7 @@ function propertyType(
|
|
|
117
117
|
facts: PropertyFacts,
|
|
118
118
|
request: SchemaRequest,
|
|
119
119
|
): CustomResult {
|
|
120
|
-
const path =
|
|
120
|
+
const path = appendPointer(request.location.path, [key]);
|
|
121
121
|
const type = facts.ref
|
|
122
122
|
? schemaRefType(facts.ref, request)
|
|
123
123
|
: request.transformNested(value, { ...request.location, path });
|
|
@@ -151,7 +151,7 @@ function propertyMember(
|
|
|
151
151
|
isReadonly: options.immutable || (!options.readWriteMarkers && facts.flags.isReadOnly),
|
|
152
152
|
},
|
|
153
153
|
);
|
|
154
|
-
return finishProperty(property, value,
|
|
154
|
+
return finishProperty(property, value, appendPointer(request.location.path, [key]), request);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
function propertyMembers(schema: SchemaObject, request: SchemaRequest): IrMember[] {
|
|
@@ -176,7 +176,7 @@ function defsMember(
|
|
|
176
176
|
): IrMember {
|
|
177
177
|
const { options } = request.context;
|
|
178
178
|
const members = Object.entries(defs).map(([key, value]) => {
|
|
179
|
-
const path =
|
|
179
|
+
const path = appendPointer(request.location.path, ["$defs", key]);
|
|
180
180
|
const flags = propertyAccessFlags(value, request.context);
|
|
181
181
|
const type = withReadWriteMarker(
|
|
182
182
|
request.transformNested(value, { ...request.location, path }),
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SCHEMA_DIALECTS } from "../../../domain/openapi/schema-dialect.js";
|
|
2
|
+
import type {
|
|
3
|
+
ReferenceSchema,
|
|
4
|
+
Schema,
|
|
5
|
+
SchemaObject,
|
|
6
|
+
} from "../../../domain/openapi/schema-object.js";
|
|
7
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
8
|
+
import type { SchemaOptions } from "./schema-context.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The `ref-siblings` fix (ADR-021 amendment 2, RC4 G16): in JSON Schema 2020-12 (OpenAPI 3.1 and
|
|
12
|
+
* 3.2) the keywords next to a `$ref` apply too, so `{ $ref: Base, required: [extra], properties:
|
|
13
|
+
* { extra } }` is a `Base` that also has a required `extra`. That is what `allOf: [{ $ref: Base }]`
|
|
14
|
+
* next to the same keywords means, so the schema is typed as that `allOf`, with every rule the
|
|
15
|
+
* generator has for `allOf` and its siblings (`WithRequired`, intersections).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Keywords that only annotate (JSON Schema 2020-12 meta-data, format-annotation and content
|
|
20
|
+
* vocabularies, OpenAPI fixed fields), or that change no type on their own (`discriminator`
|
|
21
|
+
* without `oneOf`). Next to a `$ref` they stay where they were, so the output keeps the plain
|
|
22
|
+
* reference with its comment. Extension keywords (`x-…`) count as annotations too.
|
|
23
|
+
*/
|
|
24
|
+
const ANNOTATION_KEYWORDS: ReadonlySet<string> = new Set([
|
|
25
|
+
"$anchor",
|
|
26
|
+
"$comment",
|
|
27
|
+
"$defs",
|
|
28
|
+
"$dynamicAnchor",
|
|
29
|
+
"$id",
|
|
30
|
+
"$ref",
|
|
31
|
+
"$schema",
|
|
32
|
+
"contentEncoding",
|
|
33
|
+
"contentMediaType",
|
|
34
|
+
"default",
|
|
35
|
+
"deprecated",
|
|
36
|
+
"description",
|
|
37
|
+
"discriminator",
|
|
38
|
+
"example",
|
|
39
|
+
"examples",
|
|
40
|
+
"externalDocs",
|
|
41
|
+
"format",
|
|
42
|
+
"readOnly",
|
|
43
|
+
"title",
|
|
44
|
+
"writeOnly",
|
|
45
|
+
"xml",
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
const EXTENSION_PREFIX = "x-";
|
|
49
|
+
|
|
50
|
+
function hasRef(schema: SchemaObject): schema is SchemaObject & ReferenceSchema {
|
|
51
|
+
return typeof (schema as Partial<ReferenceSchema>).$ref === "string";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function isTypeKeyword(keyword: string): boolean {
|
|
55
|
+
return !ANNOTATION_KEYWORDS.has(keyword) && !keyword.startsWith(EXTENSION_PREFIX);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A `$ref` schema as the `allOf` it means, or null where nothing changes: a schema without `$ref`,
|
|
60
|
+
* no fix, an OpenAPI 3.0 document, or no sibling that changes the type. The result has no
|
|
61
|
+
* `$ref`, so the shape rules type it as `enum`, `const` or a composition.
|
|
62
|
+
*/
|
|
63
|
+
export function refWithSiblingsAsAllOf(
|
|
64
|
+
schema: SchemaObject,
|
|
65
|
+
options: SchemaOptions,
|
|
66
|
+
): SchemaObject | null {
|
|
67
|
+
const isApplied =
|
|
68
|
+
options.fixes.has(FIX.REF_SIBLINGS) &&
|
|
69
|
+
options.schemaDialect === SCHEMA_DIALECTS.JSON_SCHEMA_2020_12;
|
|
70
|
+
if (!isApplied || !hasRef(schema) || !Object.keys(schema).some(isTypeKeyword)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const { $ref, allOf = [], ...siblings } = schema;
|
|
74
|
+
const members: readonly Schema[] = [{ $ref }, ...allOf];
|
|
75
|
+
return { ...siblings, allOf: members };
|
|
76
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
|
|
2
|
+
import type { SchemaDialect } from "../../../domain/openapi/schema-dialect.js";
|
|
2
3
|
import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
3
4
|
import type { OutputFix } from "../../../domain/output-fixes.js";
|
|
4
5
|
|
|
@@ -27,6 +28,8 @@ export interface SchemaOptions {
|
|
|
27
28
|
readonly immutable: boolean;
|
|
28
29
|
readonly propertiesRequiredByDefault: boolean;
|
|
29
30
|
readonly readWriteMarkers: boolean;
|
|
31
|
+
/** Whether keywords next to a `$ref` apply (OpenAPI 3.1 and 3.2) or not (3.0). */
|
|
32
|
+
readonly schemaDialect: SchemaDialect;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
/**
|
|
@@ -7,6 +7,7 @@ import { schemaRefType } from "../ref-pointer/pointer-type.js";
|
|
|
7
7
|
import { UNKNOWN_TYPE } from "../shared-types.js";
|
|
8
8
|
import { compositionType } from "./composition-type.js";
|
|
9
9
|
import { enumRule } from "./enum-rule.js";
|
|
10
|
+
import { refWithSiblingsAsAllOf } from "./ref-siblings.js";
|
|
10
11
|
import type { SchemaContext, SchemaLocation } from "./schema-context.js";
|
|
11
12
|
import type { SchemaRequest, SchemaRule } from "./schema-rule.js";
|
|
12
13
|
|
|
@@ -83,8 +84,9 @@ export function transformSchemaShape(
|
|
|
83
84
|
return checked.type;
|
|
84
85
|
}
|
|
85
86
|
const current = request(location, context, isFromAdditionalProperties);
|
|
86
|
-
const
|
|
87
|
-
|
|
87
|
+
const shaped = refWithSiblingsAsAllOf(checked.schema, context.options) ?? checked.schema;
|
|
88
|
+
const rule = SHAPE_RULES.find((candidate) => candidate.matches(shaped));
|
|
89
|
+
return rule ? rule.transform(shaped, current) : compositionType(shaped, current);
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
/** Transform a schema to IR, then apply `postTransform` (the original `transformSchemaObject`). */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { appendAll } from "../../domain/append-all.js";
|
|
1
2
|
import type { IrComment, IrPropertySignature } from "../../domain/ir/nodes.js";
|
|
2
3
|
import { FIX, type OutputFix } from "../../domain/output-fixes.js";
|
|
3
4
|
|
|
@@ -80,7 +81,10 @@ function valueTagLines(schema: AnnotatedSchema): string[] {
|
|
|
80
81
|
lines.push(`@${tag} ${formatValue(value)}`);
|
|
81
82
|
}
|
|
82
83
|
if (Array.isArray(schema.examples)) {
|
|
83
|
-
|
|
84
|
+
appendAll(
|
|
85
|
+
lines,
|
|
86
|
+
schema.examples.map((example: unknown) => `@example ${formatValue(example)}`),
|
|
87
|
+
);
|
|
84
88
|
}
|
|
85
89
|
return lines;
|
|
86
90
|
}
|
|
@@ -33,6 +33,11 @@ export interface DocumentFooter extends FooterDeclarations {
|
|
|
33
33
|
* it comes before any declaration the operation adds, as in the original.
|
|
34
34
|
*/
|
|
35
35
|
addOperation(build: () => IrPropertySignature): void;
|
|
36
|
+
/**
|
|
37
|
+
* The key in `operations` of the next operation with this (normalized) `operationId`: the ID,
|
|
38
|
+
* or for a repeated ID a numbered one (`OperationKeys`).
|
|
39
|
+
*/
|
|
40
|
+
operationKey(operationId: string): string;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
/** Debug output for slow parts of a run (`DEBUG=openapi-ts:*`). */
|
package/src/cli/api-settings.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { kebabCase } from "scule";
|
|
2
|
+
import { isOpenAPITypesafeError, OpenAPITypesafeError } from "../domain/errors.js";
|
|
3
|
+
import type { OutputFixName } from "../domain/output-fixes.js";
|
|
2
4
|
import { WARNING_CODES, warningText } from "../domain/warnings.js";
|
|
3
|
-
import { GENERATOR_FLAGS, hostList } from "./cli-arguments.js";
|
|
5
|
+
import { GENERATOR_FLAGS, type GeneratorFlags, hostList } from "./cli-arguments.js";
|
|
4
6
|
import { cliError } from "./cli-errors.js";
|
|
5
7
|
import { resolveLocationUrl } from "./cli-output.js";
|
|
8
|
+
import { fixNamesOf } from "./fix-option.js";
|
|
6
9
|
import type { RefLimitOptions } from "./ref-limits.js";
|
|
7
10
|
|
|
8
11
|
/**
|
|
@@ -51,22 +54,94 @@ export function unknownSettingWarnings(apiName: string, settings: ApiSettings):
|
|
|
51
54
|
);
|
|
52
55
|
}
|
|
53
56
|
|
|
57
|
+
/** The key a setting is written with: camelCase, else kebab-case; undefined when it is absent. */
|
|
58
|
+
function settingKey(settings: ApiSettings, name: string): string | undefined {
|
|
59
|
+
if (name in settings) {
|
|
60
|
+
return name;
|
|
61
|
+
}
|
|
62
|
+
const kebabName = kebabCase(name);
|
|
63
|
+
return kebabName in settings ? kebabName : undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
/** The value of a setting in camelCase, else in kebab-case; `undefined` when it is absent. */
|
|
55
67
|
function settingValue(settings: ApiSettings, name: string): unknown {
|
|
56
|
-
|
|
68
|
+
const key = settingKey(settings, name);
|
|
69
|
+
return key === undefined ? undefined : settings[key];
|
|
57
70
|
}
|
|
58
71
|
|
|
59
72
|
function hasSetting(settings: ApiSettings, name: string): boolean {
|
|
60
|
-
return
|
|
73
|
+
return settingKey(settings, name) !== undefined;
|
|
61
74
|
}
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
/** `CLI_CONFIG_INVALID` for the setting `name` of an API, named as the user wrote it. */
|
|
77
|
+
function invalidSetting(apiName: string, settings: ApiSettings, name: string, expected: string) {
|
|
78
|
+
const key = settingKey(settings, name) ?? kebabCase(name);
|
|
64
79
|
return cliError(
|
|
65
80
|
"CLI_CONFIG_INVALID",
|
|
66
|
-
`API ${apiName}: \`${
|
|
81
|
+
`API ${apiName}: \`${key}\` in x-openapi-ts must be ${expected}`,
|
|
67
82
|
);
|
|
68
83
|
}
|
|
69
84
|
|
|
85
|
+
/**
|
|
86
|
+
* The boolean flags an API sets, in camelCase or kebab-case; they win over the CLI's flags. A
|
|
87
|
+
* value of another type (`root-types: "true"`) fails with `CLI_CONFIG_INVALID`: ignoring it
|
|
88
|
+
* would generate other types than the config asks for, without a word.
|
|
89
|
+
*/
|
|
90
|
+
export function apiFlags(apiName: string, settings: ApiSettings): GeneratorFlags {
|
|
91
|
+
const flags: Partial<Record<(typeof GENERATOR_FLAGS)[number], boolean>> = {};
|
|
92
|
+
for (const name of GENERATOR_FLAGS) {
|
|
93
|
+
const value = settingValue(settings, name);
|
|
94
|
+
if (typeof value === "boolean") {
|
|
95
|
+
flags[name] = value;
|
|
96
|
+
} else if (hasSetting(settings, name)) {
|
|
97
|
+
throw invalidSetting(apiName, settings, name, "true or false");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return flags;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The API's `output` file as written; fails with `CLI_CONFIG_INVALID` when it is not text. */
|
|
104
|
+
export function apiOutputOf(apiName: string, settings: ApiSettings): string {
|
|
105
|
+
const output = settings[OUTPUT_SETTING];
|
|
106
|
+
if (typeof output !== "string") {
|
|
107
|
+
throw invalidSetting(apiName, settings, OUTPUT_SETTING, "a file path");
|
|
108
|
+
}
|
|
109
|
+
return output;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The API's `fix` names, which replace the CLI's `--fix` (ADR-021). An entry that is not text
|
|
114
|
+
* fails with `CLI_CONFIG_INVALID`; an unknown name with `OPTION_FIX_UNKNOWN`, naming the API.
|
|
115
|
+
*/
|
|
116
|
+
export function apiFixNames(
|
|
117
|
+
apiName: string,
|
|
118
|
+
settings: ApiSettings,
|
|
119
|
+
): readonly OutputFixName[] | undefined {
|
|
120
|
+
if (!hasSetting(settings, FIX_SETTING)) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const entries = [settingValue(settings, FIX_SETTING)].flat();
|
|
124
|
+
if (entries.some((entry) => typeof entry !== "string")) {
|
|
125
|
+
throw invalidSetting(apiName, settings, FIX_SETTING, "a list of fix names or a comma list");
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
return fixNamesOf(entries);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
throw isOpenAPITypesafeError(error) ? withApiName(apiName, error) : error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The same error, with the API named first in its message. */
|
|
135
|
+
function withApiName(apiName: string, error: OpenAPITypesafeError): OpenAPITypesafeError {
|
|
136
|
+
const { code, details, cause } = error;
|
|
137
|
+
return new OpenAPITypesafeError({
|
|
138
|
+
code,
|
|
139
|
+
message: `API ${apiName}: ${error.message}`,
|
|
140
|
+
details,
|
|
141
|
+
cause,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
70
145
|
/** `local-ref-root: dir`, relative to the config file; empty means the config file's directory. */
|
|
71
146
|
function localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL): RefLimitOptions {
|
|
72
147
|
if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {
|
|
@@ -74,7 +149,7 @@ function localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL)
|
|
|
74
149
|
}
|
|
75
150
|
const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? "";
|
|
76
151
|
if (typeof value !== "string") {
|
|
77
|
-
throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, "a directory path");
|
|
152
|
+
throw invalidSetting(apiName, settings, LOCAL_REF_ROOT_SETTING, "a directory path");
|
|
78
153
|
}
|
|
79
154
|
return { localRefRoot: resolveLocationUrl(value === "" ? "." : value, configRoot) };
|
|
80
155
|
}
|
|
@@ -87,7 +162,7 @@ function remoteRefHostsOf(apiName: string, settings: ApiSettings): RefLimitOptio
|
|
|
87
162
|
const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];
|
|
88
163
|
const entries = [value].flat();
|
|
89
164
|
if (entries.some((entry) => typeof entry !== "string")) {
|
|
90
|
-
throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, "a host list");
|
|
165
|
+
throw invalidSetting(apiName, settings, REMOTE_REF_HOSTS_SETTING, "a host list");
|
|
91
166
|
}
|
|
92
167
|
return { remoteRefHosts: hostList(entries) ?? [] };
|
|
93
168
|
}
|