@atscript/typescript 0.1.49 → 0.1.51

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.
@@ -1,259 +0,0 @@
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` | _(none)_ | Mark field as unique identifier; multiple fields form composite PK |
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.sensitive` | _(none)_ | Mark as sensitive (passwords, API keys). Strips from serialization |
16
- | `@meta.readonly` | _(none)_ | Mark as read-only |
17
- | `@meta.required` | `message?: string` | Required field. Strings: non-whitespace. Booleans: must be `true` |
18
- | `@meta.default` | `value: string` | Default value (strings as-is, others parsed as JSON) |
19
- | `@meta.example` | `value: string` | Example value (strings as-is, others parsed as JSON) |
20
- | `@expect.array.key` | `message?: string` | Mark field as key inside array (string/number only, non-optional). Multiple = composite key |
21
-
22
- ### `@expect.*` — Validation Constraints
23
-
24
- | Annotation | Arguments | Applies To | Description |
25
- | ------------------- | ------------------------------------------------------- | ------------- | ------------------------------------------------------ |
26
- | `@expect.minLength` | `length: number`, `message?: string` | string, array | Minimum length |
27
- | `@expect.maxLength` | `length: number`, `message?: string` | string, array | Maximum length |
28
- | `@expect.min` | `minValue: number`, `message?: string` | number | Minimum value |
29
- | `@expect.max` | `maxValue: number`, `message?: string` | number | Maximum value |
30
- | `@expect.int` | _(none)_ | number | Must be integer |
31
- | `@expect.pattern` | `pattern: string`, `flags?: string`, `message?: string` | string | Regex validation. **Multiple allowed** (all must pass) |
32
- | `@expect.array.uniqueItems` | `message?: string` | array | No duplicate items (by key fields or deep equality) |
33
-
34
- ### `@ui.*` — UI / Presentation Hints
35
-
36
- | Annotation | Arguments | Description |
37
- | ----------------- | ------------------------------ | ---------------------------------------------- |
38
- | `@ui.placeholder` | `text: string` | Input placeholder text |
39
- | `@ui.component` | `name: string` | UI component hint (`"select"`, `"datepicker"`) |
40
- | `@ui.hidden` | _(none)_ | Hide from UI forms/tables |
41
- | `@ui.group` | `name: string` | Group fields into form sections |
42
- | `@ui.order` | `order: number` | Display order (lower = first) |
43
- | `@ui.width` | `width: string` | Layout hint (`"half"`, `"full"`, `"third"`) |
44
- | `@ui.icon` | `name: string` | Icon hint |
45
- | `@ui.hint` | `text: string` | Help text / tooltip |
46
- | `@ui.disabled` | _(none)_ | Non-interactive field |
47
- | `@ui.type` | `type: string` | Input type (`"textarea"`, `"password"`, etc.) |
48
- | `@ui.attr` | `key: string`, `value: string` | Arbitrary attribute (**multiple**, append) |
49
- | `@ui.class` | `names: string` | CSS class names (**multiple**, append) |
50
- | `@ui.style` | `css: string` | Inline CSS styles (**multiple**, append) |
51
-
52
- ### `@emit.*` — Build-time Directives
53
-
54
- | Annotation | Applies To | Description |
55
- | ------------------ | ---------- | ----------------------------------------------- |
56
- | `@emit.jsonSchema` | interface | Pre-compute and embed JSON Schema at build time |
57
-
58
- ## Custom Annotations
59
-
60
- Define custom annotations in `atscript.config.ts` using `AnnotationSpec`:
61
-
62
- ```ts
63
- import { defineConfig, AnnotationSpec } from '@atscript/core'
64
- import tsPlugin from '@atscript/typescript'
65
-
66
- export default defineConfig({
67
- plugins: [tsPlugin()],
68
- annotations: {
69
- // Namespaced annotations use nested objects
70
- grid: {
71
- // @grid.column 200
72
- column: new AnnotationSpec({
73
- argument: { name: 'width', type: 'number' },
74
- description: 'Table column width in data grid',
75
- }),
76
-
77
- // @grid.hidden (no arguments — boolean flag)
78
- hidden: new AnnotationSpec({
79
- description: 'Hide column in data grid',
80
- }),
81
-
82
- // @grid.sortable
83
- sortable: new AnnotationSpec({
84
- description: 'Allow sorting by this column',
85
- }),
86
- },
87
-
88
- // @tag "important" (multiple allowed, each appended)
89
- tag: new AnnotationSpec({
90
- multiple: true,
91
- mergeStrategy: 'append',
92
- argument: { name: 'value', type: 'string' },
93
- }),
94
-
95
- // Annotation with multiple named arguments
96
- // @api.endpoint "/users" "GET"
97
- api: {
98
- endpoint: new AnnotationSpec({
99
- argument: [
100
- { name: 'path', type: 'string' },
101
- { name: 'method', type: 'string', optional: true },
102
- ],
103
- }),
104
- },
105
- },
106
- })
107
- ```
108
-
109
- ### `AnnotationSpec` Options
110
-
111
- ```ts
112
- new AnnotationSpec({
113
- // Single argument
114
- argument: { name: 'value', type: 'string' },
115
-
116
- // Or multiple arguments
117
- argument: [
118
- { name: 'first', type: 'string' },
119
- { name: 'second', type: 'number', optional: true },
120
- ],
121
-
122
- // Allow multiple instances on the same target
123
- multiple: true, // default: false
124
-
125
- // How duplicates merge: 'replace' (last wins) or 'append' (collect into array)
126
- mergeStrategy: 'append', // default: 'replace'
127
-
128
- // Human-readable description
129
- description: 'What this annotation does',
130
-
131
- // Restrict to specific node types
132
- nodeType: ['interface', 'type', 'prop'],
133
-
134
- // Custom validation function
135
- validate: (mainToken, args, doc) => {
136
- // Return array of diagnostic messages, or undefined
137
- },
138
- })
139
- ```
140
-
141
- ### Argument Types
142
-
143
- Each argument accepts:
144
-
145
- | Field | Type | Description |
146
- | ------------- | ----------------------------------- | ------------------------------------------- |
147
- | `name` | `string` | Argument name (used in metadata object key) |
148
- | `type` | `'string' \| 'number' \| 'boolean'` | Expected type |
149
- | `optional` | `boolean` | Whether the argument can be omitted |
150
- | `description` | `string` | Human-readable description |
151
- | `values` | `string[]` | Allowed values (enum-like constraint) |
152
-
153
- ### How Annotations Map to Runtime Metadata
154
-
155
- - **Single argument** → metadata value is the argument value directly
156
- - **Multiple named arguments** → metadata value is an object with argument names as keys
157
- - **No arguments** → metadata value is `true`
158
- - **`multiple: true`** → metadata value is an array
159
-
160
- Example: `@api.endpoint "/users" "GET"` becomes:
161
-
162
- ```ts
163
- metadata.get('api.endpoint') // → { path: "/users", method: "GET" }
164
- ```
165
-
166
- ## Custom Primitives
167
-
168
- Define custom primitive types in `atscript.config.ts`:
169
-
170
- ```ts
171
- export default defineConfig({
172
- primitives: {
173
- // Simple alias with built-in validation
174
- currency: {
175
- type: 'string',
176
- tags: ['string'],
177
- expect: {
178
- pattern: /^\d+\.\d{2}$/,
179
- message: 'Must be in format 0.00',
180
- },
181
- },
182
-
183
- // Primitive with extensions (subtypes)
184
- url: {
185
- type: 'string',
186
- tags: ['string'],
187
- expect: {
188
- pattern: /^https?:\/\/.+/,
189
- },
190
- extensions: {
191
- // url.https — only HTTPS
192
- https: {
193
- expect: {
194
- pattern: /^https:\/\/.+/,
195
- },
196
- },
197
- // url.relative — relative URLs
198
- relative: {
199
- expect: {
200
- pattern: /^\/.+/,
201
- },
202
- },
203
- },
204
- },
205
-
206
- // Object-shaped primitive
207
- point: {
208
- type: {
209
- kind: 'object',
210
- props: {
211
- x: 'number',
212
- y: 'number',
213
- },
214
- },
215
- },
216
- },
217
- })
218
- ```
219
-
220
- ### `TPrimitiveConfig` Options
221
-
222
- | Field | Type | Description |
223
- | --------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------ |
224
- | `type` | `TPrimitiveTypeDef` | Base type: `'string'`, `'number'`, `'boolean'`, `'void'`, `'null'`, `'phantom'`, or complex type |
225
- | `tags` | `string[]` | Custom tags for categorization |
226
- | `documentation` | `string` | Documentation string |
227
- | `expect` | object | Built-in validation constraints |
228
- | `extensions` | `Record<string, Partial<TPrimitiveConfig>>` | Sub-types accessible via dot notation |
229
-
230
- ### `expect` Validation on Primitives
231
-
232
- | Field | Applies To | Description |
233
- | ----------- | --------------- | -------------------------------- |
234
- | `min` | number | Minimum value |
235
- | `max` | number | Maximum value |
236
- | `int` | number | Must be integer |
237
- | `minLength` | string, array | Minimum length |
238
- | `maxLength` | string, array | Maximum length |
239
- | `pattern` | string | Regex pattern(s) |
240
- | `required` | string, boolean | Non-empty / must be true |
241
- | `message` | any | Custom error message for pattern |
242
-
243
- ### Usage in `.as` Files
244
-
245
- After defining custom primitives/annotations, use them directly:
246
-
247
- ```as
248
- interface Product {
249
- @meta.label "Price"
250
- price: currency
251
-
252
- @ui.component "UrlInput"
253
- website: url.https
254
-
255
- @tag "featured"
256
- @tag "new"
257
- featured: boolean
258
- }
259
- ```
@@ -1,131 +0,0 @@
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,
35
- TAtscriptAnnotatedType,
36
- TMetadataMap,
37
- Validator,
38
- TValidatorOptions,
39
- } from '@atscript/typescript/utils'
40
-
41
- export declare class User {
42
- name: string
43
- age: number
44
- email?: string
45
- static __is_atscript_annotated_type: true
46
- static type: TAtscriptTypeObject<keyof User, User>
47
- static metadata: TMetadataMap<AtscriptMetadata>
48
- static validator: (opts?: Partial<TValidatorOptions>) => Validator<typeof User>
49
- static toJsonSchema: () => any
50
- /** When exampleData is disabled (default), marked @deprecated + optional */
51
- static toExampleData?: () => any
52
- }
53
-
54
- export type Status = 'active' | 'inactive'
55
- declare namespace Status {
56
- const __is_atscript_annotated_type: true
57
- const type: TAtscriptTypeComplex<Status>
58
- const metadata: TMetadataMap<AtscriptMetadata>
59
- const validator: (opts?: Partial<TValidatorOptions>) => Validator<typeof Status>
60
- const toJsonSchema: () => any
61
- const toExampleData: (() => any) | undefined
62
- }
63
- ```
64
-
65
- Key points:
66
-
67
- - **Interfaces** become `declare class` — so they work both as types and runtime values
68
- - **Types** become a `type` alias + a companion `namespace` with runtime statics
69
- - Each has `type`, `metadata`, `validator()`, `toJsonSchema()`, and `toExampleData()` statics
70
- - `toExampleData` is always optional in `.d.ts`. When `exampleData: true`, it's rendered without deprecation; when disabled, it's marked `@deprecated`
71
-
72
- ## `.js` Output
73
-
74
- The JS module creates actual classes with runtime type definitions and metadata:
75
-
76
- - Uses `defineAnnotatedType` (aliased as `$`) to build the type tree
77
- - Each class gets a `static id` field with the stable type name (collision-safe via `__N` suffix)
78
- - Populates metadata maps with all annotation values
79
- - Wires up `validator()` and `toJsonSchema()` methods
80
- - When `exampleData: true`, adds `toExampleData()` that calls `createDataFromAnnotatedType(this, { mode: 'example' })` (aliased as `$e`)
81
- - When `jsonSchema: false` (default), `toJsonSchema()` calls `throwFeatureDisabled()` (aliased as `$d`) instead of inlining the error message
82
-
83
- You don't normally read or modify generated JS — the build tool handles it.
84
-
85
- ## `atscript.d.ts` — Global Type Declarations
86
-
87
- Running `npx asc -f dts` also generates `atscript.d.ts` in your project root:
88
-
89
- ```ts
90
- export {}
91
-
92
- declare global {
93
- interface AtscriptMetadata {
94
- 'meta.label': string
95
- 'meta.required': { message?: string } | true
96
- 'expect.minLength': { length: number; message?: string }
97
- // ... all annotations used in your project
98
- }
99
- type AtscriptPrimitiveTags = 'string' | 'number' | 'boolean' | 'null'
100
- }
101
- ```
102
-
103
- This file is **auto-generated** based on the annotations actually used across all your `.as` files. It enables:
104
-
105
- - Type-safe `metadata.get('meta.label')` calls — TypeScript knows the return type
106
- - Autocompletion for annotation keys
107
- - Correct types for primitive tags
108
-
109
- **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.
110
-
111
- ## Import Paths
112
-
113
- Generated files use these import paths:
114
-
115
- | Import | Source |
116
- | ---------------------------- | ------------------------------------------------- |
117
- | `@atscript/typescript/utils` | Runtime utilities (used by generated `.js` files) |
118
-
119
- When importing from `.as` files in your TypeScript code:
120
-
121
- ```ts
122
- // Import the generated interface — works as both a type and a runtime value
123
- import { User } from './models/user.as'
124
-
125
- // Use as a type
126
- function greet(user: User) { ... }
127
-
128
- // Use as a runtime value (has metadata, validator, etc.)
129
- User.metadata.get('meta.label') // "User"
130
- User.validator().validate(data)
131
- ```
@@ -1,166 +0,0 @@
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
-
88
- - `false` _(default)_ — method is not rendered in `.js`; `.d.ts` marks it as optional + `@deprecated`
89
- - `true` — each class gets `static toExampleData()` that calls `createDataFromAnnotatedType(this, { mode: 'example' })`, creating a new example data object on each call (no caching)
90
-
91
- ## Build Tool Integration
92
-
93
- ### Vite
94
-
95
- ```ts
96
- // vite.config.ts
97
- import atscript from 'unplugin-atscript/vite'
98
-
99
- export default {
100
- plugins: [atscript()],
101
- }
102
- ```
103
-
104
- ### Webpack
105
-
106
- ```ts
107
- // webpack.config.js
108
- const atscript = require('unplugin-atscript/webpack')
109
- module.exports = {
110
- plugins: [atscript()],
111
- }
112
- ```
113
-
114
- The unplugin automatically compiles `.as` files during development and build, generating `.as.js` modules that are importable.
115
-
116
- ## CLI — `asc`
117
-
118
- The `asc` CLI compiles `.as` files outside of build tools (e.g. for generating `.d.ts` files).
119
-
120
- ```bash
121
- # Generate .d.ts files (most common use case)
122
- npx asc -f dts
123
-
124
- # Generate .js files
125
- npx asc -f js
126
-
127
- # Use a specific config file
128
- npx asc -c atscript.config.ts
129
-
130
- # Only run diagnostics, no file output
131
- npx asc --noEmit
132
-
133
- # Skip diagnostics, always emit
134
- npx asc --skipDiag
135
- ```
136
-
137
- ### Why run `npx asc -f dts`?
138
-
139
- This generates two things:
140
-
141
- 1. **`*.as.d.ts`** files next to each `.as` file — TypeScript type declarations for all interfaces/types
142
- 2. **`atscript.d.ts`** in the project root — global type declarations for `AtscriptMetadata` and `AtscriptPrimitiveTags`
143
-
144
- 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.
145
-
146
- ### CLI Options
147
-
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 |
154
-
155
- ## Project Structure Example
156
-
157
- ```
158
- my-project/
159
- atscript.config.ts ← config file
160
- atscript.d.ts ← generated by `npx asc -f dts` (global types)
161
- src/
162
- models/
163
- user.as ← source file
164
- user.as.d.ts ← generated type declarations
165
- user.as.js ← generated runtime module (by build tool)
166
- ```