sonamu 0.2.36 → 0.2.38
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/.pnp.cjs +2117 -86
- package/dist/api/decorators.js +5 -2
- package/dist/api/decorators.js.map +1 -1
- package/dist/api/sonamu.js +3 -3
- package/dist/api/sonamu.js.map +1 -1
- package/dist/bin/cli-wrapper.d.ts +3 -0
- package/dist/bin/cli-wrapper.d.ts.map +1 -0
- package/dist/bin/cli-wrapper.js +27 -0
- package/dist/bin/cli-wrapper.js.map +1 -0
- package/dist/bin/cli.js +10 -10
- package/dist/bin/cli.js.map +1 -1
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +14 -13
- package/dist/database/base-model.js.map +1 -1
- package/dist/database/db.js +1 -1
- package/dist/database/db.js.map +1 -1
- package/dist/database/upsert-builder.js +8 -5
- package/dist/database/upsert-builder.js.map +1 -1
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +14 -12
- package/dist/entity/entity-manager.js.map +1 -1
- package/dist/entity/entity-utils.js +5 -2
- package/dist/entity/entity-utils.js.map +1 -1
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +20 -18
- package/dist/entity/entity.js.map +1 -1
- package/dist/entity/migrator.d.ts.map +1 -1
- package/dist/entity/migrator.js +59 -55
- package/dist/entity/migrator.js.map +1 -1
- package/dist/smd/smd-manager.d.ts.map +1 -1
- package/dist/smd/smd-manager.js +13 -9
- package/dist/smd/smd-manager.js.map +1 -1
- package/dist/smd/smd.d.ts.map +1 -1
- package/dist/smd/smd.js +13 -14
- package/dist/smd/smd.js.map +1 -1
- package/dist/syncer/syncer.d.ts +1 -1
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +68 -67
- package/dist/syncer/syncer.js.map +1 -1
- package/dist/templates/generated.template.js +6 -3
- package/dist/templates/generated.template.js.map +1 -1
- package/dist/templates/generated_sso.template.js +7 -4
- package/dist/templates/generated_sso.template.js.map +1 -1
- package/dist/templates/service.template.js +13 -10
- package/dist/templates/service.template.js.map +1 -1
- package/dist/templates/view_enums_dropdown.template.js +5 -2
- package/dist/templates/view_enums_dropdown.template.js.map +1 -1
- package/dist/templates/view_form.template.d.ts.map +1 -1
- package/dist/templates/view_form.template.js +7 -4
- package/dist/templates/view_form.template.js.map +1 -1
- package/dist/templates/view_id_async_select.template.js.map +1 -1
- package/dist/templates/view_list.template.js +10 -7
- package/dist/templates/view_list.template.js.map +1 -1
- package/dist/testing/fixture-manager.js +3 -3
- package/dist/testing/fixture-manager.js.map +1 -1
- package/dist/utils/sql-parser.js +5 -2
- package/dist/utils/sql-parser.js.map +1 -1
- package/dist/utils/utils.js +2 -2
- package/dist/utils/utils.js.map +1 -1
- package/package.json +19 -5
- package/src/api/decorators.ts +3 -3
- package/src/api/sonamu.ts +3 -3
- package/src/bin/cli-wrapper.ts +34 -0
- package/src/bin/cli.ts +10 -16
- package/src/database/base-model.ts +18 -15
- package/src/database/db.ts +1 -1
- package/src/database/upsert-builder.ts +5 -5
- package/src/entity/entity-manager.ts +14 -12
- package/src/entity/entity-utils.ts +2 -2
- package/src/entity/entity.ts +13 -11
- package/src/entity/migrator.ts +73 -85
- package/src/smd/smd-manager.ts +13 -9
- package/src/smd/smd.ts +10 -11
- package/src/syncer/syncer.ts +44 -44
- package/src/templates/generated.template.ts +3 -3
- package/src/templates/generated_sso.template.ts +4 -4
- package/src/templates/service.template.ts +10 -10
- package/src/templates/view_enums_dropdown.template.ts +2 -2
- package/src/templates/view_form.template.ts +36 -33
- package/src/templates/view_id_async_select.template.ts +4 -4
- package/src/templates/view_list.template.ts +18 -18
- package/src/testing/fixture-manager.ts +3 -3
- package/src/utils/sql-parser.ts +2 -2
- package/src/utils/utils.ts +2 -2
- package/tsup.config.js +21 -0
package/src/syncer/syncer.ts
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import path, { dirname } from "path";
|
|
2
2
|
import { globAsync, importMultiple } from "../utils/utils";
|
|
3
|
-
import fs
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
readJSON,
|
|
8
|
-
writeFile,
|
|
9
|
-
writeFileSync,
|
|
10
|
-
writeJSON,
|
|
11
|
-
} from "fs-extra";
|
|
3
|
+
import fs from "fs-extra";
|
|
12
4
|
import crypto from "crypto";
|
|
13
5
|
import equal from "fast-deep-equal";
|
|
14
|
-
import
|
|
15
|
-
import
|
|
6
|
+
import _ from "lodash";
|
|
7
|
+
import inflection from "inflection";
|
|
16
8
|
import { EntityManager } from "../entity/entity-manager";
|
|
17
|
-
import
|
|
9
|
+
import ts from "typescript";
|
|
18
10
|
import {
|
|
19
11
|
ApiParam,
|
|
20
12
|
ApiParamType,
|
|
@@ -134,7 +126,7 @@ export class Syncer {
|
|
|
134
126
|
const srcCodePath = path
|
|
135
127
|
.join(__dirname, `../shared/${target}.shared.ts.txt`)
|
|
136
128
|
.replace("/dist/", "/src/");
|
|
137
|
-
if (!existsSync(srcCodePath)) {
|
|
129
|
+
if (!fs.existsSync(srcCodePath)) {
|
|
138
130
|
return;
|
|
139
131
|
}
|
|
140
132
|
|
|
@@ -146,7 +138,7 @@ export class Syncer {
|
|
|
146
138
|
|
|
147
139
|
const srcChecksum = await this.getChecksumOfFile(srcCodePath);
|
|
148
140
|
const dstChecksum = await (async () => {
|
|
149
|
-
if (existsSync(dstCodePath) === false) {
|
|
141
|
+
if (fs.existsSync(dstCodePath) === false) {
|
|
150
142
|
return "";
|
|
151
143
|
}
|
|
152
144
|
return this.getChecksumOfFile(dstCodePath);
|
|
@@ -155,7 +147,7 @@ export class Syncer {
|
|
|
155
147
|
if (srcChecksum === dstChecksum) {
|
|
156
148
|
return;
|
|
157
149
|
}
|
|
158
|
-
writeFileSync(dstCodePath, readFileSync(srcCodePath));
|
|
150
|
+
fs.writeFileSync(dstCodePath, fs.readFileSync(srcCodePath));
|
|
159
151
|
})
|
|
160
152
|
);
|
|
161
153
|
|
|
@@ -176,12 +168,16 @@ export class Syncer {
|
|
|
176
168
|
}
|
|
177
169
|
|
|
178
170
|
// 변경된 파일 찾기
|
|
179
|
-
const diff = differenceWith(
|
|
171
|
+
const diff = _.differenceWith(
|
|
172
|
+
currentChecksums,
|
|
173
|
+
previousChecksums,
|
|
174
|
+
_.isEqual
|
|
175
|
+
);
|
|
180
176
|
const diffFiles = diff.map((r) => r.path);
|
|
181
177
|
console.log("Changed Files: ", diffFiles);
|
|
182
178
|
|
|
183
179
|
// 다른 부분 찾아 액션
|
|
184
|
-
const diffGroups = groupBy(diffFiles, (r) => {
|
|
180
|
+
const diffGroups = _.groupBy(diffFiles, (r) => {
|
|
185
181
|
const matched = r.match(
|
|
186
182
|
/\.(model|types|functions|entity|generated)\.[tj]s/
|
|
187
183
|
);
|
|
@@ -198,7 +194,7 @@ export class Syncer {
|
|
|
198
194
|
await this.actionGenerateSchemas();
|
|
199
195
|
|
|
200
196
|
// generated 싱크까지 동시에 처리 후 체크섬 갱신
|
|
201
|
-
diffGroups["generated"] = uniq([
|
|
197
|
+
diffGroups["generated"] = _.uniq([
|
|
202
198
|
...(diffGroups["generated"] ?? []),
|
|
203
199
|
"/src/application/sonamu.generated.ts",
|
|
204
200
|
]);
|
|
@@ -215,7 +211,7 @@ export class Syncer {
|
|
|
215
211
|
) {
|
|
216
212
|
console.log("// 액션: 파일 싱크 types / functions / generated");
|
|
217
213
|
|
|
218
|
-
const tsPaths = uniq(
|
|
214
|
+
const tsPaths = _.uniq(
|
|
219
215
|
[
|
|
220
216
|
...(diffGroups["types"] ?? []),
|
|
221
217
|
...(diffGroups["functions"] ?? []),
|
|
@@ -239,10 +235,10 @@ export class Syncer {
|
|
|
239
235
|
}
|
|
240
236
|
|
|
241
237
|
getEntityIdFromPath(filePaths: string[]): string[] {
|
|
242
|
-
return uniq(
|
|
238
|
+
return _.uniq(
|
|
243
239
|
filePaths.map((p) => {
|
|
244
240
|
const matched = p.match(/application\/(.+)\//);
|
|
245
|
-
return camelize(matched![1].replace(/\-/g, "_"));
|
|
241
|
+
return inflection.camelize(matched![1].replace(/\-/g, "_"));
|
|
246
242
|
})
|
|
247
243
|
);
|
|
248
244
|
}
|
|
@@ -299,11 +295,11 @@ export class Syncer {
|
|
|
299
295
|
}
|
|
300
296
|
|
|
301
297
|
async copyFileWithReplaceCoreToShared(fromPath: string, toPath: string) {
|
|
302
|
-
if (!existsSync(fromPath)) {
|
|
298
|
+
if (!fs.existsSync(fromPath)) {
|
|
303
299
|
return;
|
|
304
300
|
}
|
|
305
301
|
|
|
306
|
-
const oldFileContent = readFileSync(fromPath).toString();
|
|
302
|
+
const oldFileContent = fs.readFileSync(fromPath).toString();
|
|
307
303
|
|
|
308
304
|
const newFileContent = (() => {
|
|
309
305
|
const nfc = oldFileContent.replace(
|
|
@@ -317,7 +313,7 @@ export class Syncer {
|
|
|
317
313
|
return nfc;
|
|
318
314
|
}
|
|
319
315
|
})();
|
|
320
|
-
return writeFile(toPath, newFileContent);
|
|
316
|
+
return fs.writeFile(toPath, newFileContent);
|
|
321
317
|
}
|
|
322
318
|
|
|
323
319
|
async actionSyncFilesToTargets(tsPaths: string[]): Promise<string[]> {
|
|
@@ -335,8 +331,8 @@ export class Syncer {
|
|
|
335
331
|
.replace(`/${apiDir}/`, `/${target}/`)
|
|
336
332
|
.replace("/application/", "/services/");
|
|
337
333
|
const dir = dirname(dst);
|
|
338
|
-
if (!existsSync(dir)) {
|
|
339
|
-
mkdirSync(dir, { recursive: true });
|
|
334
|
+
if (!fs.existsSync(dir)) {
|
|
335
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
340
336
|
}
|
|
341
337
|
console.log(
|
|
342
338
|
"COPIED ",
|
|
@@ -387,18 +383,18 @@ export class Syncer {
|
|
|
387
383
|
}
|
|
388
384
|
|
|
389
385
|
async getPreviousChecksums(): Promise<PathAndChecksum[]> {
|
|
390
|
-
if (existsSync(this.checksumsPath) === false) {
|
|
386
|
+
if (fs.existsSync(this.checksumsPath) === false) {
|
|
391
387
|
return [];
|
|
392
388
|
}
|
|
393
389
|
|
|
394
|
-
const previousChecksums = (await readJSON(
|
|
390
|
+
const previousChecksums = (await fs.readJSON(
|
|
395
391
|
this.checksumsPath
|
|
396
392
|
)) as PathAndChecksum[];
|
|
397
393
|
return previousChecksums;
|
|
398
394
|
}
|
|
399
395
|
|
|
400
396
|
async saveChecksums(checksums: PathAndChecksum[]): Promise<void> {
|
|
401
|
-
await writeJSON(this.checksumsPath, checksums, {
|
|
397
|
+
await fs.writeJSON(this.checksumsPath, checksums, {
|
|
402
398
|
spaces: 2,
|
|
403
399
|
});
|
|
404
400
|
console.debug("checksum saved", this.checksumsPath);
|
|
@@ -421,7 +417,7 @@ export class Syncer {
|
|
|
421
417
|
async readApisFromFile(filePath: string) {
|
|
422
418
|
const sourceFile = ts.createSourceFile(
|
|
423
419
|
filePath,
|
|
424
|
-
readFileSync(filePath).toString(),
|
|
420
|
+
fs.readFileSync(filePath).toString(),
|
|
425
421
|
ts.ScriptTarget.Latest
|
|
426
422
|
);
|
|
427
423
|
|
|
@@ -456,6 +452,8 @@ export class Syncer {
|
|
|
456
452
|
(paramDec, index) => {
|
|
457
453
|
const defaultDef = this.printNode(paramDec.initializer, sourceFile);
|
|
458
454
|
|
|
455
|
+
// 기본값이 있는 경우 paramDec.type가 undefined로 나옴
|
|
456
|
+
|
|
459
457
|
return this.resolveParamDec(
|
|
460
458
|
{
|
|
461
459
|
name: paramDec.name,
|
|
@@ -709,7 +707,7 @@ export class Syncer {
|
|
|
709
707
|
// src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드
|
|
710
708
|
// 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지
|
|
711
709
|
const srcPath = path.replace("/dist/", "/src/").replace(".js", ".ts");
|
|
712
|
-
return existsSync(srcPath);
|
|
710
|
+
return fs.existsSync(srcPath);
|
|
713
711
|
});
|
|
714
712
|
const modules = await importMultiple(filePaths);
|
|
715
713
|
const functions = modules
|
|
@@ -742,7 +740,7 @@ export class Syncer {
|
|
|
742
740
|
// src 디렉터리 내에 있는 해당 파일이 존재할 경우에만 로드
|
|
743
741
|
// 삭제된 파일이지만 dist에 남아있는 경우 BaseSchema undefined 에러 방지
|
|
744
742
|
const srcPath = path.replace("/dist/", "/src/").replace(".js", ".ts");
|
|
745
|
-
return existsSync(srcPath);
|
|
743
|
+
return fs.existsSync(srcPath);
|
|
746
744
|
});
|
|
747
745
|
const modules = await importMultiple(filePaths, doRefresh);
|
|
748
746
|
const functions = modules
|
|
@@ -875,7 +873,7 @@ export class Syncer {
|
|
|
875
873
|
(importDef) => importDef.from === importPath
|
|
876
874
|
);
|
|
877
875
|
if (existsOne) {
|
|
878
|
-
existsOne.keys = uniq(existsOne.keys.concat(importKey));
|
|
876
|
+
existsOne.keys = _.uniq(existsOne.keys.concat(importKey));
|
|
879
877
|
} else {
|
|
880
878
|
r.push({
|
|
881
879
|
keys: [importKey],
|
|
@@ -925,16 +923,16 @@ export class Syncer {
|
|
|
925
923
|
const { appRootPath } = Sonamu;
|
|
926
924
|
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;
|
|
927
925
|
|
|
928
|
-
const dstFilePaths = uniq(
|
|
926
|
+
const dstFilePaths = _.uniq(
|
|
929
927
|
targets.map((target) => filePath.replace("/:target/", `/${target}/`))
|
|
930
928
|
);
|
|
931
929
|
return await Promise.all(
|
|
932
930
|
dstFilePaths.map(async (dstFilePath) => {
|
|
933
931
|
const dir = path.dirname(dstFilePath);
|
|
934
|
-
if (existsSync(dir) === false) {
|
|
935
|
-
mkdirSync(dir, { recursive: true });
|
|
932
|
+
if (fs.existsSync(dir) === false) {
|
|
933
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
936
934
|
}
|
|
937
|
-
writeFileSync(dstFilePath, pathAndCode.code);
|
|
935
|
+
fs.writeFileSync(dstFilePath, pathAndCode.code);
|
|
938
936
|
console.log(
|
|
939
937
|
"GENERATED ",
|
|
940
938
|
chalk.blue(dstFilePath.replace(appRootPath + "/", ""))
|
|
@@ -976,7 +974,9 @@ export class Syncer {
|
|
|
976
974
|
const dstFilePaths = targets.map((target) =>
|
|
977
975
|
filePath.replace("/:target/", `/${target}/`)
|
|
978
976
|
);
|
|
979
|
-
return dstFilePaths.every(
|
|
977
|
+
return dstFilePaths.every(
|
|
978
|
+
(dstPath) => fs.existsSync(dstPath) === false
|
|
979
|
+
);
|
|
980
980
|
});
|
|
981
981
|
}
|
|
982
982
|
})();
|
|
@@ -1007,7 +1007,7 @@ export class Syncer {
|
|
|
1007
1007
|
return {
|
|
1008
1008
|
subPath,
|
|
1009
1009
|
fullPath,
|
|
1010
|
-
isExists: existsSync(fullPath),
|
|
1010
|
+
isExists: fs.existsSync(fullPath),
|
|
1011
1011
|
};
|
|
1012
1012
|
}
|
|
1013
1013
|
|
|
@@ -1032,7 +1032,7 @@ export class Syncer {
|
|
|
1032
1032
|
names,
|
|
1033
1033
|
componentId
|
|
1034
1034
|
);
|
|
1035
|
-
result[`${key}__${componentId}`] = existsSync(
|
|
1035
|
+
result[`${key}__${componentId}`] = fs.existsSync(
|
|
1036
1036
|
path.join(Sonamu.appRootPath, target, p)
|
|
1037
1037
|
);
|
|
1038
1038
|
});
|
|
@@ -1043,12 +1043,12 @@ export class Syncer {
|
|
|
1043
1043
|
const { targets } = Sonamu.config.sync;
|
|
1044
1044
|
if (target.includes(":target")) {
|
|
1045
1045
|
targets.map((t) => {
|
|
1046
|
-
result[`${key}__${t}`] = existsSync(
|
|
1046
|
+
result[`${key}__${t}`] = fs.existsSync(
|
|
1047
1047
|
path.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
1048
1048
|
);
|
|
1049
1049
|
});
|
|
1050
1050
|
} else {
|
|
1051
|
-
result[key] = existsSync(path.join(Sonamu.appRootPath, target, p));
|
|
1051
|
+
result[key] = fs.existsSync(path.join(Sonamu.appRootPath, target, p));
|
|
1052
1052
|
}
|
|
1053
1053
|
|
|
1054
1054
|
return result;
|
|
@@ -1212,7 +1212,7 @@ export class Syncer {
|
|
|
1212
1212
|
): RenderingNode {
|
|
1213
1213
|
const def = {
|
|
1214
1214
|
name: baseKey,
|
|
1215
|
-
label: camelize(baseKey, false),
|
|
1215
|
+
label: inflection.camelize(baseKey, false),
|
|
1216
1216
|
zodType,
|
|
1217
1217
|
};
|
|
1218
1218
|
if (zodType instanceof z.ZodObject) {
|
|
@@ -1381,7 +1381,7 @@ export class Syncer {
|
|
|
1381
1381
|
})(); // iife
|
|
1382
1382
|
|
|
1383
1383
|
for await (const delPath of delPaths) {
|
|
1384
|
-
if (existsSync(delPath)) {
|
|
1384
|
+
if (fs.existsSync(delPath)) {
|
|
1385
1385
|
console.log(chalk.red(`DELETE ${delPath}`));
|
|
1386
1386
|
execSync(`rm -rf ${delPath}`);
|
|
1387
1387
|
} else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _ from "lodash";
|
|
2
2
|
import { TemplateOptions } from "../types/types";
|
|
3
3
|
import { EntityManager } from "../entity/entity-manager";
|
|
4
4
|
import { Entity } from "../entity/entity";
|
|
@@ -72,7 +72,7 @@ export class Template__generated extends Template {
|
|
|
72
72
|
}
|
|
73
73
|
return {
|
|
74
74
|
lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, ""],
|
|
75
|
-
importKeys: uniq([...result!.importKeys, ...ts.importKeys]),
|
|
75
|
+
importKeys: _.uniq([...result!.importKeys, ...ts.importKeys]),
|
|
76
76
|
};
|
|
77
77
|
},
|
|
78
78
|
{
|
|
@@ -280,7 +280,7 @@ z.object({
|
|
|
280
280
|
return {
|
|
281
281
|
label: `Subsets: ${entity.id}`,
|
|
282
282
|
lines,
|
|
283
|
-
importKeys: uniq(importKeys),
|
|
283
|
+
importKeys: _.uniq(importKeys),
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
286
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SubsetQuery, TemplateOptions } from "../types/types";
|
|
2
2
|
import { EntityManager } from "../entity/entity-manager";
|
|
3
3
|
import { Template } from "./base-template";
|
|
4
|
-
import
|
|
4
|
+
import inflection from "inflection";
|
|
5
5
|
import { SourceCode } from "./generated.template";
|
|
6
|
-
import
|
|
6
|
+
import _ from "lodash";
|
|
7
7
|
import { nonNullable } from "../utils/utils";
|
|
8
8
|
import { Sonamu } from "../api";
|
|
9
9
|
|
|
@@ -49,7 +49,7 @@ export class Template__generated_sso extends Template {
|
|
|
49
49
|
return {
|
|
50
50
|
label: `SubsetQuery: ${entity.id}`,
|
|
51
51
|
lines: [
|
|
52
|
-
`export const ${camelize(
|
|
52
|
+
`export const ${inflection.camelize(
|
|
53
53
|
entity.id,
|
|
54
54
|
true
|
|
55
55
|
)}SubsetQueries:{ [key in ${subsetKeyTypeName}]: SubsetQuery} = ${JSON.stringify(
|
|
@@ -69,7 +69,7 @@ export class Template__generated_sso extends Template {
|
|
|
69
69
|
}
|
|
70
70
|
return {
|
|
71
71
|
lines: [...result!.lines, `// ${ts.label}`, ...ts.lines, ""],
|
|
72
|
-
importKeys: uniq([...result!.importKeys, ...ts.importKeys]),
|
|
72
|
+
importKeys: _.uniq([...result!.importKeys, ...ts.importKeys]),
|
|
73
73
|
};
|
|
74
74
|
},
|
|
75
75
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import inflection from "inflection";
|
|
2
|
+
import _ from "lodash";
|
|
3
3
|
import { TemplateOptions } from "../types/types";
|
|
4
4
|
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
5
5
|
import { ApiParamType, ApiParam } from "../types/types";
|
|
@@ -54,7 +54,7 @@ export class Template__service extends Template {
|
|
|
54
54
|
// 제네릭에서 선언한 타입, importKeys에서 제외 필요
|
|
55
55
|
let typeParamNames: string[] = [];
|
|
56
56
|
|
|
57
|
-
const groups = groupBy(apis, (api) => api.modelName);
|
|
57
|
+
const groups = _.groupBy(apis, (api) => api.modelName);
|
|
58
58
|
const body = Object.keys(groups)
|
|
59
59
|
.map((modelName) => {
|
|
60
60
|
const methods = groups[modelName];
|
|
@@ -94,7 +94,7 @@ export class Template__service extends Template {
|
|
|
94
94
|
.map((param) => param.name)
|
|
95
95
|
.join(", ")} }`;
|
|
96
96
|
|
|
97
|
-
return sortBy(api.options.clients, (client) =>
|
|
97
|
+
return _.sortBy(api.options.clients, (client) =>
|
|
98
98
|
client === "swr" ? 0 : 1
|
|
99
99
|
)
|
|
100
100
|
.map((client) => {
|
|
@@ -137,7 +137,7 @@ export class Template__service extends Template {
|
|
|
137
137
|
);
|
|
138
138
|
case "socketio":
|
|
139
139
|
default:
|
|
140
|
-
return `// Not supported ${camelize(client, true)} yet.`;
|
|
140
|
+
return `// Not supported ${inflection.camelize(client, true)} yet.`;
|
|
141
141
|
}
|
|
142
142
|
})
|
|
143
143
|
.join("\n");
|
|
@@ -152,7 +152,7 @@ ${methodCodes}
|
|
|
152
152
|
|
|
153
153
|
return {
|
|
154
154
|
lines: [body],
|
|
155
|
-
importKeys: difference(uniq(importKeys), typeParamNames),
|
|
155
|
+
importKeys: _.difference(_.uniq(importKeys), typeParamNames),
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -165,7 +165,7 @@ ${methodCodes}
|
|
|
165
165
|
payloadDef: string
|
|
166
166
|
) {
|
|
167
167
|
const methodNameAxios = api.options.resourceName
|
|
168
|
-
? "get" + camelize(api.options.resourceName)
|
|
168
|
+
? "get" + inflection.camelize(api.options.resourceName)
|
|
169
169
|
: api.methodName;
|
|
170
170
|
|
|
171
171
|
if (api.options.httpMethod === "GET") {
|
|
@@ -236,9 +236,9 @@ export async function ${api.methodName}${typeParamsDef}(
|
|
|
236
236
|
payloadDef: string
|
|
237
237
|
) {
|
|
238
238
|
const methodNameSwr = api.options.resourceName
|
|
239
|
-
? "use" + camelize(api.options.resourceName)
|
|
240
|
-
: "use" + camelize(api.methodName);
|
|
241
|
-
return ` export function ${camelize(
|
|
239
|
+
? "use" + inflection.camelize(api.options.resourceName)
|
|
240
|
+
: "use" + inflection.camelize(api.methodName);
|
|
241
|
+
return ` export function ${inflection.camelize(
|
|
242
242
|
methodNameSwr,
|
|
243
243
|
true
|
|
244
244
|
)}${typeParamsDef}(${[paramsDef, "swrOptions?: SwrOptions"]
|
|
@@ -1,7 +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
|
|
4
|
+
import inflection from "inflection";
|
|
5
5
|
|
|
6
6
|
export class Template__view_enums_dropdown extends Template {
|
|
7
7
|
constructor() {
|
|
@@ -59,7 +59,7 @@ export function getLabel(entityId: string, enumId: string): string {
|
|
|
59
59
|
return "검색";
|
|
60
60
|
} else {
|
|
61
61
|
const enumProp = EntityManager.get(entityId).props.find(
|
|
62
|
-
(prop) => `${entityId}${camelize(prop.name)}` === enumId
|
|
62
|
+
(prop) => `${entityId}${inflection.camelize(prop.name)}` === enumId
|
|
63
63
|
);
|
|
64
64
|
if (enumProp && enumProp.desc) {
|
|
65
65
|
return enumProp.desc;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import inflection from "inflection";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { RenderingNode, TemplateKey, TemplateOptions } from "../types/types";
|
|
4
4
|
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getEnumInfoFromColName,
|
|
9
9
|
getRelationPropFromColName,
|
|
10
10
|
} from "./view_list.template";
|
|
11
|
-
import
|
|
11
|
+
import _ from "lodash";
|
|
12
12
|
|
|
13
13
|
export class Template__view_form extends Template {
|
|
14
14
|
constructor() {
|
|
@@ -99,7 +99,7 @@ export class Template__view_form extends Template {
|
|
|
99
99
|
try {
|
|
100
100
|
let enumId: string;
|
|
101
101
|
if (col.name === "orderBy") {
|
|
102
|
-
enumId = `${names.capital}${camelize(col.name)}Select`;
|
|
102
|
+
enumId = `${names.capital}${inflection.camelize(col.name)}Select`;
|
|
103
103
|
} else {
|
|
104
104
|
const { id } = getEnumInfoFromColName(entityId, col.name);
|
|
105
105
|
enumId = `${id}Select`;
|
|
@@ -135,35 +135,38 @@ export class Template__view_form extends Template {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
resolveDefaultValue(columns: RenderingNode[]): object {
|
|
138
|
-
return columns.reduce(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
return columns.reduce(
|
|
139
|
+
(result, col) => {
|
|
140
|
+
if (col.optional) {
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
let value: unknown;
|
|
145
|
+
if (col.nullable === true) {
|
|
146
|
+
value = null;
|
|
147
|
+
} else if (col.zodType instanceof z.ZodNumber) {
|
|
148
|
+
value = 0;
|
|
149
|
+
} else if (col.zodType instanceof z.ZodEnum) {
|
|
150
|
+
value = Object.keys(col.zodType.Enum)[0];
|
|
151
|
+
} else if (col.zodType instanceof z.ZodBoolean) {
|
|
152
|
+
value = false;
|
|
153
|
+
} else if (col.zodType instanceof z.ZodString) {
|
|
154
|
+
if (col.renderType === "string-datetime") {
|
|
155
|
+
value = "now()";
|
|
156
|
+
} else {
|
|
157
|
+
value = "";
|
|
158
|
+
}
|
|
159
|
+
} else if (col.zodType instanceof z.ZodArray) {
|
|
160
|
+
value = [];
|
|
161
|
+
} else if (col.zodType instanceof z.ZodObject) {
|
|
162
|
+
value = {};
|
|
157
163
|
}
|
|
158
|
-
} else if (col.zodType instanceof z.ZodArray) {
|
|
159
|
-
value = [];
|
|
160
|
-
} else if (col.zodType instanceof z.ZodObject) {
|
|
161
|
-
value = {};
|
|
162
|
-
}
|
|
163
164
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
result[col.name] = value;
|
|
166
|
+
return result;
|
|
167
|
+
},
|
|
168
|
+
{} as { [key: string]: unknown }
|
|
169
|
+
);
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
render(
|
|
@@ -277,7 +280,7 @@ import { ${names.capital}Service } from 'src/services/${names.fs}/${
|
|
|
277
280
|
names.fs
|
|
278
281
|
}.service';
|
|
279
282
|
import { ${names.capital}SubsetA } from 'src/services/sonamu.generated';
|
|
280
|
-
${uniq(
|
|
283
|
+
${_.uniq(
|
|
281
284
|
columns
|
|
282
285
|
.filter((col) => ["number-fk_id", "enums"].includes(col.renderType))
|
|
283
286
|
.map((col) => {
|
|
@@ -310,9 +313,9 @@ export function ${names.capitalPlural}Form({ id, mode }: ${
|
|
|
310
313
|
const { form, setForm, register } = useTypeForm(${
|
|
311
314
|
names.capital
|
|
312
315
|
}SaveParams, ${JSON.stringify(defaultValue).replace(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
+
/"now\(\)"/g,
|
|
317
|
+
"DateTime.local().toSQL()!.slice(0, 19)"
|
|
318
|
+
)});
|
|
316
319
|
|
|
317
320
|
// 수정일 때 기존 row 콜
|
|
318
321
|
useEffect(() => {
|
|
@@ -67,8 +67,8 @@ export function ${names.capital}IdAsyncSelect<T extends ${
|
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
const { data, error } = ${names.capital}Service.use${
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
names.capitalPlural
|
|
71
|
+
}(subset, listParams);
|
|
72
72
|
const { rows: ${names.camelPlural}, total } = data ?? {};
|
|
73
73
|
|
|
74
74
|
useEffect(() => {
|
|
@@ -78,8 +78,8 @@ export function ${names.capital}IdAsyncSelect<T extends ${
|
|
|
78
78
|
key: ${names.camel}.id,
|
|
79
79
|
value: ${names.camel}[valueField ?? 'id'] as string | number,
|
|
80
80
|
text: String(${names.camel}[textField${
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
textField ? ` ?? '${textField}'` : ""
|
|
82
|
+
}]),
|
|
83
83
|
};
|
|
84
84
|
}),
|
|
85
85
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import inflection from "inflection";
|
|
2
|
+
import _ from "lodash";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { RenderingNode, TemplateKey, TemplateOptions } from "../types/types";
|
|
5
5
|
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
@@ -113,7 +113,7 @@ export class Template__view_list extends Template {
|
|
|
113
113
|
names = EntityManager.getNamesFromId(relProp.with);
|
|
114
114
|
return this.renderColumnImport(entityId, child, names);
|
|
115
115
|
});
|
|
116
|
-
return flattenDeep(result);
|
|
116
|
+
return _.flattenDeep(result);
|
|
117
117
|
} catch {
|
|
118
118
|
return [null];
|
|
119
119
|
}
|
|
@@ -133,7 +133,7 @@ export class Template__view_list extends Template {
|
|
|
133
133
|
return `import { ${names.capital}SearchInput } from "src/components/${names.fs}/${names.capital}SearchInput";`;
|
|
134
134
|
} else if (col.renderType === "enums") {
|
|
135
135
|
if (col.name === "orderBy") {
|
|
136
|
-
const componentId = `${names.capital}${camelize(col.name)}Select`;
|
|
136
|
+
const componentId = `${names.capital}${inflection.camelize(col.name)}Select`;
|
|
137
137
|
return `import { ${componentId} } from "src/components/${names.fs}/${componentId}";`;
|
|
138
138
|
} else {
|
|
139
139
|
try {
|
|
@@ -173,7 +173,7 @@ export class Template__view_list extends Template {
|
|
|
173
173
|
let componentId: string;
|
|
174
174
|
if (col.renderType === "enums") {
|
|
175
175
|
if (col.name === "orderBy") {
|
|
176
|
-
componentId = `${names.capital}${camelize(col.name)}Select`;
|
|
176
|
+
componentId = `${names.capital}${inflection.camelize(col.name)}Select`;
|
|
177
177
|
} else {
|
|
178
178
|
try {
|
|
179
179
|
const { id } = getEnumInfoFromColName(entityId, col.name);
|
|
@@ -308,7 +308,7 @@ export class Template__view_list extends Template {
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
// 리스트 컬럼
|
|
311
|
-
const columnImports = uniq(
|
|
311
|
+
const columnImports = _.uniq(
|
|
312
312
|
columnsNode
|
|
313
313
|
.children!.map((col) => {
|
|
314
314
|
return this.renderColumnImport(entityId, col, names);
|
|
@@ -375,8 +375,8 @@ export default function ${names.capital}List({}: ${names.capital}ListProps) {
|
|
|
375
375
|
|
|
376
376
|
// 리스트 쿼리
|
|
377
377
|
const { data, mutate, error, isLoading } = ${names.capital}Service.use${
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
names.capitalPlural
|
|
379
|
+
}('A', listParams);
|
|
380
380
|
const { rows, total } = data ?? {};
|
|
381
381
|
|
|
382
382
|
// 삭제
|
|
@@ -422,14 +422,14 @@ export default function ${names.capital}List({}: ${names.capital}ListProps) {
|
|
|
422
422
|
|
|
423
423
|
// 컬럼
|
|
424
424
|
const columns:SonamuCol<${names.capital}SubsetA>[] = [${columns
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
425
|
+
.map((col) => {
|
|
426
|
+
return [
|
|
427
|
+
`{ label: "${col.label}",`,
|
|
428
|
+
`tc: ${col.tc}, `,
|
|
429
|
+
`collapsing: ${["Title", "Name"].includes(col.label) === false}, }`,
|
|
430
|
+
].join("\n");
|
|
431
|
+
})
|
|
432
|
+
.join(",\n")}];
|
|
433
433
|
|
|
434
434
|
return (
|
|
435
435
|
<div className="list ${names.fsPlural}-index">
|
|
@@ -577,8 +577,8 @@ export function getEnumInfoFromColName(
|
|
|
577
577
|
title: prop.desc ?? prop.id,
|
|
578
578
|
};
|
|
579
579
|
} else {
|
|
580
|
-
const idCandidate = camelize(
|
|
581
|
-
underscore(entityId) + "_" + underscore(colName),
|
|
580
|
+
const idCandidate = inflection.camelize(
|
|
581
|
+
inflection.underscore(entityId) + "_" + inflection.underscore(colName),
|
|
582
582
|
false
|
|
583
583
|
);
|
|
584
584
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import knex, { Knex } from "knex";
|
|
3
|
-
import
|
|
3
|
+
import _ from "lodash";
|
|
4
4
|
import { Sonamu } from "../api";
|
|
5
5
|
import { BaseModel } from "../database/base-model";
|
|
6
6
|
import { EntityManager } from "../entity/entity-manager";
|
|
@@ -161,7 +161,7 @@ export class FixtureManagerClass {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
async importFixture(entityId: string, ids: number[]) {
|
|
164
|
-
const queries = uniq(
|
|
164
|
+
const queries = _.uniq(
|
|
165
165
|
(
|
|
166
166
|
await Promise.all(
|
|
167
167
|
ids.map(async (id) => {
|
|
@@ -243,7 +243,7 @@ export class FixtureManagerClass {
|
|
|
243
243
|
})
|
|
244
244
|
);
|
|
245
245
|
|
|
246
|
-
return [...uniq(relQueries.reverse().flat()), selfQuery];
|
|
246
|
+
return [..._.uniq(relQueries.reverse().flat()), selfQuery];
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
async destory() {
|
package/src/utils/sql-parser.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _ from "lodash";
|
|
2
2
|
import { AST, ColumnRef, Expr, ExpressionValue, Select } from "node-sql-parser";
|
|
3
3
|
|
|
4
4
|
export function getTableName(expr: ColumnRef) {
|
|
@@ -30,7 +30,7 @@ export function getTableNamesFromWhere(ast: AST | AST[]): string[] {
|
|
|
30
30
|
return [...extractTableName(where.left), ...extractTableName(where.right)];
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
return uniq(
|
|
33
|
+
return _.uniq(
|
|
34
34
|
(Array.isArray(ast) ? ast : [ast]).flatMap((a) =>
|
|
35
35
|
a.type === "select" || a.type === "update" || a.type === "delete"
|
|
36
36
|
? extractTableNames(a.where)
|