openapi-typesafe 1.0.0-rc.4 → 1.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -0
- package/dist/adapters/node-file-system/node-file-system.cjs +7 -0
- package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
- package/dist/adapters/node-file-system/node-file-system.mjs +7 -0
- package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs +19 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs.map +1 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs +17 -0
- package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs.map +1 -0
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +5 -32
- package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -1
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +6 -33
- package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -1
- package/dist/adapters/redocly-loader/component-schemas.cjs +17 -0
- package/dist/adapters/redocly-loader/component-schemas.cjs.map +1 -0
- package/dist/adapters/redocly-loader/component-schemas.mjs +14 -0
- package/dist/adapters/redocly-loader/component-schemas.mjs.map +1 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.cjs +22 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.cjs.map +1 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.mjs +20 -0
- package/dist/adapters/redocly-loader/mapping-schema-names.mjs.map +1 -0
- package/dist/adapters/redocly-loader/query-named-components.cjs +137 -0
- package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -0
- package/dist/adapters/redocly-loader/query-named-components.mjs +134 -0
- package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +26 -14
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +26 -14
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +16 -3
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +16 -3
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.cjs +52 -10
- package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-holders.mjs +52 -11
- package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.cjs +5 -3
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +5 -3
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-node-limit.cjs +17 -3
- package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-node-limit.mjs +17 -3
- package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.cjs +7 -2
- package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-source.mjs +8 -3
- package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +7 -3
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +7 -3
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/api/document-refs.cjs +16 -1
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +16 -1
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +4 -10
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +4 -10
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +1 -2
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +2 -3
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/ref-limit-options.cjs +63 -0
- package/dist/api/ref-limit-options.cjs.map +1 -0
- package/dist/api/ref-limit-options.mjs +57 -0
- package/dist/api/ref-limit-options.mjs.map +1 -0
- package/dist/api/transform-schema.cjs +12 -5
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +12 -5
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/application/transform/declared-value-types.cjs +36 -0
- package/dist/application/transform/declared-value-types.cjs.map +1 -0
- package/dist/application/transform/declared-value-types.mjs +34 -0
- package/dist/application/transform/declared-value-types.mjs.map +1 -0
- package/dist/application/transform/document/document.cjs +3 -1
- package/dist/application/transform/document/document.cjs.map +1 -1
- package/dist/application/transform/document/document.mjs +3 -1
- package/dist/application/transform/document/document.mjs.map +1 -1
- package/dist/application/transform/document/exploded-query-values.cjs +63 -0
- package/dist/application/transform/document/exploded-query-values.cjs.map +1 -0
- package/dist/application/transform/document/exploded-query-values.mjs +59 -0
- package/dist/application/transform/document/exploded-query-values.mjs.map +1 -0
- package/dist/application/transform/document/header.cjs +11 -3
- package/dist/application/transform/document/header.cjs.map +1 -1
- package/dist/application/transform/document/header.mjs +10 -2
- package/dist/application/transform/document/header.mjs.map +1 -1
- package/dist/application/transform/document/parameter.cjs +1 -1
- package/dist/application/transform/document/parameter.cjs.map +1 -1
- package/dist/application/transform/document/parameter.mjs +1 -1
- package/dist/application/transform/document/parameter.mjs.map +1 -1
- package/dist/application/transform/document/parameters.cjs +23 -5
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +23 -5
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/path-item.cjs +4 -3
- package/dist/application/transform/document/path-item.cjs.map +1 -1
- package/dist/application/transform/document/path-item.mjs +4 -4
- package/dist/application/transform/document/path-item.mjs.map +1 -1
- package/dist/application/transform/document/path-template-key.cjs +84 -0
- package/dist/application/transform/document/path-template-key.cjs.map +1 -0
- package/dist/application/transform/document/path-template-key.mjs +79 -0
- package/dist/application/transform/document/path-template-key.mjs.map +1 -0
- package/dist/application/transform/document/path-template-refs.cjs +70 -0
- package/dist/application/transform/document/path-template-refs.cjs.map +1 -0
- package/dist/application/transform/document/path-template-refs.mjs +67 -0
- package/dist/application/transform/document/path-template-refs.mjs.map +1 -0
- package/dist/application/transform/document/paths-enum.cjs +7 -6
- package/dist/application/transform/document/paths-enum.cjs.map +1 -1
- package/dist/application/transform/document/paths-enum.mjs +7 -6
- package/dist/application/transform/document/paths-enum.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +38 -66
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +36 -66
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/document/webhooks.cjs +10 -3
- package/dist/application/transform/document/webhooks.cjs.map +1 -1
- package/dist/application/transform/document/webhooks.mjs +9 -2
- package/dist/application/transform/document/webhooks.mjs.map +1 -1
- package/dist/application/transform/footer/document-footer.cjs +6 -3
- package/dist/application/transform/footer/document-footer.cjs.map +1 -1
- package/dist/application/transform/footer/document-footer.mjs +6 -3
- package/dist/application/transform/footer/document-footer.mjs.map +1 -1
- package/dist/application/transform/helper-types.cjs +3 -3
- package/dist/application/transform/helper-types.cjs.map +1 -1
- package/dist/application/transform/helper-types.mjs +3 -3
- package/dist/application/transform/helper-types.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.cjs +4 -4
- package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-location.mjs +1 -1
- package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-shape.cjs +47 -66
- package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/generated-shape.mjs +36 -50
- package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.cjs +2 -2
- package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.mjs +1 -1
- package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/located-node.cjs +23 -0
- package/dist/application/transform/ref-pointer/located-node.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/located-node.mjs +18 -0
- package/dist/application/transform/ref-pointer/located-node.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/original-index.cjs +68 -13
- package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/original-index.mjs +70 -15
- package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.cjs +2 -2
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-walk.cjs +54 -13
- package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-walk.mjs +46 -7
- package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -1
- package/dist/application/transform/ref-pointer/property-shape.cjs +52 -0
- package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -0
- package/dist/application/transform/ref-pointer/property-shape.mjs +45 -0
- package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/typed-walk.cjs +79 -21
- package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/typed-walk.mjs +76 -18
- package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs.map +1 -1
- package/dist/application/transform/schema/access-flags.mjs.map +1 -1
- package/dist/application/transform/schema/index-signature-type.cjs +21 -0
- package/dist/application/transform/schema/index-signature-type.cjs.map +1 -0
- package/dist/application/transform/schema/index-signature-type.mjs +19 -0
- package/dist/application/transform/schema/index-signature-type.mjs.map +1 -0
- package/dist/application/transform/schema/input-location.cjs +23 -0
- package/dist/application/transform/schema/input-location.cjs.map +1 -0
- package/dist/application/transform/schema/input-location.mjs +21 -0
- package/dist/application/transform/schema/input-location.mjs.map +1 -0
- package/dist/application/transform/schema/object-type.cjs +15 -5
- package/dist/application/transform/schema/object-type.cjs.map +1 -1
- package/dist/application/transform/schema/object-type.mjs +15 -5
- package/dist/application/transform/schema/object-type.mjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.cjs +2 -1
- package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
- package/dist/application/transform/schema/schema-transform.mjs +2 -1
- package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs +2 -30
- package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.mjs +3 -31
- package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
- package/dist/cli/api-logger.cjs +13 -0
- package/dist/cli/api-logger.cjs.map +1 -0
- package/dist/cli/api-logger.mjs +11 -0
- package/dist/cli/api-logger.mjs.map +1 -0
- package/dist/cli/api-settings.cjs +7 -15
- package/dist/cli/api-settings.cjs.map +1 -1
- package/dist/cli/api-settings.mjs +8 -16
- package/dist/cli/api-settings.mjs.map +1 -1
- package/dist/cli/cli-arguments.cjs +51 -11
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +51 -11
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/cli-errors.cjs +17 -0
- package/dist/cli/cli-errors.cjs.map +1 -1
- package/dist/cli/cli-errors.mjs +17 -1
- package/dist/cli/cli-errors.mjs.map +1 -1
- package/dist/cli/cli-output.cjs +6 -4
- package/dist/cli/cli-output.cjs.map +1 -1
- package/dist/cli/cli-output.mjs +7 -5
- package/dist/cli/cli-output.mjs.map +1 -1
- package/dist/cli/main.cjs +10 -4
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.mjs +10 -4
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +20 -9
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +22 -11
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/ref-limits.cjs +15 -1
- package/dist/cli/ref-limits.cjs.map +1 -1
- package/dist/cli/ref-limits.mjs +15 -2
- package/dist/cli/ref-limits.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +24 -7
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +25 -8
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/cause-secrets.cjs +31 -16
- package/dist/domain/cause-secrets.cjs.map +1 -1
- package/dist/domain/cause-secrets.mjs +31 -16
- package/dist/domain/cause-secrets.mjs.map +1 -1
- package/dist/domain/errors.cjs +2 -0
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +2 -0
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/location-text.cjs +9 -0
- package/dist/domain/location-text.cjs.map +1 -0
- package/dist/domain/location-text.mjs +7 -0
- package/dist/domain/location-text.mjs.map +1 -0
- package/dist/domain/openapi/document-places.cjs +55 -0
- package/dist/domain/openapi/document-places.cjs.map +1 -0
- package/dist/domain/openapi/document-places.mjs +53 -0
- package/dist/domain/openapi/document-places.mjs.map +1 -0
- package/dist/domain/output-fixes.cjs +8 -2
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +8 -2
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/terminal-text.cjs +31 -0
- package/dist/domain/terminal-text.cjs.map +1 -0
- package/dist/domain/terminal-text.mjs +29 -0
- package/dist/domain/terminal-text.mjs.map +1 -0
- package/dist/domain/warnings.cjs +1 -0
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +1 -0
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.d.cts +26 -18
- package/dist/index.d.mts +26 -18
- package/dist/index.d.ts +26 -18
- package/package.json +1 -1
- package/src/adapters/node-file-system/node-file-system.ts +14 -1
- package/src/adapters/pipe-safe-writer/pipe-safe-writer.ts +29 -0
- package/src/adapters/redocly-loader/bundled-mapping-copies.ts +7 -42
- package/src/adapters/redocly-loader/component-schemas.ts +19 -0
- package/src/adapters/redocly-loader/mapping-schema-names.ts +25 -0
- package/src/adapters/redocly-loader/query-named-components.ts +201 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +46 -14
- package/src/adapters/redocly-loader/ref-access.ts +16 -3
- package/src/adapters/redocly-loader/ref-holders.ts +75 -14
- package/src/adapters/redocly-loader/remote-fetch.ts +11 -2
- package/src/adapters/redocly-loader/remote-node-limit.ts +44 -4
- package/src/adapters/redocly-loader/schema-source.ts +15 -3
- package/src/adapters/terminal-logger/terminal-logger.ts +10 -4
- package/src/api/document-refs.ts +29 -1
- package/src/api/document-run.ts +6 -16
- package/src/api/openapi-ts.ts +6 -3
- package/src/api/ref-limit-options.ts +76 -0
- package/src/api/transform-schema.ts +20 -5
- package/src/application/ports/file-system.ts +8 -0
- package/src/application/transform/declared-value-types.ts +42 -0
- package/src/application/transform/document/document.ts +4 -2
- package/src/application/transform/document/exploded-query-values.ts +88 -0
- package/src/application/transform/document/header.ts +25 -5
- package/src/application/transform/document/parameter.ts +4 -4
- package/src/application/transform/document/parameters.ts +45 -10
- package/src/application/transform/document/path-item.ts +3 -3
- package/src/application/transform/document/path-template-key.ts +152 -0
- package/src/application/transform/document/path-template-refs.ts +106 -0
- package/src/application/transform/document/paths-enum.ts +23 -9
- package/src/application/transform/document/paths.ts +53 -123
- package/src/application/transform/document/webhooks.ts +18 -5
- package/src/application/transform/footer/document-footer.ts +18 -8
- package/src/application/transform/helper-types.ts +4 -4
- package/src/application/transform/ref-pointer/generated-location.ts +1 -1
- package/src/application/transform/ref-pointer/generated-shape.ts +67 -78
- package/src/application/transform/ref-pointer/inline-cycles.ts +1 -1
- package/src/application/transform/ref-pointer/located-node.ts +38 -0
- package/src/application/transform/ref-pointer/original-index.ts +100 -17
- package/src/application/transform/ref-pointer/pointer-type.ts +1 -1
- package/src/application/transform/ref-pointer/pointer-walk.ts +82 -8
- package/src/application/transform/ref-pointer/property-shape.ts +97 -0
- package/src/application/transform/ref-pointer/typed-walk.ts +117 -25
- package/src/application/transform/schema/access-flags.ts +5 -2
- package/src/application/transform/schema/index-signature-type.ts +31 -0
- package/src/application/transform/schema/input-location.ts +35 -0
- package/src/application/transform/schema/object-type.ts +18 -8
- package/src/application/transform/schema/schema-transform.ts +2 -1
- package/src/application/transform/schema/unevaluated-properties.ts +4 -44
- package/src/cli/api-logger.ts +17 -0
- package/src/cli/api-settings.ts +12 -20
- package/src/cli/cli-arguments.ts +90 -14
- package/src/cli/cli-dependencies.ts +7 -2
- package/src/cli/cli-errors.ts +22 -0
- package/src/cli/cli-output.ts +11 -10
- package/src/cli/main.ts +10 -4
- package/src/cli/redocly-apis.ts +37 -17
- package/src/cli/ref-limits.ts +21 -2
- package/src/cli/run-cli.ts +39 -7
- package/src/domain/cause-secrets.ts +59 -25
- package/src/domain/errors.ts +2 -0
- package/src/domain/location-text.ts +12 -0
- package/src/domain/openapi/document-places.ts +78 -0
- package/src/domain/output-fixes.ts +9 -2
- package/src/domain/terminal-text.ts +44 -0
- package/src/domain/warnings.ts +1 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const jsonPointer = require('../../domain/openapi/json-pointer.cjs');
|
|
4
|
+
const refHolders = require('./ref-holders.cjs');
|
|
5
|
+
|
|
6
|
+
const COMPONENTS_KEY = "components";
|
|
7
|
+
const REMOTE_URL_RE = /^https?:\/\//;
|
|
8
|
+
const PATH_SEPARATOR_RE = /[/\\]/;
|
|
9
|
+
const EXTENSION_RE = /\.[^.]+$/;
|
|
10
|
+
const NAME_SUFFIX_STARTS = ["_", "-"];
|
|
11
|
+
const FIRST_SERIAL = 2;
|
|
12
|
+
function isContainer(value) {
|
|
13
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
function componentsOf(document) {
|
|
16
|
+
const components = isContainer(document) ? document[COMPONENTS_KEY] : void 0;
|
|
17
|
+
if (!isContainer(components)) {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
const groups = {};
|
|
21
|
+
for (const [group, entries] of Object.entries(components)) {
|
|
22
|
+
if (isContainer(entries)) {
|
|
23
|
+
groups[group] = entries;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return groups;
|
|
27
|
+
}
|
|
28
|
+
function componentKeysOf(document) {
|
|
29
|
+
const keys = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const [group, entries] of Object.entries(componentsOf(document))) {
|
|
31
|
+
keys.set(group, new Set(Object.keys(entries)));
|
|
32
|
+
}
|
|
33
|
+
return keys;
|
|
34
|
+
}
|
|
35
|
+
function redoclyBaseName(ref) {
|
|
36
|
+
return (ref.split(PATH_SEPARATOR_RE).at(-1) ?? "").replace(EXTENSION_RE, "");
|
|
37
|
+
}
|
|
38
|
+
function queryFreeBaseName(url) {
|
|
39
|
+
const withoutQuery = new URL(url.pathname, url.origin).href;
|
|
40
|
+
return redoclyBaseName(withoutQuery) || url.hostname;
|
|
41
|
+
}
|
|
42
|
+
function queryBaseNames(documentRefs) {
|
|
43
|
+
const names = /* @__PURE__ */ new Map();
|
|
44
|
+
for (const ref of documentRefs) {
|
|
45
|
+
const url = REMOTE_URL_RE.test(ref) && URL.canParse(ref) ? new URL(ref) : void 0;
|
|
46
|
+
if (url === void 0 || url.search === "") {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const named = redoclyBaseName(ref);
|
|
50
|
+
const clean = queryFreeBaseName(url);
|
|
51
|
+
if (named !== clean) {
|
|
52
|
+
names.set(named, clean);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return names;
|
|
56
|
+
}
|
|
57
|
+
function queryFreeName(key, baseNames) {
|
|
58
|
+
const matches = [...baseNames.keys()].filter(
|
|
59
|
+
(named2) => key === named2 || NAME_SUFFIX_STARTS.some((start) => key.startsWith(`${named2}${start}`))
|
|
60
|
+
);
|
|
61
|
+
const named = matches.sort((a, b) => b.length - a.length)[0];
|
|
62
|
+
return named === void 0 ? void 0 : `${baseNames.get(named)}${key.slice(named.length)}`;
|
|
63
|
+
}
|
|
64
|
+
function freeName(name, taken) {
|
|
65
|
+
let free = name;
|
|
66
|
+
for (let serial = FIRST_SERIAL; taken.has(free); serial += 1) {
|
|
67
|
+
free = `${name}-${serial}`;
|
|
68
|
+
}
|
|
69
|
+
return free;
|
|
70
|
+
}
|
|
71
|
+
function renameGroup(entries, keysBefore, baseNames) {
|
|
72
|
+
const renames = /* @__PURE__ */ new Map();
|
|
73
|
+
const taken = new Set(Object.keys(entries));
|
|
74
|
+
for (const key of Object.keys(entries)) {
|
|
75
|
+
const name = keysBefore.has(key) ? void 0 : queryFreeName(key, baseNames);
|
|
76
|
+
if (name !== void 0) {
|
|
77
|
+
taken.delete(key);
|
|
78
|
+
const free = freeName(name, taken);
|
|
79
|
+
taken.add(free);
|
|
80
|
+
renames.set(key, free);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
84
|
+
delete entries[key];
|
|
85
|
+
entries[renames.get(key) ?? key] = value;
|
|
86
|
+
}
|
|
87
|
+
return renames;
|
|
88
|
+
}
|
|
89
|
+
function renamedPointer(pointer, renames) {
|
|
90
|
+
if (!pointer.startsWith(`${jsonPointer.ROOT_POINTER}/`)) {
|
|
91
|
+
return pointer;
|
|
92
|
+
}
|
|
93
|
+
const [components, group = "", name = "", ...rest] = jsonPointer.parseRefPointer(jsonPointer.canonicalRef(pointer));
|
|
94
|
+
const renamed = components === COMPONENTS_KEY ? renames.get(group)?.get(name) : void 0;
|
|
95
|
+
return renamed === void 0 ? pointer : jsonPointer.appendPointer(jsonPointer.ROOT_POINTER, [COMPONENTS_KEY, group, renamed, ...rest]);
|
|
96
|
+
}
|
|
97
|
+
function renamedText(text, renames) {
|
|
98
|
+
const pairs = [...renames.values()].flatMap((group) => [...group]);
|
|
99
|
+
pairs.sort(([a], [b]) => b.length - a.length);
|
|
100
|
+
return pairs.reduce((shown, [old, renamed]) => shown.replaceAll(old, renamed), text);
|
|
101
|
+
}
|
|
102
|
+
function rewriteRefs(document, renaming) {
|
|
103
|
+
for (const { node } of refHolders.findRefHolders(document)) {
|
|
104
|
+
node.$ref = renaming.pointer(node.$ref);
|
|
105
|
+
}
|
|
106
|
+
for (const mapping of refHolders.findMappings(document)) {
|
|
107
|
+
for (const [name, value] of Object.entries(mapping)) {
|
|
108
|
+
if (typeof value === "string") {
|
|
109
|
+
mapping[name] = renaming.pointer(value);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function renameQueryNamedComponents(bundled, keysBefore, documentRefs) {
|
|
115
|
+
const baseNames = queryBaseNames(documentRefs);
|
|
116
|
+
const renames = /* @__PURE__ */ new Map();
|
|
117
|
+
if (baseNames.size > 0) {
|
|
118
|
+
for (const [group, entries] of Object.entries(componentsOf(bundled))) {
|
|
119
|
+
const groupRenames = renameGroup(entries, keysBefore.get(group) ?? /* @__PURE__ */ new Set(), baseNames);
|
|
120
|
+
if (groupRenames.size > 0) {
|
|
121
|
+
renames.set(group, groupRenames);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const renaming = {
|
|
126
|
+
pointer: (pointer) => renamedPointer(pointer, renames),
|
|
127
|
+
text: (text) => renamedText(text, renames)
|
|
128
|
+
};
|
|
129
|
+
if (renames.size > 0) {
|
|
130
|
+
rewriteRefs(bundled, renaming);
|
|
131
|
+
}
|
|
132
|
+
return renaming;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
exports.componentKeysOf = componentKeysOf;
|
|
136
|
+
exports.renameQueryNamedComponents = renameQueryNamedComponents;
|
|
137
|
+
//# sourceMappingURL=query-named-components.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-named-components.cjs","sources":["../../../src/adapters/redocly-loader/query-named-components.ts"],"sourcesContent":["import {\n appendPointer,\n canonicalRef,\n parseRefPointer,\n ROOT_POINTER,\n} from \"../../domain/openapi/json-pointer.js\";\nimport { findMappings, findRefHolders } from \"./ref-holders.js\";\n\n/**\n * Redocly 1.x bundles an external `$ref` into a component named after the last segment of the\n * document's URL, without its extension, when the pointer gives no free name (a `$ref` to a whole\n * document, or two targets with the same pointer). The query stays in that name, and a query holds\n * API keys and signatures, so `https://host/schemas/pet?token=…` became the component\n * `pet?token=…` in the generated file and in messages (threat model T4b). This renames such a\n * component after the URL without its query: `pet`, with a `-2` suffix when that name is taken.\n */\n\ntype Components = Record<string, Record<string, unknown>>;\n\n/** The keys of each `components` group before bundling: the bundle edits the document in place. */\nexport type ComponentKeys = ReadonlyMap<string, ReadonlySet<string>>;\n\n/** Old and new name of each renamed component, per `components` group. */\ntype Renames = Map<string, Map<string, string>>;\n\nconst COMPONENTS_KEY = \"components\";\nconst REMOTE_URL_RE = /^https?:\\/\\//;\nconst PATH_SEPARATOR_RE = /[/\\\\]/;\nconst EXTENSION_RE = /\\.[^.]+$/;\n/** What Redocly puts between the base name and the rest of a component name. */\nconst NAME_SUFFIX_STARTS = [\"_\", \"-\"];\nconst FIRST_SERIAL = 2;\n\nfunction isContainer(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction componentsOf(document: unknown): Components {\n const components = isContainer(document) ? document[COMPONENTS_KEY] : undefined;\n if (!isContainer(components)) {\n return {};\n }\n const groups: Components = {};\n for (const [group, entries] of Object.entries(components)) {\n if (isContainer(entries)) {\n groups[group] = entries;\n }\n }\n return groups;\n}\n\n/** The keys of every `components` group of a document. */\nexport function componentKeysOf(document: unknown): ComponentKeys {\n const keys = new Map<string, ReadonlySet<string>>();\n for (const [group, entries] of Object.entries(componentsOf(document))) {\n keys.set(group, new Set(Object.keys(entries)));\n }\n return keys;\n}\n\n/** The base name Redocly 1.34 gives a document (`refBaseName`): the last segment, no extension. */\nfunction redoclyBaseName(ref: string): string {\n return (ref.split(PATH_SEPARATOR_RE).at(-1) ?? \"\").replace(EXTENSION_RE, \"\");\n}\n\n/**\n * The base name of the URL without its query and fragment. A URL with no last segment\n * (`https://host/?key=…`) is named after its host, so the name is never empty.\n */\nfunction queryFreeBaseName(url: URL): string {\n const withoutQuery = new URL(url.pathname, url.origin).href;\n return redoclyBaseName(withoutQuery) || url.hostname;\n}\n\n/** Each base name Redocly takes from a remote URL with a query, with the name to use instead. */\nfunction queryBaseNames(documentRefs: Iterable<string>): Map<string, string> {\n const names = new Map<string, string>();\n for (const ref of documentRefs) {\n const url = REMOTE_URL_RE.test(ref) && URL.canParse(ref) ? new URL(ref) : undefined;\n if (url === undefined || url.search === \"\") {\n continue;\n }\n const named = redoclyBaseName(ref);\n const clean = queryFreeBaseName(url);\n if (named !== clean) {\n names.set(named, clean);\n }\n }\n return names;\n}\n\n/** The name `key` gets, or undefined when no query base name starts it. */\nfunction queryFreeName(key: string, baseNames: ReadonlyMap<string, string>): string | undefined {\n // The longest base name first: `pet?a=1` must not match as `pet?a` when both were loaded.\n const matches = [...baseNames.keys()].filter(\n (named) =>\n key === named || NAME_SUFFIX_STARTS.some((start) => key.startsWith(`${named}${start}`)),\n );\n const named = matches.sort((a, b) => b.length - a.length)[0];\n return named === undefined ? undefined : `${baseNames.get(named)}${key.slice(named.length)}`;\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let free = name;\n for (let serial = FIRST_SERIAL; taken.has(free); serial += 1) {\n free = `${name}-${serial}`;\n }\n return free;\n}\n\n/** Rename the bundled components of one group in place, keeping their order. */\nfunction renameGroup(\n entries: Record<string, unknown>,\n keysBefore: ReadonlySet<string>,\n baseNames: ReadonlyMap<string, string>,\n): Map<string, string> {\n const renames = new Map<string, string>();\n const taken = new Set(Object.keys(entries));\n for (const key of Object.keys(entries)) {\n const name = keysBefore.has(key) ? undefined : queryFreeName(key, baseNames);\n if (name !== undefined) {\n taken.delete(key);\n const free = freeName(name, taken);\n taken.add(free);\n renames.set(key, free);\n }\n }\n for (const [key, value] of Object.entries(entries)) {\n delete entries[key];\n entries[renames.get(key) ?? key] = value;\n }\n return renames;\n}\n\n/** Rewrites pointers and messages that name a renamed component. */\nexport interface ComponentRenaming {\n /** The pointer with a renamed component's new name; any other text as it is. */\n readonly pointer: (pointer: string) => string;\n /** The text with each renamed component's old name replaced by its new name. */\n readonly text: (text: string) => string;\n}\n\nfunction renamedPointer(pointer: string, renames: Renames): string {\n if (!pointer.startsWith(`${ROOT_POINTER}/`)) {\n return pointer;\n }\n const [components, group = \"\", name = \"\", ...rest] = parseRefPointer(canonicalRef(pointer));\n const renamed = components === COMPONENTS_KEY ? renames.get(group)?.get(name) : undefined;\n return renamed === undefined\n ? pointer\n : appendPointer(ROOT_POINTER, [COMPONENTS_KEY, group, renamed, ...rest]);\n}\n\nfunction renamedText(text: string, renames: Renames): string {\n const pairs = [...renames.values()].flatMap((group) => [...group]);\n // The longest old name first, so a name that starts another one does not split it.\n pairs.sort(([a], [b]) => b.length - a.length);\n return pairs.reduce((shown, [old, renamed]) => shown.replaceAll(old, renamed), text);\n}\n\nfunction rewriteRefs(document: unknown, renaming: ComponentRenaming): void {\n for (const { node } of findRefHolders(document)) {\n node.$ref = renaming.pointer(node.$ref);\n }\n for (const mapping of findMappings(document)) {\n for (const [name, value] of Object.entries(mapping)) {\n if (typeof value === \"string\") {\n mapping[name] = renaming.pointer(value);\n }\n }\n }\n}\n\n/**\n * Rename, in place, the components the bundle named after a URL with a query, and every local\n * `$ref` and `mapping` value that names them. `documentRefs` are the refs of the loaded documents.\n */\nexport function renameQueryNamedComponents(\n bundled: unknown,\n keysBefore: ComponentKeys,\n documentRefs: Iterable<string>,\n): ComponentRenaming {\n const baseNames = queryBaseNames(documentRefs);\n const renames: Renames = new Map();\n if (baseNames.size > 0) {\n for (const [group, entries] of Object.entries(componentsOf(bundled))) {\n const groupRenames = renameGroup(entries, keysBefore.get(group) ?? new Set(), baseNames);\n if (groupRenames.size > 0) {\n renames.set(group, groupRenames);\n }\n }\n }\n const renaming: ComponentRenaming = {\n pointer: (pointer) => renamedPointer(pointer, renames),\n text: (text) => renamedText(text, renames),\n };\n if (renames.size > 0) {\n rewriteRefs(bundled, renaming);\n }\n return renaming;\n}\n"],"names":["named","ROOT_POINTER","parseRefPointer","canonicalRef","appendPointer","findRefHolders","findMappings"],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { ROOT_POINTER, parseRefPointer, canonicalRef, appendPointer } from '../../domain/openapi/json-pointer.mjs';
|
|
2
|
+
import { findRefHolders, findMappings } from './ref-holders.mjs';
|
|
3
|
+
|
|
4
|
+
const COMPONENTS_KEY = "components";
|
|
5
|
+
const REMOTE_URL_RE = /^https?:\/\//;
|
|
6
|
+
const PATH_SEPARATOR_RE = /[/\\]/;
|
|
7
|
+
const EXTENSION_RE = /\.[^.]+$/;
|
|
8
|
+
const NAME_SUFFIX_STARTS = ["_", "-"];
|
|
9
|
+
const FIRST_SERIAL = 2;
|
|
10
|
+
function isContainer(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function componentsOf(document) {
|
|
14
|
+
const components = isContainer(document) ? document[COMPONENTS_KEY] : void 0;
|
|
15
|
+
if (!isContainer(components)) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
const groups = {};
|
|
19
|
+
for (const [group, entries] of Object.entries(components)) {
|
|
20
|
+
if (isContainer(entries)) {
|
|
21
|
+
groups[group] = entries;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return groups;
|
|
25
|
+
}
|
|
26
|
+
function componentKeysOf(document) {
|
|
27
|
+
const keys = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const [group, entries] of Object.entries(componentsOf(document))) {
|
|
29
|
+
keys.set(group, new Set(Object.keys(entries)));
|
|
30
|
+
}
|
|
31
|
+
return keys;
|
|
32
|
+
}
|
|
33
|
+
function redoclyBaseName(ref) {
|
|
34
|
+
return (ref.split(PATH_SEPARATOR_RE).at(-1) ?? "").replace(EXTENSION_RE, "");
|
|
35
|
+
}
|
|
36
|
+
function queryFreeBaseName(url) {
|
|
37
|
+
const withoutQuery = new URL(url.pathname, url.origin).href;
|
|
38
|
+
return redoclyBaseName(withoutQuery) || url.hostname;
|
|
39
|
+
}
|
|
40
|
+
function queryBaseNames(documentRefs) {
|
|
41
|
+
const names = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const ref of documentRefs) {
|
|
43
|
+
const url = REMOTE_URL_RE.test(ref) && URL.canParse(ref) ? new URL(ref) : void 0;
|
|
44
|
+
if (url === void 0 || url.search === "") {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const named = redoclyBaseName(ref);
|
|
48
|
+
const clean = queryFreeBaseName(url);
|
|
49
|
+
if (named !== clean) {
|
|
50
|
+
names.set(named, clean);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return names;
|
|
54
|
+
}
|
|
55
|
+
function queryFreeName(key, baseNames) {
|
|
56
|
+
const matches = [...baseNames.keys()].filter(
|
|
57
|
+
(named2) => key === named2 || NAME_SUFFIX_STARTS.some((start) => key.startsWith(`${named2}${start}`))
|
|
58
|
+
);
|
|
59
|
+
const named = matches.sort((a, b) => b.length - a.length)[0];
|
|
60
|
+
return named === void 0 ? void 0 : `${baseNames.get(named)}${key.slice(named.length)}`;
|
|
61
|
+
}
|
|
62
|
+
function freeName(name, taken) {
|
|
63
|
+
let free = name;
|
|
64
|
+
for (let serial = FIRST_SERIAL; taken.has(free); serial += 1) {
|
|
65
|
+
free = `${name}-${serial}`;
|
|
66
|
+
}
|
|
67
|
+
return free;
|
|
68
|
+
}
|
|
69
|
+
function renameGroup(entries, keysBefore, baseNames) {
|
|
70
|
+
const renames = /* @__PURE__ */ new Map();
|
|
71
|
+
const taken = new Set(Object.keys(entries));
|
|
72
|
+
for (const key of Object.keys(entries)) {
|
|
73
|
+
const name = keysBefore.has(key) ? void 0 : queryFreeName(key, baseNames);
|
|
74
|
+
if (name !== void 0) {
|
|
75
|
+
taken.delete(key);
|
|
76
|
+
const free = freeName(name, taken);
|
|
77
|
+
taken.add(free);
|
|
78
|
+
renames.set(key, free);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
82
|
+
delete entries[key];
|
|
83
|
+
entries[renames.get(key) ?? key] = value;
|
|
84
|
+
}
|
|
85
|
+
return renames;
|
|
86
|
+
}
|
|
87
|
+
function renamedPointer(pointer, renames) {
|
|
88
|
+
if (!pointer.startsWith(`${ROOT_POINTER}/`)) {
|
|
89
|
+
return pointer;
|
|
90
|
+
}
|
|
91
|
+
const [components, group = "", name = "", ...rest] = parseRefPointer(canonicalRef(pointer));
|
|
92
|
+
const renamed = components === COMPONENTS_KEY ? renames.get(group)?.get(name) : void 0;
|
|
93
|
+
return renamed === void 0 ? pointer : appendPointer(ROOT_POINTER, [COMPONENTS_KEY, group, renamed, ...rest]);
|
|
94
|
+
}
|
|
95
|
+
function renamedText(text, renames) {
|
|
96
|
+
const pairs = [...renames.values()].flatMap((group) => [...group]);
|
|
97
|
+
pairs.sort(([a], [b]) => b.length - a.length);
|
|
98
|
+
return pairs.reduce((shown, [old, renamed]) => shown.replaceAll(old, renamed), text);
|
|
99
|
+
}
|
|
100
|
+
function rewriteRefs(document, renaming) {
|
|
101
|
+
for (const { node } of findRefHolders(document)) {
|
|
102
|
+
node.$ref = renaming.pointer(node.$ref);
|
|
103
|
+
}
|
|
104
|
+
for (const mapping of findMappings(document)) {
|
|
105
|
+
for (const [name, value] of Object.entries(mapping)) {
|
|
106
|
+
if (typeof value === "string") {
|
|
107
|
+
mapping[name] = renaming.pointer(value);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function renameQueryNamedComponents(bundled, keysBefore, documentRefs) {
|
|
113
|
+
const baseNames = queryBaseNames(documentRefs);
|
|
114
|
+
const renames = /* @__PURE__ */ new Map();
|
|
115
|
+
if (baseNames.size > 0) {
|
|
116
|
+
for (const [group, entries] of Object.entries(componentsOf(bundled))) {
|
|
117
|
+
const groupRenames = renameGroup(entries, keysBefore.get(group) ?? /* @__PURE__ */ new Set(), baseNames);
|
|
118
|
+
if (groupRenames.size > 0) {
|
|
119
|
+
renames.set(group, groupRenames);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const renaming = {
|
|
124
|
+
pointer: (pointer) => renamedPointer(pointer, renames),
|
|
125
|
+
text: (text) => renamedText(text, renames)
|
|
126
|
+
};
|
|
127
|
+
if (renames.size > 0) {
|
|
128
|
+
rewriteRefs(bundled, renaming);
|
|
129
|
+
}
|
|
130
|
+
return renaming;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export { componentKeysOf, renameQueryNamedComponents };
|
|
134
|
+
//# sourceMappingURL=query-named-components.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-named-components.mjs","sources":["../../../src/adapters/redocly-loader/query-named-components.ts"],"sourcesContent":["import {\n appendPointer,\n canonicalRef,\n parseRefPointer,\n ROOT_POINTER,\n} from \"../../domain/openapi/json-pointer.js\";\nimport { findMappings, findRefHolders } from \"./ref-holders.js\";\n\n/**\n * Redocly 1.x bundles an external `$ref` into a component named after the last segment of the\n * document's URL, without its extension, when the pointer gives no free name (a `$ref` to a whole\n * document, or two targets with the same pointer). The query stays in that name, and a query holds\n * API keys and signatures, so `https://host/schemas/pet?token=…` became the component\n * `pet?token=…` in the generated file and in messages (threat model T4b). This renames such a\n * component after the URL without its query: `pet`, with a `-2` suffix when that name is taken.\n */\n\ntype Components = Record<string, Record<string, unknown>>;\n\n/** The keys of each `components` group before bundling: the bundle edits the document in place. */\nexport type ComponentKeys = ReadonlyMap<string, ReadonlySet<string>>;\n\n/** Old and new name of each renamed component, per `components` group. */\ntype Renames = Map<string, Map<string, string>>;\n\nconst COMPONENTS_KEY = \"components\";\nconst REMOTE_URL_RE = /^https?:\\/\\//;\nconst PATH_SEPARATOR_RE = /[/\\\\]/;\nconst EXTENSION_RE = /\\.[^.]+$/;\n/** What Redocly puts between the base name and the rest of a component name. */\nconst NAME_SUFFIX_STARTS = [\"_\", \"-\"];\nconst FIRST_SERIAL = 2;\n\nfunction isContainer(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction componentsOf(document: unknown): Components {\n const components = isContainer(document) ? document[COMPONENTS_KEY] : undefined;\n if (!isContainer(components)) {\n return {};\n }\n const groups: Components = {};\n for (const [group, entries] of Object.entries(components)) {\n if (isContainer(entries)) {\n groups[group] = entries;\n }\n }\n return groups;\n}\n\n/** The keys of every `components` group of a document. */\nexport function componentKeysOf(document: unknown): ComponentKeys {\n const keys = new Map<string, ReadonlySet<string>>();\n for (const [group, entries] of Object.entries(componentsOf(document))) {\n keys.set(group, new Set(Object.keys(entries)));\n }\n return keys;\n}\n\n/** The base name Redocly 1.34 gives a document (`refBaseName`): the last segment, no extension. */\nfunction redoclyBaseName(ref: string): string {\n return (ref.split(PATH_SEPARATOR_RE).at(-1) ?? \"\").replace(EXTENSION_RE, \"\");\n}\n\n/**\n * The base name of the URL without its query and fragment. A URL with no last segment\n * (`https://host/?key=…`) is named after its host, so the name is never empty.\n */\nfunction queryFreeBaseName(url: URL): string {\n const withoutQuery = new URL(url.pathname, url.origin).href;\n return redoclyBaseName(withoutQuery) || url.hostname;\n}\n\n/** Each base name Redocly takes from a remote URL with a query, with the name to use instead. */\nfunction queryBaseNames(documentRefs: Iterable<string>): Map<string, string> {\n const names = new Map<string, string>();\n for (const ref of documentRefs) {\n const url = REMOTE_URL_RE.test(ref) && URL.canParse(ref) ? new URL(ref) : undefined;\n if (url === undefined || url.search === \"\") {\n continue;\n }\n const named = redoclyBaseName(ref);\n const clean = queryFreeBaseName(url);\n if (named !== clean) {\n names.set(named, clean);\n }\n }\n return names;\n}\n\n/** The name `key` gets, or undefined when no query base name starts it. */\nfunction queryFreeName(key: string, baseNames: ReadonlyMap<string, string>): string | undefined {\n // The longest base name first: `pet?a=1` must not match as `pet?a` when both were loaded.\n const matches = [...baseNames.keys()].filter(\n (named) =>\n key === named || NAME_SUFFIX_STARTS.some((start) => key.startsWith(`${named}${start}`)),\n );\n const named = matches.sort((a, b) => b.length - a.length)[0];\n return named === undefined ? undefined : `${baseNames.get(named)}${key.slice(named.length)}`;\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let free = name;\n for (let serial = FIRST_SERIAL; taken.has(free); serial += 1) {\n free = `${name}-${serial}`;\n }\n return free;\n}\n\n/** Rename the bundled components of one group in place, keeping their order. */\nfunction renameGroup(\n entries: Record<string, unknown>,\n keysBefore: ReadonlySet<string>,\n baseNames: ReadonlyMap<string, string>,\n): Map<string, string> {\n const renames = new Map<string, string>();\n const taken = new Set(Object.keys(entries));\n for (const key of Object.keys(entries)) {\n const name = keysBefore.has(key) ? undefined : queryFreeName(key, baseNames);\n if (name !== undefined) {\n taken.delete(key);\n const free = freeName(name, taken);\n taken.add(free);\n renames.set(key, free);\n }\n }\n for (const [key, value] of Object.entries(entries)) {\n delete entries[key];\n entries[renames.get(key) ?? key] = value;\n }\n return renames;\n}\n\n/** Rewrites pointers and messages that name a renamed component. */\nexport interface ComponentRenaming {\n /** The pointer with a renamed component's new name; any other text as it is. */\n readonly pointer: (pointer: string) => string;\n /** The text with each renamed component's old name replaced by its new name. */\n readonly text: (text: string) => string;\n}\n\nfunction renamedPointer(pointer: string, renames: Renames): string {\n if (!pointer.startsWith(`${ROOT_POINTER}/`)) {\n return pointer;\n }\n const [components, group = \"\", name = \"\", ...rest] = parseRefPointer(canonicalRef(pointer));\n const renamed = components === COMPONENTS_KEY ? renames.get(group)?.get(name) : undefined;\n return renamed === undefined\n ? pointer\n : appendPointer(ROOT_POINTER, [COMPONENTS_KEY, group, renamed, ...rest]);\n}\n\nfunction renamedText(text: string, renames: Renames): string {\n const pairs = [...renames.values()].flatMap((group) => [...group]);\n // The longest old name first, so a name that starts another one does not split it.\n pairs.sort(([a], [b]) => b.length - a.length);\n return pairs.reduce((shown, [old, renamed]) => shown.replaceAll(old, renamed), text);\n}\n\nfunction rewriteRefs(document: unknown, renaming: ComponentRenaming): void {\n for (const { node } of findRefHolders(document)) {\n node.$ref = renaming.pointer(node.$ref);\n }\n for (const mapping of findMappings(document)) {\n for (const [name, value] of Object.entries(mapping)) {\n if (typeof value === \"string\") {\n mapping[name] = renaming.pointer(value);\n }\n }\n }\n}\n\n/**\n * Rename, in place, the components the bundle named after a URL with a query, and every local\n * `$ref` and `mapping` value that names them. `documentRefs` are the refs of the loaded documents.\n */\nexport function renameQueryNamedComponents(\n bundled: unknown,\n keysBefore: ComponentKeys,\n documentRefs: Iterable<string>,\n): ComponentRenaming {\n const baseNames = queryBaseNames(documentRefs);\n const renames: Renames = new Map();\n if (baseNames.size > 0) {\n for (const [group, entries] of Object.entries(componentsOf(bundled))) {\n const groupRenames = renameGroup(entries, keysBefore.get(group) ?? new Set(), baseNames);\n if (groupRenames.size > 0) {\n renames.set(group, groupRenames);\n }\n }\n }\n const renaming: ComponentRenaming = {\n pointer: (pointer) => renamedPointer(pointer, renames),\n text: (text) => renamedText(text, renames),\n };\n if (renames.size > 0) {\n rewriteRefs(bundled, renaming);\n }\n return renaming;\n}\n"],"names":["named"],"mappings":"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"}
|
|
@@ -3,11 +3,14 @@
|
|
|
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 urlSecrets = require('../../domain/url-secrets.cjs');
|
|
6
7
|
const warnings = require('../../domain/warnings.cjs');
|
|
7
8
|
const bundledMappingCopies = require('./bundled-mapping-copies.cjs');
|
|
8
9
|
const bundledRefRepair = require('./bundled-ref-repair.cjs');
|
|
9
10
|
const loadedDocuments = require('./loaded-documents.cjs');
|
|
10
11
|
const malformedRefs = require('./malformed-refs.cjs');
|
|
12
|
+
const mappingSchemaNames = require('./mapping-schema-names.cjs');
|
|
13
|
+
const queryNamedComponents = require('./query-named-components.cjs');
|
|
11
14
|
const refAccess = require('./ref-access.cjs');
|
|
12
15
|
const refResolutionCheck = require('./ref-resolution-check.cjs');
|
|
13
16
|
const refResolutionSteps = require('./ref-resolution-steps.cjs');
|
|
@@ -93,6 +96,7 @@ class RedoclySchemaLoader {
|
|
|
93
96
|
const document = await schemaSource.parseSchema(request.source, { absoluteRef, resolver });
|
|
94
97
|
logger.debug("Parsed schema", "redoc", now() - parseStartedAt);
|
|
95
98
|
assertOpenAPI3(document.parsed);
|
|
99
|
+
mappingSchemaNames.pointMappingNamesAtSchemas(document.parsed);
|
|
96
100
|
const bundled = await this.#lintAndBundle(document, resolver, request.shouldLint);
|
|
97
101
|
const isRootAFile = request.source instanceof URL && request.source.protocol === "file:";
|
|
98
102
|
const localFiles = await loadedDocuments.localFilesRead(document, resolver, isRootAFile);
|
|
@@ -103,6 +107,7 @@ class RedoclySchemaLoader {
|
|
|
103
107
|
const config = remoteFetch.resolveConfigWithAccess(redoc.resolve, {
|
|
104
108
|
timeoutMs: remoteRefTimeoutMs,
|
|
105
109
|
access: request.refAccess,
|
|
110
|
+
rootUrl: request.source instanceof URL ? request.source.href : void 0,
|
|
106
111
|
maxParallelFetches: remoteDocumentLimits.maxParallelFetches,
|
|
107
112
|
bodyLimits: remoteDocumentLimits
|
|
108
113
|
});
|
|
@@ -127,21 +132,24 @@ class RedoclySchemaLoader {
|
|
|
127
132
|
config: this.#options.redoc.styleguide,
|
|
128
133
|
externalRefResolver: resolver
|
|
129
134
|
});
|
|
130
|
-
this.#report(problems);
|
|
135
|
+
this.#report(problems, document.source.absoluteRef);
|
|
131
136
|
this.#options.logger.debug("Linted schema", "lint", this.#options.now() - startedAt);
|
|
132
137
|
}
|
|
133
138
|
async #bundle(document, resolver) {
|
|
134
139
|
const startedAt = this.#options.now();
|
|
135
140
|
const schemaKeys = bundledMappingCopies.schemaKeysOf(document.parsed);
|
|
141
|
+
const componentKeys = queryNamedComponents.componentKeysOf(document.parsed);
|
|
136
142
|
const bundled = await openapiCore.bundle({
|
|
137
143
|
config: this.#options.redoc,
|
|
138
144
|
dereference: false,
|
|
139
145
|
doc: document,
|
|
140
146
|
externalRefResolver: resolver
|
|
141
147
|
});
|
|
142
|
-
this.#report(bundled.problems);
|
|
143
148
|
bundledMappingCopies.removeBundledMappingCopies(bundled.bundle.parsed, schemaKeys);
|
|
144
149
|
bundledRefRepair.repairBundledRefs(bundled.bundle.parsed);
|
|
150
|
+
const documentRefs = resolver.getFiles();
|
|
151
|
+
const renaming = queryNamedComponents.renameQueryNamedComponents(bundled.bundle.parsed, componentKeys, documentRefs);
|
|
152
|
+
this.#report(bundled.problems, document.source.absoluteRef, renaming);
|
|
145
153
|
this.#options.logger.debug("Bundled schema", "bundle", this.#options.now() - startedAt);
|
|
146
154
|
return bundled.bundle.parsed;
|
|
147
155
|
}
|
|
@@ -150,22 +158,22 @@ class RedoclySchemaLoader {
|
|
|
150
158
|
* config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out
|
|
151
159
|
* (upstream #2189).
|
|
152
160
|
*/
|
|
153
|
-
#report(problems) {
|
|
161
|
+
#report(problems, rootRef, renaming = UNRENAMED) {
|
|
154
162
|
const errorMessages = [];
|
|
155
163
|
for (const problem of problems) {
|
|
156
164
|
if (problem.ignored === true) {
|
|
157
165
|
this.#options.logger.debug(
|
|
158
|
-
`Ignored by the lint ignore file: ${problemMessage(problem)}`,
|
|
166
|
+
`Ignored by the lint ignore file: ${problemMessage(problem, renaming, rootRef)}`,
|
|
159
167
|
"lint"
|
|
160
168
|
);
|
|
161
169
|
continue;
|
|
162
170
|
}
|
|
163
|
-
const message = problemMessage(problem);
|
|
171
|
+
const message = problemMessage(problem, renaming, rootRef);
|
|
164
172
|
if (problem.severity === "error") {
|
|
165
173
|
errorMessages.push(message);
|
|
166
174
|
this.#options.logger.error(message);
|
|
167
175
|
} else {
|
|
168
|
-
this.#options.logger.warn(lintWarningText(problem));
|
|
176
|
+
this.#options.logger.warn(lintWarningText(message, problem.ruleId));
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
if (errorMessages.length > 0) {
|
|
@@ -173,15 +181,19 @@ class RedoclySchemaLoader {
|
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
|
-
function lintWarningText(
|
|
177
|
-
return warnings.warningText(
|
|
178
|
-
`${problemMessage(problem)}, rule ${problem.ruleId}`,
|
|
179
|
-
warnings.WARNING_CODES.LINT_PROBLEM
|
|
180
|
-
);
|
|
184
|
+
function lintWarningText(message, ruleId) {
|
|
185
|
+
return warnings.warningText(`${message}, rule ${ruleId}`, warnings.WARNING_CODES.LINT_PROBLEM);
|
|
181
186
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
const UNRENAMED = { pointer: (pointer) => pointer, text: (text) => text };
|
|
188
|
+
function locationText(location, renaming, rootRef) {
|
|
189
|
+
const pointer = renaming.pointer(location.pointer);
|
|
190
|
+
const documentRef = location.source.absoluteRef;
|
|
191
|
+
return documentRef === rootRef ? pointer : `${pointer} in ${urlSecrets.redactUrlSecrets(documentRef)}`;
|
|
192
|
+
}
|
|
193
|
+
function problemMessage(problem, renaming, rootRef) {
|
|
194
|
+
const location = problem.location?.[0];
|
|
195
|
+
const message = renaming.text(problem.message);
|
|
196
|
+
return location?.pointer ? `${message} at ${locationText(location, renaming, rootRef)}` : message;
|
|
185
197
|
}
|
|
186
198
|
function createRedoclySchemaLoader(options) {
|
|
187
199
|
return new RedoclySchemaLoader(options);
|
|
@@ -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 {\n LoadedSchema,\n SchemaLoader,\n SchemaLoadRequest,\n} 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 { removeBundledMappingCopies, schemaKeysOf } from \"./bundled-mapping-copies.js\";\nimport { repairBundledRefs } from \"./bundled-ref-repair.js\";\nimport { loadedDocuments, localFilesRead } from \"./loaded-documents.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 { findUnsupportedKeys, unsupportedKeysError } 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/** 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<LoadedSchema> {\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<LoadedSchema> {\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 const bundled = await this.#lintAndBundle(document, resolver, request.shouldLint);\n const isRootAFile = request.source instanceof URL && request.source.protocol === \"file:\";\n const localFiles = await localFilesRead(document, resolver, isRootAFile);\n return { document: bundled, localFiles };\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 bodyLimits: remoteDocumentLimits,\n });\n return new RefAccessResolver(config, {\n access: request.refAccess,\n maxRemoteDocuments: remoteDocumentLimits.maxDocuments,\n maxRemoteNodes: remoteDocumentLimits.maxNodes,\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 const schemaKeys = schemaKeysOf(document.parsed);\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 removeBundledMappingCopies(bundled.bundle.parsed, schemaKeys);\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","loadedDocuments","findUnsupportedKeys","unsupportedKeysError","withStackOverflowReportedAsync","parseSchema","localFilesRead","resolveConfigWithAccess","RefAccessResolver","checkRefsResolve","lintDocument","schemaKeysOf","bundle","removeBundledMappingCopies","repairBundledRefs","schemaInvalidError","warningText","WARNING_CODES"],"mappings":";;;;;;;;;;;;;;;;;;AAiDA,MAAM,0BAAA,GAA6B,oDAAA;AAMnC,SAAS,eAAe,QAAA,EAAyB;AAC/C,EAAA,IAAI,OAAO,QAAA,KAAa,QAAA,IAAY,QAAA,KAAa,IAAA,EAAM;AACrD,IAAA,MAAMA,wCAAA,CAAwB,0BAAA,EAA4B,EAAE,CAAA;AAAA,EAC9D;AACA,EAAA,MAAM,MAAA,GAAS,QAAA;AACf,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,UAAA,CAAW,MAAA,CAAO,OAAiB,CAAA;AACjE,EAAA,MAAM,UAAA,GACJ,CAAC,MAAA,CAAO,OAAA,IACR,QAAQ,MAAA,CAAO,OAAO,CAAA,IACtB,CAAC,OAAO,KAAA,CAAM,cAAc,CAAA,IAC5B,cAAA,IAAkB,KAClB,cAAA,GAAiB,CAAA;AACnB,EAAA,IAAI,UAAA,EAAY;AACd,IAAA;AAAA,EACF;AACA,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,MAAMA,wCAAA;AAAA,MACJ,4DAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,MAAA,CAAO,OAAA,IAAW,cAAA,GAAiB,CAAA,IAAK,kBAAkB,CAAA,EAAG;AAC/D,IAAA,MAAMA,wCAAA,CAAwB,CAAA,6BAAA,EAAgC,MAAA,CAAO,OAAO,IAAI,MAAM,CAAA;AAAA,EACxF;AACA,EAAA,MAAMA,wCAAA,CAAwB,4BAA4B,MAAM,CAAA;AAClE;AAOA,MAAM,kBAAA,GAAqB,eAAA;AAG3B,SAAS,iBAAA,CAAkB,QAAiB,GAAA,EAAkB;AAC5D,EAAA,MAAM,WAAW,MAAA,YAAkB,GAAA,GAAM,SAAS,IAAI,GAAA,CAAI,oBAAoB,GAAG,CAAA;AACjF,EAAA,OAAO,SAAS,QAAA,KAAa,OAAA,GAAU,cAAA,CAAe,QAAQ,IAAI,QAAA,CAAS,IAAA;AAC7E;AAMA,SAAS,eAAe,MAAA,EAAqB;AAC3C,EAAA,IAAI;AACF,IAAA,OAAOC,uBAAc,MAAM,CAAA;AAAA,EAC7B,SAAS,KAAA,EAAO;AAEd,IAAA,IAAI,EAAE,iBAAiB,SAAA,CAAA,EAAY;AACjC,MAAA,MAAM,KAAA;AAAA,IACR;AACA,IAAA,MAAMC,gCAAA,CAAgB,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAAA,EAC1C;AACF;AAGA,eAAe,oBAAA,CACb,KAAA,EACA,IAAA,EACA,QAAA,EACgB;AAChB,EAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,OAAA,KAAYC,oCAAA,EAAmB;AACjE,IAAA,MAAMC,+BAAc,KAAK,CAAA;AAAA,EAC3B;AACA,EAAA,IAAI,iBAAiB,QAAA,EAAU;AAC7B,IAAA,MAAMC,gCAAA,CAAmBC,gCAAkB,MAAMC,+BAAA,CAAgB,MAAM,QAAQ,CAAC,GAAG,KAAK,CAAA;AAAA,EAC1F;AACA,EAAA,IAAI,iBAAiB,SAAA,EAAW;AAC9B,IAAA,MAAM,OAAOC,mCAAA,CAAoB,MAAMD,+BAAA,CAAgB,IAAA,EAAM,QAAQ,CAAC,CAAA;AACtE,IAAA,MAAM,KAAK,MAAA,KAAW,CAAA,GAAI,KAAA,GAAQE,oCAAA,CAAqB,MAAM,KAAK,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,KAAA;AACR;AAEA,MAAM,mBAAA,CAA4C;AAAA,EACvC,QAAA;AAAA,EAET,YAAY,OAAA,EAAqC;AAC/C,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAAA,EAClB;AAAA,EAEA,MAAM,KAAK,OAAA,EAAmD;AAC5D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAGvC,IAAA,MAAM,UAAU,MAAMC,4CAAA;AAAA,MAA+B,MAAA;AAAA,MAAQ,MAC3D,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,QAAQ;AAAA,KACxC,CAAE,KAAA,CAAM,CAAC,KAAA,KAAmB;AAC1B,MAAA,MAAM,SAAS,YAAA,IAAgB,KAAA;AAAA,IACjC,CAAC,CAAA;AAED,IAAA,IAAI,QAAA,CAAS,iBAAiB,MAAA,EAAW;AACvC,MAAA,MAAM,QAAA,CAAS,YAAA;AAAA,IACjB;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,eAAA,CAAgB,OAAA,EAA4B,QAAA,EAA+C;AAC/F,IAAA,MAAM,EAAE,MAAA,EAAQ,GAAA,EAAI,GAAI,IAAA,CAAK,QAAA;AAC7B,IAAA,MAAM,iBAAiB,GAAA,EAAI;AAC3B,IAAA,MAAA,CAAO,KAAA,CAAM,qBAAA,EAAuB,OAAA,EAAS,GAAA,KAAQ,cAAc,CAAA;AACnE,IAAA,MAAM,iBAAiB,GAAA,EAAI;AAC3B,IAAA,MAAM,WAAA,GAAc,iBAAA,CAAkB,OAAA,CAAQ,MAAA,EAAQ,QAAQ,GAAG,CAAA;AACjE,IAAA,MAAM,QAAA,GAAW,MAAMC,wBAAA,CAAY,OAAA,CAAQ,QAAQ,EAAE,WAAA,EAAa,UAAU,CAAA;AAC5E,IAAA,MAAA,CAAO,KAAA,CAAM,eAAA,EAAiB,OAAA,EAAS,GAAA,KAAQ,cAAc,CAAA;AAC7D,IAAA,cAAA,CAAe,SAAS,MAAM,CAAA;AAC9B,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,eAAe,QAAA,EAAU,QAAA,EAAU,QAAQ,UAAU,CAAA;AAChF,IAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,YAAkB,GAAA,IAAO,OAAA,CAAQ,OAAO,QAAA,KAAa,OAAA;AACjF,IAAA,MAAM,UAAA,GAAa,MAAMC,8BAAA,CAAe,QAAA,EAAU,UAAU,WAAW,CAAA;AACvE,IAAA,OAAO,EAAE,QAAA,EAAU,OAAA,EAAS,UAAA,EAAW;AAAA,EACzC;AAAA,EAEA,UAAU,OAAA,EAA+C;AACvD,IAAA,MAAM,EAAE,KAAA,EAAO,kBAAA,EAAoB,oBAAA,KAAyB,IAAA,CAAK,QAAA;AACjE,IAAA,MAAM,MAAA,GAASC,mCAAA,CAAwB,KAAA,CAAM,OAAA,EAAS;AAAA,MACpD,SAAA,EAAW,kBAAA;AAAA,MACX,QAAQ,OAAA,CAAQ,SAAA;AAAA,MAChB,oBAAoB,oBAAA,CAAqB,kBAAA;AAAA,MACzC,UAAA,EAAY;AAAA,KACb,CAAA;AACD,IAAA,OAAO,IAAIC,4BAAkB,MAAA,EAAQ;AAAA,MACnC,QAAQ,OAAA,CAAQ,SAAA;AAAA,MAChB,oBAAoB,oBAAA,CAAqB,YAAA;AAAA,MACzC,gBAAgB,oBAAA,CAAqB;AAAA,KACtC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,cAAA,CACJ,QAAA,EACA,QAAA,EACA,UAAA,EACmB;AACnB,IAAA,MAAM,UAAU,CAAC,KAAA,KAAmB,oBAAA,CAAqB,KAAA,EAAO,UAAU,QAAQ,CAAA;AAElF,IAAA,MAAMC,mCAAA,CAAiB,UAAU,QAAA,EAAU,IAAA,CAAK,SAAS,KAAA,CAAM,UAAU,CAAA,CAAE,KAAA,CAAM,OAAO,CAAA;AACxF,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,KAAK,KAAA,CAAM,QAAA,EAAU,QAAQ,CAAA,CAAE,MAAM,OAAO,CAAA;AAAA,IACpD;AACA,IAAA,OAAO,KAAK,OAAA,CAAQ,QAAA,EAAU,QAAQ,CAAA,CAAE,MAAM,OAAO,CAAA;AAAA,EACvD;AAAA,EAEA,MAAM,KAAA,CAAM,QAAA,EAAoB,QAAA,EAAuC;AACrE,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,GAAA,EAAI;AACpC,IAAA,MAAM,QAAA,GAAW,MAAMC,wBAAA,CAAa;AAAA,MAClC,QAAA;AAAA,MACA,MAAA,EAAQ,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,UAAA;AAAA,MAC5B,mBAAA,EAAqB;AAAA,KACtB,CAAA;AACD,IAAA,IAAA,CAAK,QAAQ,QAAQ,CAAA;AACrB,IAAA,IAAA,CAAK,QAAA,CAAS,OAAO,KAAA,CAAM,eAAA,EAAiB,QAAQ,IAAA,CAAK,QAAA,CAAS,GAAA,EAAI,GAAI,SAAS,CAAA;AAAA,EACrF;AAAA,EAEA,MAAM,OAAA,CAAQ,QAAA,EAAoB,QAAA,EAA2C;AAC3E,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,GAAA,EAAI;AACpC,IAAA,MAAM,UAAA,GAAaC,iCAAA,CAAa,QAAA,CAAS,MAAM,CAAA;AAE/C,IAAA,MAAM,OAAA,GAAU,MAAMC,kBAAA,CAAO;AAAA,MAC3B,MAAA,EAAQ,KAAK,QAAA,CAAS,KAAA;AAAA,MACtB,WAAA,EAAa,KAAA;AAAA,MACb,GAAA,EAAK,QAAA;AAAA,MACL,mBAAA,EAAqB;AAAA,KACtB,CAAA;AACD,IAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,QAAQ,CAAA;AAC7B,IAAAC,+CAAA,CAA2B,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,UAAU,CAAA;AAC5D,IAAAC,kCAAA,CAAkB,OAAA,CAAQ,OAAO,MAAM,CAAA;AACvC,IAAA,IAAA,CAAK,QAAA,CAAS,OAAO,KAAA,CAAM,gBAAA,EAAkB,UAAU,IAAA,CAAK,QAAA,CAAS,GAAA,EAAI,GAAI,SAAS,CAAA;AACtF,IAAA,OAAO,QAAQ,MAAA,CAAO,MAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,QAAA,EAA8C;AACpD,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,IAAI,OAAA,CAAQ,YAAY,IAAA,EAAM;AAC5B,QAAA,IAAA,CAAK,SAAS,MAAA,CAAO,KAAA;AAAA,UACnB,CAAA,iCAAA,EAAoC,cAAA,CAAe,OAAO,CAAC,CAAA,CAAA;AAAA,UAC3D;AAAA,SACF;AACA,QAAA;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,eAAe,OAAO,CAAA;AACtC,MAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAChC,QAAA,aAAA,CAAc,KAAK,OAAO,CAAA;AAC1B,QAAA,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,OAAO,CAAC,CAAA;AAAA,MACpD;AAAA,IACF;AACA,IAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,MAAA,MAAMC,oCAAmB,aAAa,CAAA;AAAA,IACxC;AAAA,EACF;AACF;AAGA,SAAS,gBAAgB,OAAA,EAAoC;AAC3D,EAAA,OAAOC,oBAAA;AAAA,IACL,GAAG,cAAA,CAAe,OAAO,CAAC,CAAA,OAAA,EAAU,QAAQ,MAAM,CAAA,CAAA;AAAA,IAClDC,sBAAA,CAAc;AAAA,GAChB;AACF;AAEA,SAAS,eAAe,OAAA,EAAoC;AAC1D,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,GAAW,CAAC,CAAA,EAAG,OAAA;AACxC,EAAA,OAAO,WAAW,CAAA,EAAG,OAAA,CAAQ,OAAO,CAAA,IAAA,EAAO,QAAQ,KAAK,OAAA,CAAQ,OAAA;AAClE;AAGO,SAAS,0BAA0B,OAAA,EAAmD;AAC3F,EAAA,OAAO,IAAI,oBAAoB,OAAO,CAAA;AACxC;;"}
|
|
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 type LocationObject,\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 {\n LoadedSchema,\n SchemaLoader,\n SchemaLoadRequest,\n} from \"../../application/ports/schema-loader.js\";\nimport { withStackOverflowReportedAsync } from \"../../application/stack-overflow.js\";\nimport { redactUrlSecrets } from \"../../domain/url-secrets.js\";\nimport { WARNING_CODES, warningText } from \"../../domain/warnings.js\";\nimport type { OpenAPI3 } from \"../../types.js\";\nimport { removeBundledMappingCopies, schemaKeysOf } from \"./bundled-mapping-copies.js\";\nimport { repairBundledRefs } from \"./bundled-ref-repair.js\";\nimport { loadedDocuments, localFilesRead } from \"./loaded-documents.js\";\nimport { findMalformedRefs, malformedRefsError } from \"./malformed-refs.js\";\nimport { pointMappingNamesAtSchemas } from \"./mapping-schema-names.js\";\nimport {\n type ComponentRenaming,\n componentKeysOf,\n renameQueryNamedComponents,\n} from \"./query-named-components.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 { findUnsupportedKeys, unsupportedKeysError } 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/** 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<LoadedSchema> {\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<LoadedSchema> {\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 pointMappingNamesAtSchemas(document.parsed);\n const bundled = await this.#lintAndBundle(document, resolver, request.shouldLint);\n const isRootAFile = request.source instanceof URL && request.source.protocol === \"file:\";\n const localFiles = await localFilesRead(document, resolver, isRootAFile);\n return { document: bundled, localFiles };\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 rootUrl: request.source instanceof URL ? request.source.href : undefined,\n maxParallelFetches: remoteDocumentLimits.maxParallelFetches,\n bodyLimits: remoteDocumentLimits,\n });\n return new RefAccessResolver(config, {\n access: request.refAccess,\n maxRemoteDocuments: remoteDocumentLimits.maxDocuments,\n maxRemoteNodes: remoteDocumentLimits.maxNodes,\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, document.source.absoluteRef);\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 const schemaKeys = schemaKeysOf(document.parsed);\n const componentKeys = componentKeysOf(document.parsed);\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 removeBundledMappingCopies(bundled.bundle.parsed, schemaKeys);\n repairBundledRefs(bundled.bundle.parsed);\n const documentRefs = resolver.getFiles();\n const renaming = renameQueryNamedComponents(bundled.bundle.parsed, componentKeys, documentRefs);\n // The problems name the components the bundle made, so they are shown by their new names.\n this.#report(bundled.problems, document.source.absoluteRef, renaming);\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[], rootRef: string, renaming = UNRENAMED): 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, renaming, rootRef)}`,\n \"lint\",\n );\n continue;\n }\n const message = problemMessage(problem, renaming, rootRef);\n if (problem.severity === \"error\") {\n errorMessages.push(message);\n this.#options.logger.error(message);\n } else {\n this.#options.logger.warn(lintWarningText(message, problem.ruleId));\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(message: string, ruleId: string): string {\n return warningText(`${message}, rule ${ruleId}`, WARNING_CODES.LINT_PROBLEM);\n}\n\n/** Problems found before the bundle named any component. */\nconst UNRENAMED: ComponentRenaming = { pointer: (pointer) => pointer, text: (text) => text };\n\n/** A problem location that names a JSON Pointer, not a line and column. */\ntype PointerLocation = Extract<LocationObject, { pointer: string }>;\n\n/**\n * Where a problem is: its pointer, and the document when it is not the root (URL secrets left\n * out).\n */\nfunction locationText(location: PointerLocation, renaming: ComponentRenaming, rootRef: string) {\n const pointer = renaming.pointer(location.pointer);\n const documentRef = location.source.absoluteRef;\n return documentRef === rootRef ? pointer : `${pointer} in ${redactUrlSecrets(documentRef)}`;\n}\n\nfunction problemMessage(\n problem: NormalizedProblem,\n renaming: ComponentRenaming,\n rootRef: string,\n): string {\n const location = problem.location?.[0];\n const message = renaming.text(problem.message);\n return location?.pointer ? `${message} at ${locationText(location, renaming, rootRef)}` : 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","loadedDocuments","findUnsupportedKeys","unsupportedKeysError","withStackOverflowReportedAsync","parseSchema","pointMappingNamesAtSchemas","localFilesRead","resolveConfigWithAccess","RefAccessResolver","checkRefsResolve","lintDocument","schemaKeysOf","componentKeysOf","bundle","removeBundledMappingCopies","repairBundledRefs","renameQueryNamedComponents","schemaInvalidError","warningText","WARNING_CODES","redactUrlSecrets"],"mappings":"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"}
|