@type-crafter/mcp 0.5.0 → 1.0.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/README.md +113 -221
- package/dist/docs/RULES_COMPOSITION.md +343 -0
- package/dist/docs/RULES_NULLABLE.md +293 -0
- package/dist/docs/RULES_PATTERNS.md +516 -0
- package/dist/docs/RULES_REFERENCES.md +302 -0
- package/dist/docs/RULES_STRUCTURE.md +248 -0
- package/dist/docs/RULES_TYPES.md +291 -0
- package/dist/docs/WRITING_GUIDE.md +179 -0
- package/dist/index.js +321 -345
- package/package.json +3 -5
- package/src/GUIDE.md +0 -459
- package/src/SPEC_RULES.md +0 -1527
package/src/SPEC_RULES.md
DELETED
|
@@ -1,1527 +0,0 @@
|
|
|
1
|
-
# Type Crafter YAML Specification Rules
|
|
2
|
-
|
|
3
|
-
Complete guide for writing Type Crafter YAML specifications and understanding TypeScript generation.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
- [🚨 Common Mistakes (Read This First)](#-common-mistakes-read-this-first)
|
|
10
|
-
- [Multi-File Specifications](#multi-file-specifications)
|
|
11
|
-
- [Root Structure](#root-structure)
|
|
12
|
-
- [Data Types & Type Mapping](#data-types--type-mapping)
|
|
13
|
-
- [Constraints & Limitations](#constraints--limitations)
|
|
14
|
-
- [Nullable Types (Critical)](#nullable-types-critical)
|
|
15
|
-
- [Type Definitions](#type-definitions)
|
|
16
|
-
- [References](#references)
|
|
17
|
-
- [Composition](#composition)
|
|
18
|
-
- [TypeScript Generation Examples](#typescript-generation-examples)
|
|
19
|
-
- [Best Practices](#best-practices)
|
|
20
|
-
- [Common Patterns](#common-patterns)
|
|
21
|
-
- [Rules Checklist](#rules-checklist)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 🚨 Common Mistakes (Read This First)
|
|
26
|
-
|
|
27
|
-
### ❌ NEVER Do These
|
|
28
|
-
|
|
29
|
-
```yaml
|
|
30
|
-
# ❌ WRONG: Adding 'nullable: true' property
|
|
31
|
-
User:
|
|
32
|
-
type: object
|
|
33
|
-
properties:
|
|
34
|
-
name:
|
|
35
|
-
type: string
|
|
36
|
-
nullable: true # ❌ INVALID! This property does NOT exist
|
|
37
|
-
|
|
38
|
-
# ❌ WRONG: Using 'optional: true' property
|
|
39
|
-
User:
|
|
40
|
-
type: object
|
|
41
|
-
properties:
|
|
42
|
-
name:
|
|
43
|
-
type: string
|
|
44
|
-
optional: true # ❌ INVALID! This property does NOT exist
|
|
45
|
-
|
|
46
|
-
# ❌ WRONG: Using '?' suffix for optional
|
|
47
|
-
User:
|
|
48
|
-
type: object
|
|
49
|
-
properties:
|
|
50
|
-
name?: # ❌ INVALID! Don't use ? suffix
|
|
51
|
-
type: string
|
|
52
|
-
|
|
53
|
-
# ❌ WRONG: Creating top-level array types
|
|
54
|
-
Tags:
|
|
55
|
-
type: array # ❌ INVALID! Arrays cannot be top-level types
|
|
56
|
-
items:
|
|
57
|
-
type: string
|
|
58
|
-
|
|
59
|
-
# ❌ WRONG: Using relative paths from current file
|
|
60
|
-
# File: src/api/users.yaml
|
|
61
|
-
User:
|
|
62
|
-
type: object
|
|
63
|
-
properties:
|
|
64
|
-
profile:
|
|
65
|
-
$ref: './profile.yaml#/Profile' # ❌ WRONG! Not relative to current file
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### ✅ CORRECT Ways
|
|
69
|
-
|
|
70
|
-
```yaml
|
|
71
|
-
# ✅ CORRECT: Use 'required' array to control nullable
|
|
72
|
-
User:
|
|
73
|
-
type: object
|
|
74
|
-
required:
|
|
75
|
-
- id # id is required (NOT nullable)
|
|
76
|
-
# name is NOT in required, so it's nullable
|
|
77
|
-
properties:
|
|
78
|
-
id:
|
|
79
|
-
type: string # Generates: string
|
|
80
|
-
name:
|
|
81
|
-
type: string # Generates: string | null (because not in required)
|
|
82
|
-
|
|
83
|
-
# ✅ CORRECT: Arrays must be properties within objects
|
|
84
|
-
Post:
|
|
85
|
-
type: object
|
|
86
|
-
properties:
|
|
87
|
-
tags:
|
|
88
|
-
type: array
|
|
89
|
-
items:
|
|
90
|
-
type: string
|
|
91
|
-
|
|
92
|
-
# ✅ CORRECT: Use paths from project root
|
|
93
|
-
# File: src/api/users.yaml (running type-crafter from project root)
|
|
94
|
-
User:
|
|
95
|
-
type: object
|
|
96
|
-
properties:
|
|
97
|
-
profile:
|
|
98
|
-
$ref: './src/api/profile.yaml#/Profile' # ✅ From project root
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### 🔑 Key Rules to Remember
|
|
102
|
-
|
|
103
|
-
1. **Nullable is controlled by `required` array ONLY**
|
|
104
|
-
- In `required` → generates `Type`
|
|
105
|
-
- NOT in `required` → generates `Type | null`
|
|
106
|
-
- No properties like `nullable`, `optional`, `?` exist
|
|
107
|
-
|
|
108
|
-
2. **Arrays cannot be top-level types**
|
|
109
|
-
- Arrays MUST be properties within objects
|
|
110
|
-
- Use `type: array` with `items` specification
|
|
111
|
-
|
|
112
|
-
3. **File paths are from project root**
|
|
113
|
-
- NOT relative to current YAML file
|
|
114
|
-
- Always use `./path/from/root/file.yaml#/Type`
|
|
115
|
-
|
|
116
|
-
4. **Every spec file needs `info` section**
|
|
117
|
-
- Even sub-files need `info: { version, title }`
|
|
118
|
-
- Top-level file and all referenced files must have `info`
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Multi-File Specifications
|
|
123
|
-
|
|
124
|
-
### File Organization Patterns
|
|
125
|
-
|
|
126
|
-
#### Pattern 1: Single Top-Level File
|
|
127
|
-
|
|
128
|
-
**Best for:** Small to medium projects
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
project/
|
|
132
|
-
├── types.yaml # Single file with all types
|
|
133
|
-
└── src/
|
|
134
|
-
└── index.ts
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**types.yaml:**
|
|
138
|
-
```yaml
|
|
139
|
-
info:
|
|
140
|
-
version: '1.0.0'
|
|
141
|
-
title: 'Project Types'
|
|
142
|
-
|
|
143
|
-
types:
|
|
144
|
-
User:
|
|
145
|
-
type: object
|
|
146
|
-
properties:
|
|
147
|
-
id: { type: string }
|
|
148
|
-
|
|
149
|
-
Post:
|
|
150
|
-
type: object
|
|
151
|
-
properties:
|
|
152
|
-
author: { $ref: '#/types/User' }
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### Pattern 2: Multiple Files with Main Entry Point
|
|
156
|
-
|
|
157
|
-
**Best for:** Large projects with logical domain separation
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
project/
|
|
161
|
-
├── types/
|
|
162
|
-
│ ├── index.yaml # Main entry point (top-level file)
|
|
163
|
-
│ ├── user.yaml # User-related types (sub-file)
|
|
164
|
-
│ ├── post.yaml # Post-related types (sub-file)
|
|
165
|
-
│ └── comment.yaml # Comment-related types (sub-file)
|
|
166
|
-
└── src/
|
|
167
|
-
└── index.ts
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
**types/index.yaml (Top-level file):**
|
|
171
|
-
```yaml
|
|
172
|
-
info:
|
|
173
|
-
version: '1.0.0'
|
|
174
|
-
title: 'Main API Types'
|
|
175
|
-
|
|
176
|
-
# Import types from other files
|
|
177
|
-
types:
|
|
178
|
-
# Reference to external file (from project root)
|
|
179
|
-
User:
|
|
180
|
-
$ref: './types/user.yaml#/User'
|
|
181
|
-
|
|
182
|
-
Post:
|
|
183
|
-
$ref: './types/post.yaml#/Post'
|
|
184
|
-
|
|
185
|
-
Comment:
|
|
186
|
-
$ref: './types/comment.yaml#/Comment'
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**types/user.yaml (Sub-file):**
|
|
190
|
-
```yaml
|
|
191
|
-
info:
|
|
192
|
-
version: '1.0.0'
|
|
193
|
-
title: 'User Types'
|
|
194
|
-
|
|
195
|
-
types:
|
|
196
|
-
User:
|
|
197
|
-
type: object
|
|
198
|
-
required:
|
|
199
|
-
- id
|
|
200
|
-
- email
|
|
201
|
-
properties:
|
|
202
|
-
id:
|
|
203
|
-
type: string
|
|
204
|
-
email:
|
|
205
|
-
type: string
|
|
206
|
-
name:
|
|
207
|
-
type: string # nullable (not in required)
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
**types/post.yaml (Sub-file):**
|
|
211
|
-
```yaml
|
|
212
|
-
info:
|
|
213
|
-
version: '1.0.0'
|
|
214
|
-
title: 'Post Types'
|
|
215
|
-
|
|
216
|
-
types:
|
|
217
|
-
Post:
|
|
218
|
-
type: object
|
|
219
|
-
required:
|
|
220
|
-
- id
|
|
221
|
-
- title
|
|
222
|
-
- author
|
|
223
|
-
properties:
|
|
224
|
-
id:
|
|
225
|
-
type: string
|
|
226
|
-
title:
|
|
227
|
-
type: string
|
|
228
|
-
author:
|
|
229
|
-
# Reference to user.yaml from project root
|
|
230
|
-
$ref: './types/user.yaml#/User'
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
#### Pattern 3: Grouped Types with External References
|
|
234
|
-
|
|
235
|
-
**Best for:** Complex domains with many related types
|
|
236
|
-
|
|
237
|
-
```
|
|
238
|
-
project/
|
|
239
|
-
├── specs/
|
|
240
|
-
│ ├── api.yaml # Main entry point
|
|
241
|
-
│ ├── auth/
|
|
242
|
-
│ │ └── types.yaml # Auth domain types
|
|
243
|
-
│ └── shop/
|
|
244
|
-
│ ├── cart.yaml # Shopping cart types
|
|
245
|
-
│ └── product.yaml # Product types
|
|
246
|
-
└── src/
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
**specs/api.yaml (Top-level file):**
|
|
250
|
-
```yaml
|
|
251
|
-
info:
|
|
252
|
-
version: '1.0.0'
|
|
253
|
-
title: 'API Specification'
|
|
254
|
-
|
|
255
|
-
groupedTypes:
|
|
256
|
-
# Import entire groups from external files
|
|
257
|
-
Auth:
|
|
258
|
-
$ref: './specs/auth/types.yaml#/AuthTypes'
|
|
259
|
-
|
|
260
|
-
Shop:
|
|
261
|
-
Cart:
|
|
262
|
-
$ref: './specs/shop/cart.yaml#/ShopTypes/Cart'
|
|
263
|
-
Product:
|
|
264
|
-
$ref: './specs/shop/product.yaml#/ShopTypes/Product'
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
**specs/auth/types.yaml:**
|
|
268
|
-
```yaml
|
|
269
|
-
info:
|
|
270
|
-
version: '1.0.0'
|
|
271
|
-
title: 'Authentication Types'
|
|
272
|
-
|
|
273
|
-
groupedTypes:
|
|
274
|
-
AuthTypes:
|
|
275
|
-
LoginRequest:
|
|
276
|
-
type: object
|
|
277
|
-
required:
|
|
278
|
-
- email
|
|
279
|
-
- password
|
|
280
|
-
properties:
|
|
281
|
-
email: { type: string }
|
|
282
|
-
password: { type: string }
|
|
283
|
-
|
|
284
|
-
LoginResponse:
|
|
285
|
-
type: object
|
|
286
|
-
required:
|
|
287
|
-
- token
|
|
288
|
-
- user
|
|
289
|
-
properties:
|
|
290
|
-
token: { type: string }
|
|
291
|
-
user:
|
|
292
|
-
$ref: './specs/user.yaml#/User' # Cross-file reference
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### Multi-File Reference Rules
|
|
296
|
-
|
|
297
|
-
#### 1. Every File Needs `info` Section
|
|
298
|
-
|
|
299
|
-
```yaml
|
|
300
|
-
# ✅ CORRECT: All files need info section
|
|
301
|
-
info:
|
|
302
|
-
version: '1.0.0'
|
|
303
|
-
title: 'File Title'
|
|
304
|
-
|
|
305
|
-
types:
|
|
306
|
-
# ... your types
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
#### 2. Reference Format
|
|
310
|
-
|
|
311
|
-
```yaml
|
|
312
|
-
# Local reference (same file)
|
|
313
|
-
$ref: '#/types/TypeName'
|
|
314
|
-
$ref: '#/groupedTypes/GroupName/TypeName'
|
|
315
|
-
|
|
316
|
-
# External reference (from project root)
|
|
317
|
-
$ref: './path/from/root/file.yaml#/TypeName'
|
|
318
|
-
$ref: './path/from/root/file.yaml#/GroupName/TypeName'
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
#### 3. Path Resolution
|
|
322
|
-
|
|
323
|
-
**CRITICAL:** All paths are from **project root** (where you run `type-crafter` command)
|
|
324
|
-
|
|
325
|
-
```bash
|
|
326
|
-
# If you run this command from /project
|
|
327
|
-
cd /project
|
|
328
|
-
type-crafter generate typescript ./specs/api.yaml ./output
|
|
329
|
-
|
|
330
|
-
# Then all $ref paths in ANY file are relative to /project
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
**Example:**
|
|
334
|
-
```
|
|
335
|
-
/project/
|
|
336
|
-
├── specs/
|
|
337
|
-
│ ├── api.yaml # File A
|
|
338
|
-
│ └── user/
|
|
339
|
-
│ └── types.yaml # File B
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
**In specs/api.yaml:**
|
|
343
|
-
```yaml
|
|
344
|
-
# ✅ CORRECT: Path from project root
|
|
345
|
-
User:
|
|
346
|
-
$ref: './specs/user/types.yaml#/User'
|
|
347
|
-
|
|
348
|
-
# ❌ WRONG: Don't use relative path from current file
|
|
349
|
-
User:
|
|
350
|
-
$ref: './user/types.yaml#/User'
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
**In specs/user/types.yaml:**
|
|
354
|
-
```yaml
|
|
355
|
-
# ✅ CORRECT: Path from project root
|
|
356
|
-
Profile:
|
|
357
|
-
$ref: './specs/api.yaml#/ApiTypes/Profile'
|
|
358
|
-
|
|
359
|
-
# ❌ WRONG: Don't use relative path
|
|
360
|
-
Profile:
|
|
361
|
-
$ref: '../api.yaml#/ApiTypes/Profile'
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Generating Types from Multi-File Specs
|
|
365
|
-
|
|
366
|
-
```bash
|
|
367
|
-
# Generate from top-level file (references will be resolved automatically)
|
|
368
|
-
type-crafter generate typescript ./types/index.yaml ./output
|
|
369
|
-
|
|
370
|
-
# Or from any entry point
|
|
371
|
-
type-crafter generate typescript ./specs/api.yaml ./src/types
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
All referenced files will be automatically processed and types generated.
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
## Root Structure
|
|
379
|
-
|
|
380
|
-
### Required Fields
|
|
381
|
-
|
|
382
|
-
```yaml
|
|
383
|
-
info:
|
|
384
|
-
version: '0.0.0' # Semver format (required)
|
|
385
|
-
title: 'My API Types' # Specification title (required)
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Type Organization
|
|
389
|
-
|
|
390
|
-
**At least ONE is required:**
|
|
391
|
-
|
|
392
|
-
```yaml
|
|
393
|
-
types: {} # Flat/top-level types
|
|
394
|
-
groupedTypes: {} # Grouped/organized types
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
**Can have both:**
|
|
398
|
-
|
|
399
|
-
```yaml
|
|
400
|
-
types:
|
|
401
|
-
User: {}
|
|
402
|
-
Post: {}
|
|
403
|
-
|
|
404
|
-
groupedTypes:
|
|
405
|
-
Auth:
|
|
406
|
-
LoginRequest: {}
|
|
407
|
-
LoginResponse: {}
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
## Data Types & Type Mapping
|
|
413
|
-
|
|
414
|
-
### Primitive Types → TypeScript Mapping
|
|
415
|
-
|
|
416
|
-
| YAML Type | TypeScript Output | Notes |
|
|
417
|
-
| ----------------------- | ----------------- | ------------------------------ |
|
|
418
|
-
| `string` | `string` | Default string |
|
|
419
|
-
| `string` (format: date) | `Date` | With format specified |
|
|
420
|
-
| `number` | `number` | Floating point |
|
|
421
|
-
| `integer` | `number` | TypeScript has no integer type |
|
|
422
|
-
| `boolean` | `boolean` | |
|
|
423
|
-
| `array` | `Type[]` | Requires `items` specification |
|
|
424
|
-
| `object` | `{ ... }` | Custom object type |
|
|
425
|
-
| `unknown` | `unknown` | For dynamic/any type |
|
|
426
|
-
|
|
427
|
-
### Format Modifiers
|
|
428
|
-
|
|
429
|
-
```yaml
|
|
430
|
-
# String with format
|
|
431
|
-
dateField:
|
|
432
|
-
type: string
|
|
433
|
-
format: date # Generates: Date (not string)
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
---
|
|
437
|
-
|
|
438
|
-
## Constraints & Limitations
|
|
439
|
-
|
|
440
|
-
### ❌ Arrays Cannot Be Top-Level Types
|
|
441
|
-
|
|
442
|
-
Arrays can **ONLY** be used as properties within object types, never as standalone top-level types.
|
|
443
|
-
|
|
444
|
-
```yaml
|
|
445
|
-
# ❌ INVALID - This will NOT work
|
|
446
|
-
Tags:
|
|
447
|
-
type: array
|
|
448
|
-
items:
|
|
449
|
-
type: string
|
|
450
|
-
|
|
451
|
-
# ✅ VALID - Arrays must be properties
|
|
452
|
-
Post:
|
|
453
|
-
type: object
|
|
454
|
-
properties:
|
|
455
|
-
tags:
|
|
456
|
-
type: array
|
|
457
|
-
items:
|
|
458
|
-
type: string
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
**Why:** Type Crafter generates named types. An array alone has no semantic meaning - it must be a property that describes what the array contains.
|
|
462
|
-
|
|
463
|
-
### ✅ Valid Type Categories
|
|
464
|
-
|
|
465
|
-
Only these can be top-level types:
|
|
466
|
-
|
|
467
|
-
- **Objects** (`type: object` with properties)
|
|
468
|
-
- **Enums** (`type: string/number` with enum array)
|
|
469
|
-
- **Primitives** (string, number, boolean, unknown)
|
|
470
|
-
- **Unions** (oneOf)
|
|
471
|
-
- **Intersections** (allOf)
|
|
472
|
-
- **References** ($ref)
|
|
473
|
-
|
|
474
|
-
---
|
|
475
|
-
|
|
476
|
-
## Nullable Types (Critical)
|
|
477
|
-
|
|
478
|
-
### ⚠️ IMPORTANT: Required vs Optional Properties
|
|
479
|
-
|
|
480
|
-
**Properties NOT in `required` array become nullable (`Type | null`)**
|
|
481
|
-
|
|
482
|
-
This is controlled EXCLUSIVELY by the `required` array. There are NO other properties or syntax for controlling nullability.
|
|
483
|
-
|
|
484
|
-
### ❌ WRONG: What NOT to Do
|
|
485
|
-
|
|
486
|
-
```yaml
|
|
487
|
-
# ❌ WRONG: Do NOT use 'nullable' property
|
|
488
|
-
User:
|
|
489
|
-
type: object
|
|
490
|
-
properties:
|
|
491
|
-
name:
|
|
492
|
-
type: string
|
|
493
|
-
nullable: true # ❌ INVALID! This property does NOT exist in Type Crafter
|
|
494
|
-
|
|
495
|
-
# ❌ WRONG: Do NOT use 'optional' property
|
|
496
|
-
User:
|
|
497
|
-
type: object
|
|
498
|
-
properties:
|
|
499
|
-
name:
|
|
500
|
-
type: string
|
|
501
|
-
optional: true # ❌ INVALID! This property does NOT exist
|
|
502
|
-
|
|
503
|
-
# ❌ WRONG: Do NOT use '?' suffix
|
|
504
|
-
User:
|
|
505
|
-
type: object
|
|
506
|
-
properties:
|
|
507
|
-
name?: # ❌ INVALID! Don't use ? in property names
|
|
508
|
-
type: string
|
|
509
|
-
|
|
510
|
-
# ❌ WRONG: Do NOT use null in type
|
|
511
|
-
User:
|
|
512
|
-
type: object
|
|
513
|
-
properties:
|
|
514
|
-
name:
|
|
515
|
-
type: [string, null] # ❌ INVALID! Don't use array of types here
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
### ✅ CORRECT: Use `required` Array Only
|
|
519
|
-
|
|
520
|
-
```yaml
|
|
521
|
-
# ✅ CORRECT: Control nullability with 'required' array
|
|
522
|
-
User:
|
|
523
|
-
type: object
|
|
524
|
-
required:
|
|
525
|
-
- id # id is required → generates: string
|
|
526
|
-
- email # email is required → generates: string
|
|
527
|
-
# name is NOT in required → generates: string | null
|
|
528
|
-
# age is NOT in required → generates: number | null
|
|
529
|
-
properties:
|
|
530
|
-
id:
|
|
531
|
-
type: string
|
|
532
|
-
email:
|
|
533
|
-
type: string
|
|
534
|
-
name:
|
|
535
|
-
type: string
|
|
536
|
-
age:
|
|
537
|
-
type: number
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
**TypeScript Output:**
|
|
541
|
-
|
|
542
|
-
```typescript
|
|
543
|
-
export type User = {
|
|
544
|
-
id: string; // Required (in required array)
|
|
545
|
-
email: string; // Required (in required array)
|
|
546
|
-
name: string | null; // Nullable (NOT in required array)
|
|
547
|
-
age: number | null; // Nullable (NOT in required array)
|
|
548
|
-
};
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
### Detailed Rules
|
|
552
|
-
|
|
553
|
-
1. ✅ **Property in `required` array** → Generates `Type` (NOT nullable)
|
|
554
|
-
|
|
555
|
-
```yaml
|
|
556
|
-
User:
|
|
557
|
-
type: object
|
|
558
|
-
required:
|
|
559
|
-
- name
|
|
560
|
-
properties:
|
|
561
|
-
name: { type: string }
|
|
562
|
-
# Generates: name: string
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
2. ✅ **Property NOT in `required` array** → Generates `Type | null` (nullable)
|
|
566
|
-
|
|
567
|
-
```yaml
|
|
568
|
-
User:
|
|
569
|
-
type: object
|
|
570
|
-
required:
|
|
571
|
-
- id
|
|
572
|
-
properties:
|
|
573
|
-
id: { type: string }
|
|
574
|
-
name: { type: string } # NOT in required
|
|
575
|
-
# Generates: name: string | null
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
3. ✅ **No `required` array at all** → All properties are `Type | null`
|
|
579
|
-
|
|
580
|
-
```yaml
|
|
581
|
-
User:
|
|
582
|
-
type: object
|
|
583
|
-
# No required array
|
|
584
|
-
properties:
|
|
585
|
-
id: { type: string }
|
|
586
|
-
name: { type: string }
|
|
587
|
-
# Generates: id: string | null, name: string | null
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
4. ✅ **Empty `required: []`** → All properties are `Type | null`
|
|
591
|
-
```yaml
|
|
592
|
-
User:
|
|
593
|
-
type: object
|
|
594
|
-
required: [] # Empty array
|
|
595
|
-
properties:
|
|
596
|
-
id: { type: string }
|
|
597
|
-
# Generates: id: string | null
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### Complete Examples
|
|
601
|
-
|
|
602
|
-
#### Example 1: All Properties Required
|
|
603
|
-
|
|
604
|
-
```yaml
|
|
605
|
-
User:
|
|
606
|
-
type: object
|
|
607
|
-
required:
|
|
608
|
-
- id
|
|
609
|
-
- email
|
|
610
|
-
- name
|
|
611
|
-
- age
|
|
612
|
-
properties:
|
|
613
|
-
id: { type: string }
|
|
614
|
-
email: { type: string }
|
|
615
|
-
name: { type: string }
|
|
616
|
-
age: { type: number }
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
```typescript
|
|
620
|
-
// Generated TypeScript
|
|
621
|
-
export type User = {
|
|
622
|
-
id: string;
|
|
623
|
-
email: string;
|
|
624
|
-
name: string;
|
|
625
|
-
age: number;
|
|
626
|
-
};
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
#### Example 2: Some Properties Required
|
|
630
|
-
|
|
631
|
-
```yaml
|
|
632
|
-
User:
|
|
633
|
-
type: object
|
|
634
|
-
required:
|
|
635
|
-
- id
|
|
636
|
-
- email
|
|
637
|
-
properties:
|
|
638
|
-
id: { type: string }
|
|
639
|
-
email: { type: string }
|
|
640
|
-
name: { type: string }
|
|
641
|
-
age: { type: number }
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
```typescript
|
|
645
|
-
// Generated TypeScript
|
|
646
|
-
export type User = {
|
|
647
|
-
id: string;
|
|
648
|
-
email: string;
|
|
649
|
-
name: string | null;
|
|
650
|
-
age: number | null;
|
|
651
|
-
};
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
#### Example 3: No Properties Required
|
|
655
|
-
|
|
656
|
-
```yaml
|
|
657
|
-
User:
|
|
658
|
-
type: object
|
|
659
|
-
properties:
|
|
660
|
-
id: { type: string }
|
|
661
|
-
email: { type: string }
|
|
662
|
-
name: { type: string }
|
|
663
|
-
age: { type: number }
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
```typescript
|
|
667
|
-
// Generated TypeScript - All nullable
|
|
668
|
-
export type User = {
|
|
669
|
-
id: string | null;
|
|
670
|
-
email: string | null;
|
|
671
|
-
name: string | null;
|
|
672
|
-
age: number | null;
|
|
673
|
-
};
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
### Nested Objects and Arrays
|
|
677
|
-
|
|
678
|
-
```yaml
|
|
679
|
-
User:
|
|
680
|
-
type: object
|
|
681
|
-
required:
|
|
682
|
-
- profile
|
|
683
|
-
- posts
|
|
684
|
-
properties:
|
|
685
|
-
profile:
|
|
686
|
-
type: object
|
|
687
|
-
required:
|
|
688
|
-
- name
|
|
689
|
-
properties:
|
|
690
|
-
name: { type: string }
|
|
691
|
-
bio: { type: string } # NOT in profile.required
|
|
692
|
-
posts:
|
|
693
|
-
type: array
|
|
694
|
-
items:
|
|
695
|
-
type: object
|
|
696
|
-
required:
|
|
697
|
-
- title
|
|
698
|
-
properties:
|
|
699
|
-
title: { type: string }
|
|
700
|
-
content: { type: string } # NOT in items.required
|
|
701
|
-
```
|
|
702
|
-
|
|
703
|
-
```typescript
|
|
704
|
-
// Generated TypeScript
|
|
705
|
-
export type User = {
|
|
706
|
-
profile: {
|
|
707
|
-
// profile is required (in User.required)
|
|
708
|
-
name: string; // required in profile
|
|
709
|
-
bio: string | null; // NOT required in profile
|
|
710
|
-
};
|
|
711
|
-
posts: Array<{
|
|
712
|
-
// posts array is required
|
|
713
|
-
title: string; // required in post item
|
|
714
|
-
content: string | null; // NOT required in post item
|
|
715
|
-
}>;
|
|
716
|
-
};
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
---
|
|
720
|
-
|
|
721
|
-
## Type Definitions
|
|
722
|
-
|
|
723
|
-
### Object Type
|
|
724
|
-
|
|
725
|
-
```yaml
|
|
726
|
-
User:
|
|
727
|
-
type: object
|
|
728
|
-
description: 'User account type' # Optional metadata
|
|
729
|
-
example: "{ id: '123', name: 'John' }" # Optional example
|
|
730
|
-
required:
|
|
731
|
-
- id
|
|
732
|
-
- email
|
|
733
|
-
properties:
|
|
734
|
-
id:
|
|
735
|
-
type: string
|
|
736
|
-
description: 'Unique identifier'
|
|
737
|
-
example: 'user-123'
|
|
738
|
-
email:
|
|
739
|
-
type: string
|
|
740
|
-
name:
|
|
741
|
-
type: string
|
|
742
|
-
age:
|
|
743
|
-
type: number
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
**TypeScript:**
|
|
747
|
-
|
|
748
|
-
```typescript
|
|
749
|
-
/**
|
|
750
|
-
* @type { User }
|
|
751
|
-
* @description User account type
|
|
752
|
-
* @example { id: '123', name: 'John' }
|
|
753
|
-
*/
|
|
754
|
-
export type User = {
|
|
755
|
-
/**
|
|
756
|
-
* @description Unique identifier
|
|
757
|
-
* @type { string }
|
|
758
|
-
* @memberof User
|
|
759
|
-
* @example user-123
|
|
760
|
-
*/
|
|
761
|
-
id: string;
|
|
762
|
-
email: string;
|
|
763
|
-
name: string | null;
|
|
764
|
-
age: number | null;
|
|
765
|
-
};
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
### Enum Type (Top-Level)
|
|
769
|
-
|
|
770
|
-
```yaml
|
|
771
|
-
Status:
|
|
772
|
-
type: string
|
|
773
|
-
description: 'User status enum'
|
|
774
|
-
example: 'active'
|
|
775
|
-
enum:
|
|
776
|
-
- active
|
|
777
|
-
- inactive
|
|
778
|
-
- pending
|
|
779
|
-
|
|
780
|
-
Priority:
|
|
781
|
-
type: number
|
|
782
|
-
enum:
|
|
783
|
-
- 1
|
|
784
|
-
- 2
|
|
785
|
-
- 3
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
**TypeScript:**
|
|
789
|
-
|
|
790
|
-
```typescript
|
|
791
|
-
// String enum
|
|
792
|
-
export type Status = 'active' | 'inactive' | 'pending';
|
|
793
|
-
|
|
794
|
-
// Number enum
|
|
795
|
-
export type Priority = 1 | 2 | 3;
|
|
796
|
-
```
|
|
797
|
-
|
|
798
|
-
### Inline Enum (Property)
|
|
799
|
-
|
|
800
|
-
```yaml
|
|
801
|
-
User:
|
|
802
|
-
type: object
|
|
803
|
-
properties:
|
|
804
|
-
role:
|
|
805
|
-
type: string
|
|
806
|
-
enum:
|
|
807
|
-
- admin
|
|
808
|
-
- user
|
|
809
|
-
- guest
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
**TypeScript:**
|
|
813
|
-
|
|
814
|
-
```typescript
|
|
815
|
-
export type User = {
|
|
816
|
-
role: ('admin' | 'user' | 'guest') | null;
|
|
817
|
-
};
|
|
818
|
-
```
|
|
819
|
-
|
|
820
|
-
### Array Types (Property-Level Only)
|
|
821
|
-
|
|
822
|
-
**⚠️ IMPORTANT: Arrays cannot be top-level types. They must be properties within an object type.**
|
|
823
|
-
|
|
824
|
-
```yaml
|
|
825
|
-
# ❌ INVALID - Cannot create standalone array types
|
|
826
|
-
Tags:
|
|
827
|
-
type: array
|
|
828
|
-
items:
|
|
829
|
-
type: string
|
|
830
|
-
|
|
831
|
-
# ✅ VALID - Arrays as properties within objects
|
|
832
|
-
Post:
|
|
833
|
-
type: object
|
|
834
|
-
required:
|
|
835
|
-
- id
|
|
836
|
-
- tags
|
|
837
|
-
properties:
|
|
838
|
-
id:
|
|
839
|
-
type: string
|
|
840
|
-
tags:
|
|
841
|
-
type: array
|
|
842
|
-
items:
|
|
843
|
-
type: string
|
|
844
|
-
comments:
|
|
845
|
-
type: array
|
|
846
|
-
items:
|
|
847
|
-
type: object
|
|
848
|
-
properties:
|
|
849
|
-
text:
|
|
850
|
-
type: string
|
|
851
|
-
relatedPosts:
|
|
852
|
-
type: array
|
|
853
|
-
items:
|
|
854
|
-
$ref: '#/types/Post'
|
|
855
|
-
```
|
|
856
|
-
|
|
857
|
-
**TypeScript:**
|
|
858
|
-
|
|
859
|
-
```typescript
|
|
860
|
-
// Arrays only appear as properties, never as top-level types
|
|
861
|
-
export type Post = {
|
|
862
|
-
id: string;
|
|
863
|
-
tags: string[];
|
|
864
|
-
comments: { text: string | null }[] | null;
|
|
865
|
-
relatedPosts: Post[] | null;
|
|
866
|
-
};
|
|
867
|
-
```
|
|
868
|
-
|
|
869
|
-
### Nested Objects
|
|
870
|
-
|
|
871
|
-
```yaml
|
|
872
|
-
Company:
|
|
873
|
-
type: object
|
|
874
|
-
required:
|
|
875
|
-
- id
|
|
876
|
-
- address
|
|
877
|
-
properties:
|
|
878
|
-
id:
|
|
879
|
-
type: string
|
|
880
|
-
address:
|
|
881
|
-
type: object
|
|
882
|
-
required:
|
|
883
|
-
- street
|
|
884
|
-
properties:
|
|
885
|
-
street:
|
|
886
|
-
type: string
|
|
887
|
-
city:
|
|
888
|
-
type: string
|
|
889
|
-
zipCode:
|
|
890
|
-
type: string
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
**TypeScript:**
|
|
894
|
-
|
|
895
|
-
```typescript
|
|
896
|
-
export type Company = {
|
|
897
|
-
id: string;
|
|
898
|
-
address: {
|
|
899
|
-
street: string;
|
|
900
|
-
city: string | null;
|
|
901
|
-
zipCode: string | null;
|
|
902
|
-
};
|
|
903
|
-
};
|
|
904
|
-
```
|
|
905
|
-
|
|
906
|
-
### Additional Properties (Hashmap/Dictionary)
|
|
907
|
-
|
|
908
|
-
```yaml
|
|
909
|
-
# Simple hashmap (any keys → any values)
|
|
910
|
-
SimpleMap:
|
|
911
|
-
type: object
|
|
912
|
-
additionalProperties: true
|
|
913
|
-
|
|
914
|
-
# Typed hashmap (string keys → string values)
|
|
915
|
-
StringMap:
|
|
916
|
-
type: object
|
|
917
|
-
additionalProperties:
|
|
918
|
-
keyType: string
|
|
919
|
-
valueType:
|
|
920
|
-
type: string
|
|
921
|
-
|
|
922
|
-
# Number keys → Object values
|
|
923
|
-
IdMap:
|
|
924
|
-
type: object
|
|
925
|
-
additionalProperties:
|
|
926
|
-
keyType: number
|
|
927
|
-
valueType:
|
|
928
|
-
$ref: '#/types/User'
|
|
929
|
-
|
|
930
|
-
# Properties + additional (mixed)
|
|
931
|
-
UserWithMeta:
|
|
932
|
-
type: object
|
|
933
|
-
required:
|
|
934
|
-
- id
|
|
935
|
-
properties:
|
|
936
|
-
id:
|
|
937
|
-
type: string
|
|
938
|
-
additionalProperties:
|
|
939
|
-
keyType: string
|
|
940
|
-
valueType:
|
|
941
|
-
type: string
|
|
942
|
-
```
|
|
943
|
-
|
|
944
|
-
**TypeScript:**
|
|
945
|
-
|
|
946
|
-
```typescript
|
|
947
|
-
export type SimpleMap = {
|
|
948
|
-
[keys: string]: unknown;
|
|
949
|
-
};
|
|
950
|
-
|
|
951
|
-
export type StringMap = {
|
|
952
|
-
[keys: string]: string;
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
export type IdMap = {
|
|
956
|
-
[keys: number]: User;
|
|
957
|
-
};
|
|
958
|
-
|
|
959
|
-
export type UserWithMeta = {
|
|
960
|
-
id: string;
|
|
961
|
-
[keys: string]: string; // Additional dynamic properties
|
|
962
|
-
};
|
|
963
|
-
```
|
|
964
|
-
|
|
965
|
-
---
|
|
966
|
-
|
|
967
|
-
## References
|
|
968
|
-
|
|
969
|
-
### Local References (Same File)
|
|
970
|
-
|
|
971
|
-
```yaml
|
|
972
|
-
# Reference to top-level type
|
|
973
|
-
Post:
|
|
974
|
-
type: object
|
|
975
|
-
properties:
|
|
976
|
-
author:
|
|
977
|
-
$ref: '#/types/User'
|
|
978
|
-
|
|
979
|
-
# Reference to grouped type
|
|
980
|
-
Comment:
|
|
981
|
-
type: object
|
|
982
|
-
properties:
|
|
983
|
-
author:
|
|
984
|
-
$ref: '#/groupedTypes/Auth/UserProfile'
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
**Reference Format:**
|
|
988
|
-
|
|
989
|
-
- Top-level: `#/types/TypeName`
|
|
990
|
-
- Grouped: `#/groupedTypes/GroupName/TypeName`
|
|
991
|
-
|
|
992
|
-
### External File References
|
|
993
|
-
|
|
994
|
-
**⚠️ IMPORTANT: Paths are from project root, not relative to current file**
|
|
995
|
-
|
|
996
|
-
```yaml
|
|
997
|
-
# Reference to type in another file (path from project root)
|
|
998
|
-
Post:
|
|
999
|
-
type: object
|
|
1000
|
-
properties:
|
|
1001
|
-
author:
|
|
1002
|
-
$ref: './src/types/users.yaml#/User'
|
|
1003
|
-
|
|
1004
|
-
# Reference to grouped type in another file
|
|
1005
|
-
Comment:
|
|
1006
|
-
type: object
|
|
1007
|
-
properties:
|
|
1008
|
-
metadata:
|
|
1009
|
-
$ref: './docs/specs/common.yaml#/SharedTypes/Metadata'
|
|
1010
|
-
|
|
1011
|
-
# Real-world example: Shopify cart referencing cart item
|
|
1012
|
-
SCart:
|
|
1013
|
-
type: object
|
|
1014
|
-
properties:
|
|
1015
|
-
items:
|
|
1016
|
-
type: array
|
|
1017
|
-
items:
|
|
1018
|
-
$ref: './docs/specs/Cart.yaml#/Cart/SCartItem'
|
|
1019
|
-
```
|
|
1020
|
-
|
|
1021
|
-
**Reference Format:**
|
|
1022
|
-
|
|
1023
|
-
- **Path from project root:** `./path/from/root/file.yaml#/TypeName`
|
|
1024
|
-
- External type: `./path/from/root/file.yaml#/TypeName`
|
|
1025
|
-
- External grouped: `./path/from/root/file.yaml#/GroupName/TypeName`
|
|
1026
|
-
|
|
1027
|
-
**Path Rules:**
|
|
1028
|
-
|
|
1029
|
-
- Paths start with `./` and are relative to **project root** (where you run the command)
|
|
1030
|
-
- NOT relative to the current YAML file location
|
|
1031
|
-
- Example: If your spec is at `./src/api.yaml` and references `./src/types/user.yaml`, the path is `./src/types/user.yaml`, not `./types/user.yaml`
|
|
1032
|
-
|
|
1033
|
-
### Group References (Entire Group)
|
|
1034
|
-
|
|
1035
|
-
```yaml
|
|
1036
|
-
groupedTypes:
|
|
1037
|
-
# Import entire group from external file
|
|
1038
|
-
SharedModels:
|
|
1039
|
-
$ref: './shared.yaml#/Models'
|
|
1040
|
-
```
|
|
1041
|
-
|
|
1042
|
-
### Cyclic References (Self-Referencing)
|
|
1043
|
-
|
|
1044
|
-
```yaml
|
|
1045
|
-
TreeNode:
|
|
1046
|
-
type: object
|
|
1047
|
-
properties:
|
|
1048
|
-
value:
|
|
1049
|
-
type: string
|
|
1050
|
-
children:
|
|
1051
|
-
type: array
|
|
1052
|
-
items:
|
|
1053
|
-
$ref: '#/types/TreeNode' # Self-reference allowed
|
|
1054
|
-
|
|
1055
|
-
LinkedList:
|
|
1056
|
-
type: object
|
|
1057
|
-
properties:
|
|
1058
|
-
value:
|
|
1059
|
-
type: number
|
|
1060
|
-
next:
|
|
1061
|
-
$ref: '#/types/LinkedList' # Self-reference allowed
|
|
1062
|
-
```
|
|
1063
|
-
|
|
1064
|
-
**TypeScript:**
|
|
1065
|
-
|
|
1066
|
-
```typescript
|
|
1067
|
-
export type TreeNode = {
|
|
1068
|
-
value: string | null;
|
|
1069
|
-
children: TreeNode[] | null;
|
|
1070
|
-
};
|
|
1071
|
-
|
|
1072
|
-
export type LinkedList = {
|
|
1073
|
-
value: number | null;
|
|
1074
|
-
next: LinkedList | null;
|
|
1075
|
-
};
|
|
1076
|
-
```
|
|
1077
|
-
|
|
1078
|
-
---
|
|
1079
|
-
|
|
1080
|
-
## Composition
|
|
1081
|
-
|
|
1082
|
-
### oneOf (Union Types)
|
|
1083
|
-
|
|
1084
|
-
Creates TypeScript union: `TypeA | TypeB | TypeC`
|
|
1085
|
-
|
|
1086
|
-
```yaml
|
|
1087
|
-
Response:
|
|
1088
|
-
oneOf:
|
|
1089
|
-
# Reference types
|
|
1090
|
-
- $ref: '#/types/SuccessResponse'
|
|
1091
|
-
- $ref: '#/types/ErrorResponse'
|
|
1092
|
-
# Primitive types
|
|
1093
|
-
- type: string
|
|
1094
|
-
- type: number
|
|
1095
|
-
# Inline enum
|
|
1096
|
-
- type: string
|
|
1097
|
-
enum:
|
|
1098
|
-
- pending
|
|
1099
|
-
- loading
|
|
1100
|
-
# Inline object
|
|
1101
|
-
- type: object
|
|
1102
|
-
properties:
|
|
1103
|
-
status:
|
|
1104
|
-
type: string
|
|
1105
|
-
# Array type
|
|
1106
|
-
- type: array
|
|
1107
|
-
items:
|
|
1108
|
-
type: string
|
|
1109
|
-
```
|
|
1110
|
-
|
|
1111
|
-
**TypeScript:**
|
|
1112
|
-
|
|
1113
|
-
```typescript
|
|
1114
|
-
export type Response =
|
|
1115
|
-
| SuccessResponse
|
|
1116
|
-
| ErrorResponse
|
|
1117
|
-
| string
|
|
1118
|
-
| number
|
|
1119
|
-
| ('pending' | 'loading')
|
|
1120
|
-
| { status: string | null }
|
|
1121
|
-
| string[];
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
### allOf (Intersection/Merge Types)
|
|
1125
|
-
|
|
1126
|
-
Creates TypeScript intersection: `TypeA & TypeB & TypeC`
|
|
1127
|
-
|
|
1128
|
-
```yaml
|
|
1129
|
-
AdminUser:
|
|
1130
|
-
allOf:
|
|
1131
|
-
- $ref: '#/types/BaseUser'
|
|
1132
|
-
- $ref: '#/types/AdminPermissions'
|
|
1133
|
-
- type: object
|
|
1134
|
-
properties:
|
|
1135
|
-
adminLevel:
|
|
1136
|
-
type: number
|
|
1137
|
-
|
|
1138
|
-
# Output merges all types together
|
|
1139
|
-
```
|
|
1140
|
-
|
|
1141
|
-
**TypeScript:**
|
|
1142
|
-
|
|
1143
|
-
```typescript
|
|
1144
|
-
export type AdminUser = BaseUser &
|
|
1145
|
-
AdminPermissions & {
|
|
1146
|
-
adminLevel: number | null;
|
|
1147
|
-
};
|
|
1148
|
-
```
|
|
1149
|
-
|
|
1150
|
-
---
|
|
1151
|
-
|
|
1152
|
-
## TypeScript Generation Examples
|
|
1153
|
-
|
|
1154
|
-
### Complete Example
|
|
1155
|
-
|
|
1156
|
-
**YAML:**
|
|
1157
|
-
|
|
1158
|
-
```yaml
|
|
1159
|
-
info:
|
|
1160
|
-
version: '1.0.0'
|
|
1161
|
-
title: 'Blog API Types'
|
|
1162
|
-
|
|
1163
|
-
types:
|
|
1164
|
-
User:
|
|
1165
|
-
type: object
|
|
1166
|
-
description: 'Blog user account'
|
|
1167
|
-
required:
|
|
1168
|
-
- id
|
|
1169
|
-
- email
|
|
1170
|
-
- role
|
|
1171
|
-
properties:
|
|
1172
|
-
id:
|
|
1173
|
-
type: string
|
|
1174
|
-
description: 'Unique user ID'
|
|
1175
|
-
email:
|
|
1176
|
-
type: string
|
|
1177
|
-
role:
|
|
1178
|
-
$ref: '#/types/UserRole'
|
|
1179
|
-
profile:
|
|
1180
|
-
type: object
|
|
1181
|
-
properties:
|
|
1182
|
-
name:
|
|
1183
|
-
type: string
|
|
1184
|
-
avatar:
|
|
1185
|
-
type: string
|
|
1186
|
-
|
|
1187
|
-
UserRole:
|
|
1188
|
-
type: string
|
|
1189
|
-
enum:
|
|
1190
|
-
- admin
|
|
1191
|
-
- editor
|
|
1192
|
-
- viewer
|
|
1193
|
-
|
|
1194
|
-
Post:
|
|
1195
|
-
type: object
|
|
1196
|
-
required:
|
|
1197
|
-
- id
|
|
1198
|
-
- title
|
|
1199
|
-
- author
|
|
1200
|
-
properties:
|
|
1201
|
-
id:
|
|
1202
|
-
type: string
|
|
1203
|
-
title:
|
|
1204
|
-
type: string
|
|
1205
|
-
content:
|
|
1206
|
-
type: string
|
|
1207
|
-
author:
|
|
1208
|
-
$ref: '#/types/User'
|
|
1209
|
-
tags:
|
|
1210
|
-
type: array
|
|
1211
|
-
items:
|
|
1212
|
-
type: string
|
|
1213
|
-
metadata:
|
|
1214
|
-
type: object
|
|
1215
|
-
additionalProperties:
|
|
1216
|
-
keyType: string
|
|
1217
|
-
valueType:
|
|
1218
|
-
type: string
|
|
1219
|
-
```
|
|
1220
|
-
|
|
1221
|
-
**TypeScript Output:**
|
|
1222
|
-
|
|
1223
|
-
```typescript
|
|
1224
|
-
/**
|
|
1225
|
-
* @type { User }
|
|
1226
|
-
* @description Blog user account
|
|
1227
|
-
*/
|
|
1228
|
-
export type User = {
|
|
1229
|
-
/**
|
|
1230
|
-
* @description Unique user ID
|
|
1231
|
-
* @type { string }
|
|
1232
|
-
* @memberof User
|
|
1233
|
-
*/
|
|
1234
|
-
id: string;
|
|
1235
|
-
email: string;
|
|
1236
|
-
role: UserRole;
|
|
1237
|
-
profile: {
|
|
1238
|
-
name: string | null;
|
|
1239
|
-
avatar: string | null;
|
|
1240
|
-
} | null;
|
|
1241
|
-
};
|
|
1242
|
-
|
|
1243
|
-
export type UserRole = 'admin' | 'editor' | 'viewer';
|
|
1244
|
-
|
|
1245
|
-
export type Post = {
|
|
1246
|
-
id: string;
|
|
1247
|
-
title: string;
|
|
1248
|
-
content: string | null;
|
|
1249
|
-
author: User;
|
|
1250
|
-
tags: string[] | null;
|
|
1251
|
-
metadata: {
|
|
1252
|
-
[keys: string]: string;
|
|
1253
|
-
} | null;
|
|
1254
|
-
};
|
|
1255
|
-
```
|
|
1256
|
-
|
|
1257
|
-
---
|
|
1258
|
-
|
|
1259
|
-
## Best Practices
|
|
1260
|
-
|
|
1261
|
-
### 1. Always Use `required` Array
|
|
1262
|
-
|
|
1263
|
-
```yaml
|
|
1264
|
-
# ❌ BAD - All properties become nullable
|
|
1265
|
-
User:
|
|
1266
|
-
type: object
|
|
1267
|
-
properties:
|
|
1268
|
-
id: { type: string }
|
|
1269
|
-
email: { type: string }
|
|
1270
|
-
|
|
1271
|
-
# ✅ GOOD - Explicit required fields
|
|
1272
|
-
User:
|
|
1273
|
-
type: object
|
|
1274
|
-
required:
|
|
1275
|
-
- id
|
|
1276
|
-
- email
|
|
1277
|
-
properties:
|
|
1278
|
-
id: { type: string }
|
|
1279
|
-
email: { type: string }
|
|
1280
|
-
```
|
|
1281
|
-
|
|
1282
|
-
### 2. Use PascalCase for Type Names
|
|
1283
|
-
|
|
1284
|
-
```yaml
|
|
1285
|
-
# ✅ GOOD
|
|
1286
|
-
types:
|
|
1287
|
-
UserProfile: {}
|
|
1288
|
-
BlogPost: {}
|
|
1289
|
-
APIResponse: {}
|
|
1290
|
-
|
|
1291
|
-
# ❌ AVOID
|
|
1292
|
-
types:
|
|
1293
|
-
userProfile: {}
|
|
1294
|
-
blog_post: {}
|
|
1295
|
-
api-response: {}
|
|
1296
|
-
```
|
|
1297
|
-
|
|
1298
|
-
### 3. Group Related Types
|
|
1299
|
-
|
|
1300
|
-
```yaml
|
|
1301
|
-
# ✅ GOOD
|
|
1302
|
-
groupedTypes:
|
|
1303
|
-
Auth:
|
|
1304
|
-
LoginRequest: {}
|
|
1305
|
-
LoginResponse: {}
|
|
1306
|
-
RefreshToken: {}
|
|
1307
|
-
|
|
1308
|
-
Users:
|
|
1309
|
-
UserProfile: {}
|
|
1310
|
-
UserSettings: {}
|
|
1311
|
-
UserPreferences: {}
|
|
1312
|
-
```
|
|
1313
|
-
|
|
1314
|
-
### 4. Use Descriptions for Complex Types
|
|
1315
|
-
|
|
1316
|
-
```yaml
|
|
1317
|
-
# ✅ GOOD
|
|
1318
|
-
User:
|
|
1319
|
-
type: object
|
|
1320
|
-
description: 'Represents a registered user account with authentication details'
|
|
1321
|
-
properties:
|
|
1322
|
-
passwordHash:
|
|
1323
|
-
type: string
|
|
1324
|
-
description: 'Bcrypt hashed password (never expose in responses)'
|
|
1325
|
-
```
|
|
1326
|
-
|
|
1327
|
-
### 5. Reference External Types for Reusability
|
|
1328
|
-
|
|
1329
|
-
```yaml
|
|
1330
|
-
# ✅ GOOD - Reuse common types (paths from project root)
|
|
1331
|
-
Post:
|
|
1332
|
-
type: object
|
|
1333
|
-
properties:
|
|
1334
|
-
author:
|
|
1335
|
-
$ref: './src/types/common.yaml#/User'
|
|
1336
|
-
metadata:
|
|
1337
|
-
$ref: './src/types/common.yaml#/Metadata'
|
|
1338
|
-
|
|
1339
|
-
# Real example: Shopify cart referencing item types
|
|
1340
|
-
SCart:
|
|
1341
|
-
type: object
|
|
1342
|
-
properties:
|
|
1343
|
-
items:
|
|
1344
|
-
type: array
|
|
1345
|
-
items:
|
|
1346
|
-
$ref: './docs/specs/Cart.yaml#/Cart/SCartItem'
|
|
1347
|
-
```
|
|
1348
|
-
|
|
1349
|
-
**Remember:** Paths are from project root, not relative to current file location.
|
|
1350
|
-
|
|
1351
|
-
---
|
|
1352
|
-
|
|
1353
|
-
## Common Patterns
|
|
1354
|
-
|
|
1355
|
-
### Pattern 1: Paginated Response
|
|
1356
|
-
|
|
1357
|
-
```yaml
|
|
1358
|
-
PaginatedUsers:
|
|
1359
|
-
type: object
|
|
1360
|
-
required:
|
|
1361
|
-
- data
|
|
1362
|
-
- total
|
|
1363
|
-
- page
|
|
1364
|
-
properties:
|
|
1365
|
-
data:
|
|
1366
|
-
type: array
|
|
1367
|
-
items:
|
|
1368
|
-
$ref: '#/types/User'
|
|
1369
|
-
total:
|
|
1370
|
-
type: number
|
|
1371
|
-
page:
|
|
1372
|
-
type: number
|
|
1373
|
-
perPage:
|
|
1374
|
-
type: number
|
|
1375
|
-
```
|
|
1376
|
-
|
|
1377
|
-
### Pattern 2: API Response Wrapper
|
|
1378
|
-
|
|
1379
|
-
```yaml
|
|
1380
|
-
ApiResponse:
|
|
1381
|
-
oneOf:
|
|
1382
|
-
- type: object
|
|
1383
|
-
required:
|
|
1384
|
-
- success
|
|
1385
|
-
- data
|
|
1386
|
-
properties:
|
|
1387
|
-
success:
|
|
1388
|
-
type: boolean
|
|
1389
|
-
data:
|
|
1390
|
-
type: unknown
|
|
1391
|
-
- type: object
|
|
1392
|
-
required:
|
|
1393
|
-
- success
|
|
1394
|
-
- error
|
|
1395
|
-
properties:
|
|
1396
|
-
success:
|
|
1397
|
-
type: boolean
|
|
1398
|
-
error:
|
|
1399
|
-
type: string
|
|
1400
|
-
```
|
|
1401
|
-
|
|
1402
|
-
### Pattern 3: Timestamps Mixin
|
|
1403
|
-
|
|
1404
|
-
```yaml
|
|
1405
|
-
Timestamped:
|
|
1406
|
-
type: object
|
|
1407
|
-
required:
|
|
1408
|
-
- createdAt
|
|
1409
|
-
- updatedAt
|
|
1410
|
-
properties:
|
|
1411
|
-
createdAt:
|
|
1412
|
-
type: string
|
|
1413
|
-
format: date
|
|
1414
|
-
updatedAt:
|
|
1415
|
-
type: string
|
|
1416
|
-
format: date
|
|
1417
|
-
|
|
1418
|
-
# Use with allOf
|
|
1419
|
-
User:
|
|
1420
|
-
allOf:
|
|
1421
|
-
- $ref: '#/types/Timestamped'
|
|
1422
|
-
- type: object
|
|
1423
|
-
required:
|
|
1424
|
-
- id
|
|
1425
|
-
properties:
|
|
1426
|
-
id: { type: string }
|
|
1427
|
-
```
|
|
1428
|
-
|
|
1429
|
-
### Pattern 4: Enum + Metadata
|
|
1430
|
-
|
|
1431
|
-
```yaml
|
|
1432
|
-
StatusType:
|
|
1433
|
-
type: string
|
|
1434
|
-
enum:
|
|
1435
|
-
- draft
|
|
1436
|
-
- published
|
|
1437
|
-
- archived
|
|
1438
|
-
|
|
1439
|
-
Post:
|
|
1440
|
-
type: object
|
|
1441
|
-
required:
|
|
1442
|
-
- status
|
|
1443
|
-
properties:
|
|
1444
|
-
status:
|
|
1445
|
-
$ref: '#/types/StatusType'
|
|
1446
|
-
statusChangedAt:
|
|
1447
|
-
type: string
|
|
1448
|
-
format: date
|
|
1449
|
-
```
|
|
1450
|
-
|
|
1451
|
-
---
|
|
1452
|
-
|
|
1453
|
-
## Rules Checklist
|
|
1454
|
-
|
|
1455
|
-
### Required ✅
|
|
1456
|
-
|
|
1457
|
-
- [ ] Has `info.version` (string)
|
|
1458
|
-
- [ ] Has `info.title` (string)
|
|
1459
|
-
- [ ] Has `types` OR `groupedTypes` (or both)
|
|
1460
|
-
|
|
1461
|
-
### Constraints ✅
|
|
1462
|
-
|
|
1463
|
-
- [ ] **Arrays CANNOT be top-level types** - must be properties within objects
|
|
1464
|
-
- [ ] Only objects, enums, primitives, unions, intersections, and references can be top-level types
|
|
1465
|
-
- [ ] Arrays require `items` specification
|
|
1466
|
-
|
|
1467
|
-
### Type Definitions ✅
|
|
1468
|
-
|
|
1469
|
-
- [ ] Objects have `type: object`
|
|
1470
|
-
- [ ] Arrays are only used as properties (never top-level)
|
|
1471
|
-
- [ ] Enums have `type` (string/number) with `enum` array
|
|
1472
|
-
- [ ] Use `required` array for non-nullable properties
|
|
1473
|
-
- [ ] Properties not in `required` become `Type | null`
|
|
1474
|
-
|
|
1475
|
-
### References ✅
|
|
1476
|
-
|
|
1477
|
-
- [ ] Local references: `#/types/Name` or `#/groupedTypes/Group/Name`
|
|
1478
|
-
- [ ] External references: `./path/from/root/file.yaml#/Name`
|
|
1479
|
-
- [ ] **External paths are from project root, NOT relative to current file**
|
|
1480
|
-
- [ ] Cyclic references are allowed
|
|
1481
|
-
|
|
1482
|
-
### Composition ✅
|
|
1483
|
-
|
|
1484
|
-
- [ ] `oneOf` creates unions (`A | B | C`)
|
|
1485
|
-
- [ ] `allOf` creates intersections (`A & B & C`)
|
|
1486
|
-
- [ ] Can mix inline types and references
|
|
1487
|
-
|
|
1488
|
-
### TypeScript Generation ✅
|
|
1489
|
-
|
|
1490
|
-
- [ ] `string` → `string`
|
|
1491
|
-
- [ ] `string` (format: date) → `Date`
|
|
1492
|
-
- [ ] `number`/`integer` → `number`
|
|
1493
|
-
- [ ] `boolean` → `boolean`
|
|
1494
|
-
- [ ] `array` → `Type[]`
|
|
1495
|
-
- [ ] `object` → `{ ... }`
|
|
1496
|
-
- [ ] `unknown` → `unknown`
|
|
1497
|
-
- [ ] NOT in `required` → `Type | null`
|
|
1498
|
-
|
|
1499
|
-
### Best Practices ✅
|
|
1500
|
-
|
|
1501
|
-
- [ ] Use PascalCase for type names
|
|
1502
|
-
- [ ] Always specify `required` array for objects
|
|
1503
|
-
- [ ] Group related types in `groupedTypes`
|
|
1504
|
-
- [ ] Add descriptions for complex types
|
|
1505
|
-
- [ ] Use references for reusability
|
|
1506
|
-
- [ ] Prefer explicit over implicit nullability
|
|
1507
|
-
|
|
1508
|
-
---
|
|
1509
|
-
|
|
1510
|
-
## Summary
|
|
1511
|
-
|
|
1512
|
-
| Concept | YAML | TypeScript |
|
|
1513
|
-
| ----------------- | ----------------------------- | -------------------- |
|
|
1514
|
-
| Required property | In `required` array | `prop: Type` |
|
|
1515
|
-
| Optional property | NOT in `required` array | `prop: Type \| null` |
|
|
1516
|
-
| String enum | `type: string, enum: [...]` | `'a' \| 'b' \| 'c'` |
|
|
1517
|
-
| Number enum | `type: number, enum: [...]` | `1 \| 2 \| 3` |
|
|
1518
|
-
| Union | `oneOf: [...]` | `A \| B \| C` |
|
|
1519
|
-
| Intersection | `allOf: [...]` | `A & B & C` |
|
|
1520
|
-
| Array | `type: array, items: {...}` | `Type[]` |
|
|
1521
|
-
| Hashmap | `additionalProperties: {...}` | `[key: Type]: Type` |
|
|
1522
|
-
| Reference | `$ref: '#/...'` | Type name |
|
|
1523
|
-
| Nested object | Inline `type: object` | `{ ... }` |
|
|
1524
|
-
|
|
1525
|
-
---
|
|
1526
|
-
|
|
1527
|
-
**Remember:** Properties NOT in the `required` array automatically become `Type | null` in TypeScript!
|