@pylonts/dsl 1.1.18 → 1.1.19
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/dto.d.ts +6 -0
- package/dist/dto.js +28 -0
- package/dist/utils.d.ts +6 -3
- package/dist/utils.js +14 -4
- package/package.json +1 -1
- package/src/dto.ts +24 -0
- package/src/utils.ts +25 -7
package/dist/dto.d.ts
CHANGED
|
@@ -103,6 +103,12 @@ export declare function dtoField(field: Field | DtoArrayFieldDef | DtoObjectFiel
|
|
|
103
103
|
export declare function isDtoMessage(v: unknown): v is DtoMessage;
|
|
104
104
|
/** Structural check — a DtoField wraps a Field in a .field property and has no .type of its own. */
|
|
105
105
|
export declare function isDtoField(v: unknown): v is DtoField;
|
|
106
|
+
/** TS type of a DtoField in generated code — unwraps the wrapped field
|
|
107
|
+
* (enum → its JS name, date/datetime → string, containers → jsType). */
|
|
108
|
+
export declare function dtoFieldJsType(df: DtoField): string;
|
|
109
|
+
/** Enum JS names referenced by a DtoField, recursing into inline array/object
|
|
110
|
+
* wrappers; DtoMessage item references stop the walk. First-occurrence order. */
|
|
111
|
+
export declare function dtoCollectEnumRefs(df: DtoField, out?: string[]): string[];
|
|
106
112
|
export declare function dtoArrayField(def: {
|
|
107
113
|
items: DtoField | DtoMessage;
|
|
108
114
|
} & Omit<BaseField, 'name'>): DtoArrayField;
|
package/dist/dto.js
CHANGED
|
@@ -119,6 +119,34 @@ export function isDtoField(v) {
|
|
|
119
119
|
return false;
|
|
120
120
|
return 'field' in v && !('type' in v);
|
|
121
121
|
}
|
|
122
|
+
/** TS type of a DtoField in generated code — unwraps the wrapped field
|
|
123
|
+
* (enum → its JS name, date/datetime → string, containers → jsType). */
|
|
124
|
+
export function dtoFieldJsType(df) {
|
|
125
|
+
const f = df.field;
|
|
126
|
+
if (f.type === 'enum')
|
|
127
|
+
return f.enum.jsName;
|
|
128
|
+
if (f.type === 'date' || f.type === 'datetime')
|
|
129
|
+
return 'string';
|
|
130
|
+
return f.jsType;
|
|
131
|
+
}
|
|
132
|
+
/** Enum JS names referenced by a DtoField, recursing into inline array/object
|
|
133
|
+
* wrappers; DtoMessage item references stop the walk. First-occurrence order. */
|
|
134
|
+
export function dtoCollectEnumRefs(df, out = []) {
|
|
135
|
+
const f = df.field;
|
|
136
|
+
if (f.type === 'enum') {
|
|
137
|
+
out.push(f.enum.jsName);
|
|
138
|
+
}
|
|
139
|
+
else if (f.type === 'array') {
|
|
140
|
+
const items = f.items;
|
|
141
|
+
if (isDtoField(items))
|
|
142
|
+
dtoCollectEnumRefs(items, out);
|
|
143
|
+
}
|
|
144
|
+
else if (f.type === 'object') {
|
|
145
|
+
for (const child of Object.values(f.properties))
|
|
146
|
+
dtoCollectEnumRefs(child, out);
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
122
150
|
export function dtoArrayField(def) {
|
|
123
151
|
// Items stay as-is: an inline DtoField is rendered inline, a DtoMessage is
|
|
124
152
|
// referenced by name (the driver renders Type.Array(<DtoName>)).
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { CollectionSchemaBase, Field, SchemaBase } from './dsl.js';
|
|
2
|
+
import type { DtoField } from './dto.js';
|
|
2
3
|
import type { FrontAppSchema, ProjectApiSchema } from './project.js';
|
|
3
4
|
/** A utility method with a full signature. */
|
|
4
5
|
export interface UtilsMethodSchema extends SchemaBase {
|
|
5
6
|
type: 'utilsMethod';
|
|
6
7
|
/** The utility module this method belongs to. */
|
|
7
8
|
schema: UtilsSchema;
|
|
8
|
-
/** Input fields. */
|
|
9
|
-
args: Record<string,
|
|
10
|
-
/** Output field
|
|
9
|
+
/** Input fields — DtoField wrappers (dtoField(...)); may wrap table columns. */
|
|
10
|
+
args: Record<string, DtoField>;
|
|
11
|
+
/** Output field — a plain inline Field (boolean for checks, decimal for
|
|
12
|
+
* computed amounts, ...). The method output is a fresh value, never a
|
|
13
|
+
* shared table column. */
|
|
11
14
|
result: Field;
|
|
12
15
|
}
|
|
13
16
|
/** Method input for defineUtils: type/schema/name are set by the builder. */
|
package/dist/utils.js
CHANGED
|
@@ -20,13 +20,23 @@ export function defineUtils(options) {
|
|
|
20
20
|
args: method.args,
|
|
21
21
|
result: method.result,
|
|
22
22
|
};
|
|
23
|
+
// Args: write back on the DtoField wrapper only (safe: wrappers are
|
|
24
|
+
// created per method via dtoField(), never shared). Inline fields get
|
|
25
|
+
// their underlying Field written back too; fields wrapping table columns
|
|
26
|
+
// (domain rules) keep the shared column instance untouched — its
|
|
27
|
+
// name/schema already point to the table.
|
|
23
28
|
for (const argKey of Object.keys(methodSchema.args)) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const df = methodSchema.args[argKey];
|
|
30
|
+
df.name = argKey;
|
|
31
|
+
df.schema = schema;
|
|
32
|
+
if (df.field.schema === undefined) {
|
|
33
|
+
df.field.name = argKey;
|
|
34
|
+
df.field.schema = schema;
|
|
35
|
+
}
|
|
27
36
|
}
|
|
37
|
+
// Result: a plain inline Field — write name/schema back directly.
|
|
28
38
|
methodSchema.result.name = key;
|
|
29
|
-
methodSchema.result.schema =
|
|
39
|
+
methodSchema.result.schema = schema;
|
|
30
40
|
schema.methods[key] = methodSchema;
|
|
31
41
|
}
|
|
32
42
|
return schema;
|
package/package.json
CHANGED
package/src/dto.ts
CHANGED
|
@@ -185,6 +185,30 @@ export function isDtoField(v: unknown): v is DtoField {
|
|
|
185
185
|
return 'field' in v && !('type' in v);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/** TS type of a DtoField in generated code — unwraps the wrapped field
|
|
189
|
+
* (enum → its JS name, date/datetime → string, containers → jsType). */
|
|
190
|
+
export function dtoFieldJsType(df: DtoField): string {
|
|
191
|
+
const f = df.field;
|
|
192
|
+
if (f.type === 'enum') return f.enum.jsName;
|
|
193
|
+
if (f.type === 'date' || f.type === 'datetime') return 'string';
|
|
194
|
+
return f.jsType;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Enum JS names referenced by a DtoField, recursing into inline array/object
|
|
198
|
+
* wrappers; DtoMessage item references stop the walk. First-occurrence order. */
|
|
199
|
+
export function dtoCollectEnumRefs(df: DtoField, out: string[] = []): string[] {
|
|
200
|
+
const f = df.field;
|
|
201
|
+
if (f.type === 'enum') {
|
|
202
|
+
out.push(f.enum.jsName);
|
|
203
|
+
} else if (f.type === 'array') {
|
|
204
|
+
const items = f.items;
|
|
205
|
+
if (isDtoField(items)) dtoCollectEnumRefs(items, out);
|
|
206
|
+
} else if (f.type === 'object') {
|
|
207
|
+
for (const child of Object.values(f.properties)) dtoCollectEnumRefs(child, out);
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
|
|
188
212
|
export function dtoArrayField(def: { items: DtoField | DtoMessage } & Omit<BaseField, 'name'>): DtoArrayField {
|
|
189
213
|
// Items stay as-is: an inline DtoField is rendered inline, a DtoMessage is
|
|
190
214
|
// referenced by name (the driver renders Type.Array(<DtoName>)).
|
package/src/utils.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import type { CollectionSchemaBase, Field, SchemaBase } from './dsl.js';
|
|
2
|
+
import type { DtoField } from './dto.js';
|
|
2
3
|
import type { FrontAppSchema, ProjectApiSchema } from './project.js';
|
|
3
4
|
|
|
4
5
|
// Base utility modules — business-agnostic helpers with full method
|
|
5
6
|
// signatures (e.g. DateTimeUtils.format). Called at the service layer;
|
|
6
7
|
// their args/results are own wire types, independent of business schemas.
|
|
8
|
+
// A utils whose name matches a table name is a domain rule module: its
|
|
9
|
+
// methods may wrap table columns via dtoField(table.columns.x) — the DtoField
|
|
10
|
+
// wrapper owns the write-back, so the shared column instance is never
|
|
11
|
+
// mutated (same rule as buildMessage: only inline fields get their
|
|
12
|
+
// underlying Field written back).
|
|
7
13
|
|
|
8
14
|
/** A utility method with a full signature. */
|
|
9
15
|
export interface UtilsMethodSchema extends SchemaBase {
|
|
10
16
|
type: 'utilsMethod';
|
|
11
17
|
/** The utility module this method belongs to. */
|
|
12
18
|
schema: UtilsSchema;
|
|
13
|
-
/** Input fields. */
|
|
14
|
-
args: Record<string,
|
|
15
|
-
/** Output field
|
|
19
|
+
/** Input fields — DtoField wrappers (dtoField(...)); may wrap table columns. */
|
|
20
|
+
args: Record<string, DtoField>;
|
|
21
|
+
/** Output field — a plain inline Field (boolean for checks, decimal for
|
|
22
|
+
* computed amounts, ...). The method output is a fresh value, never a
|
|
23
|
+
* shared table column. */
|
|
16
24
|
result: Field;
|
|
17
25
|
}
|
|
18
26
|
|
|
@@ -62,13 +70,23 @@ export function defineUtils(options: {
|
|
|
62
70
|
args: method.args,
|
|
63
71
|
result: method.result,
|
|
64
72
|
};
|
|
73
|
+
// Args: write back on the DtoField wrapper only (safe: wrappers are
|
|
74
|
+
// created per method via dtoField(), never shared). Inline fields get
|
|
75
|
+
// their underlying Field written back too; fields wrapping table columns
|
|
76
|
+
// (domain rules) keep the shared column instance untouched — its
|
|
77
|
+
// name/schema already point to the table.
|
|
65
78
|
for (const argKey of Object.keys(methodSchema.args)) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
const df = methodSchema.args[argKey] as DtoField;
|
|
80
|
+
df.name = argKey;
|
|
81
|
+
df.schema = schema;
|
|
82
|
+
if (df.field.schema === undefined) {
|
|
83
|
+
df.field.name = argKey;
|
|
84
|
+
df.field.schema = schema;
|
|
85
|
+
}
|
|
69
86
|
}
|
|
87
|
+
// Result: a plain inline Field — write name/schema back directly.
|
|
70
88
|
methodSchema.result.name = key;
|
|
71
|
-
methodSchema.result.schema =
|
|
89
|
+
methodSchema.result.schema = schema;
|
|
72
90
|
schema.methods[key] = methodSchema;
|
|
73
91
|
}
|
|
74
92
|
return schema;
|