@pylonts/dsl 1.1.4 → 1.1.5
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/dsl.d.ts +9 -1
- package/dist/dsl.js +10 -0
- package/dist/mysql-driver.js +4 -1
- package/dist/typebox-driver.js +3 -2
- package/docs/curd.md +110 -110
- package/docs/dto.md +66 -66
- package/docs/table.md +135 -135
- package/package.json +1 -1
- package/src/action.ts +10 -10
- package/src/asset.ts +62 -62
- package/src/bases.ts +29 -29
- package/src/component.ts +21 -21
- package/src/convert.ts +15 -15
- package/src/curd.ts +93 -93
- package/src/dao.ts +13 -13
- package/src/db.ts +181 -181
- package/src/dsl.ts +23 -0
- package/src/dto.ts +247 -247
- package/src/event.ts +12 -12
- package/src/index.ts +32 -32
- package/src/mermaid-driver.ts +84 -84
- package/src/mock.ts +12 -12
- package/src/mysql-driver.ts +4 -2
- package/src/navigation.ts +28 -28
- package/src/page-def.ts +79 -79
- package/src/page-flow.ts +153 -153
- package/src/page.ts +76 -76
- package/src/popup.ts +25 -25
- package/src/project.ts +97 -97
- package/src/provider.ts +72 -72
- package/src/ref.ts +18 -18
- package/src/route.ts +11 -11
- package/src/service.ts +20 -20
- package/src/typebox-driver.ts +193 -192
- package/src/utils.ts +26 -26
package/docs/table.md
CHANGED
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
# 定义表 (TableSchema)
|
|
2
|
-
|
|
3
|
-
## 字段类型
|
|
4
|
-
|
|
5
|
-
| 构建器 | 类型 | jsType | MySQL 列 | 备注 |
|
|
6
|
-
|---|---|---|---|---|
|
|
7
|
-
| `stringField` | string | string | VARCHAR | 必填 `maxLength` |
|
|
8
|
-
| `textField` | text | string | TEXT | |
|
|
9
|
-
| `intField` | integer | number | INT | |
|
|
10
|
-
| `bigintField` | bigint | string | BIGINT | 传输层走 string 保精度 |
|
|
11
|
-
| `decimalField` | decimal | string | DECIMAL | 必填 `precision` / `scale`,传输层走 string 避免浮点误差 |
|
|
12
|
-
| `booleanField` | boolean | boolean | TINYINT(1) | |
|
|
13
|
-
| `dateField` | date | Date | DATE | |
|
|
14
|
-
| `timeField` | time | string | TIME | |
|
|
15
|
-
| `datetimeField` | datetime | Date | DATETIME | |
|
|
16
|
-
| `enumField` | enum | string / number | VARCHAR(20) / TINYINT | 引用共享枚举定义,见 [enum.md](./enum.md) |
|
|
17
|
-
| `jsonField` | json | object | JSON | |
|
|
18
|
-
|
|
19
|
-
通用扩展属性(构建器参数):`label`(中文标签)、`description`、`optional`、`readOnly`、`default`。
|
|
20
|
-
|
|
21
|
-
**`optional` 默认语义(MySQL 惯例)**:不写 `optional` 或写 `optional: true` → 列可空,DDL 不渲染 `NOT NULL`;写 `optional: false` → 列必填(`NOT NULL`)。业务上必填的列必须显式声明。
|
|
22
|
-
|
|
23
|
-
## 定义表
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
import { bigintField, defineTable, decimalField, stringField } from '@pylonts/dsl';
|
|
27
|
-
|
|
28
|
-
const id = bigintField({ readOnly: true, label: '主键' });
|
|
29
|
-
|
|
30
|
-
export const order = defineTable('order', {
|
|
31
|
-
description: '订单',
|
|
32
|
-
autoIncrement: id,
|
|
33
|
-
columns: {
|
|
34
|
-
id,
|
|
35
|
-
order_no: stringField({ label: '订单号', maxLength: 32, optional: false }),
|
|
36
|
-
amount: decimalField({ precision: 18, scale: 2, label: '金额', optional: false }),
|
|
37
|
-
},
|
|
38
|
-
primaryKey: id,
|
|
39
|
-
});
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
- 字段名从 map key 反写,`columns` 里的 key 就是列名。
|
|
43
|
-
- 字段实例不可跨表复用(复用同一字段实例会抛错),枚举除外。
|
|
44
|
-
|
|
45
|
-
## 主键生成策略
|
|
46
|
-
|
|
47
|
-
`autoIncrement` 与 `generator` 互斥,二者选一:
|
|
48
|
-
|
|
49
|
-
| 属性 | 含义 | 例子 |
|
|
50
|
-
|---|---|---|
|
|
51
|
-
| `autoIncrement` | 引用自增主键字段,数据库负责生成值(MySQL `AUTO_INCREMENT`)。设了该属性的字段在 DTO 中自动标记为 optional(写入时不需要传) | `autoIncrement: id` |
|
|
52
|
-
| `generator` | 主键由业务侧生成(非数据库自增),告诉下游工具用哪个 ID 生成器 | `generator: 'snowflake'` |
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
// 数据库自增主键
|
|
56
|
-
export const t1 = defineTable('t1', {
|
|
57
|
-
autoIncrement: id,
|
|
58
|
-
columns: { id: bigintField({ readOnly: true, label: '主键' }) },
|
|
59
|
-
primaryKey: id,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// 业务生成主键(snowflake)
|
|
63
|
-
export const t2 = defineTable('t2', {
|
|
64
|
-
generator: 'snowflake',
|
|
65
|
-
columns: { id: bigintField({ readOnly: true, label: '主键' }) },
|
|
66
|
-
primaryKey: id,
|
|
67
|
-
});
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## 索引
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
indexes: [
|
|
74
|
-
{ name: 'uk_uuid', columns: c_uuid, unique: true },
|
|
75
|
-
{ columns: [c_enum, c_date] }, // 名字缺省时 = 字段名 join '_'
|
|
76
|
-
],
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 外键与短语检查链
|
|
80
|
-
|
|
81
|
-
短语统一定义在 `schema/_dictionary.ts`(见 [dictionary.md](./dictionary.md)),表文件从那里 import:
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
// schema/_dictionary.ts
|
|
85
|
-
import { defineEntityPhrase } from '@pylonts/dsl';
|
|
86
|
-
|
|
87
|
-
export const bd = defineEntityPhrase({ name: 'bd', label: 'BD推广员', description: '线下拓展商户的推广人员' });
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
```ts
|
|
91
|
-
// schema/bd.table.ts
|
|
92
|
-
import { bigintField, defineTable } from '@pylonts/dsl';
|
|
93
|
-
import { bd as bdPhrase } from './_dictionary';
|
|
94
|
-
|
|
95
|
-
const bdId = bigintField({ readOnly: true, label: 'BD ID' });
|
|
96
|
-
|
|
97
|
-
export const bd = defineTable('bd', {
|
|
98
|
-
description: 'BD',
|
|
99
|
-
phrase: bdPhrase, // 链接词典条目:本表归属的实体
|
|
100
|
-
columns: { id: bdId },
|
|
101
|
-
primaryKey: bdId,
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
// schema/audit.table.ts
|
|
107
|
-
import { bigintField, defineTable } from '@pylonts/dsl';
|
|
108
|
-
import { bd } from './bd.table';
|
|
109
|
-
|
|
110
|
-
const auditBdId = bigintField({ label: 'BD' });
|
|
111
|
-
|
|
112
|
-
export const audit = defineTable('audit', {
|
|
113
|
-
description: '审核',
|
|
114
|
-
columns: {
|
|
115
|
-
bd_id: auditBdId, // 列名必须 = 短语 + '_' + 被引用字段名
|
|
116
|
-
},
|
|
117
|
-
foreignKeys: {
|
|
118
|
-
fk_audit_bd: { columns: auditBdId, references: bd.columns.id },
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
**规则(defineTable 时强制检查)**:外键字段名必须等于 `被引用表.phrase.name + "_" + 被引用字段名`。即引用 `bd.id` 的字段必须叫 `bd_id`——`bd` 来自词典(权威短语),`id` 是 `bd` 表主键。
|
|
124
|
-
|
|
125
|
-
**短语口径**:`defineEntityPhrase`(实体短语)解释的**就是短语本身**——`name` 即短语词干(如 `mer`),不是实体全名。引用 `merchant` 实体的字段用短语 `mer`(`mer_id`),**不用长语**(`merchant_id`)。短语要短(mer / bd / amt 三字母左右),语义由 `label`/`description` 解释。`TableSchema.phrase` 只接受实体短语(`defineEntityPhrase` 产物);业务短语(`defineBusinessPhrase`)用于字段命名后缀校验,见 [field-check.md](../../lint/docs/field-check.md)。
|
|
126
|
-
|
|
127
|
-
- 被引用表未定义 `phrase` → 抛错(检查链要求每个被引用表都有短语)。
|
|
128
|
-
- 命名不匹配 → 抛错并提示期望名,例如:
|
|
129
|
-
`foreign key bad: field must be named bd_id (phrase bd + id), got merchant_id`
|
|
130
|
-
- 关联表不需要 `phrase`。
|
|
131
|
-
|
|
132
|
-
> **外键是逻辑作用**:`foreignKeys` 用于定义期命名强校验与关系表达,**DDL 默认不渲染物理 FOREIGN KEY 约束**(`pylonts gen sql init` 不传 `generateForeignKeys`)。数据完整性由 Service/DAO 层保证;如需物理约束,调用 `buildCreateTableSql(schema, { generateForeignKeys: true })`。
|
|
133
|
-
|
|
134
|
-
## 生成 SQL
|
|
135
|
-
|
|
1
|
+
# 定义表 (TableSchema)
|
|
2
|
+
|
|
3
|
+
## 字段类型
|
|
4
|
+
|
|
5
|
+
| 构建器 | 类型 | jsType | MySQL 列 | 备注 |
|
|
6
|
+
|---|---|---|---|---|
|
|
7
|
+
| `stringField` | string | string | VARCHAR | 必填 `maxLength` |
|
|
8
|
+
| `textField` | text | string | TEXT | |
|
|
9
|
+
| `intField` | integer | number | INT | |
|
|
10
|
+
| `bigintField` | bigint | string | BIGINT | 传输层走 string 保精度 |
|
|
11
|
+
| `decimalField` | decimal | string | DECIMAL | 必填 `precision` / `scale`,传输层走 string 避免浮点误差 |
|
|
12
|
+
| `booleanField` | boolean | boolean | TINYINT(1) | |
|
|
13
|
+
| `dateField` | date | Date | DATE | |
|
|
14
|
+
| `timeField` | time | string | TIME | |
|
|
15
|
+
| `datetimeField` | datetime | Date | DATETIME | |
|
|
16
|
+
| `enumField` | enum | string / number | VARCHAR(20) / TINYINT | 引用共享枚举定义,见 [enum.md](./enum.md) |
|
|
17
|
+
| `jsonField` | json | object | JSON | |
|
|
18
|
+
|
|
19
|
+
通用扩展属性(构建器参数):`label`(中文标签)、`description`、`optional`、`readOnly`、`default`。
|
|
20
|
+
|
|
21
|
+
**`optional` 默认语义(MySQL 惯例)**:不写 `optional` 或写 `optional: true` → 列可空,DDL 不渲染 `NOT NULL`;写 `optional: false` → 列必填(`NOT NULL`)。业务上必填的列必须显式声明。
|
|
22
|
+
|
|
23
|
+
## 定义表
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { bigintField, defineTable, decimalField, stringField } from '@pylonts/dsl';
|
|
27
|
+
|
|
28
|
+
const id = bigintField({ readOnly: true, label: '主键' });
|
|
29
|
+
|
|
30
|
+
export const order = defineTable('order', {
|
|
31
|
+
description: '订单',
|
|
32
|
+
autoIncrement: id,
|
|
33
|
+
columns: {
|
|
34
|
+
id,
|
|
35
|
+
order_no: stringField({ label: '订单号', maxLength: 32, optional: false }),
|
|
36
|
+
amount: decimalField({ precision: 18, scale: 2, label: '金额', optional: false }),
|
|
37
|
+
},
|
|
38
|
+
primaryKey: id,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- 字段名从 map key 反写,`columns` 里的 key 就是列名。
|
|
43
|
+
- 字段实例不可跨表复用(复用同一字段实例会抛错),枚举除外。
|
|
44
|
+
|
|
45
|
+
## 主键生成策略
|
|
46
|
+
|
|
47
|
+
`autoIncrement` 与 `generator` 互斥,二者选一:
|
|
48
|
+
|
|
49
|
+
| 属性 | 含义 | 例子 |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `autoIncrement` | 引用自增主键字段,数据库负责生成值(MySQL `AUTO_INCREMENT`)。设了该属性的字段在 DTO 中自动标记为 optional(写入时不需要传) | `autoIncrement: id` |
|
|
52
|
+
| `generator` | 主键由业务侧生成(非数据库自增),告诉下游工具用哪个 ID 生成器 | `generator: 'snowflake'` |
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// 数据库自增主键
|
|
56
|
+
export const t1 = defineTable('t1', {
|
|
57
|
+
autoIncrement: id,
|
|
58
|
+
columns: { id: bigintField({ readOnly: true, label: '主键' }) },
|
|
59
|
+
primaryKey: id,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// 业务生成主键(snowflake)
|
|
63
|
+
export const t2 = defineTable('t2', {
|
|
64
|
+
generator: 'snowflake',
|
|
65
|
+
columns: { id: bigintField({ readOnly: true, label: '主键' }) },
|
|
66
|
+
primaryKey: id,
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 索引
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
indexes: [
|
|
74
|
+
{ name: 'uk_uuid', columns: c_uuid, unique: true },
|
|
75
|
+
{ columns: [c_enum, c_date] }, // 名字缺省时 = 字段名 join '_'
|
|
76
|
+
],
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 外键与短语检查链
|
|
80
|
+
|
|
81
|
+
短语统一定义在 `schema/_dictionary.ts`(见 [dictionary.md](./dictionary.md)),表文件从那里 import:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// schema/_dictionary.ts
|
|
85
|
+
import { defineEntityPhrase } from '@pylonts/dsl';
|
|
86
|
+
|
|
87
|
+
export const bd = defineEntityPhrase({ name: 'bd', label: 'BD推广员', description: '线下拓展商户的推广人员' });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
// schema/bd.table.ts
|
|
92
|
+
import { bigintField, defineTable } from '@pylonts/dsl';
|
|
93
|
+
import { bd as bdPhrase } from './_dictionary';
|
|
94
|
+
|
|
95
|
+
const bdId = bigintField({ readOnly: true, label: 'BD ID' });
|
|
96
|
+
|
|
97
|
+
export const bd = defineTable('bd', {
|
|
98
|
+
description: 'BD',
|
|
99
|
+
phrase: bdPhrase, // 链接词典条目:本表归属的实体
|
|
100
|
+
columns: { id: bdId },
|
|
101
|
+
primaryKey: bdId,
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// schema/audit.table.ts
|
|
107
|
+
import { bigintField, defineTable } from '@pylonts/dsl';
|
|
108
|
+
import { bd } from './bd.table';
|
|
109
|
+
|
|
110
|
+
const auditBdId = bigintField({ label: 'BD' });
|
|
111
|
+
|
|
112
|
+
export const audit = defineTable('audit', {
|
|
113
|
+
description: '审核',
|
|
114
|
+
columns: {
|
|
115
|
+
bd_id: auditBdId, // 列名必须 = 短语 + '_' + 被引用字段名
|
|
116
|
+
},
|
|
117
|
+
foreignKeys: {
|
|
118
|
+
fk_audit_bd: { columns: auditBdId, references: bd.columns.id },
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**规则(defineTable 时强制检查)**:外键字段名必须等于 `被引用表.phrase.name + "_" + 被引用字段名`。即引用 `bd.id` 的字段必须叫 `bd_id`——`bd` 来自词典(权威短语),`id` 是 `bd` 表主键。
|
|
124
|
+
|
|
125
|
+
**短语口径**:`defineEntityPhrase`(实体短语)解释的**就是短语本身**——`name` 即短语词干(如 `mer`),不是实体全名。引用 `merchant` 实体的字段用短语 `mer`(`mer_id`),**不用长语**(`merchant_id`)。短语要短(mer / bd / amt 三字母左右),语义由 `label`/`description` 解释。`TableSchema.phrase` 只接受实体短语(`defineEntityPhrase` 产物);业务短语(`defineBusinessPhrase`)用于字段命名后缀校验,见 [field-check.md](../../lint/docs/field-check.md)。
|
|
126
|
+
|
|
127
|
+
- 被引用表未定义 `phrase` → 抛错(检查链要求每个被引用表都有短语)。
|
|
128
|
+
- 命名不匹配 → 抛错并提示期望名,例如:
|
|
129
|
+
`foreign key bad: field must be named bd_id (phrase bd + id), got merchant_id`
|
|
130
|
+
- 关联表不需要 `phrase`。
|
|
131
|
+
|
|
132
|
+
> **外键是逻辑作用**:`foreignKeys` 用于定义期命名强校验与关系表达,**DDL 默认不渲染物理 FOREIGN KEY 约束**(`pylonts gen sql init` 不传 `generateForeignKeys`)。数据完整性由 Service/DAO 层保证;如需物理约束,调用 `buildCreateTableSql(schema, { generateForeignKeys: true })`。
|
|
133
|
+
|
|
134
|
+
## 生成 SQL
|
|
135
|
+
|
|
136
136
|
见 [driver.md](./driver.md)。
|
package/package.json
CHANGED
package/src/action.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { SchemaBase } from './dsl.js';
|
|
2
|
-
|
|
3
|
-
/** An action a user can perform on a page (e.g. submit, approve, reject).
|
|
4
|
-
* Subclasses use `type` as the discriminator. */
|
|
5
|
-
export interface ActionSchema extends SchemaBase {
|
|
6
|
-
type: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function defineAction(name: string, description?: string): ActionSchema {
|
|
10
|
-
return { name, description, type: 'gesture' };
|
|
1
|
+
import { SchemaBase } from './dsl.js';
|
|
2
|
+
|
|
3
|
+
/** An action a user can perform on a page (e.g. submit, approve, reject).
|
|
4
|
+
* Subclasses use `type` as the discriminator. */
|
|
5
|
+
export interface ActionSchema extends SchemaBase {
|
|
6
|
+
type: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function defineAction(name: string, description?: string): ActionSchema {
|
|
10
|
+
return { name, description, type: 'gesture' };
|
|
11
11
|
}
|
package/src/asset.ts
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* defineAsset — registry for reusable project assets (utils, components, flows, pages, hooks).
|
|
3
|
-
*
|
|
4
|
-
* Each asset declares its name, category, import path, tags, and optional usage example.
|
|
5
|
-
* CLI scans all asset declarations, supports query (by tag/category) and generate (import links).
|
|
6
|
-
*
|
|
7
|
-
* // assets/utils.assets.ts
|
|
8
|
-
* import { defineAsset } from '@pylonts/dsl';
|
|
9
|
-
* export const formatAmt = defineAsset({
|
|
10
|
-
* name: 'formatAmt',
|
|
11
|
-
* category: 'util',
|
|
12
|
-
* tags: ['amount', 'format'],
|
|
13
|
-
* import: { name: 'formatAmt', from: '@/utils/amount' },
|
|
14
|
-
* example: 'formatAmt(12345) => "12,345.00"',
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
* // CLI:
|
|
18
|
-
* // pylonts gen asset list --tag form → all form-related assets
|
|
19
|
-
* // pylonts gen asset import formatAmt → import { formatAmt } from '@/utils/amount';
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
export type AssetCategory = 'util' | 'component' | 'flow' | 'page' | 'hook';
|
|
23
|
-
|
|
24
|
-
export interface AssetImport {
|
|
25
|
-
/** Named export, e.g. 'formatAmt' */
|
|
26
|
-
name: string;
|
|
27
|
-
/** Module path, e.g. '@/utils/amount' */
|
|
28
|
-
from: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface AssetConfig {
|
|
32
|
-
name: string;
|
|
33
|
-
category: AssetCategory;
|
|
34
|
-
tags: string[];
|
|
35
|
-
import: AssetImport;
|
|
36
|
-
description?: string;
|
|
37
|
-
/** One-liner usage example */
|
|
38
|
-
example?: string;
|
|
39
|
-
/** Link to detailed docs */
|
|
40
|
-
see?: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface AssetDef {
|
|
44
|
-
name: string;
|
|
45
|
-
category: AssetCategory;
|
|
46
|
-
tags: string[];
|
|
47
|
-
import: AssetImport;
|
|
48
|
-
description?: string;
|
|
49
|
-
example?: string;
|
|
50
|
-
see?: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function defineAsset(config: AssetConfig): AssetDef {
|
|
54
|
-
return {
|
|
55
|
-
name: config.name,
|
|
56
|
-
category: config.category,
|
|
57
|
-
tags: config.tags,
|
|
58
|
-
import: config.import,
|
|
59
|
-
description: config.description,
|
|
60
|
-
example: config.example,
|
|
61
|
-
see: config.see,
|
|
62
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* defineAsset — registry for reusable project assets (utils, components, flows, pages, hooks).
|
|
3
|
+
*
|
|
4
|
+
* Each asset declares its name, category, import path, tags, and optional usage example.
|
|
5
|
+
* CLI scans all asset declarations, supports query (by tag/category) and generate (import links).
|
|
6
|
+
*
|
|
7
|
+
* // assets/utils.assets.ts
|
|
8
|
+
* import { defineAsset } from '@pylonts/dsl';
|
|
9
|
+
* export const formatAmt = defineAsset({
|
|
10
|
+
* name: 'formatAmt',
|
|
11
|
+
* category: 'util',
|
|
12
|
+
* tags: ['amount', 'format'],
|
|
13
|
+
* import: { name: 'formatAmt', from: '@/utils/amount' },
|
|
14
|
+
* example: 'formatAmt(12345) => "12,345.00"',
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // CLI:
|
|
18
|
+
* // pylonts gen asset list --tag form → all form-related assets
|
|
19
|
+
* // pylonts gen asset import formatAmt → import { formatAmt } from '@/utils/amount';
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export type AssetCategory = 'util' | 'component' | 'flow' | 'page' | 'hook';
|
|
23
|
+
|
|
24
|
+
export interface AssetImport {
|
|
25
|
+
/** Named export, e.g. 'formatAmt' */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Module path, e.g. '@/utils/amount' */
|
|
28
|
+
from: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AssetConfig {
|
|
32
|
+
name: string;
|
|
33
|
+
category: AssetCategory;
|
|
34
|
+
tags: string[];
|
|
35
|
+
import: AssetImport;
|
|
36
|
+
description?: string;
|
|
37
|
+
/** One-liner usage example */
|
|
38
|
+
example?: string;
|
|
39
|
+
/** Link to detailed docs */
|
|
40
|
+
see?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface AssetDef {
|
|
44
|
+
name: string;
|
|
45
|
+
category: AssetCategory;
|
|
46
|
+
tags: string[];
|
|
47
|
+
import: AssetImport;
|
|
48
|
+
description?: string;
|
|
49
|
+
example?: string;
|
|
50
|
+
see?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function defineAsset(config: AssetConfig): AssetDef {
|
|
54
|
+
return {
|
|
55
|
+
name: config.name,
|
|
56
|
+
category: config.category,
|
|
57
|
+
tags: config.tags,
|
|
58
|
+
import: config.import,
|
|
59
|
+
description: config.description,
|
|
60
|
+
example: config.example,
|
|
61
|
+
see: config.see,
|
|
62
|
+
};
|
|
63
63
|
}
|
package/src/bases.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import type { DtoMessage, ImportBase, ImportRef } from './dto.js';
|
|
2
|
-
|
|
3
|
-
// Named base-schema references for common protocol DTOs.
|
|
4
|
-
//
|
|
5
|
-
// These are ImportRef metadata (not re-exports of the actual TypeBox schemas):
|
|
6
|
-
// the DSL stores { from, name } so the generator can emit the import line and
|
|
7
|
-
// the identifier — the runtime schema object itself is never loaded by the DSL.
|
|
8
|
-
//
|
|
9
|
-
// `import { PageRequest } from '@pylonts/dsl'` therefore gives .include() an
|
|
10
|
-
// already-resolved reference — no static analysis or name lookup needed.
|
|
11
|
-
|
|
12
|
-
/** Paginated query request base — renders `import { PageRequest } from '@pylonts/core'` + Intersect */
|
|
13
|
-
export const PageRequest: ImportBase = { from: '@pylonts/core', name: 'PageRequest' };
|
|
14
|
-
|
|
15
|
-
/** Paginated list response base — renders `import { PageResult } from '@pylonts/core'` + `PageResult(<row>)` */
|
|
16
|
-
export const PageResult = (row: DtoMessage): ImportRef => ({
|
|
17
|
-
from: '@pylonts/core',
|
|
18
|
-
name: 'PageResult',
|
|
19
|
-
args: [row],
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
/** Paged rows type base without generic args — renders `import type { PagedRows } from '@pylonts/core'` */
|
|
23
|
-
export const PagedRows: ImportBase = { from: '@pylonts/core', name: 'PagedRows', type: true };
|
|
24
|
-
|
|
25
|
-
/** Paged rows type base — renders `import { PagedRows } from '@pylonts/core'` + `PagedRows(<row>)` */
|
|
26
|
-
export const PageRows = (row: DtoMessage): ImportRef => ({
|
|
27
|
-
from: '@pylonts/core',
|
|
28
|
-
name: 'PagedRows',
|
|
29
|
-
args: [row],
|
|
1
|
+
import type { DtoMessage, ImportBase, ImportRef } from './dto.js';
|
|
2
|
+
|
|
3
|
+
// Named base-schema references for common protocol DTOs.
|
|
4
|
+
//
|
|
5
|
+
// These are ImportRef metadata (not re-exports of the actual TypeBox schemas):
|
|
6
|
+
// the DSL stores { from, name } so the generator can emit the import line and
|
|
7
|
+
// the identifier — the runtime schema object itself is never loaded by the DSL.
|
|
8
|
+
//
|
|
9
|
+
// `import { PageRequest } from '@pylonts/dsl'` therefore gives .include() an
|
|
10
|
+
// already-resolved reference — no static analysis or name lookup needed.
|
|
11
|
+
|
|
12
|
+
/** Paginated query request base — renders `import { PageRequest } from '@pylonts/core'` + Intersect */
|
|
13
|
+
export const PageRequest: ImportBase = { from: '@pylonts/core', name: 'PageRequest' };
|
|
14
|
+
|
|
15
|
+
/** Paginated list response base — renders `import { PageResult } from '@pylonts/core'` + `PageResult(<row>)` */
|
|
16
|
+
export const PageResult = (row: DtoMessage): ImportRef => ({
|
|
17
|
+
from: '@pylonts/core',
|
|
18
|
+
name: 'PageResult',
|
|
19
|
+
args: [row],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/** Paged rows type base without generic args — renders `import type { PagedRows } from '@pylonts/core'` */
|
|
23
|
+
export const PagedRows: ImportBase = { from: '@pylonts/core', name: 'PagedRows', type: true };
|
|
24
|
+
|
|
25
|
+
/** Paged rows type base — renders `import { PagedRows } from '@pylonts/core'` + `PagedRows(<row>)` */
|
|
26
|
+
export const PageRows = (row: DtoMessage): ImportRef => ({
|
|
27
|
+
from: '@pylonts/core',
|
|
28
|
+
name: 'PagedRows',
|
|
29
|
+
args: [row],
|
|
30
30
|
});
|
package/src/component.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { SchemaBase } from './dsl.js';
|
|
2
|
-
import type { RefSchema } from './ref.js';
|
|
3
|
-
import type { ActionSchema } from './action.js';
|
|
4
|
-
import type { EventDataSchema } from './event.js';
|
|
5
|
-
|
|
6
|
-
/** A component event trigger declaration. */
|
|
7
|
-
export interface TriggerSchema extends SchemaBase {
|
|
8
|
-
/** Data the event carries (e.g. e.detail). */
|
|
9
|
-
eventData?: EventDataSchema;
|
|
10
|
-
/** Actions that fire when the event occurs. */
|
|
11
|
-
actions?: ActionSchema[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** A UI component declaration — a virtual schema that describes props and
|
|
15
|
-
* event triggers, not a real renderable component.
|
|
16
|
-
*
|
|
17
|
-
* properties: data bindings via RefSchema (or literal values).
|
|
18
|
-
* triggers: event name → TriggerSchema bindings. */
|
|
19
|
-
export interface ComponentSchema extends SchemaBase {
|
|
20
|
-
properties: Record<string, RefSchema | string | number | boolean>;
|
|
21
|
-
triggers: Record<string, TriggerSchema>;
|
|
1
|
+
import type { SchemaBase } from './dsl.js';
|
|
2
|
+
import type { RefSchema } from './ref.js';
|
|
3
|
+
import type { ActionSchema } from './action.js';
|
|
4
|
+
import type { EventDataSchema } from './event.js';
|
|
5
|
+
|
|
6
|
+
/** A component event trigger declaration. */
|
|
7
|
+
export interface TriggerSchema extends SchemaBase {
|
|
8
|
+
/** Data the event carries (e.g. e.detail). */
|
|
9
|
+
eventData?: EventDataSchema;
|
|
10
|
+
/** Actions that fire when the event occurs. */
|
|
11
|
+
actions?: ActionSchema[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** A UI component declaration — a virtual schema that describes props and
|
|
15
|
+
* event triggers, not a real renderable component.
|
|
16
|
+
*
|
|
17
|
+
* properties: data bindings via RefSchema (or literal values).
|
|
18
|
+
* triggers: event name → TriggerSchema bindings. */
|
|
19
|
+
export interface ComponentSchema extends SchemaBase {
|
|
20
|
+
properties: Record<string, RefSchema | string | number | boolean>;
|
|
21
|
+
triggers: Record<string, TriggerSchema>;
|
|
22
22
|
}
|
package/src/convert.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { SchemaBase } from './dsl.js';
|
|
2
|
-
import type { FrontAppSchema } from './project.js';
|
|
3
|
-
|
|
4
|
-
/** Declares post-call result → page data field mapping.
|
|
5
|
-
* Driver generates per-item transform (e.g. .map()) before setData. */
|
|
6
|
-
export interface ConvertSchema extends SchemaBase {
|
|
7
|
-
type: 'convert';
|
|
8
|
-
/** The frontend app this convert belongs to (shared instance from project.config). */
|
|
9
|
-
app: FrontAppSchema;
|
|
10
|
-
/** { targetField: sourceField } — renames or copies fields from call result. */
|
|
11
|
-
fields: Record<string, string>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function defineConvert(name: string, app: FrontAppSchema, fields: Record<string, string>): ConvertSchema {
|
|
15
|
-
return { name, type: 'convert', app, fields };
|
|
1
|
+
import type { SchemaBase } from './dsl.js';
|
|
2
|
+
import type { FrontAppSchema } from './project.js';
|
|
3
|
+
|
|
4
|
+
/** Declares post-call result → page data field mapping.
|
|
5
|
+
* Driver generates per-item transform (e.g. .map()) before setData. */
|
|
6
|
+
export interface ConvertSchema extends SchemaBase {
|
|
7
|
+
type: 'convert';
|
|
8
|
+
/** The frontend app this convert belongs to (shared instance from project.config). */
|
|
9
|
+
app: FrontAppSchema;
|
|
10
|
+
/** { targetField: sourceField } — renames or copies fields from call result. */
|
|
11
|
+
fields: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function defineConvert(name: string, app: FrontAppSchema, fields: Record<string, string>): ConvertSchema {
|
|
15
|
+
return { name, type: 'convert', app, fields };
|
|
16
16
|
}
|