sonamu 0.1.6 → 0.2.1
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/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +8 -8
- package/dist/entity/entity.js.map +1 -1
- package/dist/syncer/syncer.d.ts +2 -2
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +47 -49
- package/dist/syncer/syncer.js.map +1 -1
- package/dist/templates/base-template.d.ts +1 -1
- package/dist/templates/base-template.d.ts.map +1 -1
- package/dist/templates/generated.template.d.ts +11 -19
- package/dist/templates/generated.template.d.ts.map +1 -1
- package/dist/templates/generated.template.js +112 -84
- package/dist/templates/generated.template.js.map +1 -1
- package/dist/templates/generated_http.template.d.ts +1 -1
- package/dist/templates/generated_http.template.d.ts.map +1 -1
- package/dist/templates/generated_http.template.js.map +1 -1
- package/dist/templates/generated_sso.template.d.ts +17 -0
- package/dist/templates/generated_sso.template.d.ts.map +1 -0
- package/dist/templates/generated_sso.template.js +61 -0
- package/dist/templates/generated_sso.template.js.map +1 -0
- package/dist/templates/init_types.template.d.ts.map +1 -1
- package/dist/templates/init_types.template.js +3 -2
- package/dist/templates/init_types.template.js.map +1 -1
- package/dist/templates/model.template.d.ts.map +1 -1
- package/dist/templates/model.template.js +25 -3
- package/dist/templates/model.template.js.map +1 -1
- package/dist/templates/service.template.d.ts.map +1 -1
- package/dist/templates/service.template.js.map +1 -1
- package/dist/templates/view_enums_dropdown.template.d.ts +1 -1
- package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -1
- package/dist/templates/view_enums_dropdown.template.js +8 -3
- package/dist/templates/view_enums_dropdown.template.js.map +1 -1
- package/dist/templates/view_enums_select.template.js +2 -2
- package/dist/templates/view_enums_select.template.js.map +1 -1
- package/dist/templates/view_form.template.d.ts +4 -6
- package/dist/templates/view_form.template.d.ts.map +1 -1
- package/dist/templates/view_form.template.js +30 -13
- package/dist/templates/view_form.template.js.map +1 -1
- package/dist/templates/view_id_async_select.template.js +3 -2
- package/dist/templates/view_id_async_select.template.js.map +1 -1
- package/dist/templates/view_list.template.d.ts +7 -10
- package/dist/templates/view_list.template.d.ts.map +1 -1
- package/dist/templates/view_list.template.js +32 -33
- package/dist/templates/view_list.template.js.map +1 -1
- package/dist/types/types.d.ts +7 -14
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +3 -3
- package/dist/types/types.js.map +1 -1
- package/package.json +1 -1
- package/src/entity/entity.ts +9 -18
- package/src/syncer/syncer.ts +59 -65
- package/src/templates/base-template.ts +1 -1
- package/src/templates/generated.template.ts +131 -134
- package/src/templates/generated_http.template.ts +1 -1
- package/src/templates/generated_sso.template.ts +85 -0
- package/src/templates/init_types.template.ts +9 -2
- package/src/templates/model.template.ts +37 -7
- package/src/templates/service.template.ts +1 -0
- package/src/templates/view_enums_dropdown.template.ts +10 -3
- package/src/templates/view_enums_select.template.ts +2 -2
- package/src/templates/view_form.template.ts +36 -21
- package/src/templates/view_id_async_select.template.ts +2 -2
- package/src/templates/view_list.template.ts +34 -52
- package/src/types/types.ts +3 -3
|
@@ -1,152 +1,158 @@
|
|
|
1
|
-
import { camelize } from "inflection";
|
|
2
1
|
import { uniq } from "lodash";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
isDateTimeProp,
|
|
6
|
-
isTimestampProp,
|
|
7
|
-
TemplateOptions,
|
|
8
|
-
} from "../types/types";
|
|
9
|
-
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
2
|
+
import { TemplateOptions } from "../types/types";
|
|
3
|
+
import { EntityManager } from "../entity/entity-manager";
|
|
10
4
|
import { Entity } from "../entity/entity";
|
|
11
|
-
import { EntityPropNode
|
|
5
|
+
import { EntityPropNode } from "../types/types";
|
|
12
6
|
import { propNodeToZodTypeDef, zodTypeToZodCode } from "../api/code-converters";
|
|
13
7
|
import { Template } from "./base-template";
|
|
8
|
+
import { nonNullable } from "../utils/utils";
|
|
14
9
|
|
|
10
|
+
export type SourceCode = {
|
|
11
|
+
label: string;
|
|
12
|
+
lines: string[];
|
|
13
|
+
importKeys: string[];
|
|
14
|
+
};
|
|
15
15
|
export class Template__generated extends Template {
|
|
16
16
|
constructor() {
|
|
17
17
|
super("generated");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
getTargetAndPath(
|
|
20
|
+
getTargetAndPath() {
|
|
21
21
|
return {
|
|
22
22
|
target: "api/src/application",
|
|
23
|
-
path:
|
|
23
|
+
path: `sonamu.generated.ts`,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
render({
|
|
28
|
-
const
|
|
27
|
+
render({}: TemplateOptions["generated"]) {
|
|
28
|
+
const entityIds = EntityManager.getAllIds();
|
|
29
|
+
const entities = entityIds.map((id) => EntityManager.get(id));
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
// 전체 SourceCode 생성
|
|
32
|
+
const sourceCodes = entities
|
|
33
|
+
.map((entity) => {
|
|
34
|
+
return [
|
|
35
|
+
this.getEnumsSourceCode(entity),
|
|
36
|
+
this.getBaseSchemaSourceCode(entity),
|
|
37
|
+
this.getBaseListParamsSourceCode(entity),
|
|
38
|
+
this.getSubsetSourceCode(entity),
|
|
39
|
+
].filter(nonNullable);
|
|
40
|
+
})
|
|
41
|
+
.flat();
|
|
42
|
+
|
|
43
|
+
// Sort
|
|
44
|
+
const LABEL_KEY_ORDER = [
|
|
45
|
+
"Enums",
|
|
46
|
+
"BaseSchema",
|
|
47
|
+
"BaseListParams",
|
|
48
|
+
"Subsets",
|
|
49
|
+
"SubsetQueries",
|
|
50
|
+
];
|
|
51
|
+
sourceCodes.sort((a, b) => {
|
|
52
|
+
const [aKey] = a.label.split(":");
|
|
53
|
+
const [bKey] = b.label.split(":");
|
|
54
|
+
const aIndex = LABEL_KEY_ORDER.indexOf(aKey);
|
|
55
|
+
const bIndex = LABEL_KEY_ORDER.indexOf(bKey);
|
|
56
|
+
if (aIndex > bIndex) {
|
|
57
|
+
return 1;
|
|
58
|
+
} else if (aIndex < bIndex) {
|
|
59
|
+
return -1;
|
|
60
|
+
} else {
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const sourceCode = sourceCodes.reduce(
|
|
40
66
|
(result, ts) => {
|
|
41
67
|
if (ts === null) {
|
|
42
68
|
return result;
|
|
43
69
|
}
|
|
44
70
|
return {
|
|
45
|
-
lines: [...result!.lines, ...ts.lines],
|
|
71
|
+
lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, ""],
|
|
46
72
|
importKeys: uniq([...result!.importKeys, ...ts.importKeys]),
|
|
47
73
|
};
|
|
48
74
|
},
|
|
49
75
|
{
|
|
50
76
|
lines: [],
|
|
51
77
|
importKeys: [],
|
|
52
|
-
}
|
|
78
|
+
} as Omit<SourceCode, "label">
|
|
53
79
|
);
|
|
54
80
|
|
|
55
|
-
// .types.ts의 타입을 참조하는 경우 순환참조(상호참조)가 발생하므로
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
// .types.ts의 타입을 참조하는 경우 순환참조(상호참조)가 발생하므로 타입을 가져와 인라인 처리
|
|
82
|
+
const allTypeKeys = entities
|
|
83
|
+
.map((entity) => Object.keys(entity.types))
|
|
84
|
+
.flat();
|
|
85
|
+
const cdImportKeys = sourceCode.importKeys.filter((importKey) =>
|
|
86
|
+
allTypeKeys.includes(importKey)
|
|
59
87
|
);
|
|
60
88
|
if (cdImportKeys.length > 0) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
89
|
+
const customScalarLines = cdImportKeys
|
|
90
|
+
.map((importKey) => {
|
|
91
|
+
const entity = entities.find((entity) => entity.types[importKey]);
|
|
92
|
+
if (!entity) {
|
|
93
|
+
throw new Error(`ZodType not found ${importKey}`);
|
|
94
|
+
}
|
|
95
|
+
const zodType = entity.types[importKey]!;
|
|
96
|
+
|
|
97
|
+
return [
|
|
98
|
+
`// CustomScalar: ${importKey}`,
|
|
99
|
+
`const ${importKey} = ${zodTypeToZodCode(zodType)};`,
|
|
68
100
|
`type ${importKey} = z.infer<typeof ${importKey}>`,
|
|
69
101
|
"",
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
typeSource.importKeys = typeSource.importKeys.filter(
|
|
102
|
+
];
|
|
103
|
+
})
|
|
104
|
+
.flat();
|
|
105
|
+
sourceCode.lines = [...customScalarLines, ...sourceCode.lines];
|
|
106
|
+
sourceCode.importKeys = sourceCode.importKeys.filter(
|
|
76
107
|
(importKey) => !cdImportKeys.includes(importKey)
|
|
77
108
|
);
|
|
78
109
|
}
|
|
79
110
|
|
|
80
|
-
|
|
81
|
-
const names = EntityManager.getNamesFromId(entityId);
|
|
82
|
-
const targetAndPath = this.getTargetAndPath(names);
|
|
111
|
+
const body = sourceCode.lines.join("\n");
|
|
83
112
|
|
|
84
113
|
// import
|
|
85
114
|
const sonamuImports = [
|
|
86
115
|
"zArrayable",
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
? ["SQLDateTimeString"]
|
|
91
|
-
: []),
|
|
92
|
-
];
|
|
116
|
+
"SQLDateTimeString",
|
|
117
|
+
"SubsetQuery",
|
|
118
|
+
].filter((mod) => body.includes(mod));
|
|
93
119
|
|
|
94
120
|
return {
|
|
95
|
-
...
|
|
96
|
-
body
|
|
97
|
-
|
|
98
|
-
.trim(),
|
|
99
|
-
importKeys: typeSource?.importKeys ?? [],
|
|
121
|
+
...this.getTargetAndPath(),
|
|
122
|
+
body,
|
|
123
|
+
importKeys: sourceCode.importKeys,
|
|
100
124
|
customHeaders: [
|
|
101
125
|
`import { z } from 'zod';`,
|
|
102
|
-
|
|
103
|
-
? `import { ${sonamuImports.join(",")} } from "sonamu";`
|
|
104
|
-
: "",
|
|
126
|
+
`import { ${sonamuImports.join(",")} } from "sonamu";`,
|
|
105
127
|
],
|
|
106
128
|
};
|
|
107
129
|
}
|
|
108
130
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const childrenIds = EntityManager.getChildrenIds(entity.id);
|
|
114
|
-
const entities = [
|
|
115
|
-
entity,
|
|
116
|
-
...childrenIds.map((id) => EntityManager.get(id)),
|
|
117
|
-
];
|
|
118
|
-
|
|
131
|
+
getEnumsSourceCode(entity: Entity): SourceCode | null {
|
|
132
|
+
if (Object.keys(entity.enumLabels).length === 0) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
119
135
|
return {
|
|
136
|
+
label: `Enums: ${entity.id}`,
|
|
120
137
|
lines: [
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
`export const ${enumId}Label = ${JSON.stringify(enumLabel)}`,
|
|
130
|
-
])
|
|
131
|
-
)
|
|
132
|
-
.flat()
|
|
138
|
+
...Object.entries(entity.enumLabels)
|
|
139
|
+
.map(([enumId, enumLabel]) => [
|
|
140
|
+
`export const ${enumId} = z.enum([${Object.keys(enumLabel).map(
|
|
141
|
+
(el) => `"${el}"`
|
|
142
|
+
)}]).describe("${enumId}");`,
|
|
143
|
+
`export type ${enumId} = z.infer<typeof ${enumId}>`,
|
|
144
|
+
`export const ${enumId}Label = ${JSON.stringify(enumLabel)}`,
|
|
145
|
+
])
|
|
133
146
|
.flat(),
|
|
134
|
-
"",
|
|
135
147
|
],
|
|
136
148
|
importKeys: [],
|
|
137
149
|
};
|
|
138
150
|
}
|
|
139
151
|
|
|
140
|
-
|
|
152
|
+
getBaseSchemaSourceCode(
|
|
141
153
|
entity: Entity,
|
|
142
|
-
depth: number = 0,
|
|
143
154
|
importKeys: string[] = []
|
|
144
|
-
): {
|
|
145
|
-
lines: string[];
|
|
146
|
-
importKeys: string[];
|
|
147
|
-
} {
|
|
148
|
-
const childrenIds = EntityManager.getChildrenIds(entity.id);
|
|
149
|
-
|
|
155
|
+
): SourceCode {
|
|
150
156
|
const schemaName = `${entity.names.module}BaseSchema`;
|
|
151
157
|
const propNode: EntityPropNode = {
|
|
152
158
|
nodeType: "object",
|
|
@@ -163,35 +169,21 @@ export class Template__generated extends Template {
|
|
|
163
169
|
const lines = [
|
|
164
170
|
`export const ${schemaName} = ${schemaBody}`,
|
|
165
171
|
`export type ${schemaName} = z.infer<typeof ${schemaName}>`,
|
|
166
|
-
...childrenIds
|
|
167
|
-
.map((childId) => {
|
|
168
|
-
const child = EntityManager.get(childId);
|
|
169
|
-
const { lines } = this.getBaseSchemaTypeSource(
|
|
170
|
-
child,
|
|
171
|
-
depth + 1,
|
|
172
|
-
importKeys
|
|
173
|
-
);
|
|
174
|
-
return lines;
|
|
175
|
-
})
|
|
176
|
-
.flat(),
|
|
177
172
|
];
|
|
178
173
|
|
|
179
174
|
return {
|
|
175
|
+
label: `BaseSchema: ${entity.id}`,
|
|
180
176
|
importKeys,
|
|
181
177
|
lines,
|
|
182
178
|
};
|
|
183
179
|
}
|
|
184
180
|
|
|
185
|
-
|
|
186
|
-
lines: string[];
|
|
187
|
-
importKeys: string[];
|
|
188
|
-
} {
|
|
181
|
+
getBaseListParamsSourceCode(entity: Entity): SourceCode | null {
|
|
189
182
|
// Prop 없는 MD인 경우 생성 제외
|
|
190
183
|
if (entity.props.length === 0) {
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
};
|
|
184
|
+
return null;
|
|
185
|
+
} else if (entity.parentId !== undefined) {
|
|
186
|
+
return null;
|
|
195
187
|
}
|
|
196
188
|
|
|
197
189
|
const schemaName = `${entity.names.module}BaseListParams`;
|
|
@@ -229,35 +221,23 @@ z.object({
|
|
|
229
221
|
];
|
|
230
222
|
|
|
231
223
|
return {
|
|
224
|
+
label: `BaseListParams: ${entity.id}`,
|
|
232
225
|
importKeys,
|
|
233
226
|
lines,
|
|
234
227
|
};
|
|
235
228
|
}
|
|
236
229
|
|
|
237
|
-
|
|
238
|
-
lines: string[];
|
|
239
|
-
importKeys: string[];
|
|
240
|
-
} | null {
|
|
230
|
+
getSubsetSourceCode(entity: Entity): SourceCode | null {
|
|
241
231
|
if (Object.keys(entity.subsets).length == 0) {
|
|
242
232
|
return null;
|
|
233
|
+
} else if (entity.parentId !== undefined) {
|
|
234
|
+
return null;
|
|
243
235
|
}
|
|
244
236
|
|
|
245
237
|
const subsetKeys = Object.keys(entity.subsets);
|
|
246
|
-
|
|
247
|
-
const subsetQueryObject = subsetKeys.reduce(
|
|
248
|
-
(r, subsetKey) => {
|
|
249
|
-
const subsetQuery = entity.getSubsetQuery(subsetKey);
|
|
250
|
-
r[subsetKey] = subsetQuery;
|
|
251
|
-
return r;
|
|
252
|
-
},
|
|
253
|
-
{} as {
|
|
254
|
-
[key: string]: SubsetQuery;
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
|
|
258
238
|
const importKeys: string[] = [];
|
|
259
239
|
const lines: string[] = [
|
|
260
|
-
|
|
240
|
+
// `// Subsets: ${entity.id}`,
|
|
261
241
|
...subsetKeys
|
|
262
242
|
.map((subsetKey) => {
|
|
263
243
|
// 서브셋에서 FieldExpr[] 가져옴
|
|
@@ -277,11 +257,9 @@ z.object({
|
|
|
277
257
|
return [
|
|
278
258
|
`export const ${schemaName} = ${body}`,
|
|
279
259
|
`export type ${schemaName} = z.infer<typeof ${schemaName}>`,
|
|
280
|
-
"",
|
|
281
260
|
];
|
|
282
261
|
})
|
|
283
262
|
.flat(),
|
|
284
|
-
"",
|
|
285
263
|
`export type ${entity.names.module}SubsetMapping = {`,
|
|
286
264
|
...subsetKeys.map(
|
|
287
265
|
(subsetKey) =>
|
|
@@ -293,14 +271,33 @@ z.object({
|
|
|
293
271
|
.join(",")}]);`,
|
|
294
272
|
`export type ${entity.names.module}SubsetKey = z.infer<typeof ${entity.names.module}SubsetKey>`,
|
|
295
273
|
"",
|
|
296
|
-
"/* BEGIN- Server-side Only */",
|
|
297
|
-
`import { SubsetQuery } from "sonamu";`,
|
|
298
|
-
`export const ${camelize(entity.id, true)}SubsetQueries:{ [key in ${
|
|
299
|
-
|
|
300
|
-
}SubsetKey]: SubsetQuery} = ${JSON.stringify(subsetQueryObject)}`,
|
|
301
|
-
"",
|
|
274
|
+
// "/* BEGIN- Server-side Only */",
|
|
275
|
+
// // `import { SubsetQuery } from "sonamu";`,
|
|
276
|
+
// `export const ${camelize(entity.id, true)}SubsetQueries:{ [key in ${
|
|
277
|
+
// entity.names.module
|
|
278
|
+
// }SubsetKey]: SubsetQuery} = ${JSON.stringify(subsetQueryObject)}`,
|
|
279
|
+
// "",
|
|
302
280
|
];
|
|
281
|
+
|
|
282
|
+
// ServerSide Only
|
|
283
|
+
// const subsetQueryObject = subsetKeys.reduce(
|
|
284
|
+
// (r, subsetKey) => {
|
|
285
|
+
// const subsetQuery = entity.getSubsetQuery(subsetKey);
|
|
286
|
+
// r[subsetKey] = subsetQuery;
|
|
287
|
+
// return r;
|
|
288
|
+
// },
|
|
289
|
+
// {} as {
|
|
290
|
+
// [key: string]: SubsetQuery;
|
|
291
|
+
// }
|
|
292
|
+
// );
|
|
293
|
+
// const lines2: string[] = [
|
|
294
|
+
// `export const ${camelize(entity.id, true)}SubsetQueries:{ [key in ${
|
|
295
|
+
// entity.names.module
|
|
296
|
+
// }SubsetKey]: SubsetQuery} = ${JSON.stringify(subsetQueryObject)}`,
|
|
297
|
+
// ];
|
|
298
|
+
|
|
303
299
|
return {
|
|
300
|
+
label: `Subsets: ${entity.id}`,
|
|
304
301
|
lines,
|
|
305
302
|
importKeys: uniq(importKeys),
|
|
306
303
|
};
|
|
@@ -21,7 +21,7 @@ export class Template__generated_http extends Template {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
render({ entityId }: TemplateOptions["
|
|
24
|
+
render({ entityId }: TemplateOptions["generated_http"], apis: ExtendedApi[]) {
|
|
25
25
|
const names = EntityManager.getNamesFromId(entityId);
|
|
26
26
|
const references = Sonamu.syncer.types;
|
|
27
27
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { SubsetQuery, TemplateOptions } from "../types/types";
|
|
2
|
+
import { EntityManager } from "../entity/entity-manager";
|
|
3
|
+
import { Template } from "./base-template";
|
|
4
|
+
import { camelize } from "inflection";
|
|
5
|
+
import { SourceCode } from "./generated.template";
|
|
6
|
+
import { uniq } from "lodash";
|
|
7
|
+
import { nonNullable } from "../utils/utils";
|
|
8
|
+
|
|
9
|
+
export class Template__generated_sso extends Template {
|
|
10
|
+
constructor() {
|
|
11
|
+
super("generated_sso");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getTargetAndPath() {
|
|
15
|
+
return {
|
|
16
|
+
target: "api/src/application",
|
|
17
|
+
path: `sonamu.generated.sso.ts`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
render({}: TemplateOptions["generated_sso"]) {
|
|
22
|
+
const entityIds = EntityManager.getAllIds();
|
|
23
|
+
const entities = entityIds.map((id) => EntityManager.get(id));
|
|
24
|
+
|
|
25
|
+
const sourceCodes: SourceCode[] = entities
|
|
26
|
+
.map((entity) => {
|
|
27
|
+
if (
|
|
28
|
+
entity.parentId !== undefined ||
|
|
29
|
+
Object.keys(entity.subsets).length === 0
|
|
30
|
+
) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const subsetKeys = Object.keys(entity.subsets);
|
|
34
|
+
const subsetQueryObject = subsetKeys.reduce(
|
|
35
|
+
(r, subsetKey) => {
|
|
36
|
+
const subsetQuery = entity.getSubsetQuery(subsetKey);
|
|
37
|
+
r[subsetKey] = subsetQuery;
|
|
38
|
+
return r;
|
|
39
|
+
},
|
|
40
|
+
{} as {
|
|
41
|
+
[key: string]: SubsetQuery;
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const subsetKeyTypeName = `${entity.names.module}SubsetKey`;
|
|
46
|
+
return {
|
|
47
|
+
label: `SubsetQuery: ${entity.id}`,
|
|
48
|
+
lines: [
|
|
49
|
+
`export const ${camelize(
|
|
50
|
+
entity.id,
|
|
51
|
+
true
|
|
52
|
+
)}SubsetQueries:{ [key in ${subsetKeyTypeName}]: SubsetQuery} = ${JSON.stringify(
|
|
53
|
+
subsetQueryObject
|
|
54
|
+
)};`,
|
|
55
|
+
"",
|
|
56
|
+
],
|
|
57
|
+
importKeys: [subsetKeyTypeName],
|
|
58
|
+
};
|
|
59
|
+
})
|
|
60
|
+
.filter(nonNullable);
|
|
61
|
+
|
|
62
|
+
const sourceCode = sourceCodes.reduce(
|
|
63
|
+
(result, ts) => {
|
|
64
|
+
if (ts === null) {
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, ""],
|
|
69
|
+
importKeys: uniq([...result!.importKeys, ...ts.importKeys]),
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
lines: [],
|
|
74
|
+
importKeys: [],
|
|
75
|
+
} as Omit<SourceCode, "label">
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
...this.getTargetAndPath(),
|
|
80
|
+
body: sourceCode.lines.join("\n"),
|
|
81
|
+
importKeys: sourceCode.importKeys,
|
|
82
|
+
customHeaders: [`import { SubsetQuery } from "sonamu";`],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -17,18 +17,25 @@ export class Template__init_types extends Template {
|
|
|
17
17
|
render({ entityId }: TemplateOptions["init_types"]) {
|
|
18
18
|
const names = EntityManager.getNamesFromId(entityId);
|
|
19
19
|
|
|
20
|
+
const hasCreatedAt =
|
|
21
|
+
EntityManager.get(entityId).props.find(
|
|
22
|
+
(prop) => prop.name === "created_at"
|
|
23
|
+
) !== undefined;
|
|
24
|
+
|
|
20
25
|
return {
|
|
21
26
|
...this.getTargetAndPath(names),
|
|
22
27
|
body: `
|
|
23
28
|
import { z } from "zod";
|
|
24
|
-
import { ${entityId}BaseSchema, ${entityId}BaseListParams } from "
|
|
29
|
+
import { ${entityId}BaseSchema, ${entityId}BaseListParams } from "../sonamu.generated";
|
|
25
30
|
|
|
26
31
|
// ${entityId} - ListParams
|
|
27
32
|
export const ${entityId}ListParams = ${entityId}BaseListParams;
|
|
28
33
|
export type ${entityId}ListParams = z.infer<typeof ${entityId}ListParams>;
|
|
29
34
|
|
|
30
35
|
// ${entityId} - SaveParams
|
|
31
|
-
export const ${entityId}SaveParams = ${entityId}BaseSchema.partial({ id: true
|
|
36
|
+
export const ${entityId}SaveParams = ${entityId}BaseSchema.partial({ id: true${
|
|
37
|
+
hasCreatedAt ? ", created_at: true" : ""
|
|
38
|
+
} });
|
|
32
39
|
export type ${entityId}SaveParams = z.infer<typeof ${entityId}SaveParams>;
|
|
33
40
|
|
|
34
41
|
`.trim(),
|
|
@@ -24,7 +24,10 @@ export class Template__model extends Template {
|
|
|
24
24
|
const entity = EntityManager.get(entityId);
|
|
25
25
|
|
|
26
26
|
const vlTpl = new Template__view_list();
|
|
27
|
-
|
|
27
|
+
if (listParamsNode?.children === undefined) {
|
|
28
|
+
throw new Error(`listParamsNode가 없습니다. ${entityId}`);
|
|
29
|
+
}
|
|
30
|
+
const def = vlTpl.getDefault(listParamsNode.children);
|
|
28
31
|
|
|
29
32
|
return {
|
|
30
33
|
...this.getTargetAndPath(names),
|
|
@@ -33,9 +36,13 @@ import { BaseModelClass, ListResult, asArray, NotFoundException, BadRequestExcep
|
|
|
33
36
|
import {
|
|
34
37
|
${entityId}SubsetKey,
|
|
35
38
|
${entityId}SubsetMapping,
|
|
39
|
+
} from "../sonamu.generated";
|
|
40
|
+
import {
|
|
36
41
|
${names.camel}SubsetQueries,
|
|
37
|
-
} from "
|
|
38
|
-
import { ${entityId}ListParams, ${entityId}SaveParams } from "./${
|
|
42
|
+
} from "../sonamu.generated.sso";
|
|
43
|
+
import { ${entityId}ListParams, ${entityId}SaveParams } from "./${
|
|
44
|
+
names.fs
|
|
45
|
+
}.types";
|
|
39
46
|
|
|
40
47
|
/*
|
|
41
48
|
${entityId} Model
|
|
@@ -73,7 +80,9 @@ class ${entityId}ModelClass extends BaseModelClass {
|
|
|
73
80
|
return rows[0] ?? null;
|
|
74
81
|
}
|
|
75
82
|
|
|
76
|
-
@api({ httpMethod: "GET", clients: ["axios", "swr"], resourceName: "${
|
|
83
|
+
@api({ httpMethod: "GET", clients: ["axios", "swr"], resourceName: "${
|
|
84
|
+
names.capitalPlural
|
|
85
|
+
}" })
|
|
77
86
|
async findMany<T extends ${entityId}SubsetKey>(
|
|
78
87
|
subset: T,
|
|
79
88
|
params: ${entityId}ListParams = {}
|
|
@@ -103,7 +112,9 @@ class ${entityId}ModelClass extends BaseModelClass {
|
|
|
103
112
|
if (params.search === "id") {
|
|
104
113
|
qb.where("${entity.table}.id", params.keyword);
|
|
105
114
|
// } else if (params.search === "field") {
|
|
106
|
-
// qb.where("${
|
|
115
|
+
// qb.where("${
|
|
116
|
+
entity.table
|
|
117
|
+
}.field", "like", \`%\${params.keyword}%\`);
|
|
107
118
|
} else {
|
|
108
119
|
throw new BadRequestException(
|
|
109
120
|
\`구현되지 않은 검색 필드 \${params.search}\`
|
|
@@ -137,9 +148,28 @@ class ${entityId}ModelClass extends BaseModelClass {
|
|
|
137
148
|
const ub = this.getUpsertBuilder();
|
|
138
149
|
|
|
139
150
|
// register
|
|
140
|
-
|
|
151
|
+
${(() => {
|
|
152
|
+
const jsonProps = entity.props.filter((prop) => prop.type === "json");
|
|
153
|
+
if (jsonProps.length === 0) {
|
|
154
|
+
return `saveParamsArray.map((saveParams) => {
|
|
141
155
|
ub.register("${entity.table}", saveParams);
|
|
142
|
-
})
|
|
156
|
+
});`;
|
|
157
|
+
} else {
|
|
158
|
+
return `saveParamsArray.map(({${jsonProps
|
|
159
|
+
.map((prop) => prop.name)
|
|
160
|
+
.join(", ")}, ...saveParams}) => {
|
|
161
|
+
ub.register("${entity.table}", {
|
|
162
|
+
${jsonProps
|
|
163
|
+
.map(
|
|
164
|
+
(prop) =>
|
|
165
|
+
`${prop.name}: ${prop.name} === null ? null : JSON.stringify(${prop.name}),`
|
|
166
|
+
)
|
|
167
|
+
.join(",\n")}
|
|
168
|
+
...saveParams
|
|
169
|
+
});
|
|
170
|
+
});`;
|
|
171
|
+
}
|
|
172
|
+
})()}
|
|
143
173
|
|
|
144
174
|
// transaction
|
|
145
175
|
return wdb.transaction(async (trx) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TemplateOptions } from "../types/types";
|
|
2
2
|
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
3
3
|
import { Template } from "./base-template";
|
|
4
|
+
import { camelize } from "inflection";
|
|
4
5
|
|
|
5
6
|
export class Template__view_enums_dropdown extends Template {
|
|
6
7
|
constructor() {
|
|
@@ -16,7 +17,7 @@ export class Template__view_enums_dropdown extends Template {
|
|
|
16
17
|
|
|
17
18
|
render({ entityId, enumId }: TemplateOptions["view_enums_dropdown"]) {
|
|
18
19
|
const names = EntityManager.getNamesFromId(entityId);
|
|
19
|
-
const label = getLabel(enumId);
|
|
20
|
+
const label = getLabel(entityId, enumId);
|
|
20
21
|
|
|
21
22
|
return {
|
|
22
23
|
...this.getTargetAndPath(names, enumId),
|
|
@@ -27,7 +28,7 @@ import {
|
|
|
27
28
|
DropdownProps,
|
|
28
29
|
} from 'semantic-ui-react';
|
|
29
30
|
|
|
30
|
-
import { ${enumId}Label } from 'src/services
|
|
31
|
+
import { ${enumId}Label } from 'src/services/sonamu.generated';
|
|
31
32
|
|
|
32
33
|
export function ${enumId}Dropdown(props: DropdownProps) {
|
|
33
34
|
const options = Object.entries(${enumId}Label).map(([key, label]) => {
|
|
@@ -51,12 +52,18 @@ export function ${enumId}Dropdown(props: DropdownProps) {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
export function getLabel(enumId: string): string {
|
|
55
|
+
export function getLabel(entityId: string, enumId: string): string {
|
|
55
56
|
if (enumId.endsWith("OrderBy")) {
|
|
56
57
|
return "정렬";
|
|
57
58
|
} else if (enumId.endsWith("SearchField")) {
|
|
58
59
|
return "검색";
|
|
59
60
|
} else {
|
|
61
|
+
const enumProp = EntityManager.get(entityId).props.find(
|
|
62
|
+
(prop) => `${entityId}${camelize(prop.name)}` === enumId
|
|
63
|
+
);
|
|
64
|
+
if (enumProp && enumProp.desc) {
|
|
65
|
+
return enumProp.desc;
|
|
66
|
+
}
|
|
60
67
|
return enumId;
|
|
61
68
|
}
|
|
62
69
|
}
|
|
@@ -17,7 +17,7 @@ export class Template__view_enums_select extends Template {
|
|
|
17
17
|
|
|
18
18
|
render({ entityId, enumId }: TemplateOptions["view_enums_select"]) {
|
|
19
19
|
const names = EntityManager.getNamesFromId(entityId);
|
|
20
|
-
const label = getLabel(enumId);
|
|
20
|
+
const label = getLabel(entityId, enumId);
|
|
21
21
|
|
|
22
22
|
return {
|
|
23
23
|
...this.getTargetAndPath(names, enumId),
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
DropdownProps,
|
|
29
29
|
} from 'semantic-ui-react';
|
|
30
30
|
|
|
31
|
-
import { ${enumId}, ${enumId}Label } from 'src/services
|
|
31
|
+
import { ${enumId}, ${enumId}Label } from 'src/services/sonamu.generated';
|
|
32
32
|
|
|
33
33
|
export type ${enumId}SelectProps = {
|
|
34
34
|
placeholder?: string;
|