@atscript/typescript 0.1.19 → 0.1.21
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/dist/cli.cjs +17 -2
- package/dist/index.cjs +17 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +17 -2
- package/dist/utils.cjs +96 -8
- package/dist/utils.d.ts +45 -2
- package/dist/utils.mjs +94 -8
- package/package.json +9 -5
- package/scripts/setup-skills.js +78 -0
- package/skills/atscript-typescript/.gitkeep +0 -0
- package/skills/atscript-typescript/SKILL.md +44 -0
- package/skills/atscript-typescript/annotations.md +240 -0
- package/skills/atscript-typescript/codegen.md +126 -0
- package/skills/atscript-typescript/core.md +164 -0
- package/skills/atscript-typescript/runtime.md +276 -0
- package/skills/atscript-typescript/syntax.md +252 -0
- package/skills/atscript-typescript/utilities.md +329 -0
- package/skills/atscript-typescript/validation.md +293 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atscript-typescript
|
|
3
|
+
description: Atscript TypeScript language extension — .as file syntax, code generation, runtime type system, validation, and utilities for the Atscript metadata description language.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @atscript/typescript
|
|
7
|
+
|
|
8
|
+
Atscript is a universal type and metadata description language. `@atscript/typescript` is the TypeScript language extension that compiles `.as` files into `.d.ts` type declarations and `.js` runtime modules with full metadata, validation, and JSON Schema support.
|
|
9
|
+
|
|
10
|
+
## How to use this skill
|
|
11
|
+
|
|
12
|
+
Read the domain file that matches the task. Do not load all files — only what you need.
|
|
13
|
+
|
|
14
|
+
| Domain | File | Load when… |
|
|
15
|
+
|--------|------|------------|
|
|
16
|
+
| Setup & configuration | [core.md](core.md) | Installing, configuring `atscript.config.ts`, using the `tsPlugin`, running the CLI |
|
|
17
|
+
| `.as` file syntax | [syntax.md](syntax.md) | Writing `.as` files — interfaces, types, imports/exports, property syntax |
|
|
18
|
+
| Annotations & primitives | [annotations.md](annotations.md) | Using built-in `@meta.*`/`@expect.*` annotations, defining custom annotations or primitives |
|
|
19
|
+
| Code generation | [codegen.md](codegen.md) | Understanding what `.d.ts` and `.js` files are generated, `atscript.d.ts` global types |
|
|
20
|
+
| Runtime type system | [runtime.md](runtime.md) | Reading/writing metadata, walking type definitions, understanding `TAtscriptAnnotatedType` |
|
|
21
|
+
| Validation | [validation.md](validation.md) | Validating data, type guards, error handling, custom validator plugins |
|
|
22
|
+
| Utility functions | [utilities.md](utilities.md) | Serialization, flattening, JSON Schema, `createDataFromAnnotatedType`, `forAnnotatedType` |
|
|
23
|
+
|
|
24
|
+
## Quick reference
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// Main export (plugin for atscript.config)
|
|
28
|
+
import tsPlugin from '@atscript/typescript'
|
|
29
|
+
|
|
30
|
+
// Runtime utilities (used in app code)
|
|
31
|
+
import {
|
|
32
|
+
defineAnnotatedType, isAnnotatedType, annotate,
|
|
33
|
+
Validator, ValidatorError,
|
|
34
|
+
buildJsonSchema, fromJsonSchema,
|
|
35
|
+
serializeAnnotatedType, deserializeAnnotatedType,
|
|
36
|
+
flattenAnnotatedType, createDataFromAnnotatedType,
|
|
37
|
+
forAnnotatedType, throwFeatureDisabled,
|
|
38
|
+
} from '@atscript/typescript/utils'
|
|
39
|
+
|
|
40
|
+
// CLI
|
|
41
|
+
// npx asc -f dts — generate .d.ts files
|
|
42
|
+
// npx asc -f js — generate .js files (not usually needed with unplugin)
|
|
43
|
+
// npx asc — generate default formats (for typescript plugin this is d.ts only, but if there are other language plugins it may generate multiple formats)
|
|
44
|
+
```
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Annotations & Primitives — @atscript/typescript
|
|
2
|
+
|
|
3
|
+
> All built-in annotations, their arguments, and how to define custom annotations and primitives.
|
|
4
|
+
|
|
5
|
+
## Built-in Annotations
|
|
6
|
+
|
|
7
|
+
### `@meta.*` — Metadata Annotations
|
|
8
|
+
|
|
9
|
+
| Annotation | Arguments | Description |
|
|
10
|
+
|------------|-----------|-------------|
|
|
11
|
+
| `@meta.label` | `text: string` | Human-readable label for UI, logs, documentation |
|
|
12
|
+
| `@meta.id` | `name?: string` (optional) | Mark field as unique identifier; optional custom name |
|
|
13
|
+
| `@meta.description` | `text: string` | Detailed description of a field or entity |
|
|
14
|
+
| `@meta.documentation` | `text: string` | Multi-line docs (Markdown). Multiple allowed — each appends |
|
|
15
|
+
| `@meta.placeholder` | `text: string` | Placeholder for UI input fields (props/types only) |
|
|
16
|
+
| `@meta.sensitive` | *(none)* | Mark as sensitive (passwords, API keys). Strips from serialization |
|
|
17
|
+
| `@meta.readonly` | *(none)* | Mark as read-only |
|
|
18
|
+
| `@meta.required` | `message?: string` | Required field. Strings: non-whitespace. Booleans: must be `true` |
|
|
19
|
+
| `@meta.default` | `value: string` | Default value (strings as-is, others parsed as JSON) |
|
|
20
|
+
| `@meta.example` | `value: string` | Example value (strings as-is, others parsed as JSON) |
|
|
21
|
+
| `@meta.isKey` | *(none)* | Mark field as key inside array (string/number types only) |
|
|
22
|
+
|
|
23
|
+
### `@expect.*` — Validation Constraints
|
|
24
|
+
|
|
25
|
+
| Annotation | Arguments | Applies To | Description |
|
|
26
|
+
|------------|-----------|-----------|-------------|
|
|
27
|
+
| `@expect.minLength` | `length: number`, `message?: string` | string, array | Minimum length |
|
|
28
|
+
| `@expect.maxLength` | `length: number`, `message?: string` | string, array | Maximum length |
|
|
29
|
+
| `@expect.min` | `minValue: number`, `message?: string` | number | Minimum value |
|
|
30
|
+
| `@expect.max` | `maxValue: number`, `message?: string` | number | Maximum value |
|
|
31
|
+
| `@expect.int` | *(none)* | number | Must be integer |
|
|
32
|
+
| `@expect.pattern` | `pattern: string`, `flags?: string`, `message?: string` | string | Regex validation. **Multiple allowed** (all must pass) |
|
|
33
|
+
|
|
34
|
+
### `@emit.*` — Build-time Directives
|
|
35
|
+
|
|
36
|
+
| Annotation | Applies To | Description |
|
|
37
|
+
|------------|-----------|-------------|
|
|
38
|
+
| `@emit.jsonSchema` | interface | Pre-compute and embed JSON Schema at build time |
|
|
39
|
+
|
|
40
|
+
## Custom Annotations
|
|
41
|
+
|
|
42
|
+
Define custom annotations in `atscript.config.ts` using `AnnotationSpec`:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { defineConfig, AnnotationSpec } from '@atscript/core'
|
|
46
|
+
import tsPlugin from '@atscript/typescript'
|
|
47
|
+
|
|
48
|
+
export default defineConfig({
|
|
49
|
+
plugins: [tsPlugin()],
|
|
50
|
+
annotations: {
|
|
51
|
+
// Namespaced annotations use nested objects
|
|
52
|
+
ui: {
|
|
53
|
+
// @ui.component "DatePicker"
|
|
54
|
+
component: new AnnotationSpec({
|
|
55
|
+
argument: { name: 'name', type: 'string' },
|
|
56
|
+
description: 'UI component to render this field',
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
// @ui.hidden (no arguments — boolean flag)
|
|
60
|
+
hidden: new AnnotationSpec({
|
|
61
|
+
description: 'Hide this field in the UI',
|
|
62
|
+
}),
|
|
63
|
+
|
|
64
|
+
// @ui.order 5
|
|
65
|
+
order: new AnnotationSpec({
|
|
66
|
+
argument: { name: 'position', type: 'number' },
|
|
67
|
+
}),
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
// @tag "important" (multiple allowed, each appended)
|
|
71
|
+
tag: new AnnotationSpec({
|
|
72
|
+
multiple: true,
|
|
73
|
+
mergeStrategy: 'append',
|
|
74
|
+
argument: { name: 'value', type: 'string' },
|
|
75
|
+
}),
|
|
76
|
+
|
|
77
|
+
// Annotation with multiple named arguments
|
|
78
|
+
// @api.endpoint "/users" "GET"
|
|
79
|
+
api: {
|
|
80
|
+
endpoint: new AnnotationSpec({
|
|
81
|
+
argument: [
|
|
82
|
+
{ name: 'path', type: 'string' },
|
|
83
|
+
{ name: 'method', type: 'string', optional: true },
|
|
84
|
+
],
|
|
85
|
+
}),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `AnnotationSpec` Options
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
new AnnotationSpec({
|
|
95
|
+
// Single argument
|
|
96
|
+
argument: { name: 'value', type: 'string' },
|
|
97
|
+
|
|
98
|
+
// Or multiple arguments
|
|
99
|
+
argument: [
|
|
100
|
+
{ name: 'first', type: 'string' },
|
|
101
|
+
{ name: 'second', type: 'number', optional: true },
|
|
102
|
+
],
|
|
103
|
+
|
|
104
|
+
// Allow multiple instances on the same target
|
|
105
|
+
multiple: true, // default: false
|
|
106
|
+
|
|
107
|
+
// How duplicates merge: 'replace' (last wins) or 'append' (collect into array)
|
|
108
|
+
mergeStrategy: 'append', // default: 'replace'
|
|
109
|
+
|
|
110
|
+
// Human-readable description
|
|
111
|
+
description: 'What this annotation does',
|
|
112
|
+
|
|
113
|
+
// Restrict to specific node types
|
|
114
|
+
nodeType: ['interface', 'type', 'prop'],
|
|
115
|
+
|
|
116
|
+
// Custom validation function
|
|
117
|
+
validate: (mainToken, args, doc) => {
|
|
118
|
+
// Return array of diagnostic messages, or undefined
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Argument Types
|
|
124
|
+
|
|
125
|
+
Each argument accepts:
|
|
126
|
+
|
|
127
|
+
| Field | Type | Description |
|
|
128
|
+
|-------|------|-------------|
|
|
129
|
+
| `name` | `string` | Argument name (used in metadata object key) |
|
|
130
|
+
| `type` | `'string' \| 'number' \| 'boolean'` | Expected type |
|
|
131
|
+
| `optional` | `boolean` | Whether the argument can be omitted |
|
|
132
|
+
| `description` | `string` | Human-readable description |
|
|
133
|
+
| `values` | `string[]` | Allowed values (enum-like constraint) |
|
|
134
|
+
|
|
135
|
+
### How Annotations Map to Runtime Metadata
|
|
136
|
+
|
|
137
|
+
- **Single argument** → metadata value is the argument value directly
|
|
138
|
+
- **Multiple named arguments** → metadata value is an object with argument names as keys
|
|
139
|
+
- **No arguments** → metadata value is `true`
|
|
140
|
+
- **`multiple: true`** → metadata value is an array
|
|
141
|
+
|
|
142
|
+
Example: `@api.endpoint "/users" "GET"` becomes:
|
|
143
|
+
```ts
|
|
144
|
+
metadata.get('api.endpoint') // → { path: "/users", method: "GET" }
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Custom Primitives
|
|
148
|
+
|
|
149
|
+
Define custom primitive types in `atscript.config.ts`:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
export default defineConfig({
|
|
153
|
+
primitives: {
|
|
154
|
+
// Simple alias with built-in validation
|
|
155
|
+
currency: {
|
|
156
|
+
type: 'string',
|
|
157
|
+
tags: ['string'],
|
|
158
|
+
expect: {
|
|
159
|
+
pattern: /^\d+\.\d{2}$/,
|
|
160
|
+
message: 'Must be in format 0.00',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// Primitive with extensions (subtypes)
|
|
165
|
+
url: {
|
|
166
|
+
type: 'string',
|
|
167
|
+
tags: ['string'],
|
|
168
|
+
expect: {
|
|
169
|
+
pattern: /^https?:\/\/.+/,
|
|
170
|
+
},
|
|
171
|
+
extensions: {
|
|
172
|
+
// url.https — only HTTPS
|
|
173
|
+
https: {
|
|
174
|
+
expect: {
|
|
175
|
+
pattern: /^https:\/\/.+/,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
// url.relative — relative URLs
|
|
179
|
+
relative: {
|
|
180
|
+
expect: {
|
|
181
|
+
pattern: /^\/.+/,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// Object-shaped primitive
|
|
188
|
+
point: {
|
|
189
|
+
type: {
|
|
190
|
+
kind: 'object',
|
|
191
|
+
props: {
|
|
192
|
+
x: 'number',
|
|
193
|
+
y: 'number',
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### `TPrimitiveConfig` Options
|
|
202
|
+
|
|
203
|
+
| Field | Type | Description |
|
|
204
|
+
|-------|------|-------------|
|
|
205
|
+
| `type` | `TPrimitiveTypeDef` | Base type: `'string'`, `'number'`, `'boolean'`, `'void'`, `'null'`, `'phantom'`, or complex type |
|
|
206
|
+
| `tags` | `string[]` | Custom tags for categorization |
|
|
207
|
+
| `documentation` | `string` | Documentation string |
|
|
208
|
+
| `expect` | object | Built-in validation constraints |
|
|
209
|
+
| `extensions` | `Record<string, Partial<TPrimitiveConfig>>` | Sub-types accessible via dot notation |
|
|
210
|
+
|
|
211
|
+
### `expect` Validation on Primitives
|
|
212
|
+
|
|
213
|
+
| Field | Applies To | Description |
|
|
214
|
+
|-------|-----------|-------------|
|
|
215
|
+
| `min` | number | Minimum value |
|
|
216
|
+
| `max` | number | Maximum value |
|
|
217
|
+
| `int` | number | Must be integer |
|
|
218
|
+
| `minLength` | string, array | Minimum length |
|
|
219
|
+
| `maxLength` | string, array | Maximum length |
|
|
220
|
+
| `pattern` | string | Regex pattern(s) |
|
|
221
|
+
| `required` | string, boolean | Non-empty / must be true |
|
|
222
|
+
| `message` | any | Custom error message for pattern |
|
|
223
|
+
|
|
224
|
+
### Usage in `.as` Files
|
|
225
|
+
|
|
226
|
+
After defining custom primitives/annotations, use them directly:
|
|
227
|
+
|
|
228
|
+
```as
|
|
229
|
+
interface Product {
|
|
230
|
+
@meta.label "Price"
|
|
231
|
+
price: currency
|
|
232
|
+
|
|
233
|
+
@ui.component "UrlInput"
|
|
234
|
+
website: url.https
|
|
235
|
+
|
|
236
|
+
@tag "featured"
|
|
237
|
+
@tag "new"
|
|
238
|
+
featured: boolean
|
|
239
|
+
}
|
|
240
|
+
```
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Code Generation — @atscript/typescript
|
|
2
|
+
|
|
3
|
+
> How `.as` files are transformed into `.d.ts` type declarations and `.js` runtime modules.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Each `.as` file produces two outputs:
|
|
8
|
+
|
|
9
|
+
| Output | Generated By | Contains |
|
|
10
|
+
|--------|-------------|----------|
|
|
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 |
|
|
13
|
+
|
|
14
|
+
## `.d.ts` Output
|
|
15
|
+
|
|
16
|
+
The TypeScript declaration file makes `.as` types importable with full IntelliSense:
|
|
17
|
+
|
|
18
|
+
```as
|
|
19
|
+
// user.as
|
|
20
|
+
@meta.label "User"
|
|
21
|
+
export interface User {
|
|
22
|
+
name: string
|
|
23
|
+
age: number
|
|
24
|
+
email?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type Status = "active" | "inactive"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Generates `user.as.d.ts`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import type {
|
|
34
|
+
TAtscriptTypeObject, TAtscriptAnnotatedType,
|
|
35
|
+
TMetadataMap, Validator, TValidatorOptions
|
|
36
|
+
} from "@atscript/typescript/utils"
|
|
37
|
+
|
|
38
|
+
export declare class User {
|
|
39
|
+
name: string
|
|
40
|
+
age: number
|
|
41
|
+
email?: string
|
|
42
|
+
static __is_atscript_annotated_type: true
|
|
43
|
+
static type: TAtscriptTypeObject<keyof User, User>
|
|
44
|
+
static metadata: TMetadataMap<AtscriptMetadata>
|
|
45
|
+
static validator: (opts?: Partial<TValidatorOptions>) => Validator<typeof User>
|
|
46
|
+
static toJsonSchema: () => any
|
|
47
|
+
/** When exampleData is disabled (default), marked @deprecated + optional */
|
|
48
|
+
static toExampleData?: () => any
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type Status = "active" | "inactive"
|
|
52
|
+
declare namespace Status {
|
|
53
|
+
const __is_atscript_annotated_type: true
|
|
54
|
+
const type: TAtscriptTypeComplex<Status>
|
|
55
|
+
const metadata: TMetadataMap<AtscriptMetadata>
|
|
56
|
+
const validator: (opts?: Partial<TValidatorOptions>) => Validator<typeof Status>
|
|
57
|
+
const toJsonSchema: () => any
|
|
58
|
+
const toExampleData: (() => any) | undefined
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Key points:
|
|
63
|
+
- **Interfaces** become `declare class` — so they work both as types and runtime values
|
|
64
|
+
- **Types** become a `type` alias + a companion `namespace` with runtime statics
|
|
65
|
+
- Each has `type`, `metadata`, `validator()`, `toJsonSchema()`, and `toExampleData()` statics
|
|
66
|
+
- `toExampleData` is always optional in `.d.ts`. When `exampleData: true`, it's rendered without deprecation; when disabled, it's marked `@deprecated`
|
|
67
|
+
|
|
68
|
+
## `.js` Output
|
|
69
|
+
|
|
70
|
+
The JS module creates actual classes with runtime type definitions and metadata:
|
|
71
|
+
|
|
72
|
+
- Uses `defineAnnotatedType` (aliased as `$`) to build the type tree
|
|
73
|
+
- Populates metadata maps with all annotation values
|
|
74
|
+
- Wires up `validator()` and `toJsonSchema()` methods
|
|
75
|
+
- When `exampleData: true`, adds `toExampleData()` that calls `createDataFromAnnotatedType(this, { mode: 'example' })` (aliased as `$e`)
|
|
76
|
+
- When `jsonSchema: false` (default), `toJsonSchema()` calls `throwFeatureDisabled()` (aliased as `$d`) instead of inlining the error message
|
|
77
|
+
|
|
78
|
+
You don't normally read or modify generated JS — the build tool handles it.
|
|
79
|
+
|
|
80
|
+
## `atscript.d.ts` — Global Type Declarations
|
|
81
|
+
|
|
82
|
+
Running `npx asc -f dts` also generates `atscript.d.ts` in your project root:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
export {}
|
|
86
|
+
|
|
87
|
+
declare global {
|
|
88
|
+
interface AtscriptMetadata {
|
|
89
|
+
'meta.label': string
|
|
90
|
+
'meta.required': { message?: string } | true
|
|
91
|
+
'expect.minLength': { length: number; message?: string }
|
|
92
|
+
// ... all annotations used in your project
|
|
93
|
+
}
|
|
94
|
+
type AtscriptPrimitiveTags = "string" | "number" | "boolean" | "null"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This file is **auto-generated** based on the annotations actually used across all your `.as` files. It enables:
|
|
99
|
+
|
|
100
|
+
- Type-safe `metadata.get('meta.label')` calls — TypeScript knows the return type
|
|
101
|
+
- Autocompletion for annotation keys
|
|
102
|
+
- Correct types for primitive tags
|
|
103
|
+
|
|
104
|
+
**Important**: Re-run `npx asc -f dts` after adding new annotations to your config. The `atscript.d.ts` file should be committed to your repository.
|
|
105
|
+
|
|
106
|
+
## Import Paths
|
|
107
|
+
|
|
108
|
+
Generated files use these import paths:
|
|
109
|
+
|
|
110
|
+
| Import | Source |
|
|
111
|
+
|--------|--------|
|
|
112
|
+
| `@atscript/typescript/utils` | Runtime utilities (used by generated `.js` files) |
|
|
113
|
+
|
|
114
|
+
When importing from `.as` files in your TypeScript code:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
// Import the generated interface — works as both a type and a runtime value
|
|
118
|
+
import { User } from './models/user.as'
|
|
119
|
+
|
|
120
|
+
// Use as a type
|
|
121
|
+
function greet(user: User) { ... }
|
|
122
|
+
|
|
123
|
+
// Use as a runtime value (has metadata, validator, etc.)
|
|
124
|
+
User.metadata.get('meta.label') // "User"
|
|
125
|
+
User.validator().validate(data)
|
|
126
|
+
```
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Setup & Configuration — @atscript/typescript
|
|
2
|
+
|
|
3
|
+
> Installation, configuration file, TypeScript plugin options, and CLI usage.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @atscript/typescript @atscript/core
|
|
9
|
+
# or
|
|
10
|
+
npm install @atscript/typescript @atscript/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For build-tool integration (Vite, Webpack, Rollup, esbuild, Rspack):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add unplugin-atscript
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configuration File
|
|
20
|
+
|
|
21
|
+
Create `atscript.config.ts` (or `.js`, `.mjs`) in your project root:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { defineConfig } from '@atscript/core'
|
|
25
|
+
import tsPlugin from '@atscript/typescript'
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
// Root directory for resolving .as files (defaults to cwd)
|
|
29
|
+
rootDir: '.',
|
|
30
|
+
|
|
31
|
+
// Entry points — glob patterns for .as files to compile
|
|
32
|
+
entries: ['src/**/*.as'],
|
|
33
|
+
|
|
34
|
+
// Include/exclude globs for dependency resolution
|
|
35
|
+
include: ['src/**/*.as'],
|
|
36
|
+
exclude: ['node_modules/**'],
|
|
37
|
+
|
|
38
|
+
// Plugins — tsPlugin is the TypeScript language extension
|
|
39
|
+
plugins: [tsPlugin()],
|
|
40
|
+
|
|
41
|
+
// How to handle unknown annotations: 'allow' | 'warn' | 'error'
|
|
42
|
+
unknownAnnotation: 'warn',
|
|
43
|
+
|
|
44
|
+
// Custom primitives (merged with built-in ones)
|
|
45
|
+
primitives: {},
|
|
46
|
+
|
|
47
|
+
// Custom annotations (merged with built-in ones)
|
|
48
|
+
annotations: {},
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `TAtscriptConfig` Fields
|
|
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 |
|
|
66
|
+
|
|
67
|
+
## TypeScript Plugin Options
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
tsPlugin({
|
|
71
|
+
jsonSchema: false // default — toJsonSchema() throws at runtime
|
|
72
|
+
// jsonSchema: 'lazy' — import buildJsonSchema, compute on demand, cache
|
|
73
|
+
// jsonSchema: 'bundle' — pre-compute at build time, embed in output
|
|
74
|
+
|
|
75
|
+
exampleData: false // default — toExampleData() not rendered
|
|
76
|
+
// exampleData: true — render toExampleData() using createDataFromAnnotatedType
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `jsonSchema`
|
|
81
|
+
|
|
82
|
+
Individual interfaces can override the JSON Schema setting with `@emit.jsonSchema` annotation to force build-time embedding regardless of plugin setting.
|
|
83
|
+
|
|
84
|
+
### `exampleData`
|
|
85
|
+
|
|
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`
|
|
88
|
+
- `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
|
+
## Build Tool Integration
|
|
91
|
+
|
|
92
|
+
### Vite
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
// vite.config.ts
|
|
96
|
+
import atscript from 'unplugin-atscript/vite'
|
|
97
|
+
|
|
98
|
+
export default {
|
|
99
|
+
plugins: [atscript()]
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Webpack
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// webpack.config.js
|
|
107
|
+
const atscript = require('unplugin-atscript/webpack')
|
|
108
|
+
module.exports = {
|
|
109
|
+
plugins: [atscript()]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The unplugin automatically compiles `.as` files during development and build, generating `.as.js` modules that are importable.
|
|
114
|
+
|
|
115
|
+
## CLI — `asc`
|
|
116
|
+
|
|
117
|
+
The `asc` CLI compiles `.as` files outside of build tools (e.g. for generating `.d.ts` files).
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Generate .d.ts files (most common use case)
|
|
121
|
+
npx asc -f dts
|
|
122
|
+
|
|
123
|
+
# Generate .js files
|
|
124
|
+
npx asc -f js
|
|
125
|
+
|
|
126
|
+
# Use a specific config file
|
|
127
|
+
npx asc -c atscript.config.ts
|
|
128
|
+
|
|
129
|
+
# Only run diagnostics, no file output
|
|
130
|
+
npx asc --noEmit
|
|
131
|
+
|
|
132
|
+
# Skip diagnostics, always emit
|
|
133
|
+
npx asc --skipDiag
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Why run `npx asc -f dts`?
|
|
137
|
+
|
|
138
|
+
This generates two things:
|
|
139
|
+
1. **`*.as.d.ts`** files next to each `.as` file — TypeScript type declarations for all interfaces/types
|
|
140
|
+
2. **`atscript.d.ts`** in the project root — global type declarations for `AtscriptMetadata` and `AtscriptPrimitiveTags`
|
|
141
|
+
|
|
142
|
+
The `atscript.d.ts` file is **crucial for type safety** — it tells TypeScript about all annotations used in your project, enabling type-safe metadata access at runtime.
|
|
143
|
+
|
|
144
|
+
### CLI Options
|
|
145
|
+
|
|
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 |
|
|
152
|
+
|
|
153
|
+
## Project Structure Example
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
my-project/
|
|
157
|
+
atscript.config.ts ← config file
|
|
158
|
+
atscript.d.ts ← generated by `npx asc -f dts` (global types)
|
|
159
|
+
src/
|
|
160
|
+
models/
|
|
161
|
+
user.as ← source file
|
|
162
|
+
user.as.d.ts ← generated type declarations
|
|
163
|
+
user.as.js ← generated runtime module (by build tool)
|
|
164
|
+
```
|