@pylonts/dsl 1.1.11 → 1.1.13
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/convert.d.ts +6 -8
- package/dist/curd.js +1 -1
- package/dist/dao.d.ts +10 -7
- package/dist/dao.js +20 -7
- package/dist/dsl.d.ts +18 -1
- package/dist/dsl.js +40 -0
- package/dist/dto.d.ts +13 -8
- package/dist/dto.js +68 -13
- package/dist/entity.d.ts +4 -3
- package/dist/entity.js +1 -1
- package/dist/filter.d.ts +6 -4
- package/dist/filter.js +1 -1
- package/dist/flow-script.js +8 -2
- package/dist/flow.d.ts +10 -2
- package/dist/flow.js +44 -4
- package/dist/mermaid-driver.js +2 -2
- package/dist/project.d.ts +5 -2
- package/dist/project.js +21 -2
- package/dist/service.d.ts +13 -8
- package/dist/service.js +1 -1
- package/dist/third-service.d.ts +10 -53
- package/dist/third-service.js +3 -78
- package/dist/typebox-driver.d.ts +0 -6
- package/dist/typebox-driver.js +8 -36
- package/dist/utils.d.ts +2 -2
- package/docs/curd.md +55 -20
- package/docs/dao-generation.md +477 -477
- package/docs/project.md +32 -24
- package/docs/token.md +326 -326
- package/package.json +1 -1
- package/src/action.ts +51 -51
- package/src/controller.ts +53 -53
- package/src/convert.ts +76 -78
- package/src/curd.ts +104 -104
- package/src/dao.ts +504 -485
- package/src/dsl.ts +296 -257
- package/src/dto.ts +323 -266
- package/src/entity.ts +43 -42
- package/src/expr.ts +64 -64
- package/src/filter.ts +71 -69
- package/src/flow-script.ts +702 -695
- package/src/flow.ts +1272 -1226
- package/src/index.ts +46 -46
- package/src/mermaid-driver.ts +339 -339
- package/src/mysql-driver.ts +108 -108
- package/src/project.ts +138 -114
- package/src/service.ts +112 -107
- package/src/third-service.ts +68 -191
- package/src/typebox-driver.ts +234 -268
- package/src/utils.ts +74 -74
package/src/dsl.ts
CHANGED
|
@@ -1,258 +1,297 @@
|
|
|
1
|
-
// DSL field type definitions.
|
|
2
|
-
// Shape: { type: <type name>, <extension fields> }
|
|
3
|
-
|
|
4
|
-
import type { DictionaryEntry } from './dictionary.js';
|
|
5
|
-
import type { ImportBase } from './import-base.js';
|
|
6
|
-
import type { MockDescriptor } from './mock.js';
|
|
7
|
-
import type { ComputeExpr } from './expr.js';
|
|
8
|
-
|
|
9
|
-
/** Field query comparison operators (search field semantics). */
|
|
10
|
-
export type Operator = 'eq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ne' | 'in' | 'null' | 'notNull';
|
|
11
|
-
|
|
12
|
-
export interface SchemaBase {
|
|
13
|
-
name: string;
|
|
14
|
-
description?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Schema base for cross-file entities. importRef locates the generating module; inline schemas omit it. */
|
|
18
|
-
export interface ImportableSchemaBase extends SchemaBase {
|
|
19
|
-
importRef?: ImportBase;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Field collection schemas (DB table vs DTO message); `type` is the discriminator */
|
|
23
|
-
export interface CollectionSchemaBase extends SchemaBase {
|
|
24
|
-
type: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface BaseField {
|
|
28
|
-
name: string;
|
|
29
|
-
/** 显示名称(中文标签) */
|
|
30
|
-
label?: string;
|
|
31
|
-
/** 字段描述 */
|
|
32
|
-
description?: string;
|
|
33
|
-
optional?: boolean;
|
|
34
|
-
readOnly?: boolean;
|
|
35
|
-
default?: string;
|
|
36
|
-
/** 所属 schema(db 或 dto) */
|
|
37
|
-
schema?: CollectionSchemaBase;
|
|
38
|
-
/** Pure-data mock descriptor for test data generation */
|
|
39
|
-
mock?: MockDescriptor;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface StringField extends BaseField {
|
|
43
|
-
type: 'string';
|
|
44
|
-
jsType: 'string';
|
|
45
|
-
minLength?: number;
|
|
46
|
-
maxLength?: number;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface TextField extends BaseField {
|
|
50
|
-
type: 'text';
|
|
51
|
-
jsType: 'string';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
interface IntField extends BaseField {
|
|
55
|
-
type: 'integer';
|
|
56
|
-
jsType: 'number';
|
|
57
|
-
min?: number;
|
|
58
|
-
max?: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
interface BigintField extends BaseField {
|
|
62
|
-
type: 'bigint';
|
|
63
|
-
jsType: 'string';
|
|
64
|
-
// Value is transported as string to keep precision beyond 2^53.
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
interface DecimalField extends BaseField {
|
|
68
|
-
type: 'decimal';
|
|
69
|
-
jsType: 'string';
|
|
70
|
-
precision: number;
|
|
71
|
-
scale: number;
|
|
72
|
-
// Value is transported as string to avoid binary float error.
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type RateUnit = 'pct' | 'pm' | 'bp';
|
|
76
|
-
|
|
77
|
-
export function rateScale(unit: RateUnit): number {
|
|
78
|
-
switch (unit) {
|
|
79
|
-
case 'pct': return 2;
|
|
80
|
-
case 'pm': return 3;
|
|
81
|
-
case 'bp': return 4;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
interface RateField extends BaseField {
|
|
86
|
-
type: 'rate';
|
|
87
|
-
jsType: 'string';
|
|
88
|
-
unit: RateUnit;
|
|
89
|
-
// Precision/scale are derived from unit at DDL/TypeBox render time,
|
|
90
|
-
// not stored on the field.
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
interface BooleanField extends BaseField {
|
|
94
|
-
type: 'boolean';
|
|
95
|
-
jsType: 'boolean';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
interface DateField extends BaseField {
|
|
99
|
-
type: 'date';
|
|
100
|
-
jsType: 'Date';
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
interface TimeField extends BaseField {
|
|
104
|
-
type: 'time';
|
|
105
|
-
jsType: 'string';
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
interface DateTimeField extends BaseField {
|
|
109
|
-
type: 'datetime';
|
|
110
|
-
jsType: 'Date';
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface EnumValue {
|
|
114
|
-
value: string | number;
|
|
115
|
-
symbol: string;
|
|
116
|
-
label: string;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** Shared enum definition. Pure value object, safe to reference from multiple fields/tables. */
|
|
120
|
-
export interface EnumDef {
|
|
121
|
-
/** JS 定义名称,如 MerchantStatus */
|
|
122
|
-
jsName: string;
|
|
123
|
-
valueType: 'string' | 'integer';
|
|
124
|
-
values: EnumValue[];
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function defineEnum(
|
|
128
|
-
jsName: string,
|
|
129
|
-
valueType: 'string' | 'integer',
|
|
130
|
-
values: EnumValue[],
|
|
131
|
-
): EnumDef {
|
|
132
|
-
return { jsName, valueType, values };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface EnumField extends BaseField {
|
|
136
|
-
type: 'enum';
|
|
137
|
-
jsType: 'string' | 'number';
|
|
138
|
-
/** Reference to a shared enum definition (see defineEnum). */
|
|
139
|
-
enum: EnumDef;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
interface JsonField extends BaseField {
|
|
143
|
-
type: 'json';
|
|
144
|
-
jsType: 'object';
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/** Recursive array field — wire-format nesting (third-party messages), not a table column. */
|
|
148
|
-
interface ArrayField extends BaseField {
|
|
149
|
-
type: 'array';
|
|
150
|
-
jsType: 'array';
|
|
151
|
-
/** Element type: any Field, including nested array/object. */
|
|
152
|
-
items: Field;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/** Recursive object field — wire-format nesting (third-party messages), not a table column. */
|
|
156
|
-
interface ObjectField extends BaseField {
|
|
157
|
-
type: 'object';
|
|
158
|
-
jsType: 'object';
|
|
159
|
-
properties: Record<string, Field>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/** Aggregate result column (count/sum/avg) of an aggregate query — a Field
|
|
163
|
-
* so that aggregate result entities can carry it like any other column.
|
|
164
|
-
* jsType follows the aggregate precision rule: count → number;
|
|
165
|
-
* sum/avg over an integer column → number, anything else → string. */
|
|
166
|
-
interface AggregateField extends BaseField {
|
|
167
|
-
type: 'aggregate';
|
|
168
|
-
jsType: 'number' | 'string';
|
|
169
|
-
/** The aggregate expression producing this column. */
|
|
170
|
-
expr: ComputeExpr;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
|
|
|
188
|
-
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
1
|
+
// DSL field type definitions.
|
|
2
|
+
// Shape: { type: <type name>, <extension fields> }
|
|
3
|
+
|
|
4
|
+
import type { DictionaryEntry } from './dictionary.js';
|
|
5
|
+
import type { ImportBase } from './import-base.js';
|
|
6
|
+
import type { MockDescriptor } from './mock.js';
|
|
7
|
+
import type { ComputeExpr } from './expr.js';
|
|
8
|
+
|
|
9
|
+
/** Field query comparison operators (search field semantics). */
|
|
10
|
+
export type Operator = 'eq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ne' | 'in' | 'null' | 'notNull';
|
|
11
|
+
|
|
12
|
+
export interface SchemaBase {
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Schema base for cross-file entities. importRef locates the generating module; inline schemas omit it. */
|
|
18
|
+
export interface ImportableSchemaBase extends SchemaBase {
|
|
19
|
+
importRef?: ImportBase;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Field collection schemas (DB table vs DTO message); `type` is the discriminator */
|
|
23
|
+
export interface CollectionSchemaBase extends SchemaBase {
|
|
24
|
+
type: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface BaseField {
|
|
28
|
+
name: string;
|
|
29
|
+
/** 显示名称(中文标签) */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** 字段描述 */
|
|
32
|
+
description?: string;
|
|
33
|
+
optional?: boolean;
|
|
34
|
+
readOnly?: boolean;
|
|
35
|
+
default?: string;
|
|
36
|
+
/** 所属 schema(db 或 dto) */
|
|
37
|
+
schema?: CollectionSchemaBase;
|
|
38
|
+
/** Pure-data mock descriptor for test data generation */
|
|
39
|
+
mock?: MockDescriptor;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface StringField extends BaseField {
|
|
43
|
+
type: 'string';
|
|
44
|
+
jsType: 'string';
|
|
45
|
+
minLength?: number;
|
|
46
|
+
maxLength?: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface TextField extends BaseField {
|
|
50
|
+
type: 'text';
|
|
51
|
+
jsType: 'string';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface IntField extends BaseField {
|
|
55
|
+
type: 'integer';
|
|
56
|
+
jsType: 'number';
|
|
57
|
+
min?: number;
|
|
58
|
+
max?: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface BigintField extends BaseField {
|
|
62
|
+
type: 'bigint';
|
|
63
|
+
jsType: 'string';
|
|
64
|
+
// Value is transported as string to keep precision beyond 2^53.
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface DecimalField extends BaseField {
|
|
68
|
+
type: 'decimal';
|
|
69
|
+
jsType: 'string';
|
|
70
|
+
precision: number;
|
|
71
|
+
scale: number;
|
|
72
|
+
// Value is transported as string to avoid binary float error.
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type RateUnit = 'pct' | 'pm' | 'bp';
|
|
76
|
+
|
|
77
|
+
export function rateScale(unit: RateUnit): number {
|
|
78
|
+
switch (unit) {
|
|
79
|
+
case 'pct': return 2;
|
|
80
|
+
case 'pm': return 3;
|
|
81
|
+
case 'bp': return 4;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface RateField extends BaseField {
|
|
86
|
+
type: 'rate';
|
|
87
|
+
jsType: 'string';
|
|
88
|
+
unit: RateUnit;
|
|
89
|
+
// Precision/scale are derived from unit at DDL/TypeBox render time,
|
|
90
|
+
// not stored on the field.
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface BooleanField extends BaseField {
|
|
94
|
+
type: 'boolean';
|
|
95
|
+
jsType: 'boolean';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface DateField extends BaseField {
|
|
99
|
+
type: 'date';
|
|
100
|
+
jsType: 'Date';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface TimeField extends BaseField {
|
|
104
|
+
type: 'time';
|
|
105
|
+
jsType: 'string';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface DateTimeField extends BaseField {
|
|
109
|
+
type: 'datetime';
|
|
110
|
+
jsType: 'Date';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface EnumValue {
|
|
114
|
+
value: string | number;
|
|
115
|
+
symbol: string;
|
|
116
|
+
label: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Shared enum definition. Pure value object, safe to reference from multiple fields/tables. */
|
|
120
|
+
export interface EnumDef {
|
|
121
|
+
/** JS 定义名称,如 MerchantStatus */
|
|
122
|
+
jsName: string;
|
|
123
|
+
valueType: 'string' | 'integer';
|
|
124
|
+
values: EnumValue[];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function defineEnum(
|
|
128
|
+
jsName: string,
|
|
129
|
+
valueType: 'string' | 'integer',
|
|
130
|
+
values: EnumValue[],
|
|
131
|
+
): EnumDef {
|
|
132
|
+
return { jsName, valueType, values };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface EnumField extends BaseField {
|
|
136
|
+
type: 'enum';
|
|
137
|
+
jsType: 'string' | 'number';
|
|
138
|
+
/** Reference to a shared enum definition (see defineEnum). */
|
|
139
|
+
enum: EnumDef;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface JsonField extends BaseField {
|
|
143
|
+
type: 'json';
|
|
144
|
+
jsType: 'object';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Recursive array field — wire-format nesting (third-party messages), not a table column. */
|
|
148
|
+
interface ArrayField extends BaseField {
|
|
149
|
+
type: 'array';
|
|
150
|
+
jsType: 'array';
|
|
151
|
+
/** Element type: any Field, including nested array/object. */
|
|
152
|
+
items: Field;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Recursive object field — wire-format nesting (third-party messages), not a table column. */
|
|
156
|
+
interface ObjectField extends BaseField {
|
|
157
|
+
type: 'object';
|
|
158
|
+
jsType: 'object';
|
|
159
|
+
properties: Record<string, Field>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Aggregate result column (count/sum/avg) of an aggregate query — a Field
|
|
163
|
+
* so that aggregate result entities can carry it like any other column.
|
|
164
|
+
* jsType follows the aggregate precision rule: count → number;
|
|
165
|
+
* sum/avg over an integer column → number, anything else → string. */
|
|
166
|
+
export interface AggregateField extends BaseField {
|
|
167
|
+
type: 'aggregate';
|
|
168
|
+
jsType: 'number' | 'string';
|
|
169
|
+
/** The aggregate expression producing this column. */
|
|
170
|
+
expr: ComputeExpr;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Whether the field is an aggregate result column — narrows to AggregateField. */
|
|
174
|
+
export function isAggregate(field: Field): field is AggregateField {
|
|
175
|
+
return field.type === 'aggregate';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export type Field =
|
|
179
|
+
| StringField
|
|
180
|
+
| TextField
|
|
181
|
+
| IntField
|
|
182
|
+
| BigintField
|
|
183
|
+
| DecimalField
|
|
184
|
+
| RateField
|
|
185
|
+
| BooleanField
|
|
186
|
+
| DateField
|
|
187
|
+
| TimeField
|
|
188
|
+
| DateTimeField
|
|
189
|
+
| EnumField
|
|
190
|
+
| JsonField
|
|
191
|
+
| ArrayField
|
|
192
|
+
| ObjectField
|
|
193
|
+
| AggregateField;
|
|
194
|
+
|
|
195
|
+
/** TS type of a field in generated code (row interfaces, dao params, filter
|
|
196
|
+
* args): enum → its JS name, date/datetime → string (transported as ISO
|
|
197
|
+
* strings), everything else → jsType. Aggregate fields carry their precision
|
|
198
|
+
* rule in jsType already. The single source for this mapping — renderers
|
|
199
|
+
* must not branch on field.type for a TS type string. */
|
|
200
|
+
export function fieldJsType(field: Field): string {
|
|
201
|
+
if (field.type === 'enum') return field.enum.jsName;
|
|
202
|
+
if (field.type === 'date' || field.type === 'datetime') return 'string';
|
|
203
|
+
return field.jsType;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Enum JS names referenced by a field, recursing into array/object
|
|
207
|
+
* containers (wire-format nesting). First-occurrence order — callers that
|
|
208
|
+
* need uniqueness collect into a Set. */
|
|
209
|
+
export function collectEnumRefs(field: Field, out: string[] = []): string[] {
|
|
210
|
+
walkContainer(field, (leaf) => {
|
|
211
|
+
if (leaf.type === 'enum') out.push(leaf.enum.jsName);
|
|
212
|
+
});
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Depth-first walk over a field's container structure: visit is called for
|
|
217
|
+
* every field including containers (top-level, array items, object
|
|
218
|
+
* properties). `key` is the object property name the field sits under
|
|
219
|
+
* (undefined for the top-level field and for array items). */
|
|
220
|
+
export function walkContainer(field: Field, visit: (f: Field, key?: string) => void, key?: string): void {
|
|
221
|
+
visit(field, key);
|
|
222
|
+
if (field.type === 'array') {
|
|
223
|
+
walkContainer(field.items, visit);
|
|
224
|
+
} else if (field.type === 'object') {
|
|
225
|
+
for (const [k, child] of Object.entries(field.properties)) walkContainer(child, visit, k);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Field builders: type and jsType are fixed, pass extra properties only.
|
|
230
|
+
// The field name is written back from the map key later (see defineTable).
|
|
231
|
+
|
|
232
|
+
type FieldExtras<T extends Field> = Omit<T, 'name' | 'type' | 'jsType'>;
|
|
233
|
+
|
|
234
|
+
export function stringField(extra: FieldExtras<StringField> = {}): StringField {
|
|
235
|
+
return { name: '', type: 'string', jsType: 'string', ...extra };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function textField(extra: FieldExtras<TextField> = {}): TextField {
|
|
239
|
+
return { name: '', type: 'text', jsType: 'string', ...extra };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function intField(extra: FieldExtras<IntField> = {}): IntField {
|
|
243
|
+
return { name: '', type: 'integer', jsType: 'number', ...extra };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function bigintField(extra: FieldExtras<BigintField> = {}): BigintField {
|
|
247
|
+
return { name: '', type: 'bigint', jsType: 'string', ...extra };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function decimalField(extra: FieldExtras<DecimalField>): DecimalField {
|
|
251
|
+
return { name: '', type: 'decimal', jsType: 'string', ...extra };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function rateField(unit: RateUnit, extra: Omit<FieldExtras<RateField>, 'unit'> = {}): RateField {
|
|
255
|
+
return { name: '', type: 'rate', jsType: 'string', unit, ...extra };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function booleanField(extra: FieldExtras<BooleanField> = {}): BooleanField {
|
|
259
|
+
return { name: '', type: 'boolean', jsType: 'boolean', ...extra };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function dateField(extra: FieldExtras<DateField> = {}): DateField {
|
|
263
|
+
return { name: '', type: 'date', jsType: 'Date', ...extra };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export function timeField(extra: FieldExtras<TimeField> = {}): TimeField {
|
|
267
|
+
return { name: '', type: 'time', jsType: 'string', ...extra };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function datetimeField(extra: FieldExtras<DateTimeField> = {}): DateTimeField {
|
|
271
|
+
return { name: '', type: 'datetime', jsType: 'Date', ...extra };
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function jsonField(extra: FieldExtras<JsonField> = {}): JsonField {
|
|
275
|
+
return { name: '', type: 'json', jsType: 'object', ...extra };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function arrayField(extra: FieldExtras<ArrayField>): ArrayField {
|
|
279
|
+
return { name: '', type: 'array', jsType: 'array', ...extra };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function objectField(extra: FieldExtras<ObjectField>): ObjectField {
|
|
283
|
+
return { name: '', type: 'object', jsType: 'object', ...extra };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function enumField(extra: Omit<EnumField, 'name' | 'type' | 'jsType'>): EnumField {
|
|
287
|
+
const jsType = extra.enum.valueType === 'integer' ? 'number' : 'string';
|
|
288
|
+
return { name: '', type: 'enum', jsType, ...extra };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Aggregate result column field: count → number; sum/avg over an integer
|
|
292
|
+
* column → number, anything else (decimal/bigint/rate…) → string.
|
|
293
|
+
* Used in aggregate-query result entities (see AggregateSchema). */
|
|
294
|
+
export function aggField(name: string, expr: ComputeExpr): AggregateField {
|
|
295
|
+
const jsType = expr.field === undefined || expr.field.type === 'integer' ? 'number' : 'string';
|
|
296
|
+
return { name, type: 'aggregate', jsType, expr };
|
|
258
297
|
}
|