@atscript/typescript 0.1.26 → 0.1.27

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.
@@ -51,18 +51,18 @@ export default defineConfig({
51
51
 
52
52
  ### `TAtscriptConfig` Fields
53
53
 
54
- | Field | Type | Description |
55
- |-------|------|-------------|
56
- | `rootDir` | `string` | Root directory for resolving files |
57
- | `entries` | `string[]` | Entry point globs for `.as` files |
58
- | `include` | `string[]` | Include globs |
59
- | `exclude` | `string[]` | Exclude globs |
60
- | `plugins` | `TAtscriptPlugin[]` | Build plugins (e.g. `tsPlugin()`) |
61
- | `primitives` | `Record<string, TPrimitiveConfig>` | Custom primitive type definitions |
62
- | `annotations` | `TAnnotationsTree` | Custom annotation definitions |
63
- | `unknownAnnotation` | `'allow' \| 'warn' \| 'error'` | Unknown annotation handling |
64
- | `format` | `string` | Output format (set by CLI or build tool) |
65
- | `outDir` | `string` | Output directory |
54
+ | Field | Type | Description |
55
+ | ------------------- | ---------------------------------- | ---------------------------------------- |
56
+ | `rootDir` | `string` | Root directory for resolving files |
57
+ | `entries` | `string[]` | Entry point globs for `.as` files |
58
+ | `include` | `string[]` | Include globs |
59
+ | `exclude` | `string[]` | Exclude globs |
60
+ | `plugins` | `TAtscriptPlugin[]` | Build plugins (e.g. `tsPlugin()`) |
61
+ | `primitives` | `Record<string, TPrimitiveConfig>` | Custom primitive type definitions |
62
+ | `annotations` | `TAnnotationsTree` | Custom annotation definitions |
63
+ | `unknownAnnotation` | `'allow' \| 'warn' \| 'error'` | Unknown annotation handling |
64
+ | `format` | `string` | Output format (set by CLI or build tool) |
65
+ | `outDir` | `string` | Output directory |
66
66
 
67
67
  ## TypeScript Plugin Options
68
68
 
@@ -84,7 +84,8 @@ Individual interfaces can override the JSON Schema setting with `@emit.jsonSchem
84
84
  ### `exampleData`
85
85
 
86
86
  Controls whether `toExampleData()` is generated on output classes:
87
- - `false` *(default)* — method is not rendered in `.js`; `.d.ts` marks it as optional + `@deprecated`
87
+
88
+ - `false` _(default)_ — method is not rendered in `.js`; `.d.ts` marks it as optional + `@deprecated`
88
89
  - `true` — each class gets `static toExampleData()` that calls `createDataFromAnnotatedType(this, { mode: 'example' })`, creating a new example data object on each call (no caching)
89
90
 
90
91
  ## Build Tool Integration
@@ -96,7 +97,7 @@ Controls whether `toExampleData()` is generated on output classes:
96
97
  import atscript from 'unplugin-atscript/vite'
97
98
 
98
99
  export default {
99
- plugins: [atscript()]
100
+ plugins: [atscript()],
100
101
  }
101
102
  ```
102
103
 
@@ -106,7 +107,7 @@ export default {
106
107
  // webpack.config.js
107
108
  const atscript = require('unplugin-atscript/webpack')
108
109
  module.exports = {
109
- plugins: [atscript()]
110
+ plugins: [atscript()],
110
111
  }
111
112
  ```
112
113
 
@@ -136,6 +137,7 @@ npx asc --skipDiag
136
137
  ### Why run `npx asc -f dts`?
137
138
 
138
139
  This generates two things:
140
+
139
141
  1. **`*.as.d.ts`** files next to each `.as` file — TypeScript type declarations for all interfaces/types
140
142
  2. **`atscript.d.ts`** in the project root — global type declarations for `AtscriptMetadata` and `AtscriptPrimitiveTags`
141
143
 
@@ -143,12 +145,12 @@ The `atscript.d.ts` file is **crucial for type safety** — it tells TypeScript
143
145
 
144
146
  ### CLI Options
145
147
 
146
- | Option | Short | Description |
147
- |--------|-------|-------------|
148
- | `--config <path>` | `-c` | Path to config file |
149
- | `--format <fmt>` | `-f` | Output format: `dts`, `js` |
150
- | `--noEmit` | | Only check for errors |
151
- | `--skipDiag` | | Skip diagnostics, always emit |
148
+ | Option | Short | Description |
149
+ | ----------------- | ----- | ----------------------------- |
150
+ | `--config <path>` | `-c` | Path to config file |
151
+ | `--format <fmt>` | `-f` | Output format: `dts`, `js` |
152
+ | `--noEmit` | | Only check for errors |
153
+ | `--skipDiag` | | Skip diagnostics, always emit |
152
154
 
153
155
  ## Project Structure Example
154
156
 
@@ -8,12 +8,12 @@ Every generated interface/type is a `TAtscriptAnnotatedType` — the core runtim
8
8
 
9
9
  ```ts
10
10
  interface TAtscriptAnnotatedType<T extends TAtscriptTypeDef = TAtscriptTypeDef> {
11
- __is_atscript_annotated_type: true // brand for type checking
12
- type: T // the type definition (shape)
13
- metadata: TMetadataMap<AtscriptMetadata> // annotation metadata
14
- optional?: boolean // whether this type is optional
15
- id?: string // stable type name (set by codegen or .id() builder)
16
- validator(opts?): Validator // create a validator instance
11
+ __is_atscript_annotated_type: true // brand for type checking
12
+ type: T // the type definition (shape)
13
+ metadata: TMetadataMap<AtscriptMetadata> // annotation metadata
14
+ optional?: boolean // whether this type is optional
15
+ id?: string // stable type name (set by codegen or .id() builder)
16
+ validator(opts?): Validator // create a validator instance
17
17
  }
18
18
  ```
19
19
 
@@ -38,7 +38,7 @@ The `type` field describes the shape. There are 5 kinds:
38
38
  interface TAtscriptTypeFinal {
39
39
  kind: ''
40
40
  designType: 'string' | 'number' | 'boolean' | 'undefined' | 'null' | 'any' | 'never' | 'phantom'
41
- value?: string | number | boolean // for literal types
41
+ value?: string | number | boolean // for literal types
42
42
  tags: Set<AtscriptPrimitiveTags>
43
43
  }
44
44
  ```
@@ -48,8 +48,8 @@ interface TAtscriptTypeFinal {
48
48
  ```ts
49
49
  interface TAtscriptTypeObject<K extends string = string> {
50
50
  kind: 'object'
51
- props: Map<K, TAtscriptAnnotatedType> // named properties
52
- propsPatterns: Array<{ pattern: RegExp; def: TAtscriptAnnotatedType }> // pattern properties
51
+ props: Map<K, TAtscriptAnnotatedType> // named properties
52
+ propsPatterns: Array<{ pattern: RegExp; def: TAtscriptAnnotatedType }> // pattern properties
53
53
  tags: Set<AtscriptPrimitiveTags>
54
54
  }
55
55
  ```
@@ -59,7 +59,7 @@ interface TAtscriptTypeObject<K extends string = string> {
59
59
  ```ts
60
60
  interface TAtscriptTypeArray {
61
61
  kind: 'array'
62
- of: TAtscriptAnnotatedType // element type
62
+ of: TAtscriptAnnotatedType // element type
63
63
  tags: Set<AtscriptPrimitiveTags>
64
64
  }
65
65
  ```
@@ -82,12 +82,12 @@ The `metadata` field is a typed `Map<keyof AtscriptMetadata, value>`:
82
82
  import { User } from './models/user.as'
83
83
 
84
84
  // Read annotations
85
- const label = User.metadata.get('meta.label') // string | undefined
86
- const required = User.metadata.get('meta.required') // { message?: string } | true | undefined
87
- const minLen = User.metadata.get('expect.minLength') // { length: number; message?: string } | undefined
85
+ const label = User.metadata.get('meta.label') // string | undefined
86
+ const required = User.metadata.get('meta.required') // { message?: string } | true | undefined
87
+ const minLen = User.metadata.get('expect.minLength') // { length: number; message?: string } | undefined
88
88
 
89
89
  // Check if annotation exists
90
- User.metadata.has('meta.sensitive') // boolean
90
+ User.metadata.has('meta.sensitive') // boolean
91
91
 
92
92
  // Iterate all annotations
93
93
  for (const [key, value] of User.metadata.entries()) {
@@ -104,11 +104,11 @@ Navigate into object properties via `type.props`:
104
104
  const nameProp = User.type.props.get('name')!
105
105
 
106
106
  // Read that property's metadata
107
- nameProp.metadata.get('meta.label') // "Full Name"
108
- nameProp.metadata.get('meta.required') // true or { message: "..." }
107
+ nameProp.metadata.get('meta.label') // "Full Name"
108
+ nameProp.metadata.get('meta.required') // true or { message: "..." }
109
109
 
110
110
  // Check if optional
111
- nameProp.optional // boolean | undefined
111
+ nameProp.optional // boolean | undefined
112
112
  ```
113
113
 
114
114
  ### Nested Properties
@@ -148,15 +148,15 @@ The `annotate()` function handles array annotations correctly — if `asArray` i
148
148
  ```ts
149
149
  function inspect(def: TAtscriptAnnotatedType) {
150
150
  switch (def.type.kind) {
151
- case '': // final/primitive
151
+ case '': // final/primitive
152
152
  console.log('Primitive:', def.type.designType)
153
153
  break
154
- case 'object': // object with props
154
+ case 'object': // object with props
155
155
  for (const [name, prop] of def.type.props) {
156
156
  console.log(` ${name}:`, prop.type.kind || prop.type.designType)
157
157
  }
158
158
  break
159
- case 'array': // array
159
+ case 'array': // array
160
160
  console.log('Array of:', def.type.of.type.kind)
161
161
  break
162
162
  case 'union':
@@ -176,14 +176,28 @@ A type-safe dispatch helper that covers all `kind` values:
176
176
  import { forAnnotatedType } from '@atscript/typescript/utils'
177
177
 
178
178
  const result = forAnnotatedType(someType, {
179
- final(d) { return `primitive: ${d.type.designType}` },
180
- object(d) { return `object with ${d.type.props.size} props` },
181
- array(d) { return `array` },
182
- union(d) { return `union of ${d.type.items.length}` },
183
- intersection(d) { return `intersection of ${d.type.items.length}` },
184
- tuple(d) { return `tuple of ${d.type.items.length}` },
179
+ final(d) {
180
+ return `primitive: ${d.type.designType}`
181
+ },
182
+ object(d) {
183
+ return `object with ${d.type.props.size} props`
184
+ },
185
+ array(d) {
186
+ return `array`
187
+ },
188
+ union(d) {
189
+ return `union of ${d.type.items.length}`
190
+ },
191
+ intersection(d) {
192
+ return `intersection of ${d.type.items.length}`
193
+ },
194
+ tuple(d) {
195
+ return `tuple of ${d.type.items.length}`
196
+ },
185
197
  // Optional: handle phantom types separately from final
186
- phantom(d) { return `phantom` },
198
+ phantom(d) {
199
+ return `phantom`
200
+ },
187
201
  })
188
202
  ```
189
203
 
@@ -195,7 +209,7 @@ Each type definition has a `tags` Set containing primitive tags (e.g. `"string"`
195
209
 
196
210
  ```ts
197
211
  const nameProp = User.type.props.get('name')!
198
- nameProp.type.tags.has('string') // true
212
+ nameProp.type.tags.has('string') // true
199
213
  ```
200
214
 
201
215
  Tags come from primitive definitions and their extensions. They're useful for categorizing types at runtime.
@@ -221,7 +235,7 @@ for (const [name, prop] of User.type.props) {
221
235
  import { isAnnotatedTypeOfPrimitive } from '@atscript/typescript/utils'
222
236
 
223
237
  // Returns true for final types and unions/intersections/tuples of all primitives
224
- isAnnotatedTypeOfPrimitive(someType) // true if no objects or arrays
238
+ isAnnotatedTypeOfPrimitive(someType) // true if no objects or arrays
225
239
  ```
226
240
 
227
241
  ## Building Types at Runtime
@@ -238,41 +252,39 @@ const strType = defineAnnotatedType().designType('string').tags('string').$type
238
252
  const userType = defineAnnotatedType('object')
239
253
  .prop('name', defineAnnotatedType().designType('string').$type)
240
254
  .prop('age', defineAnnotatedType().designType('number').$type)
241
- .prop('email', defineAnnotatedType().optional().designType('string').$type)
242
- .$type
255
+ .prop('email', defineAnnotatedType().optional().designType('string').$type).$type
243
256
 
244
257
  // Array
245
- const listType = defineAnnotatedType('array')
246
- .of(defineAnnotatedType().designType('string').$type)
247
- .$type
258
+ const listType = defineAnnotatedType('array').of(
259
+ defineAnnotatedType().designType('string').$type
260
+ ).$type
248
261
 
249
262
  // Union
250
263
  const statusType = defineAnnotatedType('union')
251
264
  .item(defineAnnotatedType().designType('string').value('active').$type)
252
- .item(defineAnnotatedType().designType('string').value('inactive').$type)
253
- .$type
265
+ .item(defineAnnotatedType().designType('string').value('inactive').$type).$type
254
266
 
255
267
  // With metadata
256
- const labeledType = defineAnnotatedType().designType('string')
268
+ const labeledType = defineAnnotatedType()
269
+ .designType('string')
257
270
  .annotate('meta.label', 'My Label')
258
- .annotate('expect.minLength', { length: 3 })
259
- .$type
271
+ .annotate('expect.minLength', { length: 3 }).$type
260
272
  ```
261
273
 
262
274
  ### `TAnnotatedTypeHandle` Fluent API
263
275
 
264
- | Method | Description |
265
- |--------|-------------|
266
- | `.designType(dt)` | Set primitive design type |
267
- | `.value(v)` | Set literal value |
268
- | `.tags(...tags)` | Add primitive tags |
269
- | `.prop(name, type)` | Add named property (object kind) |
270
- | `.propPattern(regex, type)` | Add pattern property (object kind) |
271
- | `.of(type)` | Set element type (array kind) |
272
- | `.item(type)` | Add item (union/intersection/tuple kind) |
273
- | `.optional(flag?)` | Mark as optional |
274
- | `.annotate(key, value, asArray?)` | Set metadata annotation |
275
- | `.copyMetadata(from, ignore?)` | Copy metadata from another type |
276
- | `.id(name)` | Set a stable type name (used by `buildJsonSchema` for `$defs`/`$ref`) |
277
- | `.refTo(type, chain?)` | Reference another annotated type's definition (carries `id`) |
278
- | `.$type` | Get the final `TAtscriptAnnotatedType` |
276
+ | Method | Description |
277
+ | --------------------------------- | --------------------------------------------------------------------- |
278
+ | `.designType(dt)` | Set primitive design type |
279
+ | `.value(v)` | Set literal value |
280
+ | `.tags(...tags)` | Add primitive tags |
281
+ | `.prop(name, type)` | Add named property (object kind) |
282
+ | `.propPattern(regex, type)` | Add pattern property (object kind) |
283
+ | `.of(type)` | Set element type (array kind) |
284
+ | `.item(type)` | Add item (union/intersection/tuple kind) |
285
+ | `.optional(flag?)` | Mark as optional |
286
+ | `.annotate(key, value, asArray?)` | Set metadata annotation |
287
+ | `.copyMetadata(from, ignore?)` | Copy metadata from another type |
288
+ | `.id(name)` | Set a stable type name (used by `buildJsonSchema` for `$defs`/`$ref`) |
289
+ | `.refTo(type, chain?)` | Reference another annotated type's definition (carries `id`) |
290
+ | `.$type` | Get the final `TAtscriptAnnotatedType` |
@@ -120,15 +120,15 @@ annotate User {
120
120
 
121
121
  ### Built-in Primitives
122
122
 
123
- | Primitive | Description |
124
- |-----------|-------------|
125
- | `string` | Text data |
126
- | `number` | Numeric data |
127
- | `boolean` | True/false |
128
- | `null` | Null value |
129
- | `void` / `undefined` | No value |
130
- | `never` | Impossible type |
131
- | `phantom` | Metadata-only type (no runtime/schema impact) |
123
+ | Primitive | Description |
124
+ | -------------------- | --------------------------------------------- |
125
+ | `string` | Text data |
126
+ | `number` | Numeric data |
127
+ | `boolean` | True/false |
128
+ | `null` | Null value |
129
+ | `void` / `undefined` | No value |
130
+ | `never` | Impossible type |
131
+ | `phantom` | Metadata-only type (no runtime/schema impact) |
132
132
 
133
133
  ### Primitive Extensions (Subtypes)
134
134
 
@@ -153,35 +153,35 @@ interface User {
153
153
 
154
154
  #### String Extensions
155
155
 
156
- | Extension | Validation |
157
- |-----------|-----------|
158
- | `string.email` | Email format (`^[^\s@]+@[^\s@]+\.[^\s@]+$`) |
159
- | `string.phone` | Phone format (`^\+?[0-9\s-]{10,15}$`) |
160
- | `string.date` | Date string (YYYY-MM-DD, MM/DD/YYYY, etc.) |
161
- | `string.isoDate` | ISO 8601 date/time |
162
- | `string.uuid` | UUID v4 format |
163
- | `string.required` | Non-empty (trimmed length >= 1) |
156
+ | Extension | Validation |
157
+ | ----------------- | ------------------------------------------- |
158
+ | `string.email` | Email format (`^[^\s@]+@[^\s@]+\.[^\s@]+$`) |
159
+ | `string.phone` | Phone format (`^\+?[0-9\s-]{10,15}$`) |
160
+ | `string.date` | Date string (YYYY-MM-DD, MM/DD/YYYY, etc.) |
161
+ | `string.isoDate` | ISO 8601 date/time |
162
+ | `string.uuid` | UUID v4 format |
163
+ | `string.required` | Non-empty (trimmed length >= 1) |
164
164
 
165
165
  #### Number Extensions
166
166
 
167
- | Extension | Validation |
168
- |-----------|-----------|
169
- | `number.int` | Integer (no decimals) |
170
- | `number.positive` | >= 0 |
171
- | `number.negative` | <= 0 |
172
- | `number.single` | Single-precision float |
173
- | `number.double` | Double-precision float |
174
- | `number.timestamp` | Integer timestamp |
175
- | `number.int.positive` | Integer >= 0 |
176
- | `number.int.negative` | Integer <= 0 |
167
+ | Extension | Validation |
168
+ | --------------------- | ---------------------- |
169
+ | `number.int` | Integer (no decimals) |
170
+ | `number.positive` | >= 0 |
171
+ | `number.negative` | <= 0 |
172
+ | `number.single` | Single-precision float |
173
+ | `number.double` | Double-precision float |
174
+ | `number.timestamp` | Integer timestamp |
175
+ | `number.int.positive` | Integer >= 0 |
176
+ | `number.int.negative` | Integer <= 0 |
177
177
 
178
178
  #### Boolean Extensions
179
179
 
180
- | Extension | Validation |
181
- |-----------|-----------|
180
+ | Extension | Validation |
181
+ | ------------------ | -------------- |
182
182
  | `boolean.required` | Must be `true` |
183
- | `boolean.true` | Literal true |
184
- | `boolean.false` | Literal false |
183
+ | `boolean.true` | Literal true |
184
+ | `boolean.false` | Literal false |
185
185
 
186
186
  ## Imports and Exports
187
187
 
@@ -9,17 +9,25 @@ All utilities are exported from `@atscript/typescript/utils`:
9
9
  ```ts
10
10
  import {
11
11
  // Type construction
12
- defineAnnotatedType, annotate,
12
+ defineAnnotatedType,
13
+ annotate,
13
14
  // Type checking
14
- isAnnotatedType, isAnnotatedTypeOfPrimitive, isPhantomType,
15
+ isAnnotatedType,
16
+ isAnnotatedTypeOfPrimitive,
17
+ isPhantomType,
15
18
  // Type traversal
16
19
  forAnnotatedType,
17
20
  // Validation
18
- Validator, ValidatorError,
21
+ Validator,
22
+ ValidatorError,
19
23
  // JSON Schema
20
- buildJsonSchema, fromJsonSchema, mergeJsonSchemas,
24
+ buildJsonSchema,
25
+ fromJsonSchema,
26
+ mergeJsonSchemas,
21
27
  // Serialization
22
- serializeAnnotatedType, deserializeAnnotatedType, SERIALIZE_VERSION,
28
+ serializeAnnotatedType,
29
+ deserializeAnnotatedType,
30
+ SERIALIZE_VERSION,
23
31
  // Flattening
24
32
  flattenAnnotatedType,
25
33
  // Data creation
@@ -41,13 +49,27 @@ Dispatches over `TAtscriptAnnotatedType` by its `type.kind`, providing type-narr
41
49
  import { forAnnotatedType } from '@atscript/typescript/utils'
42
50
 
43
51
  const description = forAnnotatedType(someType, {
44
- final(d) { return `${d.type.designType}` },
45
- object(d) { return `object(${d.type.props.size} props)` },
46
- array(d) { return `array` },
47
- union(d) { return `union(${d.type.items.length})` },
48
- intersection(d) { return `intersection(${d.type.items.length})` },
49
- tuple(d) { return `[${d.type.items.length}]` },
50
- phantom(d) { return `phantom` }, // optional — without it, phantoms go to final
52
+ final(d) {
53
+ return `${d.type.designType}`
54
+ },
55
+ object(d) {
56
+ return `object(${d.type.props.size} props)`
57
+ },
58
+ array(d) {
59
+ return `array`
60
+ },
61
+ union(d) {
62
+ return `union(${d.type.items.length})`
63
+ },
64
+ intersection(d) {
65
+ return `intersection(${d.type.items.length})`
66
+ },
67
+ tuple(d) {
68
+ return `[${d.type.items.length}]`
69
+ },
70
+ phantom(d) {
71
+ return `phantom`
72
+ }, // optional — without it, phantoms go to final
51
73
  })
52
74
  ```
53
75
 
@@ -88,6 +110,7 @@ const schema = buildJsonSchema(CatOrDog)
88
110
  ```
89
111
 
90
112
  Key behaviors:
113
+
91
114
  - Only **named object types** (with `id`) are extracted to `$defs`. Primitives, unions, arrays stay inline.
92
115
  - The **root type** is never extracted — it IS the schema.
93
116
  - Same `id` referenced multiple times → one `$defs` entry, all occurrences become `$ref`.
@@ -96,23 +119,23 @@ Key behaviors:
96
119
 
97
120
  ### Metadata → JSON Schema Mapping
98
121
 
99
- | Annotation | JSON Schema |
100
- |-----------|-------------|
101
- | `@expect.minLength` on string | `minLength` |
102
- | `@expect.maxLength` on string | `maxLength` |
103
- | `@expect.minLength` on array | `minItems` |
104
- | `@expect.maxLength` on array | `maxItems` |
105
- | `@expect.min` | `minimum` |
106
- | `@expect.max` | `maximum` |
107
- | `@expect.int` | `type: 'integer'` (instead of `'number'`) |
108
- | `@expect.pattern` (single) | `pattern` |
109
- | `@expect.pattern` (multiple) | `allOf: [{ pattern }, ...]` |
110
- | `@meta.required` on string | `minLength: 1` |
111
- | optional property | not in `required` array |
112
- | union | `anyOf` (or `oneOf` + `discriminator` for discriminated unions) |
113
- | intersection | `allOf` |
114
- | tuple | `items` as array |
115
- | phantom | empty object `{}` (excluded) |
122
+ | Annotation | JSON Schema |
123
+ | ----------------------------- | --------------------------------------------------------------- |
124
+ | `@expect.minLength` on string | `minLength` |
125
+ | `@expect.maxLength` on string | `maxLength` |
126
+ | `@expect.minLength` on array | `minItems` |
127
+ | `@expect.maxLength` on array | `maxItems` |
128
+ | `@expect.min` | `minimum` |
129
+ | `@expect.max` | `maximum` |
130
+ | `@expect.int` | `type: 'integer'` (instead of `'number'`) |
131
+ | `@expect.pattern` (single) | `pattern` |
132
+ | `@expect.pattern` (multiple) | `allOf: [{ pattern }, ...]` |
133
+ | `@meta.required` on string | `minLength: 1` |
134
+ | optional property | not in `required` array |
135
+ | union | `anyOf` (or `oneOf` + `discriminator` for discriminated unions) |
136
+ | intersection | `allOf` |
137
+ | tuple | `items` as array |
138
+ | phantom | empty object `{}` (excluded) |
116
139
 
117
140
  ### Discriminated Unions
118
141
 
@@ -131,11 +154,11 @@ const type = fromJsonSchema({
131
154
  name: { type: 'string', minLength: 1 },
132
155
  age: { type: 'integer', minimum: 0 },
133
156
  },
134
- required: ['name', 'age']
157
+ required: ['name', 'age'],
135
158
  })
136
159
 
137
160
  // The resulting type has a working validator
138
- type.validator().validate({ name: 'Alice', age: 30 }) // passes
161
+ type.validator().validate({ name: 'Alice', age: 30 }) // passes
139
162
  ```
140
163
 
141
164
  Supports: `type`, `properties`, `required`, `items`, `anyOf`, `oneOf`, `allOf`, `enum`, `const`, `minLength`, `maxLength`, `minimum`, `maximum`, `pattern`, `minItems`, `maxItems`, `$ref`/`$defs`.
@@ -288,19 +311,19 @@ const custom = createDataFromAnnotatedType(User, {
288
311
  mode: (prop, path) => {
289
312
  if (path === 'name') return 'John Doe'
290
313
  if (path === 'age') return 25
291
- return undefined // fall through to structural default
292
- }
314
+ return undefined // fall through to structural default
315
+ },
293
316
  })
294
317
  ```
295
318
 
296
319
  ### Modes
297
320
 
298
- | Mode | Behavior |
299
- |------|----------|
300
- | `'empty'` (default) | Structural defaults: `''`, `0`, `false`, `[]`, `{}`. Optional props omitted |
301
- | `'default'` | Uses `@meta.default` annotations. Optional props only included if annotated |
302
- | `'example'` | Uses `@meta.example` annotations. Optional props always included. Arrays get one sample item |
303
- | `function` | Custom resolver per field. Return `undefined` to fall through |
321
+ | Mode | Behavior |
322
+ | ------------------- | -------------------------------------------------------------------------------------------- |
323
+ | `'empty'` (default) | Structural defaults: `''`, `0`, `false`, `[]`, `{}`. Optional props omitted |
324
+ | `'default'` | Uses `@meta.default` annotations. Optional props only included if annotated |
325
+ | `'example'` | Uses `@meta.example` annotations. Optional props always included. Arrays get one sample item |
326
+ | `function` | Custom resolver per field. Return `undefined` to fall through |
304
327
 
305
328
  ### Behavior Notes
306
329
 
@@ -317,8 +340,8 @@ const custom = createDataFromAnnotatedType(User, {
317
340
  import { isAnnotatedType } from '@atscript/typescript/utils'
318
341
 
319
342
  if (isAnnotatedType(value)) {
320
- value.metadata // safe
321
- value.type // safe
343
+ value.metadata // safe
344
+ value.type // safe
322
345
  }
323
346
  ```
324
347
 
@@ -329,10 +352,10 @@ Returns `true` for final types and for unions/intersections/tuples whose all mem
329
352
  ```ts
330
353
  import { isAnnotatedTypeOfPrimitive } from '@atscript/typescript/utils'
331
354
 
332
- isAnnotatedTypeOfPrimitive(stringType) // true
333
- isAnnotatedTypeOfPrimitive(objectType) // false
334
- isAnnotatedTypeOfPrimitive(unionOfStringAndNumber) // true
335
- isAnnotatedTypeOfPrimitive(unionOfStringAndObject) // false
355
+ isAnnotatedTypeOfPrimitive(stringType) // true
356
+ isAnnotatedTypeOfPrimitive(objectType) // false
357
+ isAnnotatedTypeOfPrimitive(unionOfStringAndNumber) // true
358
+ isAnnotatedTypeOfPrimitive(unionOfStringAndObject) // false
336
359
  ```
337
360
 
338
361
  ## `isPhantomType(def)` — Check if Phantom
@@ -340,7 +363,7 @@ isAnnotatedTypeOfPrimitive(unionOfStringAndObject) // false
340
363
  ```ts
341
364
  import { isPhantomType } from '@atscript/typescript/utils'
342
365
 
343
- isPhantomType(someProperty) // true if designType === 'phantom'
366
+ isPhantomType(someProperty) // true if designType === 'phantom'
344
367
  ```
345
368
 
346
369
  ## `TAtscriptDataType<T>` — Extract DataType from Annotated Type
@@ -370,8 +393,12 @@ import type { TAtscriptAnnotatedType, TAtscriptDataType } from '@atscript/typesc
370
393
 
371
394
  // Generic repository that infers its entity type
372
395
  class Repository<T extends TAtscriptAnnotatedType> {
373
- findOne(id: string): Promise<TAtscriptDataType<T>> { /* ... */ }
374
- insertOne(data: TAtscriptDataType<T>): Promise<void> { /* ... */ }
396
+ findOne(id: string): Promise<TAtscriptDataType<T>> {
397
+ /* ... */
398
+ }
399
+ insertOne(data: TAtscriptDataType<T>): Promise<void> {
400
+ /* ... */
401
+ }
375
402
  }
376
403
 
377
404
  // Usage — DataType is automatically inferred
@@ -398,25 +425,25 @@ Key types you may need to import:
398
425
 
399
426
  ```ts
400
427
  import type {
401
- TAtscriptAnnotatedType, // core annotated type
428
+ TAtscriptAnnotatedType, // core annotated type
402
429
  TAtscriptAnnotatedTypeConstructor, // annotated type that's also a class
403
- TAtscriptTypeDef, // union of all type def shapes
404
- TAtscriptTypeFinal, // primitive/literal type def
405
- TAtscriptTypeObject, // object type def
406
- TAtscriptTypeArray, // array type def
407
- TAtscriptTypeComplex, // union/intersection/tuple type def
408
- TMetadataMap, // typed metadata map
409
- TAnnotatedTypeHandle, // fluent builder handle
410
- InferDataType, // extract DataType from a type def's phantom generic
411
- TAtscriptDataType, // extract DataType from TAtscriptAnnotatedType
412
- TValidatorOptions, // validator config
413
- TValidatorPlugin, // plugin function type
414
- TValidatorPluginContext, // plugin context
415
- TSerializedAnnotatedType, // serialized type (top-level)
416
- TSerializeOptions, // serialization options
417
- TFlattenOptions, // flatten options
418
- TCreateDataOptions, // createData options
419
- TValueResolver, // custom resolver for createData
420
- TJsonSchema, // JSON Schema object
430
+ TAtscriptTypeDef, // union of all type def shapes
431
+ TAtscriptTypeFinal, // primitive/literal type def
432
+ TAtscriptTypeObject, // object type def
433
+ TAtscriptTypeArray, // array type def
434
+ TAtscriptTypeComplex, // union/intersection/tuple type def
435
+ TMetadataMap, // typed metadata map
436
+ TAnnotatedTypeHandle, // fluent builder handle
437
+ InferDataType, // extract DataType from a type def's phantom generic
438
+ TAtscriptDataType, // extract DataType from TAtscriptAnnotatedType
439
+ TValidatorOptions, // validator config
440
+ TValidatorPlugin, // plugin function type
441
+ TValidatorPluginContext, // plugin context
442
+ TSerializedAnnotatedType, // serialized type (top-level)
443
+ TSerializeOptions, // serialization options
444
+ TFlattenOptions, // flatten options
445
+ TCreateDataOptions, // createData options
446
+ TValueResolver, // custom resolver for createData
447
+ TJsonSchema, // JSON Schema object
421
448
  } from '@atscript/typescript/utils'
422
449
  ```