openapi-typesafe 0.0.0 → 1.0.0-rc.0
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 +42 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +35 -0
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +169 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +167 -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 +145 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +139 -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 +204 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -0
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +201 -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-enum.cjs +44 -0
- package/dist/api/discriminator-enum.cjs.map +1 -0
- package/dist/api/discriminator-enum.mjs +42 -0
- package/dist/api/discriminator-enum.mjs.map +1 -0
- package/dist/api/discriminator-scan.cjs +168 -0
- package/dist/api/discriminator-scan.cjs.map +1 -0
- package/dist/api/discriminator-scan.mjs +165 -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 +107 -0
- package/dist/api/document-run.cjs.map +1 -0
- package/dist/api/document-run.mjs +101 -0
- package/dist/api/document-run.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/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 +82 -0
- package/dist/api/transform-context.cjs.map +1 -0
- package/dist/api/transform-context.mjs +65 -0
- package/dist/api/transform-context.mjs.map +1 -0
- package/dist/api/transform-schema.cjs +31 -0
- package/dist/api/transform-schema.cjs.map +1 -0
- package/dist/api/transform-schema.mjs +26 -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 +17 -0
- package/dist/api/unsupported-feature-warnings.cjs.map +1 -0
- package/dist/api/unsupported-feature-warnings.mjs +15 -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 +214 -0
- package/dist/application/print/type-printer.cjs.map +1 -0
- package/dist/application/print/type-printer.mjs +210 -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/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/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 +86 -0
- package/dist/application/transform/document/document.cjs.map +1 -0
- package/dist/application/transform/document/document.mjs +83 -0
- package/dist/application/transform/document/document.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/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 +114 -0
- package/dist/application/transform/document/parameters.cjs.map +1 -0
- package/dist/application/transform/document/parameters.mjs +112 -0
- package/dist/application/transform/document/parameters.mjs.map +1 -0
- package/dist/application/transform/document/path-item-conflicts.cjs +51 -0
- package/dist/application/transform/document/path-item-conflicts.cjs.map +1 -0
- package/dist/application/transform/document/path-item-conflicts.mjs +49 -0
- package/dist/application/transform/document/path-item-conflicts.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 +57 -0
- package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -0
- package/dist/application/transform/document/path-key-overlaps.mjs +55 -0
- package/dist/application/transform/document/path-key-overlaps.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 +127 -0
- package/dist/application/transform/document/paths.cjs.map +1 -0
- package/dist/application/transform/document/paths.mjs +125 -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 +69 -0
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -0
- package/dist/application/transform/document/root-type-aliases.mjs +65 -0
- package/dist/application/transform/document/root-type-aliases.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 +88 -0
- package/dist/application/transform/footer/document-footer.cjs.map +1 -0
- package/dist/application/transform/footer/document-footer.mjs +86 -0
- package/dist/application/transform/footer/document-footer.mjs.map +1 -0
- package/dist/application/transform/footer/enum-naming.cjs +121 -0
- package/dist/application/transform/footer/enum-naming.cjs.map +1 -0
- package/dist/application/transform/footer/enum-naming.mjs +115 -0
- package/dist/application/transform/footer/enum-naming.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-type.cjs +57 -0
- package/dist/application/transform/ref-type.cjs.map +1 -0
- package/dist/application/transform/ref-type.mjs +54 -0
- package/dist/application/transform/ref-type.mjs.map +1 -0
- package/dist/application/transform/schema/array-type.cjs +105 -0
- package/dist/application/transform/schema/array-type.cjs.map +1 -0
- package/dist/application/transform/schema/array-type.mjs +103 -0
- package/dist/application/transform/schema/array-type.mjs.map +1 -0
- package/dist/application/transform/schema/composition-type.cjs +107 -0
- package/dist/application/transform/schema/composition-type.cjs.map +1 -0
- package/dist/application/transform/schema/composition-type.mjs +105 -0
- package/dist/application/transform/schema/composition-type.mjs.map +1 -0
- package/dist/application/transform/schema/core-type.cjs +84 -0
- package/dist/application/transform/schema/core-type.cjs.map +1 -0
- package/dist/application/transform/schema/core-type.mjs +82 -0
- package/dist/application/transform/schema/core-type.mjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.cjs +21 -0
- package/dist/application/transform/schema/discriminator-property.cjs.map +1 -0
- package/dist/application/transform/schema/discriminator-property.mjs +19 -0
- package/dist/application/transform/schema/discriminator-property.mjs.map +1 -0
- package/dist/application/transform/schema/enum-rule.cjs +107 -0
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -0
- package/dist/application/transform/schema/enum-rule.mjs +105 -0
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +173 -0
- package/dist/application/transform/schema/object-type.cjs.map +1 -0
- package/dist/application/transform/schema/object-type.mjs +170 -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/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 +84 -0
- package/dist/application/transform/schema-comment.cjs.map +1 -0
- package/dist/application/transform/schema-comment.mjs +81 -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 +137 -0
- package/dist/cli/cli-arguments.cjs.map +1 -0
- package/dist/cli/cli-arguments.mjs +129 -0
- package/dist/cli/cli-arguments.mjs.map +1 -0
- package/dist/cli/cli-errors.cjs +80 -0
- package/dist/cli/cli-errors.cjs.map +1 -0
- package/dist/cli/cli-errors.mjs +76 -0
- package/dist/cli/cli-errors.mjs.map +1 -0
- package/dist/cli/cli-output.cjs +37 -0
- package/dist/cli/cli-output.cjs.map +1 -0
- package/dist/cli/cli-output.mjs +30 -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 +62 -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 +54 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/redocly-apis.cjs +65 -0
- package/dist/cli/redocly-apis.cjs.map +1 -0
- package/dist/cli/redocly-apis.mjs +62 -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 +100 -0
- package/dist/cli/run-cli.cjs.map +1 -0
- package/dist/cli/run-cli.mjs +98 -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 +50 -0
- package/dist/domain/errors.cjs.map +1 -0
- package/dist/domain/errors.mjs +46 -0
- package/dist/domain/errors.mjs.map +1 -0
- package/dist/domain/ir/constructors.cjs +89 -0
- package/dist/domain/ir/constructors.cjs.map +1 -0
- package/dist/domain/ir/constructors.mjs +71 -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/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/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/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 +66 -0
- package/dist/domain/output-fixes.cjs.map +1 -0
- package/dist/domain/output-fixes.mjs +59 -0
- package/dist/domain/output-fixes.mjs.map +1 -0
- package/dist/index.cjs +98 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +812 -0
- package/dist/index.d.mts +812 -0
- package/dist/index.d.ts +812 -0
- package/dist/index.mjs +27 -0
- package/dist/index.mjs.map +1 -0
- package/dist/transform/components-object.cjs +14 -0
- package/dist/transform/components-object.cjs.map +1 -0
- package/dist/transform/components-object.mjs +10 -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 +43 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +246 -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 +220 -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 +280 -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-enum.ts +76 -0
- package/src/api/discriminator-scan.ts +272 -0
- package/src/api/document-declarations.ts +41 -0
- package/src/api/document-refs.ts +71 -0
- package/src/api/document-run.ts +159 -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/schema-callbacks.ts +211 -0
- package/src/api/string-to-ast.ts +27 -0
- package/src/api/transform-context.ts +87 -0
- package/src/api/transform-schema.ts +39 -0
- package/src/api/type-helpers.ts +130 -0
- package/src/api/unsupported-feature-warnings.ts +26 -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 +16 -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 +281 -0
- package/src/application/stack-overflow.ts +54 -0
- package/src/application/transform/document/components.ts +189 -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 +157 -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/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 +200 -0
- package/src/application/transform/document/path-item-conflicts.ts +79 -0
- package/src/application/transform/document/path-item.ts +168 -0
- package/src/application/transform/document/path-key-overlaps.ts +112 -0
- package/src/application/transform/document/paths-enum.ts +127 -0
- package/src/application/transform/document/paths.ts +211 -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 +106 -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 +127 -0
- package/src/application/transform/footer/enum-naming.ts +181 -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-type.ts +97 -0
- package/src/application/transform/schema/array-type.ts +152 -0
- package/src/application/transform/schema/composition-type.ts +183 -0
- package/src/application/transform/schema/core-type.ts +115 -0
- package/src/application/transform/schema/discriminator-property.ts +28 -0
- package/src/application/transform/schema/enum-rule.ts +157 -0
- package/src/application/transform/schema/object-type.ts +271 -0
- package/src/application/transform/schema/presence-members.ts +96 -0
- package/src/application/transform/schema/schema-context.ts +110 -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 +116 -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 +198 -0
- package/src/cli/cli-dependencies.ts +42 -0
- package/src/cli/cli-errors.ts +125 -0
- package/src/cli/cli-output.ts +53 -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 +67 -0
- package/src/cli/redocly-apis.ts +91 -0
- package/src/cli/ref-limits.ts +16 -0
- package/src/cli/run-cli.ts +114 -0
- package/src/domain/assert-never.ts +8 -0
- package/src/domain/errors.ts +74 -0
- package/src/domain/ir/constructors.ts +137 -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 +224 -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/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/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 +30 -0
- package/src/domain/openapi/path-item-object.ts +70 -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 +59 -0
- package/src/domain/openapi/unsupported-features.ts +139 -0
- package/src/domain/output-fixes.ts +95 -0
- package/src/index.ts +67 -0
- package/src/transform/components-object.ts +25 -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 +267 -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,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ERROR_CODES,
|
|
3
|
+
type ErrorCode,
|
|
4
|
+
isOpenAPITypesafeError,
|
|
5
|
+
OpenAPITypesafeError,
|
|
6
|
+
} from "../domain/errors.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* How the CLI reports a failure (ENGINEERING_PLAN 4.6, ADR-011): each error code maps to a process
|
|
10
|
+
* exit code and the line printed for it. The table is exhaustive, so a new error code does not
|
|
11
|
+
* compile until the CLI handles it.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Process exit codes of the CLI, documented in docs/cli.md. */
|
|
15
|
+
export const EXIT_CODES = {
|
|
16
|
+
SUCCESS: 0,
|
|
17
|
+
/** `--check` found output that differs from the generated types (as in the original CLI). */
|
|
18
|
+
OUTPUT_STALE: 1,
|
|
19
|
+
/** A flag, the Redocly config, the environment or a callback is wrong. */
|
|
20
|
+
USAGE: 2,
|
|
21
|
+
/** The OpenAPI document cannot be read, is invalid, or cannot be converted. */
|
|
22
|
+
SCHEMA: 3,
|
|
23
|
+
/** An output file cannot be read or written. */
|
|
24
|
+
OUTPUT: 4,
|
|
25
|
+
/** An unexpected failure: a bug in the generator (sysexits `EX_SOFTWARE`). */
|
|
26
|
+
INTERNAL: 70,
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
|
|
30
|
+
|
|
31
|
+
interface CliErrorReport {
|
|
32
|
+
readonly exitCode: ExitCode;
|
|
33
|
+
/** The printed text; the error's own message when absent. */
|
|
34
|
+
readonly message?: (error: OpenAPITypesafeError) => string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Problems are printed one by one while linting, so the summary only counts them. */
|
|
38
|
+
function schemaInvalidMessage(error: OpenAPITypesafeError): string {
|
|
39
|
+
const count = Array.isArray(error.details.problems) ? error.details.problems.length : 1;
|
|
40
|
+
return `The OpenAPI document has ${count} ${count === 1 ? "error" : "errors"} (see above)`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Node's `fetch` fails with only "fetch failed"; the network reason (refused, DNS, TLS) is the
|
|
45
|
+
* cause of that error. The Node API keeps the original message, so only the CLI adds it.
|
|
46
|
+
*/
|
|
47
|
+
function loadFailedMessage(error: OpenAPITypesafeError): string {
|
|
48
|
+
const reason = error.cause instanceof Error ? error.cause.cause : undefined;
|
|
49
|
+
if (!(reason instanceof Error)) {
|
|
50
|
+
return error.message;
|
|
51
|
+
}
|
|
52
|
+
const source = typeof error.details.source === "string" ? ` (${error.details.source})` : "";
|
|
53
|
+
return `${error.message}: ${reason.message}${source}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The message js-yaml throws at its nesting limit (docs/security/threat-model.md T2). */
|
|
57
|
+
const YAML_DEPTH_LIMIT_MESSAGE = /nesting exceeded maxDepth \((\d+)\)/;
|
|
58
|
+
|
|
59
|
+
/** The parser's message says the limit, not how to stay under it. */
|
|
60
|
+
function parseFailedMessage(error: OpenAPITypesafeError): string {
|
|
61
|
+
const limit = YAML_DEPTH_LIMIT_MESSAGE.exec(error.message)?.[1];
|
|
62
|
+
if (limit === undefined) {
|
|
63
|
+
return error.message;
|
|
64
|
+
}
|
|
65
|
+
return (
|
|
66
|
+
`${error.message}. The YAML parser reads at most ${limit} nested levels: ` +
|
|
67
|
+
"move nested schemas to `components` and reference them with `$ref`"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const CLI_ERROR_REPORTS: Readonly<Record<ErrorCode, CliErrorReport>> = {
|
|
72
|
+
SCHEMA_SOURCE_EMPTY: { exitCode: EXIT_CODES.SCHEMA },
|
|
73
|
+
SCHEMA_SOURCE_INVALID: { exitCode: EXIT_CODES.SCHEMA },
|
|
74
|
+
SCHEMA_LOAD_FAILED: { exitCode: EXIT_CODES.SCHEMA, message: loadFailedMessage },
|
|
75
|
+
SCHEMA_PARSE_FAILED: { exitCode: EXIT_CODES.SCHEMA, message: parseFailedMessage },
|
|
76
|
+
SCHEMA_VERSION_UNSUPPORTED: { exitCode: EXIT_CODES.SCHEMA },
|
|
77
|
+
SCHEMA_INVALID: { exitCode: EXIT_CODES.SCHEMA, message: schemaInvalidMessage },
|
|
78
|
+
SCHEMA_REF_INVALID: { exitCode: EXIT_CODES.SCHEMA },
|
|
79
|
+
SCHEMA_REF_FORBIDDEN: { exitCode: EXIT_CODES.SCHEMA },
|
|
80
|
+
SCHEMA_OBJECT_INVALID: { exitCode: EXIT_CODES.SCHEMA },
|
|
81
|
+
SCHEMA_PROPERTY_INVALID: { exitCode: EXIT_CODES.SCHEMA },
|
|
82
|
+
SCHEMA_TOO_DEEP: { exitCode: EXIT_CODES.SCHEMA },
|
|
83
|
+
SCHEMA_KEY_UNSUPPORTED: { exitCode: EXIT_CODES.SCHEMA },
|
|
84
|
+
ENUM_NAME_EMPTY: { exitCode: EXIT_CODES.SCHEMA },
|
|
85
|
+
CALLBACK_RESULT_UNREADABLE: { exitCode: EXIT_CODES.USAGE },
|
|
86
|
+
OPTION_FIX_UNKNOWN: { exitCode: EXIT_CODES.USAGE },
|
|
87
|
+
TYPESCRIPT_NOT_FOUND: { exitCode: EXIT_CODES.USAGE },
|
|
88
|
+
CLI_FLAG_REMOVED: { exitCode: EXIT_CODES.USAGE },
|
|
89
|
+
CLI_GLOB_UNSUPPORTED: { exitCode: EXIT_CODES.USAGE },
|
|
90
|
+
CLI_CONFIG_NOT_FOUND: { exitCode: EXIT_CODES.USAGE },
|
|
91
|
+
CLI_CONFIG_OUTPUT_MISSING: { exitCode: EXIT_CODES.USAGE },
|
|
92
|
+
CLI_CHECK_OUTPUT_MISSING: { exitCode: EXIT_CODES.USAGE },
|
|
93
|
+
OUTPUT_STALE: { exitCode: EXIT_CODES.OUTPUT_STALE },
|
|
94
|
+
OUTPUT_READ_FAILED: { exitCode: EXIT_CODES.OUTPUT },
|
|
95
|
+
OUTPUT_WRITE_FAILED: { exitCode: EXIT_CODES.OUTPUT },
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** What the CLI prints and returns for a thrown value. */
|
|
99
|
+
export interface CliFailure {
|
|
100
|
+
readonly exitCode: ExitCode;
|
|
101
|
+
readonly message: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Map a thrown value to the CLI's output. A typed error prints one line with its code; anything
|
|
106
|
+
* else is a bug and prints its stack, so it can be reported.
|
|
107
|
+
*/
|
|
108
|
+
export function describeCliFailure(error: unknown): CliFailure {
|
|
109
|
+
if (!isOpenAPITypesafeError(error)) {
|
|
110
|
+
const text = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
|
111
|
+
return { exitCode: EXIT_CODES.INTERNAL, message: `Unexpected error: ${text}` };
|
|
112
|
+
}
|
|
113
|
+
const report = CLI_ERROR_REPORTS[error.code];
|
|
114
|
+
const message = report.message?.(error) ?? error.message;
|
|
115
|
+
return { exitCode: report.exitCode, message: `${message} (${error.code})` };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Errors of the CLI itself; its messages are the original CLI's messages. */
|
|
119
|
+
export function cliError(
|
|
120
|
+
code: Extract<ErrorCode, `CLI_${string}` | `OUTPUT_${string}`>,
|
|
121
|
+
message: string,
|
|
122
|
+
cause?: unknown,
|
|
123
|
+
): OpenAPITypesafeError {
|
|
124
|
+
return new OpenAPITypesafeError({ code: ERROR_CODES[code], message, cause });
|
|
125
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { formatDuration } from "../adapters/terminal-logger/terminal-logger.js";
|
|
4
|
+
import type { CliArguments } from "./cli-arguments.js";
|
|
5
|
+
import type { CliDependencies } from "./cli-dependencies.js";
|
|
6
|
+
import { cliError } from "./cli-errors.js";
|
|
7
|
+
|
|
8
|
+
/** Writing one generated file, or checking it with `--check`, and the line printed for it. */
|
|
9
|
+
|
|
10
|
+
/** One CLI run: its dependencies, its arguments and when it started. */
|
|
11
|
+
export interface CliRun {
|
|
12
|
+
readonly deps: CliDependencies;
|
|
13
|
+
readonly args: CliArguments;
|
|
14
|
+
readonly startedAt: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A generated file: `source` names the schema and `output` is the path as the user wrote it. */
|
|
18
|
+
export interface OutputFile {
|
|
19
|
+
readonly source: string;
|
|
20
|
+
readonly output: string;
|
|
21
|
+
readonly file: URL;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** A file URL for a path that is absolute, or relative to `base` (a directory or file URL). */
|
|
25
|
+
export function resolveFileUrl(filePath: string, base: URL): URL {
|
|
26
|
+
return path.isAbsolute(filePath) ? pathToFileURL(filePath) : new URL(filePath, base);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function printDone(run: CliRun, output: OutputFile): void {
|
|
30
|
+
const { style, now } = run.deps;
|
|
31
|
+
const target = style.green(`${output.source} → ${style.bold(output.output)}`);
|
|
32
|
+
const duration = style.dim(`[${formatDuration(now() - run.startedAt)}]`);
|
|
33
|
+
run.deps.console.info(`🚀 ${target} ${duration}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* With `--check`, fail with `OUTPUT_STALE` when the file differs from `contents` and leave it
|
|
38
|
+
* alone otherwise. Without it, write the file and print where it went.
|
|
39
|
+
*/
|
|
40
|
+
export function emitOutput(run: CliRun, output: OutputFile, contents: string): void {
|
|
41
|
+
if (run.args.isCheck) {
|
|
42
|
+
if (run.deps.files.readText(output.file) !== contents) {
|
|
43
|
+
// The original message, then the file: with several APIs it tells which one is stale.
|
|
44
|
+
throw cliError(
|
|
45
|
+
"OUTPUT_STALE",
|
|
46
|
+
`Generated types are not up-to-date! ${output.output} differs from its schema.`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
run.deps.files.writeText(output.file, contents);
|
|
52
|
+
printDone(run, output);
|
|
53
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Links that CLI messages print. They point at the docs in this repository on GitHub, which work
|
|
3
|
+
* before the docs site is published and stay valid after.
|
|
4
|
+
*/
|
|
5
|
+
export const MULTIPLE_SCHEMAS_DOCS_URL =
|
|
6
|
+
"https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/cli.md#multiple-schemas";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type OutputFixName, outputFixNamesOf } from "../domain/output-fixes.js";
|
|
2
|
+
import type { GeneratorOptions } from "../types.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The `fix` option (ADR-021) as the CLI and `redocly.yaml` give it: `--fix a,b`, repeatable, or
|
|
6
|
+
* `fix: [a, b]` / `fix: a,b` in an API's settings. Unknown names fail with `OPTION_FIX_UNKNOWN`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const SEPARATOR = ",";
|
|
10
|
+
|
|
11
|
+
/** The names of a flag value or a config value; `undefined` when the option is not set. */
|
|
12
|
+
export function fixNamesOf(value: unknown): readonly OutputFixName[] | undefined {
|
|
13
|
+
if (value === undefined) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const names = [value]
|
|
17
|
+
.flat()
|
|
18
|
+
.flatMap((entry) => String(entry).split(SEPARATOR))
|
|
19
|
+
.map((name) => name.trim())
|
|
20
|
+
.filter((name) => name !== "");
|
|
21
|
+
return outputFixNamesOf(names);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The generator option for the names; nothing when the option is not set. */
|
|
25
|
+
export function fixOption(
|
|
26
|
+
names: readonly OutputFixName[] | undefined,
|
|
27
|
+
): Pick<GeneratorOptions, "fix"> {
|
|
28
|
+
return names === undefined ? {} : { fix: names };
|
|
29
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** The text of `--help`, as in the original CLI; long lines are split only in this source. */
|
|
2
|
+
export const HELP_TEXT = [
|
|
3
|
+
"Usage",
|
|
4
|
+
" $ openapi-typesafe [input] [options]",
|
|
5
|
+
"",
|
|
6
|
+
"Options",
|
|
7
|
+
" --help Display this",
|
|
8
|
+
" --version Display the version",
|
|
9
|
+
" --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)",
|
|
10
|
+
" --output, -o Specify output file (if not specified in redocly.yaml)",
|
|
11
|
+
" --enum Export true TS enums instead of unions",
|
|
12
|
+
" --enum-values Export enum values as arrays",
|
|
13
|
+
" --conditional-enums Only generate true TS enums when enum" +
|
|
14
|
+
" metadata is available (default: false)",
|
|
15
|
+
" --dedupe-enums Dedupe enum types when `--enum=true` is set",
|
|
16
|
+
" --check Check that the generated types are" +
|
|
17
|
+
" up-to-date. (default: false)",
|
|
18
|
+
" --export-type, -t Export top-level `type` instead of `interface`",
|
|
19
|
+
" --immutable Generate readonly types",
|
|
20
|
+
" --additional-properties Treat schema objects as if `additionalProperties: true` is set",
|
|
21
|
+
" --empty-objects-unknown Generate `unknown` instead of" +
|
|
22
|
+
" `Record<string, never>` for empty objects",
|
|
23
|
+
" --default-non-nullable Set to `false` to ignore default values" +
|
|
24
|
+
" when generating non-nullable types",
|
|
25
|
+
" --properties-required-by-default",
|
|
26
|
+
" Treat schema objects as if `required` is" +
|
|
27
|
+
" set to all properties by default",
|
|
28
|
+
" --array-length Generate tuples using array minItems / maxItems",
|
|
29
|
+
" --binary-as-blob Type raw binary strings (format: binary," +
|
|
30
|
+
" contentMediaType) as Blob",
|
|
31
|
+
" --fix [names] Turn on output fixes, comma-separated, or" +
|
|
32
|
+
' "all" (see docs/cli.md#fix)',
|
|
33
|
+
" --path-params-as-types Convert paths to template literal types",
|
|
34
|
+
" --generate-path-params Generate path parameters for all paths where they are" +
|
|
35
|
+
" undefined by schema",
|
|
36
|
+
" --alphabetize Sort object keys alphabetically",
|
|
37
|
+
" --exclude-deprecated Exclude deprecated types",
|
|
38
|
+
" --root-types Export schemas types at root level",
|
|
39
|
+
" --root-types-no-schema-prefix",
|
|
40
|
+
' Do not add "Schema" prefix to types at' +
|
|
41
|
+
" the root level (should only be used with --root-types)",
|
|
42
|
+
" --root-types-keep-casing Keep casing of root types (should only be" +
|
|
43
|
+
" used with --root-types)",
|
|
44
|
+
" --make-paths-enum Generate ApiPaths enum for all paths",
|
|
45
|
+
" --read-write-markers Generate $Read/$Write markers for" +
|
|
46
|
+
" readOnly/writeOnly properties",
|
|
47
|
+
" --no-lint Skip the Redocly lint (bundling errors still fail)",
|
|
48
|
+
" --local-ref-root [dir] Load local $ref files only from this directory",
|
|
49
|
+
" --remote-ref-hosts [hosts] Load remote $ref documents only from these" +
|
|
50
|
+
" comma-separated hosts (empty: none)",
|
|
51
|
+
"",
|
|
52
|
+
].join("\n");
|
package/src/cli/main.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import colors from "ansi-colors";
|
|
4
|
+
import { createNodeFileSystem } from "../adapters/node-file-system/node-file-system.js";
|
|
5
|
+
import { createRedoclyConfigSource } from "../adapters/redocly-loader/redocly-config-source.js";
|
|
6
|
+
import { astToString } from "../api/ast-to-string.js";
|
|
7
|
+
import { COMMENT_HEADER } from "../api/comment-header.js";
|
|
8
|
+
import { defaultLogger, monotonicNow, terminalSupportsColor } from "../api/default-ports.js";
|
|
9
|
+
import openapiTS from "../api/openapi-ts.js";
|
|
10
|
+
import type { CliConsole, CliDependencies, GenerateTypes, TextStyle } from "./cli-dependencies.js";
|
|
11
|
+
import { runCli } from "./run-cli.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The CLI's composition root (ENGINEERING_PLAN 4.5, ADR-012): the only CLI module that touches the
|
|
15
|
+
* process. `bin/cli.js` imports the built copy of this module.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** The same path from `src/cli/` and from the built `dist/cli/`. */
|
|
19
|
+
const PACKAGE_JSON = new URL("../../package.json", import.meta.url);
|
|
20
|
+
|
|
21
|
+
function readVersion(): string {
|
|
22
|
+
const packageJson: { version: string } = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8"));
|
|
23
|
+
return packageJson.version;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function terminalStyle(): TextStyle {
|
|
27
|
+
const palette = colors.create();
|
|
28
|
+
palette.enabled = terminalSupportsColor();
|
|
29
|
+
return {
|
|
30
|
+
bold: (text) => palette.bold(text),
|
|
31
|
+
green: (text) => palette.green(text),
|
|
32
|
+
dim: (text) => palette.dim(text),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const generateTypes: GenerateTypes = async (source, options) =>
|
|
37
|
+
`${COMMENT_HEADER}${astToString(await openapiTS(source, options))}`;
|
|
38
|
+
|
|
39
|
+
function terminalConsole(): CliConsole {
|
|
40
|
+
return {
|
|
41
|
+
// biome-ignore lint/suspicious/noConsole: the CLI's own output lines
|
|
42
|
+
info: (text) => console.info(text),
|
|
43
|
+
// biome-ignore lint/suspicious/noConsole: the CLI's own notices
|
|
44
|
+
notice: (text) => console.warn(text),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function processDependencies(): CliDependencies {
|
|
49
|
+
const cwd = process.cwd();
|
|
50
|
+
return {
|
|
51
|
+
cwd: pathToFileURL(`${cwd}/`),
|
|
52
|
+
version: readVersion(),
|
|
53
|
+
logger: defaultLogger(false),
|
|
54
|
+
console: terminalConsole(),
|
|
55
|
+
writeStdout: (text) => process.stdout.write(text),
|
|
56
|
+
stdin: () => process.stdin,
|
|
57
|
+
files: createNodeFileSystem(),
|
|
58
|
+
redoclyConfigs: createRedoclyConfigSource(cwd),
|
|
59
|
+
generate: generateTypes,
|
|
60
|
+
now: monotonicNow,
|
|
61
|
+
style: terminalStyle(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
runCli(process.argv.slice(2), processDependencies()).then((exitCode) => {
|
|
66
|
+
process.exitCode = exitCode;
|
|
67
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { kebabCase } from "scule";
|
|
2
|
+
import type { RedoclyConfig } from "../application/ports/redocly-config-source.js";
|
|
3
|
+
import type { OutputFixName } from "../domain/output-fixes.js";
|
|
4
|
+
import type { GeneratorOptions } from "../types.js";
|
|
5
|
+
import { GENERATOR_FLAGS, type GeneratorFlags } from "./cli-arguments.js";
|
|
6
|
+
import { cliError } from "./cli-errors.js";
|
|
7
|
+
import { type CliRun, emitOutput, resolveFileUrl } from "./cli-output.js";
|
|
8
|
+
import { MULTIPLE_SCHEMAS_DOCS_URL } from "./docs-links.js";
|
|
9
|
+
import { fixNamesOf, fixOption } from "./fix-option.js";
|
|
10
|
+
import { refLimitOptions } from "./ref-limits.js";
|
|
11
|
+
|
|
12
|
+
/** The `apis` of a Redocly config: each API is generated into its `x-openapi-ts.output`. */
|
|
13
|
+
|
|
14
|
+
/** The key of an API's openapi-typesafe settings in `redocly.yaml`. */
|
|
15
|
+
const REDOCLY_CONFIG_KEY = "x-openapi-ts";
|
|
16
|
+
|
|
17
|
+
/** The setting of an API that lists its output fixes. */
|
|
18
|
+
const FIX_SETTING = "fix";
|
|
19
|
+
|
|
20
|
+
type ApiSettings = Readonly<Record<string, unknown>>;
|
|
21
|
+
|
|
22
|
+
interface RedoclyApi {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly root: string;
|
|
25
|
+
readonly settings: ApiSettings | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function redoclyApisOf(redocly: RedoclyConfig): RedoclyApi[] {
|
|
29
|
+
return Object.entries(redocly.apis ?? {}).map(([name, api]) => {
|
|
30
|
+
const settings = (api as Record<string, unknown>)[REDOCLY_CONFIG_KEY];
|
|
31
|
+
return { name, root: api.root, settings: settings as ApiSettings | undefined };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function hasRedoclyApis(redocly: RedoclyConfig): boolean {
|
|
36
|
+
return Object.keys(redocly.apis ?? {}).length > 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The boolean flags an API sets, in camelCase or kebab-case; they win over the CLI's flags. */
|
|
40
|
+
function apiFlags(settings: ApiSettings): GeneratorFlags {
|
|
41
|
+
const flags: Partial<Record<(typeof GENERATOR_FLAGS)[number], boolean>> = {};
|
|
42
|
+
for (const name of GENERATOR_FLAGS) {
|
|
43
|
+
const value = typeof settings[name] === "boolean" ? settings[name] : settings[kebabCase(name)];
|
|
44
|
+
if (typeof value === "boolean") {
|
|
45
|
+
flags[name] = value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return flags;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The API's `fix` names; they replace the CLI's `--fix`, as its boolean settings win (ADR-021). */
|
|
52
|
+
function apiFixNames(settings: ApiSettings): readonly OutputFixName[] | undefined {
|
|
53
|
+
return fixNamesOf(settings[FIX_SETTING]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Paths in the config are relative to the config file; without a file, to the working dir. */
|
|
57
|
+
function configRootOf(redocly: RedoclyConfig, cwd: URL): URL {
|
|
58
|
+
return redocly.configFile ? resolveFileUrl(redocly.configFile, cwd) : cwd;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function generateApi(run: CliRun, redocly: RedoclyConfig, api: RedoclyApi): Promise<void> {
|
|
62
|
+
if (!api.settings?.output) {
|
|
63
|
+
throw cliError(
|
|
64
|
+
"CLI_CONFIG_OUTPUT_MISSING",
|
|
65
|
+
`API ${api.name} is missing an \`${REDOCLY_CONFIG_KEY}.output\` key. ` +
|
|
66
|
+
`See ${MULTIPLE_SCHEMAS_DOCS_URL}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const output = String(api.settings.output);
|
|
70
|
+
const configRoot = configRootOf(redocly, run.deps.cwd);
|
|
71
|
+
const options: GeneratorOptions = {
|
|
72
|
+
...run.args.generatorFlags,
|
|
73
|
+
...apiFlags(api.settings),
|
|
74
|
+
...refLimitOptions(run.args, run.deps.cwd),
|
|
75
|
+
...fixOption(apiFixNames(api.settings) ?? run.args.fix),
|
|
76
|
+
redocly,
|
|
77
|
+
};
|
|
78
|
+
const contents = await run.deps.generate(new URL(api.root, configRoot), options);
|
|
79
|
+
emitOutput(run, { source: api.name, output, file: new URL(output, configRoot) }, contents);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Generate every API of the config, concurrently. Every API is generated or checked even when
|
|
84
|
+
* another fails, so `--check` reports a stale output wherever it is; the failures are returned
|
|
85
|
+
* in the order of the config.
|
|
86
|
+
*/
|
|
87
|
+
export async function generateRedoclyApis(run: CliRun, redocly: RedoclyConfig): Promise<unknown[]> {
|
|
88
|
+
const apis = redoclyApisOf(redocly);
|
|
89
|
+
const results = await Promise.allSettled(apis.map((api) => generateApi(run, redocly, api)));
|
|
90
|
+
return results.flatMap((result) => (result.status === "rejected" ? [result.reason] : []));
|
|
91
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GeneratorOptions } from "../types.js";
|
|
2
|
+
import type { CliArguments } from "./cli-arguments.js";
|
|
3
|
+
import { resolveFileUrl } from "./cli-output.js";
|
|
4
|
+
|
|
5
|
+
/** The `$ref` limits of the CLI flags as generator options (threat model R1, R2, ADR-017). */
|
|
6
|
+
|
|
7
|
+
export type RefLimitOptions = Pick<GeneratorOptions, "localRefRoot" | "remoteRefHosts">;
|
|
8
|
+
|
|
9
|
+
/** `--local-ref-root` resolves against the working directory, like every other CLI path. */
|
|
10
|
+
export function refLimitOptions(args: CliArguments, cwd: URL): RefLimitOptions {
|
|
11
|
+
const { localRefRoot, remoteRefHosts } = args.refLimits;
|
|
12
|
+
return {
|
|
13
|
+
...(localRefRoot === undefined ? {} : { localRefRoot: resolveFileUrl(localRefRoot, cwd) }),
|
|
14
|
+
...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Logger } from "../application/ports/logger.js";
|
|
2
|
+
import type { RedoclyConfig } from "../application/ports/redocly-config-source.js";
|
|
3
|
+
import { ineffectiveFlagNotices, parseCliArguments } from "./cli-arguments.js";
|
|
4
|
+
import type { CliDependencies } from "./cli-dependencies.js";
|
|
5
|
+
import { cliError, describeCliFailure, EXIT_CODES, type ExitCode } from "./cli-errors.js";
|
|
6
|
+
import { type CliRun, emitOutput, resolveFileUrl } from "./cli-output.js";
|
|
7
|
+
import { MULTIPLE_SCHEMAS_DOCS_URL } from "./docs-links.js";
|
|
8
|
+
import { fixOption } from "./fix-option.js";
|
|
9
|
+
import { HELP_TEXT } from "./help-text.js";
|
|
10
|
+
import { generateRedoclyApis, hasRedoclyApis } from "./redocly-apis.js";
|
|
11
|
+
import { refLimitOptions } from "./ref-limits.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The CLI's use case: parse the arguments, then generate the APIs of the Redocly config, one
|
|
15
|
+
* schema file or URL, or stdin. It has no process access of its own; `main.ts` wires it (ADR-012).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
async function loadRedoclyConfig(run: CliRun): Promise<RedoclyConfig> {
|
|
19
|
+
const { redoclyConfigs } = run.deps;
|
|
20
|
+
const explicitPath = run.args.redocly;
|
|
21
|
+
const configPath = redoclyConfigs.find(explicitPath);
|
|
22
|
+
if (explicitPath && !configPath) {
|
|
23
|
+
throw cliError("CLI_CONFIG_NOT_FOUND", `Redocly config not found at: ${explicitPath}`);
|
|
24
|
+
}
|
|
25
|
+
return configPath ? redoclyConfigs.load(configPath) : redoclyConfigs.createDefault();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** One schema from a path, a URL or stdin; without `--output`, the types go to stdout only. */
|
|
29
|
+
async function generateSingleSchema(run: CliRun, redocly: RedoclyConfig): Promise<void> {
|
|
30
|
+
const { input, output } = run.args;
|
|
31
|
+
if (input?.includes("*")) {
|
|
32
|
+
throw cliError(
|
|
33
|
+
"CLI_GLOB_UNSUPPORTED",
|
|
34
|
+
"Globbing has been deprecated in favor of redocly.yaml’s `apis` keys. " +
|
|
35
|
+
`See ${MULTIPLE_SCHEMAS_DOCS_URL}`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
if (run.args.isCheck && !output) {
|
|
39
|
+
// Without a file there is nothing to compare: the original printed the types and passed.
|
|
40
|
+
throw cliError(
|
|
41
|
+
"CLI_CHECK_OUTPUT_MISSING",
|
|
42
|
+
"--check needs the generated file to compare with: add --output <file>.",
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const source = input ? new URL(input, run.deps.cwd) : run.deps.stdin();
|
|
46
|
+
const options = {
|
|
47
|
+
...run.args.generatorFlags,
|
|
48
|
+
...refLimitOptions(run.args, run.deps.cwd),
|
|
49
|
+
...fixOption(run.args.fix),
|
|
50
|
+
redocly,
|
|
51
|
+
silent: !output,
|
|
52
|
+
};
|
|
53
|
+
const contents = await run.deps.generate(source, options);
|
|
54
|
+
if (!output) {
|
|
55
|
+
run.deps.writeStdout(contents);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const file = resolveFileUrl(output, run.deps.cwd);
|
|
59
|
+
emitOutput(run, { source: input ?? "stdin", output, file }, contents);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function generate(run: CliRun): Promise<unknown[]> {
|
|
63
|
+
const redocly = await loadRedoclyConfig(run);
|
|
64
|
+
if (!hasRedoclyApis(redocly)) {
|
|
65
|
+
await generateSingleSchema(run, redocly);
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
if (run.args.input) {
|
|
69
|
+
run.deps.logger.warn(
|
|
70
|
+
"APIs are specified both in Redocly Config and CLI argument. Only using Redocly config.",
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return generateRedoclyApis(run, redocly);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Run the command; the failures it returns did not stop the other outputs. */
|
|
77
|
+
async function runCommand(argv: readonly string[], deps: CliDependencies): Promise<unknown[]> {
|
|
78
|
+
const startedAt = deps.now();
|
|
79
|
+
for (const notice of ineffectiveFlagNotices(argv)) {
|
|
80
|
+
deps.console.notice(notice);
|
|
81
|
+
}
|
|
82
|
+
const args = parseCliArguments(argv);
|
|
83
|
+
for (const flag of args.unknownFlags) {
|
|
84
|
+
deps.console.notice(`Unknown flag ${flag} is ignored (see --help)`);
|
|
85
|
+
}
|
|
86
|
+
if (args.isHelp || args.isVersion) {
|
|
87
|
+
deps.console.info(args.isHelp ? HELP_TEXT : `v${deps.version}`);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
if (args.output) {
|
|
91
|
+
deps.console.info(`✨ ${deps.style.bold(`openapi-typesafe ${deps.version}`)}`);
|
|
92
|
+
}
|
|
93
|
+
return generate({ deps, args, startedAt });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Print one line per failure; the exit code is the first failure's (ADR-011). */
|
|
97
|
+
function reportFailures(failures: readonly unknown[], logger: Logger): ExitCode {
|
|
98
|
+
const reports = failures.map(describeCliFailure);
|
|
99
|
+
for (const report of reports) {
|
|
100
|
+
logger.error(report.message);
|
|
101
|
+
}
|
|
102
|
+
return reports[0]?.exitCode ?? EXIT_CODES.SUCCESS;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Run the CLI with the arguments after `node cli.js`, and return the process exit code. */
|
|
106
|
+
export async function runCli(argv: readonly string[], deps: CliDependencies): Promise<ExitCode> {
|
|
107
|
+
let failures: unknown[];
|
|
108
|
+
try {
|
|
109
|
+
failures = await runCommand(argv, deps);
|
|
110
|
+
} catch (thrown) {
|
|
111
|
+
failures = [thrown];
|
|
112
|
+
}
|
|
113
|
+
return reportFailures(failures, deps.logger);
|
|
114
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exhaustiveness guard for `switch` over a closed union: the call compiles only when every variant
|
|
3
|
+
* is handled. Reaching it at run time means a value outside the union, which is a bug, so it
|
|
4
|
+
* throws.
|
|
5
|
+
*/
|
|
6
|
+
export function assertNever(value: never): never {
|
|
7
|
+
throw new Error(`Unexpected variant: ${JSON.stringify(value)}`);
|
|
8
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI
|
|
3
|
+
* is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The
|
|
4
|
+
* `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken
|
|
5
|
+
* invariant) is a plain `Error`, not one of these.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Every error code. The set is closed: a new code must be handled by the CLI exit-code table. */
|
|
9
|
+
export const ERROR_CODES = {
|
|
10
|
+
SCHEMA_SOURCE_EMPTY: "SCHEMA_SOURCE_EMPTY",
|
|
11
|
+
SCHEMA_SOURCE_INVALID: "SCHEMA_SOURCE_INVALID",
|
|
12
|
+
SCHEMA_LOAD_FAILED: "SCHEMA_LOAD_FAILED",
|
|
13
|
+
SCHEMA_PARSE_FAILED: "SCHEMA_PARSE_FAILED",
|
|
14
|
+
SCHEMA_VERSION_UNSUPPORTED: "SCHEMA_VERSION_UNSUPPORTED",
|
|
15
|
+
SCHEMA_INVALID: "SCHEMA_INVALID",
|
|
16
|
+
SCHEMA_REF_INVALID: "SCHEMA_REF_INVALID",
|
|
17
|
+
SCHEMA_REF_FORBIDDEN: "SCHEMA_REF_FORBIDDEN",
|
|
18
|
+
SCHEMA_OBJECT_INVALID: "SCHEMA_OBJECT_INVALID",
|
|
19
|
+
SCHEMA_PROPERTY_INVALID: "SCHEMA_PROPERTY_INVALID",
|
|
20
|
+
SCHEMA_TOO_DEEP: "SCHEMA_TOO_DEEP",
|
|
21
|
+
SCHEMA_KEY_UNSUPPORTED: "SCHEMA_KEY_UNSUPPORTED",
|
|
22
|
+
ENUM_NAME_EMPTY: "ENUM_NAME_EMPTY",
|
|
23
|
+
CALLBACK_RESULT_UNREADABLE: "CALLBACK_RESULT_UNREADABLE",
|
|
24
|
+
OPTION_FIX_UNKNOWN: "OPTION_FIX_UNKNOWN",
|
|
25
|
+
TYPESCRIPT_NOT_FOUND: "TYPESCRIPT_NOT_FOUND",
|
|
26
|
+
CLI_FLAG_REMOVED: "CLI_FLAG_REMOVED",
|
|
27
|
+
CLI_GLOB_UNSUPPORTED: "CLI_GLOB_UNSUPPORTED",
|
|
28
|
+
CLI_CONFIG_NOT_FOUND: "CLI_CONFIG_NOT_FOUND",
|
|
29
|
+
CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING",
|
|
30
|
+
CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING",
|
|
31
|
+
OUTPUT_STALE: "OUTPUT_STALE",
|
|
32
|
+
OUTPUT_READ_FAILED: "OUTPUT_READ_FAILED",
|
|
33
|
+
OUTPUT_WRITE_FAILED: "OUTPUT_WRITE_FAILED",
|
|
34
|
+
} as const;
|
|
35
|
+
|
|
36
|
+
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
37
|
+
|
|
38
|
+
/** Structured, JSON-serializable facts about a failure, for programs and logs. */
|
|
39
|
+
export type ErrorDetails = Readonly<Record<string, unknown>>;
|
|
40
|
+
|
|
41
|
+
export interface OpenAPITypesafeErrorInit {
|
|
42
|
+
readonly code: ErrorCode;
|
|
43
|
+
readonly message: string;
|
|
44
|
+
readonly details?: ErrorDetails;
|
|
45
|
+
/** The lower-level error this one reports, if any (kept as the standard `cause`). */
|
|
46
|
+
readonly cause?: unknown;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The base of every expected failure; check `code`, not the class or the message. */
|
|
50
|
+
export class OpenAPITypesafeError extends Error {
|
|
51
|
+
readonly code: ErrorCode;
|
|
52
|
+
readonly details: ErrorDetails;
|
|
53
|
+
|
|
54
|
+
constructor(init: OpenAPITypesafeErrorInit) {
|
|
55
|
+
super(init.message, init.cause === undefined ? undefined : { cause: init.cause });
|
|
56
|
+
this.name = "OpenAPITypesafeError";
|
|
57
|
+
this.code = init.code;
|
|
58
|
+
this.details = init.details ?? {};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */
|
|
63
|
+
export function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {
|
|
64
|
+
if (value instanceof OpenAPITypesafeError) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const code = (value as { code?: unknown } | null)?.code;
|
|
68
|
+
return (
|
|
69
|
+
value instanceof Error &&
|
|
70
|
+
typeof code === "string" &&
|
|
71
|
+
Object.hasOwn(ERROR_CODES, code) &&
|
|
72
|
+
typeof (value as { details?: unknown }).details === "object"
|
|
73
|
+
);
|
|
74
|
+
}
|