openapi-typesafe 1.0.0-rc.2 → 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/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/api/default-ports.cjs +5 -0
- package/dist/api/default-ports.cjs.map +1 -1
- package/dist/api/default-ports.mjs +5 -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 +3 -3
- package/dist/api/discriminator-patch.cjs.map +1 -1
- package/dist/api/discriminator-patch.mjs +4 -4
- 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-run.cjs +2 -1
- package/dist/api/document-run.cjs.map +1 -1
- package/dist/api/document-run.mjs +2 -1
- package/dist/api/document-run.mjs.map +1 -1
- package/dist/api/legacy-callback-warning.cjs +7 -4
- package/dist/api/legacy-callback-warning.cjs.map +1 -1
- package/dist/api/legacy-callback-warning.mjs +8 -5
- package/dist/api/legacy-callback-warning.mjs.map +1 -1
- package/dist/api/openapi-ts.cjs +1 -1
- package/dist/api/openapi-ts.cjs.map +1 -1
- package/dist/api/openapi-ts.mjs +2 -2
- 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-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/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 +1 -1
- package/dist/application/transform/document/parameters.cjs.map +1 -1
- package/dist/application/transform/document/parameters.mjs +2 -2
- package/dist/application/transform/document/parameters.mjs.map +1 -1
- package/dist/application/transform/document/paths.cjs +1 -1
- package/dist/application/transform/document/paths.cjs.map +1 -1
- package/dist/application/transform/document/paths.mjs +2 -2
- package/dist/application/transform/document/paths.mjs.map +1 -1
- 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/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.map +1 -1
- package/dist/domain/errors.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/warnings.cjs +0 -1
- package/dist/domain/warnings.cjs.map +1 -1
- package/dist/domain/warnings.mjs +0 -1
- package/dist/domain/warnings.mjs.map +1 -1
- package/dist/index.cjs +2 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -16
- package/dist/index.d.mts +35 -16
- package/dist/index.d.ts +35 -16
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/adapters/node-deprecations/node-deprecations.ts +14 -0
- package/src/api/default-ports.ts +7 -0
- package/src/api/discriminator-conflict-warnings.ts +2 -2
- package/src/api/discriminator-patch.ts +4 -5
- package/src/api/discriminator-scan.ts +3 -3
- package/src/api/document-run.ts +5 -0
- package/src/api/legacy-callback-warning.ts +13 -6
- package/src/api/openapi-ts.ts +6 -2
- package/src/api/run-context.ts +3 -0
- package/src/api/string-to-ast.ts +11 -15
- package/src/api/transform-schema.ts +3 -3
- package/src/application/ports/deprecation-reporter.ts +9 -0
- package/src/application/transform/document/components.ts +2 -2
- package/src/application/transform/document/parameters.ts +2 -2
- package/src/application/transform/document/paths.ts +2 -2
- 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/domain/deprecations.ts +15 -0
- package/src/domain/errors.ts +8 -2
- package/src/domain/output-fixes.ts +16 -16
- package/src/domain/warnings.ts +0 -1
- package/src/index.ts +2 -6
package/src/api/string-to-ast.ts
CHANGED
|
@@ -1,27 +1,23 @@
|
|
|
1
|
-
import { deprecate } from "node:util";
|
|
2
1
|
import { parseStatements } from "../adapters/type-ast-bridge/ir-declarations-to-typescript.js";
|
|
3
2
|
import { loadTypeScript } from "../adapters/type-ast-bridge/load-typescript.js";
|
|
3
|
+
import { DEPRECATION_CODES } from "../domain/deprecations.js";
|
|
4
|
+
import { defaultDeprecationReporter } from "./default-ports.js";
|
|
4
5
|
import { IR_CALLBACKS_GUIDE_URL } from "./legacy-callback-warning.js";
|
|
5
6
|
|
|
6
7
|
const STRING_TO_AST_DEPRECATION =
|
|
7
8
|
"stringToAST() is deprecated and removed in 2.0. Return TypeScript type text from an IR " +
|
|
8
9
|
`callback (irCallbacks: true) instead: ${IR_CALLBACKS_GUIDE_URL}`;
|
|
9
10
|
|
|
10
|
-
/** Node's deprecation code for `stringToAST`, so users can filter or trace the warning. */
|
|
11
|
-
export const STRING_TO_AST_DEPRECATION_CODE = "OPENAPI_TYPESAFE_DEP_STRING_TO_AST";
|
|
12
|
-
|
|
13
|
-
function parseSource(source: string): unknown[] {
|
|
14
|
-
return [...parseStatements(loadTypeScript(), source)];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
/**
|
|
18
12
|
* Convert an arbitrary string to TS (assuming it’s valid). Parses with the TypeScript bridge, so
|
|
19
|
-
* it needs TypeScript 6 or earlier (or `@typescript/typescript6`). Node
|
|
20
|
-
* on the first call only.
|
|
13
|
+
* it needs TypeScript 6 or earlier (or `@typescript/typescript6`). Emits a Node.js
|
|
14
|
+
* `DeprecationWarning` (`OPENAPI_TYPESAFE_DEP_STRING_TO_AST`) on the first call only.
|
|
21
15
|
* @deprecated Kept for 1.x; removed in 2.0 (ADR-004, decision 7). Use type text in IR callbacks.
|
|
22
16
|
*/
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
17
|
+
export function stringToAST(source: string): unknown[] {
|
|
18
|
+
defaultDeprecationReporter().report(
|
|
19
|
+
DEPRECATION_CODES.OPENAPI_TYPESAFE_DEP_STRING_TO_AST,
|
|
20
|
+
STRING_TO_AST_DEPRECATION,
|
|
21
|
+
);
|
|
22
|
+
return [...parseStatements(loadTypeScript(), source)];
|
|
23
|
+
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "../application/transform/footer/shared-enum-names.js";
|
|
10
10
|
import type { IrDeclaration } from "../domain/ir/nodes.js";
|
|
11
11
|
import type { DocumentObject } from "../domain/openapi/document-object.js";
|
|
12
|
-
import {
|
|
12
|
+
import { FIX } from "../domain/output-fixes.js";
|
|
13
13
|
import type { GlobalContext, OpenAPI3 } from "../types.js";
|
|
14
14
|
import { FirstSchemaNameRecorder } from "./discriminator-enum-names.js";
|
|
15
15
|
import { documentDeclarations, type TransformedDocument } from "./document-declarations.js";
|
|
@@ -65,10 +65,10 @@ function sharedEnumNamesOf(
|
|
|
65
65
|
|
|
66
66
|
/** The recorder of the run's fixes, or null where the first schema's name needs no first pass. */
|
|
67
67
|
function enumNameRecorderOf(ctx: GlobalContext): EnumNameRecorder | null {
|
|
68
|
-
if (ctx.fix?.includes(
|
|
68
|
+
if (ctx.fix?.includes(FIX.DEDUPE_ENUM_NAMES)) {
|
|
69
69
|
return new SharedEnumNameRecorder();
|
|
70
70
|
}
|
|
71
|
-
return ctx.fix?.includes(
|
|
71
|
+
return ctx.fix?.includes(FIX.DISCRIMINATOR_VALUES) ? new FirstSchemaNameRecorder() : null;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/** With a naming fix, `--enum` and `--dedupe-enums`, the run's footer names shared enums. */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DeprecationCode } from "../../domain/deprecations.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Where the generator reports the use of something 2.0 removes (ENGINEERING_PLAN 4.5). The
|
|
5
|
+
* adapter decides how often a code is shown; the Node.js one shows each code once per process.
|
|
6
|
+
*/
|
|
7
|
+
export interface DeprecationReporter {
|
|
8
|
+
report(code: DeprecationCode, message: string): void;
|
|
9
|
+
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
singularizeComponentKind,
|
|
20
20
|
} from "../../../domain/openapi/components-object.js";
|
|
21
21
|
import { createRef } from "../../../domain/openapi/json-pointer.js";
|
|
22
|
-
import {
|
|
22
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
23
23
|
import { type DeprecatedEntryFilter, documentEntries } from "../document-entries.js";
|
|
24
24
|
import type { SchemaLocation } from "../schema/schema-context.js";
|
|
25
25
|
import { transformSchema } from "../schema/schema-transform.js";
|
|
@@ -174,7 +174,7 @@ export function componentsType(
|
|
|
174
174
|
// A plain object, as in the original: its key order (integer-like names first) is the
|
|
175
175
|
// output order.
|
|
176
176
|
const aliases: Record<string, IrTypeAliasDeclaration> = {};
|
|
177
|
-
const displaced = context.options.fixes.has(
|
|
177
|
+
const displaced = context.options.fixes.has(FIX.ROOT_TYPE_NUMBERING) ? [] : null;
|
|
178
178
|
const isKept = (item: unknown) => kept.has(item as object);
|
|
179
179
|
const request = { components, isKept, aliases, displaced };
|
|
180
180
|
const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
QUERYSTRING_LOCATION,
|
|
17
17
|
} from "../../../domain/openapi/parameter-object.js";
|
|
18
18
|
import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
19
|
-
import {
|
|
19
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
20
20
|
import { refType } from "../ref-type.js";
|
|
21
21
|
import type { SchemaLocation } from "../schema/schema-context.js";
|
|
22
22
|
import { withSchemaComment } from "../schema-comment.js";
|
|
@@ -166,7 +166,7 @@ function querystringMember(
|
|
|
166
166
|
/** With `exploded-query-objects`, whether the parameter's object keys are keys of `query`. */
|
|
167
167
|
function isExplodedEntry(entry: ResolvedEntry, context: TransformContext): boolean {
|
|
168
168
|
return (
|
|
169
|
-
context.options.fixes.has(
|
|
169
|
+
context.options.fixes.has(FIX.EXPLODED_QUERY_OBJECTS) &&
|
|
170
170
|
isExplodedQueryObject(entry.resolved, context.refs)
|
|
171
171
|
);
|
|
172
172
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
pathItemOperations,
|
|
15
15
|
} from "../../../domain/openapi/path-item-object.js";
|
|
16
16
|
import type { ReferenceSchema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
17
|
-
import {
|
|
17
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
18
18
|
import { documentEntries } from "../document-entries.js";
|
|
19
19
|
import { refType } from "../ref-type.js";
|
|
20
20
|
import type { TransformContext } from "../transform-context.js";
|
|
@@ -112,7 +112,7 @@ function pathTemplateParts(
|
|
|
112
112
|
const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;
|
|
113
113
|
return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
|
|
114
114
|
});
|
|
115
|
-
return context.options.fixes.has(
|
|
115
|
+
return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES)
|
|
116
116
|
? splitTemplateParts(url, matches)
|
|
117
117
|
: replacedTemplateParts(url, matches);
|
|
118
118
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { irReference } from "../../../domain/ir/constructors.js";
|
|
2
2
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
3
|
-
import {
|
|
3
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
4
4
|
import { InvalidRefError, refType } from "../ref-type.js";
|
|
5
5
|
import type { SchemaRequest } from "../schema/schema-rule.js";
|
|
6
6
|
import { generatedLocationOf } from "./generated-location.js";
|
|
@@ -62,9 +62,7 @@ function correctedType(
|
|
|
62
62
|
|
|
63
63
|
function isCorrected(pointer: RefPointer, request: SchemaRequest): boolean {
|
|
64
64
|
const { options, refs } = request.context;
|
|
65
|
-
return (
|
|
66
|
-
options.fixes.has(OutputFix.REF_POINTERS) || originalIndexFails({ pointer, options, refs })
|
|
67
|
-
);
|
|
65
|
+
return options.fixes.has(FIX.REF_POINTERS) || originalIndexFails({ pointer, options, refs });
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
/** The type of a schema `$ref`. Throws InvalidRefError when the `$ref` has no pointer. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
3
3
|
import type { SchemaContext } from "./schema-context.js";
|
|
4
4
|
|
|
5
5
|
/** Whether a property is `readOnly` or `writeOnly` (JSON Schema 2020-12 Validation §9.4). */
|
|
@@ -56,7 +56,7 @@ export function propertyAccessFlags(value: Schema, context: SchemaContext): Acce
|
|
|
56
56
|
if (typeof value !== "object") {
|
|
57
57
|
return NO_FLAGS;
|
|
58
58
|
}
|
|
59
|
-
if (!context.options.fixes.has(
|
|
59
|
+
if (!context.options.fixes.has(FIX.READ_WRITE_REFS)) {
|
|
60
60
|
return ownFlags(value as SchemaObject);
|
|
61
61
|
}
|
|
62
62
|
return appliedFlags(value, context, new Set());
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "../../../domain/ir/constructors.js";
|
|
8
8
|
import type { IrTupleElement, IrType } from "../../../domain/ir/nodes.js";
|
|
9
9
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
10
|
-
import {
|
|
10
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
11
11
|
import { UNKNOWN_TYPE } from "../shared-types.js";
|
|
12
12
|
import { unionOf } from "../type-combinators.js";
|
|
13
13
|
import type { SchemaRequest } from "./schema-rule.js";
|
|
@@ -79,9 +79,7 @@ function prefixItemsTupleType(
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function isPrefixItemsFixed(schema: SchemaObject, request: SchemaRequest): boolean {
|
|
82
|
-
return (
|
|
83
|
-
schema.prefixItems !== undefined && request.context.options.fixes.has(OutputFix.PREFIX_ITEMS)
|
|
84
|
-
);
|
|
82
|
+
return schema.prefixItems !== undefined && request.context.options.fixes.has(FIX.PREFIX_ITEMS);
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
/** The type of one item; `unknown` without `items`. */
|
|
@@ -193,7 +191,7 @@ function fixedArrayType(schema: SchemaObject, request: SchemaRequest): IrType {
|
|
|
193
191
|
|
|
194
192
|
function isArrayLengthFixed(request: SchemaRequest): boolean {
|
|
195
193
|
const { arrayLength, fixes } = request.context.options;
|
|
196
|
-
return arrayLength && fixes.has(
|
|
194
|
+
return arrayLength && fixes.has(FIX.ARRAY_LENGTH_TUPLES);
|
|
197
195
|
}
|
|
198
196
|
|
|
199
197
|
/** `type: array`, including tuples (`prefixItems`, array `items`) and `--array-length`. */
|
|
@@ -2,7 +2,7 @@ import { irKeyword, irRecord } from "../../../domain/ir/constructors.js";
|
|
|
2
2
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
3
3
|
import { createRef } from "../../../domain/openapi/json-pointer.js";
|
|
4
4
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
5
|
-
import {
|
|
5
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
6
6
|
import { requirableRefType } from "../ref-pointer/pointer-type.js";
|
|
7
7
|
import { UNKNOWN_TYPE } from "../shared-types.js";
|
|
8
8
|
import {
|
|
@@ -58,7 +58,7 @@ function keysToRequire(
|
|
|
58
58
|
if (!request.context.discriminators.isHandled(ref)) {
|
|
59
59
|
return defined;
|
|
60
60
|
}
|
|
61
|
-
if (!request.context.options.fixes.has(
|
|
61
|
+
if (!request.context.options.fixes.has(FIX.DISCRIMINATOR_MEMBER_REQUIRED)) {
|
|
62
62
|
return [];
|
|
63
63
|
}
|
|
64
64
|
return defined.filter((key) => !target.required?.includes(key));
|
|
@@ -131,7 +131,7 @@ function allOfItemType(
|
|
|
131
131
|
const isUnion =
|
|
132
132
|
unionItem !== undefined &&
|
|
133
133
|
!unionItem.isMapped &&
|
|
134
|
-
request.context.options.fixes.has(
|
|
134
|
+
request.context.options.fixes.has(FIX.ALLOF_DISCRIMINATED_UNION);
|
|
135
135
|
if (!propertyName || isUnion) {
|
|
136
136
|
return type;
|
|
137
137
|
}
|
|
@@ -173,7 +173,7 @@ function anyOfType(
|
|
|
173
173
|
if (variants.length === 0 || previous === null) {
|
|
174
174
|
return variants.length === 0 ? previous : unionOf(variants);
|
|
175
175
|
}
|
|
176
|
-
if (!request.context.options.fixes.has(
|
|
176
|
+
if (!request.context.options.fixes.has(FIX.ANYOF_PROPERTIES)) {
|
|
177
177
|
return unionOf([previous, ...variants]);
|
|
178
178
|
}
|
|
179
179
|
return Array.isArray(schema.type) ? previous : intersectionOf([previous, unionOf(variants)]);
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
9
9
|
import { createRef, parseRefPointer } from "../../../domain/openapi/json-pointer.js";
|
|
10
10
|
import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
11
|
-
import {
|
|
11
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
12
12
|
import { literalType } from "../literal-type.js";
|
|
13
13
|
import { refType } from "../ref-type.js";
|
|
14
14
|
import { intersectionOf, unionOf } from "../type-combinators.js";
|
|
@@ -55,7 +55,7 @@ function hasEnumMetadata(schema: SchemaObject): boolean {
|
|
|
55
55
|
*/
|
|
56
56
|
function tsEnumEntries(schema: SchemaObject, options: SchemaOptions): [unknown, number][] {
|
|
57
57
|
const entries = (schema.enum ?? []).map((value, index): [unknown, number] => [value, index]);
|
|
58
|
-
return options.fixes.has(
|
|
58
|
+
return options.fixes.has(FIX.NULLABLE_ENUMS)
|
|
59
59
|
? entries.filter(([value]) => value !== null)
|
|
60
60
|
: entries;
|
|
61
61
|
}
|
|
@@ -147,9 +147,7 @@ export function ownerEnumMembersType(
|
|
|
147
147
|
request: SchemaRequest,
|
|
148
148
|
): IrType | null {
|
|
149
149
|
const { options, discriminators, footer } = request.context;
|
|
150
|
-
const parent: DiscriminatorEnumParent | undefined = options.fixes.has(
|
|
151
|
-
OutputFix.DISCRIMINATOR_VALUES,
|
|
152
|
-
)
|
|
150
|
+
const parent: DiscriminatorEnumParent | undefined = options.fixes.has(FIX.DISCRIMINATOR_VALUES)
|
|
153
151
|
? discriminators.enumParentOf(key)
|
|
154
152
|
: undefined;
|
|
155
153
|
if (parent === undefined || !isTsEnum(parent.schema, options)) {
|
|
@@ -175,7 +173,7 @@ function tsEnumType(schema: SchemaObject, request: SchemaRequest): IrType {
|
|
|
175
173
|
irReference(footer.addEnum(enumRequest(schema, request.location.path, options))),
|
|
176
174
|
schema,
|
|
177
175
|
);
|
|
178
|
-
return options.fixes.has(
|
|
176
|
+
return options.fixes.has(FIX.NULLABLE_ENUMS) && isNullAllowed(schema)
|
|
179
177
|
? unionOf([type, irKeyword("null")])
|
|
180
178
|
: type;
|
|
181
179
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
3
3
|
import type { SchemaRequest } from "./schema-rule.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -81,7 +81,7 @@ export interface AllOfMembers {
|
|
|
81
81
|
*/
|
|
82
82
|
export function allOfMembers(members: readonly Schema[], request: SchemaRequest): AllOfMembers {
|
|
83
83
|
const unchanged = { members, required: [] };
|
|
84
|
-
if (!request.context.options.fixes.has(
|
|
84
|
+
if (!request.context.options.fixes.has(FIX.ALLOF_REQUIRED)) {
|
|
85
85
|
return unchanged;
|
|
86
86
|
}
|
|
87
87
|
const schemas = members.map((member) => memberSchema(member, request));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IrType } from "../../../domain/ir/nodes.js";
|
|
2
2
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
3
|
-
import {
|
|
3
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
4
4
|
import { unionOf, withRequiredKeys } from "../type-combinators.js";
|
|
5
5
|
import { isKeptProperty } from "./object-type.js";
|
|
6
6
|
import type { SchemaRequest } from "./schema-rule.js";
|
|
@@ -55,7 +55,7 @@ export function hasRequiredVariants(
|
|
|
55
55
|
request: SchemaRequest,
|
|
56
56
|
): boolean {
|
|
57
57
|
return (
|
|
58
|
-
request.context.options.fixes.has(
|
|
58
|
+
request.context.options.fixes.has(FIX.ANYOF_ONEOF_REQUIRED) &&
|
|
59
59
|
isObjectTyped(schema) &&
|
|
60
60
|
requiredKeyLists(schema, variants, request) !== null
|
|
61
61
|
);
|
|
@@ -73,7 +73,7 @@ export function requiredVariantsType(
|
|
|
73
73
|
variants: readonly Schema[],
|
|
74
74
|
request: SchemaRequest,
|
|
75
75
|
): IrType | null {
|
|
76
|
-
if (!request.context.options.fixes.has(
|
|
76
|
+
if (!request.context.options.fixes.has(FIX.ANYOF_ONEOF_REQUIRED) || previous === null) {
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
const keyLists = isObjectTyped(schema) ? requiredKeyLists(schema, variants, request) : null;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../../../domain/ir/constructors.js";
|
|
7
7
|
import type { IrMember, IrType } from "../../../domain/ir/nodes.js";
|
|
8
8
|
import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
|
|
9
|
-
import {
|
|
9
|
+
import { FIX } from "../../../domain/output-fixes.js";
|
|
10
10
|
import { HELPER_TYPES } from "../helper-types.js";
|
|
11
11
|
import { UNKNOWN_TYPE } from "../shared-types.js";
|
|
12
12
|
import { unionOf } from "../type-combinators.js";
|
|
@@ -32,7 +32,7 @@ import type { SchemaRequest } from "./schema-rule.js";
|
|
|
32
32
|
function unevaluatedSchemaOf(schema: SchemaObject, request: SchemaRequest): Schema | null {
|
|
33
33
|
const { unevaluatedProperties } = schema;
|
|
34
34
|
if (
|
|
35
|
-
!request.context.options.fixes.has(
|
|
35
|
+
!request.context.options.fixes.has(FIX.UNEVALUATED_PROPERTIES) ||
|
|
36
36
|
unevaluatedProperties === undefined ||
|
|
37
37
|
unevaluatedProperties === false ||
|
|
38
38
|
schema.additionalProperties !== undefined
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IrComment, IrPropertySignature } from "../../domain/ir/nodes.js";
|
|
2
|
-
import { OutputFix } from "../../domain/output-fixes.js";
|
|
2
|
+
import { FIX, type OutputFix } from "../../domain/output-fixes.js";
|
|
3
3
|
|
|
4
4
|
/** Schema fields that produce JSDoc lines (the original `AnnotatedSchemaObject`). */
|
|
5
5
|
export interface AnnotatedSchema {
|
|
@@ -44,7 +44,7 @@ export const ORIGINAL_SCHEMA_COMMENT: SchemaCommentOptions = { hasMemberDescript
|
|
|
44
44
|
|
|
45
45
|
/** How the fixes turned on write a schema's JSDoc. */
|
|
46
46
|
export function schemaCommentOptionsOf(fixes: ReadonlySet<OutputFix>): SchemaCommentOptions {
|
|
47
|
-
return { hasMemberDescriptions: fixes.has(
|
|
47
|
+
return { hasMemberDescriptions: fixes.has(FIX.ANYOF_ONEOF_DESCRIPTIONS) };
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function formatValue(value: unknown): string {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deprecations of what 2.0 removes. Each one is a Node.js `DeprecationWarning` with one of these
|
|
3
|
+
* codes, so `--no-deprecation`, `--throw-deprecation`, `--trace-deprecation` and
|
|
4
|
+
* `process.on("warning")` work on it as on Node's own (ADR-004, amendment of 2026-11-08).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Every deprecation code. */
|
|
8
|
+
export const DEPRECATION_CODES = {
|
|
9
|
+
OPENAPI_TYPESAFE_DEP_STRING_TO_AST: "OPENAPI_TYPESAFE_DEP_STRING_TO_AST",
|
|
10
|
+
OPENAPI_TYPESAFE_DEP_TS_TRANSFORM: "OPENAPI_TYPESAFE_DEP_TS_TRANSFORM",
|
|
11
|
+
OPENAPI_TYPESAFE_DEP_TS_POST_TRANSFORM: "OPENAPI_TYPESAFE_DEP_TS_POST_TRANSFORM",
|
|
12
|
+
OPENAPI_TYPESAFE_DEP_TS_TRANSFORM_PROPERTY: "OPENAPI_TYPESAFE_DEP_TS_TRANSFORM_PROPERTY",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type DeprecationCode = (typeof DEPRECATION_CODES)[keyof typeof DEPRECATION_CODES];
|
package/src/domain/errors.ts
CHANGED
|
@@ -7,7 +7,10 @@ import { redactUrlCredentials } from "./url-credentials.js";
|
|
|
7
7
|
* invariant) is a plain `Error`, not one of these.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Every error code. A minor release may add codes (ADR-034); each one needs a row in the CLI's
|
|
12
|
+
* exit-code table, which the compiler checks.
|
|
13
|
+
*/
|
|
11
14
|
export const ERROR_CODES = {
|
|
12
15
|
SCHEMA_SOURCE_EMPTY: "SCHEMA_SOURCE_EMPTY",
|
|
13
16
|
SCHEMA_SOURCE_INVALID: "SCHEMA_SOURCE_INVALID",
|
|
@@ -39,7 +42,10 @@ export const ERROR_CODES = {
|
|
|
39
42
|
|
|
40
43
|
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
41
44
|
|
|
42
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Structured, JSON-serializable facts about a failure, for programs and logs. Only the keys that
|
|
47
|
+
* docs/node.md (Errors) lists are stable (ADR-034, amendment of 2026-11-08).
|
|
48
|
+
*/
|
|
43
49
|
export type ErrorDetails = Readonly<Record<string, unknown>>;
|
|
44
50
|
|
|
45
51
|
export interface OpenAPITypesafeErrorInit {
|
|
@@ -3,9 +3,10 @@ import { ERROR_CODES, OpenAPITypesafeError } from "./errors.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Opt-in fixes of the output of valid schemas (ADR-021). Each one changes only the cases it names;
|
|
5
5
|
* without any, the output is the same as openapi-typescript 7.13 gives. In 2.0 they become the
|
|
6
|
-
* default.
|
|
6
|
+
* default. The object names the fixes for this package's code; the public API is the `OutputFix`
|
|
7
|
+
* union and the `OUTPUT_FIXES` list (ADR-021, amendment 1).
|
|
7
8
|
*/
|
|
8
|
-
export const
|
|
9
|
+
export const FIX = {
|
|
9
10
|
/** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */
|
|
10
11
|
ALLOF_DISCRIMINATED_UNION: "allof-discriminated-union",
|
|
11
12
|
/** An `allOf` member with only `required` makes those properties of the others required. */
|
|
@@ -48,18 +49,19 @@ export const OutputFix = {
|
|
|
48
49
|
/** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */
|
|
49
50
|
UNEVALUATED_PROPERTIES: "unevaluated-properties",
|
|
50
51
|
} as const;
|
|
51
|
-
|
|
52
|
+
/** The name of one opt-in output fix. */
|
|
53
|
+
export type OutputFix = (typeof FIX)[keyof typeof FIX];
|
|
52
54
|
|
|
53
55
|
/** Every fix of this version, in the order the docs list them. */
|
|
54
|
-
export const OUTPUT_FIXES: readonly OutputFix[] = Object.values(
|
|
56
|
+
export const OUTPUT_FIXES: readonly OutputFix[] = Object.values(FIX);
|
|
55
57
|
|
|
56
58
|
/** The name that turns on every fix of the installed version. */
|
|
57
|
-
|
|
59
|
+
const ALL_FIXES = "all";
|
|
58
60
|
|
|
59
|
-
/** A name the `fix` option accepts: one fix, or `all`. */
|
|
60
|
-
export type OutputFixName = OutputFix | typeof
|
|
61
|
+
/** A name the `fix` option accepts: one fix, or `"all"`. */
|
|
62
|
+
export type OutputFixName = OutputFix | typeof ALL_FIXES;
|
|
61
63
|
|
|
62
|
-
const KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES,
|
|
64
|
+
const KNOWN_NAMES: ReadonlySet<string> = new Set<string>([...OUTPUT_FIXES, ALL_FIXES]);
|
|
63
65
|
|
|
64
66
|
function isOutputFixName(value: unknown): value is OutputFixName {
|
|
65
67
|
return typeof value === "string" && KNOWN_NAMES.has(value);
|
|
@@ -82,7 +84,7 @@ export function outputFixNamesOf(values: readonly unknown[]): readonly OutputFix
|
|
|
82
84
|
|
|
83
85
|
/** The fixes the names turn on; `all` stands for every fix of this version. */
|
|
84
86
|
export function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet<OutputFix> {
|
|
85
|
-
return new Set(names.flatMap((name) => (name ===
|
|
87
|
+
return new Set(names.flatMap((name) => (name === ALL_FIXES ? OUTPUT_FIXES : [name])));
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
/** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */
|
|
@@ -106,13 +108,11 @@ const NO_SCHEMA_PREFIX = {
|
|
|
106
108
|
|
|
107
109
|
/** The options each fix needs, by fix name; `all` has none. */
|
|
108
110
|
const REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {
|
|
109
|
-
[
|
|
110
|
-
[
|
|
111
|
-
[
|
|
112
|
-
[
|
|
113
|
-
|
|
114
|
-
],
|
|
115
|
-
[OutputFix.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],
|
|
111
|
+
[FIX.ARRAY_LENGTH_TUPLES]: [{ option: "arrayLength", flag: "--array-length" }],
|
|
112
|
+
[FIX.DEDUPE_ENUM_NAMES]: [ENUM, { option: "dedupeEnums", flag: "--dedupe-enums" }],
|
|
113
|
+
[FIX.NULLABLE_ENUMS]: [ENUM],
|
|
114
|
+
[FIX.PATH_PARAM_TYPE_NAMES]: [{ option: "pathParamsAsTypes", flag: "--path-params-as-types" }],
|
|
115
|
+
[FIX.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
function describeRequirement(requirement: OutputFixRequirement): string {
|
package/src/domain/warnings.ts
CHANGED
|
@@ -12,7 +12,6 @@ export const WARNING_CODES = {
|
|
|
12
12
|
DISCRIMINATOR_VALUE_NOT_ALLOWED: "DISCRIMINATOR_VALUE_NOT_ALLOWED",
|
|
13
13
|
ENUM_VALUES_EXCLUDED: "ENUM_VALUES_EXCLUDED",
|
|
14
14
|
FIX_NEEDS_OPTION: "FIX_NEEDS_OPTION",
|
|
15
|
-
LEGACY_CALLBACK_DEPRECATED: "LEGACY_CALLBACK_DEPRECATED",
|
|
16
15
|
LINT_PROBLEM: "LINT_PROBLEM",
|
|
17
16
|
PATH_TEMPLATES_IDENTICAL: "PATH_TEMPLATES_IDENTICAL",
|
|
18
17
|
QUERYSTRING_NEXT_TO_QUERY: "QUERYSTRING_NEXT_TO_QUERY",
|
package/src/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export {
|
|
|
34
34
|
UNDEFINED,
|
|
35
35
|
UNKNOWN,
|
|
36
36
|
} from "./api/type-helpers.js";
|
|
37
|
+
export { DEPRECATION_CODES, type DeprecationCode } from "./domain/deprecations.js";
|
|
37
38
|
export {
|
|
38
39
|
ERROR_CODES,
|
|
39
40
|
type ErrorCode,
|
|
@@ -42,12 +43,7 @@ export {
|
|
|
42
43
|
OpenAPITypesafeError,
|
|
43
44
|
} from "./domain/errors.js";
|
|
44
45
|
export type * from "./domain/ir/nodes.js";
|
|
45
|
-
export {
|
|
46
|
-
ALL_OUTPUT_FIXES,
|
|
47
|
-
OUTPUT_FIXES,
|
|
48
|
-
OutputFix,
|
|
49
|
-
type OutputFixName,
|
|
50
|
-
} from "./domain/output-fixes.js";
|
|
46
|
+
export { OUTPUT_FIXES, type OutputFix, type OutputFixName } from "./domain/output-fixes.js";
|
|
51
47
|
export { WARNING_CODES, type WarningCode } from "./domain/warnings.js";
|
|
52
48
|
export { default as transformComponentsObject } from "./transform/components-object.js";
|
|
53
49
|
export { default as transformHeaderObject } from "./transform/header-object.js";
|