openapi-typesafe 1.0.0-rc.1 → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/adapters/node-deprecations/node-deprecations.cjs +14 -0
- package/dist/adapters/node-deprecations/node-deprecations.cjs.map +1 -0
- package/dist/adapters/node-deprecations/node-deprecations.mjs +12 -0
- package/dist/adapters/node-deprecations/node-deprecations.mjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
- package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
- package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +19 -6
- package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +18 -5
- package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
- package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
- package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
- package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
- package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
- package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
- package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
- package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
- package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
- package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
- package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
- package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
- package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +2 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +2 -1
- package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
- package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
- package/dist/api/default-ports.cjs +14 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +12 -1
- package/dist/api/default-ports.mjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs +1 -1
- package/dist/api/discriminator-conflict-warnings.cjs.map +1 -1
- package/dist/api/discriminator-conflict-warnings.mjs +2 -2
- package/dist/api/discriminator-conflict-warnings.mjs.map +1 -1
- package/dist/api/discriminator-patch.cjs +8 -4
- package/dist/api/discriminator-patch.cjs.map +1 -1
- package/dist/api/discriminator-patch.mjs +9 -5
- package/dist/api/discriminator-patch.mjs.map +1 -1
- package/dist/api/discriminator-scan.cjs +2 -2
- package/dist/api/discriminator-scan.cjs.map +1 -1
- package/dist/api/discriminator-scan.mjs +3 -3
- package/dist/api/discriminator-scan.mjs.map +1 -1
- package/dist/api/document-refs.cjs +15 -12
- package/dist/api/document-refs.cjs.map +1 -1
- package/dist/api/document-refs.mjs +15 -12
- package/dist/api/document-refs.mjs.map +1 -1
- package/dist/api/document-run.cjs +6 -3
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +6 -3
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/footer-sink.cjs +25 -2
- package/dist/api/footer-sink.cjs.map +1 -1
- package/dist/api/footer-sink.mjs +25 -2
- package/dist/api/footer-sink.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +7 -1
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +8 -2
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/legacy-ts-helpers.cjs.map +1 -1
- package/dist/api/legacy-ts-helpers.mjs.map +1 -1
- package/dist/api/legacy-utils.cjs.map +1 -1
- package/dist/api/legacy-utils.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +3 -2
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +4 -3
- package/dist/api/openapi-ts.mjs.map +1 -1
- package/dist/api/string-to-ast.cjs +7 -9
- package/dist/api/string-to-ast.cjs.map +1 -1
- package/dist/api/string-to-ast.mjs +8 -9
- package/dist/api/string-to-ast.mjs.map +1 -1
- package/dist/api/transform-context.cjs +1 -1
- package/dist/api/transform-context.cjs.map +1 -1
- package/dist/api/transform-context.mjs +1 -1
- package/dist/api/transform-context.mjs.map +1 -1
- package/dist/api/transform-schema.cjs +2 -2
- package/dist/api/transform-schema.cjs.map +1 -1
- package/dist/api/transform-schema.mjs +3 -3
- package/dist/api/transform-schema.mjs.map +1 -1
- package/dist/application/print/type-printer.cjs +2 -1
- package/dist/application/print/type-printer.cjs.map +1 -1
- package/dist/application/print/type-printer.mjs +2 -1
- package/dist/application/print/type-printer.mjs.map +1 -1
- package/dist/application/transform/document/components.cjs +1 -1
- package/dist/application/transform/document/components.cjs.map +1 -1
- package/dist/application/transform/document/components.mjs +2 -2
- package/dist/application/transform/document/components.mjs.map +1 -1
- package/dist/application/transform/document/parameters.cjs +2 -2
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +3 -3
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +2 -2
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +3 -3
- package/dist/application/transform/document/paths.mjs.map +1 -1
- package/dist/application/transform/footer/evaluation.cjs +9 -0
- package/dist/application/transform/footer/evaluation.cjs.map +1 -1
- package/dist/application/transform/footer/evaluation.mjs +8 -1
- package/dist/application/transform/footer/evaluation.mjs.map +1 -1
- package/dist/application/transform/footer/type-evaluation.cjs +4 -112
- package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
- package/dist/application/transform/footer/type-evaluation.mjs +4 -112
- package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
- package/dist/application/transform/footer/type-indexing.cjs +107 -0
- package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
- package/dist/application/transform/footer/type-indexing.mjs +105 -0
- package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
- package/dist/application/transform/ref-pointer/pointer-type.cjs +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
- package/dist/application/transform/ref-pointer/pointer-type.mjs +2 -2
- package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
- package/dist/application/transform/schema/access-flags.cjs +1 -1
- package/dist/application/transform/schema/access-flags.cjs.map +1 -1
- package/dist/application/transform/schema/access-flags.mjs +2 -2
- package/dist/application/transform/schema/access-flags.mjs.map +1 -1
- package/dist/application/transform/schema/array-type.cjs +2 -2
- package/dist/application/transform/schema/array-type.cjs.map +1 -1
- package/dist/application/transform/schema/array-type.mjs +3 -3
- package/dist/application/transform/schema/array-type.mjs.map +1 -1
- package/dist/application/transform/schema/composition-type.cjs +3 -3
- package/dist/application/transform/schema/composition-type.cjs.map +1 -1
- package/dist/application/transform/schema/composition-type.mjs +4 -4
- package/dist/application/transform/schema/composition-type.mjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.cjs +3 -5
- package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
- package/dist/application/transform/schema/enum-rule.mjs +4 -6
- package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
- package/dist/application/transform/schema/presence-members.cjs +1 -1
- package/dist/application/transform/schema/presence-members.cjs.map +1 -1
- package/dist/application/transform/schema/presence-members.mjs +2 -2
- package/dist/application/transform/schema/presence-members.mjs.map +1 -1
- package/dist/application/transform/schema/required-variants.cjs +2 -2
- package/dist/application/transform/schema/required-variants.cjs.map +1 -1
- package/dist/application/transform/schema/required-variants.mjs +3 -3
- package/dist/application/transform/schema/required-variants.mjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs +1 -1
- package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
- package/dist/application/transform/schema/unevaluated-properties.mjs +2 -2
- package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
- package/dist/application/transform/schema-comment.cjs +1 -1
- package/dist/application/transform/schema-comment.cjs.map +1 -1
- package/dist/application/transform/schema-comment.mjs +2 -2
- package/dist/application/transform/schema-comment.mjs.map +1 -1
- package/dist/cli/api-settings.cjs +78 -0
- package/dist/cli/api-settings.cjs.map +1 -0
- package/dist/cli/api-settings.mjs +73 -0
- package/dist/cli/api-settings.mjs.map +1 -0
- package/dist/cli/cli-arguments.cjs +1 -0
- package/dist/cli/cli-arguments.cjs.map +1 -1
- package/dist/cli/cli-arguments.mjs +1 -1
- package/dist/cli/cli-arguments.mjs.map +1 -1
- package/dist/cli/help-text.cjs +3 -3
- package/dist/cli/help-text.cjs.map +1 -1
- package/dist/cli/help-text.mjs +3 -3
- package/dist/cli/help-text.mjs.map +1 -1
- package/dist/cli/redocly-apis.cjs +8 -4
- package/dist/cli/redocly-apis.cjs.map +1 -1
- package/dist/cli/redocly-apis.mjs +7 -3
- package/dist/cli/redocly-apis.mjs.map +1 -1
- package/dist/cli/run-cli.cjs +5 -1
- package/dist/cli/run-cli.cjs.map +1 -1
- package/dist/cli/run-cli.mjs +5 -1
- package/dist/cli/run-cli.mjs.map +1 -1
- package/dist/domain/deprecations.cjs +11 -0
- package/dist/domain/deprecations.cjs.map +1 -0
- package/dist/domain/deprecations.mjs +9 -0
- package/dist/domain/deprecations.mjs.map +1 -0
- package/dist/domain/errors.cjs +4 -1
- package/dist/domain/errors.cjs.map +1 -1
- package/dist/domain/errors.mjs +4 -1
- package/dist/domain/errors.mjs.map +1 -1
- package/dist/domain/ir/constructors.cjs +2 -0
- package/dist/domain/ir/constructors.cjs.map +1 -1
- package/dist/domain/ir/constructors.mjs +2 -1
- package/dist/domain/ir/constructors.mjs.map +1 -1
- package/dist/domain/openapi/path-templates.cjs +1 -1
- package/dist/domain/openapi/path-templates.cjs.map +1 -1
- package/dist/domain/openapi/path-templates.mjs +1 -1
- package/dist/domain/openapi/path-templates.mjs.map +1 -1
- package/dist/domain/output-fixes.cjs +11 -14
- package/dist/domain/output-fixes.cjs.map +1 -1
- package/dist/domain/output-fixes.mjs +11 -13
- package/dist/domain/output-fixes.mjs.map +1 -1
- package/dist/domain/url-credentials.cjs +10 -0
- package/dist/domain/url-credentials.cjs.map +1 -0
- package/dist/domain/url-credentials.mjs +8 -0
- package/dist/domain/url-credentials.mjs.map +1 -0
- package/dist/domain/warnings.cjs +8 -1
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +8 -1
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.cjs +4 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1185 -59
- package/dist/index.d.mts +1185 -59
- package/dist/index.d.ts +1185 -59
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/dist/transform/path-item-object.cjs.map +1 -1
- package/dist/transform/path-item-object.mjs.map +1 -1
- package/package.json +5 -4
- package/src/adapters/node-deprecations/node-deprecations.ts +14 -0
- package/src/adapters/redocly-loader/configured-headers.ts +65 -0
- package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -7
- package/src/adapters/redocly-loader/ref-access.ts +60 -5
- package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
- package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
- package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
- package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
- package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
- package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
- package/src/adapters/type-ast-bridge/ir-to-typescript.ts +2 -1
- package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
- package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
- package/src/api/default-ports.ts +23 -0
- package/src/api/discriminator-conflict-warnings.ts +2 -2
- package/src/api/discriminator-patch.ts +11 -7
- package/src/api/discriminator-scan.ts +3 -3
- package/src/api/document-refs.ts +19 -15
- package/src/api/document-run.ts +14 -6
- package/src/api/footer-sink.ts +34 -2
- package/src/api/legacy-callback-warning.ts +16 -5
- package/src/api/legacy-ts-helpers.ts +7 -5
- package/src/api/legacy-utils.ts +1 -1
- package/src/api/openapi-ts.ts +8 -2
- package/src/api/run-context.ts +37 -0
- package/src/api/string-to-ast.ts +11 -15
- package/src/api/transform-context.ts +10 -8
- package/src/api/transform-schema.ts +9 -8
- package/src/application/ports/deprecation-reporter.ts +9 -0
- package/src/application/print/type-printer.ts +2 -1
- package/src/application/transform/document/components.ts +2 -2
- package/src/application/transform/document/parameters.ts +4 -3
- package/src/application/transform/document/paths.ts +4 -3
- package/src/application/transform/footer/evaluation.ts +10 -0
- package/src/application/transform/footer/type-evaluation.ts +6 -133
- package/src/application/transform/footer/type-indexing.ts +152 -0
- package/src/application/transform/ref-pointer/pointer-type.ts +2 -4
- package/src/application/transform/schema/access-flags.ts +2 -2
- package/src/application/transform/schema/array-type.ts +3 -5
- package/src/application/transform/schema/composition-type.ts +4 -4
- package/src/application/transform/schema/enum-rule.ts +4 -6
- package/src/application/transform/schema/presence-members.ts +2 -2
- package/src/application/transform/schema/required-variants.ts +3 -3
- package/src/application/transform/schema/unevaluated-properties.ts +2 -2
- package/src/application/transform/schema-comment.ts +2 -2
- package/src/cli/api-settings.ts +109 -0
- package/src/cli/cli-arguments.ts +5 -2
- package/src/cli/help-text.ts +4 -4
- package/src/cli/redocly-apis.ts +13 -7
- package/src/cli/run-cli.ts +5 -1
- package/src/domain/deprecations.ts +15 -0
- package/src/domain/errors.ts +16 -4
- package/src/domain/ir/constructors.ts +3 -0
- package/src/domain/ir/nodes.ts +9 -6
- package/src/domain/openapi/path-templates.ts +2 -1
- package/src/domain/output-fixes.ts +16 -16
- package/src/domain/url-credentials.ts +18 -0
- package/src/domain/warnings.ts +7 -0
- package/src/index.ts +3 -6
- package/src/transform/path-item-object.ts +6 -2
- package/src/types/generator-options.ts +12 -32
- package/src/types/openapi-common.ts +1 -0
- package/src/types/openapi-request.ts +3 -0
- package/src/types/openapi-schema.ts +2 -0
- package/src/types/openapi-security.ts +1 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const evaluation = require('./evaluation.cjs');
|
|
4
|
+
const typeRules = require('./type-rules.cjs');
|
|
5
|
+
|
|
6
|
+
function indexType(types, value, index) {
|
|
7
|
+
const owner = types.expand(value);
|
|
8
|
+
if (owner.kind !== "type") {
|
|
9
|
+
return owner;
|
|
10
|
+
}
|
|
11
|
+
if (types.membersOf(owner).length > 1) {
|
|
12
|
+
return unionIndex(types, owner, index);
|
|
13
|
+
}
|
|
14
|
+
const { type } = owner;
|
|
15
|
+
switch (type.kind) {
|
|
16
|
+
case "object":
|
|
17
|
+
return memberType(types, owner, type.members, index);
|
|
18
|
+
case "intersection":
|
|
19
|
+
return partsIndex(types, owner, type.types, index);
|
|
20
|
+
case "union":
|
|
21
|
+
return unionIndex(types, owner, index);
|
|
22
|
+
case "array":
|
|
23
|
+
return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);
|
|
24
|
+
case "keyword":
|
|
25
|
+
return type.keyword === "never" ? owner : builtInIndex(index);
|
|
26
|
+
default:
|
|
27
|
+
return builtInIndex(index);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function memberType(types, owner, members, index) {
|
|
31
|
+
const key = indexKey(index);
|
|
32
|
+
const property = members.find(
|
|
33
|
+
(member) => member.kind === "property" && key !== null && evaluation.propertyKey(member.name) === key
|
|
34
|
+
);
|
|
35
|
+
if (property !== void 0) {
|
|
36
|
+
return flattened(types, owner, property.type);
|
|
37
|
+
}
|
|
38
|
+
const signature = members.find((member) => member.kind === "indexSignature");
|
|
39
|
+
if (signature !== void 0) {
|
|
40
|
+
return flattened(types, owner, signature.type);
|
|
41
|
+
}
|
|
42
|
+
return key === null || isObjectBuiltIn(key) ? evaluation.OPAQUE : evaluation.MISSING;
|
|
43
|
+
}
|
|
44
|
+
function partsIndex(types, owner, parts, index) {
|
|
45
|
+
if (typeRules.isNeverIntersection(types, owner, parts)) {
|
|
46
|
+
return { ...owner, type: evaluation.NEVER };
|
|
47
|
+
}
|
|
48
|
+
const found = parts.map((type) => types.index({ ...owner, type }, index));
|
|
49
|
+
if (found.some((part) => part.kind === "opaque")) {
|
|
50
|
+
return evaluation.OPAQUE;
|
|
51
|
+
}
|
|
52
|
+
const read = parts.map((type, at) => ({ type, found: found[at] }));
|
|
53
|
+
const kept = typeRules.declaredFirst(types, owner, indexKey(index), read).flatMap(
|
|
54
|
+
(part) => part.kind === "type" ? [part.type] : []
|
|
55
|
+
);
|
|
56
|
+
return kept.length === 0 ? evaluation.MISSING : { ...owner, type: evaluation.intersectionType(kept) };
|
|
57
|
+
}
|
|
58
|
+
function unionIndex(types, owner, index) {
|
|
59
|
+
const found = types.membersOf(owner).map((member) => member.kind === "type" ? types.index(member, index) : member);
|
|
60
|
+
if (found.some((member) => member.kind === "missing")) {
|
|
61
|
+
return evaluation.MISSING;
|
|
62
|
+
}
|
|
63
|
+
if (found.some((member) => member.kind === "opaque")) {
|
|
64
|
+
return evaluation.OPAQUE;
|
|
65
|
+
}
|
|
66
|
+
return { ...owner, type: evaluation.unionType(found.map((member) => member.type)) };
|
|
67
|
+
}
|
|
68
|
+
function flattened(types, owner, type) {
|
|
69
|
+
const member = { ...owner, type };
|
|
70
|
+
if (!owner.deep) {
|
|
71
|
+
return types.expand(member);
|
|
72
|
+
}
|
|
73
|
+
const members = types.membersOf(member);
|
|
74
|
+
if (members.some((candidate) => candidate.kind !== "type")) {
|
|
75
|
+
return evaluation.OPAQUE;
|
|
76
|
+
}
|
|
77
|
+
const present = members.filter((candidate) => !evaluation.isNullish(candidate.type));
|
|
78
|
+
const elements = present.map((candidate) => arrayElement(candidate.type));
|
|
79
|
+
if (present.length > 0 && elements.every((element) => element !== null)) {
|
|
80
|
+
return types.expand({ ...owner, type: evaluation.unionType(elements) });
|
|
81
|
+
}
|
|
82
|
+
return { ...owner, type: evaluation.unionType(present.map((candidate) => candidate.type)) };
|
|
83
|
+
}
|
|
84
|
+
function arrayElement(type) {
|
|
85
|
+
return type.kind === "array" ? type.element : null;
|
|
86
|
+
}
|
|
87
|
+
function indexKey(index) {
|
|
88
|
+
if (index.kind === "stringLiteral") {
|
|
89
|
+
return index.value;
|
|
90
|
+
}
|
|
91
|
+
return index.kind === "numberLiteral" ? String(index.value) : null;
|
|
92
|
+
}
|
|
93
|
+
function isNumberIndex(index) {
|
|
94
|
+
const key = indexKey(index);
|
|
95
|
+
return index.kind === "keyword" && index.keyword === "number" || /^\d+$/.test(key ?? "");
|
|
96
|
+
}
|
|
97
|
+
function isObjectBuiltIn(key) {
|
|
98
|
+
return key in {};
|
|
99
|
+
}
|
|
100
|
+
function builtInIndex(index) {
|
|
101
|
+
const key = indexKey(index);
|
|
102
|
+
const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;
|
|
103
|
+
return isBuiltIn || key in Number.prototype ? evaluation.OPAQUE : evaluation.MISSING;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
exports.indexType = indexType;
|
|
107
|
+
//# sourceMappingURL=type-indexing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-indexing.cjs","sources":["../../../../src/application/transform/footer/type-indexing.ts"],"sourcesContent":["import type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport {\n type Evaluated,\n type Evaluation,\n intersectionType,\n isNullish,\n MISSING,\n NEVER,\n OPAQUE,\n propertyKey,\n unionType,\n} from \"./evaluation.js\";\nimport { declaredFirst, isNeverIntersection, type TypeExpansion } from \"./type-rules.js\";\n\n/**\n * Indexed access (`T[\"key\"]`, `T[number]`) on the generated types, as TypeScript reads it, for\n * the evaluator of the `--enum-values` check (ADR-027).\n */\n\n/** The part of the evaluator that indexed access uses. */\nexport interface IndexedTypes extends TypeExpansion {\n expand(value: Evaluated): Evaluation;\n index(value: Evaluated, index: IrType): Evaluation;\n}\n\n/** `value[index]` for a string literal, `string` or `number` index. */\nexport function indexType(types: IndexedTypes, value: Evaluated, index: IrType): Evaluation {\n const owner = types.expand(value);\n if (owner.kind !== \"type\") {\n return owner;\n }\n if (types.membersOf(owner).length > 1) {\n return unionIndex(types, owner, index);\n }\n const { type } = owner;\n switch (type.kind) {\n case \"object\":\n return memberType(types, owner, type.members, index);\n case \"intersection\":\n return partsIndex(types, owner, type.types, index);\n case \"union\":\n return unionIndex(types, owner, index);\n case \"array\":\n return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);\n case \"keyword\":\n return type.keyword === \"never\" ? owner : builtInIndex(index);\n default:\n return builtInIndex(index);\n }\n}\n\nfunction memberType(\n types: IndexedTypes,\n owner: Evaluated,\n members: readonly IrMember[],\n index: IrType,\n): Evaluation {\n const key = indexKey(index);\n const property = members.find(\n (member) => member.kind === \"property\" && key !== null && propertyKey(member.name) === key,\n );\n if (property !== undefined) {\n return flattened(types, owner, property.type);\n }\n const signature = members.find((member) => member.kind === \"indexSignature\");\n if (signature !== undefined) {\n return flattened(types, owner, signature.type);\n }\n return key === null || isObjectBuiltIn(key) ? OPAQUE : MISSING;\n}\n\nfunction partsIndex(\n types: IndexedTypes,\n owner: Evaluated,\n parts: readonly IrType[],\n index: IrType,\n): Evaluation {\n if (isNeverIntersection(types, owner, parts)) {\n return { ...owner, type: NEVER };\n }\n const found = parts.map((type) => types.index({ ...owner, type }, index));\n if (found.some((part) => part.kind === \"opaque\")) {\n return OPAQUE;\n }\n const read = parts.map((type, at) => ({ type, found: found[at] as Evaluation }));\n const kept = declaredFirst(types, owner, indexKey(index), read).flatMap((part) =>\n part.kind === \"type\" ? [part.type] : [],\n );\n return kept.length === 0 ? MISSING : { ...owner, type: intersectionType(kept) };\n}\n\nfunction unionIndex(types: IndexedTypes, owner: Evaluated, index: IrType): Evaluation {\n const found = types\n .membersOf(owner)\n .map((member) => (member.kind === \"type\" ? types.index(member, index) : member));\n if (found.some((member) => member.kind === \"missing\")) {\n return MISSING;\n }\n if (found.some((member) => member.kind === \"opaque\")) {\n return OPAQUE;\n }\n return { ...owner, type: unionType((found as Evaluated[]).map((member) => member.type)) };\n}\n\n/**\n * A member read through `FlattenedDeepRequired`: a value that is only arrays (and `undefined` or\n * `null`) is replaced by its elements, anything else loses `undefined` and `null`.\n */\nfunction flattened(types: IndexedTypes, owner: Evaluated, type: IrType): Evaluation {\n const member: Evaluated = { ...owner, type };\n if (!owner.deep) {\n return types.expand(member);\n }\n const members = types.membersOf(member);\n if (members.some((candidate) => candidate.kind !== \"type\")) {\n return OPAQUE;\n }\n const present = (members as Evaluated[]).filter((candidate) => !isNullish(candidate.type));\n const elements = present.map((candidate) => arrayElement(candidate.type));\n if (present.length > 0 && elements.every((element) => element !== null)) {\n return types.expand({ ...owner, type: unionType(elements as IrType[]) });\n }\n return { ...owner, type: unionType(present.map((candidate) => candidate.type)) };\n}\n\n/** The element of an expanded member; expanding already dropped `readonly`. */\nfunction arrayElement(type: IrType): IrType | null {\n return type.kind === \"array\" ? type.element : null;\n}\n\nfunction indexKey(index: IrType): string | null {\n if (index.kind === \"stringLiteral\") {\n return index.value;\n }\n return index.kind === \"numberLiteral\" ? String(index.value) : null;\n}\n\nfunction isNumberIndex(index: IrType): boolean {\n const key = indexKey(index);\n return (index.kind === \"keyword\" && index.keyword === \"number\") || /^\\d+$/.test(key ?? \"\");\n}\n\nfunction isObjectBuiltIn(key: string): boolean {\n return key in {};\n}\n\n/** A key of a primitive or an array: a built-in member is opaque, any other key is missing. */\nfunction builtInIndex(index: IrType): Evaluation {\n const key = indexKey(index);\n const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;\n return isBuiltIn || key in Number.prototype ? OPAQUE : MISSING;\n}\n"],"names":["propertyKey","OPAQUE","MISSING","isNeverIntersection","NEVER","declaredFirst","intersectionType","unionType","isNullish"],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { MISSING, OPAQUE, unionType, isNullish, NEVER, intersectionType, propertyKey } from './evaluation.mjs';
|
|
2
|
+
import { isNeverIntersection, declaredFirst } from './type-rules.mjs';
|
|
3
|
+
|
|
4
|
+
function indexType(types, value, index) {
|
|
5
|
+
const owner = types.expand(value);
|
|
6
|
+
if (owner.kind !== "type") {
|
|
7
|
+
return owner;
|
|
8
|
+
}
|
|
9
|
+
if (types.membersOf(owner).length > 1) {
|
|
10
|
+
return unionIndex(types, owner, index);
|
|
11
|
+
}
|
|
12
|
+
const { type } = owner;
|
|
13
|
+
switch (type.kind) {
|
|
14
|
+
case "object":
|
|
15
|
+
return memberType(types, owner, type.members, index);
|
|
16
|
+
case "intersection":
|
|
17
|
+
return partsIndex(types, owner, type.types, index);
|
|
18
|
+
case "union":
|
|
19
|
+
return unionIndex(types, owner, index);
|
|
20
|
+
case "array":
|
|
21
|
+
return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);
|
|
22
|
+
case "keyword":
|
|
23
|
+
return type.keyword === "never" ? owner : builtInIndex(index);
|
|
24
|
+
default:
|
|
25
|
+
return builtInIndex(index);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function memberType(types, owner, members, index) {
|
|
29
|
+
const key = indexKey(index);
|
|
30
|
+
const property = members.find(
|
|
31
|
+
(member) => member.kind === "property" && key !== null && propertyKey(member.name) === key
|
|
32
|
+
);
|
|
33
|
+
if (property !== void 0) {
|
|
34
|
+
return flattened(types, owner, property.type);
|
|
35
|
+
}
|
|
36
|
+
const signature = members.find((member) => member.kind === "indexSignature");
|
|
37
|
+
if (signature !== void 0) {
|
|
38
|
+
return flattened(types, owner, signature.type);
|
|
39
|
+
}
|
|
40
|
+
return key === null || isObjectBuiltIn(key) ? OPAQUE : MISSING;
|
|
41
|
+
}
|
|
42
|
+
function partsIndex(types, owner, parts, index) {
|
|
43
|
+
if (isNeverIntersection(types, owner, parts)) {
|
|
44
|
+
return { ...owner, type: NEVER };
|
|
45
|
+
}
|
|
46
|
+
const found = parts.map((type) => types.index({ ...owner, type }, index));
|
|
47
|
+
if (found.some((part) => part.kind === "opaque")) {
|
|
48
|
+
return OPAQUE;
|
|
49
|
+
}
|
|
50
|
+
const read = parts.map((type, at) => ({ type, found: found[at] }));
|
|
51
|
+
const kept = declaredFirst(types, owner, indexKey(index), read).flatMap(
|
|
52
|
+
(part) => part.kind === "type" ? [part.type] : []
|
|
53
|
+
);
|
|
54
|
+
return kept.length === 0 ? MISSING : { ...owner, type: intersectionType(kept) };
|
|
55
|
+
}
|
|
56
|
+
function unionIndex(types, owner, index) {
|
|
57
|
+
const found = types.membersOf(owner).map((member) => member.kind === "type" ? types.index(member, index) : member);
|
|
58
|
+
if (found.some((member) => member.kind === "missing")) {
|
|
59
|
+
return MISSING;
|
|
60
|
+
}
|
|
61
|
+
if (found.some((member) => member.kind === "opaque")) {
|
|
62
|
+
return OPAQUE;
|
|
63
|
+
}
|
|
64
|
+
return { ...owner, type: unionType(found.map((member) => member.type)) };
|
|
65
|
+
}
|
|
66
|
+
function flattened(types, owner, type) {
|
|
67
|
+
const member = { ...owner, type };
|
|
68
|
+
if (!owner.deep) {
|
|
69
|
+
return types.expand(member);
|
|
70
|
+
}
|
|
71
|
+
const members = types.membersOf(member);
|
|
72
|
+
if (members.some((candidate) => candidate.kind !== "type")) {
|
|
73
|
+
return OPAQUE;
|
|
74
|
+
}
|
|
75
|
+
const present = members.filter((candidate) => !isNullish(candidate.type));
|
|
76
|
+
const elements = present.map((candidate) => arrayElement(candidate.type));
|
|
77
|
+
if (present.length > 0 && elements.every((element) => element !== null)) {
|
|
78
|
+
return types.expand({ ...owner, type: unionType(elements) });
|
|
79
|
+
}
|
|
80
|
+
return { ...owner, type: unionType(present.map((candidate) => candidate.type)) };
|
|
81
|
+
}
|
|
82
|
+
function arrayElement(type) {
|
|
83
|
+
return type.kind === "array" ? type.element : null;
|
|
84
|
+
}
|
|
85
|
+
function indexKey(index) {
|
|
86
|
+
if (index.kind === "stringLiteral") {
|
|
87
|
+
return index.value;
|
|
88
|
+
}
|
|
89
|
+
return index.kind === "numberLiteral" ? String(index.value) : null;
|
|
90
|
+
}
|
|
91
|
+
function isNumberIndex(index) {
|
|
92
|
+
const key = indexKey(index);
|
|
93
|
+
return index.kind === "keyword" && index.keyword === "number" || /^\d+$/.test(key ?? "");
|
|
94
|
+
}
|
|
95
|
+
function isObjectBuiltIn(key) {
|
|
96
|
+
return key in {};
|
|
97
|
+
}
|
|
98
|
+
function builtInIndex(index) {
|
|
99
|
+
const key = indexKey(index);
|
|
100
|
+
const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;
|
|
101
|
+
return isBuiltIn || key in Number.prototype ? OPAQUE : MISSING;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export { indexType };
|
|
105
|
+
//# sourceMappingURL=type-indexing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-indexing.mjs","sources":["../../../../src/application/transform/footer/type-indexing.ts"],"sourcesContent":["import type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport {\n type Evaluated,\n type Evaluation,\n intersectionType,\n isNullish,\n MISSING,\n NEVER,\n OPAQUE,\n propertyKey,\n unionType,\n} from \"./evaluation.js\";\nimport { declaredFirst, isNeverIntersection, type TypeExpansion } from \"./type-rules.js\";\n\n/**\n * Indexed access (`T[\"key\"]`, `T[number]`) on the generated types, as TypeScript reads it, for\n * the evaluator of the `--enum-values` check (ADR-027).\n */\n\n/** The part of the evaluator that indexed access uses. */\nexport interface IndexedTypes extends TypeExpansion {\n expand(value: Evaluated): Evaluation;\n index(value: Evaluated, index: IrType): Evaluation;\n}\n\n/** `value[index]` for a string literal, `string` or `number` index. */\nexport function indexType(types: IndexedTypes, value: Evaluated, index: IrType): Evaluation {\n const owner = types.expand(value);\n if (owner.kind !== \"type\") {\n return owner;\n }\n if (types.membersOf(owner).length > 1) {\n return unionIndex(types, owner, index);\n }\n const { type } = owner;\n switch (type.kind) {\n case \"object\":\n return memberType(types, owner, type.members, index);\n case \"intersection\":\n return partsIndex(types, owner, type.types, index);\n case \"union\":\n return unionIndex(types, owner, index);\n case \"array\":\n return isNumberIndex(index) ? flattened(types, owner, type.element) : builtInIndex(index);\n case \"keyword\":\n return type.keyword === \"never\" ? owner : builtInIndex(index);\n default:\n return builtInIndex(index);\n }\n}\n\nfunction memberType(\n types: IndexedTypes,\n owner: Evaluated,\n members: readonly IrMember[],\n index: IrType,\n): Evaluation {\n const key = indexKey(index);\n const property = members.find(\n (member) => member.kind === \"property\" && key !== null && propertyKey(member.name) === key,\n );\n if (property !== undefined) {\n return flattened(types, owner, property.type);\n }\n const signature = members.find((member) => member.kind === \"indexSignature\");\n if (signature !== undefined) {\n return flattened(types, owner, signature.type);\n }\n return key === null || isObjectBuiltIn(key) ? OPAQUE : MISSING;\n}\n\nfunction partsIndex(\n types: IndexedTypes,\n owner: Evaluated,\n parts: readonly IrType[],\n index: IrType,\n): Evaluation {\n if (isNeverIntersection(types, owner, parts)) {\n return { ...owner, type: NEVER };\n }\n const found = parts.map((type) => types.index({ ...owner, type }, index));\n if (found.some((part) => part.kind === \"opaque\")) {\n return OPAQUE;\n }\n const read = parts.map((type, at) => ({ type, found: found[at] as Evaluation }));\n const kept = declaredFirst(types, owner, indexKey(index), read).flatMap((part) =>\n part.kind === \"type\" ? [part.type] : [],\n );\n return kept.length === 0 ? MISSING : { ...owner, type: intersectionType(kept) };\n}\n\nfunction unionIndex(types: IndexedTypes, owner: Evaluated, index: IrType): Evaluation {\n const found = types\n .membersOf(owner)\n .map((member) => (member.kind === \"type\" ? types.index(member, index) : member));\n if (found.some((member) => member.kind === \"missing\")) {\n return MISSING;\n }\n if (found.some((member) => member.kind === \"opaque\")) {\n return OPAQUE;\n }\n return { ...owner, type: unionType((found as Evaluated[]).map((member) => member.type)) };\n}\n\n/**\n * A member read through `FlattenedDeepRequired`: a value that is only arrays (and `undefined` or\n * `null`) is replaced by its elements, anything else loses `undefined` and `null`.\n */\nfunction flattened(types: IndexedTypes, owner: Evaluated, type: IrType): Evaluation {\n const member: Evaluated = { ...owner, type };\n if (!owner.deep) {\n return types.expand(member);\n }\n const members = types.membersOf(member);\n if (members.some((candidate) => candidate.kind !== \"type\")) {\n return OPAQUE;\n }\n const present = (members as Evaluated[]).filter((candidate) => !isNullish(candidate.type));\n const elements = present.map((candidate) => arrayElement(candidate.type));\n if (present.length > 0 && elements.every((element) => element !== null)) {\n return types.expand({ ...owner, type: unionType(elements as IrType[]) });\n }\n return { ...owner, type: unionType(present.map((candidate) => candidate.type)) };\n}\n\n/** The element of an expanded member; expanding already dropped `readonly`. */\nfunction arrayElement(type: IrType): IrType | null {\n return type.kind === \"array\" ? type.element : null;\n}\n\nfunction indexKey(index: IrType): string | null {\n if (index.kind === \"stringLiteral\") {\n return index.value;\n }\n return index.kind === \"numberLiteral\" ? String(index.value) : null;\n}\n\nfunction isNumberIndex(index: IrType): boolean {\n const key = indexKey(index);\n return (index.kind === \"keyword\" && index.keyword === \"number\") || /^\\d+$/.test(key ?? \"\");\n}\n\nfunction isObjectBuiltIn(key: string): boolean {\n return key in {};\n}\n\n/** A key of a primitive or an array: a built-in member is opaque, any other key is missing. */\nfunction builtInIndex(index: IrType): Evaluation {\n const key = indexKey(index);\n const isBuiltIn = key === null || key in String.prototype || key in Array.prototype;\n return isBuiltIn || key in Number.prototype ? OPAQUE : MISSING;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -39,7 +39,7 @@ function correctedType(ref, pointer, request, seen) {
|
|
|
39
39
|
}
|
|
40
40
|
function isCorrected(pointer, request) {
|
|
41
41
|
const { options, refs } = request.context;
|
|
42
|
-
return options.fixes.has(outputFixes.
|
|
42
|
+
return options.fixes.has(outputFixes.FIX.REF_POINTERS) || originalIndex.originalIndexFails({ pointer, options, refs });
|
|
43
43
|
}
|
|
44
44
|
function schemaRefType(ref, request, seen = []) {
|
|
45
45
|
const pointer = pointerOf(ref);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer-type.cjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"pointer-type.cjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":["refPointerOf","InvalidRefError","pointerNode","isJsonObject","hasInlineCycle","generatedLocationOf","typedWalk","FIX","originalIndexFails","leadingSegmentsOf","refType","irReference"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { irReference } from '../../../domain/ir/constructors.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { FIX } from '../../../domain/output-fixes.mjs';
|
|
3
3
|
import { refType, InvalidRefError } from '../ref-type.mjs';
|
|
4
4
|
import { generatedLocationOf } from './generated-location.mjs';
|
|
5
5
|
import { isJsonObject } from './generated-shape.mjs';
|
|
@@ -37,7 +37,7 @@ function correctedType(ref, pointer, request, seen) {
|
|
|
37
37
|
}
|
|
38
38
|
function isCorrected(pointer, request) {
|
|
39
39
|
const { options, refs } = request.context;
|
|
40
|
-
return options.fixes.has(
|
|
40
|
+
return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });
|
|
41
41
|
}
|
|
42
42
|
function schemaRefType(ref, request, seen = []) {
|
|
43
43
|
const pointer = pointerOf(ref);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer-type.mjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"pointer-type.mjs","sources":["../../../../src/application/transform/ref-pointer/pointer-type.ts"],"sourcesContent":["import { irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrType } from \"../../../domain/ir/nodes.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { InvalidRefError, refType } from \"../ref-type.js\";\nimport type { SchemaRequest } from \"../schema/schema-rule.js\";\nimport { generatedLocationOf } from \"./generated-location.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { hasInlineCycle } from \"./inline-cycles.js\";\nimport { originalIndexFails } from \"./original-index.js\";\nimport { leadingSegmentsOf, pointerNode, type RefPointer, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * The type of a schema `$ref` (ADR-026). The original indexed every segment of the pointer by\n * name (`refType`), also schema keywords the generated types do not have (`[\"schema\"]`,\n * `[\"items\"]`, `[\"allOf\"][\"0\"]`), and did not look through optional or nullable values. Where that\n * type does not compile, the `$ref` now gets the type of what it points at; where it compiles\n * (through an index signature), it stays, and the `ref-pointers` fix gives the right type there.\n */\n\nfunction pointerOf(ref: string): RefPointer {\n const pointer = refPointerOf(ref);\n if (pointer === null) {\n throw new InvalidRefError(ref);\n }\n return pointer;\n}\n\n/** The target of a pointer that crosses a segment with no type: its `$ref`, or its own type. */\nfunction targetType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const target = pointerNode(pointer, request.context.refs);\n if (isJsonObject(target) && typeof target.$ref === \"string\") {\n return seen.includes(target.$ref) ? null : schemaRefType(target.$ref, request, [...seen, ref]);\n }\n if (target === undefined || hasInlineCycle(ref, request.context.options, request.context.refs)) {\n return null;\n }\n // Typed where the generator types the node, so it shares the node's enum (`--enum`).\n const location = generatedLocationOf(ref, request.context.refs);\n return request.transformNested(\n target as never,\n { path: location.path, schema: target },\n location.isFromAdditionalProperties,\n );\n}\n\nfunction correctedType(\n ref: string,\n pointer: RefPointer,\n request: SchemaRequest,\n seen: readonly string[],\n) {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer, options, refs });\n return result.kind === \"typed\" ? result.walk.type : targetType(ref, pointer, request, seen);\n}\n\nfunction isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {\n const { options, refs } = request.context;\n return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });\n}\n\n/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */\nexport function schemaRefType(\n ref: string,\n request: SchemaRequest,\n seen: readonly string[] = [],\n): IrType {\n const pointer = pointerOf(ref);\n if (pointer.segments.length <= leadingSegmentsOf(pointer) || !isCorrected(pointer, request)) {\n return refType(ref);\n }\n return correctedType(ref, pointer, request, seen) ?? refType(ref);\n}\n\n/**\n * The type of a `$ref` that `WithRequired` takes. A `$ref` to an optional or nullable value has\n * no keys (`keyof (T | undefined)` is `never`), so it is wrapped in `NonNullable` (TS2344).\n */\nexport function requirableRefType(ref: string, type: IrType, request: SchemaRequest): IrType {\n const { options, refs } = request.context;\n const result = typedWalk({ pointer: pointerOf(ref), options, refs });\n const isAbsent = result.kind === \"typed\" && result.walk.presence === \"absent\";\n return isAbsent ? irReference(\"NonNullable\", [type]) : type;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@ function propertyAccessFlags(value, context) {
|
|
|
28
28
|
if (typeof value !== "object") {
|
|
29
29
|
return NO_FLAGS;
|
|
30
30
|
}
|
|
31
|
-
if (!context.options.fixes.has(outputFixes.
|
|
31
|
+
if (!context.options.fixes.has(outputFixes.FIX.READ_WRITE_REFS)) {
|
|
32
32
|
return ownFlags(value);
|
|
33
33
|
}
|
|
34
34
|
return appliedFlags(value, context, /* @__PURE__ */ new Set());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-flags.cjs","sources":["../../../../src/application/transform/schema/access-flags.ts"],"sourcesContent":["import type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"access-flags.cjs","sources":["../../../../src/application/transform/schema/access-flags.ts"],"sourcesContent":["import type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport type { SchemaContext } from \"./schema-context.js\";\n\n/** Whether a property is `readOnly` or `writeOnly` (JSON Schema 2020-12 Validation §9.4). */\nexport interface AccessFlags {\n readonly isReadOnly: boolean;\n readonly isWriteOnly: boolean;\n}\n\nconst NO_FLAGS: AccessFlags = { isReadOnly: false, isWriteOnly: false };\n\nfunction ownFlags(schema: SchemaObject): AccessFlags {\n return { isReadOnly: Boolean(schema.readOnly), isWriteOnly: Boolean(schema.writeOnly) };\n}\n\nfunction merged(left: AccessFlags, right: AccessFlags): AccessFlags {\n return {\n isReadOnly: left.isReadOnly || right.isReadOnly,\n isWriteOnly: left.isWriteOnly || right.isWriteOnly,\n };\n}\n\n/**\n * The flags of a schema and of the schemas that always apply to the same value: the one its\n * `$ref` names and its `allOf` members, followed until a schema repeats. `readOnly` is an\n * annotation, and the annotations of those schemas are the value's (2020-12 Core §7.7.1); in\n * OpenAPI 3.0 a referenced schema is the property's definition. `anyOf` and `oneOf` members apply\n * only when they match, which the type cannot tell, so they are not read.\n */\nfunction appliedFlags(\n schema: Schema | undefined,\n context: SchemaContext,\n seen: ReadonlySet<Schema>,\n): AccessFlags {\n if (typeof schema !== \"object\" || schema === null || seen.has(schema)) {\n return NO_FLAGS;\n }\n const inner = new Set([...seen, schema]);\n // `readOnly` next to a `$ref` is read too, as the generator always has.\n const object = schema as SchemaObject & { readonly $ref?: unknown };\n const target =\n typeof object.$ref === \"string\" ? (context.refs.resolve(object.$ref) as Schema) : undefined;\n return (object.allOf ?? []).reduce<AccessFlags>(\n (flags, member) => merged(flags, appliedFlags(member, context, inner)),\n merged(ownFlags(object), appliedFlags(target, context, inner)),\n );\n}\n\n/**\n * The flags of a property schema. Without the `read-write-refs` fix only the keywords written on\n * it count, as in openapi-typescript; with it, also those of the schemas its `$ref` and `allOf`\n * apply (upstream #1938).\n */\nexport function propertyAccessFlags(value: Schema, context: SchemaContext): AccessFlags {\n if (typeof value !== \"object\") {\n return NO_FLAGS;\n }\n if (!context.options.fixes.has(FIX.READ_WRITE_REFS)) {\n return ownFlags(value as SchemaObject);\n }\n return appliedFlags(value, context, new Set());\n}\n"],"names":["FIX"],"mappings":";;;;AAUA,MAAM,QAAA,GAAwB,EAAE,UAAA,EAAY,KAAA,EAAO,aAAa,KAAA,EAAM;AAEtE,SAAS,SAAS,MAAA,EAAmC;AACnD,EAAA,OAAO,EAAE,UAAA,EAAY,OAAA,CAAQ,MAAA,CAAO,QAAQ,GAAG,WAAA,EAAa,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAE;AACxF;AAEA,SAAS,MAAA,CAAO,MAAmB,KAAA,EAAiC;AAClE,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,IAAA,CAAK,UAAA,IAAc,KAAA,CAAM,UAAA;AAAA,IACrC,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,KAAA,CAAM;AAAA,GACzC;AACF;AASA,SAAS,YAAA,CACP,MAAA,EACA,OAAA,EACA,IAAA,EACa;AACb,EAAA,IAAI,OAAO,WAAW,QAAA,IAAY,MAAA,KAAW,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,EAAG;AACrE,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,wBAAQ,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,EAAM,MAAM,CAAC,CAAA;AAEvC,EAAA,MAAM,MAAA,GAAS,MAAA;AACf,EAAA,MAAM,MAAA,GACJ,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAY,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,GAAe,MAAA;AACpF,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,IAAS,EAAC,EAAG,MAAA;AAAA,IAC1B,CAAC,OAAO,MAAA,KAAW,MAAA,CAAO,OAAO,YAAA,CAAa,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC,CAAA;AAAA,IACrE,MAAA,CAAO,SAAS,MAAM,CAAA,EAAG,aAAa,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC;AAAA,GAC/D;AACF;AAOO,SAAS,mBAAA,CAAoB,OAAe,OAAA,EAAqC;AACtF,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,CAAQ,MAAM,GAAA,CAAIA,eAAA,CAAI,eAAe,CAAA,EAAG;AACnD,IAAA,OAAO,SAAS,KAAqB,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,YAAA,CAAa,KAAA,EAAO,OAAA,kBAAS,IAAI,KAAK,CAAA;AAC/C;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FIX } from '../../../domain/output-fixes.mjs';
|
|
2
2
|
|
|
3
3
|
const NO_FLAGS = { isReadOnly: false, isWriteOnly: false };
|
|
4
4
|
function ownFlags(schema) {
|
|
@@ -26,7 +26,7 @@ function propertyAccessFlags(value, context) {
|
|
|
26
26
|
if (typeof value !== "object") {
|
|
27
27
|
return NO_FLAGS;
|
|
28
28
|
}
|
|
29
|
-
if (!context.options.fixes.has(
|
|
29
|
+
if (!context.options.fixes.has(FIX.READ_WRITE_REFS)) {
|
|
30
30
|
return ownFlags(value);
|
|
31
31
|
}
|
|
32
32
|
return appliedFlags(value, context, /* @__PURE__ */ new Set());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-flags.mjs","sources":["../../../../src/application/transform/schema/access-flags.ts"],"sourcesContent":["import type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"access-flags.mjs","sources":["../../../../src/application/transform/schema/access-flags.ts"],"sourcesContent":["import type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport type { SchemaContext } from \"./schema-context.js\";\n\n/** Whether a property is `readOnly` or `writeOnly` (JSON Schema 2020-12 Validation §9.4). */\nexport interface AccessFlags {\n readonly isReadOnly: boolean;\n readonly isWriteOnly: boolean;\n}\n\nconst NO_FLAGS: AccessFlags = { isReadOnly: false, isWriteOnly: false };\n\nfunction ownFlags(schema: SchemaObject): AccessFlags {\n return { isReadOnly: Boolean(schema.readOnly), isWriteOnly: Boolean(schema.writeOnly) };\n}\n\nfunction merged(left: AccessFlags, right: AccessFlags): AccessFlags {\n return {\n isReadOnly: left.isReadOnly || right.isReadOnly,\n isWriteOnly: left.isWriteOnly || right.isWriteOnly,\n };\n}\n\n/**\n * The flags of a schema and of the schemas that always apply to the same value: the one its\n * `$ref` names and its `allOf` members, followed until a schema repeats. `readOnly` is an\n * annotation, and the annotations of those schemas are the value's (2020-12 Core §7.7.1); in\n * OpenAPI 3.0 a referenced schema is the property's definition. `anyOf` and `oneOf` members apply\n * only when they match, which the type cannot tell, so they are not read.\n */\nfunction appliedFlags(\n schema: Schema | undefined,\n context: SchemaContext,\n seen: ReadonlySet<Schema>,\n): AccessFlags {\n if (typeof schema !== \"object\" || schema === null || seen.has(schema)) {\n return NO_FLAGS;\n }\n const inner = new Set([...seen, schema]);\n // `readOnly` next to a `$ref` is read too, as the generator always has.\n const object = schema as SchemaObject & { readonly $ref?: unknown };\n const target =\n typeof object.$ref === \"string\" ? (context.refs.resolve(object.$ref) as Schema) : undefined;\n return (object.allOf ?? []).reduce<AccessFlags>(\n (flags, member) => merged(flags, appliedFlags(member, context, inner)),\n merged(ownFlags(object), appliedFlags(target, context, inner)),\n );\n}\n\n/**\n * The flags of a property schema. Without the `read-write-refs` fix only the keywords written on\n * it count, as in openapi-typescript; with it, also those of the schemas its `$ref` and `allOf`\n * apply (upstream #1938).\n */\nexport function propertyAccessFlags(value: Schema, context: SchemaContext): AccessFlags {\n if (typeof value !== \"object\") {\n return NO_FLAGS;\n }\n if (!context.options.fixes.has(FIX.READ_WRITE_REFS)) {\n return ownFlags(value as SchemaObject);\n }\n return appliedFlags(value, context, new Set());\n}\n"],"names":[],"mappings":";;AAUA,MAAM,QAAA,GAAwB,EAAE,UAAA,EAAY,KAAA,EAAO,aAAa,KAAA,EAAM;AAEtE,SAAS,SAAS,MAAA,EAAmC;AACnD,EAAA,OAAO,EAAE,UAAA,EAAY,OAAA,CAAQ,MAAA,CAAO,QAAQ,GAAG,WAAA,EAAa,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,EAAE;AACxF;AAEA,SAAS,MAAA,CAAO,MAAmB,KAAA,EAAiC;AAClE,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,IAAA,CAAK,UAAA,IAAc,KAAA,CAAM,UAAA;AAAA,IACrC,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,KAAA,CAAM;AAAA,GACzC;AACF;AASA,SAAS,YAAA,CACP,MAAA,EACA,OAAA,EACA,IAAA,EACa;AACb,EAAA,IAAI,OAAO,WAAW,QAAA,IAAY,MAAA,KAAW,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,EAAG;AACrE,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,wBAAQ,IAAI,GAAA,CAAI,CAAC,GAAG,IAAA,EAAM,MAAM,CAAC,CAAA;AAEvC,EAAA,MAAM,MAAA,GAAS,MAAA;AACf,EAAA,MAAM,MAAA,GACJ,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAY,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,GAAe,MAAA;AACpF,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,IAAS,EAAC,EAAG,MAAA;AAAA,IAC1B,CAAC,OAAO,MAAA,KAAW,MAAA,CAAO,OAAO,YAAA,CAAa,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC,CAAA;AAAA,IACrE,MAAA,CAAO,SAAS,MAAM,CAAA,EAAG,aAAa,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC;AAAA,GAC/D;AACF;AAOO,SAAS,mBAAA,CAAoB,OAAe,OAAA,EAAqC;AACtF,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,CAAQ,MAAM,GAAA,CAAI,GAAA,CAAI,eAAe,CAAA,EAAG;AACnD,IAAA,OAAO,SAAS,KAAqB,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,YAAA,CAAa,KAAA,EAAO,OAAA,kBAAS,IAAI,KAAK,CAAA;AAC/C;;"}
|
|
@@ -45,7 +45,7 @@ function prefixItemsTupleType(prefixItems, schema, request) {
|
|
|
45
45
|
return constructors.irTuple(rest === null ? elements : [...elements, constructors.irTupleElement(constructors.irArray(rest), true)]);
|
|
46
46
|
}
|
|
47
47
|
function isPrefixItemsFixed(schema, request) {
|
|
48
|
-
return schema.prefixItems !== void 0 && request.context.options.fixes.has(outputFixes.
|
|
48
|
+
return schema.prefixItems !== void 0 && request.context.options.fixes.has(outputFixes.FIX.PREFIX_ITEMS);
|
|
49
49
|
}
|
|
50
50
|
function singleItemType(schema, request) {
|
|
51
51
|
const { items } = schema;
|
|
@@ -117,7 +117,7 @@ function fixedArrayType(schema, request) {
|
|
|
117
117
|
}
|
|
118
118
|
function isArrayLengthFixed(request) {
|
|
119
119
|
const { arrayLength, fixes } = request.context.options;
|
|
120
|
-
return arrayLength && fixes.has(outputFixes.
|
|
120
|
+
return arrayLength && fixes.has(outputFixes.FIX.ARRAY_LENGTH_TUPLES);
|
|
121
121
|
}
|
|
122
122
|
function arrayType(schema, request) {
|
|
123
123
|
if (isArrayLengthFixed(request)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"array-type.cjs","sources":["../../../../src/application/transform/schema/array-type.ts"],"sourcesContent":["import {\n irArray,\n irOptionalTupleElement,\n irReadonly,\n irTuple,\n irTupleElement,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrTupleElement, IrType } from \"../../../domain/ir/nodes.js\";\nimport type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { UNKNOWN_TYPE } from \"../shared-types.js\";\nimport { unionOf } from \"../type-combinators.js\";\nimport type { SchemaRequest } from \"./schema-rule.js\";\n\n/**\n * `--array-length` writes tuples only while the estimated number of tuple elements stays below\n * this; the original chose it as roughly where TypeScript starts to struggle with tuple inference.\n */\nconst MAX_LENGTH_TUPLE_ELEMENTS = 30;\n\n/**\n * The tuple of `prefixItems` (or of an `items` list); null without either. The original closes a\n * `prefixItems` tuple and requires every element; the `prefix-items` fix does not.\n */\nfunction prefixTupleType(schema: SchemaObject, request: SchemaRequest): IrType | null {\n const { items } = schema;\n if (schema.prefixItems && isPrefixItemsFixed(schema, request)) {\n return prefixItemsTupleType(schema.prefixItems, schema, request);\n }\n if (!schema.prefixItems && !Array.isArray(items)) {\n return null;\n }\n const prefixItems = schema.prefixItems ?? (items as SchemaObject[]);\n return irTuple(\n prefixItems.map((item) => irTupleElement(request.transformNested(item, request.location))),\n );\n}\n\n/** The type of the items after the prefix, or null when there may be none (`false`). */\nfunction restItemType(schema: Schema, request: SchemaRequest): IrType | null {\n return schema === false ? null : request.transformNested(schema, request.location);\n}\n\n/**\n * The type of the items after a `prefixItems` tuple (JSON Schema 2020-12 §10.3.1): `items`, else\n * `unevaluatedItems`, which does not apply to the items `contains` matches, else any item. Null\n * when no item may follow. An `items` list is not a schema in 2020-12, so it allows any item.\n */\nfunction prefixRestType(schema: SchemaObject, request: SchemaRequest): IrType | null {\n const { items, unevaluatedItems, contains } = schema;\n if (items !== undefined && !Array.isArray(items)) {\n return restItemType(items as Schema, request);\n }\n if (unevaluatedItems === undefined || items !== undefined) {\n return UNKNOWN_TYPE;\n }\n const unevaluated = restItemType(unevaluatedItems, request);\n const matched = contains === undefined ? null : restItemType(contains, request);\n const types = [unevaluated, matched].filter((type): type is IrType => type !== null);\n return types.length === 0 ? null : unionOf(types);\n}\n\n/**\n * The `prefix-items` tuple of `prefixItems`: an array may end before the prefix does, so the\n * elements from `minItems` on are optional (`T?`), and a rest element types the items after it.\n */\nfunction prefixItemsTupleType(\n prefixItems: readonly Schema[],\n schema: SchemaObject,\n request: SchemaRequest,\n): IrType {\n const { min } = lengthBounds(schema);\n const elements = prefixItems.map((item, index): IrTupleElement => {\n const type = request.transformNested(item, request.location);\n return index < min ? irTupleElement(type) : irOptionalTupleElement(type);\n });\n const rest = prefixRestType(schema, request);\n return irTuple(rest === null ? elements : [...elements, irTupleElement(irArray(rest), true)]);\n}\n\nfunction isPrefixItemsFixed(schema: SchemaObject, request: SchemaRequest): boolean {\n return (\n schema.prefixItems !== undefined && request.context.options.fixes.has(OutputFix.PREFIX_ITEMS)\n );\n}\n\n/** The type of one item; `unknown` without `items`. */\nfunction singleItemType(schema: SchemaObject, request: SchemaRequest): IrType {\n const { items } = schema;\n return items ? request.transformNested(items as SchemaObject, request.location) : UNKNOWN_TYPE;\n}\n\n/**\n * The item type as the original returns it: a tuple stands for the whole array, and a nested\n * `type: array` item is wrapped in an array here already.\n */\nfunction itemType(schema: SchemaObject, request: SchemaRequest): IrType {\n const tuple = prefixTupleType(schema, request);\n if (tuple !== null) {\n return tuple;\n }\n const { items } = schema;\n // Checked first: the `in` test below throws for `items: null`.\n if (!items) {\n return UNKNOWN_TYPE;\n }\n const nested = singleItemType(schema, request);\n const isNestedArray = typeof items === \"object\" && \"type\" in items && items.type === \"array\";\n return isNestedArray ? irArray(nested) : nested;\n}\n\nfunction repeat(type: IrType, count: number): IrType[] {\n return Array.from({ length: count }, () => type);\n}\n\ninterface LengthBounds {\n readonly min: number;\n readonly max: number | undefined;\n}\n\nfunction lengthBounds(schema: SchemaObject): LengthBounds {\n const { minItems, maxItems } = schema;\n const min = typeof minItems === \"number\" && minItems >= 0 ? minItems : 0;\n const isMaxValid = typeof maxItems === \"number\" && maxItems >= 0 && min <= maxItems;\n return { min, max: isMaxValid ? maxItems : undefined };\n}\n\n/**\n * Tuples for `--array-length`, as the original builds them. With both bounds it emits tuples of\n * length 0 to `max - min` (not `min` to `max`); the `array-length-tuples` fix corrects it.\n */\nfunction lengthTupleType(schema: SchemaObject, item: IrType, bounds: LengthBounds): IrType {\n const { min, max } = bounds;\n if (min === max) {\n return unionOf([irTuple(repeat(item, min).map((type) => irTupleElement(type)))]);\n }\n if ((schema.maxItems as number) > 0) {\n const lengths = Array.from({ length: Math.max(0, (max ?? 0) - min + 1) }, (_, index) => index);\n return unionOf(\n lengths.map((length) => irTuple(repeat(item, length).map((type) => irTupleElement(type)))),\n );\n }\n const elements = repeat(item, min).map((type) => irTupleElement(type));\n return irTuple([...elements, irTupleElement(irArray(item), true)]);\n}\n\nfunction isLengthTupleWanted(bounds: LengthBounds, request: SchemaRequest): boolean {\n const { min, max } = bounds;\n const estimatedSize = max === undefined ? min : (max * (max + 1) - min * (min - 1)) / 2;\n const hasBounds = min !== 0 || max !== undefined;\n return (\n request.context.options.arrayLength && hasBounds && estimatedSize < MAX_LENGTH_TUPLE_ELEMENTS\n );\n}\n\n/** Applies `--immutable` to one array or tuple type. */\ntype ArrayWrapper = (type: IrType) => IrType;\n\nfunction tupleOf(item: IrType, length: number, isOpen: boolean): IrType {\n const elements = repeat(item, length).map((type) => irTupleElement(type));\n return irTuple(isOpen ? [...elements, irTupleElement(irArray(item), true)] : elements);\n}\n\n/** Tuples of every length from `min` to `max`; without `max`, `min` items and a rest element. */\nfunction fixedLengthTupleType(item: IrType, bounds: LengthBounds, wrap: ArrayWrapper): IrType {\n const { min, max } = bounds;\n if (max === undefined) {\n return wrap(tupleOf(item, min, true));\n }\n const lengths = Array.from({ length: max - min + 1 }, (_, index) => min + index);\n return unionOf(lengths.map((length) => wrap(tupleOf(item, length, false))));\n}\n\n/**\n * `type: array` with `--array-length` and the `array-length-tuples` fix (#2048, #2330, #2546):\n * the tuples have `min` to `max` items, the item type is used as it is (a nested array stays one\n * level deep), a `prefixItems` tuple gets no length tuples around it, and `--immutable` makes\n * every tuple `readonly`.\n */\nfunction fixedArrayType(schema: SchemaObject, request: SchemaRequest): IrType {\n const wrap: ArrayWrapper = (type) =>\n request.context.options.immutable ? irReadonly(type) : type;\n const tuple = prefixTupleType(schema, request);\n if (tuple !== null) {\n return wrap(tuple);\n }\n const item = singleItemType(schema, request);\n const bounds = lengthBounds(schema);\n return isLengthTupleWanted(bounds, request)\n ? fixedLengthTupleType(item, bounds, wrap)\n : wrap(irArray(item));\n}\n\nfunction isArrayLengthFixed(request: SchemaRequest): boolean {\n const { arrayLength, fixes } = request.context.options;\n return arrayLength && fixes.has(OutputFix.ARRAY_LENGTH_TUPLES);\n}\n\n/** `type: array`, including tuples (`prefixItems`, array `items`) and `--array-length`. */\nexport function arrayType(schema: SchemaObject, request: SchemaRequest): IrType {\n if (isArrayLengthFixed(request)) {\n return fixedArrayType(schema, request);\n }\n const item = itemType(schema, request);\n const bounds = lengthBounds(schema);\n // A `prefix-items` tuple has its own lengths, so `--array-length` adds no tuples around it.\n if (!isPrefixItemsFixed(schema, request) && isLengthTupleWanted(bounds, request)) {\n return lengthTupleType(schema, item, bounds);\n }\n // A tuple or an array item is used as the array type itself.\n const type = item.kind === \"tuple\" || item.kind === \"array\" ? item : irArray(item);\n return request.context.options.immutable ? irReadonly(type) : type;\n}\n"],"names":["irTuple","irTupleElement","UNKNOWN_TYPE","unionOf","irOptionalTupleElement","irArray","OutputFix","irReadonly"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"array-type.cjs","sources":["../../../../src/application/transform/schema/array-type.ts"],"sourcesContent":["import {\n irArray,\n irOptionalTupleElement,\n irReadonly,\n irTuple,\n irTupleElement,\n} from \"../../../domain/ir/constructors.js\";\nimport type { IrTupleElement, IrType } from \"../../../domain/ir/nodes.js\";\nimport type { Schema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { FIX } from \"../../../domain/output-fixes.js\";\nimport { UNKNOWN_TYPE } from \"../shared-types.js\";\nimport { unionOf } from \"../type-combinators.js\";\nimport type { SchemaRequest } from \"./schema-rule.js\";\n\n/**\n * `--array-length` writes tuples only while the estimated number of tuple elements stays below\n * this; the original chose it as roughly where TypeScript starts to struggle with tuple inference.\n */\nconst MAX_LENGTH_TUPLE_ELEMENTS = 30;\n\n/**\n * The tuple of `prefixItems` (or of an `items` list); null without either. The original closes a\n * `prefixItems` tuple and requires every element; the `prefix-items` fix does not.\n */\nfunction prefixTupleType(schema: SchemaObject, request: SchemaRequest): IrType | null {\n const { items } = schema;\n if (schema.prefixItems && isPrefixItemsFixed(schema, request)) {\n return prefixItemsTupleType(schema.prefixItems, schema, request);\n }\n if (!schema.prefixItems && !Array.isArray(items)) {\n return null;\n }\n const prefixItems = schema.prefixItems ?? (items as SchemaObject[]);\n return irTuple(\n prefixItems.map((item) => irTupleElement(request.transformNested(item, request.location))),\n );\n}\n\n/** The type of the items after the prefix, or null when there may be none (`false`). */\nfunction restItemType(schema: Schema, request: SchemaRequest): IrType | null {\n return schema === false ? null : request.transformNested(schema, request.location);\n}\n\n/**\n * The type of the items after a `prefixItems` tuple (JSON Schema 2020-12 §10.3.1): `items`, else\n * `unevaluatedItems`, which does not apply to the items `contains` matches, else any item. Null\n * when no item may follow. An `items` list is not a schema in 2020-12, so it allows any item.\n */\nfunction prefixRestType(schema: SchemaObject, request: SchemaRequest): IrType | null {\n const { items, unevaluatedItems, contains } = schema;\n if (items !== undefined && !Array.isArray(items)) {\n return restItemType(items as Schema, request);\n }\n if (unevaluatedItems === undefined || items !== undefined) {\n return UNKNOWN_TYPE;\n }\n const unevaluated = restItemType(unevaluatedItems, request);\n const matched = contains === undefined ? null : restItemType(contains, request);\n const types = [unevaluated, matched].filter((type): type is IrType => type !== null);\n return types.length === 0 ? null : unionOf(types);\n}\n\n/**\n * The `prefix-items` tuple of `prefixItems`: an array may end before the prefix does, so the\n * elements from `minItems` on are optional (`T?`), and a rest element types the items after it.\n */\nfunction prefixItemsTupleType(\n prefixItems: readonly Schema[],\n schema: SchemaObject,\n request: SchemaRequest,\n): IrType {\n const { min } = lengthBounds(schema);\n const elements = prefixItems.map((item, index): IrTupleElement => {\n const type = request.transformNested(item, request.location);\n return index < min ? irTupleElement(type) : irOptionalTupleElement(type);\n });\n const rest = prefixRestType(schema, request);\n return irTuple(rest === null ? elements : [...elements, irTupleElement(irArray(rest), true)]);\n}\n\nfunction isPrefixItemsFixed(schema: SchemaObject, request: SchemaRequest): boolean {\n return schema.prefixItems !== undefined && request.context.options.fixes.has(FIX.PREFIX_ITEMS);\n}\n\n/** The type of one item; `unknown` without `items`. */\nfunction singleItemType(schema: SchemaObject, request: SchemaRequest): IrType {\n const { items } = schema;\n return items ? request.transformNested(items as SchemaObject, request.location) : UNKNOWN_TYPE;\n}\n\n/**\n * The item type as the original returns it: a tuple stands for the whole array, and a nested\n * `type: array` item is wrapped in an array here already.\n */\nfunction itemType(schema: SchemaObject, request: SchemaRequest): IrType {\n const tuple = prefixTupleType(schema, request);\n if (tuple !== null) {\n return tuple;\n }\n const { items } = schema;\n // Checked first: the `in` test below throws for `items: null`.\n if (!items) {\n return UNKNOWN_TYPE;\n }\n const nested = singleItemType(schema, request);\n const isNestedArray = typeof items === \"object\" && \"type\" in items && items.type === \"array\";\n return isNestedArray ? irArray(nested) : nested;\n}\n\nfunction repeat(type: IrType, count: number): IrType[] {\n return Array.from({ length: count }, () => type);\n}\n\ninterface LengthBounds {\n readonly min: number;\n readonly max: number | undefined;\n}\n\nfunction lengthBounds(schema: SchemaObject): LengthBounds {\n const { minItems, maxItems } = schema;\n const min = typeof minItems === \"number\" && minItems >= 0 ? minItems : 0;\n const isMaxValid = typeof maxItems === \"number\" && maxItems >= 0 && min <= maxItems;\n return { min, max: isMaxValid ? maxItems : undefined };\n}\n\n/**\n * Tuples for `--array-length`, as the original builds them. With both bounds it emits tuples of\n * length 0 to `max - min` (not `min` to `max`); the `array-length-tuples` fix corrects it.\n */\nfunction lengthTupleType(schema: SchemaObject, item: IrType, bounds: LengthBounds): IrType {\n const { min, max } = bounds;\n if (min === max) {\n return unionOf([irTuple(repeat(item, min).map((type) => irTupleElement(type)))]);\n }\n if ((schema.maxItems as number) > 0) {\n const lengths = Array.from({ length: Math.max(0, (max ?? 0) - min + 1) }, (_, index) => index);\n return unionOf(\n lengths.map((length) => irTuple(repeat(item, length).map((type) => irTupleElement(type)))),\n );\n }\n const elements = repeat(item, min).map((type) => irTupleElement(type));\n return irTuple([...elements, irTupleElement(irArray(item), true)]);\n}\n\nfunction isLengthTupleWanted(bounds: LengthBounds, request: SchemaRequest): boolean {\n const { min, max } = bounds;\n const estimatedSize = max === undefined ? min : (max * (max + 1) - min * (min - 1)) / 2;\n const hasBounds = min !== 0 || max !== undefined;\n return (\n request.context.options.arrayLength && hasBounds && estimatedSize < MAX_LENGTH_TUPLE_ELEMENTS\n );\n}\n\n/** Applies `--immutable` to one array or tuple type. */\ntype ArrayWrapper = (type: IrType) => IrType;\n\nfunction tupleOf(item: IrType, length: number, isOpen: boolean): IrType {\n const elements = repeat(item, length).map((type) => irTupleElement(type));\n return irTuple(isOpen ? [...elements, irTupleElement(irArray(item), true)] : elements);\n}\n\n/** Tuples of every length from `min` to `max`; without `max`, `min` items and a rest element. */\nfunction fixedLengthTupleType(item: IrType, bounds: LengthBounds, wrap: ArrayWrapper): IrType {\n const { min, max } = bounds;\n if (max === undefined) {\n return wrap(tupleOf(item, min, true));\n }\n const lengths = Array.from({ length: max - min + 1 }, (_, index) => min + index);\n return unionOf(lengths.map((length) => wrap(tupleOf(item, length, false))));\n}\n\n/**\n * `type: array` with `--array-length` and the `array-length-tuples` fix (#2048, #2330, #2546):\n * the tuples have `min` to `max` items, the item type is used as it is (a nested array stays one\n * level deep), a `prefixItems` tuple gets no length tuples around it, and `--immutable` makes\n * every tuple `readonly`.\n */\nfunction fixedArrayType(schema: SchemaObject, request: SchemaRequest): IrType {\n const wrap: ArrayWrapper = (type) =>\n request.context.options.immutable ? irReadonly(type) : type;\n const tuple = prefixTupleType(schema, request);\n if (tuple !== null) {\n return wrap(tuple);\n }\n const item = singleItemType(schema, request);\n const bounds = lengthBounds(schema);\n return isLengthTupleWanted(bounds, request)\n ? fixedLengthTupleType(item, bounds, wrap)\n : wrap(irArray(item));\n}\n\nfunction isArrayLengthFixed(request: SchemaRequest): boolean {\n const { arrayLength, fixes } = request.context.options;\n return arrayLength && fixes.has(FIX.ARRAY_LENGTH_TUPLES);\n}\n\n/** `type: array`, including tuples (`prefixItems`, array `items`) and `--array-length`. */\nexport function arrayType(schema: SchemaObject, request: SchemaRequest): IrType {\n if (isArrayLengthFixed(request)) {\n return fixedArrayType(schema, request);\n }\n const item = itemType(schema, request);\n const bounds = lengthBounds(schema);\n // A `prefix-items` tuple has its own lengths, so `--array-length` adds no tuples around it.\n if (!isPrefixItemsFixed(schema, request) && isLengthTupleWanted(bounds, request)) {\n return lengthTupleType(schema, item, bounds);\n }\n // A tuple or an array item is used as the array type itself.\n const type = item.kind === \"tuple\" || item.kind === \"array\" ? item : irArray(item);\n return request.context.options.immutable ? irReadonly(type) : type;\n}\n"],"names":["irTuple","irTupleElement","UNKNOWN_TYPE","unionOf","irOptionalTupleElement","irArray","FIX","irReadonly"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { irArray, irReadonly, irTuple, irTupleElement, irOptionalTupleElement } from '../../../domain/ir/constructors.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import { FIX } from '../../../domain/output-fixes.mjs';
|
|
3
3
|
import { UNKNOWN_TYPE } from '../shared-types.mjs';
|
|
4
4
|
import { unionOf } from '../type-combinators.mjs';
|
|
5
5
|
|
|
@@ -43,7 +43,7 @@ function prefixItemsTupleType(prefixItems, schema, request) {
|
|
|
43
43
|
return irTuple(rest === null ? elements : [...elements, irTupleElement(irArray(rest), true)]);
|
|
44
44
|
}
|
|
45
45
|
function isPrefixItemsFixed(schema, request) {
|
|
46
|
-
return schema.prefixItems !== void 0 && request.context.options.fixes.has(
|
|
46
|
+
return schema.prefixItems !== void 0 && request.context.options.fixes.has(FIX.PREFIX_ITEMS);
|
|
47
47
|
}
|
|
48
48
|
function singleItemType(schema, request) {
|
|
49
49
|
const { items } = schema;
|
|
@@ -115,7 +115,7 @@ function fixedArrayType(schema, request) {
|
|
|
115
115
|
}
|
|
116
116
|
function isArrayLengthFixed(request) {
|
|
117
117
|
const { arrayLength, fixes } = request.context.options;
|
|
118
|
-
return arrayLength && fixes.has(
|
|
118
|
+
return arrayLength && fixes.has(FIX.ARRAY_LENGTH_TUPLES);
|
|
119
119
|
}
|
|
120
120
|
function arrayType(schema, request) {
|
|
121
121
|
if (isArrayLengthFixed(request)) {
|