ts-json-schema-generator 2.4.1--canary.2306.1ddde9f.0 → 2.4.1--canary.2413.e57678e.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.
@@ -7,7 +7,7 @@ import { createProgram } from "./program.js";
7
7
 
8
8
  export function createGenerator(config: Config): SchemaGenerator {
9
9
  const completedConfig = { ...DEFAULT_CONFIG, ...config };
10
- const program = createProgram(completedConfig);
10
+ const program = config.tsProgram || createProgram(completedConfig);
11
11
  const parser = createParser(program, completedConfig);
12
12
  const formatter = createFormatter(completedConfig);
13
13
 
package/factory/parser.ts CHANGED
@@ -16,6 +16,7 @@ import { BooleanLiteralNodeParser } from "../src/NodeParser/BooleanLiteralNodePa
16
16
  import { BooleanTypeNodeParser } from "../src/NodeParser/BooleanTypeNodeParser.js";
17
17
  import { CallExpressionParser } from "../src/NodeParser/CallExpressionParser.js";
18
18
  import { ConditionalTypeNodeParser } from "../src/NodeParser/ConditionalTypeNodeParser.js";
19
+ import { NewExpressionParser } from "../src/NodeParser/NewExpressionParser.js";
19
20
  import { ConstructorNodeParser } from "../src/NodeParser/ConstructorNodeParser.js";
20
21
  import { EnumNodeParser } from "../src/NodeParser/EnumNodeParser.js";
21
22
  import { ExpressionWithTypeArgumentsNodeParser } from "../src/NodeParser/ExpressionWithTypeArgumentsNodeParser.js";
@@ -149,6 +150,7 @@ export function createParser(program: ts.Program, config: CompletedConfig, augme
149
150
  .addNodeParser(new SpreadElementNodeParser(chainNodeParser))
150
151
 
151
152
  .addNodeParser(new CallExpressionParser(typeChecker, chainNodeParser))
153
+ .addNodeParser(new NewExpressionParser(typeChecker, chainNodeParser))
152
154
  .addNodeParser(new PropertyAccessExpressionParser(typeChecker, chainNodeParser))
153
155
 
154
156
  .addNodeParser(withCircular(withExpose(withJsDoc(new TypeAliasNodeParser(typeChecker, chainNodeParser)))))
@@ -1,9 +1,9 @@
1
+ import { globSync } from "glob";
1
2
  import * as path from "node:path";
2
3
  import normalize from "normalize-path";
3
- import ts from "typescript";
4
+ import ts, { CompilerOptions } from "typescript";
4
5
  import type { CompletedConfig, Config } from "../src/Config.js";
5
6
  import { BuildError } from "../src/Error/Errors.js";
6
- import { globSync } from "glob";
7
7
 
8
8
  function loadTsConfigFile(configFile: string) {
9
9
  const raw = ts.sys.readFile(configFile);
@@ -55,10 +55,13 @@ function getTsConfig(config: Config) {
55
55
  noEmit: true,
56
56
  emitDecoratorMetadata: true,
57
57
  experimentalDecorators: true,
58
- target: ts.ScriptTarget.ES5,
58
+ target: ts.ScriptTarget.ES2022,
59
59
  module: ts.ModuleKind.CommonJS,
60
60
  strictNullChecks: false,
61
- },
61
+ skipLibCheck: true,
62
+ skipDefaultLibCheck: true,
63
+ esModuleInterop: true,
64
+ } satisfies CompilerOptions,
62
65
  };
63
66
  }
64
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-json-schema-generator",
3
- "version": "2.4.1--canary.2306.1ddde9f.0",
3
+ "version": "2.4.1--canary.2413.e57678e.0",
4
4
  "description": "Generate JSON schema from your Typescript sources",
5
5
  "keywords": [
6
6
  "ts",
@@ -49,16 +49,17 @@
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": "jest test/ --verbose",
53
- "test:coverage": "npm run jest -- test/ --collectCoverage=true",
54
- "test:fast": "cross-env FAST_TEST=1 jest test/ --verbose",
52
+ "test": "tsx --test \"test/**/*.test.ts\"",
53
+ "test:coverage": "c8 --reporter lcov --reporter text npm run test",
54
+ "test:fast": "cross-env FAST_TEST=1 npm run test",
55
55
  "test:update": "cross-env UPDATE_SCHEMA=true npm run test:fast",
56
56
  "watch": "tsc -w"
57
57
  },
