openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.2
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/README.md +12 -5
- package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
- package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
- package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +34 -11
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +33 -10
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +5 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
- package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
- package/dist/api/default-ports.cjs +9 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +8 -1
- package/dist/api/default-ports.mjs.map +1 -1
- 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 +25 -0
- package/dist/api/discriminator-enum.cjs.map +1 -1
- package/dist/api/discriminator-enum.mjs +25 -1
- package/dist/api/discriminator-enum.mjs.map +1 -1
- 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 +92 -0
- package/dist/api/discriminator-patch.cjs.map +1 -0
- package/dist/api/discriminator-patch.mjs +86 -0
- package/dist/api/discriminator-patch.mjs.map +1 -0
- package/dist/api/discriminator-scan.cjs +50 -65
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +44 -59
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-refs.cjs +15 -12
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +15 -12
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +21 -4
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +22 -5
- package/dist/api/document-run.mjs.map +1 -1
- 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-sink.cjs +25 -2
- package/dist/api/footer-sink.cjs.map +1 -1
- package/dist/api/footer-sink.mjs +25 -2
- package/dist/api/footer-sink.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +4 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +4 -1
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/legacy-ts-helpers.cjs.map +1 -1
- package/dist/api/legacy-ts-helpers.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +2 -1
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +3 -2
- package/dist/api/openapi-ts.mjs.map +1 -1
- 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/transform-context.cjs +4 -2
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +4 -2
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +52 -3
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +53 -4
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.cjs +6 -1
- package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
- package/dist/api/unsupported-feature-warnings.mjs +6 -1
- package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
- package/dist/application/print/type-printer.cjs +7 -1
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +7 -1
- package/dist/application/print/type-printer.mjs.map +1 -1
- 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 +2 -2
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +4 -4
- package/dist/application/transform/document/components.mjs.map +1 -1
- 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/document.cjs +32 -9
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +34 -11
- package/dist/application/transform/document/document.mjs.map +1 -1
- 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/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/parameters.cjs +41 -9
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +42 -10
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
- package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
- package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
- 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.cjs +55 -29
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +54 -30
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.cjs +15 -14
- package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
- package/dist/application/transform/document/root-type-aliases.mjs +15 -13
- package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
- 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/footer/document-footer.cjs +66 -4
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +67 -5
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.cjs +17 -0
- package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
- package/dist/application/transform/footer/enum-naming.mjs +17 -1
- package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
- 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 +42 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/evaluation.mjs +33 -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 +138 -0
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
- package/dist/application/transform/footer/type-evaluation.mjs +136 -0
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.cjs +107 -0
- package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.mjs +105 -0
- package/dist/application/transform/footer/type-indexing.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/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 +7 -2
- package/dist/application/transform/ref-type.cjs.map +1 -1
- package/dist/application/transform/ref-type.mjs +3 -2
- package/dist/application/transform/ref-type.mjs.map +1 -1
- 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 +32 -1
- package/dist/application/transform/schema/array-type.cjs.map +1 -1
- package/dist/application/transform/schema/array-type.mjs +33 -2
- package/dist/application/transform/schema/array-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +50 -15
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +50 -15
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/core-type.cjs +3 -1
- package/dist/application/transform/schema/core-type.cjs.map +1 -1
- package/dist/application/transform/schema/core-type.mjs +3 -1
- package/dist/application/transform/schema/core-type.mjs.map +1 -1
- 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 +3 -2
- package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
- package/dist/application/transform/schema/discriminator-property.mjs +3 -2
- package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +66 -10
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +67 -12
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- 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 +38 -25
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +39 -27
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- 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 +2 -2
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +2 -2
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +51 -5
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +50 -6
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/application/transform/type-combinators.mjs +1 -1
- package/dist/cli/api-settings.cjs +78 -0
- package/dist/cli/api-settings.cjs.map +1 -0
- package/dist/cli/api-settings.mjs +73 -0
- package/dist/cli/api-settings.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +12 -3
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +12 -4
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/cli-errors.cjs +3 -2
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +3 -2
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-output.cjs +8 -3
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +9 -4
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/help-text.cjs +3 -3
- package/dist/cli/help-text.cjs.map +1 -1
- package/dist/cli/help-text.mjs +3 -3
- package/dist/cli/help-text.mjs.map +1 -1
- package/dist/cli/main.cjs +5 -0
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +5 -0
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +15 -7
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +15 -7
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/ref-limits.cjs +1 -1
- package/dist/cli/ref-limits.cjs.map +1 -1
- package/dist/cli/ref-limits.mjs +2 -2
- package/dist/cli/ref-limits.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +20 -3
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +21 -4
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/errors.cjs +6 -1
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +6 -1
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +7 -1
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +6 -2
- package/dist/domain/ir/constructors.mjs.map +1 -1
- 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/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/parameter-object.cjs.map +1 -1
- package/dist/domain/openapi/parameter-object.mjs.map +1 -1
- 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/output-fixes.cjs +36 -1
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +36 -1
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/url-credentials.cjs +10 -0
- package/dist/domain/url-credentials.cjs.map +1 -0
- package/dist/domain/url-credentials.mjs +8 -0
- package/dist/domain/url-credentials.mjs.map +1 -0
- package/dist/domain/warnings.cjs +23 -0
- package/dist/domain/warnings.cjs.map +1 -0
- package/dist/domain/warnings.mjs +20 -0
- package/dist/domain/warnings.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1182 -46
- package/dist/index.d.mts +1182 -46
- package/dist/index.d.ts +1182 -46
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/transform/components-object.cjs +2 -1
- package/dist/transform/components-object.cjs.map +1 -1
- package/dist/transform/components-object.mjs +2 -1
- package/dist/transform/components-object.mjs.map +1 -1
- package/dist/transform/path-item-object.cjs.map +1 -1
- package/dist/transform/path-item-object.mjs.map +1 -1
- package/package.json +6 -5
- package/src/adapters/redocly-loader/configured-headers.ts +65 -0
- package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +44 -13
- package/src/adapters/redocly-loader/ref-access.ts +60 -5
- package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
- package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
- package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
- package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
- package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +5 -1
- package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
- package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
- package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
- package/src/api/default-ports.ts +16 -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 +39 -0
- package/src/api/discriminator-other-owners.ts +97 -0
- package/src/api/discriminator-patch.ts +152 -0
- package/src/api/discriminator-scan.ts +78 -90
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +32 -11
- package/src/api/enum-values-warnings.ts +21 -0
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +7 -3
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +2 -0
- package/src/api/path-template-warnings.ts +27 -0
- package/src/api/run-context.ts +34 -0
- package/src/api/transform-context.ts +17 -9
- package/src/api/transform-schema.ts +90 -5
- package/src/api/unsupported-feature-warnings.ts +8 -1
- package/src/application/ports/redocly-config-source.ts +5 -1
- package/src/application/print/type-printer.ts +8 -1
- package/src/application/transform/document/assignability.ts +203 -0
- package/src/application/transform/document/components.ts +6 -6
- package/src/application/transform/document/declared-types.ts +93 -0
- package/src/application/transform/document/document.ts +71 -13
- 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/list-assignability.ts +87 -0
- package/src/application/transform/document/parameters.ts +78 -12
- package/src/application/transform/document/path-key-overlaps.ts +148 -59
- package/src/application/transform/document/path-template-replace.ts +90 -0
- package/src/application/transform/document/paths.ts +101 -38
- package/src/application/transform/document/root-type-aliases.ts +29 -28
- 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/footer/document-footer.ts +91 -6
- package/src/application/transform/footer/enum-naming.ts +29 -0
- package/src/application/transform/footer/enum-values-check.ts +171 -0
- package/src/application/transform/footer/evaluation.ts +57 -0
- package/src/application/transform/footer/shared-enum-names.ts +86 -0
- package/src/application/transform/footer/type-evaluation.ts +167 -0
- package/src/application/transform/footer/type-indexing.ts +152 -0
- package/src/application/transform/footer/type-rules.ts +269 -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 +11 -6
- package/src/application/transform/schema/access-flags.ts +63 -0
- package/src/application/transform/schema/array-type.ts +66 -5
- package/src/application/transform/schema/composition-type.ts +96 -24
- package/src/application/transform/schema/core-type.ts +8 -4
- package/src/application/transform/schema/discriminated-union.ts +58 -0
- package/src/application/transform/schema/discriminator-property.ts +8 -3
- package/src/application/transform/schema/enum-rule.ts +136 -13
- package/src/application/transform/schema/inherited-discriminator.ts +54 -0
- package/src/application/transform/schema/object-type.ts +51 -33
- package/src/application/transform/schema/required-variants.ts +88 -0
- package/src/application/transform/schema/schema-context.ts +26 -0
- package/src/application/transform/schema/schema-transform.ts +2 -2
- package/src/application/transform/schema-comment.ts +84 -4
- package/src/cli/api-settings.ts +109 -0
- package/src/cli/cli-arguments.ts +18 -5
- package/src/cli/cli-dependencies.ts +5 -0
- package/src/cli/cli-errors.ts +4 -2
- package/src/cli/cli-output.ts +18 -4
- package/src/cli/help-text.ts +4 -4
- package/src/cli/main.ts +6 -0
- package/src/cli/redocly-apis.ts +21 -11
- package/src/cli/ref-limits.ts +2 -2
- package/src/cli/run-cli.ts +25 -4
- package/src/domain/errors.ts +10 -2
- package/src/domain/ir/constructors.ts +9 -1
- package/src/domain/ir/nodes.ts +11 -7
- package/src/domain/openapi/admitted-values.ts +113 -0
- package/src/domain/openapi/discriminated-union.ts +109 -0
- package/src/domain/openapi/discriminator-conflicts.ts +251 -0
- package/src/domain/openapi/parameter-object.ts +4 -0
- package/src/domain/openapi/path-templates.ts +32 -0
- package/src/domain/openapi/schema-object.ts +2 -0
- package/src/domain/output-fixes.ts +43 -2
- package/src/domain/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +28 -0
- package/src/index.ts +1 -0
- package/src/transform/components-object.ts +3 -1
- package/src/transform/path-item-object.ts +6 -2
- package/src/types/generator-options.ts +12 -21
- package/src/types/openapi-common.ts +1 -0
- package/src/types/openapi-request.ts +3 -0
- package/src/types/openapi-schema.ts +2 -0
- package/src/types/openapi-security.ts +1 -0
- package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
- package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
- package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
- package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
- package/src/application/transform/document/path-item-conflicts.ts +0 -79
package/README.md
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# openapi-typesafe
|
|
2
2
|
|
|
3
|
-
Generate TypeScript types from [OpenAPI 3.0 and 3.
|
|
3
|
+
Generate TypeScript types from [OpenAPI 3.0, 3.1 and 3.2](https://spec.openapis.org/oas/latest.html) schemas.
|
|
4
4
|
Runs on Node.js; no Java, no running server, no runtime code in the output.
|
|
5
5
|
|
|
6
6
|
A maintained, drop-in successor to `openapi-typescript` (see the [repository README](../../README.md)).
|
|
7
7
|
|
|
8
|
-
> **
|
|
8
|
+
> **Release candidate.** The current version is a 1.0.0 release candidate (`1.0.0-rc.N`);
|
|
9
|
+
> names and output can still change before 1.0.0.
|
|
9
10
|
|
|
10
11
|
## Features
|
|
11
12
|
|
|
12
|
-
- OpenAPI 3.0 and 3.
|
|
13
|
+
- OpenAPI 3.0, 3.1 and 3.2, including discriminators, `oneOf` / `anyOf` / `allOf`, and `$ref` across files.
|
|
13
14
|
- Runtime-free output: only types.
|
|
14
15
|
- Local or remote schemas, YAML or JSON.
|
|
15
16
|
- Swagger 2.0 is not supported.
|
|
16
17
|
|
|
17
18
|
## Setup
|
|
18
19
|
|
|
19
|
-
Requires Node.js 22 or newer.
|
|
20
|
+
Requires Node.js 22.12 or newer. TypeScript 5.4 or newer, including 6 and 7, type-checks the output.
|
|
20
21
|
|
|
21
22
|
```sh
|
|
22
23
|
npm i -D openapi-typesafe typescript
|
|
@@ -59,7 +60,7 @@ Run `npx openapi-typesafe --help` for all options. Generated examples for real A
|
|
|
59
60
|
|
|
60
61
|
## Migrating from openapi-typescript
|
|
61
62
|
|
|
62
|
-
Replace the package and the binary name; options and
|
|
63
|
+
Replace the package and the binary name; the options and the types are the same.
|
|
63
64
|
|
|
64
65
|
```diff
|
|
65
66
|
- npx openapi-typescript ./schema.yaml -o ./schema.d.ts
|
|
@@ -68,6 +69,12 @@ Replace the package and the binary name; options and output are the same.
|
|
|
68
69
|
|
|
69
70
|
The header of generated files names the new generator, so regenerate and commit the output once.
|
|
70
71
|
|
|
72
|
+
## Versioning
|
|
73
|
+
|
|
74
|
+
Semantic versioning from 1.0.0, with one version for all openapi-typesafe packages. What the
|
|
75
|
+
version promises, and what may grow in a minor release, is listed under
|
|
76
|
+
[Versioning](https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/compatibility.md#versioning).
|
|
77
|
+
|
|
71
78
|
## License
|
|
72
79
|
|
|
73
80
|
[MIT](./LICENSE)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const openapiCore = require('@redocly/openapi-core');
|
|
4
|
+
|
|
5
|
+
const EXPLICIT_HTTP_PATTERN = /^http:\/\//;
|
|
6
|
+
const LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "[::1]"]);
|
|
7
|
+
const LOOPBACK_IPV4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
8
|
+
function isLoopback(url) {
|
|
9
|
+
return LOOPBACK_HOSTNAMES.has(url.hostname) || LOOPBACK_IPV4.test(url.hostname);
|
|
10
|
+
}
|
|
11
|
+
function isProtocolAllowed(header, url) {
|
|
12
|
+
return url.protocol === "https:" || url.protocol === "http:" && isLoopback(url) || EXPLICIT_HTTP_PATTERN.test(header.matches);
|
|
13
|
+
}
|
|
14
|
+
function matchedText(url) {
|
|
15
|
+
return `${url.protocol}//${url.host}${url.pathname}`;
|
|
16
|
+
}
|
|
17
|
+
async function headersFor(url, configured) {
|
|
18
|
+
const candidates = configured.filter((header) => isProtocolAllowed(header, url));
|
|
19
|
+
let selected = {};
|
|
20
|
+
if (candidates.length === 0) {
|
|
21
|
+
return selected;
|
|
22
|
+
}
|
|
23
|
+
const recordHeaders = async (_input, init) => {
|
|
24
|
+
selected = init.headers;
|
|
25
|
+
return new Response("");
|
|
26
|
+
};
|
|
27
|
+
await openapiCore.readFileFromUrl(matchedText(url), { headers: [...candidates], customFetch: recordHeaders });
|
|
28
|
+
return selected;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exports.headersFor = headersFor;
|
|
32
|
+
//# sourceMappingURL=configured-headers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configured-headers.cjs","sources":["../../../src/adapters/redocly-loader/configured-headers.ts"],"sourcesContent":["import { type Config as RedoclyConfig, readFileFromUrl } from \"@redocly/openapi-core\";\n\n/**\n * Which `resolve.http.headers` of the Redocly config go with a request (threat model T4a). The\n * headers often carry credentials, so they are chosen again for every request and every redirect,\n * from the parsed URL, and never sent over plain HTTP to another machine unless the pattern asks\n * for it.\n */\n\n/** One `resolve.http.headers` entry: a name, a value or an environment variable, a pattern. */\nexport type ConfiguredHeader = RedoclyConfig[\"resolve\"][\"http\"][\"headers\"][number];\n\n/** Redocly matches the protocol only when the pattern starts with one; the same test. */\nconst EXPLICIT_HTTP_PATTERN = /^http:\\/\\//;\n\n/** Hosts that never leave the machine: plain HTTP to them cannot be read on the network. */\nconst LOOPBACK_HOSTNAMES: ReadonlySet<string> = new Set([\"localhost\", \"[::1]\"]);\n// The URL parser has already turned every IPv4 form (`2130706433`, `0x7f.1`) into dotted decimal.\nconst LOOPBACK_IPV4 = /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/;\n\nfunction isLoopback(url: URL): boolean {\n return LOOPBACK_HOSTNAMES.has(url.hostname) || LOOPBACK_IPV4.test(url.hostname);\n}\n\n/**\n * A header goes over HTTPS, over HTTP to this machine (a local dev server), or over HTTP to\n * another machine when its pattern names `http://` itself.\n */\nfunction isProtocolAllowed(header: ConfiguredHeader, url: URL): boolean {\n return (\n url.protocol === \"https:\" ||\n (url.protocol === \"http:\" && isLoopback(url)) ||\n EXPLICIT_HTTP_PATTERN.test(header.matches)\n );\n}\n\n/**\n * The URL as a pattern sees it: protocol, host and path. User info, query and fragment are left\n * out, so a `*` in the pattern cannot match across `?`, `#` or `@` into another host's URL.\n */\nfunction matchedText(url: URL): string {\n return `${url.protocol}//${url.host}${url.pathname}`;\n}\n\n/**\n * The headers configured for this URL. The patterns are matched by Redocly's own matcher, which\n * also reads `envVariable` values, so a pattern means here what it means in Redocly; its fetch\n * only records the headers it would send and sends nothing.\n */\nexport async function headersFor(\n url: URL,\n configured: readonly ConfiguredHeader[],\n): Promise<Record<string, string>> {\n const candidates = configured.filter((header) => isProtocolAllowed(header, url));\n let selected: Record<string, string> = {};\n if (candidates.length === 0) {\n return selected;\n }\n const recordHeaders = async (_input: string, init: { headers: Record<string, string> }) => {\n selected = init.headers;\n return new Response(\"\");\n };\n await readFileFromUrl(matchedText(url), { headers: [...candidates], customFetch: recordHeaders });\n return selected;\n}\n"],"names":["readFileFromUrl"],"mappings":";;;;AAaA,MAAM,qBAAA,GAAwB,YAAA;AAG9B,MAAM,qCAA0C,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,OAAO,CAAC,CAAA;AAE9E,MAAM,aAAA,GAAgB,kCAAA;AAEtB,SAAS,WAAW,GAAA,EAAmB;AACrC,EAAA,OAAO,kBAAA,CAAmB,IAAI,GAAA,CAAI,QAAQ,KAAK,aAAA,CAAc,IAAA,CAAK,IAAI,QAAQ,CAAA;AAChF;AAMA,SAAS,iBAAA,CAAkB,QAA0B,GAAA,EAAmB;AACtE,EAAA,OACE,GAAA,CAAI,QAAA,KAAa,QAAA,IAChB,GAAA,CAAI,QAAA,KAAa,OAAA,IAAW,UAAA,CAAW,GAAG,CAAA,IAC3C,qBAAA,CAAsB,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA;AAE7C;AAMA,SAAS,YAAY,GAAA,EAAkB;AACrC,EAAA,OAAO,CAAA,EAAG,IAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,EAAG,IAAI,QAAQ,CAAA,CAAA;AACpD;AAOA,eAAsB,UAAA,CACpB,KACA,UAAA,EACiC;AACjC,EAAA,MAAM,UAAA,GAAa,WAAW,MAAA,CAAO,CAAC,WAAW,iBAAA,CAAkB,MAAA,EAAQ,GAAG,CAAC,CAAA;AAC/E,EAAA,IAAI,WAAmC,EAAC;AACxC,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,aAAA,GAAgB,OAAO,MAAA,EAAgB,IAAA,KAA8C;AACzF,IAAA,QAAA,GAAW,IAAA,CAAK,OAAA;AAChB,IAAA,OAAO,IAAI,SAAS,EAAE,CAAA;AAAA,EACxB,CAAA;AACA,EAAA,MAAMA,2BAAA,CAAgB,WAAA,CAAY,GAAG,CAAA,EAAG,EAAE,OAAA,EAAS,CAAC,GAAG,UAAU,CAAA,EAAG,WAAA,EAAa,aAAA,EAAe,CAAA;AAChG,EAAA,OAAO,QAAA;AACT;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { readFileFromUrl } from '@redocly/openapi-core';
|
|
2
|
+
|
|
3
|
+
const EXPLICIT_HTTP_PATTERN = /^http:\/\//;
|
|
4
|
+
const LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "[::1]"]);
|
|
5
|
+
const LOOPBACK_IPV4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
6
|
+
function isLoopback(url) {
|
|
7
|
+
return LOOPBACK_HOSTNAMES.has(url.hostname) || LOOPBACK_IPV4.test(url.hostname);
|
|
8
|
+
}
|
|
9
|
+
function isProtocolAllowed(header, url) {
|
|
10
|
+
return url.protocol === "https:" || url.protocol === "http:" && isLoopback(url) || EXPLICIT_HTTP_PATTERN.test(header.matches);
|
|
11
|
+
}
|
|
12
|
+
function matchedText(url) {
|
|
13
|
+
return `${url.protocol}//${url.host}${url.pathname}`;
|
|
14
|
+
}
|
|
15
|
+
async function headersFor(url, configured) {
|
|
16
|
+
const candidates = configured.filter((header) => isProtocolAllowed(header, url));
|
|
17
|
+
let selected = {};
|
|
18
|
+
if (candidates.length === 0) {
|
|
19
|
+
return selected;
|
|
20
|
+
}
|
|
21
|
+
const recordHeaders = async (_input, init) => {
|
|
22
|
+
selected = init.headers;
|
|
23
|
+
return new Response("");
|
|
24
|
+
};
|
|
25
|
+
await readFileFromUrl(matchedText(url), { headers: [...candidates], customFetch: recordHeaders });
|
|
26
|
+
return selected;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { headersFor };
|
|
30
|
+
//# sourceMappingURL=configured-headers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configured-headers.mjs","sources":["../../../src/adapters/redocly-loader/configured-headers.ts"],"sourcesContent":["import { type Config as RedoclyConfig, readFileFromUrl } from \"@redocly/openapi-core\";\n\n/**\n * Which `resolve.http.headers` of the Redocly config go with a request (threat model T4a). The\n * headers often carry credentials, so they are chosen again for every request and every redirect,\n * from the parsed URL, and never sent over plain HTTP to another machine unless the pattern asks\n * for it.\n */\n\n/** One `resolve.http.headers` entry: a name, a value or an environment variable, a pattern. */\nexport type ConfiguredHeader = RedoclyConfig[\"resolve\"][\"http\"][\"headers\"][number];\n\n/** Redocly matches the protocol only when the pattern starts with one; the same test. */\nconst EXPLICIT_HTTP_PATTERN = /^http:\\/\\//;\n\n/** Hosts that never leave the machine: plain HTTP to them cannot be read on the network. */\nconst LOOPBACK_HOSTNAMES: ReadonlySet<string> = new Set([\"localhost\", \"[::1]\"]);\n// The URL parser has already turned every IPv4 form (`2130706433`, `0x7f.1`) into dotted decimal.\nconst LOOPBACK_IPV4 = /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/;\n\nfunction isLoopback(url: URL): boolean {\n return LOOPBACK_HOSTNAMES.has(url.hostname) || LOOPBACK_IPV4.test(url.hostname);\n}\n\n/**\n * A header goes over HTTPS, over HTTP to this machine (a local dev server), or over HTTP to\n * another machine when its pattern names `http://` itself.\n */\nfunction isProtocolAllowed(header: ConfiguredHeader, url: URL): boolean {\n return (\n url.protocol === \"https:\" ||\n (url.protocol === \"http:\" && isLoopback(url)) ||\n EXPLICIT_HTTP_PATTERN.test(header.matches)\n );\n}\n\n/**\n * The URL as a pattern sees it: protocol, host and path. User info, query and fragment are left\n * out, so a `*` in the pattern cannot match across `?`, `#` or `@` into another host's URL.\n */\nfunction matchedText(url: URL): string {\n return `${url.protocol}//${url.host}${url.pathname}`;\n}\n\n/**\n * The headers configured for this URL. The patterns are matched by Redocly's own matcher, which\n * also reads `envVariable` values, so a pattern means here what it means in Redocly; its fetch\n * only records the headers it would send and sends nothing.\n */\nexport async function headersFor(\n url: URL,\n configured: readonly ConfiguredHeader[],\n): Promise<Record<string, string>> {\n const candidates = configured.filter((header) => isProtocolAllowed(header, url));\n let selected: Record<string, string> = {};\n if (candidates.length === 0) {\n return selected;\n }\n const recordHeaders = async (_input: string, init: { headers: Record<string, string> }) => {\n selected = init.headers;\n return new Response(\"\");\n };\n await readFileFromUrl(matchedText(url), { headers: [...candidates], customFetch: recordHeaders });\n return selected;\n}\n"],"names":[],"mappings":";;AAaA,MAAM,qBAAA,GAAwB,YAAA;AAG9B,MAAM,qCAA0C,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,OAAO,CAAC,CAAA;AAE9E,MAAM,aAAA,GAAgB,kCAAA;AAEtB,SAAS,WAAW,GAAA,EAAmB;AACrC,EAAA,OAAO,kBAAA,CAAmB,IAAI,GAAA,CAAI,QAAQ,KAAK,aAAA,CAAc,IAAA,CAAK,IAAI,QAAQ,CAAA;AAChF;AAMA,SAAS,iBAAA,CAAkB,QAA0B,GAAA,EAAmB;AACtE,EAAA,OACE,GAAA,CAAI,QAAA,KAAa,QAAA,IAChB,GAAA,CAAI,QAAA,KAAa,OAAA,IAAW,UAAA,CAAW,GAAG,CAAA,IAC3C,qBAAA,CAAsB,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA;AAE7C;AAMA,SAAS,YAAY,GAAA,EAAkB;AACrC,EAAA,OAAO,CAAA,EAAG,IAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,EAAG,IAAI,QAAQ,CAAA,CAAA;AACpD;AAOA,eAAsB,UAAA,CACpB,KACA,UAAA,EACiC;AACjC,EAAA,MAAM,UAAA,GAAa,WAAW,MAAA,CAAO,CAAC,WAAW,iBAAA,CAAkB,MAAA,EAAQ,GAAG,CAAC,CAAA;AAC/E,EAAA,IAAI,WAAmC,EAAC;AACxC,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,aAAA,GAAgB,OAAO,MAAA,EAAgB,IAAA,KAA8C;AACzF,IAAA,QAAA,GAAW,IAAA,CAAK,OAAA;AAChB,IAAA,OAAO,IAAI,SAAS,EAAE,CAAA;AAAA,EACxB,CAAA;AACA,EAAA,MAAM,eAAA,CAAgB,WAAA,CAAY,GAAG,CAAA,EAAG,EAAE,OAAA,EAAS,CAAC,GAAG,UAAU,CAAA,EAAG,WAAA,EAAa,aAAA,EAAe,CAAA;AAChG,EAAA,OAAO,QAAA;AACT;;"}
|
|
@@ -3,12 +3,30 @@
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const openapiCore = require('@redocly/openapi-core');
|
|
6
|
+
const errors = require('../../domain/errors.cjs');
|
|
6
7
|
|
|
7
8
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
8
9
|
|
|
9
10
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
10
11
|
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
11
12
|
|
|
13
|
+
function reasonOf(error) {
|
|
14
|
+
return String(error).replace(/\n[\s\S]*$/, "");
|
|
15
|
+
}
|
|
16
|
+
async function loadedConfig(load, configPath) {
|
|
17
|
+
try {
|
|
18
|
+
return await load();
|
|
19
|
+
} catch (error) {
|
|
20
|
+
const config = configPath === void 0 ? "the default Redocly config" : `the Redocly config ${configPath}`;
|
|
21
|
+
const where = configPath === void 0 ? "in the working directory" : "next to it";
|
|
22
|
+
throw new errors.OpenAPITypesafeError({
|
|
23
|
+
code: errors.ERROR_CODES.CLI_CONFIG_INVALID,
|
|
24
|
+
message: `Cannot load ${config} or the ${openapiCore.IGNORE_FILE} ${where}: ${reasonOf(error)}`,
|
|
25
|
+
details: { configPath },
|
|
26
|
+
cause: error
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
12
30
|
class RedoclyConfigFiles {
|
|
13
31
|
#cwd;
|
|
14
32
|
constructor(cwd) {
|
|
@@ -25,13 +43,14 @@ class RedoclyConfigFiles {
|
|
|
25
43
|
return fs__default.statSync(resolved).isDirectory() ? openapiCore.findConfig(resolved) : resolved;
|
|
26
44
|
}
|
|
27
45
|
load(configPath) {
|
|
28
|
-
return openapiCore.loadConfig({ configPath });
|
|
46
|
+
return loadedConfig(() => openapiCore.loadConfig({ configPath }), configPath);
|
|
29
47
|
}
|
|
30
48
|
createDefault() {
|
|
31
|
-
|
|
49
|
+
const create = () => openapiCore.createConfig(
|
|
32
50
|
{ rules: { "operation-operationId-unique": { severity: "warn" } } },
|
|
33
51
|
{ extends: ["minimal"] }
|
|
34
52
|
);
|
|
53
|
+
return loadedConfig(create, void 0);
|
|
35
54
|
}
|
|
36
55
|
}
|
|
37
56
|
function createRedoclyConfigSource(cwd) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redocly-config-source.cjs","sources":["../../../src/adapters/redocly-loader/redocly-config-source.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createConfig, findConfig, loadConfig } from \"@redocly/openapi-core\";\nimport type {\n RedoclyConfig,\n RedoclyConfigSource,\n} from \"../../application/ports/redocly-config-source.js\";\n\n/** The Redocly config port on `@redocly/openapi-core`, resolving paths from `cwd`. */\nclass RedoclyConfigFiles implements RedoclyConfigSource {\n readonly #cwd: string;\n\n constructor(cwd: string) {\n this.#cwd = cwd;\n }\n\n find(explicitPath: string | undefined): string | undefined {\n if (!explicitPath) {\n return findConfig(this.#cwd);\n }\n const resolved = path.resolve(this.#cwd, explicitPath);\n if (!fs.existsSync(resolved)) {\n return undefined;\n }\n return fs.statSync(resolved).isDirectory() ? findConfig(resolved) : resolved;\n }\n\n load(configPath: string): Promise<RedoclyConfig> {\n return loadConfig({ configPath });\n }\n\n createDefault(): Promise<RedoclyConfig> {\n
|
|
1
|
+
{"version":3,"file":"redocly-config-source.cjs","sources":["../../../src/adapters/redocly-loader/redocly-config-source.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createConfig, findConfig, IGNORE_FILE, loadConfig } from \"@redocly/openapi-core\";\nimport type {\n RedoclyConfig,\n RedoclyConfigSource,\n} from \"../../application/ports/redocly-config-source.js\";\nimport { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * The first line of a failure, with the error's name: a YAML error goes on with a snippet of the\n * file, and the name tells a YAML error from a file system one.\n */\nfunction reasonOf(error: unknown): string {\n return String(error).replace(/\\n[\\s\\S]*$/, \"\");\n}\n\n/**\n * The config, or `CLI_CONFIG_INVALID`. Redocly reads the config file and the lint-ignore file\n * next to it (or in the working directory); either can be malformed, and its error does not\n * always name the file, so the message names both.\n */\nasync function loadedConfig(\n load: () => Promise<RedoclyConfig>,\n configPath: string | undefined,\n): Promise<RedoclyConfig> {\n try {\n return await load();\n } catch (error) {\n const config =\n configPath === undefined ? \"the default Redocly config\" : `the Redocly config ${configPath}`;\n const where = configPath === undefined ? \"in the working directory\" : \"next to it\";\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.CLI_CONFIG_INVALID,\n message: `Cannot load ${config} or the ${IGNORE_FILE} ${where}: ${reasonOf(error)}`,\n details: { configPath },\n cause: error,\n });\n }\n}\n\n/** The Redocly config port on `@redocly/openapi-core`, resolving paths from `cwd`. */\nclass RedoclyConfigFiles implements RedoclyConfigSource {\n readonly #cwd: string;\n\n constructor(cwd: string) {\n this.#cwd = cwd;\n }\n\n find(explicitPath: string | undefined): string | undefined {\n if (!explicitPath) {\n return findConfig(this.#cwd);\n }\n const resolved = path.resolve(this.#cwd, explicitPath);\n if (!fs.existsSync(resolved)) {\n return undefined;\n }\n return fs.statSync(resolved).isDirectory() ? findConfig(resolved) : resolved;\n }\n\n load(configPath: string): Promise<RedoclyConfig> {\n return loadedConfig(() => loadConfig({ configPath }), configPath);\n }\n\n createDefault(): Promise<RedoclyConfig> {\n const create = () =>\n createConfig(\n { rules: { \"operation-operationId-unique\": { severity: \"warn\" } } },\n { extends: [\"minimal\"] },\n );\n return loadedConfig(create, undefined);\n }\n}\n\n/** Find and load `redocly.yaml` relative to the directory `cwd`. */\nexport function createRedoclyConfigSource(cwd: string): RedoclyConfigSource {\n return new RedoclyConfigFiles(cwd);\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES","IGNORE_FILE","findConfig","path","fs","loadConfig","createConfig"],"mappings":";;;;;;;;;;;;AAaA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,OAAO,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,cAAc,EAAE,CAAA;AAC/C;AAOA,eAAe,YAAA,CACb,MACA,UAAA,EACwB;AACxB,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,MAAA,GACJ,UAAA,KAAe,MAAA,GAAY,4BAAA,GAA+B,sBAAsB,UAAU,CAAA,CAAA;AAC5F,IAAA,MAAM,KAAA,GAAQ,UAAA,KAAe,MAAA,GAAY,0BAAA,GAA6B,YAAA;AACtE,IAAA,MAAM,IAAIA,2BAAA,CAAqB;AAAA,MAC7B,MAAMC,kBAAA,CAAY,kBAAA;AAAA,MAClB,OAAA,EAAS,CAAA,YAAA,EAAe,MAAM,CAAA,QAAA,EAAWC,uBAAW,IAAI,KAAK,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA;AAAA,MACjF,OAAA,EAAS,EAAE,UAAA,EAAW;AAAA,MACtB,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF;AAGA,MAAM,kBAAA,CAAkD;AAAA,EAC7C,IAAA;AAAA,EAET,YAAY,GAAA,EAAa;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AAAA,EACd;AAAA,EAEA,KAAK,YAAA,EAAsD;AACzD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAOC,sBAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,MAAM,QAAA,GAAWC,aAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAM,YAAY,CAAA;AACrD,IAAA,IAAI,CAACC,WAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC5B,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAOA,WAAA,CAAG,SAAS,QAAQ,CAAA,CAAE,aAAY,GAAIF,sBAAA,CAAW,QAAQ,CAAA,GAAI,QAAA;AAAA,EACtE;AAAA,EAEA,KAAK,UAAA,EAA4C;AAC/C,IAAA,OAAO,aAAa,MAAMG,sBAAA,CAAW,EAAE,UAAA,EAAY,GAAG,UAAU,CAAA;AAAA,EAClE;AAAA,EAEA,aAAA,GAAwC;AACtC,IAAA,MAAM,SAAS,MACbC,wBAAA;AAAA,MACE,EAAE,OAAO,EAAE,8BAAA,EAAgC,EAAE,QAAA,EAAU,MAAA,IAAS,EAAE;AAAA,MAClE,EAAE,OAAA,EAAS,CAAC,SAAS,CAAA;AAAE,KACzB;AACF,IAAA,OAAO,YAAA,CAAa,QAAQ,MAAS,CAAA;AAAA,EACvC;AACF;AAGO,SAAS,0BAA0B,GAAA,EAAkC;AAC1E,EAAA,OAAO,IAAI,mBAAmB,GAAG,CAAA;AACnC;;"}
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { findConfig, loadConfig, createConfig } from '@redocly/openapi-core';
|
|
3
|
+
import { findConfig, IGNORE_FILE, loadConfig, createConfig } from '@redocly/openapi-core';
|
|
4
|
+
import { OpenAPITypesafeError, ERROR_CODES } from '../../domain/errors.mjs';
|
|
4
5
|
|
|
6
|
+
function reasonOf(error) {
|
|
7
|
+
return String(error).replace(/\n[\s\S]*$/, "");
|
|
8
|
+
}
|
|
9
|
+
async function loadedConfig(load, configPath) {
|
|
10
|
+
try {
|
|
11
|
+
return await load();
|
|
12
|
+
} catch (error) {
|
|
13
|
+
const config = configPath === void 0 ? "the default Redocly config" : `the Redocly config ${configPath}`;
|
|
14
|
+
const where = configPath === void 0 ? "in the working directory" : "next to it";
|
|
15
|
+
throw new OpenAPITypesafeError({
|
|
16
|
+
code: ERROR_CODES.CLI_CONFIG_INVALID,
|
|
17
|
+
message: `Cannot load ${config} or the ${IGNORE_FILE} ${where}: ${reasonOf(error)}`,
|
|
18
|
+
details: { configPath },
|
|
19
|
+
cause: error
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
5
23
|
class RedoclyConfigFiles {
|
|
6
24
|
#cwd;
|
|
7
25
|
constructor(cwd) {
|
|
@@ -18,13 +36,14 @@ class RedoclyConfigFiles {
|
|
|
18
36
|
return fs.statSync(resolved).isDirectory() ? findConfig(resolved) : resolved;
|
|
19
37
|
}
|
|
20
38
|
load(configPath) {
|
|
21
|
-
return loadConfig({ configPath });
|
|
39
|
+
return loadedConfig(() => loadConfig({ configPath }), configPath);
|
|
22
40
|
}
|
|
23
41
|
createDefault() {
|
|
24
|
-
|
|
42
|
+
const create = () => createConfig(
|
|
25
43
|
{ rules: { "operation-operationId-unique": { severity: "warn" } } },
|
|
26
44
|
{ extends: ["minimal"] }
|
|
27
45
|
);
|
|
46
|
+
return loadedConfig(create, void 0);
|
|
28
47
|
}
|
|
29
48
|
}
|
|
30
49
|
function createRedoclyConfigSource(cwd) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redocly-config-source.mjs","sources":["../../../src/adapters/redocly-loader/redocly-config-source.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createConfig, findConfig, loadConfig } from \"@redocly/openapi-core\";\nimport type {\n RedoclyConfig,\n RedoclyConfigSource,\n} from \"../../application/ports/redocly-config-source.js\";\n\n/** The Redocly config port on `@redocly/openapi-core`, resolving paths from `cwd`. */\nclass RedoclyConfigFiles implements RedoclyConfigSource {\n readonly #cwd: string;\n\n constructor(cwd: string) {\n this.#cwd = cwd;\n }\n\n find(explicitPath: string | undefined): string | undefined {\n if (!explicitPath) {\n return findConfig(this.#cwd);\n }\n const resolved = path.resolve(this.#cwd, explicitPath);\n if (!fs.existsSync(resolved)) {\n return undefined;\n }\n return fs.statSync(resolved).isDirectory() ? findConfig(resolved) : resolved;\n }\n\n load(configPath: string): Promise<RedoclyConfig> {\n return loadConfig({ configPath });\n }\n\n createDefault(): Promise<RedoclyConfig> {\n
|
|
1
|
+
{"version":3,"file":"redocly-config-source.mjs","sources":["../../../src/adapters/redocly-loader/redocly-config-source.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createConfig, findConfig, IGNORE_FILE, loadConfig } from \"@redocly/openapi-core\";\nimport type {\n RedoclyConfig,\n RedoclyConfigSource,\n} from \"../../application/ports/redocly-config-source.js\";\nimport { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * The first line of a failure, with the error's name: a YAML error goes on with a snippet of the\n * file, and the name tells a YAML error from a file system one.\n */\nfunction reasonOf(error: unknown): string {\n return String(error).replace(/\\n[\\s\\S]*$/, \"\");\n}\n\n/**\n * The config, or `CLI_CONFIG_INVALID`. Redocly reads the config file and the lint-ignore file\n * next to it (or in the working directory); either can be malformed, and its error does not\n * always name the file, so the message names both.\n */\nasync function loadedConfig(\n load: () => Promise<RedoclyConfig>,\n configPath: string | undefined,\n): Promise<RedoclyConfig> {\n try {\n return await load();\n } catch (error) {\n const config =\n configPath === undefined ? \"the default Redocly config\" : `the Redocly config ${configPath}`;\n const where = configPath === undefined ? \"in the working directory\" : \"next to it\";\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.CLI_CONFIG_INVALID,\n message: `Cannot load ${config} or the ${IGNORE_FILE} ${where}: ${reasonOf(error)}`,\n details: { configPath },\n cause: error,\n });\n }\n}\n\n/** The Redocly config port on `@redocly/openapi-core`, resolving paths from `cwd`. */\nclass RedoclyConfigFiles implements RedoclyConfigSource {\n readonly #cwd: string;\n\n constructor(cwd: string) {\n this.#cwd = cwd;\n }\n\n find(explicitPath: string | undefined): string | undefined {\n if (!explicitPath) {\n return findConfig(this.#cwd);\n }\n const resolved = path.resolve(this.#cwd, explicitPath);\n if (!fs.existsSync(resolved)) {\n return undefined;\n }\n return fs.statSync(resolved).isDirectory() ? findConfig(resolved) : resolved;\n }\n\n load(configPath: string): Promise<RedoclyConfig> {\n return loadedConfig(() => loadConfig({ configPath }), configPath);\n }\n\n createDefault(): Promise<RedoclyConfig> {\n const create = () =>\n createConfig(\n { rules: { \"operation-operationId-unique\": { severity: \"warn\" } } },\n { extends: [\"minimal\"] },\n );\n return loadedConfig(create, undefined);\n }\n}\n\n/** Find and load `redocly.yaml` relative to the directory `cwd`. */\nexport function createRedoclyConfigSource(cwd: string): RedoclyConfigSource {\n return new RedoclyConfigFiles(cwd);\n}\n"],"names":[],"mappings":";;;;;AAaA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,OAAO,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,cAAc,EAAE,CAAA;AAC/C;AAOA,eAAe,YAAA,CACb,MACA,UAAA,EACwB;AACxB,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,MAAA,GACJ,UAAA,KAAe,MAAA,GAAY,4BAAA,GAA+B,sBAAsB,UAAU,CAAA,CAAA;AAC5F,IAAA,MAAM,KAAA,GAAQ,UAAA,KAAe,MAAA,GAAY,0BAAA,GAA6B,YAAA;AACtE,IAAA,MAAM,IAAI,oBAAA,CAAqB;AAAA,MAC7B,MAAM,WAAA,CAAY,kBAAA;AAAA,MAClB,OAAA,EAAS,CAAA,YAAA,EAAe,MAAM,CAAA,QAAA,EAAW,WAAW,IAAI,KAAK,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,CAAC,CAAA,CAAA;AAAA,MACjF,OAAA,EAAS,EAAE,UAAA,EAAW;AAAA,MACtB,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF;AAGA,MAAM,kBAAA,CAAkD;AAAA,EAC7C,IAAA;AAAA,EAET,YAAY,GAAA,EAAa;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AAAA,EACd;AAAA,EAEA,KAAK,YAAA,EAAsD;AACzD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,MAAM,YAAY,CAAA;AACrD,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC5B,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAA,CAAG,SAAS,QAAQ,CAAA,CAAE,aAAY,GAAI,UAAA,CAAW,QAAQ,CAAA,GAAI,QAAA;AAAA,EACtE;AAAA,EAEA,KAAK,UAAA,EAA4C;AAC/C,IAAA,OAAO,aAAa,MAAM,UAAA,CAAW,EAAE,UAAA,EAAY,GAAG,UAAU,CAAA;AAAA,EAClE;AAAA,EAEA,aAAA,GAAwC;AACtC,IAAA,MAAM,SAAS,MACb,YAAA;AAAA,MACE,EAAE,OAAO,EAAE,8BAAA,EAAgC,EAAE,QAAA,EAAU,MAAA,IAAS,EAAE;AAAA,MAClE,EAAE,OAAA,EAAS,CAAC,SAAS,CAAA;AAAE,KACzB;AACF,IAAA,OAAO,YAAA,CAAa,QAAQ,MAAS,CAAA;AAAA,EACvC;AACF;AAGO,SAAS,0BAA0B,GAAA,EAAkC;AAC1E,EAAA,OAAO,IAAI,mBAAmB,GAAG,CAAA;AACnC;;"}
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
const node_url = require('node:url');
|
|
4
4
|
const openapiCore = require('@redocly/openapi-core');
|
|
5
5
|
const stackOverflow = require('../../application/stack-overflow.cjs');
|
|
6
|
+
const warnings = require('../../domain/warnings.cjs');
|
|
6
7
|
const bundledRefRepair = require('./bundled-ref-repair.cjs');
|
|
7
8
|
const malformedRefs = require('./malformed-refs.cjs');
|
|
8
9
|
const refAccess = require('./ref-access.cjs');
|
|
10
|
+
const refResolutionCheck = require('./ref-resolution-check.cjs');
|
|
11
|
+
const refResolutionSteps = require('./ref-resolution-steps.cjs');
|
|
9
12
|
const remoteFetch = require('./remote-fetch.cjs');
|
|
10
13
|
const schemaLoadErrors = require('./schema-load-errors.cjs');
|
|
11
14
|
const schemaSource = require('./schema-source.cjs');
|
|
@@ -33,11 +36,10 @@ function assertOpenAPI3(document) {
|
|
|
33
36
|
}
|
|
34
37
|
throw schemaLoadErrors.versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, parsed);
|
|
35
38
|
}
|
|
39
|
+
const INLINE_SOURCE_NAME = "inline-source";
|
|
36
40
|
function sourceAbsoluteRef(source, cwd) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
return node_url.fileURLToPath(cwd);
|
|
41
|
+
const document = source instanceof URL ? source : new URL(INLINE_SOURCE_NAME, cwd);
|
|
42
|
+
return document.protocol === "file:" ? sourceFilePath(document) : document.href;
|
|
41
43
|
}
|
|
42
44
|
function sourceFilePath(source) {
|
|
43
45
|
try {
|
|
@@ -49,7 +51,6 @@ function sourceFilePath(source) {
|
|
|
49
51
|
throw schemaLoadErrors.loadFailedError(source.href, error);
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
|
-
const REF_CYCLE_MESSAGE = "Self-referencing circular pointer";
|
|
53
54
|
async function loadedDocuments(root, resolver) {
|
|
54
55
|
const cached = await Promise.all(resolver.cache.values());
|
|
55
56
|
const bySource = /* @__PURE__ */ new Map([[root.source.absoluteRef, root.parsed]]);
|
|
@@ -61,7 +62,7 @@ async function loadedDocuments(root, resolver) {
|
|
|
61
62
|
return [...bySource].map(([source, parsed]) => ({ source, parsed }));
|
|
62
63
|
}
|
|
63
64
|
async function rethrowDocumentError(error, root, resolver) {
|
|
64
|
-
if (error instanceof Error && error.message === REF_CYCLE_MESSAGE) {
|
|
65
|
+
if (error instanceof Error && error.message === refResolutionSteps.REF_CYCLE_MESSAGE) {
|
|
65
66
|
throw schemaLoadErrors.refCycleError(error);
|
|
66
67
|
}
|
|
67
68
|
if (error instanceof URIError) {
|
|
@@ -103,15 +104,20 @@ class RedoclySchemaLoader {
|
|
|
103
104
|
return this.#lintAndBundle(document, resolver, request.shouldLint);
|
|
104
105
|
}
|
|
105
106
|
#resolver(request) {
|
|
106
|
-
const { redoc, remoteRefTimeoutMs } = this.#options;
|
|
107
|
+
const { redoc, remoteRefTimeoutMs, remoteDocumentLimits } = this.#options;
|
|
107
108
|
const config = remoteFetch.resolveConfigWithAccess(redoc.resolve, {
|
|
108
109
|
timeoutMs: remoteRefTimeoutMs,
|
|
109
|
-
access: request.refAccess
|
|
110
|
+
access: request.refAccess,
|
|
111
|
+
maxParallelFetches: remoteDocumentLimits.maxParallelFetches
|
|
112
|
+
});
|
|
113
|
+
return new refAccess.RefAccessResolver(config, {
|
|
114
|
+
access: request.refAccess,
|
|
115
|
+
maxRemoteDocuments: remoteDocumentLimits.maxDocuments
|
|
110
116
|
});
|
|
111
|
-
return new refAccess.RefAccessResolver(config, request.refAccess);
|
|
112
117
|
}
|
|
113
118
|
async #lintAndBundle(document, resolver, shouldLint) {
|
|
114
119
|
const rethrow = (error) => rethrowDocumentError(error, document, resolver);
|
|
120
|
+
await refResolutionCheck.checkRefsResolve(document, resolver, this.#options.redoc.styleguide).catch(rethrow);
|
|
115
121
|
if (shouldLint) {
|
|
116
122
|
await this.#lint(document, resolver).catch(rethrow);
|
|
117
123
|
}
|
|
@@ -140,16 +146,27 @@ class RedoclySchemaLoader {
|
|
|
140
146
|
this.#options.logger.debug("Bundled schema", "bundle", this.#options.now() - startedAt);
|
|
141
147
|
return bundled.bundle.parsed;
|
|
142
148
|
}
|
|
143
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* Report every problem; then throw if any of them is an error. A problem that the Redocly
|
|
151
|
+
* config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out
|
|
152
|
+
* (upstream #2189).
|
|
153
|
+
*/
|
|
144
154
|
#report(problems) {
|
|
145
155
|
const errorMessages = [];
|
|
146
156
|
for (const problem of problems) {
|
|
157
|
+
if (problem.ignored === true) {
|
|
158
|
+
this.#options.logger.debug(
|
|
159
|
+
`Ignored by the lint ignore file: ${problemMessage(problem)}`,
|
|
160
|
+
"lint"
|
|
161
|
+
);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
147
164
|
const message = problemMessage(problem);
|
|
148
165
|
if (problem.severity === "error") {
|
|
149
166
|
errorMessages.push(message);
|
|
150
167
|
this.#options.logger.error(message);
|
|
151
168
|
} else {
|
|
152
|
-
this.#options.logger.warn(
|
|
169
|
+
this.#options.logger.warn(lintWarningText(problem));
|
|
153
170
|
}
|
|
154
171
|
}
|
|
155
172
|
if (errorMessages.length > 0) {
|
|
@@ -157,6 +174,12 @@ class RedoclySchemaLoader {
|
|
|
157
174
|
}
|
|
158
175
|
}
|
|
159
176
|
}
|
|
177
|
+
function lintWarningText(problem) {
|
|
178
|
+
return warnings.warningText(
|
|
179
|
+
`${problemMessage(problem)}, rule ${problem.ruleId}`,
|
|
180
|
+
warnings.WARNING_CODES.LINT_PROBLEM
|
|
181
|
+
);
|
|
182
|
+
}
|
|
160
183
|
function problemMessage(problem) {
|
|
161
184
|
const location = problem.location?.[0]?.pointer;
|
|
162
185
|
return location ? `${problem.message} at ${location}` : problem.message;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redocly-schema-loader.cjs","sources":["../../../src/adapters/redocly-loader/redocly-schema-loader.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport {\n type BaseResolver,\n bundle,\n type Document,\n lintDocument,\n type NormalizedProblem,\n type Config as RedoclyConfig,\n} from \"@redocly/openapi-core\";\nimport type { Logger } from \"../../application/ports/logger.js\";\nimport type { SchemaLoader, SchemaLoadRequest } from \"../../application/ports/schema-loader.js\";\nimport { withStackOverflowReportedAsync } from \"../../application/stack-overflow.js\";\nimport type { OpenAPI3 } from \"../../types.js\";\nimport { repairBundledRefs } from \"./bundled-ref-repair.js\";\nimport { findMalformedRefs, malformedRefsError } from \"./malformed-refs.js\";\nimport { RefAccessResolver } from \"./ref-access.js\";\nimport { resolveConfigWithAccess } from \"./remote-fetch.js\";\nimport {\n loadFailedError,\n refCycleError,\n schemaInvalidError,\n versionUnsupportedError,\n} from \"./schema-load-errors.js\";\nimport { parseSchema } from \"./schema-source.js\";\nimport {\n findUnsupportedKeys,\n type LoadedDocument,\n unsupportedKeysError,\n} from \"./unsupported-keys.js\";\n\n/**\n * The SchemaLoader port on Redocly 1.34 (ADR-005): parse any inherited source type, then lint and\n * bundle with the given Redocly config. Problems go to the logger; errors fail the load.\n */\nexport interface RedoclySchemaLoaderOptions {\n readonly redoc: RedoclyConfig;\n readonly logger: Logger;\n /** A monotonic time in milliseconds, for the debug durations. */\n readonly now: () => number;\n /** Time limit of one remote fetch, unless the Redocly config brings its own `customFetch`. */\n readonly remoteRefTimeoutMs: number;\n}\n\nconst UNSUPPORTED_FORMAT_MESSAGE = \"Unsupported schema format, expected `openapi: 3.x`\";\n\n/**\n * Accept OpenAPI 3.x only; Swagger 2 and other formats get their own message. An empty file or a\n * `null` root parses to nothing, so it is checked before any field is read.\n */\nfunction assertOpenAPI3(document: unknown): void {\n if (typeof document !== \"object\" || document === null) {\n throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, {});\n }\n const parsed = document as Record<string, unknown>;\n const openapiVersion = Number.parseFloat(parsed.openapi as string);\n const isOpenAPI3 =\n !parsed.swagger &&\n Boolean(parsed.openapi) &&\n !Number.isNaN(openapiVersion) &&\n openapiVersion >= 3 &&\n openapiVersion < 4;\n if (isOpenAPI3) {\n return;\n }\n if (parsed.swagger) {\n throw versionUnsupportedError(\n \"Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.\",\n parsed,\n );\n }\n if (parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) {\n throw versionUnsupportedError(`Unsupported OpenAPI version: ${parsed.openapi}`, parsed);\n }\n throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, parsed);\n}\n\n/** The base for relative `$ref`s: the source file or URL itself, else the working directory. */\nfunction sourceAbsoluteRef(source: unknown, cwd: URL): string {\n if (source instanceof URL) {\n return source.protocol === \"file:\" ? sourceFilePath(source) : source.href;\n }\n return fileURLToPath(cwd);\n}\n\n/**\n * The path of a `file:` source. A URL that names no path on this platform (an encoded slash, a\n * host on POSIX, no drive letter on Windows) cannot be read, so it fails as a read would.\n */\nfunction sourceFilePath(source: URL): string {\n try {\n return fileURLToPath(source);\n } catch (error) {\n // Node.js reports these as TypeErrors (ERR_INVALID_FILE_URL_PATH, ERR_INVALID_FILE_URL_HOST).\n if (!(error instanceof TypeError)) {\n throw error;\n }\n throw loadFailedError(source.href, error);\n }\n}\n\n/** Redocly throws a plain Error for a `$ref` chain that points back to itself. */\nconst REF_CYCLE_MESSAGE = \"Self-referencing circular pointer\";\n\n/**\n * The root document and every other document the resolver loaded, as far as they parsed. A root\n * read from a file or URL is in the resolver cache too, and is listed once.\n */\nasync function loadedDocuments(root: Document, resolver: BaseResolver): Promise<LoadedDocument[]> {\n const cached = await Promise.all(resolver.cache.values());\n const bySource = new Map<string, unknown>([[root.source.absoluteRef, root.parsed]]);\n for (const document of cached) {\n if (\"parsed\" in document && !bySource.has(document.source.absoluteRef)) {\n bySource.set(document.source.absoluteRef, document.parsed);\n }\n }\n return [...bySource].map(([source, parsed]) => ({ source, parsed }));\n}\n\n/** Report the document problems Redocly throws as typed errors; anything else passes through. */\nasync function rethrowDocumentError(\n error: unknown,\n root: Document,\n resolver: BaseResolver,\n): Promise<never> {\n if (error instanceof Error && error.message === REF_CYCLE_MESSAGE) {\n throw refCycleError(error);\n }\n if (error instanceof URIError) {\n throw malformedRefsError(findMalformedRefs(await loadedDocuments(root, resolver)), error);\n }\n if (error instanceof TypeError) {\n const keys = findUnsupportedKeys(await loadedDocuments(root, resolver));\n throw keys.length === 0 ? error : unsupportedKeysError(keys, error);\n }\n throw error;\n}\n\nclass RedoclySchemaLoader implements SchemaLoader {\n readonly #options: RedoclySchemaLoaderOptions;\n\n constructor(options: RedoclySchemaLoaderOptions) {\n this.#options = options;\n }\n\n async load(request: SchemaLoadRequest): Promise<OpenAPI3> {\n const resolver = this.#resolver(request);\n // Parsing is guarded too: `JSON.stringify` of a deep object source overflows the stack on\n // Node.js 22 and 24, before linting starts.\n const bundled = await withStackOverflowReportedAsync(\"load\", () =>\n this.#parseAndBundle(request, resolver),\n ).catch((error: unknown) => {\n throw resolver.firstRefusal ?? error;\n });\n // A refused `$ref` is an unresolved-`$ref` problem, which a Redocly config can turn off.\n if (resolver.firstRefusal !== undefined) {\n throw resolver.firstRefusal;\n }\n return bundled;\n }\n\n async #parseAndBundle(request: SchemaLoadRequest, resolver: BaseResolver): Promise<OpenAPI3> {\n const { logger, now } = this.#options;\n const configLoadedAt = now();\n logger.debug(\"Loaded Redoc config\", \"redoc\", now() - configLoadedAt);\n const parseStartedAt = now();\n const absoluteRef = sourceAbsoluteRef(request.source, request.cwd);\n const document = await parseSchema(request.source, { absoluteRef, resolver });\n logger.debug(\"Parsed schema\", \"redoc\", now() - parseStartedAt);\n assertOpenAPI3(document.parsed);\n return this.#lintAndBundle(document, resolver, request.shouldLint);\n }\n\n #resolver(request: SchemaLoadRequest): RefAccessResolver {\n const { redoc, remoteRefTimeoutMs } = this.#options;\n const config = resolveConfigWithAccess(redoc.resolve, {\n timeoutMs: remoteRefTimeoutMs,\n access: request.refAccess,\n });\n return new RefAccessResolver(config, request.refAccess);\n }\n\n async #lintAndBundle(\n document: Document,\n resolver: BaseResolver,\n shouldLint: boolean,\n ): Promise<OpenAPI3> {\n const rethrow = (error: unknown) => rethrowDocumentError(error, document, resolver);\n if (shouldLint) {\n await this.#lint(document, resolver).catch(rethrow);\n }\n return this.#bundle(document, resolver).catch(rethrow);\n }\n\n async #lint(document: Document, resolver: BaseResolver): Promise<void> {\n const startedAt = this.#options.now();\n const problems = await lintDocument({\n document,\n config: this.#options.redoc.styleguide,\n externalRefResolver: resolver,\n });\n this.#report(problems);\n this.#options.logger.debug(\"Linted schema\", \"lint\", this.#options.now() - startedAt);\n }\n\n async #bundle(document: Document, resolver: BaseResolver): Promise<OpenAPI3> {\n const startedAt = this.#options.now();\n // The lint resolver: documents it already loaded are not fetched again.\n const bundled = await bundle({\n config: this.#options.redoc,\n dereference: false,\n doc: document,\n externalRefResolver: resolver,\n });\n this.#report(bundled.problems);\n repairBundledRefs(bundled.bundle.parsed);\n this.#options.logger.debug(\"Bundled schema\", \"bundle\", this.#options.now() - startedAt);\n return bundled.bundle.parsed;\n }\n\n /** Report every problem; then throw if any of them is an error. */\n #report(problems: readonly NormalizedProblem[]): void {\n const errorMessages: string[] = [];\n for (const problem of problems) {\n const message = problemMessage(problem);\n if (problem.severity === \"error\") {\n errorMessages.push(message);\n this.#options.logger.error(message);\n } else {\n this.#options.logger.warn(message);\n }\n }\n if (errorMessages.length > 0) {\n throw schemaInvalidError(errorMessages);\n }\n }\n}\n\nfunction problemMessage(problem: NormalizedProblem): string {\n const location = problem.location?.[0]?.pointer;\n return location ? `${problem.message} at ${location}` : problem.message;\n}\n\n/** A schema loader with one Redocly config and logger, for one or more loads. */\nexport function createRedoclySchemaLoader(options: RedoclySchemaLoaderOptions): SchemaLoader {\n return new RedoclySchemaLoader(options);\n}\n"],"names":["versionUnsupportedError","fileURLToPath","loadFailedError","refCycleError","malformedRefsError","findMalformedRefs","findUnsupportedKeys","unsupportedKeysError","withStackOverflowReportedAsync","parseSchema","resolveConfigWithAccess","RefAccessResolver","lintDocument","bundle","repairBundledRefs","schemaInvalidError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"redocly-schema-loader.cjs","sources":["../../../src/adapters/redocly-loader/redocly-schema-loader.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport {\n type BaseResolver,\n bundle,\n type Document,\n lintDocument,\n type NormalizedProblem,\n type Config as RedoclyConfig,\n} from \"@redocly/openapi-core\";\nimport type { Logger } from \"../../application/ports/logger.js\";\nimport type { SchemaLoader, SchemaLoadRequest } from \"../../application/ports/schema-loader.js\";\nimport { withStackOverflowReportedAsync } from \"../../application/stack-overflow.js\";\nimport { WARNING_CODES, warningText } from \"../../domain/warnings.js\";\nimport type { OpenAPI3 } from \"../../types.js\";\nimport { repairBundledRefs } from \"./bundled-ref-repair.js\";\nimport { findMalformedRefs, malformedRefsError } from \"./malformed-refs.js\";\nimport { RefAccessResolver } from \"./ref-access.js\";\nimport { checkRefsResolve } from \"./ref-resolution-check.js\";\nimport { REF_CYCLE_MESSAGE } from \"./ref-resolution-steps.js\";\nimport { type RemoteDocumentLimits, resolveConfigWithAccess } from \"./remote-fetch.js\";\nimport {\n loadFailedError,\n refCycleError,\n schemaInvalidError,\n versionUnsupportedError,\n} from \"./schema-load-errors.js\";\nimport { parseSchema } from \"./schema-source.js\";\nimport {\n findUnsupportedKeys,\n type LoadedDocument,\n unsupportedKeysError,\n} from \"./unsupported-keys.js\";\n\n/**\n * The SchemaLoader port on Redocly 1.34 (ADR-005): parse any inherited source type, then lint and\n * bundle with the given Redocly config. Problems go to the logger; errors fail the load.\n */\nexport interface RedoclySchemaLoaderOptions {\n readonly redoc: RedoclyConfig;\n readonly logger: Logger;\n /** A monotonic time in milliseconds, for the debug durations. */\n readonly now: () => number;\n /** Time limit of one remote fetch, unless the Redocly config brings its own `customFetch`. */\n readonly remoteRefTimeoutMs: number;\n readonly remoteDocumentLimits: RemoteDocumentLimits;\n}\n\nconst UNSUPPORTED_FORMAT_MESSAGE = \"Unsupported schema format, expected `openapi: 3.x`\";\n\n/**\n * Accept OpenAPI 3.x only; Swagger 2 and other formats get their own message. An empty file or a\n * `null` root parses to nothing, so it is checked before any field is read.\n */\nfunction assertOpenAPI3(document: unknown): void {\n if (typeof document !== \"object\" || document === null) {\n throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, {});\n }\n const parsed = document as Record<string, unknown>;\n const openapiVersion = Number.parseFloat(parsed.openapi as string);\n const isOpenAPI3 =\n !parsed.swagger &&\n Boolean(parsed.openapi) &&\n !Number.isNaN(openapiVersion) &&\n openapiVersion >= 3 &&\n openapiVersion < 4;\n if (isOpenAPI3) {\n return;\n }\n if (parsed.swagger) {\n throw versionUnsupportedError(\n \"Unsupported Swagger version: 2.x. Use OpenAPI 3.x instead.\",\n parsed,\n );\n }\n if (parsed.openapi || openapiVersion < 3 || openapiVersion >= 4) {\n throw versionUnsupportedError(`Unsupported OpenAPI version: ${parsed.openapi}`, parsed);\n }\n throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, parsed);\n}\n\n/**\n * The name an inline source (a string, object, buffer or stream) gets inside the working\n * directory. Redocly resolves relative `$ref`s against the directory of the document, so the\n * document must be named as a file in the working directory, not as the directory itself.\n */\nconst INLINE_SOURCE_NAME = \"inline-source\";\n\n/** The base for relative `$ref`s: the source file or URL itself, else a file in the cwd. */\nfunction sourceAbsoluteRef(source: unknown, cwd: URL): string {\n const document = source instanceof URL ? source : new URL(INLINE_SOURCE_NAME, cwd);\n return document.protocol === \"file:\" ? sourceFilePath(document) : document.href;\n}\n\n/**\n * The path of a `file:` source. A URL that names no path on this platform (an encoded slash, a\n * host on POSIX, no drive letter on Windows) cannot be read, so it fails as a read would.\n */\nfunction sourceFilePath(source: URL): string {\n try {\n return fileURLToPath(source);\n } catch (error) {\n // Node.js reports these as TypeErrors (ERR_INVALID_FILE_URL_PATH, ERR_INVALID_FILE_URL_HOST).\n if (!(error instanceof TypeError)) {\n throw error;\n }\n throw loadFailedError(source.href, error);\n }\n}\n\n/**\n * The root document and every other document the resolver loaded, as far as they parsed. A root\n * read from a file or URL is in the resolver cache too, and is listed once.\n */\nasync function loadedDocuments(root: Document, resolver: BaseResolver): Promise<LoadedDocument[]> {\n const cached = await Promise.all(resolver.cache.values());\n const bySource = new Map<string, unknown>([[root.source.absoluteRef, root.parsed]]);\n for (const document of cached) {\n if (\"parsed\" in document && !bySource.has(document.source.absoluteRef)) {\n bySource.set(document.source.absoluteRef, document.parsed);\n }\n }\n return [...bySource].map(([source, parsed]) => ({ source, parsed }));\n}\n\n/** Report the document problems Redocly throws as typed errors; anything else passes through. */\nasync function rethrowDocumentError(\n error: unknown,\n root: Document,\n resolver: BaseResolver,\n): Promise<never> {\n if (error instanceof Error && error.message === REF_CYCLE_MESSAGE) {\n throw refCycleError(error);\n }\n if (error instanceof URIError) {\n throw malformedRefsError(findMalformedRefs(await loadedDocuments(root, resolver)), error);\n }\n if (error instanceof TypeError) {\n const keys = findUnsupportedKeys(await loadedDocuments(root, resolver));\n throw keys.length === 0 ? error : unsupportedKeysError(keys, error);\n }\n throw error;\n}\n\nclass RedoclySchemaLoader implements SchemaLoader {\n readonly #options: RedoclySchemaLoaderOptions;\n\n constructor(options: RedoclySchemaLoaderOptions) {\n this.#options = options;\n }\n\n async load(request: SchemaLoadRequest): Promise<OpenAPI3> {\n const resolver = this.#resolver(request);\n // Parsing is guarded too: `JSON.stringify` of a deep object source overflows the stack on\n // Node.js 22 and 24, before linting starts.\n const bundled = await withStackOverflowReportedAsync(\"load\", () =>\n this.#parseAndBundle(request, resolver),\n ).catch((error: unknown) => {\n throw resolver.firstRefusal ?? error;\n });\n // A refused `$ref` is an unresolved-`$ref` problem, which a Redocly config can turn off.\n if (resolver.firstRefusal !== undefined) {\n throw resolver.firstRefusal;\n }\n return bundled;\n }\n\n async #parseAndBundle(request: SchemaLoadRequest, resolver: BaseResolver): Promise<OpenAPI3> {\n const { logger, now } = this.#options;\n const configLoadedAt = now();\n logger.debug(\"Loaded Redoc config\", \"redoc\", now() - configLoadedAt);\n const parseStartedAt = now();\n const absoluteRef = sourceAbsoluteRef(request.source, request.cwd);\n const document = await parseSchema(request.source, { absoluteRef, resolver });\n logger.debug(\"Parsed schema\", \"redoc\", now() - parseStartedAt);\n assertOpenAPI3(document.parsed);\n return this.#lintAndBundle(document, resolver, request.shouldLint);\n }\n\n #resolver(request: SchemaLoadRequest): RefAccessResolver {\n const { redoc, remoteRefTimeoutMs, remoteDocumentLimits } = this.#options;\n const config = resolveConfigWithAccess(redoc.resolve, {\n timeoutMs: remoteRefTimeoutMs,\n access: request.refAccess,\n maxParallelFetches: remoteDocumentLimits.maxParallelFetches,\n });\n return new RefAccessResolver(config, {\n access: request.refAccess,\n maxRemoteDocuments: remoteDocumentLimits.maxDocuments,\n });\n }\n\n async #lintAndBundle(\n document: Document,\n resolver: BaseResolver,\n shouldLint: boolean,\n ): Promise<OpenAPI3> {\n const rethrow = (error: unknown) => rethrowDocumentError(error, document, resolver);\n // Redocly leaves unhandled rejections behind when a `$ref` fails in two documents (ADR-031).\n await checkRefsResolve(document, resolver, this.#options.redoc.styleguide).catch(rethrow);\n if (shouldLint) {\n await this.#lint(document, resolver).catch(rethrow);\n }\n return this.#bundle(document, resolver).catch(rethrow);\n }\n\n async #lint(document: Document, resolver: BaseResolver): Promise<void> {\n const startedAt = this.#options.now();\n const problems = await lintDocument({\n document,\n config: this.#options.redoc.styleguide,\n externalRefResolver: resolver,\n });\n this.#report(problems);\n this.#options.logger.debug(\"Linted schema\", \"lint\", this.#options.now() - startedAt);\n }\n\n async #bundle(document: Document, resolver: BaseResolver): Promise<OpenAPI3> {\n const startedAt = this.#options.now();\n // The lint resolver: documents it already loaded are not fetched again.\n const bundled = await bundle({\n config: this.#options.redoc,\n dereference: false,\n doc: document,\n externalRefResolver: resolver,\n });\n this.#report(bundled.problems);\n repairBundledRefs(bundled.bundle.parsed);\n this.#options.logger.debug(\"Bundled schema\", \"bundle\", this.#options.now() - startedAt);\n return bundled.bundle.parsed;\n }\n\n /**\n * Report every problem; then throw if any of them is an error. A problem that the Redocly\n * config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out\n * (upstream #2189).\n */\n #report(problems: readonly NormalizedProblem[]): void {\n const errorMessages: string[] = [];\n for (const problem of problems) {\n if (problem.ignored === true) {\n this.#options.logger.debug(\n `Ignored by the lint ignore file: ${problemMessage(problem)}`,\n \"lint\",\n );\n continue;\n }\n const message = problemMessage(problem);\n if (problem.severity === \"error\") {\n errorMessages.push(message);\n this.#options.logger.error(message);\n } else {\n this.#options.logger.warn(lintWarningText(problem));\n }\n }\n if (errorMessages.length > 0) {\n throw schemaInvalidError(errorMessages);\n }\n }\n}\n\n/** A lint warning names its rule, which `redocly.yaml` can turn off, and ends with its code. */\nfunction lintWarningText(problem: NormalizedProblem): string {\n return warningText(\n `${problemMessage(problem)}, rule ${problem.ruleId}`,\n WARNING_CODES.LINT_PROBLEM,\n );\n}\n\nfunction problemMessage(problem: NormalizedProblem): string {\n const location = problem.location?.[0]?.pointer;\n return location ? `${problem.message} at ${location}` : problem.message;\n}\n\n/** A schema loader with one Redocly config and logger, for one or more loads. */\nexport function createRedoclySchemaLoader(options: RedoclySchemaLoaderOptions): SchemaLoader {\n return new RedoclySchemaLoader(options);\n}\n"],"names":["versionUnsupportedError","fileURLToPath","loadFailedError","REF_CYCLE_MESSAGE","refCycleError","malformedRefsError","findMalformedRefs","findUnsupportedKeys","unsupportedKeysError","withStackOverflowReportedAsync","parseSchema","resolveConfigWithAccess","RefAccessResolver","checkRefsResolve","lintDocument","bundle","repairBundledRefs","schemaInvalidError","warningText","WARNING_CODES"],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
2
|
import { lintDocument, bundle } from '@redocly/openapi-core';
|
|
3
3
|
import { withStackOverflowReportedAsync } from '../../application/stack-overflow.mjs';
|
|
4
|
+
import { warningText, WARNING_CODES } from '../../domain/warnings.mjs';
|
|
4
5
|
import { repairBundledRefs } from './bundled-ref-repair.mjs';
|
|
5
6
|
import { malformedRefsError, findMalformedRefs } from './malformed-refs.mjs';
|
|
6
7
|
import { RefAccessResolver } from './ref-access.mjs';
|
|
8
|
+
import { checkRefsResolve } from './ref-resolution-check.mjs';
|
|
9
|
+
import { REF_CYCLE_MESSAGE } from './ref-resolution-steps.mjs';
|
|
7
10
|
import { resolveConfigWithAccess } from './remote-fetch.mjs';
|
|
8
11
|
import { schemaInvalidError, versionUnsupportedError, refCycleError, loadFailedError } from './schema-load-errors.mjs';
|
|
9
12
|
import { parseSchema } from './schema-source.mjs';
|
|
@@ -31,11 +34,10 @@ function assertOpenAPI3(document) {
|
|
|
31
34
|
}
|
|
32
35
|
throw versionUnsupportedError(UNSUPPORTED_FORMAT_MESSAGE, parsed);
|
|
33
36
|
}
|
|
37
|
+
const INLINE_SOURCE_NAME = "inline-source";
|
|
34
38
|
function sourceAbsoluteRef(source, cwd) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
return fileURLToPath(cwd);
|
|
39
|
+
const document = source instanceof URL ? source : new URL(INLINE_SOURCE_NAME, cwd);
|
|
40
|
+
return document.protocol === "file:" ? sourceFilePath(document) : document.href;
|
|
39
41
|
}
|
|
40
42
|
function sourceFilePath(source) {
|
|
41
43
|
try {
|
|
@@ -47,7 +49,6 @@ function sourceFilePath(source) {
|
|
|
47
49
|
throw loadFailedError(source.href, error);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
|
-
const REF_CYCLE_MESSAGE = "Self-referencing circular pointer";
|
|
51
52
|
async function loadedDocuments(root, resolver) {
|
|
52
53
|
const cached = await Promise.all(resolver.cache.values());
|
|
53
54
|
const bySource = /* @__PURE__ */ new Map([[root.source.absoluteRef, root.parsed]]);
|
|
@@ -101,15 +102,20 @@ class RedoclySchemaLoader {
|
|
|
101
102
|
return this.#lintAndBundle(document, resolver, request.shouldLint);
|
|
102
103
|
}
|
|
103
104
|
#resolver(request) {
|
|
104
|
-
const { redoc, remoteRefTimeoutMs } = this.#options;
|
|
105
|
+
const { redoc, remoteRefTimeoutMs, remoteDocumentLimits } = this.#options;
|
|
105
106
|
const config = resolveConfigWithAccess(redoc.resolve, {
|
|
106
107
|
timeoutMs: remoteRefTimeoutMs,
|
|
107
|
-
access: request.refAccess
|
|
108
|
+
access: request.refAccess,
|
|
109
|
+
maxParallelFetches: remoteDocumentLimits.maxParallelFetches
|
|
110
|
+
});
|
|
111
|
+
return new RefAccessResolver(config, {
|
|
112
|
+
access: request.refAccess,
|
|
113
|
+
maxRemoteDocuments: remoteDocumentLimits.maxDocuments
|
|
108
114
|
});
|
|
109
|
-
return new RefAccessResolver(config, request.refAccess);
|
|
110
115
|
}
|
|
111
116
|
async #lintAndBundle(document, resolver, shouldLint) {
|
|
112
117
|
const rethrow = (error) => rethrowDocumentError(error, document, resolver);
|
|
118
|
+
await checkRefsResolve(document, resolver, this.#options.redoc.styleguide).catch(rethrow);
|
|
113
119
|
if (shouldLint) {
|
|
114
120
|
await this.#lint(document, resolver).catch(rethrow);
|
|
115
121
|
}
|
|
@@ -138,16 +144,27 @@ class RedoclySchemaLoader {
|
|
|
138
144
|
this.#options.logger.debug("Bundled schema", "bundle", this.#options.now() - startedAt);
|
|
139
145
|
return bundled.bundle.parsed;
|
|
140
146
|
}
|
|
141
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Report every problem; then throw if any of them is an error. A problem that the Redocly
|
|
149
|
+
* config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out
|
|
150
|
+
* (upstream #2189).
|
|
151
|
+
*/
|
|
142
152
|
#report(problems) {
|
|
143
153
|
const errorMessages = [];
|
|
144
154
|
for (const problem of problems) {
|
|
155
|
+
if (problem.ignored === true) {
|
|
156
|
+
this.#options.logger.debug(
|
|
157
|
+
`Ignored by the lint ignore file: ${problemMessage(problem)}`,
|
|
158
|
+
"lint"
|
|
159
|
+
);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
145
162
|
const message = problemMessage(problem);
|
|
146
163
|
if (problem.severity === "error") {
|
|
147
164
|
errorMessages.push(message);
|
|
148
165
|
this.#options.logger.error(message);
|
|
149
166
|
} else {
|
|
150
|
-
this.#options.logger.warn(
|
|
167
|
+
this.#options.logger.warn(lintWarningText(problem));
|
|
151
168
|
}
|
|
152
169
|
}
|
|
153
170
|
if (errorMessages.length > 0) {
|
|
@@ -155,6 +172,12 @@ class RedoclySchemaLoader {
|
|
|
155
172
|
}
|
|
156
173
|
}
|
|
157
174
|
}
|
|
175
|
+
function lintWarningText(problem) {
|
|
176
|
+
return warningText(
|
|
177
|
+
`${problemMessage(problem)}, rule ${problem.ruleId}`,
|
|
178
|
+
WARNING_CODES.LINT_PROBLEM
|
|
179
|
+
);
|
|
180
|
+
}
|
|
158
181
|
function problemMessage(problem) {
|
|
159
182
|
const location = problem.location?.[0]?.pointer;
|
|
160
183
|
return location ? `${problem.message} at ${location}` : problem.message;
|