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
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { redactUrlSecrets } from './url-secrets.mjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const MAX_CAUSE_DEPTH = 8;
|
|
4
|
+
function deeper(walk, value) {
|
|
5
|
+
return { path: /* @__PURE__ */ new Set([...walk.path, value]), depth: walk.depth + 1 };
|
|
5
6
|
}
|
|
6
|
-
function
|
|
7
|
-
const inner =
|
|
8
|
-
const
|
|
7
|
+
function redactedArray(array, walk) {
|
|
8
|
+
const inner = deeper(walk, array);
|
|
9
|
+
const items = array.map((item) => redactedValue(item, inner));
|
|
10
|
+
return items.every((item, index) => item === array[index]) ? array : items;
|
|
11
|
+
}
|
|
12
|
+
function redactedObject(value, walk) {
|
|
13
|
+
const inner = deeper(walk, value);
|
|
14
|
+
const copy = value instanceof Error ? Object.setPrototypeOf(new Error(), Object.getPrototypeOf(value)) : Object.create(Object.getPrototypeOf(value));
|
|
9
15
|
let isChanged = false;
|
|
10
|
-
for (const key of Reflect.ownKeys(
|
|
11
|
-
const
|
|
12
|
-
const shown =
|
|
13
|
-
isChanged ||= shown !==
|
|
14
|
-
const enumerable = Object.getOwnPropertyDescriptor(
|
|
16
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
17
|
+
const property = Reflect.get(value, key);
|
|
18
|
+
const shown = redactedValue(property, inner);
|
|
19
|
+
isChanged ||= shown !== property;
|
|
20
|
+
const enumerable = Object.getOwnPropertyDescriptor(value, key)?.enumerable === true;
|
|
15
21
|
Object.defineProperty(copy, key, {
|
|
16
22
|
value: shown,
|
|
17
23
|
enumerable,
|
|
@@ -19,16 +25,25 @@ function redactedError(error, seen) {
|
|
|
19
25
|
configurable: true
|
|
20
26
|
});
|
|
21
27
|
}
|
|
22
|
-
return isChanged ? copy :
|
|
28
|
+
return isChanged ? copy : value;
|
|
29
|
+
}
|
|
30
|
+
function isOpaque(value) {
|
|
31
|
+
return typeof value === "function" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer;
|
|
23
32
|
}
|
|
24
|
-
function
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
33
|
+
function redactedValue(value, walk) {
|
|
34
|
+
if (typeof value === "string") {
|
|
35
|
+
return redactUrlSecrets(value);
|
|
36
|
+
}
|
|
37
|
+
if (typeof value !== "object" || value === null || isOpaque(value)) {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
if (walk.path.has(value) || walk.depth >= MAX_CAUSE_DEPTH) {
|
|
41
|
+
return void 0;
|
|
27
42
|
}
|
|
28
|
-
return
|
|
43
|
+
return Array.isArray(value) ? redactedArray(value, walk) : redactedObject(value, walk);
|
|
29
44
|
}
|
|
30
45
|
function redactCauseSecrets(cause) {
|
|
31
|
-
return
|
|
46
|
+
return redactedValue(cause, { path: /* @__PURE__ */ new Set(), depth: 0 });
|
|
32
47
|
}
|
|
33
48
|
|
|
34
49
|
export { redactCauseSecrets };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cause-secrets.mjs","sources":["../../src/domain/cause-secrets.ts"],"sourcesContent":["import { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * The `cause` of a typed error is shown wherever the error is: `console.error(error)` and\n * `util.inspect` print the whole chain, and error trackers send it. A lower-level error names the\n * URL it failed on (fetch refuses `https://user:token@host/…` and quotes it), so the chain must
|
|
1
|
+
{"version":3,"file":"cause-secrets.mjs","sources":["../../src/domain/cause-secrets.ts"],"sourcesContent":["import { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * The `cause` of a typed error is shown wherever the error is: `console.error(error)` and\n * `util.inspect` print the whole chain, and error trackers send it. A lower-level error names the\n * URL it failed on (fetch refuses `https://user:token@host/…` and quotes it), and may keep it in\n * nested objects too (Redocly's parse error holds `originalError.mark.name` and\n * `source.absoluteRef`), so the chain must hide the same secrets as the message (url-secrets.ts)\n * at every depth.\n */\n\n/**\n * How deep the walk copies a cause. The data of a cause is shallow (Redocly's deepest URL is three\n * levels below the error); a value below this depth is dropped, so no secret is kept unread.\n */\nconst MAX_CAUSE_DEPTH = 8;\n\ninterface Walk {\n /** The objects on the way from the cause to the value, so a cycle is cut where it closes. */\n readonly path: ReadonlySet<object>;\n readonly depth: number;\n}\n\nfunction deeper(walk: Walk, value: object): Walk {\n return { path: new Set([...walk.path, value]), depth: walk.depth + 1 };\n}\n\n/** An array with each item hidden, or the array itself when no item holds a secret. */\nfunction redactedArray(array: readonly unknown[], walk: Walk): readonly unknown[] {\n const inner = deeper(walk, array);\n const items = array.map((item) => redactedValue(item, inner));\n return items.every((item, index) => item === array[index]) ? array : items;\n}\n\n/**\n * A copy of `value` with the same prototype, its own properties (`message`, `stack`, `code`,\n * `input`, a nested `cause` or object) with URL secrets hidden, or `value` itself when none of\n * them holds one. Each property is read through its getter (V8 keeps `stack` behind one) and\n * copied as a value.\n */\nfunction redactedObject(value: object, walk: Walk): object {\n const inner = deeper(walk, value);\n // An error is copied as a real error, so `util.inspect` and `util.types.isNativeError` treat\n // the copy as one.\n const copy: object =\n value instanceof Error\n ? Object.setPrototypeOf(new Error(), Object.getPrototypeOf(value))\n : Object.create(Object.getPrototypeOf(value) as object | null);\n let isChanged = false;\n for (const key of Reflect.ownKeys(value)) {\n const property: unknown = Reflect.get(value, key);\n const shown = redactedValue(property, inner);\n isChanged ||= shown !== property;\n const enumerable = Object.getOwnPropertyDescriptor(value, key)?.enumerable === true;\n Object.defineProperty(copy, key, {\n value: shown,\n enumerable,\n writable: true,\n configurable: true,\n });\n }\n return isChanged ? copy : value;\n}\n\n/** Binary data and functions hold no text to hide, so they are kept as they are. */\nfunction isOpaque(value: object): boolean {\n return typeof value === \"function\" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer;\n}\n\nfunction redactedValue(value: unknown, walk: Walk): unknown {\n if (typeof value === \"string\") {\n return redactUrlSecrets(value);\n }\n if (typeof value !== \"object\" || value === null || isOpaque(value)) {\n return value;\n }\n if (walk.path.has(value) || walk.depth >= MAX_CAUSE_DEPTH) {\n return undefined;\n }\n return Array.isArray(value) ? redactedArray(value, walk) : redactedObject(value, walk);\n}\n\n/** The cause of a typed error with the URL secrets of its whole chain hidden. */\nexport function redactCauseSecrets(cause: unknown): unknown {\n return redactedValue(cause, { path: new Set(), depth: 0 });\n}\n"],"names":[],"mappings":";;AAeA,MAAM,eAAA,GAAkB,CAAA;AAQxB,SAAS,MAAA,CAAO,MAAY,KAAA,EAAqB;AAC/C,EAAA,OAAO,EAAE,IAAA,kBAAM,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,CAAK,IAAA,EAAM,KAAK,CAAC,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,QAAQ,CAAA,EAAE;AACvE;AAGA,SAAS,aAAA,CAAc,OAA2B,IAAA,EAAgC;AAChF,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAChC,EAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,CAAC,SAAS,aAAA,CAAc,IAAA,EAAM,KAAK,CAAC,CAAA;AAC5D,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAC,IAAA,EAAM,KAAA,KAAU,SAAS,KAAA,CAAM,KAAK,CAAC,CAAA,GAAI,KAAA,GAAQ,KAAA;AACvE;AAQA,SAAS,cAAA,CAAe,OAAe,IAAA,EAAoB;AACzD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAGhC,EAAA,MAAM,OACJ,KAAA,YAAiB,KAAA,GACb,OAAO,cAAA,CAAe,IAAI,OAAM,EAAG,MAAA,CAAO,cAAA,CAAe,KAAK,CAAC,CAAA,GAC/D,MAAA,CAAO,OAAO,MAAA,CAAO,cAAA,CAAe,KAAK,CAAkB,CAAA;AACjE,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,KAAA,MAAW,GAAA,IAAO,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxC,IAAA,MAAM,QAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAChD,IAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,QAAA,EAAU,KAAK,CAAA;AAC3C,IAAA,SAAA,KAAc,KAAA,KAAU,QAAA;AACxB,IAAA,MAAM,aAAa,MAAA,CAAO,wBAAA,CAAyB,KAAA,EAAO,GAAG,GAAG,UAAA,KAAe,IAAA;AAC/E,IAAA,MAAA,CAAO,cAAA,CAAe,MAAM,GAAA,EAAK;AAAA,MAC/B,KAAA,EAAO,KAAA;AAAA,MACP,UAAA;AAAA,MACA,QAAA,EAAU,IAAA;AAAA,MACV,YAAA,EAAc;AAAA,KACf,CAAA;AAAA,EACH;AACA,EAAA,OAAO,YAAY,IAAA,GAAO,KAAA;AAC5B;AAGA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,OAAO,OAAO,KAAA,KAAU,UAAA,IAAc,YAAY,MAAA,CAAO,KAAK,KAAK,KAAA,YAAiB,WAAA;AACtF;AAEA,SAAS,aAAA,CAAc,OAAgB,IAAA,EAAqB;AAC1D,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,iBAAiB,KAAK,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AAClE,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAK,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,IAAK,IAAA,CAAK,SAAS,eAAA,EAAiB;AACzD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,aAAA,CAAc,OAAO,IAAI,CAAA,GAAI,cAAA,CAAe,KAAA,EAAO,IAAI,CAAA;AACvF;AAGO,SAAS,mBAAmB,KAAA,EAAyB;AAC1D,EAAA,OAAO,aAAA,CAAc,OAAO,EAAE,IAAA,sBAAU,GAAA,EAAI,EAAG,KAAA,EAAO,CAAA,EAAG,CAAA;AAC3D;;"}
|
package/dist/domain/errors.cjs
CHANGED
|
@@ -19,8 +19,10 @@ const ERROR_CODES = {
|
|
|
19
19
|
ENUM_NAME_EMPTY: "ENUM_NAME_EMPTY",
|
|
20
20
|
CALLBACK_RESULT_UNREADABLE: "CALLBACK_RESULT_UNREADABLE",
|
|
21
21
|
OPTION_FIX_UNKNOWN: "OPTION_FIX_UNKNOWN",
|
|
22
|
+
OPTION_INVALID: "OPTION_INVALID",
|
|
22
23
|
TYPESCRIPT_NOT_FOUND: "TYPESCRIPT_NOT_FOUND",
|
|
23
24
|
CLI_FLAG_REMOVED: "CLI_FLAG_REMOVED",
|
|
25
|
+
CLI_FLAG_INVALID: "CLI_FLAG_INVALID",
|
|
24
26
|
CLI_GLOB_UNSUPPORTED: "CLI_GLOB_UNSUPPORTED",
|
|
25
27
|
CLI_CONFIG_NOT_FOUND: "CLI_CONFIG_NOT_FOUND",
|
|
26
28
|
CLI_CONFIG_INVALID: "CLI_CONFIG_INVALID",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":["redactUrlSecrets","redactCauseSecrets"],"mappings":";;;;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAUA,2BAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQC,+BAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;;;"}
|
|
1
|
+
{"version":3,"file":"errors.cjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":["redactUrlSecrets","redactCauseSecrets"],"mappings":";;;;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAUA,2BAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQC,+BAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;;;"}
|
package/dist/domain/errors.mjs
CHANGED
|
@@ -17,8 +17,10 @@ const ERROR_CODES = {
|
|
|
17
17
|
ENUM_NAME_EMPTY: "ENUM_NAME_EMPTY",
|
|
18
18
|
CALLBACK_RESULT_UNREADABLE: "CALLBACK_RESULT_UNREADABLE",
|
|
19
19
|
OPTION_FIX_UNKNOWN: "OPTION_FIX_UNKNOWN",
|
|
20
|
+
OPTION_INVALID: "OPTION_INVALID",
|
|
20
21
|
TYPESCRIPT_NOT_FOUND: "TYPESCRIPT_NOT_FOUND",
|
|
21
22
|
CLI_FLAG_REMOVED: "CLI_FLAG_REMOVED",
|
|
23
|
+
CLI_FLAG_INVALID: "CLI_FLAG_INVALID",
|
|
22
24
|
CLI_GLOB_UNSUPPORTED: "CLI_GLOB_UNSUPPORTED",
|
|
23
25
|
CLI_CONFIG_NOT_FOUND: "CLI_CONFIG_NOT_FOUND",
|
|
24
26
|
CLI_CONFIG_INVALID: "CLI_CONFIG_INVALID",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":[],"mappings":";;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;"}
|
|
1
|
+
{"version":3,"file":"errors.mjs","sources":["../../src/domain/errors.ts"],"sourcesContent":["import { redactCauseSecrets } from \"./cause-secrets.js\";\nimport { redactUrlSecrets } from \"./url-secrets.js\";\n\n/**\n * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI\n * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The\n * `message` is English text for people; programs and the CLI decide by `code`. A bug (a broken\n * invariant) is a plain `Error`, not one of these.\n */\n\n/**\n * Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's\n * exit-code table, which the compiler checks.\n */\nexport const ERROR_CODES = {\n SCHEMA_SOURCE_EMPTY: \"SCHEMA_SOURCE_EMPTY\",\n SCHEMA_SOURCE_INVALID: \"SCHEMA_SOURCE_INVALID\",\n SCHEMA_LOAD_FAILED: \"SCHEMA_LOAD_FAILED\",\n SCHEMA_PARSE_FAILED: \"SCHEMA_PARSE_FAILED\",\n SCHEMA_VERSION_UNSUPPORTED: \"SCHEMA_VERSION_UNSUPPORTED\",\n SCHEMA_INVALID: \"SCHEMA_INVALID\",\n SCHEMA_REF_INVALID: \"SCHEMA_REF_INVALID\",\n SCHEMA_REF_FORBIDDEN: \"SCHEMA_REF_FORBIDDEN\",\n SCHEMA_OBJECT_INVALID: \"SCHEMA_OBJECT_INVALID\",\n SCHEMA_PROPERTY_INVALID: \"SCHEMA_PROPERTY_INVALID\",\n SCHEMA_TOO_DEEP: \"SCHEMA_TOO_DEEP\",\n SCHEMA_KEY_UNSUPPORTED: \"SCHEMA_KEY_UNSUPPORTED\",\n ENUM_NAME_EMPTY: \"ENUM_NAME_EMPTY\",\n CALLBACK_RESULT_UNREADABLE: \"CALLBACK_RESULT_UNREADABLE\",\n OPTION_FIX_UNKNOWN: \"OPTION_FIX_UNKNOWN\",\n OPTION_INVALID: \"OPTION_INVALID\",\n TYPESCRIPT_NOT_FOUND: \"TYPESCRIPT_NOT_FOUND\",\n CLI_FLAG_REMOVED: \"CLI_FLAG_REMOVED\",\n CLI_FLAG_INVALID: \"CLI_FLAG_INVALID\",\n CLI_GLOB_UNSUPPORTED: \"CLI_GLOB_UNSUPPORTED\",\n CLI_CONFIG_NOT_FOUND: \"CLI_CONFIG_NOT_FOUND\",\n CLI_CONFIG_INVALID: \"CLI_CONFIG_INVALID\",\n CLI_CONFIG_OUTPUT_MISSING: \"CLI_CONFIG_OUTPUT_MISSING\",\n CLI_CHECK_OUTPUT_MISSING: \"CLI_CHECK_OUTPUT_MISSING\",\n CLI_INPUT_MISSING: \"CLI_INPUT_MISSING\",\n CLI_OUTPUT_IS_INPUT: \"CLI_OUTPUT_IS_INPUT\",\n CLI_OUTPUT_DUPLICATE: \"CLI_OUTPUT_DUPLICATE\",\n CLI_OUTPUT_INVALID: \"CLI_OUTPUT_INVALID\",\n CLI_LOCATION_INVALID: \"CLI_LOCATION_INVALID\",\n OUTPUT_STALE: \"OUTPUT_STALE\",\n OUTPUT_READ_FAILED: \"OUTPUT_READ_FAILED\",\n OUTPUT_WRITE_FAILED: \"OUTPUT_WRITE_FAILED\",\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that\n * docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).\n */\nexport type ErrorDetails = Readonly<Record<string, unknown>>;\n\nexport interface OpenAPITypesafeErrorInit {\n readonly code: ErrorCode;\n readonly message: string;\n readonly details?: ErrorDetails;\n /**\n * The lower-level error this one reports, if any (kept as the standard `cause`; a copy with URL\n * secrets hidden when its chain names one, see cause-secrets.ts).\n */\n readonly cause?: unknown;\n}\n\n/**\n * The base of every expected failure; check `code`, not the class or the message. The message\n * and the `cause` chain never show the user info or the query of a URL (`url-secrets.ts`).\n */\nexport class OpenAPITypesafeError extends Error {\n readonly code: ErrorCode;\n readonly details: ErrorDetails;\n\n constructor(init: OpenAPITypesafeErrorInit) {\n const message = redactUrlSecrets(init.message);\n const cause = redactCauseSecrets(init.cause);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"OpenAPITypesafeError\";\n this.code = init.code;\n this.details = init.details ?? {};\n }\n}\n\n/** Whether a thrown value is one of our typed errors (also across bundled copies of the class). */\nexport function isOpenAPITypesafeError(value: unknown): value is OpenAPITypesafeError {\n if (value instanceof OpenAPITypesafeError) {\n return true;\n }\n const code = (value as { code?: unknown } | null)?.code;\n return (\n value instanceof Error &&\n typeof code === \"string\" &&\n Object.hasOwn(ERROR_CODES, code) &&\n typeof (value as { details?: unknown }).details === \"object\"\n );\n}\n"],"names":[],"mappings":";;;AAcO,MAAM,WAAA,GAAc;AAAA,EACzB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,cAAA,EAAgB,gBAAA;AAAA,EAChB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,qBAAA,EAAuB,uBAAA;AAAA,EACvB,uBAAA,EAAyB,yBAAA;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,eAAA,EAAiB,iBAAA;AAAA,EACjB,0BAAA,EAA4B,4BAAA;AAAA,EAC5B,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,yBAAA,EAA2B,2BAAA;AAAA,EAC3B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,iBAAA,EAAmB,mBAAA;AAAA,EACnB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,YAAA,EAAc,cAAA;AAAA,EACd,kBAAA,EAAoB,oBAAA;AAAA,EACpB,mBAAA,EAAqB;AACvB;AAyBO,MAAM,6BAA6B,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACA,OAAA;AAAA,EAET,YAAY,IAAA,EAAgC;AAC1C,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,KAAA,CAAM,SAAS,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,EAAE,OAAO,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,EAClC;AACF;AAGO,SAAS,uBAAuB,KAAA,EAA+C;AACpF,EAAA,IAAI,iBAAiB,oBAAA,EAAsB;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAQ,KAAA,EAAqC,IAAA;AACnD,EAAA,OACE,KAAA,YAAiB,KAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa,IAAI,CAAA,IAC/B,OAAQ,KAAA,CAAgC,OAAA,KAAY,QAAA;AAExD;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location-text.cjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** Whether the location is written as a URL, not as a file path. */\nexport function hasUrlScheme(location: string): boolean {\n return URL_SCHEME.test(location);\n}\n"],"names":[],"mappings":";;AAMA,MAAM,UAAA,GAAa,qBAAA;AAGZ,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,OAAO,UAAA,CAAW,KAAK,QAAQ,CAAA;AACjC;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location-text.mjs","sources":["../../src/domain/location-text.ts"],"sourcesContent":["/** How a location the user writes, as a CLI argument or an option string, is read. */\n\n/**\n * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so\n * `C:\\\\specs\\\\api.yaml` stays a path.\n */\nconst URL_SCHEME = /^[a-z][a-z\\d+.-]+:/i;\n\n/** Whether the location is written as a URL, not as a file path. */\nexport function hasUrlScheme(location: string): boolean {\n return URL_SCHEME.test(location);\n}\n"],"names":[],"mappings":"AAMA,MAAM,UAAA,GAAa,qBAAA;AAGZ,SAAS,aAAa,QAAA,EAA2B;AACtD,EAAA,OAAO,UAAA,CAAW,KAAK,QAAQ,CAAA;AACjC;;"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const pathItemObject = require('./path-item-object.cjs');
|
|
4
|
+
|
|
5
|
+
const OPERATION_KEYS = /* @__PURE__ */ new Set([...pathItemObject.HTTP_METHODS, pathItemObject.QUERY_METHOD]);
|
|
6
|
+
const FIELDS = {
|
|
7
|
+
root: {
|
|
8
|
+
paths: "namedPathItems",
|
|
9
|
+
webhooks: "namedPathItems",
|
|
10
|
+
components: "components",
|
|
11
|
+
$defs: "other"
|
|
12
|
+
},
|
|
13
|
+
components: {
|
|
14
|
+
parameters: "input",
|
|
15
|
+
requestBodies: "input",
|
|
16
|
+
pathItems: "namedPathItems",
|
|
17
|
+
callbacks: "namedCallbacks"
|
|
18
|
+
},
|
|
19
|
+
pathItem: { parameters: "input", [pathItemObject.ADDITIONAL_OPERATIONS_KEY]: "namedOperations" },
|
|
20
|
+
operation: { parameters: "input", requestBody: "input", callbacks: "namedCallbacks" }
|
|
21
|
+
};
|
|
22
|
+
const NAMED = {
|
|
23
|
+
namedPathItems: "pathItem",
|
|
24
|
+
namedCallbacks: "callback",
|
|
25
|
+
callback: "pathItem",
|
|
26
|
+
namedOperations: "operation"
|
|
27
|
+
};
|
|
28
|
+
function nextPlace(place, segment) {
|
|
29
|
+
const named = NAMED[place];
|
|
30
|
+
if (named !== void 0) {
|
|
31
|
+
return named;
|
|
32
|
+
}
|
|
33
|
+
if (place === "pathItem" && OPERATION_KEYS.has(segment)) {
|
|
34
|
+
return "operation";
|
|
35
|
+
}
|
|
36
|
+
const fields = FIELDS[place] ?? {};
|
|
37
|
+
if (Object.hasOwn(fields, segment)) {
|
|
38
|
+
return fields[segment];
|
|
39
|
+
}
|
|
40
|
+
return place === "root" ? "outside" : "other";
|
|
41
|
+
}
|
|
42
|
+
const TERMINAL_PLACES = /* @__PURE__ */ new Set(["outside", "input", "other"]);
|
|
43
|
+
function placeOf(segments) {
|
|
44
|
+
let place = "root";
|
|
45
|
+
for (const segment of segments) {
|
|
46
|
+
place = nextPlace(place, segment);
|
|
47
|
+
if (TERMINAL_PLACES.has(place)) {
|
|
48
|
+
return place;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return place;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports.placeOf = placeOf;
|
|
55
|
+
//# sourceMappingURL=document-places.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-places.cjs","sources":["../../../src/domain/openapi/document-places.ts"],"sourcesContent":["import { ADDITIONAL_OPERATIONS_KEY, HTTP_METHODS, QUERY_METHOD } from \"./path-item-object.js\";\n\n/**\n * The places of an OpenAPI document that a JSON Pointer passes through, read from the document's\n * structure rather than from the words of the pointer. `named*` places and `callback` are maps\n * whose next segment is a name (a path, a component name, a callback expression). `outside` (a\n * root key that is no document key), `input` (a parameter or a request body) and `other` end the\n * walk.\n */\nexport type DocumentPlace =\n | \"root\"\n | \"outside\"\n | \"components\"\n | \"namedPathItems\"\n | \"namedCallbacks\"\n | \"callback\"\n | \"pathItem\"\n | \"namedOperations\"\n | \"operation\"\n | \"input\"\n | \"other\";\n\nconst OPERATION_KEYS: ReadonlySet<string> = new Set([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The place each fixed field leads to; any other field leads to `other`. */\nconst FIELDS: Readonly<Partial<Record<DocumentPlace, Readonly<Record<string, DocumentPlace>>>>> = {\n root: {\n paths: \"namedPathItems\",\n webhooks: \"namedPathItems\",\n components: \"components\",\n $defs: \"other\",\n },\n components: {\n parameters: \"input\",\n requestBodies: \"input\",\n pathItems: \"namedPathItems\",\n callbacks: \"namedCallbacks\",\n },\n pathItem: { parameters: \"input\", [ADDITIONAL_OPERATIONS_KEY]: \"namedOperations\" },\n operation: { parameters: \"input\", requestBody: \"input\", callbacks: \"namedCallbacks\" },\n};\n\n/** Maps whose every key leads to the same place. */\nconst NAMED: Readonly<Partial<Record<DocumentPlace, DocumentPlace>>> = {\n namedPathItems: \"pathItem\",\n namedCallbacks: \"callback\",\n callback: \"pathItem\",\n namedOperations: \"operation\",\n};\n\nfunction nextPlace(place: DocumentPlace, segment: string): DocumentPlace {\n const named = NAMED[place];\n if (named !== undefined) {\n return named;\n }\n if (place === \"pathItem\" && OPERATION_KEYS.has(segment)) {\n return \"operation\";\n }\n const fields = FIELDS[place] ?? {};\n if (Object.hasOwn(fields, segment)) {\n return fields[segment] as DocumentPlace;\n }\n return place === \"root\" ? \"outside\" : \"other\";\n}\n\nconst TERMINAL_PLACES: ReadonlySet<DocumentPlace> = new Set([\"outside\", \"input\", \"other\"]);\n\n/** The place the segments of a pointer (after `#`) lead to; the walk stops at a terminal place. */\nexport function placeOf(segments: Iterable<string>): DocumentPlace {\n let place: DocumentPlace = \"root\";\n for (const segment of segments) {\n place = nextPlace(place, segment);\n if (TERMINAL_PLACES.has(place)) {\n return place;\n }\n }\n return place;\n}\n"],"names":["HTTP_METHODS","QUERY_METHOD","ADDITIONAL_OPERATIONS_KEY"],"mappings":";;;;AAsBA,MAAM,iCAAsC,IAAI,GAAA,CAAI,CAAC,GAAGA,2BAAA,EAAcC,2BAAY,CAAC,CAAA;AAGnF,MAAM,MAAA,GAA4F;AAAA,EAChG,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,gBAAA;AAAA,IACP,QAAA,EAAU,gBAAA;AAAA,IACV,UAAA,EAAY,YAAA;AAAA,IACZ,KAAA,EAAO;AAAA,GACT;AAAA,EACA,UAAA,EAAY;AAAA,IACV,UAAA,EAAY,OAAA;AAAA,IACZ,aAAA,EAAe,OAAA;AAAA,IACf,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA,EAAW;AAAA,GACb;AAAA,EACA,UAAU,EAAE,UAAA,EAAY,SAAS,CAACC,wCAAyB,GAAG,iBAAA,EAAkB;AAAA,EAChF,WAAW,EAAE,UAAA,EAAY,SAAS,WAAA,EAAa,OAAA,EAAS,WAAW,gBAAA;AACrE,CAAA;AAGA,MAAM,KAAA,GAAiE;AAAA,EACrE,cAAA,EAAgB,UAAA;AAAA,EAChB,cAAA,EAAgB,UAAA;AAAA,EAChB,QAAA,EAAU,UAAA;AAAA,EACV,eAAA,EAAiB;AACnB,CAAA;AAEA,SAAS,SAAA,CAAU,OAAsB,OAAA,EAAgC;AACvE,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAK,CAAA;AACzB,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,UAAA,IAAc,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA,EAAG;AACvD,IAAA,OAAO,WAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAK,CAAA,IAAK,EAAC;AACjC,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,OAAO,CAAA,EAAG;AAClC,IAAA,OAAO,OAAO,OAAO,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,KAAA,KAAU,SAAS,SAAA,GAAY,OAAA;AACxC;AAEA,MAAM,kCAA8C,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,OAAA,EAAS,OAAO,CAAC,CAAA;AAGlF,SAAS,QAAQ,QAAA,EAA2C;AACjE,EAAA,IAAI,KAAA,GAAuB,MAAA;AAC3B,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,KAAA,GAAQ,SAAA,CAAU,OAAO,OAAO,CAAA;AAChC,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { HTTP_METHODS, QUERY_METHOD, ADDITIONAL_OPERATIONS_KEY } from './path-item-object.mjs';
|
|
2
|
+
|
|
3
|
+
const OPERATION_KEYS = /* @__PURE__ */ new Set([...HTTP_METHODS, QUERY_METHOD]);
|
|
4
|
+
const FIELDS = {
|
|
5
|
+
root: {
|
|
6
|
+
paths: "namedPathItems",
|
|
7
|
+
webhooks: "namedPathItems",
|
|
8
|
+
components: "components",
|
|
9
|
+
$defs: "other"
|
|
10
|
+
},
|
|
11
|
+
components: {
|
|
12
|
+
parameters: "input",
|
|
13
|
+
requestBodies: "input",
|
|
14
|
+
pathItems: "namedPathItems",
|
|
15
|
+
callbacks: "namedCallbacks"
|
|
16
|
+
},
|
|
17
|
+
pathItem: { parameters: "input", [ADDITIONAL_OPERATIONS_KEY]: "namedOperations" },
|
|
18
|
+
operation: { parameters: "input", requestBody: "input", callbacks: "namedCallbacks" }
|
|
19
|
+
};
|
|
20
|
+
const NAMED = {
|
|
21
|
+
namedPathItems: "pathItem",
|
|
22
|
+
namedCallbacks: "callback",
|
|
23
|
+
callback: "pathItem",
|
|
24
|
+
namedOperations: "operation"
|
|
25
|
+
};
|
|
26
|
+
function nextPlace(place, segment) {
|
|
27
|
+
const named = NAMED[place];
|
|
28
|
+
if (named !== void 0) {
|
|
29
|
+
return named;
|
|
30
|
+
}
|
|
31
|
+
if (place === "pathItem" && OPERATION_KEYS.has(segment)) {
|
|
32
|
+
return "operation";
|
|
33
|
+
}
|
|
34
|
+
const fields = FIELDS[place] ?? {};
|
|
35
|
+
if (Object.hasOwn(fields, segment)) {
|
|
36
|
+
return fields[segment];
|
|
37
|
+
}
|
|
38
|
+
return place === "root" ? "outside" : "other";
|
|
39
|
+
}
|
|
40
|
+
const TERMINAL_PLACES = /* @__PURE__ */ new Set(["outside", "input", "other"]);
|
|
41
|
+
function placeOf(segments) {
|
|
42
|
+
let place = "root";
|
|
43
|
+
for (const segment of segments) {
|
|
44
|
+
place = nextPlace(place, segment);
|
|
45
|
+
if (TERMINAL_PLACES.has(place)) {
|
|
46
|
+
return place;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return place;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { placeOf };
|
|
53
|
+
//# sourceMappingURL=document-places.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-places.mjs","sources":["../../../src/domain/openapi/document-places.ts"],"sourcesContent":["import { ADDITIONAL_OPERATIONS_KEY, HTTP_METHODS, QUERY_METHOD } from \"./path-item-object.js\";\n\n/**\n * The places of an OpenAPI document that a JSON Pointer passes through, read from the document's\n * structure rather than from the words of the pointer. `named*` places and `callback` are maps\n * whose next segment is a name (a path, a component name, a callback expression). `outside` (a\n * root key that is no document key), `input` (a parameter or a request body) and `other` end the\n * walk.\n */\nexport type DocumentPlace =\n | \"root\"\n | \"outside\"\n | \"components\"\n | \"namedPathItems\"\n | \"namedCallbacks\"\n | \"callback\"\n | \"pathItem\"\n | \"namedOperations\"\n | \"operation\"\n | \"input\"\n | \"other\";\n\nconst OPERATION_KEYS: ReadonlySet<string> = new Set([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The place each fixed field leads to; any other field leads to `other`. */\nconst FIELDS: Readonly<Partial<Record<DocumentPlace, Readonly<Record<string, DocumentPlace>>>>> = {\n root: {\n paths: \"namedPathItems\",\n webhooks: \"namedPathItems\",\n components: \"components\",\n $defs: \"other\",\n },\n components: {\n parameters: \"input\",\n requestBodies: \"input\",\n pathItems: \"namedPathItems\",\n callbacks: \"namedCallbacks\",\n },\n pathItem: { parameters: \"input\", [ADDITIONAL_OPERATIONS_KEY]: \"namedOperations\" },\n operation: { parameters: \"input\", requestBody: \"input\", callbacks: \"namedCallbacks\" },\n};\n\n/** Maps whose every key leads to the same place. */\nconst NAMED: Readonly<Partial<Record<DocumentPlace, DocumentPlace>>> = {\n namedPathItems: \"pathItem\",\n namedCallbacks: \"callback\",\n callback: \"pathItem\",\n namedOperations: \"operation\",\n};\n\nfunction nextPlace(place: DocumentPlace, segment: string): DocumentPlace {\n const named = NAMED[place];\n if (named !== undefined) {\n return named;\n }\n if (place === \"pathItem\" && OPERATION_KEYS.has(segment)) {\n return \"operation\";\n }\n const fields = FIELDS[place] ?? {};\n if (Object.hasOwn(fields, segment)) {\n return fields[segment] as DocumentPlace;\n }\n return place === \"root\" ? \"outside\" : \"other\";\n}\n\nconst TERMINAL_PLACES: ReadonlySet<DocumentPlace> = new Set([\"outside\", \"input\", \"other\"]);\n\n/** The place the segments of a pointer (after `#`) lead to; the walk stops at a terminal place. */\nexport function placeOf(segments: Iterable<string>): DocumentPlace {\n let place: DocumentPlace = \"root\";\n for (const segment of segments) {\n place = nextPlace(place, segment);\n if (TERMINAL_PLACES.has(place)) {\n return place;\n }\n }\n return place;\n}\n"],"names":[],"mappings":";;AAsBA,MAAM,iCAAsC,IAAI,GAAA,CAAI,CAAC,GAAG,YAAA,EAAc,YAAY,CAAC,CAAA;AAGnF,MAAM,MAAA,GAA4F;AAAA,EAChG,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,gBAAA;AAAA,IACP,QAAA,EAAU,gBAAA;AAAA,IACV,UAAA,EAAY,YAAA;AAAA,IACZ,KAAA,EAAO;AAAA,GACT;AAAA,EACA,UAAA,EAAY;AAAA,IACV,UAAA,EAAY,OAAA;AAAA,IACZ,aAAA,EAAe,OAAA;AAAA,IACf,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA,EAAW;AAAA,GACb;AAAA,EACA,UAAU,EAAE,UAAA,EAAY,SAAS,CAAC,yBAAyB,GAAG,iBAAA,EAAkB;AAAA,EAChF,WAAW,EAAE,UAAA,EAAY,SAAS,WAAA,EAAa,OAAA,EAAS,WAAW,gBAAA;AACrE,CAAA;AAGA,MAAM,KAAA,GAAiE;AAAA,EACrE,cAAA,EAAgB,UAAA;AAAA,EAChB,cAAA,EAAgB,UAAA;AAAA,EAChB,QAAA,EAAU,UAAA;AAAA,EACV,eAAA,EAAiB;AACnB,CAAA;AAEA,SAAS,SAAA,CAAU,OAAsB,OAAA,EAAgC;AACvE,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAK,CAAA;AACzB,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,KAAU,UAAA,IAAc,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA,EAAG;AACvD,IAAA,OAAO,WAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAK,CAAA,IAAK,EAAC;AACjC,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,OAAO,CAAA,EAAG;AAClC,IAAA,OAAO,OAAO,OAAO,CAAA;AAAA,EACvB;AACA,EAAA,OAAO,KAAA,KAAU,SAAS,SAAA,GAAY,OAAA;AACxC;AAEA,MAAM,kCAA8C,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,OAAA,EAAS,OAAO,CAAC,CAAA;AAGlF,SAAS,QAAQ,QAAA,EAA2C;AACjE,EAAA,IAAI,KAAA,GAAuB,MAAA;AAC3B,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,KAAA,GAAQ,SAAA,CAAU,OAAO,OAAO,CAAA;AAChC,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;"}
|
|
@@ -17,6 +17,11 @@ const FIX = {
|
|
|
17
17
|
ARRAY_LENGTH_TUPLES: "array-length-tuples",
|
|
18
18
|
/** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */
|
|
19
19
|
DEDUPE_ENUM_NAMES: "dedupe-enum-names",
|
|
20
|
+
/**
|
|
21
|
+
* `--default-non-nullable` finds parameters and request bodies by the document's structure, not
|
|
22
|
+
* by the words `parameters` and `requestBody` anywhere in a schema's location.
|
|
23
|
+
*/
|
|
24
|
+
DEFAULT_INPUT_LOCATIONS: "default-input-locations",
|
|
20
25
|
/** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */
|
|
21
26
|
DISCRIMINATOR_MEMBER_REQUIRED: "discriminator-member-required",
|
|
22
27
|
/**
|
|
@@ -29,8 +34,8 @@ const FIX = {
|
|
|
29
34
|
EXPLODED_QUERY_OBJECTS: "exploded-query-objects",
|
|
30
35
|
/** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */
|
|
31
36
|
NULLABLE_ENUMS: "nullable-enums",
|
|
32
|
-
/** A parameter with `content
|
|
33
|
-
|
|
37
|
+
/** A parameter or header with `content`, not `schema`, is typed by its media type's schema. */
|
|
38
|
+
PARAMETER_HEADER_CONTENT: "parameter-header-content",
|
|
34
39
|
/** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */
|
|
35
40
|
PATH_PARAM_TYPE_NAMES: "path-param-type-names",
|
|
36
41
|
/** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */
|
|
@@ -90,6 +95,7 @@ const NO_SCHEMA_PREFIX = {
|
|
|
90
95
|
const REQUIREMENTS = {
|
|
91
96
|
[FIX.ARRAY_LENGTH_TUPLES]: [{ option: "arrayLength", flag: "--array-length" }],
|
|
92
97
|
[FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: "dedupeEnums", flag: "--dedupe-enums" }],
|
|
98
|
+
[FIX.DEFAULT_INPUT_LOCATIONS]: [{ option: "defaultNonNullable", flag: "--default-non-nullable" }],
|
|
93
99
|
[FIX.NULLABLE_ENUMS]: [ENUM],
|
|
94
100
|
[FIX.PATH_PARAM_TYPE_NAMES]: [{ option: "pathParamsAsTypes", flag: "--path-params-as-types" }],
|
|
95
101
|
[FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-fixes.cjs","sources":["../../src/domain/output-fixes.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"./errors.js\";\n\n/**\n * Opt-in fixes of the output of valid schemas (ADR-021). Each one changes only the cases it names;\n * without any, the output is the same as openapi-typescript 7.13 gives. In 2.0 they become the\n * default. The object names the fixes for this package's code; the public API is the `OutputFix`\n * union and the `OUTPUT_FIXES` list (ADR-021, amendment 1).\n */\nexport const FIX = {\n /** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */\n ALLOF_DISCRIMINATED_UNION: \"allof-discriminated-union\",\n /** An `allOf` member with only `required` makes those properties of the others required. */\n ALLOF_REQUIRED: \"allof-required\",\n /** The JSDoc of a schema lists the descriptions of its `anyOf` and `oneOf` members. */\n ANYOF_ONEOF_DESCRIPTIONS: \"anyof-oneof-descriptions\",\n /** `anyOf` / `oneOf` variants with only `required` make those keys of the parent required. */\n ANYOF_ONEOF_REQUIRED: \"anyof-oneof-required\",\n /** `anyOf` next to object keywords or `allOf` is intersected with them, not added to a union. */\n ANYOF_PROPERTIES: \"anyof-properties\",\n /** `--array-length` tuples have `min` to `max` items, nest right and follow `--immutable`. */\n ARRAY_LENGTH_TUPLES: \"array-length-tuples\",\n /** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */\n DEDUPE_ENUM_NAMES: \"dedupe-enum-names\",\n /** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */\n DISCRIMINATOR_MEMBER_REQUIRED: \"discriminator-member-required\",\n /**\n * The value a discriminator member gets: one enum of every discriminator's values, a mapping\n * before the schema name, a schema's own mapping before an inherited one, none where the member\n * declares it, and with `--enum` a member of the owner's enum.\n */\n DISCRIMINATOR_VALUES: \"discriminator-values\",\n /** An exploded object query parameter's properties are keys of `query`, as they are sent. */\n EXPLODED_QUERY_OBJECTS: \"exploded-query-objects\",\n /** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */\n NULLABLE_ENUMS: \"nullable-enums\",\n /** A parameter with `content` instead of `schema` is typed by the schema of its media type. */\n PARAMETER_CONTENT: \"parameter-content\",\n /** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */\n PATH_PARAM_TYPE_NAMES: \"path-param-type-names\",\n /** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */\n PREFIX_ITEMS: \"prefix-items\",\n /** `readOnly` and `writeOnly` of the schema a `$ref` names, or of `allOf` members, count. */\n READ_WRITE_REFS: \"read-write-refs\",\n /**\n * A `$ref` into schema keywords (`content/<type>/schema`, `items`, `allOf/0`) gets the type it\n * points at, also where the original type compiles through an index signature.\n */\n REF_POINTERS: \"ref-pointers\",\n /**\n * OpenAPI 3.1 and 3.2: keywords next to a `$ref` (`required`, `properties`) apply too, so the\n * type is the reference intersected with them. OpenAPI 3.0 ignores them, as its spec says.\n */\n REF_SIBLINGS: \"ref-siblings\",\n /** Schemas of one root type name without the prefix each get an alias, the earlier numbered. */\n ROOT_TYPE_NUMBERING: \"root-type-numbering\",\n /** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */\n UNEVALUATED_PROPERTIES: \"unevaluated-properties\",\n} as const;\n/** The name of one opt-in output fix. */\nexport type OutputFix = (typeof FIX)[keyof typeof FIX];\n\n/** Every fix of this version, in the order the docs list them. */\nexport const OUTPUT_FIXES: readonly OutputFix[] = Object.values(FIX);\n\n/** The name that turns on every fix of the installed version. */\nconst ALL_FIXES = \"all\";\n\n/** A name the `fix` option accepts: one fix, or `\"all\"`. */\nexport type OutputFixName = OutputFix | typeof ALL_FIXES;\n\nconst KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES, ALL_FIXES]);\n\nfunction isOutputFixName(value: unknown): value is OutputFixName {\n return typeof value === \"string\" && KNOWN_NAMES.has(value);\n}\n\n/**\n * The fix names as given; fails with `OPTION_FIX_UNKNOWN` for any other value, and for a `fix`\n * option that is no list (`fix: \"all\"` from JavaScript), which must not be read letter by letter.\n */\nexport function outputFixNamesOf(values: unknown): readonly OutputFixName[] {\n if (!Array.isArray(values)) {\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message:\n 'The fix option must be a list of fix names, such as [\"all\"]. ' +\n `Got ${JSON.stringify(values)}.`,\n details: { unknown: [values], known: [...KNOWN_NAMES] },\n });\n }\n const unknown = values.filter((value) => !isOutputFixName(value));\n if (unknown.length > 0) {\n const names = unknown.map((value) => JSON.stringify(value)).join(\", \");\n const known = [...KNOWN_NAMES].join(\", \");\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message: `Unknown fix ${names}. Known fixes: ${known}.`,\n details: { unknown, known: [...KNOWN_NAMES] },\n });\n }\n return values as readonly OutputFixName[];\n}\n\n/** The fixes the names turn on; `all` stands for every fix of this version. */\nexport function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet<OutputFix> {\n return new Set(names.flatMap((name) => (name === ALL_FIXES ? OUTPUT_FIXES : [name])));\n}\n\n/** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */\nexport interface OutputFixRequirement {\n readonly option:\n | \"arrayLength\"\n | \"dedupeEnums\"\n | \"enum\"\n | \"pathParamsAsTypes\"\n | \"rootTypes\"\n | \"rootTypesNoSchemaPrefix\";\n readonly flag: string;\n}\n\nconst ROOT_TYPES = { option: \"rootTypes\", flag: \"--root-types\" } as const;\nconst ENUM = { option: \"enum\", flag: \"--enum\" } as const;\nconst NO_SCHEMA_PREFIX = {\n option: \"rootTypesNoSchemaPrefix\",\n flag: \"--root-types-no-schema-prefix\",\n} as const;\n\n/** The options each fix needs, by fix name; `all` has none. */\nconst REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {\n [FIX.ARRAY_LENGTH_TUPLES]: [{ option: \"arrayLength\", flag: \"--array-length\" }],\n [FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: \"dedupeEnums\", flag: \"--dedupe-enums\" }],\n [FIX.NULLABLE_ENUMS]: [ENUM],\n [FIX.PATH_PARAM_TYPE_NAMES]: [{ option: \"pathParamsAsTypes\", flag: \"--path-params-as-types\" }],\n [FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],\n};\n\nfunction describeRequirement(requirement: OutputFixRequirement): string {\n return `${requirement.option} (${requirement.flag})`;\n}\n\n/**\n * A notice for each fix given by name with an option it needs off; it names the options that are\n * off. `all` adds none: it means every fix that applies, so one that does not apply is expected.\n */\nexport function ineffectiveFixNotices(\n names: readonly OutputFixName[],\n isOptionOn: (option: OutputFixRequirement[\"option\"]) => boolean,\n): string[] {\n return [...new Set(names)].flatMap((name) => {\n const missing = (REQUIREMENTS[name] ?? []).filter(({ option }) => !isOptionOn(option));\n return missing.length === 0\n ? []\n : [`Fix \"${name}\" has no effect without ${missing.map(describeRequirement).join(\" and \")}`];\n });\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"output-fixes.cjs","sources":["../../src/domain/output-fixes.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"./errors.js\";\n\n/**\n * Opt-in fixes of the output of valid schemas (ADR-021). Each one changes only the cases it names;\n * without any, the output is the same as openapi-typescript 7.13 gives. In 2.0 they become the\n * default. The object names the fixes for this package's code; the public API is the `OutputFix`\n * union and the `OUTPUT_FIXES` list (ADR-021, amendment 1).\n */\nexport const FIX = {\n /** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */\n ALLOF_DISCRIMINATED_UNION: \"allof-discriminated-union\",\n /** An `allOf` member with only `required` makes those properties of the others required. */\n ALLOF_REQUIRED: \"allof-required\",\n /** The JSDoc of a schema lists the descriptions of its `anyOf` and `oneOf` members. */\n ANYOF_ONEOF_DESCRIPTIONS: \"anyof-oneof-descriptions\",\n /** `anyOf` / `oneOf` variants with only `required` make those keys of the parent required. */\n ANYOF_ONEOF_REQUIRED: \"anyof-oneof-required\",\n /** `anyOf` next to object keywords or `allOf` is intersected with them, not added to a union. */\n ANYOF_PROPERTIES: \"anyof-properties\",\n /** `--array-length` tuples have `min` to `max` items, nest right and follow `--immutable`. */\n ARRAY_LENGTH_TUPLES: \"array-length-tuples\",\n /** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */\n DEDUPE_ENUM_NAMES: \"dedupe-enum-names\",\n /**\n * `--default-non-nullable` finds parameters and request bodies by the document's structure, not\n * by the words `parameters` and `requestBody` anywhere in a schema's location.\n */\n DEFAULT_INPUT_LOCATIONS: \"default-input-locations\",\n /** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */\n DISCRIMINATOR_MEMBER_REQUIRED: \"discriminator-member-required\",\n /**\n * The value a discriminator member gets: one enum of every discriminator's values, a mapping\n * before the schema name, a schema's own mapping before an inherited one, none where the member\n * declares it, and with `--enum` a member of the owner's enum.\n */\n DISCRIMINATOR_VALUES: \"discriminator-values\",\n /** An exploded object query parameter's properties are keys of `query`, as they are sent. */\n EXPLODED_QUERY_OBJECTS: \"exploded-query-objects\",\n /** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */\n NULLABLE_ENUMS: \"nullable-enums\",\n /** A parameter or header with `content`, not `schema`, is typed by its media type's schema. */\n PARAMETER_HEADER_CONTENT: \"parameter-header-content\",\n /** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */\n PATH_PARAM_TYPE_NAMES: \"path-param-type-names\",\n /** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */\n PREFIX_ITEMS: \"prefix-items\",\n /** `readOnly` and `writeOnly` of the schema a `$ref` names, or of `allOf` members, count. */\n READ_WRITE_REFS: \"read-write-refs\",\n /**\n * A `$ref` into schema keywords (`content/<type>/schema`, `items`, `allOf/0`) gets the type it\n * points at, also where the original type compiles through an index signature.\n */\n REF_POINTERS: \"ref-pointers\",\n /**\n * OpenAPI 3.1 and 3.2: keywords next to a `$ref` (`required`, `properties`) apply too, so the\n * type is the reference intersected with them. OpenAPI 3.0 ignores them, as its spec says.\n */\n REF_SIBLINGS: \"ref-siblings\",\n /** Schemas of one root type name without the prefix each get an alias, the earlier numbered. */\n ROOT_TYPE_NUMBERING: \"root-type-numbering\",\n /** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */\n UNEVALUATED_PROPERTIES: \"unevaluated-properties\",\n} as const;\n/** The name of one opt-in output fix. */\nexport type OutputFix = (typeof FIX)[keyof typeof FIX];\n\n/** Every fix of this version, in the order the docs list them. */\nexport const OUTPUT_FIXES: readonly OutputFix[] = Object.values(FIX);\n\n/** The name that turns on every fix of the installed version. */\nconst ALL_FIXES = \"all\";\n\n/** A name the `fix` option accepts: one fix, or `\"all\"`. */\nexport type OutputFixName = OutputFix | typeof ALL_FIXES;\n\nconst KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES, ALL_FIXES]);\n\nfunction isOutputFixName(value: unknown): value is OutputFixName {\n return typeof value === \"string\" && KNOWN_NAMES.has(value);\n}\n\n/**\n * The fix names as given; fails with `OPTION_FIX_UNKNOWN` for any other value, and for a `fix`\n * option that is no list (`fix: \"all\"` from JavaScript), which must not be read letter by letter.\n */\nexport function outputFixNamesOf(values: unknown): readonly OutputFixName[] {\n if (!Array.isArray(values)) {\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message:\n 'The fix option must be a list of fix names, such as [\"all\"]. ' +\n `Got ${JSON.stringify(values)}.`,\n details: { unknown: [values], known: [...KNOWN_NAMES] },\n });\n }\n const unknown = values.filter((value) => !isOutputFixName(value));\n if (unknown.length > 0) {\n const names = unknown.map((value) => JSON.stringify(value)).join(\", \");\n const known = [...KNOWN_NAMES].join(\", \");\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message: `Unknown fix ${names}. Known fixes: ${known}.`,\n details: { unknown, known: [...KNOWN_NAMES] },\n });\n }\n return values as readonly OutputFixName[];\n}\n\n/** The fixes the names turn on; `all` stands for every fix of this version. */\nexport function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet<OutputFix> {\n return new Set(names.flatMap((name) => (name === ALL_FIXES ? OUTPUT_FIXES : [name])));\n}\n\n/** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */\nexport interface OutputFixRequirement {\n readonly option:\n | \"arrayLength\"\n | \"dedupeEnums\"\n | \"defaultNonNullable\"\n | \"enum\"\n | \"pathParamsAsTypes\"\n | \"rootTypes\"\n | \"rootTypesNoSchemaPrefix\";\n readonly flag: string;\n}\n\nconst ROOT_TYPES = { option: \"rootTypes\", flag: \"--root-types\" } as const;\nconst ENUM = { option: \"enum\", flag: \"--enum\" } as const;\nconst NO_SCHEMA_PREFIX = {\n option: \"rootTypesNoSchemaPrefix\",\n flag: \"--root-types-no-schema-prefix\",\n} as const;\n\n/** The options each fix needs, by fix name; `all` has none. */\nconst REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {\n [FIX.ARRAY_LENGTH_TUPLES]: [{ option: \"arrayLength\", flag: \"--array-length\" }],\n [FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: \"dedupeEnums\", flag: \"--dedupe-enums\" }],\n [FIX.DEFAULT_INPUT_LOCATIONS]: [{ option: \"defaultNonNullable\", flag: \"--default-non-nullable\" }],\n [FIX.NULLABLE_ENUMS]: [ENUM],\n [FIX.PATH_PARAM_TYPE_NAMES]: [{ option: \"pathParamsAsTypes\", flag: \"--path-params-as-types\" }],\n [FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],\n};\n\nfunction describeRequirement(requirement: OutputFixRequirement): string {\n return `${requirement.option} (${requirement.flag})`;\n}\n\n/**\n * A notice for each fix given by name with an option it needs off; it names the options that are\n * off. `all` adds none: it means every fix that applies, so one that does not apply is expected.\n */\nexport function ineffectiveFixNotices(\n names: readonly OutputFixName[],\n isOptionOn: (option: OutputFixRequirement[\"option\"]) => boolean,\n): string[] {\n return [...new Set(names)].flatMap((name) => {\n const missing = (REQUIREMENTS[name] ?? []).filter(({ option }) => !isOptionOn(option));\n return missing.length === 0\n ? []\n : [`Fix \"${name}\" has no effect without ${missing.map(describeRequirement).join(\" and \")}`];\n });\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES"],"mappings":"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"}
|
|
@@ -15,6 +15,11 @@ const FIX = {
|
|
|
15
15
|
ARRAY_LENGTH_TUPLES: "array-length-tuples",
|
|
16
16
|
/** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */
|
|
17
17
|
DEDUPE_ENUM_NAMES: "dedupe-enum-names",
|
|
18
|
+
/**
|
|
19
|
+
* `--default-non-nullable` finds parameters and request bodies by the document's structure, not
|
|
20
|
+
* by the words `parameters` and `requestBody` anywhere in a schema's location.
|
|
21
|
+
*/
|
|
22
|
+
DEFAULT_INPUT_LOCATIONS: "default-input-locations",
|
|
18
23
|
/** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */
|
|
19
24
|
DISCRIMINATOR_MEMBER_REQUIRED: "discriminator-member-required",
|
|
20
25
|
/**
|
|
@@ -27,8 +32,8 @@ const FIX = {
|
|
|
27
32
|
EXPLODED_QUERY_OBJECTS: "exploded-query-objects",
|
|
28
33
|
/** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */
|
|
29
34
|
NULLABLE_ENUMS: "nullable-enums",
|
|
30
|
-
/** A parameter with `content
|
|
31
|
-
|
|
35
|
+
/** A parameter or header with `content`, not `schema`, is typed by its media type's schema. */
|
|
36
|
+
PARAMETER_HEADER_CONTENT: "parameter-header-content",
|
|
32
37
|
/** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */
|
|
33
38
|
PATH_PARAM_TYPE_NAMES: "path-param-type-names",
|
|
34
39
|
/** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */
|
|
@@ -88,6 +93,7 @@ const NO_SCHEMA_PREFIX = {
|
|
|
88
93
|
const REQUIREMENTS = {
|
|
89
94
|
[FIX.ARRAY_LENGTH_TUPLES]: [{ option: "arrayLength", flag: "--array-length" }],
|
|
90
95
|
[FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: "dedupeEnums", flag: "--dedupe-enums" }],
|
|
96
|
+
[FIX.DEFAULT_INPUT_LOCATIONS]: [{ option: "defaultNonNullable", flag: "--default-non-nullable" }],
|
|
91
97
|
[FIX.NULLABLE_ENUMS]: [ENUM],
|
|
92
98
|
[FIX.PATH_PARAM_TYPE_NAMES]: [{ option: "pathParamsAsTypes", flag: "--path-params-as-types" }],
|
|
93
99
|
[FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-fixes.mjs","sources":["../../src/domain/output-fixes.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"./errors.js\";\n\n/**\n * Opt-in fixes of the output of valid schemas (ADR-021). Each one changes only the cases it names;\n * without any, the output is the same as openapi-typescript 7.13 gives. In 2.0 they become the\n * default. The object names the fixes for this package's code; the public API is the `OutputFix`\n * union and the `OUTPUT_FIXES` list (ADR-021, amendment 1).\n */\nexport const FIX = {\n /** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */\n ALLOF_DISCRIMINATED_UNION: \"allof-discriminated-union\",\n /** An `allOf` member with only `required` makes those properties of the others required. */\n ALLOF_REQUIRED: \"allof-required\",\n /** The JSDoc of a schema lists the descriptions of its `anyOf` and `oneOf` members. */\n ANYOF_ONEOF_DESCRIPTIONS: \"anyof-oneof-descriptions\",\n /** `anyOf` / `oneOf` variants with only `required` make those keys of the parent required. */\n ANYOF_ONEOF_REQUIRED: \"anyof-oneof-required\",\n /** `anyOf` next to object keywords or `allOf` is intersected with them, not added to a union. */\n ANYOF_PROPERTIES: \"anyof-properties\",\n /** `--array-length` tuples have `min` to `max` items, nest right and follow `--immutable`. */\n ARRAY_LENGTH_TUPLES: \"array-length-tuples\",\n /** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */\n DEDUPE_ENUM_NAMES: \"dedupe-enum-names\",\n /** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */\n DISCRIMINATOR_MEMBER_REQUIRED: \"discriminator-member-required\",\n /**\n * The value a discriminator member gets: one enum of every discriminator's values, a mapping\n * before the schema name, a schema's own mapping before an inherited one, none where the member\n * declares it, and with `--enum` a member of the owner's enum.\n */\n DISCRIMINATOR_VALUES: \"discriminator-values\",\n /** An exploded object query parameter's properties are keys of `query`, as they are sent. */\n EXPLODED_QUERY_OBJECTS: \"exploded-query-objects\",\n /** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */\n NULLABLE_ENUMS: \"nullable-enums\",\n /** A parameter with `content` instead of `schema` is typed by the schema of its media type. */\n PARAMETER_CONTENT: \"parameter-content\",\n /** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */\n PATH_PARAM_TYPE_NAMES: \"path-param-type-names\",\n /** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */\n PREFIX_ITEMS: \"prefix-items\",\n /** `readOnly` and `writeOnly` of the schema a `$ref` names, or of `allOf` members, count. */\n READ_WRITE_REFS: \"read-write-refs\",\n /**\n * A `$ref` into schema keywords (`content/<type>/schema`, `items`, `allOf/0`) gets the type it\n * points at, also where the original type compiles through an index signature.\n */\n REF_POINTERS: \"ref-pointers\",\n /**\n * OpenAPI 3.1 and 3.2: keywords next to a `$ref` (`required`, `properties`) apply too, so the\n * type is the reference intersected with them. OpenAPI 3.0 ignores them, as its spec says.\n */\n REF_SIBLINGS: \"ref-siblings\",\n /** Schemas of one root type name without the prefix each get an alias, the earlier numbered. */\n ROOT_TYPE_NUMBERING: \"root-type-numbering\",\n /** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */\n UNEVALUATED_PROPERTIES: \"unevaluated-properties\",\n} as const;\n/** The name of one opt-in output fix. */\nexport type OutputFix = (typeof FIX)[keyof typeof FIX];\n\n/** Every fix of this version, in the order the docs list them. */\nexport const OUTPUT_FIXES: readonly OutputFix[] = Object.values(FIX);\n\n/** The name that turns on every fix of the installed version. */\nconst ALL_FIXES = \"all\";\n\n/** A name the `fix` option accepts: one fix, or `\"all\"`. */\nexport type OutputFixName = OutputFix | typeof ALL_FIXES;\n\nconst KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES, ALL_FIXES]);\n\nfunction isOutputFixName(value: unknown): value is OutputFixName {\n return typeof value === \"string\" && KNOWN_NAMES.has(value);\n}\n\n/**\n * The fix names as given; fails with `OPTION_FIX_UNKNOWN` for any other value, and for a `fix`\n * option that is no list (`fix: \"all\"` from JavaScript), which must not be read letter by letter.\n */\nexport function outputFixNamesOf(values: unknown): readonly OutputFixName[] {\n if (!Array.isArray(values)) {\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message:\n 'The fix option must be a list of fix names, such as [\"all\"]. ' +\n `Got ${JSON.stringify(values)}.`,\n details: { unknown: [values], known: [...KNOWN_NAMES] },\n });\n }\n const unknown = values.filter((value) => !isOutputFixName(value));\n if (unknown.length > 0) {\n const names = unknown.map((value) => JSON.stringify(value)).join(\", \");\n const known = [...KNOWN_NAMES].join(\", \");\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message: `Unknown fix ${names}. Known fixes: ${known}.`,\n details: { unknown, known: [...KNOWN_NAMES] },\n });\n }\n return values as readonly OutputFixName[];\n}\n\n/** The fixes the names turn on; `all` stands for every fix of this version. */\nexport function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet<OutputFix> {\n return new Set(names.flatMap((name) => (name === ALL_FIXES ? OUTPUT_FIXES : [name])));\n}\n\n/** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */\nexport interface OutputFixRequirement {\n readonly option:\n | \"arrayLength\"\n | \"dedupeEnums\"\n | \"enum\"\n | \"pathParamsAsTypes\"\n | \"rootTypes\"\n | \"rootTypesNoSchemaPrefix\";\n readonly flag: string;\n}\n\nconst ROOT_TYPES = { option: \"rootTypes\", flag: \"--root-types\" } as const;\nconst ENUM = { option: \"enum\", flag: \"--enum\" } as const;\nconst NO_SCHEMA_PREFIX = {\n option: \"rootTypesNoSchemaPrefix\",\n flag: \"--root-types-no-schema-prefix\",\n} as const;\n\n/** The options each fix needs, by fix name; `all` has none. */\nconst REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {\n [FIX.ARRAY_LENGTH_TUPLES]: [{ option: \"arrayLength\", flag: \"--array-length\" }],\n [FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: \"dedupeEnums\", flag: \"--dedupe-enums\" }],\n [FIX.NULLABLE_ENUMS]: [ENUM],\n [FIX.PATH_PARAM_TYPE_NAMES]: [{ option: \"pathParamsAsTypes\", flag: \"--path-params-as-types\" }],\n [FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],\n};\n\nfunction describeRequirement(requirement: OutputFixRequirement): string {\n return `${requirement.option} (${requirement.flag})`;\n}\n\n/**\n * A notice for each fix given by name with an option it needs off; it names the options that are\n * off. `all` adds none: it means every fix that applies, so one that does not apply is expected.\n */\nexport function ineffectiveFixNotices(\n names: readonly OutputFixName[],\n isOptionOn: (option: OutputFixRequirement[\"option\"]) => boolean,\n): string[] {\n return [...new Set(names)].flatMap((name) => {\n const missing = (REQUIREMENTS[name] ?? []).filter(({ option }) => !isOptionOn(option));\n return missing.length === 0\n ? []\n : [`Fix \"${name}\" has no effect without ${missing.map(describeRequirement).join(\" and \")}`];\n });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"output-fixes.mjs","sources":["../../src/domain/output-fixes.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"./errors.js\";\n\n/**\n * Opt-in fixes of the output of valid schemas (ADR-021). Each one changes only the cases it names;\n * without any, the output is the same as openapi-typescript 7.13 gives. In 2.0 they become the\n * default. The object names the fixes for this package's code; the public API is the `OutputFix`\n * union and the `OUTPUT_FIXES` list (ADR-021, amendment 1).\n */\nexport const FIX = {\n /** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */\n ALLOF_DISCRIMINATED_UNION: \"allof-discriminated-union\",\n /** An `allOf` member with only `required` makes those properties of the others required. */\n ALLOF_REQUIRED: \"allof-required\",\n /** The JSDoc of a schema lists the descriptions of its `anyOf` and `oneOf` members. */\n ANYOF_ONEOF_DESCRIPTIONS: \"anyof-oneof-descriptions\",\n /** `anyOf` / `oneOf` variants with only `required` make those keys of the parent required. */\n ANYOF_ONEOF_REQUIRED: \"anyof-oneof-required\",\n /** `anyOf` next to object keywords or `allOf` is intersected with them, not added to a union. */\n ANYOF_PROPERTIES: \"anyof-properties\",\n /** `--array-length` tuples have `min` to `max` items, nest right and follow `--immutable`. */\n ARRAY_LENGTH_TUPLES: \"array-length-tuples\",\n /** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */\n DEDUPE_ENUM_NAMES: \"dedupe-enum-names\",\n /**\n * `--default-non-nullable` finds parameters and request bodies by the document's structure, not\n * by the words `parameters` and `requestBody` anywhere in a schema's location.\n */\n DEFAULT_INPUT_LOCATIONS: \"default-input-locations\",\n /** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */\n DISCRIMINATOR_MEMBER_REQUIRED: \"discriminator-member-required\",\n /**\n * The value a discriminator member gets: one enum of every discriminator's values, a mapping\n * before the schema name, a schema's own mapping before an inherited one, none where the member\n * declares it, and with `--enum` a member of the owner's enum.\n */\n DISCRIMINATOR_VALUES: \"discriminator-values\",\n /** An exploded object query parameter's properties are keys of `query`, as they are sent. */\n EXPLODED_QUERY_OBJECTS: \"exploded-query-objects\",\n /** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */\n NULLABLE_ENUMS: \"nullable-enums\",\n /** A parameter or header with `content`, not `schema`, is typed by its media type's schema. */\n PARAMETER_HEADER_CONTENT: \"parameter-header-content\",\n /** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */\n PATH_PARAM_TYPE_NAMES: \"path-param-type-names\",\n /** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */\n PREFIX_ITEMS: \"prefix-items\",\n /** `readOnly` and `writeOnly` of the schema a `$ref` names, or of `allOf` members, count. */\n READ_WRITE_REFS: \"read-write-refs\",\n /**\n * A `$ref` into schema keywords (`content/<type>/schema`, `items`, `allOf/0`) gets the type it\n * points at, also where the original type compiles through an index signature.\n */\n REF_POINTERS: \"ref-pointers\",\n /**\n * OpenAPI 3.1 and 3.2: keywords next to a `$ref` (`required`, `properties`) apply too, so the\n * type is the reference intersected with them. OpenAPI 3.0 ignores them, as its spec says.\n */\n REF_SIBLINGS: \"ref-siblings\",\n /** Schemas of one root type name without the prefix each get an alias, the earlier numbered. */\n ROOT_TYPE_NUMBERING: \"root-type-numbering\",\n /** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */\n UNEVALUATED_PROPERTIES: \"unevaluated-properties\",\n} as const;\n/** The name of one opt-in output fix. */\nexport type OutputFix = (typeof FIX)[keyof typeof FIX];\n\n/** Every fix of this version, in the order the docs list them. */\nexport const OUTPUT_FIXES: readonly OutputFix[] = Object.values(FIX);\n\n/** The name that turns on every fix of the installed version. */\nconst ALL_FIXES = \"all\";\n\n/** A name the `fix` option accepts: one fix, or `\"all\"`. */\nexport type OutputFixName = OutputFix | typeof ALL_FIXES;\n\nconst KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES, ALL_FIXES]);\n\nfunction isOutputFixName(value: unknown): value is OutputFixName {\n return typeof value === \"string\" && KNOWN_NAMES.has(value);\n}\n\n/**\n * The fix names as given; fails with `OPTION_FIX_UNKNOWN` for any other value, and for a `fix`\n * option that is no list (`fix: \"all\"` from JavaScript), which must not be read letter by letter.\n */\nexport function outputFixNamesOf(values: unknown): readonly OutputFixName[] {\n if (!Array.isArray(values)) {\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message:\n 'The fix option must be a list of fix names, such as [\"all\"]. ' +\n `Got ${JSON.stringify(values)}.`,\n details: { unknown: [values], known: [...KNOWN_NAMES] },\n });\n }\n const unknown = values.filter((value) => !isOutputFixName(value));\n if (unknown.length > 0) {\n const names = unknown.map((value) => JSON.stringify(value)).join(\", \");\n const known = [...KNOWN_NAMES].join(\", \");\n throw new OpenAPITypesafeError({\n code: ERROR_CODES.OPTION_FIX_UNKNOWN,\n message: `Unknown fix ${names}. Known fixes: ${known}.`,\n details: { unknown, known: [...KNOWN_NAMES] },\n });\n }\n return values as readonly OutputFixName[];\n}\n\n/** The fixes the names turn on; `all` stands for every fix of this version. */\nexport function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet<OutputFix> {\n return new Set(names.flatMap((name) => (name === ALL_FIXES ? OUTPUT_FIXES : [name])));\n}\n\n/** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */\nexport interface OutputFixRequirement {\n readonly option:\n | \"arrayLength\"\n | \"dedupeEnums\"\n | \"defaultNonNullable\"\n | \"enum\"\n | \"pathParamsAsTypes\"\n | \"rootTypes\"\n | \"rootTypesNoSchemaPrefix\";\n readonly flag: string;\n}\n\nconst ROOT_TYPES = { option: \"rootTypes\", flag: \"--root-types\" } as const;\nconst ENUM = { option: \"enum\", flag: \"--enum\" } as const;\nconst NO_SCHEMA_PREFIX = {\n option: \"rootTypesNoSchemaPrefix\",\n flag: \"--root-types-no-schema-prefix\",\n} as const;\n\n/** The options each fix needs, by fix name; `all` has none. */\nconst REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {\n [FIX.ARRAY_LENGTH_TUPLES]: [{ option: \"arrayLength\", flag: \"--array-length\" }],\n [FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: \"dedupeEnums\", flag: \"--dedupe-enums\" }],\n [FIX.DEFAULT_INPUT_LOCATIONS]: [{ option: \"defaultNonNullable\", flag: \"--default-non-nullable\" }],\n [FIX.NULLABLE_ENUMS]: [ENUM],\n [FIX.PATH_PARAM_TYPE_NAMES]: [{ option: \"pathParamsAsTypes\", flag: \"--path-params-as-types\" }],\n [FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],\n};\n\nfunction describeRequirement(requirement: OutputFixRequirement): string {\n return `${requirement.option} (${requirement.flag})`;\n}\n\n/**\n * A notice for each fix given by name with an option it needs off; it names the options that are\n * off. `all` adds none: it means every fix that applies, so one that does not apply is expected.\n */\nexport function ineffectiveFixNotices(\n names: readonly OutputFixName[],\n isOptionOn: (option: OutputFixRequirement[\"option\"]) => boolean,\n): string[] {\n return [...new Set(names)].flatMap((name) => {\n const missing = (REQUIREMENTS[name] ?? []).filter(({ option }) => !isOptionOn(option));\n return missing.length === 0\n ? []\n : [`Fix \"${name}\" has no effect without ${missing.map(describeRequirement).join(\" and \")}`];\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CONTROL_RANGES = [
|
|
4
|
+
[0, 8],
|
|
5
|
+
[10, 31],
|
|
6
|
+
[127, 159],
|
|
7
|
+
[8232, 8233],
|
|
8
|
+
[8234, 8238],
|
|
9
|
+
[8294, 8297]
|
|
10
|
+
];
|
|
11
|
+
const SHORT_ESCAPES = { "\n": "\\n", "\r": "\\r" };
|
|
12
|
+
const HEX_DIGITS = 4;
|
|
13
|
+
const HEX_RADIX = 16;
|
|
14
|
+
function isControl(codePoint) {
|
|
15
|
+
return CONTROL_RANGES.some(([first, last]) => codePoint >= first && codePoint <= last);
|
|
16
|
+
}
|
|
17
|
+
function escapeOf(character, codePoint) {
|
|
18
|
+
const hex = codePoint.toString(HEX_RADIX).padStart(HEX_DIGITS, "0");
|
|
19
|
+
return SHORT_ESCAPES[character] ?? `\\u${hex}`;
|
|
20
|
+
}
|
|
21
|
+
function terminalSafeText(text) {
|
|
22
|
+
let shown = "";
|
|
23
|
+
for (const character of text) {
|
|
24
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
25
|
+
shown += isControl(codePoint) ? escapeOf(character, codePoint) : character;
|
|
26
|
+
}
|
|
27
|
+
return shown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.terminalSafeText = terminalSafeText;
|
|
31
|
+
//# sourceMappingURL=terminal-text.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-text.cjs","sources":["../../src/domain/terminal-text.ts"],"sourcesContent":["/**\n * Text from a document or a project (a path key, an `operationId`, a file name) reaches the\n * terminal and CI job logs. A line break in it starts a new line that CI reads as a command\n * (`::error …` in GitHub Actions, `##vso[…]` in Azure Pipelines), and an escape sequence moves\n * the cursor or erases lines, so it can forge or hide output. Each such character is shown as an\n * escape instead (`\\n`, `\\u001b`), so one message stays one line and shows what the text holds.\n */\n\n/**\n * The code points shown as escapes: C0 controls but the tab, DEL and C1 controls, the Unicode\n * line and paragraph separators, and the bidirectional controls, which reorder how a terminal\n * shows the text around them.\n */\nconst CONTROL_RANGES: readonly (readonly [number, number])[] = [\n [0x00, 0x08],\n [0x0a, 0x1f],\n [0x7f, 0x9f],\n [0x2028, 0x2029],\n [0x202a, 0x202e],\n [0x2066, 0x2069],\n];\n\nconst SHORT_ESCAPES: Readonly<Record<string, string>> = { \"\\n\": \"\\\\n\", \"\\r\": \"\\\\r\" };\nconst HEX_DIGITS = 4;\nconst HEX_RADIX = 16;\n\nfunction isControl(codePoint: number): boolean {\n return CONTROL_RANGES.some(([first, last]) => codePoint >= first && codePoint <= last);\n}\n\nfunction escapeOf(character: string, codePoint: number): string {\n const hex = codePoint.toString(HEX_RADIX).padStart(HEX_DIGITS, \"0\");\n return SHORT_ESCAPES[character] ?? `\\\\u${hex}`;\n}\n\n/** The text with every control character shown as an escape, so it prints as one plain line. */\nexport function terminalSafeText(text: string): string {\n let shown = \"\";\n for (const character of text) {\n const codePoint = character.codePointAt(0) ?? 0;\n shown += isControl(codePoint) ? escapeOf(character, codePoint) : character;\n }\n return shown;\n}\n"],"names":[],"mappings":";;AAaA,MAAM,cAAA,GAAyD;AAAA,EAC7D,CAAC,GAAM,CAAI,CAAA;AAAA,EACX,CAAC,IAAM,EAAI,CAAA;AAAA,EACX,CAAC,KAAM,GAAI,CAAA;AAAA,EACX,CAAC,MAAQ,IAAM,CAAA;AAAA,EACf,CAAC,MAAQ,IAAM,CAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AACjB,CAAA;AAEA,MAAM,aAAA,GAAkD,EAAE,IAAA,EAAM,KAAA,EAAO,MAAM,KAAA,EAAM;AACnF,MAAM,UAAA,GAAa,CAAA;AACnB,MAAM,SAAA,GAAY,EAAA;AAElB,SAAS,UAAU,SAAA,EAA4B;AAC7C,EAAA,OAAO,cAAA,CAAe,IAAA,CAAK,CAAC,CAAC,KAAA,EAAO,IAAI,CAAA,KAAM,SAAA,IAAa,KAAA,IAAS,SAAA,IAAa,IAAI,CAAA;AACvF;AAEA,SAAS,QAAA,CAAS,WAAmB,SAAA,EAA2B;AAC9D,EAAA,MAAM,MAAM,SAAA,CAAU,QAAA,CAAS,SAAS,CAAA,CAAE,QAAA,CAAS,YAAY,GAAG,CAAA;AAClE,EAAA,OAAO,aAAA,CAAc,SAAS,CAAA,IAAK,CAAA,GAAA,EAAM,GAAG,CAAA,CAAA;AAC9C;AAGO,SAAS,iBAAiB,IAAA,EAAsB;AACrD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,MAAW,aAAa,IAAA,EAAM;AAC5B,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA;AAC9C,IAAA,KAAA,IAAS,UAAU,SAAS,CAAA,GAAI,QAAA,CAAS,SAAA,EAAW,SAAS,CAAA,GAAI,SAAA;AAAA,EACnE;AACA,EAAA,OAAO,KAAA;AACT;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const CONTROL_RANGES = [
|
|
2
|
+
[0, 8],
|
|
3
|
+
[10, 31],
|
|
4
|
+
[127, 159],
|
|
5
|
+
[8232, 8233],
|
|
6
|
+
[8234, 8238],
|
|
7
|
+
[8294, 8297]
|
|
8
|
+
];
|
|
9
|
+
const SHORT_ESCAPES = { "\n": "\\n", "\r": "\\r" };
|
|
10
|
+
const HEX_DIGITS = 4;
|
|
11
|
+
const HEX_RADIX = 16;
|
|
12
|
+
function isControl(codePoint) {
|
|
13
|
+
return CONTROL_RANGES.some(([first, last]) => codePoint >= first && codePoint <= last);
|
|
14
|
+
}
|
|
15
|
+
function escapeOf(character, codePoint) {
|
|
16
|
+
const hex = codePoint.toString(HEX_RADIX).padStart(HEX_DIGITS, "0");
|
|
17
|
+
return SHORT_ESCAPES[character] ?? `\\u${hex}`;
|
|
18
|
+
}
|
|
19
|
+
function terminalSafeText(text) {
|
|
20
|
+
let shown = "";
|
|
21
|
+
for (const character of text) {
|
|
22
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
23
|
+
shown += isControl(codePoint) ? escapeOf(character, codePoint) : character;
|
|
24
|
+
}
|
|
25
|
+
return shown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { terminalSafeText };
|
|
29
|
+
//# sourceMappingURL=terminal-text.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-text.mjs","sources":["../../src/domain/terminal-text.ts"],"sourcesContent":["/**\n * Text from a document or a project (a path key, an `operationId`, a file name) reaches the\n * terminal and CI job logs. A line break in it starts a new line that CI reads as a command\n * (`::error …` in GitHub Actions, `##vso[…]` in Azure Pipelines), and an escape sequence moves\n * the cursor or erases lines, so it can forge or hide output. Each such character is shown as an\n * escape instead (`\\n`, `\\u001b`), so one message stays one line and shows what the text holds.\n */\n\n/**\n * The code points shown as escapes: C0 controls but the tab, DEL and C1 controls, the Unicode\n * line and paragraph separators, and the bidirectional controls, which reorder how a terminal\n * shows the text around them.\n */\nconst CONTROL_RANGES: readonly (readonly [number, number])[] = [\n [0x00, 0x08],\n [0x0a, 0x1f],\n [0x7f, 0x9f],\n [0x2028, 0x2029],\n [0x202a, 0x202e],\n [0x2066, 0x2069],\n];\n\nconst SHORT_ESCAPES: Readonly<Record<string, string>> = { \"\\n\": \"\\\\n\", \"\\r\": \"\\\\r\" };\nconst HEX_DIGITS = 4;\nconst HEX_RADIX = 16;\n\nfunction isControl(codePoint: number): boolean {\n return CONTROL_RANGES.some(([first, last]) => codePoint >= first && codePoint <= last);\n}\n\nfunction escapeOf(character: string, codePoint: number): string {\n const hex = codePoint.toString(HEX_RADIX).padStart(HEX_DIGITS, \"0\");\n return SHORT_ESCAPES[character] ?? `\\\\u${hex}`;\n}\n\n/** The text with every control character shown as an escape, so it prints as one plain line. */\nexport function terminalSafeText(text: string): string {\n let shown = \"\";\n for (const character of text) {\n const codePoint = character.codePointAt(0) ?? 0;\n shown += isControl(codePoint) ? escapeOf(character, codePoint) : character;\n }\n return shown;\n}\n"],"names":[],"mappings":"AAaA,MAAM,cAAA,GAAyD;AAAA,EAC7D,CAAC,GAAM,CAAI,CAAA;AAAA,EACX,CAAC,IAAM,EAAI,CAAA;AAAA,EACX,CAAC,KAAM,GAAI,CAAA;AAAA,EACX,CAAC,MAAQ,IAAM,CAAA;AAAA,EACf,CAAC,MAAQ,IAAM,CAAA;AAAA,EACf,CAAC,MAAQ,IAAM;AACjB,CAAA;AAEA,MAAM,aAAA,GAAkD,EAAE,IAAA,EAAM,KAAA,EAAO,MAAM,KAAA,EAAM;AACnF,MAAM,UAAA,GAAa,CAAA;AACnB,MAAM,SAAA,GAAY,EAAA;AAElB,SAAS,UAAU,SAAA,EAA4B;AAC7C,EAAA,OAAO,cAAA,CAAe,IAAA,CAAK,CAAC,CAAC,KAAA,EAAO,IAAI,CAAA,KAAM,SAAA,IAAa,KAAA,IAAS,SAAA,IAAa,IAAI,CAAA;AACvF;AAEA,SAAS,QAAA,CAAS,WAAmB,SAAA,EAA2B;AAC9D,EAAA,MAAM,MAAM,SAAA,CAAU,QAAA,CAAS,SAAS,CAAA,CAAE,QAAA,CAAS,YAAY,GAAG,CAAA;AAClE,EAAA,OAAO,aAAA,CAAc,SAAS,CAAA,IAAK,CAAA,GAAA,EAAM,GAAG,CAAA,CAAA;AAC9C;AAGO,SAAS,iBAAiB,IAAA,EAAsB;AACrD,EAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,EAAA,KAAA,MAAW,aAAa,IAAA,EAAM;AAC5B,IAAA,MAAM,SAAA,GAAY,SAAA,CAAU,WAAA,CAAY,CAAC,CAAA,IAAK,CAAA;AAC9C,IAAA,KAAA,IAAS,UAAU,SAAS,CAAA,GAAI,QAAA,CAAS,SAAA,EAAW,SAAS,CAAA,GAAI,SAAA;AAAA,EACnE;AACA,EAAA,OAAO,KAAA;AACT;;"}
|