@flink-app/ts-source-to-json-schema 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,574 @@
1
+ # ts-to-jsonschema
2
+
3
+ A zero-dependency TypeScript-to-JSON Schema converter that uses its own mini-parser instead of the TypeScript compiler.
4
+
5
+ It parses TypeScript type declarations (interfaces, type aliases, enums) directly from source strings and emits JSON Schema (2020-12 draft). No `ts.createProgram`, no `node_modules` bloat, no compiler startup cost.
6
+
7
+ ## Why
8
+
9
+ Existing tools like `ts-json-schema-generator` and `typescript-json-schema` rely on the full TypeScript compiler API to resolve types. That works, but it's slow, heavy, and ties you to Node.js. Furthermore, these libraries might need significant rewrites when TypeScript 7 (tsgo) is released, making their long-term future uncertain.
10
+
11
+ This library takes a different approach: instead of running the type checker, it tokenizes and parses a **practical subset** of TypeScript's type syntax directly. The result is a tool that's fast enough to run in a hot path, portable enough to run anywhere (Cloudflare Workers, browser, CLI), and simple enough to extend.
12
+
13
+ The trade-off is explicit: it handles the type constructs you'd actually use in API contracts, tool schemas, and config definitions — not the full type-level programming language.
14
+
15
+ ## What it handles
16
+
17
+ - **Declarations**: `interface`, `type`, `enum` (string + numeric), `export`
18
+ - **Primitives**: `string`, `number`, `boolean`, `null`, `undefined`, `any`, `unknown`, `never`, `void`, `bigint`
19
+ - **Built-in types**: `Date` → `{ type: "string", format: "date-time" }`
20
+ - **Literal types**: `"active"`, `42`, `true`
21
+ - **Unions**: `A | B | C` → `anyOf` (or `enum` when all members are literals)
22
+ - **Intersections**: `A & B` → `allOf`
23
+ - **Arrays**: `T[]`, `Array<T>`, nested `T[][]`
24
+ - **Tuples**: `[string, number]` → `prefixItems`
25
+ - **Nullable**: `string | null` → `type: ["string", "null"]`
26
+ - **Nested objects**: inline `{ foo: string }` and cross-references via `$ref`
27
+ - **Self-referential types**: `Task` containing `subtasks: Task[]`
28
+ - **Interface extends**: `interface Dog extends Animal` → `allOf`
29
+ - **Index signatures**: `[key: string]: T` → `additionalProperties`
30
+ - **Utility types**: `Partial<T>`, `Required<T>`, `Pick<T, K>`, `Omit<T, K>`, `Record<K, V>`, `Readonly<T>`, `Set<T>`, `Map<K, V>`, `Promise<T>` (unwrapped)
31
+ - **Local imports**: Automatic resolution of relative imports (`./` and `../`) across files
32
+ - **JSDoc**: `/** description */` → `description`, plus tags: `@minimum`, `@maximum`, `@minLength`, `@maxLength`, `@pattern`, `@format`, `@default`, `@deprecated`, `@title`, `@example`, `@additionalProperties`
33
+ - **Readonly**: `readonly` → `readOnly` in schema
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ npm install ts-source-to-json-schema
39
+ ```
40
+
41
+ ## CLI Usage
42
+
43
+ The package includes a command-line tool for converting TypeScript files to JSON Schema:
44
+
45
+ ```bash
46
+ # Convert a TypeScript file
47
+ npx ts-source-to-json-schema src/types.ts
48
+
49
+ # Convert with automatic import resolution (default)
50
+ npx ts-source-to-json-schema src/api.ts
51
+
52
+ # Convert a specific type as the root schema
53
+ npx ts-source-to-json-schema src/api.ts --rootType ApiResponse
54
+
55
+ # Use strict mode (no additional properties allowed)
56
+ npx ts-source-to-json-schema src/config.ts --strictObjects
57
+
58
+ # Disable JSDoc processing
59
+ npx ts-source-to-json-schema src/types.ts --includeJSDoc false
60
+
61
+ # Single file mode, no imports
62
+ npx ts-source-to-json-schema src/types.ts --followImports none
63
+
64
+ # Combine multiple options
65
+ npx ts-source-to-json-schema src/user.ts -r User --strictObjects --followImports local
66
+ ```
67
+
68
+ ### CLI Options
69
+
70
+ ```
71
+ -h, --help Show help message
72
+ -v, --version Show version number
73
+ --doctor Output diagnostic information for debugging
74
+
75
+ -r, --rootType <name> Emit this type as root (others in $defs)
76
+ -s, --includeSchema <bool> Include $schema property (default: true)
77
+ --schemaVersion <url> Custom $schema URL
78
+ --strictObjects Set additionalProperties: false globally
79
+ --additionalProperties Set additionalProperties default (true/false)
80
+ --includeJSDoc <bool> Include JSDoc comments (default: true)
81
+
82
+ --followImports <mode> Follow imports: none, local, all (default: local)
83
+ --baseDir <path> Base directory for resolving imports
84
+ ```
85
+
86
+ The CLI reads TypeScript files and outputs JSON Schema to stdout, making it easy to pipe to files or other tools:
87
+
88
+ ```bash
89
+ # Save to file
90
+ npx ts-source-to-json-schema src/types.ts > schema.json
91
+
92
+ # Pretty-print with jq
93
+ npx ts-source-to-json-schema src/types.ts | jq '.'
94
+
95
+ # Use in scripts
96
+ npx ts-source-to-json-schema src/api.ts --rootType Request > openapi/request-schema.json
97
+ ```
98
+
99
+ ### Multi-File Support (`--followImports`)
100
+
101
+ By default, the CLI automatically follows local relative imports (`./` and `../`) to resolve type definitions across multiple files:
102
+
103
+ ```typescript
104
+ // pet.ts
105
+ export interface Pet {
106
+ _id: string;
107
+ name: string;
108
+ species: string;
109
+ }
110
+
111
+ // api.ts
112
+ import { Pet } from './pet';
113
+ export interface PostPetReq extends Omit<Pet, "_id"> {}
114
+ ```
115
+
116
+ ```bash
117
+ # Follows imports and resolves Pet type (default behavior)
118
+ npx ts-source-to-json-schema api.ts --rootType PostPetReq
119
+
120
+ # Output includes both Pet (in $defs) and PostPetReq (as root)
121
+ ```
122
+
123
+ **Import Resolution Modes:**
124
+ - `local` (default in CLI): Follows relative imports (`./` and `../`), skips `node_modules`
125
+ - `none`: Single-file mode, does not follow any imports
126
+ - `all`: Reserved for future `node_modules` support (currently behaves like `local`)
127
+
128
+ **Key Features:**
129
+ - Circular dependency detection (no infinite loops)
130
+ - Duplicate name detection (errors if same type name in multiple files)
131
+ - Automatic extension resolution (`.ts`, `.tsx`, `.d.ts`)
132
+ - Index file support (`./types` → `./types/index.ts`)
133
+
134
+ **Examples:**
135
+
136
+ ```bash
137
+ # Multi-file project with local imports
138
+ npx ts-source-to-json-schema src/api.ts --followImports local
139
+
140
+ # Single file only, ignore imports
141
+ npx ts-source-to-json-schema src/standalone.ts --followImports none
142
+
143
+ # Custom base directory for import resolution
144
+ npx ts-source-to-json-schema src/api.ts --baseDir ./src
145
+ ```
146
+
147
+ ### Diagnostics Mode (`--doctor`)
148
+
149
+ When you encounter issues with schema conversion, use the `--doctor` flag to output comprehensive diagnostic information that can be shared with developers:
150
+
151
+ ```bash
152
+ npx ts-source-to-json-schema src/problematic-types.ts --doctor
153
+ ```
154
+
155
+ The doctor output includes:
156
+ - **Timestamp**: When the conversion was attempted
157
+ - **Environment**: Node.js version, platform, architecture, and current working directory
158
+ - **Input file details**: Path, existence, size, modification time, source length, and full source code
159
+ - **Options used**: All configuration options passed to the converter
160
+ - **Conversion result**: Either the successfully generated schema or detailed error information with stack traces
161
+
162
+ This makes it easy to:
163
+ 1. Copy-paste the full diagnostic output when reporting issues
164
+ 2. Debug why a particular TypeScript file isn't converting as expected
165
+ 3. Share reproducible examples with maintainers
166
+
167
+ **Example output:**
168
+ ```json
169
+ {
170
+ "timestamp": "2026-02-25T10:50:55.680Z",
171
+ "environment": {
172
+ "nodeVersion": "v20.17.0",
173
+ "platform": "darwin",
174
+ "arch": "arm64",
175
+ "cwd": "/path/to/project"
176
+ },
177
+ "input": {
178
+ "filePath": "types.ts",
179
+ "absolutePath": "/absolute/path/to/types.ts",
180
+ "fileExists": true,
181
+ "fileSize": 486,
182
+ "sourceLength": 486,
183
+ "source": "interface User { ... }"
184
+ },
185
+ "options": { "rootType": "User" },
186
+ "conversionResult": {
187
+ "success": true,
188
+ "schema": { ... }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ## Programmatic Usage
194
+
195
+ ### String-Based API
196
+
197
+ ```typescript
198
+ import { toJsonSchema } from "ts-source-to-json-schema";
199
+
200
+ const schema = toJsonSchema(`
201
+ /** Input for the ad analysis tool */
202
+ interface AnalyzeAdInput {
203
+ /** URL of the ad to analyze */
204
+ url: string;
205
+ /** Platform the ad is from */
206
+ platform: "instagram" | "facebook" | "tiktok";
207
+ /** Whether to extract color palette */
208
+ extractColors?: boolean;
209
+ /** Max elements to identify
210
+ * @minimum 1
211
+ * @maximum 50
212
+ * @default 10
213
+ */
214
+ maxElements?: number;
215
+ tags: string[];
216
+ }
217
+ `, { rootType: "AnalyzeAdInput" });
218
+ ```
219
+
220
+ ### File-Based API with Import Resolution
221
+
222
+ ```typescript
223
+ import { toJsonSchemaFromFile } from "ts-source-to-json-schema";
224
+
225
+ // Convert a TypeScript file with automatic import resolution
226
+ const schema = toJsonSchemaFromFile('./src/types/api.ts', {
227
+ followImports: 'local', // Follow relative imports
228
+ rootType: 'ApiRequest',
229
+ strictObjects: true
230
+ });
231
+
232
+ // Single-file mode (no import resolution)
233
+ const singleFileSchema = toJsonSchemaFromFile('./src/types.ts', {
234
+ followImports: 'none'
235
+ });
236
+ ```
237
+
238
+ ### Batch Schema Generation
239
+
240
+ When you need schemas for multiple types from the same source file, use `toJsonSchemas()` (plural) for better performance. This is particularly useful for build tools, documentation generators, or API schema validators that process many types at once.
241
+
242
+ ```typescript
243
+ import { toJsonSchemas } from "ts-source-to-json-schema";
244
+
245
+ const source = `
246
+ export interface User { id: string; name: string; }
247
+ export interface Post { id: string; title: string; author: User; }
248
+ export interface Comment { id: string; text: string; }
249
+ `;
250
+
251
+ // Generate all schemas at once (~70% faster than calling toJsonSchema() for each type)
252
+ const schemas = toJsonSchemas(source);
253
+
254
+ console.log(schemas.User); // Standalone User schema
255
+ console.log(schemas.Post); // Post schema with User in definitions
256
+ console.log(schemas.Comment); // Standalone Comment schema
257
+ ```
258
+
259
+ **Key benefits:**
260
+ - **Performance**: ~70% faster when generating 30+ schemas from the same source
261
+ - **Single parse**: Source is tokenized and parsed only once
262
+ - **Standalone schemas**: Each schema includes only the types it references in its `definitions` field
263
+ - **Self-contained**: Each schema includes `$schema` field by default for better IDE validation
264
+ - **Draft-07 compatible**: Uses `definitions` instead of `$defs` for broader compatibility
265
+
266
+ **How it works:**
267
+ - Parses the source once and emits all type declarations
268
+ - Each schema is standalone with minimal `definitions` (only transitively referenced types)
269
+ - Uses `#/definitions/TypeName` refs instead of `#/$defs/TypeName`
270
+ - Handles circular references, transitive dependencies, and utility types
271
+
272
+ **Use cases:**
273
+ - Framework integrations (like Flink) that need many schemas from one source
274
+ - Build tools generating schemas for entire API definition files
275
+ - Documentation generators processing large type files
276
+ - Schema validation libraries caching multiple schemas
277
+
278
+ **Example with real-world API:**
279
+ ```typescript
280
+ const schemas = toJsonSchemas(`
281
+ interface User { id: string; name: string; }
282
+ interface CreateUserRequest { name: string; }
283
+ interface CreateUserResponse { user: User; }
284
+ interface GetUserRequest { id: string; }
285
+ interface GetUserResponse { user: User; }
286
+ `, { includeJSDoc: true, strictObjects: true });
287
+
288
+ // Extract specific schemas as needed
289
+ const requestSchemas = {
290
+ CreateUser: schemas.CreateUserRequest,
291
+ GetUser: schemas.GetUserRequest
292
+ };
293
+ ```
294
+
295
+ #### Batch Generation with Import Resolution
296
+
297
+ If your types are spread across multiple files with imports, use `toJsonSchemasFromFile()` (the file-based batch API):
298
+
299
+ ```typescript
300
+ import { toJsonSchemasFromFile } from "ts-source-to-json-schema";
301
+
302
+ // Intermediate schema file (e.g., generated by a framework)
303
+ // schemas.ts:
304
+ // import TreeNode from "../../src/schemas/TreeNode";
305
+ // import Car from "../../src/schemas/Car";
306
+ // export interface GetTree_12_ResSchema extends TreeNode {}
307
+ // export interface GetCar_10_ResSchema extends Car {}
308
+
309
+ const schemas = toJsonSchemasFromFile('./schemas.ts', {
310
+ followImports: 'local', // Resolve relative imports
311
+ strictObjects: true
312
+ });
313
+
314
+ console.log(schemas.GetTree_12_ResSchema);
315
+ // {
316
+ // "$ref": "#/definitions/TreeNode",
317
+ // "definitions": {
318
+ // "TreeNode": { "type": "object", ... } // ✅ Included from imported file!
319
+ // }
320
+ // }
321
+ ```
322
+
323
+ **Why use `toJsonSchemasFromFile()`?**
324
+ - Automatically resolves imports from local files
325
+ - Generates batch schemas for all types (like `toJsonSchemas()`)
326
+ - Handles circular dependencies across files
327
+ - Perfect for framework integrations (like Flink) with generated intermediate files
328
+
329
+ **Performance:** Same batch performance benefits as `toJsonSchemas()`, plus automatic import resolution.
330
+
331
+ Output:
332
+
333
+ ```json
334
+ {
335
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
336
+ "type": "object",
337
+ "description": "Input for the ad analysis tool",
338
+ "properties": {
339
+ "url": { "type": "string", "description": "URL of the ad to analyze" },
340
+ "platform": {
341
+ "type": "string",
342
+ "enum": ["instagram", "facebook", "tiktok"],
343
+ "description": "Platform the ad is from"
344
+ },
345
+ "extractColors": { "type": "boolean", "description": "Whether to extract color palette" },
346
+ "maxElements": {
347
+ "type": "number",
348
+ "description": "Max elements to identify",
349
+ "minimum": 1,
350
+ "maximum": 50,
351
+ "default": 10
352
+ },
353
+ "tags": { "type": "array", "items": { "type": "string" } }
354
+ },
355
+ "required": ["url", "platform", "tags"]
356
+ }
357
+ ```
358
+
359
+ ## Options
360
+
361
+ ```typescript
362
+ toJsonSchema(source, {
363
+ rootType: "MyType", // Emit this type as the root schema (others go in $defs)
364
+ includeSchema: true, // Include $schema field (default: true)
365
+ strictObjects: false, // Set additionalProperties: false on all objects
366
+ schemaVersion: "https://json-schema.org/draft/2020-12/schema",
367
+ includeJSDoc: true, // Include JSDoc descriptions and tags (default: true)
368
+ additionalProperties: undefined, // Default value for additionalProperties (undefined, true, or false)
369
+ });
370
+
371
+ toJsonSchemaFromFile(filePath, {
372
+ // All options from toJsonSchema, plus:
373
+ followImports: 'local', // Follow imports: 'none' (default for API), 'local' (default for CLI), 'all'
374
+ baseDir: './src', // Base directory for resolving imports (default: dirname(filePath))
375
+ });
376
+
377
+ toJsonSchemasFromFile(filePath, {
378
+ // All options from toJsonSchemas, plus:
379
+ followImports: 'local', // Follow imports: 'none', 'local' (default), 'all'
380
+ baseDir: './src', // Base directory for resolving imports (default: dirname(filePath))
381
+ // Note: rootType is not supported (generates schemas for all types)
382
+ });
383
+ ```
384
+
385
+ ### `includeJSDoc` (optional)
386
+ - **Type:** `boolean`
387
+ - **Default:** `true`
388
+ - **Description:** Controls whether JSDoc comments are processed and included in the schema
389
+
390
+ When `true` (default):
391
+ - Interface/type descriptions are extracted from JSDoc comments
392
+ - Property descriptions are included
393
+ - JSDoc tags like `@minimum`, `@maximum`, `@pattern` are applied as constraints
394
+
395
+ When `false`:
396
+ - All JSDoc comments are ignored
397
+ - Schema only contains structural information (types, properties, required fields)
398
+ - Useful for generating minimal schemas or when descriptions aren't needed
399
+
400
+ **Example:**
401
+ ```typescript
402
+ const schema = toJsonSchema(`
403
+ /** User profile */
404
+ interface User {
405
+ /** @minLength 1 */
406
+ name: string;
407
+ }
408
+ `, { rootType: 'User', includeJSDoc: false });
409
+
410
+ // Result: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] }
411
+ // No description or minLength constraint
412
+ ```
413
+
414
+ ### `includeSchema` (optional)
415
+ - **Type:** `boolean`
416
+ - **Default:** `true`
417
+ - **Description:** Controls whether the `$schema` field is included in generated schemas
418
+
419
+ When `true` (default):
420
+ - Each generated schema includes a `$schema` field pointing to the JSON Schema specification
421
+ - Makes schemas self-contained and improves IDE validation support
422
+ - Uses the URL from `schemaVersion` option (default: `https://json-schema.org/draft/2020-12/schema`)
423
+
424
+ When `false`:
425
+ - The `$schema` field is omitted from all generated schemas
426
+ - Useful when embedding schemas in larger documents or when the schema version is managed elsewhere
427
+
428
+ **Example:**
429
+ ```typescript
430
+ const schema = toJsonSchema(`
431
+ interface User {
432
+ name: string;
433
+ }
434
+ `, { rootType: 'User', includeSchema: true });
435
+
436
+ // Result includes: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: 'object', ... }
437
+ ```
438
+
439
+ **Batch generation:** The `toJsonSchemas()` function also respects this option and includes `$schema` in each generated schema by default.
440
+
441
+ ### `schemaVersion` (optional)
442
+ - **Type:** `string`
443
+ - **Default:** `"https://json-schema.org/draft/2020-12/schema"`
444
+ - **Description:** Specifies the JSON Schema draft version URL
445
+
446
+ Use this to generate schemas compatible with different JSON Schema drafts:
447
+
448
+ ```typescript
449
+ // Generate draft-07 compatible schema
450
+ const schema = toJsonSchema(`interface User { name: string; }`, {
451
+ rootType: 'User',
452
+ schemaVersion: 'http://json-schema.org/draft-07/schema#'
453
+ });
454
+
455
+ // Result includes: { "$schema": "http://json-schema.org/draft-07/schema#", ... }
456
+ ```
457
+
458
+ **Note:** This library always generates draft-2020-12 compatible schemas. The `schemaVersion` option only changes the `$schema` field value. For maximum compatibility with draft-07 validators, use `toJsonSchemas()` which uses `definitions` instead of `$defs`.
459
+
460
+ ### `additionalProperties` (optional)
461
+ - **Type:** `boolean | undefined`
462
+ - **Default:** `undefined`
463
+ - **Description:** Sets the default value for `additionalProperties` on all object schemas
464
+
465
+ This option provides a global default for `additionalProperties` when not explicitly set via JSDoc or index signatures.
466
+
467
+ **Precedence (highest to lowest):**
468
+ 1. Index signature: `[key: string]: T` → `additionalProperties: T`
469
+ 2. JSDoc `@additionalProperties` tag
470
+ 3. `strictObjects` option
471
+ 4. `additionalProperties` option
472
+ 5. Not set (JSON Schema default behavior)
473
+
474
+ **Example:**
475
+ ```typescript
476
+ // Set all objects to disallow additional properties by default
477
+ const schema = toJsonSchema(`
478
+ interface User {
479
+ name: string;
480
+ }
481
+ `, { rootType: 'User', additionalProperties: false });
482
+
483
+ // Result: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'], additionalProperties: false }
484
+ ```
485
+
486
+ ### `@additionalProperties` JSDoc Tag
487
+
488
+ Control `additionalProperties` on specific types or properties using the `@additionalProperties` JSDoc tag.
489
+
490
+ **Supported values:** `true` | `false` (case-insensitive)
491
+
492
+ **Usage at interface/type level:**
493
+ ```typescript
494
+ /**
495
+ * Strict configuration object
496
+ * @additionalProperties false
497
+ */
498
+ interface Config {
499
+ host: string;
500
+ port: number;
501
+ }
502
+ // Result: { type: 'object', properties: {...}, additionalProperties: false }
503
+ ```
504
+
505
+ **Usage at property level:**
506
+ ```typescript
507
+ interface Settings {
508
+ /**
509
+ * Database configuration
510
+ * @additionalProperties false
511
+ */
512
+ database: {
513
+ host: string;
514
+ port: number;
515
+ };
516
+ }
517
+ // Result: database property has additionalProperties: false
518
+ ```
519
+
520
+ **Interaction with other options:**
521
+ - When `includeJSDoc: false`, the tag is ignored
522
+ - The tag overrides the global `additionalProperties` and `strictObjects` options
523
+ - Index signatures take precedence over the tag
524
+
525
+ ### `followImports` (optional)
526
+ - **Type:** `"none" | "local" | "all"`
527
+ - **Default:** `"none"` (programmatic API), `"local"` (CLI)
528
+ - **Description:** Controls import resolution across multiple TypeScript files
529
+
530
+ **Modes:**
531
+ - `none`: Single-file mode, imports are ignored
532
+ - `local`: Follows relative imports (`./` and `../`), skips `node_modules`
533
+ - `all`: Reserved for future `node_modules` support (currently behaves like `local`)
534
+
535
+ **Only available with file-based APIs** (`toJsonSchemaFromFile()` and `toJsonSchemasFromFile()`) — the string-based APIs (`toJsonSchema()` and `toJsonSchemas()`) do not support import resolution.
536
+
537
+ **Example:**
538
+ ```typescript
539
+ // Given: pet.ts exports Pet interface
540
+ // Given: api.ts imports Pet and uses it in PostPetReq
541
+
542
+ const schema = toJsonSchemaFromFile('./api.ts', {
543
+ followImports: 'local',
544
+ rootType: 'PostPetReq'
545
+ });
546
+
547
+ // Result: Schema includes both Pet (in $defs) and PostPetReq
548
+ ```
549
+
550
+ **Features:**
551
+ - Circular dependency detection (prevents infinite loops)
552
+ - Duplicate name detection (throws error if same type appears in multiple files)
553
+ - Automatic extension resolution (`.ts`, `.tsx`, `.d.ts`)
554
+ - Index file resolution (`./types` → `./types/index.ts`)
555
+
556
+ ### `baseDir` (optional)
557
+ - **Type:** `string`
558
+ - **Default:** `path.dirname(filePath)`
559
+ - **Description:** Base directory for resolving relative imports
560
+
561
+ Only relevant when `followImports` is not `"none"`.
562
+
563
+ ## What it doesn't handle
564
+
565
+ Anything that requires the type checker to evaluate:
566
+
567
+ - Conditional types (`T extends U ? X : Y`)
568
+ - Mapped types (`{ [K in keyof T]: ... }`)
569
+ - Template literal types (`` `${A}-${B}` ``)
570
+ - `typeof`, `keyof`, `infer`
571
+ - Generics (user-defined, beyond the built-in utility types)
572
+ - `node_modules` imports (planned for future)
573
+
574
+ If you need these, use `ts-json-schema-generator`. If your types look like API contracts and tool definitions, this is probably all you need.
package/dist/ast.d.ts ADDED
@@ -0,0 +1,102 @@
1
+ /** A property in an object/interface type */
2
+ export interface PropertyNode {
3
+ name: string;
4
+ type: TypeNode;
5
+ optional: boolean;
6
+ readonly: boolean;
7
+ description?: string;
8
+ tags?: Record<string, string>;
9
+ }
10
+ /** Index signature: [key: string]: ValueType */
11
+ export interface IndexSignatureNode {
12
+ keyType: TypeNode;
13
+ valueType: TypeNode;
14
+ }
15
+ /** All possible type AST nodes */
16
+ export type TypeNode = {
17
+ kind: "primitive";
18
+ value: "string" | "number" | "boolean" | "null" | "undefined" | "any" | "unknown" | "never" | "void" | "object" | "bigint";
19
+ } | {
20
+ kind: "literal_string";
21
+ value: string;
22
+ } | {
23
+ kind: "literal_number";
24
+ value: number;
25
+ } | {
26
+ kind: "literal_boolean";
27
+ value: boolean;
28
+ } | {
29
+ kind: "object";
30
+ properties: PropertyNode[];
31
+ indexSignature?: IndexSignatureNode;
32
+ } | {
33
+ kind: "array";
34
+ element: TypeNode;
35
+ } | {
36
+ kind: "tuple";
37
+ elements: TupleElement[];
38
+ } | {
39
+ kind: "union";
40
+ members: TypeNode[];
41
+ } | {
42
+ kind: "intersection";
43
+ members: TypeNode[];
44
+ } | {
45
+ kind: "reference";
46
+ name: string;
47
+ typeArgs?: TypeNode[];
48
+ } | {
49
+ kind: "parenthesized";
50
+ inner: TypeNode;
51
+ } | {
52
+ kind: "template_literal";
53
+ parts: (string | TypeNode)[];
54
+ } | {
55
+ kind: "record";
56
+ keyType: TypeNode;
57
+ valueType: TypeNode;
58
+ } | {
59
+ kind: "mapped";
60
+ keyName: string;
61
+ constraint: TypeNode;
62
+ valueType: TypeNode;
63
+ optional?: boolean;
64
+ };
65
+ export interface TupleElement {
66
+ type: TypeNode;
67
+ optional?: boolean;
68
+ label?: string;
69
+ rest?: boolean;
70
+ }
71
+ /** Top-level declarations we extract from source */
72
+ export type Declaration = InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration;
73
+ export interface InterfaceDeclaration {
74
+ kind: "interface";
75
+ name: string;
76
+ extends?: TypeNode[];
77
+ properties: PropertyNode[];
78
+ indexSignature?: IndexSignatureNode;
79
+ description?: string;
80
+ tags?: Record<string, string>;
81
+ exported: boolean;
82
+ }
83
+ export interface TypeAliasDeclaration {
84
+ kind: "type_alias";
85
+ name: string;
86
+ type: TypeNode;
87
+ description?: string;
88
+ tags?: Record<string, string>;
89
+ exported: boolean;
90
+ }
91
+ export interface EnumDeclaration {
92
+ kind: "enum";
93
+ name: string;
94
+ members: {
95
+ name: string;
96
+ value: string | number;
97
+ }[];
98
+ description?: string;
99
+ tags?: Record<string, string>;
100
+ exported: boolean;
101
+ }
102
+ //# sourceMappingURL=ast.d.ts.map