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
|
@@ -3,10 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
const document = require('../application/transform/document/document.cjs');
|
|
6
|
+
const enumNamesGivenBack = require('../application/transform/document/enum-names-given-back.cjs');
|
|
7
|
+
const operationKeysWritten = require('../application/transform/document/operation-keys-written.cjs');
|
|
6
8
|
const rootTypeAliases = require('../application/transform/document/root-type-aliases.cjs');
|
|
7
9
|
const documentFooter = require('../application/transform/footer/document-footer.cjs');
|
|
10
|
+
const enumNameClaims = require('../application/transform/footer/enum-name-claims.cjs');
|
|
8
11
|
const enumValuesCheck = require('../application/transform/footer/enum-values-check.cjs');
|
|
12
|
+
const operationKeys = require('../application/transform/footer/operation-keys.cjs');
|
|
9
13
|
const sharedEnumNames = require('../application/transform/footer/shared-enum-names.cjs');
|
|
14
|
+
const schemaDialect = require('../domain/openapi/schema-dialect.cjs');
|
|
10
15
|
const outputFixes = require('../domain/output-fixes.cjs');
|
|
11
16
|
const discriminatorEnumNames = require('./discriminator-enum-names.cjs');
|
|
12
17
|
const documentDeclarations = require('./document-declarations.cjs');
|
|
@@ -41,13 +46,28 @@ function enumNameRecorderOf(ctx) {
|
|
|
41
46
|
}
|
|
42
47
|
return ctx.fix?.includes(outputFixes.FIX.DISCRIMINATOR_VALUES) ? new discriminatorEnumNames.FirstSchemaNameRecorder() : null;
|
|
43
48
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
if (recorder === null || !ctx.enum || !ctx.dedupeEnums) {
|
|
49
|
+
function withRunFooter(document, ctx, names) {
|
|
50
|
+
if (ctx.runFooter !== void 0) {
|
|
47
51
|
return;
|
|
48
52
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
53
|
+
const recorder = enumNameRecorderOf(ctx);
|
|
54
|
+
const shared = recorder === null || !ctx.enum || !ctx.dedupeEnums ? null : sharedEnumNamesOf(document, ctx, recorder);
|
|
55
|
+
const sink = new footerSink.ContextFooterSink(ctx.injectFooter);
|
|
56
|
+
ctx.runFooter = shared === null ? new documentFooter.RunFooter(sink, ctx.dedupeEnums, sharedEnumNames.FIRST_SCHEMA_NAMES, names) : new documentFooter.RunFooter(sink, true, shared, names);
|
|
57
|
+
}
|
|
58
|
+
function withEnumNamesGivenBack(parts, names) {
|
|
59
|
+
const footer = parts.footer.filter(footerEntry.isIrDeclaration);
|
|
60
|
+
const renames = names.enums.givenBack(enumNamesGivenBack.namesTheOutputNeeds({ ...parts, footer }));
|
|
61
|
+
if (renames.size === 0) {
|
|
62
|
+
return parts;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
body: enumNamesGivenBack.withEnumsRenamed(parts.body, renames),
|
|
66
|
+
footer: parts.footer.map(
|
|
67
|
+
(entry) => footerEntry.isIrDeclaration(entry) ? enumNamesGivenBack.withEnumsRenamed([entry], renames)[0] ?? entry : entry
|
|
68
|
+
),
|
|
69
|
+
closing: enumNamesGivenBack.withEnumsRenamed(parts.closing, renames)
|
|
70
|
+
};
|
|
51
71
|
}
|
|
52
72
|
function enumValuesChecked(body, footer, ctx) {
|
|
53
73
|
if (!ctx.enumValues) {
|
|
@@ -63,13 +83,23 @@ function enumValuesChecked(body, footer, ctx) {
|
|
|
63
83
|
}
|
|
64
84
|
function transformDocument(schema, ctx) {
|
|
65
85
|
const document$1 = schema;
|
|
66
|
-
|
|
86
|
+
ctx.schemaDialect = schemaDialect.schemaDialectOf(document$1.openapi);
|
|
87
|
+
const names = {
|
|
88
|
+
enums: new enumNameClaims.EnumNameClaims(enumNamesGivenBack.NAMES_THE_OUTPUT_MAY_NEED),
|
|
89
|
+
operations: new operationKeys.OperationKeys(operationKeysWritten.operationKeysWritten(document$1))
|
|
90
|
+
};
|
|
91
|
+
withRunFooter(document$1, ctx, names);
|
|
67
92
|
const context = transformContext.createTransformContext(ctx);
|
|
68
93
|
const rawBody = document.documentBody(document$1, context, () => ctx.injectFooter.filter(footerEntry.isIrDeclaration));
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
|
|
94
|
+
const rawFooter = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);
|
|
95
|
+
const rawClosing = document.documentClosing(document$1, context, rawFooter.some(isOperations));
|
|
96
|
+
const parts = { body: rawBody, footer: rawFooter, closing: rawClosing };
|
|
97
|
+
const { body, footer, closing } = withEnumNamesGivenBack(parts, names);
|
|
98
|
+
return {
|
|
99
|
+
body: rootTypeAliases.renameTakenAliases(body, footer.filter(footerEntry.isIrDeclaration), closing),
|
|
100
|
+
footer,
|
|
101
|
+
closing
|
|
102
|
+
};
|
|
73
103
|
}
|
|
74
104
|
function transformSchema(schema, ctx) {
|
|
75
105
|
return documentDeclarations.documentDeclarations(transformDocument(schema, ctx));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform-schema.cjs","sources":["../../src/api/transform-schema.ts"],"sourcesContent":["import type { ts } from \"../adapters/type-ast-bridge/typescript-types.js\";\nimport { documentBody, documentClosing } from \"../application/transform/document/document.js\";\nimport { renameTakenAliases } from \"../application/transform/document/root-type-aliases.js\";\nimport { RunFooter } from \"../application/transform/footer/document-footer.js\";\nimport { checkedEnumValues } from \"../application/transform/footer/enum-values-check.js\";\nimport {\n SharedEnumNameRecorder,\n type SharedEnumNames,\n} from \"../application/transform/footer/shared-enum-names.js\";\nimport type { IrDeclaration } from \"../domain/ir/nodes.js\";\nimport type { DocumentObject } from \"../domain/openapi/document-object.js\";\nimport { FIX } from \"../domain/output-fixes.js\";\nimport type { GlobalContext, OpenAPI3 } from \"../types.js\";\nimport { FirstSchemaNameRecorder } from \"./discriminator-enum-names.js\";\nimport { documentDeclarations, type TransformedDocument } from \"./document-declarations.js\";\nimport { excludedValuesWarning } from \"./enum-values-warnings.js\";\nimport { type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\nimport { ContextFooterSink } from \"./footer-sink.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { createTransformContext } from \"./transform-context.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/** Whether a footer entry is named `operations` (any declaration kind, as in the original). */\nfunction isOperations(entry: FooterEntry): boolean {\n const name = isIrDeclaration(entry)\n ? (entry as { name?: string }).name\n : (entry as Partial<ts.InterfaceDeclaration>).name?.escapedText;\n return name === OPERATIONS_NAME;\n}\n\n/** Drops a message: the first pass must not repeat the run's warnings or debug lines. */\nconst dropMessage = (): void => undefined;\nconst DROPPED_MESSAGES = { debug: dropMessage, warn: dropMessage, error: dropMessage };\n\n/** A shared enum name recorder of a first pass, and the names it gives the second. */\ninterface EnumNameRecorder extends SharedEnumNames {\n chosenNames(): SharedEnumNames;\n}\n\n/**\n * The names of shared enums, known only at the end: a first pass transforms the document into a\n * scratch footer that `recorder` watches; its output is dropped. User callbacks run in both\n * passes. The `dedupe-enum-names` fix (ADR-021, upstream #1683) names an enum by all of its\n * schemas; `discriminator-values` keeps the first declaring schema's name\n * (`FirstSchemaNameRecorder`).\n */\nfunction sharedEnumNamesOf(\n document: DocumentObject,\n ctx: RunContext,\n recorder: EnumNameRecorder,\n): SharedEnumNames {\n const injectFooter: FooterEntry[] = [];\n const scratch: RunContext = {\n ...ctx,\n injectFooter,\n runFooter: new RunFooter(new ContextFooterSink(injectFooter), true, recorder),\n logger: DROPPED_MESSAGES,\n legacyCallbackWarnings: new Set(),\n };\n const scratchContext = createTransformContext(scratch);\n documentBody(document, scratchContext, () => injectFooter.filter(isIrDeclaration));\n return recorder.chosenNames();\n}\n\n/** The recorder of the run's fixes, or null where the first schema's name needs no first pass. */\nfunction enumNameRecorderOf(ctx: GlobalContext): EnumNameRecorder | null {\n if (ctx.fix?.includes(FIX.DEDUPE_ENUM_NAMES)) {\n return new SharedEnumNameRecorder();\n }\n return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;\n}\n\n/** With a naming fix, `--enum` and `--dedupe-enums`, the run's footer names shared enums. */\nfunction withSharedEnumNames(document: DocumentObject, ctx: RunContext): void {\n const recorder = ctx.runFooter === undefined ? enumNameRecorderOf(ctx) : null;\n if (recorder === null || !ctx.enum || !ctx.dedupeEnums) {\n return;\n }\n const names = sharedEnumNamesOf(document, ctx, recorder);\n ctx.runFooter = new RunFooter(new ContextFooterSink(ctx.injectFooter), true, names);\n}\n\n/**\n * With `--enum-values`, arrays whose location type does not hold their values are typed by their\n * values (ADR-027); a location that excludes listed values is a contradiction of the document.\n */\nfunction enumValuesChecked(\n body: readonly IrDeclaration[],\n footer: FooterEntry[],\n ctx: RunContext,\n): FooterEntry[] {\n if (!ctx.enumValues) {\n return footer;\n }\n const checked = checkedEnumValues(footer, body, isIrDeclaration);\n for (const retype of checked.retyped) {\n if (retype.kind === \"excluded\") {\n ctx.logger?.warn(excludedValuesWarning(retype.name, retype.excluded));\n }\n }\n return checked.footer;\n}\n\n/** @internal Root types, the footer, then the closing declarations (Phase 5, step 6). */\nexport function transformDocument(schema: OpenAPI3, ctx: RunContext): TransformedDocument {\n const document = schema as DocumentObject;\n withSharedEnumNames(document, ctx);\n const context = createTransformContext(ctx);\n // documentBody registers the enums in the footer, so the footer is read after it.\n const rawBody = documentBody(document, context, () => ctx.injectFooter.filter(isIrDeclaration));\n const footer = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);\n const closing = documentClosing(document, context, footer.some(isOperations));\n const body = renameTakenAliases(rawBody, footer.filter(isIrDeclaration), closing);\n return { body, footer, closing };\n}\n\n/**\n * The whole document as IR declarations (ENGINEERING_PLAN 6.1–6.2); `openapiTS` returns the same\n * for a loaded document.\n */\nexport default function transformSchema(schema: OpenAPI3, ctx: GlobalContext): IrDeclaration[] {\n return documentDeclarations(transformDocument(schema, ctx));\n}\n"],"names":["isIrDeclaration","document","RunFooter","ContextFooterSink","createTransformContext","documentBody","FIX","SharedEnumNameRecorder","FirstSchemaNameRecorder","checkedEnumValues","excludedValuesWarning","documentClosing","renameTakenAliases","documentDeclarations"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transform-schema.cjs","sources":["../../src/api/transform-schema.ts"],"sourcesContent":["import type { ts } from \"../adapters/type-ast-bridge/typescript-types.js\";\nimport { documentBody, documentClosing } from \"../application/transform/document/document.js\";\nimport {\n NAMES_THE_OUTPUT_MAY_NEED,\n namesTheOutputNeeds,\n withEnumsRenamed,\n} from \"../application/transform/document/enum-names-given-back.js\";\nimport { operationKeysWritten } from \"../application/transform/document/operation-keys-written.js\";\nimport { renameTakenAliases } from \"../application/transform/document/root-type-aliases.js\";\nimport { RunFooter, type RunFooterNames } from \"../application/transform/footer/document-footer.js\";\nimport { EnumNameClaims } from \"../application/transform/footer/enum-name-claims.js\";\nimport { checkedEnumValues } from \"../application/transform/footer/enum-values-check.js\";\nimport { OperationKeys } from \"../application/transform/footer/operation-keys.js\";\nimport {\n FIRST_SCHEMA_NAMES,\n SharedEnumNameRecorder,\n type SharedEnumNames,\n} from \"../application/transform/footer/shared-enum-names.js\";\nimport type { IrDeclaration } from \"../domain/ir/nodes.js\";\nimport type { DocumentObject } from \"../domain/openapi/document-object.js\";\nimport { schemaDialectOf } from \"../domain/openapi/schema-dialect.js\";\nimport { FIX } from \"../domain/output-fixes.js\";\nimport type { GlobalContext, OpenAPI3 } from \"../types.js\";\nimport { FirstSchemaNameRecorder } from \"./discriminator-enum-names.js\";\nimport { documentDeclarations, type TransformedDocument } from \"./document-declarations.js\";\nimport { excludedValuesWarning } from \"./enum-values-warnings.js\";\nimport { type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\nimport { ContextFooterSink } from \"./footer-sink.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { createTransformContext } from \"./transform-context.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/** Whether a footer entry is named `operations` (any declaration kind, as in the original). */\nfunction isOperations(entry: FooterEntry): boolean {\n const name = isIrDeclaration(entry)\n ? (entry as { name?: string }).name\n : (entry as Partial<ts.InterfaceDeclaration>).name?.escapedText;\n return name === OPERATIONS_NAME;\n}\n\n/** Drops a message: the first pass must not repeat the run's warnings or debug lines. */\nconst dropMessage = (): void => undefined;\nconst DROPPED_MESSAGES = { debug: dropMessage, warn: dropMessage, error: dropMessage };\n\n/** A shared enum name recorder of a first pass, and the names it gives the second. */\ninterface EnumNameRecorder extends SharedEnumNames {\n chosenNames(): SharedEnumNames;\n}\n\n/**\n * The names of shared enums, known only at the end: a first pass transforms the document into a\n * scratch footer that `recorder` watches; its output is dropped. User callbacks run in both\n * passes. The `dedupe-enum-names` fix (ADR-021, upstream #1683) names an enum by all of its\n * schemas; `discriminator-values` keeps the first declaring schema's name\n * (`FirstSchemaNameRecorder`).\n */\nfunction sharedEnumNamesOf(\n document: DocumentObject,\n ctx: RunContext,\n recorder: EnumNameRecorder,\n): SharedEnumNames {\n const injectFooter: FooterEntry[] = [];\n const scratch: RunContext = {\n ...ctx,\n injectFooter,\n runFooter: new RunFooter(new ContextFooterSink(injectFooter), true, recorder),\n logger: DROPPED_MESSAGES,\n legacyCallbackWarnings: new Set(),\n };\n const scratchContext = createTransformContext(scratch);\n documentBody(document, scratchContext, () => injectFooter.filter(isIrDeclaration));\n return recorder.chosenNames();\n}\n\n/** The recorder of the run's fixes, or null where the first schema's name needs no first pass. */\nfunction enumNameRecorderOf(ctx: GlobalContext): EnumNameRecorder | null {\n if (ctx.fix?.includes(FIX.DEDUPE_ENUM_NAMES)) {\n return new SharedEnumNameRecorder();\n }\n return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;\n}\n\n/**\n * The run's footer: with a naming fix, `--enum` and `--dedupe-enums` it names shared enums. A\n * footer that a call before created on the context is kept.\n */\nfunction withRunFooter(document: DocumentObject, ctx: RunContext, names: RunFooterNames): void {\n if (ctx.runFooter !== undefined) {\n return;\n }\n const recorder = enumNameRecorderOf(ctx);\n const shared =\n recorder === null || !ctx.enum || !ctx.dedupeEnums\n ? null\n : sharedEnumNamesOf(document, ctx, recorder);\n const sink = new ContextFooterSink(ctx.injectFooter);\n ctx.runFooter =\n shared === null\n ? new RunFooter(sink, ctx.dedupeEnums, FIRST_SCHEMA_NAMES, names)\n : new RunFooter(sink, true, shared, names);\n}\n\n/**\n * The document with the enums renamed that gave way to a name the output turned out not to need\n * (`EnumNameClaims`): they get that name back, as before.\n */\nfunction withEnumNamesGivenBack(\n parts: TransformedDocument,\n names: RunFooterNames,\n): TransformedDocument {\n const footer = parts.footer.filter(isIrDeclaration);\n const renames = names.enums.givenBack(namesTheOutputNeeds({ ...parts, footer }));\n if (renames.size === 0) {\n return parts;\n }\n return {\n body: withEnumsRenamed(parts.body, renames),\n footer: parts.footer.map((entry) =>\n isIrDeclaration(entry) ? (withEnumsRenamed([entry], renames)[0] ?? entry) : entry,\n ),\n closing: withEnumsRenamed(parts.closing, renames),\n };\n}\n\n/**\n * With `--enum-values`, arrays whose location type does not hold their values are typed by their\n * values (ADR-027); a location that excludes listed values is a contradiction of the document.\n */\nfunction enumValuesChecked(\n body: readonly IrDeclaration[],\n footer: FooterEntry[],\n ctx: RunContext,\n): FooterEntry[] {\n if (!ctx.enumValues) {\n return footer;\n }\n const checked = checkedEnumValues(footer, body, isIrDeclaration);\n for (const retype of checked.retyped) {\n if (retype.kind === \"excluded\") {\n ctx.logger?.warn(excludedValuesWarning(retype.name, retype.excluded));\n }\n }\n return checked.footer;\n}\n\n/** @internal Root types, the footer, then the closing declarations (Phase 5, step 6). */\nexport function transformDocument(schema: OpenAPI3, ctx: RunContext): TransformedDocument {\n const document = schema as DocumentObject;\n ctx.schemaDialect = schemaDialectOf(document.openapi);\n const names: RunFooterNames = {\n enums: new EnumNameClaims(NAMES_THE_OUTPUT_MAY_NEED),\n operations: new OperationKeys(operationKeysWritten(document)),\n };\n withRunFooter(document, ctx, names);\n const context = createTransformContext(ctx);\n // documentBody registers the enums in the footer, so the footer is read after it.\n const rawBody = documentBody(document, context, () => ctx.injectFooter.filter(isIrDeclaration));\n const rawFooter = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);\n const rawClosing = documentClosing(document, context, rawFooter.some(isOperations));\n const parts = { body: rawBody, footer: rawFooter, closing: rawClosing };\n const { body, footer, closing } = withEnumNamesGivenBack(parts, names);\n return {\n body: renameTakenAliases(body, footer.filter(isIrDeclaration), closing),\n footer,\n closing,\n };\n}\n\n/**\n * The whole document as IR declarations (ENGINEERING_PLAN 6.1–6.2); `openapiTS` returns the same\n * for a loaded document.\n */\nexport default function transformSchema(schema: OpenAPI3, ctx: GlobalContext): IrDeclaration[] {\n return documentDeclarations(transformDocument(schema, ctx));\n}\n"],"names":["isIrDeclaration","document","RunFooter","ContextFooterSink","createTransformContext","documentBody","FIX","SharedEnumNameRecorder","FirstSchemaNameRecorder","FIRST_SCHEMA_NAMES","namesTheOutputNeeds","withEnumsRenamed","checkedEnumValues","excludedValuesWarning","schemaDialectOf","EnumNameClaims","NAMES_THE_OUTPUT_MAY_NEED","OperationKeys","operationKeysWritten","documentClosing","renameTakenAliases","documentDeclarations"],"mappings":"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"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { documentBody, documentClosing } from '../application/transform/document/document.mjs';
|
|
2
|
+
import { NAMES_THE_OUTPUT_MAY_NEED, namesTheOutputNeeds, withEnumsRenamed } from '../application/transform/document/enum-names-given-back.mjs';
|
|
3
|
+
import { operationKeysWritten } from '../application/transform/document/operation-keys-written.mjs';
|
|
2
4
|
import { renameTakenAliases } from '../application/transform/document/root-type-aliases.mjs';
|
|
3
5
|
import { RunFooter } from '../application/transform/footer/document-footer.mjs';
|
|
6
|
+
import { EnumNameClaims } from '../application/transform/footer/enum-name-claims.mjs';
|
|
4
7
|
import { checkedEnumValues } from '../application/transform/footer/enum-values-check.mjs';
|
|
5
|
-
import {
|
|
8
|
+
import { OperationKeys } from '../application/transform/footer/operation-keys.mjs';
|
|
9
|
+
import { FIRST_SCHEMA_NAMES, SharedEnumNameRecorder } from '../application/transform/footer/shared-enum-names.mjs';
|
|
10
|
+
import { schemaDialectOf } from '../domain/openapi/schema-dialect.mjs';
|
|
6
11
|
import { FIX } from '../domain/output-fixes.mjs';
|
|
7
12
|
import { FirstSchemaNameRecorder } from './discriminator-enum-names.mjs';
|
|
8
13
|
import { documentDeclarations } from './document-declarations.mjs';
|
|
@@ -37,13 +42,28 @@ function enumNameRecorderOf(ctx) {
|
|
|
37
42
|
}
|
|
38
43
|
return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;
|
|
39
44
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
if (recorder === null || !ctx.enum || !ctx.dedupeEnums) {
|
|
45
|
+
function withRunFooter(document, ctx, names) {
|
|
46
|
+
if (ctx.runFooter !== void 0) {
|
|
43
47
|
return;
|
|
44
48
|
}
|
|
45
|
-
const
|
|
46
|
-
ctx.
|
|
49
|
+
const recorder = enumNameRecorderOf(ctx);
|
|
50
|
+
const shared = recorder === null || !ctx.enum || !ctx.dedupeEnums ? null : sharedEnumNamesOf(document, ctx, recorder);
|
|
51
|
+
const sink = new ContextFooterSink(ctx.injectFooter);
|
|
52
|
+
ctx.runFooter = shared === null ? new RunFooter(sink, ctx.dedupeEnums, FIRST_SCHEMA_NAMES, names) : new RunFooter(sink, true, shared, names);
|
|
53
|
+
}
|
|
54
|
+
function withEnumNamesGivenBack(parts, names) {
|
|
55
|
+
const footer = parts.footer.filter(isIrDeclaration);
|
|
56
|
+
const renames = names.enums.givenBack(namesTheOutputNeeds({ ...parts, footer }));
|
|
57
|
+
if (renames.size === 0) {
|
|
58
|
+
return parts;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
body: withEnumsRenamed(parts.body, renames),
|
|
62
|
+
footer: parts.footer.map(
|
|
63
|
+
(entry) => isIrDeclaration(entry) ? withEnumsRenamed([entry], renames)[0] ?? entry : entry
|
|
64
|
+
),
|
|
65
|
+
closing: withEnumsRenamed(parts.closing, renames)
|
|
66
|
+
};
|
|
47
67
|
}
|
|
48
68
|
function enumValuesChecked(body, footer, ctx) {
|
|
49
69
|
if (!ctx.enumValues) {
|
|
@@ -59,13 +79,23 @@ function enumValuesChecked(body, footer, ctx) {
|
|
|
59
79
|
}
|
|
60
80
|
function transformDocument(schema, ctx) {
|
|
61
81
|
const document = schema;
|
|
62
|
-
|
|
82
|
+
ctx.schemaDialect = schemaDialectOf(document.openapi);
|
|
83
|
+
const names = {
|
|
84
|
+
enums: new EnumNameClaims(NAMES_THE_OUTPUT_MAY_NEED),
|
|
85
|
+
operations: new OperationKeys(operationKeysWritten(document))
|
|
86
|
+
};
|
|
87
|
+
withRunFooter(document, ctx, names);
|
|
63
88
|
const context = createTransformContext(ctx);
|
|
64
89
|
const rawBody = documentBody(document, context, () => ctx.injectFooter.filter(isIrDeclaration));
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
90
|
+
const rawFooter = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);
|
|
91
|
+
const rawClosing = documentClosing(document, context, rawFooter.some(isOperations));
|
|
92
|
+
const parts = { body: rawBody, footer: rawFooter, closing: rawClosing };
|
|
93
|
+
const { body, footer, closing } = withEnumNamesGivenBack(parts, names);
|
|
94
|
+
return {
|
|
95
|
+
body: renameTakenAliases(body, footer.filter(isIrDeclaration), closing),
|
|
96
|
+
footer,
|
|
97
|
+
closing
|
|
98
|
+
};
|
|
69
99
|
}
|
|
70
100
|
function transformSchema(schema, ctx) {
|
|
71
101
|
return documentDeclarations(transformDocument(schema, ctx));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform-schema.mjs","sources":["../../src/api/transform-schema.ts"],"sourcesContent":["import type { ts } from \"../adapters/type-ast-bridge/typescript-types.js\";\nimport { documentBody, documentClosing } from \"../application/transform/document/document.js\";\nimport { renameTakenAliases } from \"../application/transform/document/root-type-aliases.js\";\nimport { RunFooter } from \"../application/transform/footer/document-footer.js\";\nimport { checkedEnumValues } from \"../application/transform/footer/enum-values-check.js\";\nimport {\n SharedEnumNameRecorder,\n type SharedEnumNames,\n} from \"../application/transform/footer/shared-enum-names.js\";\nimport type { IrDeclaration } from \"../domain/ir/nodes.js\";\nimport type { DocumentObject } from \"../domain/openapi/document-object.js\";\nimport { FIX } from \"../domain/output-fixes.js\";\nimport type { GlobalContext, OpenAPI3 } from \"../types.js\";\nimport { FirstSchemaNameRecorder } from \"./discriminator-enum-names.js\";\nimport { documentDeclarations, type TransformedDocument } from \"./document-declarations.js\";\nimport { excludedValuesWarning } from \"./enum-values-warnings.js\";\nimport { type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\nimport { ContextFooterSink } from \"./footer-sink.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { createTransformContext } from \"./transform-context.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/** Whether a footer entry is named `operations` (any declaration kind, as in the original). */\nfunction isOperations(entry: FooterEntry): boolean {\n const name = isIrDeclaration(entry)\n ? (entry as { name?: string }).name\n : (entry as Partial<ts.InterfaceDeclaration>).name?.escapedText;\n return name === OPERATIONS_NAME;\n}\n\n/** Drops a message: the first pass must not repeat the run's warnings or debug lines. */\nconst dropMessage = (): void => undefined;\nconst DROPPED_MESSAGES = { debug: dropMessage, warn: dropMessage, error: dropMessage };\n\n/** A shared enum name recorder of a first pass, and the names it gives the second. */\ninterface EnumNameRecorder extends SharedEnumNames {\n chosenNames(): SharedEnumNames;\n}\n\n/**\n * The names of shared enums, known only at the end: a first pass transforms the document into a\n * scratch footer that `recorder` watches; its output is dropped. User callbacks run in both\n * passes. The `dedupe-enum-names` fix (ADR-021, upstream #1683) names an enum by all of its\n * schemas; `discriminator-values` keeps the first declaring schema's name\n * (`FirstSchemaNameRecorder`).\n */\nfunction sharedEnumNamesOf(\n document: DocumentObject,\n ctx: RunContext,\n recorder: EnumNameRecorder,\n): SharedEnumNames {\n const injectFooter: FooterEntry[] = [];\n const scratch: RunContext = {\n ...ctx,\n injectFooter,\n runFooter: new RunFooter(new ContextFooterSink(injectFooter), true, recorder),\n logger: DROPPED_MESSAGES,\n legacyCallbackWarnings: new Set(),\n };\n const scratchContext = createTransformContext(scratch);\n documentBody(document, scratchContext, () => injectFooter.filter(isIrDeclaration));\n return recorder.chosenNames();\n}\n\n/** The recorder of the run's fixes, or null where the first schema's name needs no first pass. */\nfunction enumNameRecorderOf(ctx: GlobalContext): EnumNameRecorder | null {\n if (ctx.fix?.includes(FIX.DEDUPE_ENUM_NAMES)) {\n return new SharedEnumNameRecorder();\n }\n return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;\n}\n\n/** With a naming fix, `--enum` and `--dedupe-enums`, the run's footer names shared enums. */\nfunction withSharedEnumNames(document: DocumentObject, ctx: RunContext): void {\n const recorder = ctx.runFooter === undefined ? enumNameRecorderOf(ctx) : null;\n if (recorder === null || !ctx.enum || !ctx.dedupeEnums) {\n return;\n }\n const names = sharedEnumNamesOf(document, ctx, recorder);\n ctx.runFooter = new RunFooter(new ContextFooterSink(ctx.injectFooter), true, names);\n}\n\n/**\n * With `--enum-values`, arrays whose location type does not hold their values are typed by their\n * values (ADR-027); a location that excludes listed values is a contradiction of the document.\n */\nfunction enumValuesChecked(\n body: readonly IrDeclaration[],\n footer: FooterEntry[],\n ctx: RunContext,\n): FooterEntry[] {\n if (!ctx.enumValues) {\n return footer;\n }\n const checked = checkedEnumValues(footer, body, isIrDeclaration);\n for (const retype of checked.retyped) {\n if (retype.kind === \"excluded\") {\n ctx.logger?.warn(excludedValuesWarning(retype.name, retype.excluded));\n }\n }\n return checked.footer;\n}\n\n/** @internal Root types, the footer, then the closing declarations (Phase 5, step 6). */\nexport function transformDocument(schema: OpenAPI3, ctx: RunContext): TransformedDocument {\n const document = schema as DocumentObject;\n withSharedEnumNames(document, ctx);\n const context = createTransformContext(ctx);\n // documentBody registers the enums in the footer, so the footer is read after it.\n const rawBody = documentBody(document, context, () => ctx.injectFooter.filter(isIrDeclaration));\n const footer = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);\n const closing = documentClosing(document, context, footer.some(isOperations));\n const body = renameTakenAliases(rawBody, footer.filter(isIrDeclaration), closing);\n return { body, footer, closing };\n}\n\n/**\n * The whole document as IR declarations (ENGINEERING_PLAN 6.1–6.2); `openapiTS` returns the same\n * for a loaded document.\n */\nexport default function transformSchema(schema: OpenAPI3, ctx: GlobalContext): IrDeclaration[] {\n return documentDeclarations(transformDocument(schema, ctx));\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAqBA,MAAM,eAAA,GAAkB,YAAA;AAGxB,SAAS,aAAa,KAAA,EAA6B;AACjD,EAAA,MAAM,OAAO,eAAA,CAAgB,KAAK,IAC7B,KAAA,CAA4B,IAAA,GAC5B,MAA2C,IAAA,EAAM,WAAA;AACtD,EAAA,OAAO,IAAA,KAAS,eAAA;AAClB;AAGA,MAAM,cAAc,MAAY,MAAA;AAChC,MAAM,mBAAmB,EAAE,KAAA,EAAO,aAAa,IAAA,EAAM,WAAA,EAAa,OAAO,WAAA,EAAY;AAcrF,SAAS,iBAAA,CACP,QAAA,EACA,GAAA,EACA,QAAA,EACiB;AACjB,EAAA,MAAM,eAA8B,EAAC;AACrC,EAAA,MAAM,OAAA,GAAsB;AAAA,IAC1B,GAAG,GAAA;AAAA,IACH,YAAA;AAAA,IACA,SAAA,EAAW,IAAI,SAAA,CAAU,IAAI,kBAAkB,YAAY,CAAA,EAAG,MAAM,QAAQ,CAAA;AAAA,IAC5E,MAAA,EAAQ,gBAAA;AAAA,IACR,sBAAA,sBAA4B,GAAA;AAAI,GAClC;AACA,EAAA,MAAM,cAAA,GAAiB,uBAAuB,OAAO,CAAA;AACrD,EAAA,YAAA,CAAa,UAAU,cAAA,EAAgB,MAAM,YAAA,CAAa,MAAA,CAAO,eAAe,CAAC,CAAA;AACjF,EAAA,OAAO,SAAS,WAAA,EAAY;AAC9B;AAGA,SAAS,mBAAmB,GAAA,EAA6C;AACvE,EAAA,IAAI,GAAA,CAAI,GAAA,EAAK,QAAA,CAAS,GAAA,CAAI,iBAAiB,CAAA,EAAG;AAC5C,IAAA,OAAO,IAAI,sBAAA,EAAuB;AAAA,EACpC;AACA,EAAA,OAAO,GAAA,CAAI,KAAK,QAAA,CAAS,GAAA,CAAI,oBAAoB,CAAA,GAAI,IAAI,yBAAwB,GAAI,IAAA;AACvF;AAGA,SAAS,mBAAA,CAAoB,UAA0B,GAAA,EAAuB;AAC5E,EAAA,MAAM,WAAW,GAAA,CAAI,SAAA,KAAc,MAAA,GAAY,kBAAA,CAAmB,GAAG,CAAA,GAAI,IAAA;AACzE,EAAA,IAAI,aAAa,IAAA,IAAQ,CAAC,IAAI,IAAA,IAAQ,CAAC,IAAI,WAAA,EAAa;AACtD,IAAA;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,QAAA,EAAU,GAAA,EAAK,QAAQ,CAAA;AACvD,EAAA,GAAA,CAAI,SAAA,GAAY,IAAI,SAAA,CAAU,IAAI,kBAAkB,GAAA,CAAI,YAAY,CAAA,EAAG,IAAA,EAAM,KAAK,CAAA;AACpF;AAMA,SAAS,iBAAA,CACP,IAAA,EACA,MAAA,EACA,GAAA,EACe;AACf,EAAA,IAAI,CAAC,IAAI,UAAA,EAAY;AACnB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,MAAA,EAAQ,IAAA,EAAM,eAAe,CAAA;AAC/D,EAAA,KAAA,MAAW,MAAA,IAAU,QAAQ,OAAA,EAAS;AACpC,IAAA,IAAI,MAAA,CAAO,SAAS,UAAA,EAAY;AAC9B,MAAA,GAAA,CAAI,QAAQ,IAAA,CAAK,qBAAA,CAAsB,OAAO,IAAA,EAAM,MAAA,CAAO,QAAQ,CAAC,CAAA;AAAA,IACtE;AAAA,EACF;AACA,EAAA,OAAO,OAAA,CAAQ,MAAA;AACjB;AAGO,SAAS,iBAAA,CAAkB,QAAkB,GAAA,EAAsC;AACxF,EAAA,MAAM,QAAA,GAAW,MAAA;AACjB,EAAA,mBAAA,CAAoB,UAAU,GAAG,CAAA;AACjC,EAAA,MAAM,OAAA,GAAU,uBAAuB,GAAG,CAAA;AAE1C,EAAA,MAAM,OAAA,GAAU,aAAa,QAAA,EAAU,OAAA,EAAS,MAAM,GAAA,CAAI,YAAA,CAAa,MAAA,CAAO,eAAe,CAAC,CAAA;AAC9F,EAAA,MAAM,MAAA,GAAS,kBAAkB,OAAA,EAAS,CAAC,GAAG,GAAA,CAAI,YAAY,GAAG,GAAG,CAAA;AACpE,EAAA,MAAM,UAAU,eAAA,CAAgB,QAAA,EAAU,SAAS,MAAA,CAAO,IAAA,CAAK,YAAY,CAAC,CAAA;AAC5E,EAAA,MAAM,OAAO,kBAAA,CAAmB,OAAA,EAAS,OAAO,MAAA,CAAO,eAAe,GAAG,OAAO,CAAA;AAChF,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAQ;AACjC;AAMA,SAAwB,eAAA,CAAgB,QAAkB,GAAA,EAAqC;AAC7F,EAAA,OAAO,oBAAA,CAAqB,iBAAA,CAAkB,MAAA,EAAQ,GAAG,CAAC,CAAA;AAC5D;;"}
|
|
1
|
+
{"version":3,"file":"transform-schema.mjs","sources":["../../src/api/transform-schema.ts"],"sourcesContent":["import type { ts } from \"../adapters/type-ast-bridge/typescript-types.js\";\nimport { documentBody, documentClosing } from \"../application/transform/document/document.js\";\nimport {\n NAMES_THE_OUTPUT_MAY_NEED,\n namesTheOutputNeeds,\n withEnumsRenamed,\n} from \"../application/transform/document/enum-names-given-back.js\";\nimport { operationKeysWritten } from \"../application/transform/document/operation-keys-written.js\";\nimport { renameTakenAliases } from \"../application/transform/document/root-type-aliases.js\";\nimport { RunFooter, type RunFooterNames } from \"../application/transform/footer/document-footer.js\";\nimport { EnumNameClaims } from \"../application/transform/footer/enum-name-claims.js\";\nimport { checkedEnumValues } from \"../application/transform/footer/enum-values-check.js\";\nimport { OperationKeys } from \"../application/transform/footer/operation-keys.js\";\nimport {\n FIRST_SCHEMA_NAMES,\n SharedEnumNameRecorder,\n type SharedEnumNames,\n} from \"../application/transform/footer/shared-enum-names.js\";\nimport type { IrDeclaration } from \"../domain/ir/nodes.js\";\nimport type { DocumentObject } from \"../domain/openapi/document-object.js\";\nimport { schemaDialectOf } from \"../domain/openapi/schema-dialect.js\";\nimport { FIX } from \"../domain/output-fixes.js\";\nimport type { GlobalContext, OpenAPI3 } from \"../types.js\";\nimport { FirstSchemaNameRecorder } from \"./discriminator-enum-names.js\";\nimport { documentDeclarations, type TransformedDocument } from \"./document-declarations.js\";\nimport { excludedValuesWarning } from \"./enum-values-warnings.js\";\nimport { type FooterEntry, isIrDeclaration } from \"./footer-entry.js\";\nimport { ContextFooterSink } from \"./footer-sink.js\";\nimport type { RunContext } from \"./run-context.js\";\nimport { createTransformContext } from \"./transform-context.js\";\n\nconst OPERATIONS_NAME = \"operations\";\n\n/** Whether a footer entry is named `operations` (any declaration kind, as in the original). */\nfunction isOperations(entry: FooterEntry): boolean {\n const name = isIrDeclaration(entry)\n ? (entry as { name?: string }).name\n : (entry as Partial<ts.InterfaceDeclaration>).name?.escapedText;\n return name === OPERATIONS_NAME;\n}\n\n/** Drops a message: the first pass must not repeat the run's warnings or debug lines. */\nconst dropMessage = (): void => undefined;\nconst DROPPED_MESSAGES = { debug: dropMessage, warn: dropMessage, error: dropMessage };\n\n/** A shared enum name recorder of a first pass, and the names it gives the second. */\ninterface EnumNameRecorder extends SharedEnumNames {\n chosenNames(): SharedEnumNames;\n}\n\n/**\n * The names of shared enums, known only at the end: a first pass transforms the document into a\n * scratch footer that `recorder` watches; its output is dropped. User callbacks run in both\n * passes. The `dedupe-enum-names` fix (ADR-021, upstream #1683) names an enum by all of its\n * schemas; `discriminator-values` keeps the first declaring schema's name\n * (`FirstSchemaNameRecorder`).\n */\nfunction sharedEnumNamesOf(\n document: DocumentObject,\n ctx: RunContext,\n recorder: EnumNameRecorder,\n): SharedEnumNames {\n const injectFooter: FooterEntry[] = [];\n const scratch: RunContext = {\n ...ctx,\n injectFooter,\n runFooter: new RunFooter(new ContextFooterSink(injectFooter), true, recorder),\n logger: DROPPED_MESSAGES,\n legacyCallbackWarnings: new Set(),\n };\n const scratchContext = createTransformContext(scratch);\n documentBody(document, scratchContext, () => injectFooter.filter(isIrDeclaration));\n return recorder.chosenNames();\n}\n\n/** The recorder of the run's fixes, or null where the first schema's name needs no first pass. */\nfunction enumNameRecorderOf(ctx: GlobalContext): EnumNameRecorder | null {\n if (ctx.fix?.includes(FIX.DEDUPE_ENUM_NAMES)) {\n return new SharedEnumNameRecorder();\n }\n return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;\n}\n\n/**\n * The run's footer: with a naming fix, `--enum` and `--dedupe-enums` it names shared enums. A\n * footer that a call before created on the context is kept.\n */\nfunction withRunFooter(document: DocumentObject, ctx: RunContext, names: RunFooterNames): void {\n if (ctx.runFooter !== undefined) {\n return;\n }\n const recorder = enumNameRecorderOf(ctx);\n const shared =\n recorder === null || !ctx.enum || !ctx.dedupeEnums\n ? null\n : sharedEnumNamesOf(document, ctx, recorder);\n const sink = new ContextFooterSink(ctx.injectFooter);\n ctx.runFooter =\n shared === null\n ? new RunFooter(sink, ctx.dedupeEnums, FIRST_SCHEMA_NAMES, names)\n : new RunFooter(sink, true, shared, names);\n}\n\n/**\n * The document with the enums renamed that gave way to a name the output turned out not to need\n * (`EnumNameClaims`): they get that name back, as before.\n */\nfunction withEnumNamesGivenBack(\n parts: TransformedDocument,\n names: RunFooterNames,\n): TransformedDocument {\n const footer = parts.footer.filter(isIrDeclaration);\n const renames = names.enums.givenBack(namesTheOutputNeeds({ ...parts, footer }));\n if (renames.size === 0) {\n return parts;\n }\n return {\n body: withEnumsRenamed(parts.body, renames),\n footer: parts.footer.map((entry) =>\n isIrDeclaration(entry) ? (withEnumsRenamed([entry], renames)[0] ?? entry) : entry,\n ),\n closing: withEnumsRenamed(parts.closing, renames),\n };\n}\n\n/**\n * With `--enum-values`, arrays whose location type does not hold their values are typed by their\n * values (ADR-027); a location that excludes listed values is a contradiction of the document.\n */\nfunction enumValuesChecked(\n body: readonly IrDeclaration[],\n footer: FooterEntry[],\n ctx: RunContext,\n): FooterEntry[] {\n if (!ctx.enumValues) {\n return footer;\n }\n const checked = checkedEnumValues(footer, body, isIrDeclaration);\n for (const retype of checked.retyped) {\n if (retype.kind === \"excluded\") {\n ctx.logger?.warn(excludedValuesWarning(retype.name, retype.excluded));\n }\n }\n return checked.footer;\n}\n\n/** @internal Root types, the footer, then the closing declarations (Phase 5, step 6). */\nexport function transformDocument(schema: OpenAPI3, ctx: RunContext): TransformedDocument {\n const document = schema as DocumentObject;\n ctx.schemaDialect = schemaDialectOf(document.openapi);\n const names: RunFooterNames = {\n enums: new EnumNameClaims(NAMES_THE_OUTPUT_MAY_NEED),\n operations: new OperationKeys(operationKeysWritten(document)),\n };\n withRunFooter(document, ctx, names);\n const context = createTransformContext(ctx);\n // documentBody registers the enums in the footer, so the footer is read after it.\n const rawBody = documentBody(document, context, () => ctx.injectFooter.filter(isIrDeclaration));\n const rawFooter = enumValuesChecked(rawBody, [...ctx.injectFooter], ctx);\n const rawClosing = documentClosing(document, context, rawFooter.some(isOperations));\n const parts = { body: rawBody, footer: rawFooter, closing: rawClosing };\n const { body, footer, closing } = withEnumNamesGivenBack(parts, names);\n return {\n body: renameTakenAliases(body, footer.filter(isIrDeclaration), closing),\n footer,\n closing,\n };\n}\n\n/**\n * The whole document as IR declarations (ENGINEERING_PLAN 6.1–6.2); `openapiTS` returns the same\n * for a loaded document.\n */\nexport default function transformSchema(schema: OpenAPI3, ctx: GlobalContext): IrDeclaration[] {\n return documentDeclarations(transformDocument(schema, ctx));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,12 @@ function isLineBreak(code) {
|
|
|
9
9
|
}
|
|
10
10
|
class TextWriter {
|
|
11
11
|
#options;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The written parts, joined once at the end. A string built with `+=` is kept by V8 as a tree
|
|
14
|
+
* of its parts, several times the size of the text, for as long as the text is kept (until the
|
|
15
|
+
* CLI writes it); `join` gives one flat string.
|
|
16
|
+
*/
|
|
17
|
+
#parts = [];
|
|
13
18
|
#indent = 0;
|
|
14
19
|
#isAtLineStart = true;
|
|
15
20
|
constructor(options) {
|
|
@@ -22,7 +27,9 @@ class TextWriter {
|
|
|
22
27
|
return this.#options;
|
|
23
28
|
}
|
|
24
29
|
get text() {
|
|
25
|
-
|
|
30
|
+
const text = this.#parts.join("");
|
|
31
|
+
this.#parts = [text];
|
|
32
|
+
return text;
|
|
26
33
|
}
|
|
27
34
|
increaseIndent() {
|
|
28
35
|
this.#indent++;
|
|
@@ -40,7 +47,7 @@ class TextWriter {
|
|
|
40
47
|
}
|
|
41
48
|
/** Write text exactly as given. */
|
|
42
49
|
rawWrite(text) {
|
|
43
|
-
this.#
|
|
50
|
+
this.#parts.push(text);
|
|
44
51
|
this.#updateLineStart(text);
|
|
45
52
|
}
|
|
46
53
|
/** End the current line; does nothing when nothing has been written on it yet. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-writer.cjs","sources":["../../../src/application/print/text-writer.ts"],"sourcesContent":["import type { PrintOptions } from \"./print-options.js\";\n\nconst LINE_FEED = 0x0a;\nconst CARRIAGE_RETURN = 0x0d;\nconst LINE_SEPARATOR = 0x2028;\nconst PARAGRAPH_SEPARATOR = 0x2029;\n\n/** Line breaks as the TypeScript scanner defines them (`isLineBreak`). */\nexport function isLineBreak(code: number): boolean {\n return (\n code === LINE_FEED ||\n code === CARRIAGE_RETURN ||\n code === LINE_SEPARATOR ||\n code === PARAGRAPH_SEPARATOR\n );\n}\n\n/**\n * Output buffer with indentation, modeled on the TypeScript printer's text writer: `write` indents\n * text that starts a line, `rawWrite` never does, and `writeLine` does nothing at the start of a\n * line. Matching these rules is what makes comment re-indentation byte-identical to the original.\n */\nexport class TextWriter {\n readonly #options: PrintOptions;\n #
|
|
1
|
+
{"version":3,"file":"text-writer.cjs","sources":["../../../src/application/print/text-writer.ts"],"sourcesContent":["import type { PrintOptions } from \"./print-options.js\";\n\nconst LINE_FEED = 0x0a;\nconst CARRIAGE_RETURN = 0x0d;\nconst LINE_SEPARATOR = 0x2028;\nconst PARAGRAPH_SEPARATOR = 0x2029;\n\n/** Line breaks as the TypeScript scanner defines them (`isLineBreak`). */\nexport function isLineBreak(code: number): boolean {\n return (\n code === LINE_FEED ||\n code === CARRIAGE_RETURN ||\n code === LINE_SEPARATOR ||\n code === PARAGRAPH_SEPARATOR\n );\n}\n\n/**\n * Output buffer with indentation, modeled on the TypeScript printer's text writer: `write` indents\n * text that starts a line, `rawWrite` never does, and `writeLine` does nothing at the start of a\n * line. Matching these rules is what makes comment re-indentation byte-identical to the original.\n */\nexport class TextWriter {\n readonly #options: PrintOptions;\n /**\n * The written parts, joined once at the end. A string built with `+=` is kept by V8 as a tree\n * of its parts, several times the size of the text, for as long as the text is kept (until the\n * CLI writes it); `join` gives one flat string.\n */\n #parts: string[] = [];\n #indent = 0;\n #isAtLineStart = true;\n\n constructor(options: PrintOptions) {\n this.#options = options;\n }\n\n get indent(): number {\n return this.#indent;\n }\n\n get options(): PrintOptions {\n return this.#options;\n }\n\n get text(): string {\n const text = this.#parts.join(\"\");\n this.#parts = [text];\n return text;\n }\n\n increaseIndent(): void {\n this.#indent++;\n }\n\n decreaseIndent(): void {\n this.#indent--;\n }\n\n /** Write text, indenting it first when it starts a line. */\n write(text: string): void {\n if (text.length === 0) {\n return;\n }\n const prefix = this.#isAtLineStart ? this.indentString(this.#indent) : \"\";\n this.rawWrite(prefix + text);\n }\n\n /** Write text exactly as given. */\n rawWrite(text: string): void {\n this.#parts.push(text);\n this.#updateLineStart(text);\n }\n\n /** End the current line; does nothing when nothing has been written on it yet. */\n writeLine(): void {\n if (!this.#isAtLineStart) {\n this.rawWrite(this.#options.newLine);\n }\n }\n\n indentString(level: number): string {\n return \" \".repeat(level * this.#options.indentSize);\n }\n\n // Like TypeScript: any write leaves the writer mid-line unless the text ends with a line break.\n #updateLineStart(text: string): void {\n this.#isAtLineStart = text.length > 0 && isLineBreak(text.charCodeAt(text.length - 1));\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAM,SAAA,GAAY,EAAA;AAClB,MAAM,eAAA,GAAkB,EAAA;AACxB,MAAM,cAAA,GAAiB,IAAA;AACvB,MAAM,mBAAA,GAAsB,IAAA;AAGrB,SAAS,YAAY,IAAA,EAAuB;AACjD,EAAA,OACE,SAAS,SAAA,IACT,IAAA,KAAS,eAAA,IACT,IAAA,KAAS,kBACT,IAAA,KAAS,mBAAA;AAEb;AAOO,MAAM,UAAA,CAAW;AAAA,EACb,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAAmB,EAAC;AAAA,EACpB,OAAA,GAAU,CAAA;AAAA,EACV,cAAA,GAAiB,IAAA;AAAA,EAEjB,YAAY,OAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAAA,EAClB;AAAA,EAEA,IAAI,MAAA,GAAiB;AACnB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,IAAI,OAAA,GAAwB;AAC1B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS,CAAC,IAAI,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAA;AAAA,EACP;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAA;AAAA,EACP;AAAA;AAAA,EAGA,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,GAAiB,KAAK,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA,GAAI,EAAA;AACvE,IAAA,IAAA,CAAK,QAAA,CAAS,SAAS,IAAI,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,SAAS,IAAA,EAAoB;AAC3B,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,EAC5B;AAAA;AAAA,EAGA,SAAA,GAAkB;AAChB,IAAA,IAAI,CAAC,KAAK,cAAA,EAAgB;AACxB,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,aAAa,KAAA,EAAuB;AAClC,IAAA,OAAO,GAAA,CAAI,MAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,SAAS,UAAU,CAAA;AAAA,EACpD;AAAA;AAAA,EAGA,iBAAiB,IAAA,EAAoB;AACnC,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,WAAA,CAAY,KAAK,UAAA,CAAW,IAAA,CAAK,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,EACvF;AACF;;;"}
|
|
@@ -7,7 +7,12 @@ function isLineBreak(code) {
|
|
|
7
7
|
}
|
|
8
8
|
class TextWriter {
|
|
9
9
|
#options;
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The written parts, joined once at the end. A string built with `+=` is kept by V8 as a tree
|
|
12
|
+
* of its parts, several times the size of the text, for as long as the text is kept (until the
|
|
13
|
+
* CLI writes it); `join` gives one flat string.
|
|
14
|
+
*/
|
|
15
|
+
#parts = [];
|
|
11
16
|
#indent = 0;
|
|
12
17
|
#isAtLineStart = true;
|
|
13
18
|
constructor(options) {
|
|
@@ -20,7 +25,9 @@ class TextWriter {
|
|
|
20
25
|
return this.#options;
|
|
21
26
|
}
|
|
22
27
|
get text() {
|
|
23
|
-
|
|
28
|
+
const text = this.#parts.join("");
|
|
29
|
+
this.#parts = [text];
|
|
30
|
+
return text;
|
|
24
31
|
}
|
|
25
32
|
increaseIndent() {
|
|
26
33
|
this.#indent++;
|
|
@@ -38,7 +45,7 @@ class TextWriter {
|
|
|
38
45
|
}
|
|
39
46
|
/** Write text exactly as given. */
|
|
40
47
|
rawWrite(text) {
|
|
41
|
-
this.#
|
|
48
|
+
this.#parts.push(text);
|
|
42
49
|
this.#updateLineStart(text);
|
|
43
50
|
}
|
|
44
51
|
/** End the current line; does nothing when nothing has been written on it yet. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-writer.mjs","sources":["../../../src/application/print/text-writer.ts"],"sourcesContent":["import type { PrintOptions } from \"./print-options.js\";\n\nconst LINE_FEED = 0x0a;\nconst CARRIAGE_RETURN = 0x0d;\nconst LINE_SEPARATOR = 0x2028;\nconst PARAGRAPH_SEPARATOR = 0x2029;\n\n/** Line breaks as the TypeScript scanner defines them (`isLineBreak`). */\nexport function isLineBreak(code: number): boolean {\n return (\n code === LINE_FEED ||\n code === CARRIAGE_RETURN ||\n code === LINE_SEPARATOR ||\n code === PARAGRAPH_SEPARATOR\n );\n}\n\n/**\n * Output buffer with indentation, modeled on the TypeScript printer's text writer: `write` indents\n * text that starts a line, `rawWrite` never does, and `writeLine` does nothing at the start of a\n * line. Matching these rules is what makes comment re-indentation byte-identical to the original.\n */\nexport class TextWriter {\n readonly #options: PrintOptions;\n #
|
|
1
|
+
{"version":3,"file":"text-writer.mjs","sources":["../../../src/application/print/text-writer.ts"],"sourcesContent":["import type { PrintOptions } from \"./print-options.js\";\n\nconst LINE_FEED = 0x0a;\nconst CARRIAGE_RETURN = 0x0d;\nconst LINE_SEPARATOR = 0x2028;\nconst PARAGRAPH_SEPARATOR = 0x2029;\n\n/** Line breaks as the TypeScript scanner defines them (`isLineBreak`). */\nexport function isLineBreak(code: number): boolean {\n return (\n code === LINE_FEED ||\n code === CARRIAGE_RETURN ||\n code === LINE_SEPARATOR ||\n code === PARAGRAPH_SEPARATOR\n );\n}\n\n/**\n * Output buffer with indentation, modeled on the TypeScript printer's text writer: `write` indents\n * text that starts a line, `rawWrite` never does, and `writeLine` does nothing at the start of a\n * line. Matching these rules is what makes comment re-indentation byte-identical to the original.\n */\nexport class TextWriter {\n readonly #options: PrintOptions;\n /**\n * The written parts, joined once at the end. A string built with `+=` is kept by V8 as a tree\n * of its parts, several times the size of the text, for as long as the text is kept (until the\n * CLI writes it); `join` gives one flat string.\n */\n #parts: string[] = [];\n #indent = 0;\n #isAtLineStart = true;\n\n constructor(options: PrintOptions) {\n this.#options = options;\n }\n\n get indent(): number {\n return this.#indent;\n }\n\n get options(): PrintOptions {\n return this.#options;\n }\n\n get text(): string {\n const text = this.#parts.join(\"\");\n this.#parts = [text];\n return text;\n }\n\n increaseIndent(): void {\n this.#indent++;\n }\n\n decreaseIndent(): void {\n this.#indent--;\n }\n\n /** Write text, indenting it first when it starts a line. */\n write(text: string): void {\n if (text.length === 0) {\n return;\n }\n const prefix = this.#isAtLineStart ? this.indentString(this.#indent) : \"\";\n this.rawWrite(prefix + text);\n }\n\n /** Write text exactly as given. */\n rawWrite(text: string): void {\n this.#parts.push(text);\n this.#updateLineStart(text);\n }\n\n /** End the current line; does nothing when nothing has been written on it yet. */\n writeLine(): void {\n if (!this.#isAtLineStart) {\n this.rawWrite(this.#options.newLine);\n }\n }\n\n indentString(level: number): string {\n return \" \".repeat(level * this.#options.indentSize);\n }\n\n // Like TypeScript: any write leaves the writer mid-line unless the text ends with a line break.\n #updateLineStart(text: string): void {\n this.#isAtLineStart = text.length > 0 && isLineBreak(text.charCodeAt(text.length - 1));\n }\n}\n"],"names":[],"mappings":"AAEA,MAAM,SAAA,GAAY,EAAA;AAClB,MAAM,eAAA,GAAkB,EAAA;AACxB,MAAM,cAAA,GAAiB,IAAA;AACvB,MAAM,mBAAA,GAAsB,IAAA;AAGrB,SAAS,YAAY,IAAA,EAAuB;AACjD,EAAA,OACE,SAAS,SAAA,IACT,IAAA,KAAS,eAAA,IACT,IAAA,KAAS,kBACT,IAAA,KAAS,mBAAA;AAEb;AAOO,MAAM,UAAA,CAAW;AAAA,EACb,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,SAAmB,EAAC;AAAA,EACpB,OAAA,GAAU,CAAA;AAAA,EACV,cAAA,GAAiB,IAAA;AAAA,EAEjB,YAAY,OAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAAA,EAClB;AAAA,EAEA,IAAI,MAAA,GAAiB;AACnB,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,IAAI,OAAA,GAAwB;AAC1B,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS,CAAC,IAAI,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAA;AAAA,EACP;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,OAAA,EAAA;AAAA,EACP;AAAA;AAAA,EAGA,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,GAAiB,KAAK,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA,GAAI,EAAA;AACvE,IAAA,IAAA,CAAK,QAAA,CAAS,SAAS,IAAI,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,SAAS,IAAA,EAAoB;AAC3B,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,iBAAiB,IAAI,CAAA;AAAA,EAC5B;AAAA;AAAA,EAGA,SAAA,GAAkB;AAChB,IAAA,IAAI,CAAC,KAAK,cAAA,EAAgB;AACxB,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,aAAa,KAAA,EAAuB;AAClC,IAAA,OAAO,GAAA,CAAI,MAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,SAAS,UAAU,CAAA;AAAA,EACpD;AAAA;AAAA,EAGA,iBAAiB,IAAA,EAAoB;AACnC,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,WAAA,CAAY,KAAK,UAAA,CAAW,IAAA,CAAK,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,EACvF;AACF;;"}
|
|
@@ -7,9 +7,10 @@ function isStackOverflowError(error) {
|
|
|
7
7
|
return error instanceof RangeError && STACK_OVERFLOW_MESSAGE.test(error.message);
|
|
8
8
|
}
|
|
9
9
|
function schemaTooDeepError(step, cause) {
|
|
10
|
+
const wide = step === "load" ? ", and so does an object with more than about 100,000 keys" : "";
|
|
10
11
|
return new errors.OpenAPITypesafeError({
|
|
11
12
|
code: errors.ERROR_CODES.SCHEMA_TOO_DEEP,
|
|
12
|
-
message: `The schema is nested too deeply to ${step}: the call stack ran out. Both inline schemas and chains of $ref (each schema referring to the next) count; shorten the deepest.`,
|
|
13
|
+
message: `The schema is nested too deeply to ${step}: the call stack ran out. Both inline schemas and chains of $ref (each schema referring to the next) count${wide}; shorten the deepest.`,
|
|
13
14
|
details: { step },
|
|
14
15
|
cause
|
|
15
16
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-overflow.cjs","sources":["../../src/application/stack-overflow.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../domain/errors.js\";\n\n/**\n * Deeply nested schemas (ENGINEERING_PLAN 8.5). Loading, bundling, transforming and printing walk\n * schemas recursively, and Redocly follows each `$ref` inside the walk. On the default Node.js\n * stack, about 550 levels of inline schemas or a chain of about 900 `$ref`s (each schema refers to\n * the next) run out of call stack. Real documents stay far below: every YAML or JSON file goes
|
|
1
|
+
{"version":3,"file":"stack-overflow.cjs","sources":["../../src/application/stack-overflow.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../domain/errors.js\";\n\n/**\n * Deeply nested schemas (ENGINEERING_PLAN 8.5). Loading, bundling, transforming and printing walk\n * schemas recursively, and Redocly follows each `$ref` inside the walk. On the default Node.js\n * stack, about 550 levels of inline schemas or a chain of about 900 `$ref`s (each schema refers to\n * the next) run out of call stack. Redocly's walk also passes the keys of an object to one call as\n * arguments, so a single object with more than about 100,000 keys runs out of it while loading.\n * Real documents stay far below: every YAML or JSON file goes through the YAML parser, which stops\n * at 100 levels, and the whole corpus passes. The overflow is reported as a typed error instead of\n * a `RangeError` with a stack trace.\n */\n\n/** The step that ran out of call stack; named in the message and the details. */\nexport type DeepSchemaStep = \"load\" | \"transform\" | \"print\";\n\n/** V8 and JavaScriptCore (Node.js, Deno, Bun) throw a `RangeError` with this message. */\nconst STACK_OVERFLOW_MESSAGE = /maximum call stack size exceeded/i;\n\n/** Whether a thrown value is a call stack overflow. */\nexport function isStackOverflowError(error: unknown): boolean {\n return error instanceof RangeError && STACK_OVERFLOW_MESSAGE.test(error.message);\n}\n\n/** The typed error for a document nested too deeply, or too wide, for the call stack. */\nexport function schemaTooDeepError(step: DeepSchemaStep, cause: unknown): OpenAPITypesafeError {\n const wide = step === \"load\" ? \", and so does an object with more than about 100,000 keys\" : \"\";\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_TOO_DEEP,\n message:\n `The schema is nested too deeply to ${step}: the call stack ran out. Both inline ` +\n `schemas and chains of $ref (each schema referring to the next) count${wide}; shorten ` +\n \"the deepest.\",\n details: { step },\n cause,\n });\n}\n\n/** Run a step and report a stack overflow in it as SCHEMA_TOO_DEEP; other errors pass through. */\nexport function withStackOverflowReported<T>(step: DeepSchemaStep, run: () => T): T {\n try {\n return run();\n } catch (error) {\n throw isStackOverflowError(error) ? schemaTooDeepError(step, error) : error;\n }\n}\n\n/** The asynchronous form of `withStackOverflowReported`. */\nexport async function withStackOverflowReportedAsync<T>(\n step: DeepSchemaStep,\n run: () => Promise<T>,\n): Promise<T> {\n try {\n return await run();\n } catch (error) {\n throw isStackOverflowError(error) ? schemaTooDeepError(step, error) : error;\n }\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES"],"mappings":";;;;AAiBA,MAAM,sBAAA,GAAyB,mCAAA;AAGxB,SAAS,qBAAqB,KAAA,EAAyB;AAC5D,EAAA,OAAO,KAAA,YAAiB,UAAA,IAAc,sBAAA,CAAuB,IAAA,CAAK,MAAM,OAAO,CAAA;AACjF;AAGO,SAAS,kBAAA,CAAmB,MAAsB,KAAA,EAAsC;AAC7F,EAAA,MAAM,IAAA,GAAO,IAAA,KAAS,MAAA,GAAS,2DAAA,GAA8D,EAAA;AAC7F,EAAA,OAAO,IAAIA,2BAAA,CAAqB;AAAA,IAC9B,MAAMC,kBAAA,CAAY,eAAA;AAAA,IAClB,OAAA,EACE,CAAA,mCAAA,EAAsC,IAAI,CAAA,0GAAA,EAC6B,IAAI,CAAA,sBAAA,CAAA;AAAA,IAE7E,OAAA,EAAS,EAAE,IAAA,EAAK;AAAA,IAChB;AAAA,GACD,CAAA;AACH;AAGO,SAAS,yBAAA,CAA6B,MAAsB,GAAA,EAAiB;AAClF,EAAA,IAAI;AACF,IAAA,OAAO,GAAA,EAAI;AAAA,EACb,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,qBAAqB,KAAK,CAAA,GAAI,kBAAA,CAAmB,IAAA,EAAM,KAAK,CAAA,GAAI,KAAA;AAAA,EACxE;AACF;AAGA,eAAsB,8BAAA,CACpB,MACA,GAAA,EACY;AACZ,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,GAAA,EAAI;AAAA,EACnB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,qBAAqB,KAAK,CAAA,GAAI,kBAAA,CAAmB,IAAA,EAAM,KAAK,CAAA,GAAI,KAAA;AAAA,EACxE;AACF;;;;;"}
|
|
@@ -5,9 +5,10 @@ function isStackOverflowError(error) {
|
|
|
5
5
|
return error instanceof RangeError && STACK_OVERFLOW_MESSAGE.test(error.message);
|
|
6
6
|
}
|
|
7
7
|
function schemaTooDeepError(step, cause) {
|
|
8
|
+
const wide = step === "load" ? ", and so does an object with more than about 100,000 keys" : "";
|
|
8
9
|
return new OpenAPITypesafeError({
|
|
9
10
|
code: ERROR_CODES.SCHEMA_TOO_DEEP,
|
|
10
|
-
message: `The schema is nested too deeply to ${step}: the call stack ran out. Both inline schemas and chains of $ref (each schema referring to the next) count; shorten the deepest.`,
|
|
11
|
+
message: `The schema is nested too deeply to ${step}: the call stack ran out. Both inline schemas and chains of $ref (each schema referring to the next) count${wide}; shorten the deepest.`,
|
|
11
12
|
details: { step },
|
|
12
13
|
cause
|
|
13
14
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stack-overflow.mjs","sources":["../../src/application/stack-overflow.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../domain/errors.js\";\n\n/**\n * Deeply nested schemas (ENGINEERING_PLAN 8.5). Loading, bundling, transforming and printing walk\n * schemas recursively, and Redocly follows each `$ref` inside the walk. On the default Node.js\n * stack, about 550 levels of inline schemas or a chain of about 900 `$ref`s (each schema refers to\n * the next) run out of call stack. Real documents stay far below: every YAML or JSON file goes
|
|
1
|
+
{"version":3,"file":"stack-overflow.mjs","sources":["../../src/application/stack-overflow.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../domain/errors.js\";\n\n/**\n * Deeply nested schemas (ENGINEERING_PLAN 8.5). Loading, bundling, transforming and printing walk\n * schemas recursively, and Redocly follows each `$ref` inside the walk. On the default Node.js\n * stack, about 550 levels of inline schemas or a chain of about 900 `$ref`s (each schema refers to\n * the next) run out of call stack. Redocly's walk also passes the keys of an object to one call as\n * arguments, so a single object with more than about 100,000 keys runs out of it while loading.\n * Real documents stay far below: every YAML or JSON file goes through the YAML parser, which stops\n * at 100 levels, and the whole corpus passes. The overflow is reported as a typed error instead of\n * a `RangeError` with a stack trace.\n */\n\n/** The step that ran out of call stack; named in the message and the details. */\nexport type DeepSchemaStep = \"load\" | \"transform\" | \"print\";\n\n/** V8 and JavaScriptCore (Node.js, Deno, Bun) throw a `RangeError` with this message. */\nconst STACK_OVERFLOW_MESSAGE = /maximum call stack size exceeded/i;\n\n/** Whether a thrown value is a call stack overflow. */\nexport function isStackOverflowError(error: unknown): boolean {\n return error instanceof RangeError && STACK_OVERFLOW_MESSAGE.test(error.message);\n}\n\n/** The typed error for a document nested too deeply, or too wide, for the call stack. */\nexport function schemaTooDeepError(step: DeepSchemaStep, cause: unknown): OpenAPITypesafeError {\n const wide = step === \"load\" ? \", and so does an object with more than about 100,000 keys\" : \"\";\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_TOO_DEEP,\n message:\n `The schema is nested too deeply to ${step}: the call stack ran out. Both inline ` +\n `schemas and chains of $ref (each schema referring to the next) count${wide}; shorten ` +\n \"the deepest.\",\n details: { step },\n cause,\n });\n}\n\n/** Run a step and report a stack overflow in it as SCHEMA_TOO_DEEP; other errors pass through. */\nexport function withStackOverflowReported<T>(step: DeepSchemaStep, run: () => T): T {\n try {\n return run();\n } catch (error) {\n throw isStackOverflowError(error) ? schemaTooDeepError(step, error) : error;\n }\n}\n\n/** The asynchronous form of `withStackOverflowReported`. */\nexport async function withStackOverflowReportedAsync<T>(\n step: DeepSchemaStep,\n run: () => Promise<T>,\n): Promise<T> {\n try {\n return await run();\n } catch (error) {\n throw isStackOverflowError(error) ? schemaTooDeepError(step, error) : error;\n }\n}\n"],"names":[],"mappings":";;AAiBA,MAAM,sBAAA,GAAyB,mCAAA;AAGxB,SAAS,qBAAqB,KAAA,EAAyB;AAC5D,EAAA,OAAO,KAAA,YAAiB,UAAA,IAAc,sBAAA,CAAuB,IAAA,CAAK,MAAM,OAAO,CAAA;AACjF;AAGO,SAAS,kBAAA,CAAmB,MAAsB,KAAA,EAAsC;AAC7F,EAAA,MAAM,IAAA,GAAO,IAAA,KAAS,MAAA,GAAS,2DAAA,GAA8D,EAAA;AAC7F,EAAA,OAAO,IAAI,oBAAA,CAAqB;AAAA,IAC9B,MAAM,WAAA,CAAY,eAAA;AAAA,IAClB,OAAA,EACE,CAAA,mCAAA,EAAsC,IAAI,CAAA,0GAAA,EAC6B,IAAI,CAAA,sBAAA,CAAA;AAAA,IAE7E,OAAA,EAAS,EAAE,IAAA,EAAK;AAAA,IAChB;AAAA,GACD,CAAA;AACH;AAGO,SAAS,yBAAA,CAA6B,MAAsB,GAAA,EAAiB;AAClF,EAAA,IAAI;AACF,IAAA,OAAO,GAAA,EAAI;AAAA,EACb,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,qBAAqB,KAAK,CAAA,GAAI,kBAAA,CAAmB,IAAA,EAAM,KAAK,CAAA,GAAI,KAAA;AAAA,EACxE;AACF;AAGA,eAAsB,8BAAA,CACpB,MACA,GAAA,EACY;AACZ,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,GAAA,EAAI;AAAA,EACnB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,qBAAqB,KAAK,CAAA,GAAI,kBAAA,CAAmB,IAAA,EAAM,KAAK,CAAA,GAAI,KAAA;AAAA,EACxE;AACF;;"}
|
|
@@ -27,7 +27,7 @@ const COMPONENT_TRANSFORMS = {
|
|
|
27
27
|
mediaTypes: mediaType.contentEntryType
|
|
28
28
|
};
|
|
29
29
|
function componentMember(kind, name, item, context) {
|
|
30
|
-
const location = { path: jsonPointer.
|
|
30
|
+
const location = { path: jsonPointer.appendPointer(jsonPointer.ROOT_POINTER, ["components", kind, name]), schema: item };
|
|
31
31
|
const type = COMPONENT_TRANSFORMS[kind](item, location, context);
|
|
32
32
|
const custom = context.callbacks.transform(item, location);
|
|
33
33
|
const property = constructors.irProperty(propertyName.toPropertyName(name), custom?.type ?? type, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.cjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["transformSchema","responseType","parameterType","requestBodyType","headerType","pathItemType","contentEntryType","createRef","irProperty","toPropertyName","withSchemaComment","schemaCommentOptionsOf","singularizeComponentKind","withIdentifierParts","alias","hasIdentifierStart","isReservedTypeName","isEnumSchema","documentEntries","rootTypeAlias","irObject","irKeyword","FIX","DECLARED_COMPONENT_KINDS","COMPONENT_KINDS"],"mappings":";;;;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAA,GAA4E;AAAA,EAChF,OAAA,EAASA,+BAAA;AAAA,EACT,SAAA,EAAWC,qBAAA;AAAA,EACX,UAAA,EAAYC,uBAAA;AAAA,EACZ,aAAA,EAAeC,2BAAA;AAAA,EACf,OAAA,EAASC,iBAAA;AAAA,EACT,SAAA,EAAWC,qBAAA;AAAA,EACX,UAAA,EAAYC;AACd,CAAA;AASA,SAAS,eAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,QAAA,GAAW,EAAE,IAAA,EAAMC,qBAAA,CAAU,CAAC,YAAA,EAAc,IAAA,EAAM,IAAI,CAAC,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAC7E,EAAA,MAAM,OAAO,oBAAA,CAAqB,IAAI,CAAA,CAAE,IAAA,EAAe,UAAU,OAAO,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,SAAA,CAAU,MAAM,QAAQ,CAAA;AACzD,EAAA,MAAM,WAAWC,uBAAA,CAAWC,2BAAA,CAAe,IAAI,CAAA,EAAG,MAAA,EAAQ,QAAQ,IAAA,EAAM;AAAA,IACtE,UAAA,EAAY,QAAQ,UAAA,IAAc,KAAA;AAAA,IAClC,UAAA,EAAY,QAAQ,OAAA,CAAQ;AAAA,GAC7B,CAAA;AACD,EAAA,OAAOC,gCAAkB,QAAA,EAAU,IAAA,EAAMC,qCAAuB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA;AACxF;AAaA,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,OAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,OAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAWC,yCAAA,CAAyB,IAAI,CAAC,CAAA;AAC/D,EAAA,MAAM,WAAW,IAAA,KAAS,SAAA;AAC1B,EAAA,MAAM,IAAA,GAAOC,kCAAA;AAAA,IACX,QAAQ,mBAAA,IAAuB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAO,WAAW,IAAI;AAAA,GACzE;AACA,EAAA,MAAM,YAAA,GAAe,CAACC,MAAAA,KAA0B;AAC9C,IAAA,MAAM,UAAA,GAAaA,MAAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC3C,IAAA,MAAM,YAAA,GAAe,QAAQ,uBAAA,IAA2B,QAAA;AACxD,IAAA,MAAM,aAAaC,iCAAA,CAAmB,UAAU,CAAA,IAAK,CAACC,kCAAmB,UAAU,CAAA;AACnF,IAAA,OAAO,YAAA,IAAgB,aAAa,UAAA,GAAaF,MAAAA;AAAA,EACnD,CAAA;AACA,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA;AAC5B,EAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,KAAM,QAAW,OAAA,EAAA,EAAW;AAC7D,IAAA,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,IAAI,OAAO,CAAA,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,aAAa,KAAK,CAAA;AAC3B;AASA,SAAS,YAAA,CAAa,SAA4B,KAAA,EAAqC;AACrF,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,OAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AACnC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,EACzB;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AACxB;AAGA,SAAS,WAAA,CAAY,IAAA,EAAqB,IAAA,EAAe,OAAA,EAAoC;AAC3F,EAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,EAAA,OAAO,OAAA,CAAQ,aAAa,EAAE,OAAA,CAAQ,QAAQ,IAAA,KAAS,SAAA,IAAaG,8BAAa,IAAI,CAAA,CAAA;AACvF;AAWA,SAAS,UAAA,CACP,IAAA,EACA,OAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,EAAE,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAQ,GAAI,OAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI;AAC1C,EAAA,MAAM,QAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAKC,+BAAA,CAAgB,UAAA,CAAW,IAAI,CAAA,IAAK,EAAC,EAAG,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA,EAAG;AAC3F,IAAA,KAAA,CAAM,KAAK,eAAA,CAAgB,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC,CAAA;AACrD,IAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA,EAAG;AACpC,MAAA,YAAA,CAAa,OAAA,EAASC,6BAAA,CAAc,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,SAAS,OAAO,CAAA,EAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,IAC7F;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,GAAS,CAAA,GAAIC,sBAAS,KAAK,CAAA,GAAIC,uBAAU,OAAO,CAAA;AACnE,EAAA,OAAA,CAAQ,WAAA,CAAY,KAAA;AAAA,IAClB,iCAA4B,IAAI,CAAA,CAAA;AAAA,IAChC,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI,GAAI;AAAA,GAC9B;AACA,EAAA,OAAOb,uBAAA,CAAWC,2BAAA,CAAe,IAAI,CAAA,EAAG,IAAI,CAAA;AAC9C;AAOO,SAAS,eACd,UAAA,EACA,OAAA,EACA,IAAA,mBAA4B,IAAI,KAAI,EAClB;AAGlB,EAAA,MAAM,UAAkD,EAAC;AACzD,EAAA,MAAM,SAAA,GAAY,QAAQ,OAAA,CAAQ,KAAA,CAAM,IAAIa,eAAA,CAAI,mBAAmB,CAAA,GAAI,EAAC,GAAI,IAAA;AAC5E,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAkB,IAAA,CAAK,IAAI,IAAc,CAAA;AACzD,EAAA,MAAM,OAAA,GAAU,EAAE,UAAA,EAAY,MAAA,EAAQ,SAAS,SAAA,EAAU;AACzD,EAAA,MAAM,aAAA,GAAgBC,0CAAyB,MAAA,CAAO,CAAC,SAAS,UAAA,CAAW,IAAI,MAAM,MAAS,CAAA;AAC9F,EAAA,MAAM,UAAU,CAAC,GAAGC,gCAAA,EAAiB,GAAG,aAAa,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,IAAA,KAC1D,UAAA,CAAW,IAAA,EAAM,SAAS,OAAO;AAAA,GACnC;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAMJ,sBAAS,OAAO,CAAA;AAAA,IACtB,WAAW,CAAC,GAAG,WAAW,GAAI,SAAA,IAAa,EAAG;AAAA,GAChD;AACF;;"}
|
|
1
|
+
{"version":3,"file":"components.cjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { appendPointer, ROOT_POINTER } from \"../../../domain/openapi/json-pointer.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: appendPointer(ROOT_POINTER, [\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["transformSchema","responseType","parameterType","requestBodyType","headerType","pathItemType","contentEntryType","appendPointer","ROOT_POINTER","irProperty","toPropertyName","withSchemaComment","schemaCommentOptionsOf","singularizeComponentKind","withIdentifierParts","alias","hasIdentifierStart","isReservedTypeName","isEnumSchema","documentEntries","rootTypeAlias","irObject","irKeyword","FIX","DECLARED_COMPONENT_KINDS","COMPONENT_KINDS"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { irObject, irProperty, irKeyword } from '../../../domain/ir/constructors
|
|
|
2
2
|
import { withIdentifierParts, hasIdentifierStart, isReservedTypeName } from '../../../domain/ir/identifier-text.mjs';
|
|
3
3
|
import { toPropertyName } from '../../../domain/ir/property-name.mjs';
|
|
4
4
|
import { DECLARED_COMPONENT_KINDS, COMPONENT_KINDS, isEnumSchema, singularizeComponentKind } from '../../../domain/openapi/components-object.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { appendPointer, ROOT_POINTER } from '../../../domain/openapi/json-pointer.mjs';
|
|
6
6
|
import { FIX } from '../../../domain/output-fixes.mjs';
|
|
7
7
|
import { documentEntries } from '../document-entries.mjs';
|
|
8
8
|
import { transformSchema } from '../schema/schema-transform.mjs';
|
|
@@ -25,7 +25,7 @@ const COMPONENT_TRANSFORMS = {
|
|
|
25
25
|
mediaTypes: contentEntryType
|
|
26
26
|
};
|
|
27
27
|
function componentMember(kind, name, item, context) {
|
|
28
|
-
const location = { path:
|
|
28
|
+
const location = { path: appendPointer(ROOT_POINTER, ["components", kind, name]), schema: item };
|
|
29
29
|
const type = COMPONENT_TRANSFORMS[kind](item, location, context);
|
|
30
30
|
const custom = context.callbacks.transform(item, location);
|
|
31
31
|
const property = irProperty(toPropertyName(name), custom?.type ?? type, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["alias"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { appendPointer, ROOT_POINTER } from \"../../../domain/openapi/json-pointer.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: appendPointer(ROOT_POINTER, [\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["alias"],"mappings":"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"}
|