@atscript/typescript 0.1.26 → 0.1.28

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.
@@ -6,10 +6,10 @@
6
6
 
7
7
  Each `.as` file produces two outputs:
8
8
 
9
- | Output | Generated By | Contains |
10
- |--------|-------------|----------|
9
+ | Output | Generated By | Contains |
10
+ | ----------- | ------------------------------ | ---------------------------------------------------------------------------------------------------- |
11
11
  | `*.as.d.ts` | `npx asc -f dts` or build tool | TypeScript type declarations — interfaces become `declare class` with static type/metadata/validator |
12
- | `*.as.js` | Build tool (unplugin-atscript) | Runtime module — classes with full type definitions, metadata maps, and validator factories |
12
+ | `*.as.js` | Build tool (unplugin-atscript) | Runtime module — classes with full type definitions, metadata maps, and validator factories |
13
13
 
14
14
  ## `.d.ts` Output
15
15
 
@@ -31,9 +31,12 @@ Generates `user.as.d.ts`:
31
31
 
32
32
  ```ts
33
33
  import type {
34
- TAtscriptTypeObject, TAtscriptAnnotatedType,
35
- TMetadataMap, Validator, TValidatorOptions
36
- } from "@atscript/typescript/utils"
34
+ TAtscriptTypeObject,
35
+ TAtscriptAnnotatedType,
36
+ TMetadataMap,
37
+ Validator,
38
+ TValidatorOptions,
39
+ } from '@atscript/typescript/utils'
37
40
 
38
41
  export declare class User {
39
42
  name: string
@@ -48,7 +51,7 @@ export declare class User {
48
51
  static toExampleData?: () => any
49
52
  }
50
53
 
51
- export type Status = "active" | "inactive"
54
+ export type Status = 'active' | 'inactive'
52
55
  declare namespace Status {
53
56
  const __is_atscript_annotated_type: true
54
57
  const type: TAtscriptTypeComplex<Status>
@@ -60,6 +63,7 @@ declare namespace Status {
60
63
  ```
61
64
 
62
65
  Key points:
66
+
63
67
  - **Interfaces** become `declare class` — so they work both as types and runtime values
64
68
  - **Types** become a `type` alias + a companion `namespace` with runtime statics
65
69
  - Each has `type`, `metadata`, `validator()`, `toJsonSchema()`, and `toExampleData()` statics
@@ -92,7 +96,7 @@ declare global {
92
96
  'expect.minLength': { length: number; message?: string }
93
97
  // ... all annotations used in your project
94
98
  }
95
- type AtscriptPrimitiveTags = "string" | "number" | "boolean" | "null"
99
+ type AtscriptPrimitiveTags = 'string' | 'number' | 'boolean' | 'null'
96
100
  }
97
101
  ```
98
102
 
@@ -108,8 +112,8 @@ This file is **auto-generated** based on the annotations actually used across al
108
112
 
109
113
  Generated files use these import paths:
110
114
 
111
- | Import | Source |
112
- |--------|--------|
115
+ | Import | Source |
116
+ | ---------------------------- | ------------------------------------------------- |
113
117
  | `@atscript/typescript/utils` | Runtime utilities (used by generated `.js` files) |
114
118
 
115
119
  When importing from `.as` files in your TypeScript code:
@@ -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