58
58
  "dependencies": {
59
59
  "@types/json-schema": "^7.0.15",
60
+ "@typescript/vfs": "1.6.2",
60
61
  "commander": "^14.0.0",
61
- "glob": "^11.0.3",
62
+ "glob": "^13.0.0",
62
63
  "json5": "^2.2.3",
63
64
  "normalize-path": "^3.0.0",
64
65
  "safe-stable-stringify": "^2.5.0",
@@ -73,21 +74,20 @@
73
74
  "@babel/preset-typescript": "^7.27.1",
74
75
  "@eslint/js": "^9.30.1",
75
76
  "@types/eslint": "^9.6.1",
76
- "@types/jest": "^30.0.0",
77
77
  "@types/node": "^24.0.10",
78
78
  "@types/normalize-path": "^3.0.2",
79
79
  "ajv": "^8.17.1",
80
80
  "ajv-formats": "^3.0.1",
81
81
  "auto": "^11.3.0",
82
- "chai": "^5.2.0",
83
- "cross-env": "^7.0.3",
84
- "eslint": "9.30.1",
82
+ "c8": "^10.1.3",
83
+ "chai": "^6.0.1",
84
+ "cross-env": "^10.0.0",
85
+ "eslint": "9.39.1",
85
86
  "eslint-config-prettier": "^10.1.5",
86
87
  "eslint-plugin-prettier": "^5.5.1",
87
88
  "globals": "^16.3.0",
88
- "jest": "^30.0.4",
89
- "jest-junit": "^16.0.0",
90
89
  "prettier": "^3.6.2",
90
+ "try": "^1.0.1",
91
91
  "tsx": "^4.20.3",
92
92
  "typescript-eslint": "^8.35.1",
93
93
  "vega": "^6.1.2",
package/src/Config.ts CHANGED
@@ -1,29 +1,149 @@
1
+ import type ts from "typescript";
2
+
1
3
  export interface Config {
4
+ /**
5
+ * Glob pattern(s) for source TypeScript files to process.
6
+ * If not provided, falls back to files from tsconfig.
7
+ */
2
8
  path?: string;
9
+
10
+ /**
11
+ * Name of the type/interface to generate schema for.
12
+ * Use "*" to generate schemas for all exported types.
13
+ */
3
14
  type?: string;
15
+
16
+ /**
17
+ * Minify the output JSON schema (no whitespace).
18
+ * When false, the schema is pretty-printed with 2-space indentation.
19
+ * @default false
20
+ */
4
21
  minify?: boolean;
22
+
23
+ /**
24
+ * Sets the `$id` property in the root of the generated schema.
25
+ * Used for schema identification and referencing.
26
+ */
5
27
  schemaId?: string;
28
+
29
+ /**
30
+ * Path to a custom tsconfig.json file for TypeScript compilation.
31
+ * If not provided, uses default TypeScript configuration.
32
+ */
6
33
  tsconfig?: string;
34
+
35
+ /**
36
+ * Controls which types are exposed as definitions in the schema.
37
+ * - "all": Exposes all types except type literals
38
+ * - "none": Exposes no types automatically
39
+ * - "export": Only exposes exported types (respects @internal JSDoc tag)
40
+ * @default "export"
41
+ */
7
42
  expose?: "all" | "none" | "export";
43
+
44
+ /**
45
+ * Wraps the root type in a `$ref` definition.
46
+ * When false, inlines the root type definition directly.
47
+ * @default true
48
+ */
8
49
  topRef?: boolean;
50
+
51
+ /**
52
+ * Controls how JSDoc comments are parsed and included in the schema.
53
+ * - "none": Ignores all JSDoc annotations
54
+ * - "basic": Parses standard JSON Schema JSDoc tags
55
+ * - "extended": Parses all tags plus descriptions, examples, and type overrides
56
+ * @default "extended"
57
+ */
9
58
  jsDoc?: "none" | "extended" | "basic";
59
+
60
+ /**
61
+ * Adds a `markdownDescription` field alongside `description` in the schema.
62
+ * Preserves markdown formatting including newlines.
63
+ * Only works with `jsDoc: "extended"`.
64
+ * @default false
65
+ */
10
66
  markdownDescription?: boolean;
67
+
68
+ /**
69
+ * Includes the complete raw JSDoc comment as `fullDescription` in the schema.
70
+ * Only works with `jsDoc: "extended"`.
71
+ * @default false
72
+ */
11
73
  fullDescription?: boolean;
74
+
75
+ /**
76
+ * Sorts object properties alphabetically in the output.
77
+ * @default true
78
+ */
12
79
  sortProps?: boolean;
80
+
81
+ /**
82
+ * Controls whether tuples allow additional items beyond their defined length.
83
+ * @default false
84
+ */
13
85
  strictTuples?: boolean;
86
+
87
+ /**
88
+ * Skips TypeScript type checking to improve performance.
89
+ * Speeds up generation but may miss type errors.
90
+ * @default false
91
+ */
14
92
  skipTypeCheck?: boolean;
93
+
94
+ /**
95
+ * URI-encodes `$ref` values (e.g., `#/definitions/Foo%3CBar%3E`).
96
+ * When false, uses raw names in reference paths.
97
+ * @default true
98
+ */
15
99
  encodeRefs?: boolean;
100
+
101
+ /**
102
+ * Array of additional JSDoc tag names to include in the schema.
103
+ * Custom tags (e.g., `@customProperty`) are parsed and included in output.
104
+ * Values are parsed as JSON5.
105
+ * @default []
106
+ */
16
107
  extraTags?: string[];
108
+
109
+ /**
110
+ * Sets default value for `additionalProperties` on objects without index signatures.
111
+ * When false, objects get `additionalProperties: false` by default.
112
+ * When true, allows additional properties on all objects.
113
+ * @default false
114
+ */
17
115
  additionalProperties?: boolean;
116
+
117
+ /**
118
+ * Controls discriminator style for discriminated unions.
119
+ * - "json-schema": Uses `if`/`then`/`allOf` with properties containing discriminator enum
120
+ * - "open-api": Uses OpenAPI 3.x style with `discriminator: { propertyName }` and `oneOf`
121
+ * @default "json-schema"
122
+ */
18
123
  discriminatorType?: "json-schema" | "open-api";
124
+
125
+ /**
126
+ * Controls how function types are handled in the schema.
127
+ * - "fail": Throws error when encountering function types
128
+ * - "comment": Generates schema with `$comment` describing the function signature
129
+ * - "hide": Treats functions as NeverType (excluded from schema)
130
+ * @default "comment"
131
+ */
19
132
  functions?: FunctionOptions;
133
+
134
+ /**
135
+ * Pre-compiled TypeScript Program instance to use.
136
+ * Bypasses the default setup of a TypeScript program, and so some configuration options may not be applied.
137
+ * Useful for programmatic usage with existing TypeScript compilation, or for vfs scenarios where you do not want file-system representation.
138
+ */
139
+ tsProgram?: ts.Program;
20
140
  }
21
141
 
22
142
  export type CompletedConfig = Config & typeof DEFAULT_CONFIG;
23
143
 
24
144
  export type FunctionOptions = "fail" | "comment" | "hide";
25
145
 
26
- export const DEFAULT_CONFIG: Omit<Required<Config>, "path" | "type" | "schemaId" | "tsconfig"> = {
146
+ export const DEFAULT_CONFIG: Omit<Required<Config>, "path" | "type" | "schemaId" | "tsconfig" | "tsProgram"> = {
27
147
  expose: "export",
28
148
  topRef: true,
29
149
  jsDoc: "extended",
@@ -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,46 @@
1
+ import ts from "typescript";
2
+ import type { NodeParser } from "../NodeParser.js";
3
+ import { Context } from "../NodeParser.js";
4
+ import type { SubNodeParser } from "../SubNodeParser.js";
5
+ import type { BaseType } from "../Type/BaseType.js";
6
+ import { UnknownNodeError } from "../Error/Errors.js";
7
+
8
+ export class NewExpressionParser implements SubNodeParser {
9
+ public constructor(
10
+ protected typeChecker: ts.TypeChecker,
11
+ protected childNodeParser: NodeParser,
12
+ ) {}
13
+
14
+ public supportsNode(node: ts.NewExpression): boolean {
15
+ return node.kind === ts.SyntaxKind.NewExpression;
16
+ }
17
+
18
+ public createType(node: ts.NewExpression, context: Context): BaseType {
19
+ const type = this.typeChecker.getTypeAtLocation(node);
20
+
21
+ const symbol = type.symbol || type.aliasSymbol;
22
+
23
+ const decl =
24
+ this.typeChecker.typeToTypeNode(type, node, ts.NodeBuilderFlags.IgnoreErrors) ||
25
+ symbol?.valueDeclaration ||
26
+ symbol?.declarations?.[0];
27
+
28
+ if (!decl) {
29
+ throw new UnknownNodeError(node);
30
+ }
31
+
32
+ return this.childNodeParser.createType(decl, this.createSubContext(node, context));
33
+ }
34
+
35
+ protected createSubContext(node: ts.NewExpression, parentContext: Context): Context {
36
+ const subContext = new Context(node);
37
+
38
+ if (node.arguments) {
39
+ for (const arg of node.arguments) {
40
+ const type = this.childNodeParser.createType(arg, parentContext);
41
+ subContext.pushArgument(type);
42
+ }
43
+ }
44
+ return subContext;
45
+ }
46
+ }
@@ -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: boolean,
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: Definition[] | undefined = (def.oneOf as Definition[]) || def.anyOf;
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") {