openapi-typesafe 0.0.0 → 1.0.0-rc.1
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/LICENSE +22 -0
- package/README.md +71 -1
- package/bin/cli.js +4 -0
- package/dist/adapters/node-file-system/node-file-system.cjs +46 -0
- package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -0
- package/dist/adapters/node-file-system/node-file-system.mjs +40 -0
- package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -0
- package/dist/adapters/redocly-loader/alias-limit.cjs +16 -0
- package/dist/adapters/redocly-loader/alias-limit.cjs.map +1 -0
- package/dist/adapters/redocly-loader/alias-limit.mjs +14 -0
- package/dist/adapters/redocly-loader/alias-limit.mjs.map +1 -0
- package/dist/adapters/redocly-loader/allowed-hosts.cjs +42 -0
- package/dist/adapters/redocly-loader/allowed-hosts.cjs.map +1 -0
- package/dist/adapters/redocly-loader/allowed-hosts.mjs +40 -0
- package/dist/adapters/redocly-loader/allowed-hosts.mjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +53 -0
- package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +51 -0
- package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -0
- package/dist/adapters/redocly-loader/malformed-refs.cjs +41 -0
- package/dist/adapters/redocly-loader/malformed-refs.cjs.map +1 -0
- package/dist/adapters/redocly-loader/malformed-refs.mjs +38 -0
- package/dist/adapters/redocly-loader/malformed-refs.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs +61 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +54 -0
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +179 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +177 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-access.cjs +107 -0
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-access.mjs +99 -0
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-holders.cjs +31 -0
- package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-holders.mjs +29 -0
- package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +60 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.mjs +56 -0
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -0
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +87 -0
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -0
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +77 -0
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -0
- package/dist/adapters/redocly-loader/schema-source.cjs +104 -0
- package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -0
- package/dist/adapters/redocly-loader/schema-source.mjs +98 -0
- package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -0
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +62 -0
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -0
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +58 -0
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -0
- package/dist/adapters/terminal-logger/terminal-logger.cjs +67 -0
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -0
- package/dist/adapters/terminal-logger/terminal-logger.mjs +59 -0
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/footer-nodes.cjs +21 -0
- package/dist/adapters/type-ast-bridge/footer-nodes.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/footer-nodes.mjs +17 -0
- package/dist/adapters/type-ast-bridge/footer-nodes.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs +75 -0
- package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs +71 -0
- package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +148 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +142 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/lazy-node.cjs +23 -0
- package/dist/adapters/type-ast-bridge/lazy-node.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/lazy-node.mjs +21 -0
- package/dist/adapters/type-ast-bridge/lazy-node.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/load-typescript.cjs +57 -0
- package/dist/adapters/type-ast-bridge/load-typescript.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/load-typescript.mjs +51 -0
- package/dist/adapters/type-ast-bridge/load-typescript.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/print-typescript.cjs +21 -0
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/print-typescript.mjs +19 -0
- package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs +33 -0
- package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs +29 -0
- package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs.map +1 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +210 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +207 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -0
- package/dist/api/ast-to-string.cjs +39 -0
- package/dist/api/ast-to-string.cjs.map +1 -0
- package/dist/api/ast-to-string.mjs +37 -0
- package/dist/api/ast-to-string.mjs.map +1 -0
- package/dist/api/comment-header.cjs +11 -0
- package/dist/api/comment-header.cjs.map +1 -0
- package/dist/api/comment-header.mjs +9 -0
- package/dist/api/comment-header.mjs.map +1 -0
- package/dist/api/default-ports.cjs +38 -0
- package/dist/api/default-ports.cjs.map +1 -0
- package/dist/api/default-ports.mjs +28 -0
- package/dist/api/default-ports.mjs.map +1 -0
- package/dist/api/discriminator-conflict-warnings.cjs +25 -0
- package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
- package/dist/api/discriminator-conflict-warnings.mjs +23 -0
- package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
- package/dist/api/discriminator-enum-names.cjs +19 -0
- package/dist/api/discriminator-enum-names.cjs.map +1 -0
- package/dist/api/discriminator-enum-names.mjs +17 -0
- package/dist/api/discriminator-enum-names.mjs.map +1 -0
- package/dist/api/discriminator-enum-parent.cjs +59 -0
- package/dist/api/discriminator-enum-parent.cjs.map +1 -0
- package/dist/api/discriminator-enum-parent.mjs +57 -0
- package/dist/api/discriminator-enum-parent.mjs.map +1 -0
- package/dist/api/discriminator-enum.cjs +69 -0
- package/dist/api/discriminator-enum.cjs.map +1 -0
- package/dist/api/discriminator-enum.mjs +66 -0
- package/dist/api/discriminator-enum.mjs.map +1 -0
- package/dist/api/discriminator-other-owners.cjs +67 -0
- package/dist/api/discriminator-other-owners.cjs.map +1 -0
- package/dist/api/discriminator-other-owners.mjs +64 -0
- package/dist/api/discriminator-other-owners.mjs.map +1 -0
- package/dist/api/discriminator-patch.cjs +88 -0
- package/dist/api/discriminator-patch.cjs.map +1 -0
- package/dist/api/discriminator-patch.mjs +82 -0
- package/dist/api/discriminator-patch.mjs.map +1 -0
- package/dist/api/discriminator-scan.cjs +153 -0
- package/dist/api/discriminator-scan.cjs.map +1 -0
- package/dist/api/discriminator-scan.mjs +150 -0
- package/dist/api/discriminator-scan.mjs.map +1 -0
- package/dist/api/document-declarations.cjs +28 -0
- package/dist/api/document-declarations.cjs.map +1 -0
- package/dist/api/document-declarations.mjs +26 -0
- package/dist/api/document-declarations.mjs.map +1 -0
- package/dist/api/document-refs.cjs +53 -0
- package/dist/api/document-refs.cjs.map +1 -0
- package/dist/api/document-refs.mjs +50 -0
- package/dist/api/document-refs.mjs.map +1 -0
- package/dist/api/document-run.cjs +122 -0
- package/dist/api/document-run.cjs.map +1 -0
- package/dist/api/document-run.mjs +116 -0
- package/dist/api/document-run.mjs.map +1 -0
- package/dist/api/enum-values-warnings.cjs +16 -0
- package/dist/api/enum-values-warnings.cjs.map +1 -0
- package/dist/api/enum-values-warnings.mjs +14 -0
- package/dist/api/enum-values-warnings.mjs.map +1 -0
- package/dist/api/footer-entry.cjs +18 -0
- package/dist/api/footer-entry.cjs.map +1 -0
- package/dist/api/footer-entry.mjs +15 -0
- package/dist/api/footer-entry.mjs.map +1 -0
- package/dist/api/footer-sink.cjs +53 -0
- package/dist/api/footer-sink.cjs.map +1 -0
- package/dist/api/footer-sink.mjs +51 -0
- package/dist/api/footer-sink.mjs.map +1 -0
- package/dist/api/legacy-callback-warning.cjs +25 -0
- package/dist/api/legacy-callback-warning.cjs.map +1 -0
- package/dist/api/legacy-callback-warning.mjs +22 -0
- package/dist/api/legacy-callback-warning.mjs.map +1 -0
- package/dist/api/legacy-ts-helpers.cjs +203 -0
- package/dist/api/legacy-ts-helpers.cjs.map +1 -0
- package/dist/api/legacy-ts-helpers.mjs +187 -0
- package/dist/api/legacy-ts-helpers.mjs.map +1 -0
- package/dist/api/legacy-utils.cjs +65 -0
- package/dist/api/legacy-utils.cjs.map +1 -0
- package/dist/api/legacy-utils.mjs +50 -0
- package/dist/api/legacy-utils.mjs.map +1 -0
- package/dist/api/openapi-ts.cjs +40 -0
- package/dist/api/openapi-ts.cjs.map +1 -0
- package/dist/api/openapi-ts.mjs +34 -0
- package/dist/api/openapi-ts.mjs.map +1 -0
- package/dist/api/path-template-warnings.cjs +21 -0
- package/dist/api/path-template-warnings.cjs.map +1 -0
- package/dist/api/path-template-warnings.mjs +19 -0
- package/dist/api/path-template-warnings.mjs.map +1 -0
- package/dist/api/schema-callbacks.cjs +140 -0
- package/dist/api/schema-callbacks.cjs.map +1 -0
- package/dist/api/schema-callbacks.mjs +136 -0
- package/dist/api/schema-callbacks.mjs.map +1 -0
- package/dist/api/string-to-ast.cjs +21 -0
- package/dist/api/string-to-ast.cjs.map +1 -0
- package/dist/api/string-to-ast.mjs +18 -0
- package/dist/api/string-to-ast.mjs.map +1 -0
- package/dist/api/transform-context.cjs +84 -0
- package/dist/api/transform-context.cjs.map +1 -0
- package/dist/api/transform-context.mjs +67 -0
- package/dist/api/transform-context.mjs.map +1 -0
- package/dist/api/transform-schema.cjs +80 -0
- package/dist/api/transform-schema.cjs.map +1 -0
- package/dist/api/transform-schema.mjs +75 -0
- package/dist/api/transform-schema.mjs.map +1 -0
- package/dist/api/type-helpers.cjs +85 -0
- package/dist/api/type-helpers.cjs.map +1 -0
- package/dist/api/type-helpers.mjs +66 -0
- package/dist/api/type-helpers.mjs.map +1 -0
- package/dist/api/unsupported-feature-warnings.cjs +22 -0
- package/dist/api/unsupported-feature-warnings.cjs.map +1 -0
- package/dist/api/unsupported-feature-warnings.mjs +20 -0
- package/dist/api/unsupported-feature-warnings.mjs.map +1 -0
- package/dist/application/print/comment-writer.cjs +95 -0
- package/dist/application/print/comment-writer.cjs.map +1 -0
- package/dist/application/print/comment-writer.mjs +93 -0
- package/dist/application/print/comment-writer.mjs.map +1 -0
- package/dist/application/print/declaration-printer.cjs +83 -0
- package/dist/application/print/declaration-printer.cjs.map +1 -0
- package/dist/application/print/declaration-printer.mjs +81 -0
- package/dist/application/print/declaration-printer.mjs.map +1 -0
- package/dist/application/print/literal-text.cjs +52 -0
- package/dist/application/print/literal-text.cjs.map +1 -0
- package/dist/application/print/literal-text.mjs +48 -0
- package/dist/application/print/literal-text.mjs.map +1 -0
- package/dist/application/print/print-nodes.cjs +38 -0
- package/dist/application/print/print-nodes.cjs.map +1 -0
- package/dist/application/print/print-nodes.mjs +36 -0
- package/dist/application/print/print-nodes.mjs.map +1 -0
- package/dist/application/print/print-options.cjs +6 -0
- package/dist/application/print/print-options.cjs.map +1 -0
- package/dist/application/print/print-options.mjs +4 -0
- package/dist/application/print/print-options.mjs.map +1 -0
- package/dist/application/print/text-writer.cjs +63 -0
- package/dist/application/print/text-writer.cjs.map +1 -0
- package/dist/application/print/text-writer.mjs +60 -0
- package/dist/application/print/text-writer.mjs.map +1 -0
- package/dist/application/print/type-printer.cjs +219 -0
- package/dist/application/print/type-printer.cjs.map +1 -0
- package/dist/application/print/type-printer.mjs +215 -0
- package/dist/application/print/type-printer.mjs.map +1 -0
- package/dist/application/stack-overflow.cjs +36 -0
- package/dist/application/stack-overflow.cjs.map +1 -0
- package/dist/application/stack-overflow.mjs +31 -0
- package/dist/application/stack-overflow.mjs.map +1 -0
- package/dist/application/transform/document/assignability.cjs +144 -0
- package/dist/application/transform/document/assignability.cjs.map +1 -0
- package/dist/application/transform/document/assignability.mjs +138 -0
- package/dist/application/transform/document/assignability.mjs.map +1 -0
- package/dist/application/transform/document/components.cjs +104 -0
- package/dist/application/transform/document/components.cjs.map +1 -0
- package/dist/application/transform/document/components.mjs +102 -0
- package/dist/application/transform/document/components.mjs.map +1 -0
- package/dist/application/transform/document/declared-types.cjs +66 -0
- package/dist/application/transform/document/declared-types.cjs.map +1 -0
- package/dist/application/transform/document/declared-types.mjs +63 -0
- package/dist/application/transform/document/declared-types.mjs.map +1 -0
- package/dist/application/transform/document/defs-root.cjs +18 -0
- package/dist/application/transform/document/defs-root.cjs.map +1 -0
- package/dist/application/transform/document/defs-root.mjs +16 -0
- package/dist/application/transform/document/defs-root.mjs.map +1 -0
- package/dist/application/transform/document/document-member.cjs +13 -0
- package/dist/application/transform/document/document-member.cjs.map +1 -0
- package/dist/application/transform/document/document-member.mjs +11 -0
- package/dist/application/transform/document/document-member.mjs.map +1 -0
- package/dist/application/transform/document/document.cjs +109 -0
- package/dist/application/transform/document/document.cjs.map +1 -0
- package/dist/application/transform/document/document.mjs +106 -0
- package/dist/application/transform/document/document.mjs.map +1 -0
- package/dist/application/transform/document/exploded-query.cjs +46 -0
- package/dist/application/transform/document/exploded-query.cjs.map +1 -0
- package/dist/application/transform/document/exploded-query.mjs +43 -0
- package/dist/application/transform/document/exploded-query.mjs.map +1 -0
- package/dist/application/transform/document/global-type-references.cjs +63 -0
- package/dist/application/transform/document/global-type-references.cjs.map +1 -0
- package/dist/application/transform/document/global-type-references.mjs +61 -0
- package/dist/application/transform/document/global-type-references.mjs.map +1 -0
- package/dist/application/transform/document/header.cjs +27 -0
- package/dist/application/transform/document/header.cjs.map +1 -0
- package/dist/application/transform/document/header.mjs +25 -0
- package/dist/application/transform/document/header.mjs.map +1 -0
- package/dist/application/transform/document/kept-deprecated.cjs +96 -0
- package/dist/application/transform/document/kept-deprecated.cjs.map +1 -0
- package/dist/application/transform/document/kept-deprecated.mjs +94 -0
- package/dist/application/transform/document/kept-deprecated.mjs.map +1 -0
- package/dist/application/transform/document/list-assignability.cjs +54 -0
- package/dist/application/transform/document/list-assignability.cjs.map +1 -0
- package/dist/application/transform/document/list-assignability.mjs +52 -0
- package/dist/application/transform/document/list-assignability.mjs.map +1 -0
- package/dist/application/transform/document/media-type.cjs +42 -0
- package/dist/application/transform/document/media-type.cjs.map +1 -0
- package/dist/application/transform/document/media-type.mjs +38 -0
- package/dist/application/transform/document/media-type.mjs.map +1 -0
- package/dist/application/transform/document/operation.cjs +45 -0
- package/dist/application/transform/document/operation.cjs.map +1 -0
- package/dist/application/transform/document/operation.mjs +43 -0
- package/dist/application/transform/document/operation.mjs.map +1 -0
- package/dist/application/transform/document/parameter.cjs +25 -0
- package/dist/application/transform/document/parameter.cjs.map +1 -0
- package/dist/application/transform/document/parameter.mjs +23 -0
- package/dist/application/transform/document/parameter.mjs.map +1 -0
- package/dist/application/transform/document/parameters.cjs +146 -0
- package/dist/application/transform/document/parameters.cjs.map +1 -0
- package/dist/application/transform/document/parameters.mjs +144 -0
- package/dist/application/transform/document/parameters.mjs.map +1 -0
- package/dist/application/transform/document/path-item.cjs +82 -0
- package/dist/application/transform/document/path-item.cjs.map +1 -0
- package/dist/application/transform/document/path-item.mjs +80 -0
- package/dist/application/transform/document/path-item.mjs.map +1 -0
- package/dist/application/transform/document/path-key-overlaps.cjs +107 -0
- package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -0
- package/dist/application/transform/document/path-key-overlaps.mjs +105 -0
- package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -0
- package/dist/application/transform/document/path-template-replace.cjs +48 -0
- package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
- package/dist/application/transform/document/path-template-replace.mjs +45 -0
- package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
- package/dist/application/transform/document/paths-enum.cjs +75 -0
- package/dist/application/transform/document/paths-enum.cjs.map +1 -0
- package/dist/application/transform/document/paths-enum.mjs +72 -0
- package/dist/application/transform/document/paths-enum.mjs.map +1 -0
- package/dist/application/transform/document/paths.cjs +153 -0
- package/dist/application/transform/document/paths.cjs.map +1 -0
- package/dist/application/transform/document/paths.mjs +149 -0
- package/dist/application/transform/document/paths.mjs.map +1 -0
- package/dist/application/transform/document/request-body.cjs +36 -0
- package/dist/application/transform/document/request-body.cjs.map +1 -0
- package/dist/application/transform/document/request-body.mjs +34 -0
- package/dist/application/transform/document/request-body.mjs.map +1 -0
- package/dist/application/transform/document/response.cjs +59 -0
- package/dist/application/transform/document/response.cjs.map +1 -0
- package/dist/application/transform/document/response.mjs +57 -0
- package/dist/application/transform/document/response.mjs.map +1 -0
- package/dist/application/transform/document/responses.cjs +23 -0
- package/dist/application/transform/document/responses.cjs.map +1 -0
- package/dist/application/transform/document/responses.mjs +21 -0
- package/dist/application/transform/document/responses.mjs.map +1 -0
- package/dist/application/transform/document/root-type-aliases.cjs +70 -0
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -0
- package/dist/application/transform/document/root-type-aliases.mjs +67 -0
- package/dist/application/transform/document/root-type-aliases.mjs.map +1 -0
- package/dist/application/transform/document/template-key-match.cjs +128 -0
- package/dist/application/transform/document/template-key-match.cjs.map +1 -0
- package/dist/application/transform/document/template-key-match.mjs +125 -0
- package/dist/application/transform/document/template-key-match.mjs.map +1 -0
- package/dist/application/transform/document/type-assignability.cjs +192 -0
- package/dist/application/transform/document/type-assignability.cjs.map +1 -0
- package/dist/application/transform/document/type-assignability.mjs +190 -0
- package/dist/application/transform/document/type-assignability.mjs.map +1 -0
- package/dist/application/transform/document/type-key.cjs +70 -0
- package/dist/application/transform/document/type-key.cjs.map +1 -0
- package/dist/application/transform/document/type-key.mjs +68 -0
- package/dist/application/transform/document/type-key.mjs.map +1 -0
- package/dist/application/transform/document/type-resolution.cjs +131 -0
- package/dist/application/transform/document/type-resolution.cjs.map +1 -0
- package/dist/application/transform/document/type-resolution.mjs +125 -0
- package/dist/application/transform/document/type-resolution.mjs.map +1 -0
- package/dist/application/transform/document/webhooks.cjs +19 -0
- package/dist/application/transform/document/webhooks.cjs.map +1 -0
- package/dist/application/transform/document/webhooks.mjs +17 -0
- package/dist/application/transform/document/webhooks.mjs.map +1 -0
- package/dist/application/transform/document-entries.cjs +17 -0
- package/dist/application/transform/document-entries.cjs.map +1 -0
- package/dist/application/transform/document-entries.mjs +14 -0
- package/dist/application/transform/document-entries.mjs.map +1 -0
- package/dist/application/transform/footer/document-footer.cjs +150 -0
- package/dist/application/transform/footer/document-footer.cjs.map +1 -0
- package/dist/application/transform/footer/document-footer.mjs +148 -0
- package/dist/application/transform/footer/document-footer.mjs.map +1 -0
- package/dist/application/transform/footer/enum-naming.cjs +138 -0
- package/dist/application/transform/footer/enum-naming.cjs.map +1 -0
- package/dist/application/transform/footer/enum-naming.mjs +131 -0
- package/dist/application/transform/footer/enum-naming.mjs.map +1 -0
- package/dist/application/transform/footer/enum-values-check.cjs +129 -0
- package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
- package/dist/application/transform/footer/enum-values-check.mjs +127 -0
- package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
- package/dist/application/transform/footer/evaluation.cjs +33 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/evaluation.mjs +26 -0
- package/dist/application/transform/footer/evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
- package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
- package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
- package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.cjs +246 -0
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.mjs +244 -0
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/type-rules.cjs +172 -0
- package/dist/application/transform/footer/type-rules.cjs.map +1 -0
- package/dist/application/transform/footer/type-rules.mjs +166 -0
- package/dist/application/transform/footer/type-rules.mjs.map +1 -0
- package/dist/application/transform/helper-types.cjs +68 -0
- package/dist/application/transform/helper-types.cjs.map +1 -0
- package/dist/application/transform/helper-types.mjs +65 -0
- package/dist/application/transform/helper-types.mjs.map +1 -0
- package/dist/application/transform/literal-type.cjs +36 -0
- package/dist/application/transform/literal-type.cjs.map +1 -0
- package/dist/application/transform/literal-type.mjs +34 -0
- package/dist/application/transform/literal-type.mjs.map +1 -0
- package/dist/application/transform/numbered-names.cjs +18 -0
- package/dist/application/transform/numbered-names.cjs.map +1 -0
- package/dist/application/transform/numbered-names.mjs +16 -0
- package/dist/application/transform/numbered-names.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
- package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
- package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
- package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
- package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
- package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
- package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
- package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
- package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
- package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
- package/dist/application/transform/ref-type.cjs +62 -0
- package/dist/application/transform/ref-type.cjs.map +1 -0
- package/dist/application/transform/ref-type.mjs +55 -0
- package/dist/application/transform/ref-type.mjs.map +1 -0
- package/dist/application/transform/schema/access-flags.cjs +38 -0
- package/dist/application/transform/schema/access-flags.cjs.map +1 -0
- package/dist/application/transform/schema/access-flags.mjs +36 -0
- package/dist/application/transform/schema/access-flags.mjs.map +1 -0
- package/dist/application/transform/schema/array-type.cjs +136 -0
- package/dist/application/transform/schema/array-type.cjs.map +1 -0
- package/dist/application/transform/schema/array-type.mjs +134 -0
- package/dist/application/transform/schema/array-type.mjs.map +1 -0
- package/dist/application/transform/schema/composition-type.cjs +142 -0
- package/dist/application/transform/schema/composition-type.cjs.map +1 -0
- package/dist/application/transform/schema/composition-type.mjs +140 -0
- package/dist/application/transform/schema/composition-type.mjs.map +1 -0
- package/dist/application/transform/schema/core-type.cjs +86 -0
- package/dist/application/transform/schema/core-type.cjs.map +1 -0
- package/dist/application/transform/schema/core-type.mjs +84 -0
- package/dist/application/transform/schema/core-type.mjs.map +1 -0
- package/dist/application/transform/schema/discriminated-union.cjs +30 -0
- package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
- package/dist/application/transform/schema/discriminated-union.mjs +27 -0
- package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.cjs +22 -0
- package/dist/application/transform/schema/discriminator-property.cjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.mjs +20 -0
- package/dist/application/transform/schema/discriminator-property.mjs.map +1 -0
- package/dist/application/transform/schema/enum-rule.cjs +163 -0
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -0
- package/dist/application/transform/schema/enum-rule.mjs +160 -0
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -0
- package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
- package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
- package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +186 -0
- package/dist/application/transform/schema/object-type.cjs.map +1 -0
- package/dist/application/transform/schema/object-type.mjs +182 -0
- package/dist/application/transform/schema/object-type.mjs.map +1 -0
- package/dist/application/transform/schema/presence-members.cjs +59 -0
- package/dist/application/transform/schema/presence-members.cjs.map +1 -0
- package/dist/application/transform/schema/presence-members.mjs +57 -0
- package/dist/application/transform/schema/presence-members.mjs.map +1 -0
- package/dist/application/transform/schema/required-variants.cjs +45 -0
- package/dist/application/transform/schema/required-variants.cjs.map +1 -0
- package/dist/application/transform/schema/required-variants.mjs +42 -0
- package/dist/application/transform/schema/required-variants.mjs.map +1 -0
- package/dist/application/transform/schema/schema-transform.cjs +72 -0
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -0
- package/dist/application/transform/schema/schema-transform.mjs +68 -0
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -0
- package/dist/application/transform/schema/unevaluated-properties.cjs +61 -0
- package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -0
- package/dist/application/transform/schema/unevaluated-properties.mjs +59 -0
- package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -0
- package/dist/application/transform/schema-comment.cjs +130 -0
- package/dist/application/transform/schema-comment.cjs.map +1 -0
- package/dist/application/transform/schema-comment.mjs +125 -0
- package/dist/application/transform/schema-comment.mjs.map +1 -0
- package/dist/application/transform/shared-types.cjs +8 -0
- package/dist/application/transform/shared-types.cjs.map +1 -0
- package/dist/application/transform/shared-types.mjs +6 -0
- package/dist/application/transform/shared-types.mjs.map +1 -0
- package/dist/application/transform/type-combinators.cjs +49 -0
- package/dist/application/transform/type-combinators.cjs.map +1 -0
- package/dist/application/transform/type-combinators.mjs +42 -0
- package/dist/application/transform/type-combinators.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +145 -0
- package/dist/cli/cli-arguments.cjs.map +1 -0
- package/dist/cli/cli-arguments.mjs +137 -0
- package/dist/cli/cli-arguments.mjs.map +1 -0
- package/dist/cli/cli-errors.cjs +81 -0
- package/dist/cli/cli-errors.cjs.map +1 -0
- package/dist/cli/cli-errors.mjs +77 -0
- package/dist/cli/cli-errors.mjs.map +1 -0
- package/dist/cli/cli-output.cjs +42 -0
- package/dist/cli/cli-output.cjs.map +1 -0
- package/dist/cli/cli-output.mjs +35 -0
- package/dist/cli/cli-output.mjs.map +1 -0
- package/dist/cli/docs-links.cjs +6 -0
- package/dist/cli/docs-links.cjs.map +1 -0
- package/dist/cli/docs-links.mjs +4 -0
- package/dist/cli/docs-links.mjs.map +1 -0
- package/dist/cli/fix-option.cjs +19 -0
- package/dist/cli/fix-option.cjs.map +1 -0
- package/dist/cli/fix-option.mjs +16 -0
- package/dist/cli/fix-option.mjs.map +1 -0
- package/dist/cli/help-text.cjs +44 -0
- package/dist/cli/help-text.cjs.map +1 -0
- package/dist/cli/help-text.mjs +42 -0
- package/dist/cli/help-text.mjs.map +1 -0
- package/dist/cli/main.cjs +67 -0
- package/dist/cli/main.cjs.map +1 -0
- package/dist/cli/main.d.cts +2 -0
- package/dist/cli/main.d.mts +2 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.mjs +59 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/redocly-apis.cjs +69 -0
- package/dist/cli/redocly-apis.cjs.map +1 -0
- package/dist/cli/redocly-apis.mjs +66 -0
- package/dist/cli/redocly-apis.mjs.map +1 -0
- package/dist/cli/ref-limits.cjs +14 -0
- package/dist/cli/ref-limits.cjs.map +1 -0
- package/dist/cli/ref-limits.mjs +12 -0
- package/dist/cli/ref-limits.mjs.map +1 -0
- package/dist/cli/run-cli.cjs +113 -0
- package/dist/cli/run-cli.cjs.map +1 -0
- package/dist/cli/run-cli.mjs +111 -0
- package/dist/cli/run-cli.mjs.map +1 -0
- package/dist/domain/assert-never.cjs +8 -0
- package/dist/domain/assert-never.cjs.map +1 -0
- package/dist/domain/assert-never.mjs +6 -0
- package/dist/domain/assert-never.mjs.map +1 -0
- package/dist/domain/errors.cjs +52 -0
- package/dist/domain/errors.cjs.map +1 -0
- package/dist/domain/errors.mjs +48 -0
- package/dist/domain/errors.mjs.map +1 -0
- package/dist/domain/ir/constructors.cjs +93 -0
- package/dist/domain/ir/constructors.cjs.map +1 -0
- package/dist/domain/ir/constructors.mjs +74 -0
- package/dist/domain/ir/constructors.mjs.map +1 -0
- package/dist/domain/ir/identifier-text.cjs +29 -0
- package/dist/domain/ir/identifier-text.cjs.map +1 -0
- package/dist/domain/ir/identifier-text.mjs +25 -0
- package/dist/domain/ir/identifier-text.mjs.map +1 -0
- package/dist/domain/ir/newer-identifier-ranges.cjs +109 -0
- package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -0
- package/dist/domain/ir/newer-identifier-ranges.mjs +106 -0
- package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -0
- package/dist/domain/ir/normalize.cjs +32 -0
- package/dist/domain/ir/normalize.cjs.map +1 -0
- package/dist/domain/ir/normalize.mjs +29 -0
- package/dist/domain/ir/normalize.mjs.map +1 -0
- package/dist/domain/ir/property-name.cjs +19 -0
- package/dist/domain/ir/property-name.cjs.map +1 -0
- package/dist/domain/ir/property-name.mjs +16 -0
- package/dist/domain/ir/property-name.mjs.map +1 -0
- package/dist/domain/ir/raw-text-escapes.cjs +25 -0
- package/dist/domain/ir/raw-text-escapes.cjs.map +1 -0
- package/dist/domain/ir/raw-text-escapes.mjs +22 -0
- package/dist/domain/ir/raw-text-escapes.mjs.map +1 -0
- package/dist/domain/openapi/admitted-values.cjs +75 -0
- package/dist/domain/openapi/admitted-values.cjs.map +1 -0
- package/dist/domain/openapi/admitted-values.mjs +72 -0
- package/dist/domain/openapi/admitted-values.mjs.map +1 -0
- package/dist/domain/openapi/alias-expansion.cjs +50 -0
- package/dist/domain/openapi/alias-expansion.cjs.map +1 -0
- package/dist/domain/openapi/alias-expansion.mjs +45 -0
- package/dist/domain/openapi/alias-expansion.mjs.map +1 -0
- package/dist/domain/openapi/binary-content.cjs +48 -0
- package/dist/domain/openapi/binary-content.cjs.map +1 -0
- package/dist/domain/openapi/binary-content.mjs +45 -0
- package/dist/domain/openapi/binary-content.mjs.map +1 -0
- package/dist/domain/openapi/components-object.cjs +29 -0
- package/dist/domain/openapi/components-object.cjs.map +1 -0
- package/dist/domain/openapi/components-object.mjs +24 -0
- package/dist/domain/openapi/components-object.mjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.cjs +68 -0
- package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
- package/dist/domain/openapi/discriminated-union.mjs +62 -0
- package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
- package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
- package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
- package/dist/domain/openapi/json-pointer.cjs +31 -0
- package/dist/domain/openapi/json-pointer.cjs.map +1 -0
- package/dist/domain/openapi/json-pointer.mjs +27 -0
- package/dist/domain/openapi/json-pointer.mjs.map +1 -0
- package/dist/domain/openapi/media-type-object.cjs +14 -0
- package/dist/domain/openapi/media-type-object.cjs.map +1 -0
- package/dist/domain/openapi/media-type-object.mjs +11 -0
- package/dist/domain/openapi/media-type-object.mjs.map +1 -0
- package/dist/domain/openapi/parameter-object.cjs +13 -0
- package/dist/domain/openapi/parameter-object.cjs.map +1 -0
- package/dist/domain/openapi/parameter-object.mjs +10 -0
- package/dist/domain/openapi/parameter-object.mjs.map +1 -0
- package/dist/domain/openapi/path-item-object.cjs +35 -0
- package/dist/domain/openapi/path-item-object.cjs.map +1 -0
- package/dist/domain/openapi/path-item-object.mjs +30 -0
- package/dist/domain/openapi/path-item-object.mjs.map +1 -0
- package/dist/domain/openapi/path-templates.cjs +23 -0
- package/dist/domain/openapi/path-templates.cjs.map +1 -0
- package/dist/domain/openapi/path-templates.mjs +21 -0
- package/dist/domain/openapi/path-templates.mjs.map +1 -0
- package/dist/domain/openapi/unsupported-features.cjs +87 -0
- package/dist/domain/openapi/unsupported-features.cjs.map +1 -0
- package/dist/domain/openapi/unsupported-features.mjs +84 -0
- package/dist/domain/openapi/unsupported-features.mjs.map +1 -0
- package/dist/domain/output-fixes.cjs +101 -0
- package/dist/domain/output-fixes.cjs.map +1 -0
- package/dist/domain/output-fixes.mjs +94 -0
- package/dist/domain/output-fixes.mjs.map +1 -0
- package/dist/domain/warnings.cjs +15 -0
- package/dist/domain/warnings.cjs.map +1 -0
- package/dist/domain/warnings.mjs +12 -0
- package/dist/domain/warnings.mjs.map +1 -0
- package/dist/index.cjs +98 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +841 -0
- package/dist/index.d.mts +841 -0
- package/dist/index.d.ts +841 -0
- package/dist/index.mjs +27 -0
- package/dist/index.mjs.map +1 -0
- package/dist/transform/components-object.cjs +15 -0
- package/dist/transform/components-object.cjs.map +1 -0
- package/dist/transform/components-object.mjs +11 -0
- package/dist/transform/components-object.mjs.map +1 -0
- package/dist/transform/header-object.cjs +12 -0
- package/dist/transform/header-object.cjs.map +1 -0
- package/dist/transform/header-object.mjs +10 -0
- package/dist/transform/header-object.mjs.map +1 -0
- package/dist/transform/media-type-object.cjs +12 -0
- package/dist/transform/media-type-object.cjs.map +1 -0
- package/dist/transform/media-type-object.mjs +10 -0
- package/dist/transform/media-type-object.mjs.map +1 -0
- package/dist/transform/operation-object.cjs +26 -0
- package/dist/transform/operation-object.cjs.map +1 -0
- package/dist/transform/operation-object.mjs +21 -0
- package/dist/transform/operation-object.mjs.map +1 -0
- package/dist/transform/parameter-object.cjs +12 -0
- package/dist/transform/parameter-object.cjs.map +1 -0
- package/dist/transform/parameter-object.mjs +10 -0
- package/dist/transform/parameter-object.mjs.map +1 -0
- package/dist/transform/path-item-object.cjs +12 -0
- package/dist/transform/path-item-object.cjs.map +1 -0
- package/dist/transform/path-item-object.mjs +10 -0
- package/dist/transform/path-item-object.mjs.map +1 -0
- package/dist/transform/paths-object.cjs +11 -0
- package/dist/transform/paths-object.cjs.map +1 -0
- package/dist/transform/paths-object.mjs +9 -0
- package/dist/transform/paths-object.mjs.map +1 -0
- package/dist/transform/request-body-object.cjs +12 -0
- package/dist/transform/request-body-object.cjs.map +1 -0
- package/dist/transform/request-body-object.mjs +10 -0
- package/dist/transform/request-body-object.mjs.map +1 -0
- package/dist/transform/response-object.cjs +12 -0
- package/dist/transform/response-object.cjs.map +1 -0
- package/dist/transform/response-object.mjs +10 -0
- package/dist/transform/response-object.mjs.map +1 -0
- package/dist/transform/responses-object.cjs +12 -0
- package/dist/transform/responses-object.cjs.map +1 -0
- package/dist/transform/responses-object.mjs +10 -0
- package/dist/transform/responses-object.mjs.map +1 -0
- package/dist/transform/schema-object.cjs +21 -0
- package/dist/transform/schema-object.cjs.map +1 -0
- package/dist/transform/schema-object.mjs +16 -0
- package/dist/transform/schema-object.mjs.map +1 -0
- package/package.json +115 -4
- package/src/adapters/node-file-system/node-file-system.ts +44 -0
- package/src/adapters/redocly-loader/alias-limit.ts +20 -0
- package/src/adapters/redocly-loader/allowed-hosts.ts +62 -0
- package/src/adapters/redocly-loader/bundled-ref-repair.ts +65 -0
- package/src/adapters/redocly-loader/malformed-refs.ts +61 -0
- package/src/adapters/redocly-loader/redocly-config-source.ts +78 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +262 -0
- package/src/adapters/redocly-loader/ref-access.ts +146 -0
- package/src/adapters/redocly-loader/ref-holders.ts +43 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +104 -0
- package/src/adapters/redocly-loader/schema-load-errors.ts +124 -0
- package/src/adapters/redocly-loader/schema-source.ts +151 -0
- package/src/adapters/redocly-loader/unsupported-keys.ts +102 -0
- package/src/adapters/terminal-logger/terminal-logger.ts +98 -0
- package/src/adapters/type-ast-bridge/footer-nodes.ts +38 -0
- package/src/adapters/type-ast-bridge/ir-declarations-to-typescript.ts +100 -0
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +223 -0
- package/src/adapters/type-ast-bridge/lazy-node.ts +24 -0
- package/src/adapters/type-ast-bridge/load-typescript.ts +84 -0
- package/src/adapters/type-ast-bridge/print-typescript.ts +33 -0
- package/src/adapters/type-ast-bridge/typescript-raw-text.ts +49 -0
- package/src/adapters/type-ast-bridge/typescript-to-ir.ts +294 -0
- package/src/adapters/type-ast-bridge/typescript-types.ts +8 -0
- package/src/api/ast-to-string.ts +59 -0
- package/src/api/comment-header.ts +7 -0
- package/src/api/default-ports.ts +44 -0
- package/src/api/discriminator-conflict-warnings.ts +43 -0
- package/src/api/discriminator-enum-names.ts +26 -0
- package/src/api/discriminator-enum-parent.ts +129 -0
- package/src/api/discriminator-enum.ts +115 -0
- package/src/api/discriminator-other-owners.ts +97 -0
- package/src/api/discriminator-patch.ts +147 -0
- package/src/api/discriminator-scan.ts +260 -0
- package/src/api/document-declarations.ts +41 -0
- package/src/api/document-refs.ts +71 -0
- package/src/api/document-run.ts +177 -0
- package/src/api/enum-values-warnings.ts +21 -0
- package/src/api/footer-entry.ts +23 -0
- package/src/api/footer-sink.ts +67 -0
- package/src/api/legacy-callback-warning.ts +29 -0
- package/src/api/legacy-ts-helpers.ts +311 -0
- package/src/api/legacy-utils.ts +118 -0
- package/src/api/openapi-ts.ts +62 -0
- package/src/api/path-template-warnings.ts +27 -0
- package/src/api/schema-callbacks.ts +211 -0
- package/src/api/string-to-ast.ts +27 -0
- package/src/api/transform-context.ts +93 -0
- package/src/api/transform-schema.ts +123 -0
- package/src/api/type-helpers.ts +130 -0
- package/src/api/unsupported-feature-warnings.ts +33 -0
- package/src/application/ports/file-system.ts +12 -0
- package/src/application/ports/logger.ts +16 -0
- package/src/application/ports/redocly-config-source.ts +20 -0
- package/src/application/ports/schema-loader.ts +32 -0
- package/src/application/print/comment-writer.ts +91 -0
- package/src/application/print/declaration-printer.ts +100 -0
- package/src/application/print/literal-text.ts +62 -0
- package/src/application/print/print-nodes.ts +62 -0
- package/src/application/print/print-options.ts +11 -0
- package/src/application/print/text-writer.ts +83 -0
- package/src/application/print/type-printer.ts +287 -0
- package/src/application/stack-overflow.ts +54 -0
- package/src/application/transform/document/assignability.ts +203 -0
- package/src/application/transform/document/components.ts +189 -0
- package/src/application/transform/document/declared-types.ts +93 -0
- package/src/application/transform/document/defs-root.ts +25 -0
- package/src/application/transform/document/document-member.ts +20 -0
- package/src/application/transform/document/document.ts +215 -0
- package/src/application/transform/document/exploded-query.ts +91 -0
- package/src/application/transform/document/global-type-references.ts +78 -0
- package/src/application/transform/document/header.ts +34 -0
- package/src/application/transform/document/kept-deprecated.ts +135 -0
- package/src/application/transform/document/list-assignability.ts +87 -0
- package/src/application/transform/document/media-type.ts +78 -0
- package/src/application/transform/document/operation.ts +64 -0
- package/src/application/transform/document/parameter.ts +45 -0
- package/src/application/transform/document/parameters.ts +265 -0
- package/src/application/transform/document/path-item.ts +168 -0
- package/src/application/transform/document/path-key-overlaps.ts +201 -0
- package/src/application/transform/document/path-template-replace.ts +90 -0
- package/src/application/transform/document/paths-enum.ts +127 -0
- package/src/application/transform/document/paths.ts +273 -0
- package/src/application/transform/document/request-body.ts +50 -0
- package/src/application/transform/document/response.ts +109 -0
- package/src/application/transform/document/responses.ts +29 -0
- package/src/application/transform/document/root-type-aliases.ts +107 -0
- package/src/application/transform/document/template-key-match.ts +183 -0
- package/src/application/transform/document/type-assignability.ts +268 -0
- package/src/application/transform/document/type-key.ts +80 -0
- package/src/application/transform/document/type-resolution.ts +163 -0
- package/src/application/transform/document/webhooks.ts +22 -0
- package/src/application/transform/document-entries.ts +28 -0
- package/src/application/transform/footer/document-footer.ts +212 -0
- package/src/application/transform/footer/enum-naming.ts +210 -0
- package/src/application/transform/footer/enum-values-check.ts +171 -0
- package/src/application/transform/footer/evaluation.ts +47 -0
- package/src/application/transform/footer/shared-enum-names.ts +86 -0
- package/src/application/transform/footer/type-evaluation.ts +294 -0
- package/src/application/transform/footer/type-rules.ts +269 -0
- package/src/application/transform/helper-types.ts +92 -0
- package/src/application/transform/literal-type.ts +54 -0
- package/src/application/transform/numbered-names.ts +20 -0
- package/src/application/transform/ref-pointer/generated-location.ts +211 -0
- package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
- package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
- package/src/application/transform/ref-pointer/original-index.ts +95 -0
- package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
- package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
- package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
- package/src/application/transform/ref-type.ts +102 -0
- package/src/application/transform/schema/access-flags.ts +63 -0
- package/src/application/transform/schema/array-type.ts +213 -0
- package/src/application/transform/schema/composition-type.ts +255 -0
- package/src/application/transform/schema/core-type.ts +119 -0
- package/src/application/transform/schema/discriminated-union.ts +58 -0
- package/src/application/transform/schema/discriminator-property.ts +33 -0
- package/src/application/transform/schema/enum-rule.ts +280 -0
- package/src/application/transform/schema/inherited-discriminator.ts +54 -0
- package/src/application/transform/schema/object-type.ts +289 -0
- package/src/application/transform/schema/presence-members.ts +96 -0
- package/src/application/transform/schema/required-variants.ts +88 -0
- package/src/application/transform/schema/schema-context.ts +136 -0
- package/src/application/transform/schema/schema-rule.ts +29 -0
- package/src/application/transform/schema/schema-transform.ts +99 -0
- package/src/application/transform/schema/unevaluated-properties.ts +105 -0
- package/src/application/transform/schema-comment.ts +196 -0
- package/src/application/transform/shared-types.ts +9 -0
- package/src/application/transform/transform-context.ts +51 -0
- package/src/application/transform/type-combinators.ts +57 -0
- package/src/cli/cli-arguments.ts +208 -0
- package/src/cli/cli-dependencies.ts +47 -0
- package/src/cli/cli-errors.ts +127 -0
- package/src/cli/cli-output.ts +67 -0
- package/src/cli/docs-links.ts +6 -0
- package/src/cli/fix-option.ts +29 -0
- package/src/cli/help-text.ts +52 -0
- package/src/cli/main.ts +73 -0
- package/src/cli/redocly-apis.ts +95 -0
- package/src/cli/ref-limits.ts +16 -0
- package/src/cli/run-cli.ts +131 -0
- package/src/domain/assert-never.ts +8 -0
- package/src/domain/errors.ts +76 -0
- package/src/domain/ir/constructors.ts +142 -0
- package/src/domain/ir/identifier-text.ts +49 -0
- package/src/domain/ir/newer-identifier-ranges.ts +109 -0
- package/src/domain/ir/nodes.ts +225 -0
- package/src/domain/ir/normalize.ts +51 -0
- package/src/domain/ir/property-name.ts +28 -0
- package/src/domain/ir/raw-text-escapes.ts +37 -0
- package/src/domain/openapi/admitted-values.ts +113 -0
- package/src/domain/openapi/alias-expansion.ts +72 -0
- package/src/domain/openapi/binary-content.ts +74 -0
- package/src/domain/openapi/components-object.ts +52 -0
- package/src/domain/openapi/discriminated-union.ts +109 -0
- package/src/domain/openapi/discriminator-conflicts.ts +251 -0
- package/src/domain/openapi/document-object.ts +12 -0
- package/src/domain/openapi/header-object.ts +9 -0
- package/src/domain/openapi/json-pointer.ts +46 -0
- package/src/domain/openapi/media-type-object.ts +26 -0
- package/src/domain/openapi/operation-object.ts +13 -0
- package/src/domain/openapi/parameter-object.ts +34 -0
- package/src/domain/openapi/path-item-object.ts +70 -0
- package/src/domain/openapi/path-templates.ts +31 -0
- package/src/domain/openapi/request-body-object.ts +7 -0
- package/src/domain/openapi/response-object.ts +14 -0
- package/src/domain/openapi/schema-object.ts +61 -0
- package/src/domain/openapi/unsupported-features.ts +139 -0
- package/src/domain/output-fixes.ts +136 -0
- package/src/domain/warnings.ts +20 -0
- package/src/index.ts +67 -0
- package/src/transform/components-object.ts +27 -0
- package/src/transform/header-object.ts +19 -0
- package/src/transform/media-type-object.ts +19 -0
- package/src/transform/operation-object.ts +36 -0
- package/src/transform/parameter-object.ts +19 -0
- package/src/transform/parameters-array.ts +19 -0
- package/src/transform/path-item-object.ts +22 -0
- package/src/transform/paths-enum.ts +8 -0
- package/src/transform/paths-object.ts +15 -0
- package/src/transform/request-body-object.ts +19 -0
- package/src/transform/response-object.ts +19 -0
- package/src/transform/responses-object.ts +19 -0
- package/src/transform/schema-object.ts +36 -0
- package/src/transform/webhooks-object.ts +15 -0
- package/src/types/generator-options.ts +278 -0
- package/src/types/openapi-common.ts +100 -0
- package/src/types/openapi-document.ts +196 -0
- package/src/types/openapi-path-item.ts +130 -0
- package/src/types/openapi-request.ts +209 -0
- package/src/types/openapi-response.ts +81 -0
- package/src/types/openapi-schema.ts +169 -0
- package/src/types/openapi-security.ts +116 -0
- package/src/types.ts +12 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import {
|
|
3
|
+
type BaseResolver,
|
|
4
|
+
bundle,
|
|
5
|
+
type Document,
|
|
6
|
+
lintDocument,
|
|
7
|
+
type NormalizedProblem,
|
|
8
|
+
type Config as RedoclyConfig,
|
|
9
|
+
} from "@redocly/openapi-core";
|
|
10
|
+
import type { Logger } from "../../application/ports/logger.js";
|
|
11
|
+
import type { SchemaLoader, SchemaLoadRequest } from "../../application/ports/schema-loader.js";
|
|
12
|
+
import { withStackOverflowReportedAsync } from "../../application/stack-overflow.js";
|
|
13
|
+
import type { OpenAPI3 } from "../../types.js";
|
|
14
|
+
import { repairBundledRefs } from "./bundled-ref-repair.js";
|
|
15
|
+
import { findMalformedRefs, malformedRefsError } from "./malformed-refs.js";
|
|
16
|
+
import { RefAccessResolver } from "./ref-access.js";
|
|
17
|
+
import { resolveConfigWithAccess } from "./remote-fetch.js";
|
|
18
|
+
import {
|
|
19
|
+
loadFailedError,
|
|
20
|
+
refCycleError,
|
|
21
|
+
schemaInvalidError,
|
|
22
|
+
versionUnsupportedError,
|
|
23
|
+
} from "./schema-load-errors.js";
|
|
24
|
+
import { parseSchema } from "./schema-source.js";
|
|
25
|
+
import {
|
|
26
|
+
findUnsupportedKeys,
|
|
27
|
+
type LoadedDocument,
|
|
28
|
+
unsupportedKeysError,
|
|
29
|
+
} from "./unsupported-keys.js";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The SchemaLoader port on Redocly 1.34 (ADR-005): parse any inherited source type, then lint and
|
|
33
|
+
* bundle with the given Redocly config. Problems go to the logger; errors fail the load.
|
|
34
|
+
*/
|
|
35
|
+
export interface RedoclySchemaLoaderOptions {
|
|
36
|
+
readonly redoc: RedoclyConfig;
|
|
37
|
+
readonly logger: Logger;
|
|
38
|
+
/** A monotonic time in milliseconds, for the debug durations. */
|
|
39
|
+
readonly now: () => number;
|
|
40
|
+
/** Time limit of one remote fetch, unless the Redocly config brings its own `customFetch`. */
|
|
41
|
+
readonly remoteRefTimeoutMs: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const UNSUPPORTED_FORMAT_MESSAGE = "Unsupported schema format, expected `openapi: 3.x`";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Accept OpenAPI 3.x only; Swagger 2 and other formats get their own message. An empty file or a
|
|
48
|
+
* `null` root parses to nothing, so it is checked before any field is read.
|
|
49
|
+
*/
|
|
50
|
+
function assertOpenAPI3(document: unknown): void {
|
|
51
|
+
if (typeof document !== "object" || document === null) {
|
|
52
|
+
throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, {});
|
|
53
|
+
}
|
|
54
|
+
const parsed = document as Record<string, unknown>;
|
|
55
|
+
const openapiVersion = Number.parseFloat(parsed.openapi as string);
|
|
56
|
+
const isOpenAPI3 =
|
|
57
|
+
!parsed.swagger &&
|
|
58
|
+
Boolean(parsed.openapi) &&
|
|
59
|
+
!Number.isNaN(openapiVersion) &&
|
|
60
|
+
openapiVersion >= 3 &&
|
|
61
|
+
openapiVersion < 4;
|
|
62
|
+
if (isOpenAPI3) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (parsed.swagger) {
|
|
66
|
+
throw versionUnsupportedError(
|
|
67
|
+
"Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.",
|
|
68
|
+
parsed,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) {
|
|
72
|
+
throw versionUnsupportedError(`Unsupported OpenAPI version: ${parsed.openapi}`, parsed);
|
|
73
|
+
}
|
|
74
|
+
throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, parsed);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The name an inline source (a string, object, buffer or stream) gets inside the working
|
|
79
|
+
* directory. Redocly resolves relative `$ref`s against the directory of the document, so the
|
|
80
|
+
* document must be named as a file in the working directory, not as the directory itself.
|
|
81
|
+
*/
|
|
82
|
+
const INLINE_SOURCE_NAME = "inline-source";
|
|
83
|
+
|
|
84
|
+
/** The base for relative `$ref`s: the source file or URL itself, else a file in the cwd. */
|
|
85
|
+
function sourceAbsoluteRef(source: unknown, cwd: URL): string {
|
|
86
|
+
const document = source instanceof URL ? source : new URL(INLINE_SOURCE_NAME, cwd);
|
|
87
|
+
return document.protocol === "file:" ? sourceFilePath(document) : document.href;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The path of a `file:` source. A URL that names no path on this platform (an encoded slash, a
|
|
92
|
+
* host on POSIX, no drive letter on Windows) cannot be read, so it fails as a read would.
|
|
93
|
+
*/
|
|
94
|
+
function sourceFilePath(source: URL): string {
|
|
95
|
+
try {
|
|
96
|
+
return fileURLToPath(source);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
// Node.js reports these as TypeErrors (ERR_INVALID_FILE_URL_PATH, ERR_INVALID_FILE_URL_HOST).
|
|
99
|
+
if (!(error instanceof TypeError)) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
throw loadFailedError(source.href, error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Redocly throws a plain Error for a `$ref` chain that points back to itself. */
|
|
107
|
+
const REF_CYCLE_MESSAGE = "Self-referencing circular pointer";
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The root document and every other document the resolver loaded, as far as they parsed. A root
|
|
111
|
+
* read from a file or URL is in the resolver cache too, and is listed once.
|
|
112
|
+
*/
|
|
113
|
+
async function loadedDocuments(root: Document, resolver: BaseResolver): Promise<LoadedDocument[]> {
|
|
114
|
+
const cached = await Promise.all(resolver.cache.values());
|
|
115
|
+
const bySource = new Map<string, unknown>([[root.source.absoluteRef, root.parsed]]);
|
|
116
|
+
for (const document of cached) {
|
|
117
|
+
if ("parsed" in document && !bySource.has(document.source.absoluteRef)) {
|
|
118
|
+
bySource.set(document.source.absoluteRef, document.parsed);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return [...bySource].map(([source, parsed]) => ({ source, parsed }));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Report the document problems Redocly throws as typed errors; anything else passes through. */
|
|
125
|
+
async function rethrowDocumentError(
|
|
126
|
+
error: unknown,
|
|
127
|
+
root: Document,
|
|
128
|
+
resolver: BaseResolver,
|
|
129
|
+
): Promise<never> {
|
|
130
|
+
if (error instanceof Error && error.message === REF_CYCLE_MESSAGE) {
|
|
131
|
+
throw refCycleError(error);
|
|
132
|
+
}
|
|
133
|
+
if (error instanceof URIError) {
|
|
134
|
+
throw malformedRefsError(findMalformedRefs(await loadedDocuments(root, resolver)), error);
|
|
135
|
+
}
|
|
136
|
+
if (error instanceof TypeError) {
|
|
137
|
+
const keys = findUnsupportedKeys(await loadedDocuments(root, resolver));
|
|
138
|
+
throw keys.length === 0 ? error : unsupportedKeysError(keys, error);
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class RedoclySchemaLoader implements SchemaLoader {
|
|
144
|
+
readonly #options: RedoclySchemaLoaderOptions;
|
|
145
|
+
|
|
146
|
+
constructor(options: RedoclySchemaLoaderOptions) {
|
|
147
|
+
this.#options = options;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async load(request: SchemaLoadRequest): Promise<OpenAPI3> {
|
|
151
|
+
const resolver = this.#resolver(request);
|
|
152
|
+
// Parsing is guarded too: `JSON.stringify` of a deep object source overflows the stack on
|
|
153
|
+
// Node.js 22 and 24, before linting starts.
|
|
154
|
+
const bundled = await withStackOverflowReportedAsync("load", () =>
|
|
155
|
+
this.#parseAndBundle(request, resolver),
|
|
156
|
+
).catch((error: unknown) => {
|
|
157
|
+
throw resolver.firstRefusal ?? error;
|
|
158
|
+
});
|
|
159
|
+
// A refused `$ref` is an unresolved-`$ref` problem, which a Redocly config can turn off.
|
|
160
|
+
if (resolver.firstRefusal !== undefined) {
|
|
161
|
+
throw resolver.firstRefusal;
|
|
162
|
+
}
|
|
163
|
+
return bundled;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async #parseAndBundle(request: SchemaLoadRequest, resolver: BaseResolver): Promise<OpenAPI3> {
|
|
167
|
+
const { logger, now } = this.#options;
|
|
168
|
+
const configLoadedAt = now();
|
|
169
|
+
logger.debug("Loaded Redoc config", "redoc", now() - configLoadedAt);
|
|
170
|
+
const parseStartedAt = now();
|
|
171
|
+
const absoluteRef = sourceAbsoluteRef(request.source, request.cwd);
|
|
172
|
+
const document = await parseSchema(request.source, { absoluteRef, resolver });
|
|
173
|
+
logger.debug("Parsed schema", "redoc", now() - parseStartedAt);
|
|
174
|
+
assertOpenAPI3(document.parsed);
|
|
175
|
+
return this.#lintAndBundle(document, resolver, request.shouldLint);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#resolver(request: SchemaLoadRequest): RefAccessResolver {
|
|
179
|
+
const { redoc, remoteRefTimeoutMs } = this.#options;
|
|
180
|
+
const config = resolveConfigWithAccess(redoc.resolve, {
|
|
181
|
+
timeoutMs: remoteRefTimeoutMs,
|
|
182
|
+
access: request.refAccess,
|
|
183
|
+
});
|
|
184
|
+
return new RefAccessResolver(config, request.refAccess);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async #lintAndBundle(
|
|
188
|
+
document: Document,
|
|
189
|
+
resolver: BaseResolver,
|
|
190
|
+
shouldLint: boolean,
|
|
191
|
+
): Promise<OpenAPI3> {
|
|
192
|
+
const rethrow = (error: unknown) => rethrowDocumentError(error, document, resolver);
|
|
193
|
+
if (shouldLint) {
|
|
194
|
+
await this.#lint(document, resolver).catch(rethrow);
|
|
195
|
+
}
|
|
196
|
+
return this.#bundle(document, resolver).catch(rethrow);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async #lint(document: Document, resolver: BaseResolver): Promise<void> {
|
|
200
|
+
const startedAt = this.#options.now();
|
|
201
|
+
const problems = await lintDocument({
|
|
202
|
+
document,
|
|
203
|
+
config: this.#options.redoc.styleguide,
|
|
204
|
+
externalRefResolver: resolver,
|
|
205
|
+
});
|
|
206
|
+
this.#report(problems);
|
|
207
|
+
this.#options.logger.debug("Linted schema", "lint", this.#options.now() - startedAt);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async #bundle(document: Document, resolver: BaseResolver): Promise<OpenAPI3> {
|
|
211
|
+
const startedAt = this.#options.now();
|
|
212
|
+
// The lint resolver: documents it already loaded are not fetched again.
|
|
213
|
+
const bundled = await bundle({
|
|
214
|
+
config: this.#options.redoc,
|
|
215
|
+
dereference: false,
|
|
216
|
+
doc: document,
|
|
217
|
+
externalRefResolver: resolver,
|
|
218
|
+
});
|
|
219
|
+
this.#report(bundled.problems);
|
|
220
|
+
repairBundledRefs(bundled.bundle.parsed);
|
|
221
|
+
this.#options.logger.debug("Bundled schema", "bundle", this.#options.now() - startedAt);
|
|
222
|
+
return bundled.bundle.parsed;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Report every problem; then throw if any of them is an error. A problem that the Redocly
|
|
227
|
+
* config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out
|
|
228
|
+
* (upstream #2189).
|
|
229
|
+
*/
|
|
230
|
+
#report(problems: readonly NormalizedProblem[]): void {
|
|
231
|
+
const errorMessages: string[] = [];
|
|
232
|
+
for (const problem of problems) {
|
|
233
|
+
if (problem.ignored === true) {
|
|
234
|
+
this.#options.logger.debug(
|
|
235
|
+
`Ignored by the lint ignore file: ${problemMessage(problem)}`,
|
|
236
|
+
"lint",
|
|
237
|
+
);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const message = problemMessage(problem);
|
|
241
|
+
if (problem.severity === "error") {
|
|
242
|
+
errorMessages.push(message);
|
|
243
|
+
this.#options.logger.error(message);
|
|
244
|
+
} else {
|
|
245
|
+
this.#options.logger.warn(message);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (errorMessages.length > 0) {
|
|
249
|
+
throw schemaInvalidError(errorMessages);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function problemMessage(problem: NormalizedProblem): string {
|
|
255
|
+
const location = problem.location?.[0]?.pointer;
|
|
256
|
+
return location ? `${problem.message} at ${location}` : problem.message;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** A schema loader with one Redocly config and logger, for one or more loads. */
|
|
260
|
+
export function createRedoclySchemaLoader(options: RedoclySchemaLoaderOptions): SchemaLoader {
|
|
261
|
+
return new RedoclySchemaLoader(options);
|
|
262
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import {
|
|
5
|
+
BaseResolver,
|
|
6
|
+
type Document,
|
|
7
|
+
type Config as RedoclyConfig,
|
|
8
|
+
type Source,
|
|
9
|
+
YamlParseError,
|
|
10
|
+
} from "@redocly/openapi-core";
|
|
11
|
+
import type { RefAccess } from "../../application/ports/schema-loader.js";
|
|
12
|
+
import { ERROR_CODES, type OpenAPITypesafeError } from "../../domain/errors.js";
|
|
13
|
+
import { aliasExpansionFailure } from "./alias-limit.js";
|
|
14
|
+
import { isHostAllowed } from "./allowed-hosts.js";
|
|
15
|
+
import { refForbiddenError } from "./schema-load-errors.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Limits on where `$ref` documents may be loaded from (threat model R1 and R2, ADR-017). The root
|
|
19
|
+
* document is chosen by the developer and is always loaded; every other document must pass.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
type ResolveConfig = RedoclyConfig["resolve"];
|
|
23
|
+
|
|
24
|
+
/** Redocly treats only these prefixes as remote; any other `$ref` is a local file path. */
|
|
25
|
+
function isRemoteRef(absoluteRef: string): boolean {
|
|
26
|
+
return absoluteRef.startsWith("http://") || absoluteRef.startsWith("https://");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Whether `target` is `root` or below it; both are absolute paths. */
|
|
30
|
+
export function isInsideDirectory(target: string, root: string): boolean {
|
|
31
|
+
const relative = path.relative(root, target);
|
|
32
|
+
// Compare the first segment: a directory named `..hidden` is inside, `../x` is not.
|
|
33
|
+
const isParent = relative === ".." || relative.startsWith(`..${path.sep}`);
|
|
34
|
+
return !isParent && !path.isAbsolute(relative);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The real path, so a link inside the root that points outside it is caught. */
|
|
38
|
+
async function realPathOrSelf(file: string): Promise<string> {
|
|
39
|
+
const absolute = path.resolve(file);
|
|
40
|
+
try {
|
|
41
|
+
return await realpath(absolute);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
// A missing file is never read, and Redocly reports it. Resolve its nearest existing
|
|
44
|
+
// directory instead, so it compares with the root's real path: the root may be reached
|
|
45
|
+
// through a link (macOS `/tmp` is one), and the missing file must not look outside it.
|
|
46
|
+
const parent = path.dirname(absolute);
|
|
47
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT" && parent !== absolute) {
|
|
48
|
+
return path.join(await realPathOrSelf(parent), path.basename(absolute));
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function localRefusal(
|
|
55
|
+
absoluteRef: string,
|
|
56
|
+
localRoot: URL,
|
|
57
|
+
): Promise<OpenAPITypesafeError | undefined> {
|
|
58
|
+
const root = await realPathOrSelf(fileURLToPath(localRoot));
|
|
59
|
+
if (isInsideDirectory(await realPathOrSelf(absoluteRef), root)) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return refForbiddenError(absoluteRef, { reason: "outside-local-root", localRoot: root });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The refusal for one document, or undefined when the limits allow it. */
|
|
66
|
+
export async function refusalOf(
|
|
67
|
+
absoluteRef: string,
|
|
68
|
+
access: RefAccess,
|
|
69
|
+
): Promise<OpenAPITypesafeError | undefined> {
|
|
70
|
+
if (!isRemoteRef(absoluteRef)) {
|
|
71
|
+
return access.localRoot === undefined ? undefined : localRefusal(absoluteRef, access.localRoot);
|
|
72
|
+
}
|
|
73
|
+
if (access.remoteHosts === undefined || isHostAllowed(new URL(absoluteRef), access.remoteHosts)) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
return refForbiddenError(absoluteRef, {
|
|
77
|
+
reason: "host-not-allowed",
|
|
78
|
+
allowedHosts: [...access.remoteHosts],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A Redocly resolver that checks each document before it loads it. Redocly turns a failed load
|
|
84
|
+
* into an unresolved-`$ref` problem, so the refusals are also kept for the loader to report as
|
|
85
|
+
* the typed error.
|
|
86
|
+
*/
|
|
87
|
+
export class RefAccessResolver extends BaseResolver {
|
|
88
|
+
readonly #access: RefAccess;
|
|
89
|
+
readonly #refusals: OpenAPITypesafeError[] = [];
|
|
90
|
+
/** The root document's ref: it is chosen by the developer, so it is not limited. */
|
|
91
|
+
#rootRef: string | undefined;
|
|
92
|
+
|
|
93
|
+
constructor(config: ResolveConfig, access: RefAccess) {
|
|
94
|
+
super(config);
|
|
95
|
+
this.#access = access;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The first document that was refused, if any. */
|
|
99
|
+
get firstRefusal(): OpenAPITypesafeError | undefined {
|
|
100
|
+
return this.#refusals[0];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
override resolveDocument(
|
|
104
|
+
base: string | null,
|
|
105
|
+
ref: string,
|
|
106
|
+
isRoot = false,
|
|
107
|
+
): ReturnType<BaseResolver["resolveDocument"]> {
|
|
108
|
+
if (isRoot) {
|
|
109
|
+
this.#rootRef = this.resolveExternalRef(base, ref);
|
|
110
|
+
}
|
|
111
|
+
return super.resolveDocument(base, ref, isRoot);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */
|
|
115
|
+
override parseDocument(source: Source, isRoot = false): Document {
|
|
116
|
+
const document = super.parseDocument(source, isRoot);
|
|
117
|
+
const failure = aliasExpansionFailure(document.parsed);
|
|
118
|
+
if (failure !== undefined) {
|
|
119
|
+
throw new YamlParseError(failure, source);
|
|
120
|
+
}
|
|
121
|
+
return document;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
override async loadExternalRef(absoluteRef: string): Promise<Source> {
|
|
125
|
+
const refusal =
|
|
126
|
+
absoluteRef === this.#rootRef ? undefined : await refusalOf(absoluteRef, this.#access);
|
|
127
|
+
if (refusal !== undefined) {
|
|
128
|
+
this.#refusals.push(refusal);
|
|
129
|
+
throw refusal;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
return await super.loadExternalRef(absoluteRef);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
// A refused redirect throws inside the fetch, and Redocly wraps it in a ResolveError.
|
|
135
|
+
const cause = (error as { originalError?: unknown }).originalError;
|
|
136
|
+
if (isRefusal(cause)) {
|
|
137
|
+
this.#refusals.push(cause);
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function isRefusal(value: unknown): value is OpenAPITypesafeError {
|
|
145
|
+
return (value as { code?: unknown } | null)?.code === ERROR_CODES.SCHEMA_REF_FORBIDDEN;
|
|
146
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { escapePointerSegment } from "../../domain/openapi/json-pointer.js";
|
|
2
|
+
|
|
3
|
+
/** An object with a string `$ref`, and its JSON Pointer in the document. */
|
|
4
|
+
export interface RefHolder {
|
|
5
|
+
readonly node: { $ref: string };
|
|
6
|
+
readonly pointer: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface PendingNode {
|
|
10
|
+
readonly value: object;
|
|
11
|
+
readonly pointer: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hasStringRef(value: object): value is { $ref: string } {
|
|
15
|
+
return !Array.isArray(value) && typeof (value as { $ref?: unknown }).$ref === "string";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Every object with a string `$ref` in a parsed document, in no particular order. The walk uses
|
|
20
|
+
* its own stack, so a deeply nested document does not run out of call stack, and a node shared by
|
|
21
|
+
* YAML aliases (or a cycle of them) is visited once.
|
|
22
|
+
*/
|
|
23
|
+
export function findRefHolders(document: unknown): RefHolder[] {
|
|
24
|
+
const found: RefHolder[] = [];
|
|
25
|
+
const visited = new WeakSet<object>();
|
|
26
|
+
const pending: PendingNode[] = [];
|
|
27
|
+
const enqueue = (value: unknown, pointer: string): void => {
|
|
28
|
+
if (typeof value === "object" && value !== null && !visited.has(value)) {
|
|
29
|
+
visited.add(value);
|
|
30
|
+
pending.push({ value, pointer });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
enqueue(document, "#");
|
|
34
|
+
for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
|
|
35
|
+
if (hasStringRef(next.value)) {
|
|
36
|
+
found.push({ node: next.value, pointer: next.pointer });
|
|
37
|
+
}
|
|
38
|
+
for (const [key, child] of Object.entries(next.value)) {
|
|
39
|
+
enqueue(child, `${next.pointer}/${escapePointerSegment(key)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return found;
|
|
43
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Config as RedoclyConfig } from "@redocly/openapi-core";
|
|
2
|
+
import type { RefAccess } from "../../application/ports/schema-loader.js";
|
|
3
|
+
import { isHostAllowed } from "./allowed-hosts.js";
|
|
4
|
+
import { refForbiddenError } from "./schema-load-errors.js";
|
|
5
|
+
|
|
6
|
+
/** How the loader fetches remote documents: a time limit, and the host limit on redirects. */
|
|
7
|
+
|
|
8
|
+
type ResolveConfig = RedoclyConfig["resolve"];
|
|
9
|
+
|
|
10
|
+
/** The fetch Redocly calls for a remote document (`resolve.http.customFetch`). */
|
|
11
|
+
export type RemoteFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Redirects followed for a remote `$ref` when hosts are limited. Each hop is checked, so fetch
|
|
15
|
+
* cannot follow them on its own; 5 covers http → https plus a moved file, and a loop stops early.
|
|
16
|
+
*/
|
|
17
|
+
export const MAX_CHECKED_REDIRECTS = 5;
|
|
18
|
+
|
|
19
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
20
|
+
|
|
21
|
+
/** Statuses whose responses have no body; `new Response()` refuses a body for them. */
|
|
22
|
+
const NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);
|
|
23
|
+
|
|
24
|
+
/** A response whose body is already read, so that reading it again cannot wait or fail. */
|
|
25
|
+
async function bufferedResponse(response: Response): Promise<Response> {
|
|
26
|
+
const body = await response.arrayBuffer();
|
|
27
|
+
const { status, statusText, headers } = response;
|
|
28
|
+
return new Response(NULL_BODY_STATUSES.has(status) ? null : body, {
|
|
29
|
+
status,
|
|
30
|
+
statusText,
|
|
31
|
+
headers,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fetch with a time limit for the whole response, body included: Node's own fetch waits five
|
|
37
|
+
* minutes for a server that never answers, and a server that sends its body one byte at a time
|
|
38
|
+
* never finishes. The body is read here, inside the limit; when Redocly read it, the abort
|
|
39
|
+
* surfaced as a `DOMException` whose read-only `message` Redocly tried to change, which gave
|
|
40
|
+
* "Cannot set property message of which has only a getter" instead of the time limit.
|
|
41
|
+
*/
|
|
42
|
+
function fetchWithTimeout(timeoutMs: number): RemoteFetch {
|
|
43
|
+
return async (input, init = {}) => {
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(input, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
46
|
+
return await bufferedResponse(response);
|
|
47
|
+
} catch (cause) {
|
|
48
|
+
const isTimeout = cause instanceof Error && cause.name === "TimeoutError";
|
|
49
|
+
throw isTimeout ? new Error(`Timed out after ${timeoutMs} ms loading ${input}`) : cause;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Follow redirects one by one, and refuse a redirect to a host that is not listed. The first URL
|
|
56
|
+
* was checked by the resolver (or is the root document). As fetch does, the configured headers
|
|
57
|
+
* (often credentials) are not sent on to another origin.
|
|
58
|
+
*/
|
|
59
|
+
export function fetchWithCheckedRedirects(
|
|
60
|
+
fetchImpl: RemoteFetch,
|
|
61
|
+
hosts: readonly string[],
|
|
62
|
+
): RemoteFetch {
|
|
63
|
+
return async (input, init = {}) => {
|
|
64
|
+
const firstOrigin = new URL(input).origin;
|
|
65
|
+
let url = new URL(input);
|
|
66
|
+
for (let hop = 0; hop <= MAX_CHECKED_REDIRECTS; hop += 1) {
|
|
67
|
+
if (hop > 0 && !isHostAllowed(url, hosts)) {
|
|
68
|
+
throw refForbiddenError(url.href, { reason: "host-not-allowed", allowedHosts: [...hosts] });
|
|
69
|
+
}
|
|
70
|
+
const { headers, ...rest } = init;
|
|
71
|
+
const hopInit: RequestInit =
|
|
72
|
+
url.origin === firstOrigin && headers !== undefined ? { ...rest, headers } : rest;
|
|
73
|
+
const response = await fetchImpl(url.href, { ...hopInit, redirect: "manual" });
|
|
74
|
+
const location = response.headers.get("location");
|
|
75
|
+
if (!REDIRECT_STATUSES.has(response.status) || location === null) {
|
|
76
|
+
return response;
|
|
77
|
+
}
|
|
78
|
+
url = new URL(location, url);
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`More than ${MAX_CHECKED_REDIRECTS} redirects loading ${input}`);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface RemoteFetchOptions {
|
|
85
|
+
/** Time limit of one fetch and its body, unless the Redocly config has its own `customFetch`. */
|
|
86
|
+
readonly timeoutMs: number;
|
|
87
|
+
readonly access: RefAccess;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The resolve config with the fetch the loader uses. A `customFetch` of the Redocly config is
|
|
92
|
+
* kept; with a host limit, it is wrapped so that each redirect is checked.
|
|
93
|
+
*/
|
|
94
|
+
export function resolveConfigWithAccess(
|
|
95
|
+
resolve: ResolveConfig,
|
|
96
|
+
options: RemoteFetchOptions,
|
|
97
|
+
): ResolveConfig {
|
|
98
|
+
// Redocly types `customFetch` as `Function`; it is called as fetch is.
|
|
99
|
+
const configured = resolve.http.customFetch as RemoteFetch | undefined;
|
|
100
|
+
const base = configured ?? fetchWithTimeout(options.timeoutMs);
|
|
101
|
+
const hosts = options.access.remoteHosts;
|
|
102
|
+
const customFetch = hosts === undefined ? base : fetchWithCheckedRedirects(base, hosts);
|
|
103
|
+
return { ...resolve, http: { ...resolve.http, customFetch } };
|
|
104
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { ERROR_CODES, OpenAPITypesafeError } from "../../domain/errors.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The typed errors of loading, validating and bundling a document (ADR-011). Messages are the
|
|
5
|
+
* original messages, so Node API users who match on them keep working.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** No source was given, or the source is empty. */
|
|
9
|
+
export function sourceEmptyError(message: string): OpenAPITypesafeError {
|
|
10
|
+
return new OpenAPITypesafeError({ code: ERROR_CODES.SCHEMA_SOURCE_EMPTY, message });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** The source is neither a URL, text, buffer, stream nor plain object. */
|
|
14
|
+
export function sourceInvalidError(source: unknown): OpenAPITypesafeError {
|
|
15
|
+
const received = Array.isArray(source) ? "Array" : typeof source;
|
|
16
|
+
return new OpenAPITypesafeError({
|
|
17
|
+
code: ERROR_CODES.SCHEMA_SOURCE_INVALID,
|
|
18
|
+
message: `Expected string, object, or Buffer. Got ${received}`,
|
|
19
|
+
details: { received },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function causeMessage(cause: unknown): string {
|
|
24
|
+
return cause instanceof Error ? cause.message : String(cause);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Enough of a source string to recognise it in the message. */
|
|
28
|
+
const SOURCE_TEXT_IN_MESSAGE = 200;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A string source is document text, so a file path parses as a YAML string scalar, not as a
|
|
32
|
+
* document (docs/node.md). The message says how to load the file instead.
|
|
33
|
+
*/
|
|
34
|
+
export function pathStringError(text: string): OpenAPITypesafeError {
|
|
35
|
+
const shown =
|
|
36
|
+
text.length > SOURCE_TEXT_IN_MESSAGE ? `${text.slice(0, SOURCE_TEXT_IN_MESSAGE)}…` : text;
|
|
37
|
+
return new OpenAPITypesafeError({
|
|
38
|
+
code: ERROR_CODES.SCHEMA_SOURCE_INVALID,
|
|
39
|
+
message:
|
|
40
|
+
`The string "${shown}" was parsed as YAML text, not loaded as a file. ` +
|
|
41
|
+
"To load a file, pass a URL: openapiTS(pathToFileURL(path)) from node:url.",
|
|
42
|
+
details: { reason: "path", received: "string" },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Reading the document from a file or URL failed; the message is the reader's message. */
|
|
47
|
+
export function loadFailedError(absoluteRef: string, cause: unknown): OpenAPITypesafeError {
|
|
48
|
+
return new OpenAPITypesafeError({
|
|
49
|
+
code: ERROR_CODES.SCHEMA_LOAD_FAILED,
|
|
50
|
+
message: causeMessage(cause),
|
|
51
|
+
details: { source: absoluteRef },
|
|
52
|
+
cause,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The document text is not valid JSON or YAML; the message is the parser's message. */
|
|
57
|
+
export function parseFailedError(
|
|
58
|
+
format: "json" | "yaml",
|
|
59
|
+
absoluteRef: string,
|
|
60
|
+
cause: unknown,
|
|
61
|
+
): OpenAPITypesafeError {
|
|
62
|
+
return new OpenAPITypesafeError({
|
|
63
|
+
code: ERROR_CODES.SCHEMA_PARSE_FAILED,
|
|
64
|
+
message: causeMessage(cause),
|
|
65
|
+
details: { format, source: absoluteRef },
|
|
66
|
+
cause,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The document is not OpenAPI 3.x. */
|
|
71
|
+
export function versionUnsupportedError(
|
|
72
|
+
message: string,
|
|
73
|
+
parsed: Readonly<Record<string, unknown>>,
|
|
74
|
+
): OpenAPITypesafeError {
|
|
75
|
+
return new OpenAPITypesafeError({
|
|
76
|
+
code: ERROR_CODES.SCHEMA_VERSION_UNSUPPORTED,
|
|
77
|
+
message,
|
|
78
|
+
details: { openapi: parsed.openapi, swagger: parsed.swagger },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Linting or bundling found errors. The message is the last error, as in the original; all error
|
|
84
|
+
* messages are in `details.problems`.
|
|
85
|
+
*/
|
|
86
|
+
export function schemaInvalidError(problems: readonly string[]): OpenAPITypesafeError {
|
|
87
|
+
return new OpenAPITypesafeError({
|
|
88
|
+
code: ERROR_CODES.SCHEMA_INVALID,
|
|
89
|
+
message: problems.at(-1) ?? "",
|
|
90
|
+
details: { problems: [...problems] },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** A `$ref` chain points back to itself with no schema in between (`A: $ref B`, `B: $ref A`). */
|
|
95
|
+
export function refCycleError(cause: Error): OpenAPITypesafeError {
|
|
96
|
+
return new OpenAPITypesafeError({
|
|
97
|
+
code: ERROR_CODES.SCHEMA_REF_INVALID,
|
|
98
|
+
message: cause.message,
|
|
99
|
+
details: { reason: "cycle" },
|
|
100
|
+
cause,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function hostListText(hosts: readonly string[]): string {
|
|
105
|
+
return hosts.length === 0 ? "none" : hosts.join(", ");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Why a `$ref` document was refused, with the limit it broke (ADR-017). */
|
|
109
|
+
export type RefRefusalDetails =
|
|
110
|
+
| { readonly reason: "outside-local-root"; readonly localRoot: string }
|
|
111
|
+
| { readonly reason: "host-not-allowed"; readonly allowedHosts: readonly string[] };
|
|
112
|
+
|
|
113
|
+
/** A `$ref` is outside the local root, or its host is not allowed (threat model R1, R2). */
|
|
114
|
+
export function refForbiddenError(ref: string, details: RefRefusalDetails): OpenAPITypesafeError {
|
|
115
|
+
const limit =
|
|
116
|
+
details.reason === "outside-local-root"
|
|
117
|
+
? `it is outside the local $ref root ${details.localRoot}`
|
|
118
|
+
: `its host is not in the allowed remote $ref hosts (${hostListText(details.allowedHosts)})`;
|
|
119
|
+
return new OpenAPITypesafeError({
|
|
120
|
+
code: ERROR_CODES.SCHEMA_REF_FORBIDDEN,
|
|
121
|
+
message: `Refused to load ${ref}: ${limit}`,
|
|
122
|
+
details: { ref, ...details },
|
|
123
|
+
});
|
|
124
|
+
}
|