ts-json-schema-generator 2.5.0--canary.76e1a68.0 → 2.5.0--canary.2413.011011e.0
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/factory/parser.js +2 -0
- package/dist/factory/parser.js.map +1 -1
- package/dist/factory/program.js +5 -2
- package/dist/factory/program.js.map +1 -1
- package/dist/package.json +29 -30
- package/dist/src/Error/BaseError.d.ts +1 -1
- package/dist/src/Error/BaseError.js +1 -2
- package/dist/src/Error/BaseError.js.map +1 -1
- package/dist/src/NodeParser/BinaryExpressionNodeParser.d.ts +13 -0
- package/dist/src/NodeParser/BinaryExpressionNodeParser.js +79 -0
- package/dist/src/NodeParser/BinaryExpressionNodeParser.js.map +1 -0
- package/dist/src/Type/AnnotatedType.d.ts +1 -3
- package/dist/src/Type/AnnotatedType.js.map +1 -1
- package/dist/src/Type/UnknownType.d.ts +1 -1
- package/dist/src/Type/UnknownType.js +1 -1
- package/dist/src/Type/UnknownType.js.map +1 -1
- package/dist/src/TypeFormatter/AnnotatedTypeFormatter.js +1 -1
- package/dist/src/TypeFormatter/AnnotatedTypeFormatter.js.map +1 -1
- package/dist/src/Utils/narrowType.js.map +1 -1
- package/dist/src/Utils/nodeKey.d.ts +1 -1
- package/dist/src/Utils/nodeKey.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/factory/parser.ts +2 -0
- package/factory/program.ts +7 -3
- package/package.json +29 -30
- package/src/Error/BaseError.ts +1 -3
- package/src/NodeParser/BinaryExpressionNodeParser.ts +99 -0
- package/src/Type/AnnotatedType.ts +1 -3
- package/src/Type/UnknownType.ts +1 -1
- package/src/TypeFormatter/AnnotatedTypeFormatter.ts +2 -2
- package/src/Utils/narrowType.ts +1 -6
- package/src/Utils/nodeKey.ts +3 -1
package/factory/parser.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { AnyTypeNodeParser } from "../src/NodeParser/AnyTypeNodeParser.js";
|
|
|
12
12
|
import { ArrayLiteralExpressionNodeParser } from "../src/NodeParser/ArrayLiteralExpressionNodeParser.js";
|
|
13
13
|
import { ArrayNodeParser } from "../src/NodeParser/ArrayNodeParser.js";
|
|
14
14
|
import { AsExpressionNodeParser } from "../src/NodeParser/AsExpressionNodeParser.js";
|
|
15
|
+
import { BinaryExpressionNodeParser } from "../src/NodeParser/BinaryExpressionNodeParser.js";
|
|
15
16
|
import { BooleanLiteralNodeParser } from "../src/NodeParser/BooleanLiteralNodeParser.js";
|
|
16
17
|
import { BooleanTypeNodeParser } from "../src/NodeParser/BooleanTypeNodeParser.js";
|
|
17
18
|
import { CallExpressionParser } from "../src/NodeParser/CallExpressionParser.js";
|
|
@@ -118,6 +119,7 @@ export function createParser(program: ts.Program, config: CompletedConfig, augme
|
|
|
118
119
|
.addNodeParser(new NeverTypeNodeParser())
|
|
119
120
|
.addNodeParser(new ObjectTypeNodeParser())
|
|
120
121
|
.addNodeParser(new AsExpressionNodeParser(chainNodeParser))
|
|
122
|
+
.addNodeParser(new BinaryExpressionNodeParser(chainNodeParser))
|
|
121
123
|
.addNodeParser(new SatisfiesNodeParser(chainNodeParser))
|
|
122
124
|
.addNodeParser(withJsDoc(new ParameterParser(chainNodeParser)))
|
|
123
125
|
.addNodeParser(new StringLiteralNodeParser())
|
package/factory/program.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { globSync } from "glob";
|
|
1
2
|
import * as path from "node:path";
|
|
2
3
|
import normalize from "normalize-path";
|
|
4
|
+
import type { CompilerOptions } from "typescript";
|
|
3
5
|
import ts from "typescript";
|
|
4
6
|
import type { CompletedConfig, Config } from "../src/Config.js";
|
|
5
7
|
import { BuildError } from "../src/Error/Errors.js";
|
|
6
|
-
import { globSync } from "glob";
|
|
7
8
|
|
|
8
9
|
function loadTsConfigFile(configFile: string) {
|
|
9
10
|
const raw = ts.sys.readFile(configFile);
|
|
@@ -55,10 +56,13 @@ function getTsConfig(config: Config) {
|
|
|
55
56
|
noEmit: true,
|
|
56
57
|
emitDecoratorMetadata: true,
|
|
57
58
|
experimentalDecorators: true,
|
|
58
|
-
target: ts.ScriptTarget.
|
|
59
|
+
target: ts.ScriptTarget.ES2022,
|
|
59
60
|
module: ts.ModuleKind.CommonJS,
|
|
60
61
|
strictNullChecks: false,
|
|
61
|
-
|
|
62
|
+
skipLibCheck: true,
|
|
63
|
+
skipDefaultLibCheck: true,
|
|
64
|
+
esModuleInterop: true,
|
|
65
|
+
} satisfies CompilerOptions,
|
|
62
66
|
};
|
|
63
67
|
}
|
|
64
68
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-json-schema-generator",
|
|
3
|
-
"version": "2.5.0--canary.
|
|
3
|
+
"version": "2.5.0--canary.2413.011011e.0",
|
|
4
4
|
"description": "Generate JSON schema from your Typescript sources",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ts",
|
|
@@ -49,52 +49,51 @@
|
|
|
49
49
|
"prepublishOnly": "npm run build",
|
|
50
50
|
"release": "npm run build && auto shipit",
|
|
51
51
|
"run": "tsx ts-json-schema-generator.ts",
|
|
52
|
-
"test": "
|
|
53
|
-
"test:
|
|
54
|
-
"test:fast": "cross-env FAST_TEST=1
|
|
55
|
-
"test:update": "cross-env UPDATE_SCHEMA=true
|
|
52
|
+
"test": "tsx --test \"test/**/*.test.ts\"",
|
|
53
|
+
"test:debug": "tsx --inspect-brk --test-concurrency=1 --test",
|
|
54
|
+
"test:fast": "cross-env FAST_TEST=1 tsx --test \"test/**/*.test.ts\"",
|
|
55
|
+
"test:update": "cross-env FAST_TEST=1 UPDATE_SCHEMA=true tsx --test \"test/**/*.test.ts\"",
|
|
56
|
+
"test:coverage": "c8 --reporter lcov --reporter text tsx --test \"test/**/*.test.ts\"",
|
|
56
57
|
"watch": "tsc -w"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
60
|
"@types/json-schema": "^7.0.15",
|
|
60
|
-
"
|
|
61
|
+
"@typescript/vfs": "1.6.2",
|
|
62
|
+
"commander": "^14.0.2",
|
|
61
63
|
"glob": "^13.0.0",
|
|
62
64
|
"json5": "^2.2.3",
|
|
63
65
|
"normalize-path": "^3.0.0",
|
|
64
66
|
"safe-stable-stringify": "^2.5.0",
|
|
65
67
|
"tslib": "^2.8.1",
|
|
66
|
-
"typescript": "^5.
|
|
67
|
-
"@typescript/vfs": "1.6.2"
|
|
68
|
+
"typescript": "^5.9.3"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
70
|
-
"@auto-it/conventional-commits": "^11.3.
|
|
71
|
-
"@auto-it/first-time-contributor": "^11.3.
|
|
72
|
-
"@babel/core": "^7.28.
|
|
73
|
-
"@babel/preset-env": "^7.28.
|
|
74
|
-
"@babel/preset-typescript": "^7.
|
|
75
|
-
"@eslint/js": "^9.
|
|
71
|
+
"@auto-it/conventional-commits": "^11.3.6",
|
|
72
|
+
"@auto-it/first-time-contributor": "^11.3.6",
|
|
73
|
+
"@babel/core": "^7.28.5",
|
|
74
|
+
"@babel/preset-env": "^7.28.5",
|
|
75
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
76
|
+
"@eslint/js": "^9.39.1",
|
|
76
77
|
"@types/eslint": "^9.6.1",
|
|
77
|
-
"@types/
|
|
78
|
-
"@types/node": "^24.0.10",
|
|
78
|
+
"@types/node": "^24.10.1",
|
|
79
79
|
"@types/normalize-path": "^3.0.2",
|
|
80
80
|
"ajv": "^8.17.1",
|
|
81
81
|
"ajv-formats": "^3.0.1",
|
|
82
|
-
"auto": "^11.3.
|
|
83
|
-
"chai": "^6.
|
|
84
|
-
"cross-env": "^10.
|
|
82
|
+
"auto": "^11.3.6",
|
|
83
|
+
"chai": "^6.2.1",
|
|
84
|
+
"cross-env": "^10.1.0",
|
|
85
85
|
"eslint": "9.39.1",
|
|
86
|
-
"eslint-config-prettier": "^10.1.
|
|
87
|
-
"eslint-plugin-prettier": "^5.5.
|
|
88
|
-
"globals": "^16.
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"vega": "^6.1
|
|
95
|
-
"vega-lite": "^6.2.0"
|
|
86
|
+
"eslint-config-prettier": "^10.1.8",
|
|
87
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
88
|
+
"globals": "^16.5.0",
|
|
89
|
+
"prettier": "^3.7.3",
|
|
90
|
+
"try": "^1.0.1",
|
|
91
|
+
"tsx": "^4.21.0",
|
|
92
|
+
"typescript-eslint": "^8.48.0",
|
|
93
|
+
"vega": "^6.2.0",
|
|
94
|
+
"vega-lite": "^6.4.1"
|
|
96
95
|
},
|
|
97
|
-
"packageManager": "npm@11.4
|
|
96
|
+
"packageManager": "npm@11.6.4",
|
|
98
97
|
"engines": {
|
|
99
98
|
"node": ">=18.0.0"
|
|
100
99
|
}
|
package/src/Error/BaseError.ts
CHANGED
|
@@ -12,8 +12,6 @@ export type PartialDiagnostic = Omit<ts.Diagnostic, "category" | "file" | "start
|
|
|
12
12
|
category?: ts.DiagnosticCategory;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
const isTTY = process.env.TTY || process.stdout.isTTY;
|
|
16
|
-
|
|
17
15
|
/**
|
|
18
16
|
* Base error for ts-json-schema-generator
|
|
19
17
|
*/
|
|
@@ -51,7 +49,7 @@ export abstract class BaseError extends Error {
|
|
|
51
49
|
);
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
format() {
|
|
52
|
+
format(isTTY = process.env.TTY || process.stdout.isTTY): string {
|
|
55
53
|
const formatter = isTTY ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics;
|
|
56
54
|
|
|
57
55
|
return formatter([this.diagnostic], {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { Context, NodeParser } from "../NodeParser.js";
|
|
3
|
+
import type { SubNodeParser } from "../SubNodeParser.js";
|
|
4
|
+
import { AnyType } from "../Type/AnyType.js";
|
|
5
|
+
import type { BaseType } from "../Type/BaseType.js";
|
|
6
|
+
import { BooleanType } from "../Type/BooleanType.js";
|
|
7
|
+
import { LiteralType } from "../Type/LiteralType.js";
|
|
8
|
+
import { NumberType } from "../Type/NumberType.js";
|
|
9
|
+
import { StringType } from "../Type/StringType.js";
|
|
10
|
+
import { UnionType } from "../Type/UnionType.js";
|
|
11
|
+
import { AliasType } from "../Type/AliasType.js";
|
|
12
|
+
|
|
13
|
+
export class BinaryExpressionNodeParser implements SubNodeParser {
|
|
14
|
+
public constructor(protected childNodeParser: NodeParser) {}
|
|
15
|
+
|
|
16
|
+
public supportsNode(node: ts.Node): boolean {
|
|
17
|
+
return node.kind === ts.SyntaxKind.BinaryExpression;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public createType(node: ts.BinaryExpression, context: Context): BaseType {
|
|
21
|
+
const leftType = this.childNodeParser.createType(node.left, context);
|
|
22
|
+
const rightType = this.childNodeParser.createType(node.right, context);
|
|
23
|
+
|
|
24
|
+
if (leftType instanceof AnyType || rightType instanceof AnyType) {
|
|
25
|
+
return new AnyType();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (this.isStringLike(leftType) || this.isStringLike(rightType)) {
|
|
29
|
+
return new StringType();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (this.isDefinitelyNumberLike(leftType) && this.isDefinitelyNumberLike(rightType)) {
|
|
33
|
+
return new NumberType();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (this.isBooleanLike(leftType) && this.isBooleanLike(rightType)) {
|
|
37
|
+
return new BooleanType();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Anything else (objects, any, unknown, weird unions, etc.) return
|
|
41
|
+
// 'string' because at runtime + will usually go through ToPrimitive and
|
|
42
|
+
// end up in the "string concatenation" branch when non-numeric stuff is
|
|
43
|
+
// involved.
|
|
44
|
+
return new StringType();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private isStringLike(type: BaseType): boolean {
|
|
48
|
+
if (type instanceof AliasType) {
|
|
49
|
+
return this.isStringLike(type.getType());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (type instanceof StringType) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (type instanceof LiteralType && type.isString()) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Any union member being string-like is enough.
|
|
61
|
+
if (type instanceof UnionType) {
|
|
62
|
+
return type.getTypes().some((t) => this.isStringLike(t));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private isBooleanLike(type: BaseType): boolean {
|
|
69
|
+
if (type instanceof BooleanType) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (type instanceof LiteralType && typeof type.getValue() === "boolean") {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private isDefinitelyNumberLike(type: BaseType): boolean {
|
|
81
|
+
if (type instanceof AliasType) {
|
|
82
|
+
return this.isDefinitelyNumberLike(type.getType());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (type instanceof NumberType) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (type instanceof LiteralType && typeof type.getValue() === "number") {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (type instanceof UnionType) {
|
|
94
|
+
return type.getTypes().every((t) => this.isDefinitelyNumberLike(t));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { BaseType } from "./BaseType.js";
|
|
2
2
|
import { hash } from "../Utils/nodeKey.js";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
[name: string]: any;
|
|
6
|
-
}
|
|
4
|
+
export type Annotations = Record<string, unknown>;
|
|
7
5
|
|
|
8
6
|
export class AnnotatedType extends BaseType {
|
|
9
7
|
public constructor(
|
package/src/Type/UnknownType.ts
CHANGED
|
@@ -5,7 +5,7 @@ export class UnknownType extends BaseType {
|
|
|
5
5
|
/**
|
|
6
6
|
* If the source for this UnknownType was from a failed operation than to an actual `unknown` type present in the source code.
|
|
7
7
|
*/
|
|
8
|
-
readonly erroredSource
|
|
8
|
+
readonly erroredSource = false,
|
|
9
9
|
) {
|
|
10
10
|
super();
|
|
11
11
|
}
|
|
@@ -8,7 +8,7 @@ import type { TypeFormatter } from "../TypeFormatter.js";
|
|
|
8
8
|
import { derefType } from "../Utils/derefType.js";
|
|
9
9
|
|
|
10
10
|
export function makeNullable(def: Definition): Definition {
|
|
11
|
-
const union
|
|
11
|
+
const union = (def.oneOf || def.anyOf) as Definition[] | undefined;
|
|
12
12
|
if (union && union.filter((d: Definition) => d.type === "null").length === 0) {
|
|
13
13
|
union.push({ type: "null" });
|
|
14
14
|
} else if (def.type && def.type !== "object") {
|
|
@@ -58,7 +58,7 @@ export class AnnotatedTypeFormatter implements SubTypeFormatter {
|
|
|
58
58
|
if ("discriminator" in annotations) {
|
|
59
59
|
const deref = derefType(type.getType());
|
|
60
60
|
if (deref instanceof UnionType) {
|
|
61
|
-
deref.setDiscriminator(annotations.discriminator);
|
|
61
|
+
deref.setDiscriminator(annotations.discriminator as string);
|
|
62
62
|
delete annotations.discriminator;
|
|
63
63
|
} else {
|
|
64
64
|
throw new JsonTypeError(
|
package/src/Utils/narrowType.ts
CHANGED
|
@@ -16,12 +16,7 @@ import { derefType } from "./derefType.js";
|
|
|
16
16
|
* kept, when returning false it is removed.
|
|
17
17
|
* @return The narrowed down type.
|
|
18
18
|
*/
|
|
19
|
-
export function narrowType(
|
|
20
|
-
type: BaseType,
|
|
21
|
-
// TODO: remove the next line
|
|
22
|
-
// eslint-disable-next-line no-shadow
|
|
23
|
-
predicate: (type: BaseType) => boolean,
|
|
24
|
-
): BaseType {
|
|
19
|
+
export function narrowType(type: BaseType, predicate: (type: BaseType) => boolean): BaseType {
|
|
25
20
|
const derefed = derefType(type);
|
|
26
21
|
if (derefed instanceof UnionType || derefed instanceof EnumType) {
|
|
27
22
|
let changed = false;
|
package/src/Utils/nodeKey.ts
CHANGED
|
@@ -2,7 +2,9 @@ import stringify from "safe-stable-stringify";
|
|
|
2
2
|
import type { Node } from "typescript";
|
|
3
3
|
import type { Context } from "../NodeParser.js";
|
|
4
4
|
|
|
5
|
-
export function hash(
|
|
5
|
+
export function hash(
|
|
6
|
+
a: string | boolean | number | (string | boolean | number | Record<string, unknown>)[] | Record<string, unknown>,
|
|
7
|
+
): string | number {
|
|
6
8
|
if (typeof a === "number") {
|
|
7
9
|
return a;
|
|
8
10
|
}
|