sonamu 0.0.8 → 0.0.9
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/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/init.d.ts +35 -5
- package/dist/api/init.d.ts.map +1 -1
- package/dist/api/init.js +142 -79
- package/dist/api/init.js.map +1 -1
- package/dist/api/sonamu.d.ts +42 -0
- package/dist/api/sonamu.d.ts.map +1 -0
- package/dist/api/sonamu.js +175 -0
- package/dist/api/sonamu.js.map +1 -0
- package/dist/bin/cli.js +6 -19
- package/dist/bin/cli.js.map +1 -1
- package/dist/database/db.d.ts +1 -3
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +12 -23
- package/dist/database/db.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/smd/migrator.d.ts +0 -5
- package/dist/smd/migrator.d.ts.map +1 -1
- package/dist/smd/migrator.js +18 -19
- package/dist/smd/migrator.js.map +1 -1
- package/dist/smd/smd-manager.d.ts.map +1 -1
- package/dist/smd/smd-manager.js +2 -3
- package/dist/smd/smd-manager.js.map +1 -1
- package/dist/smd/smd.d.ts.map +1 -1
- package/dist/smd/smd.js +3 -4
- package/dist/smd/smd.js.map +1 -1
- package/dist/syncer/syncer.d.ts +8 -12
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +43 -43
- package/dist/syncer/syncer.js.map +1 -1
- package/dist/templates/generated_http.template.js +2 -2
- package/dist/templates/generated_http.template.js.map +1 -1
- package/dist/templates/service.template.d.ts +1 -1
- package/dist/templates/service.template.d.ts.map +1 -1
- package/dist/templates/service.template.js +3 -2
- package/dist/templates/service.template.js.map +1 -1
- package/dist/templates/view_form.template.d.ts +2 -2
- package/dist/templates/view_list.template.d.ts +2 -2
- package/dist/testing/fixture-manager.d.ts +6 -7
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +35 -42
- package/dist/testing/fixture-manager.js.map +1 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +10 -3
- package/dist/utils/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/api/index.ts +1 -1
- package/src/api/sonamu.ts +212 -0
- package/src/bin/cli.ts +6 -23
- package/src/database/db.ts +15 -27
- package/src/index.ts +1 -1
- package/src/smd/migrator.ts +18 -31
- package/src/smd/smd-manager.ts +3 -4
- package/src/smd/smd.ts +7 -8
- package/src/syncer/syncer.ts +49 -68
- package/src/templates/generated_http.template.ts +2 -2
- package/src/templates/service.template.ts +6 -5
- package/src/testing/fixture-manager.ts +44 -54
- package/src/utils/utils.ts +6 -1
- package/src/api/init.ts +0 -129
package/src/bin/cli.ts
CHANGED
|
@@ -15,19 +15,13 @@ import { FixtureManager } from "../testing/fixture-manager";
|
|
|
15
15
|
import { tsicli } from "tsicli";
|
|
16
16
|
import { execSync } from "child_process";
|
|
17
17
|
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
|
|
18
|
-
import {
|
|
18
|
+
import { Sonamu } from "../api";
|
|
19
19
|
|
|
20
20
|
let migrator: Migrator;
|
|
21
21
|
let fixtureManager: FixtureManager;
|
|
22
22
|
|
|
23
23
|
async function bootstrap() {
|
|
24
|
-
|
|
25
|
-
const appRootPath = await findAppRootPath();
|
|
26
|
-
Syncer.getInstance({
|
|
27
|
-
appRootPath,
|
|
28
|
-
});
|
|
29
|
-
await DB.readKnexfile(appRootPath);
|
|
30
|
-
await SMDManager.autoload();
|
|
24
|
+
await Sonamu.init();
|
|
31
25
|
|
|
32
26
|
await tsicli(process.argv, {
|
|
33
27
|
types: {
|
|
@@ -89,7 +83,6 @@ bootstrap().finally(async () => {
|
|
|
89
83
|
async function setupMigrator() {
|
|
90
84
|
// migrator
|
|
91
85
|
migrator = new Migrator({
|
|
92
|
-
appRootPath: Syncer.getInstance().config.appRootPath,
|
|
93
86
|
knexfile: DB.getKnexfile(),
|
|
94
87
|
mode: "dev",
|
|
95
88
|
});
|
|
@@ -138,14 +131,7 @@ async function fixture_sync() {
|
|
|
138
131
|
}
|
|
139
132
|
|
|
140
133
|
async function stub_practice(name: string) {
|
|
141
|
-
|
|
142
|
-
return;
|
|
143
|
-
const practiceDir = path.join(
|
|
144
|
-
Syncer.getInstance().config.appRootPath,
|
|
145
|
-
"api",
|
|
146
|
-
"src",
|
|
147
|
-
"practices"
|
|
148
|
-
);
|
|
134
|
+
const practiceDir = path.join(Sonamu.apiRootPath, "src", "practices");
|
|
149
135
|
const fileNames = readdirSync(practiceDir);
|
|
150
136
|
|
|
151
137
|
const maxSeqNo = (() => {
|
|
@@ -200,22 +186,19 @@ async function stub_practice(name: string) {
|
|
|
200
186
|
}
|
|
201
187
|
|
|
202
188
|
async function stub_smd(name: string) {
|
|
203
|
-
|
|
204
|
-
await syncer.generateTemplate("smd", {
|
|
189
|
+
await Sonamu.syncer.generateTemplate("smd", {
|
|
205
190
|
smdId: name,
|
|
206
191
|
});
|
|
207
192
|
}
|
|
208
193
|
|
|
209
194
|
async function scaffold_model(smdId: string) {
|
|
210
|
-
|
|
211
|
-
await syncer.generateTemplate("model", {
|
|
195
|
+
await Sonamu.syncer.generateTemplate("model", {
|
|
212
196
|
smdId,
|
|
213
197
|
});
|
|
214
198
|
}
|
|
215
199
|
|
|
216
200
|
async function scaffold_model_test(smdId: string) {
|
|
217
|
-
|
|
218
|
-
await syncer.generateTemplate("model_test", {
|
|
201
|
+
await Sonamu.syncer.generateTemplate("model_test", {
|
|
219
202
|
smdId,
|
|
220
203
|
});
|
|
221
204
|
}
|
package/src/database/db.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export type DBPreset = "w" | "r";
|
|
2
2
|
import knex, { Knex } from "knex";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { Sonamu } from "../api";
|
|
4
5
|
import { ServiceUnavailableException } from "../exceptions/so-exceptions";
|
|
5
|
-
import { findAppRootPath } from "../utils/utils";
|
|
6
6
|
|
|
7
7
|
export type SonamuDBConfig = {
|
|
8
8
|
development_master: Knex.Config;
|
|
@@ -17,36 +17,24 @@ export type SonamuDBConfig = {
|
|
|
17
17
|
class DBClass {
|
|
18
18
|
private wdb?: Knex;
|
|
19
19
|
private rdb?: Knex;
|
|
20
|
-
private knexfile?: SonamuDBConfig;
|
|
21
20
|
|
|
22
|
-
async readKnexfile(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const appRootPath = _appRootPath ?? (await findAppRootPath());
|
|
28
|
-
const configPath: string = path.join(appRootPath, "/api/dist/configs/db");
|
|
21
|
+
async readKnexfile(): Promise<SonamuDBConfig> {
|
|
22
|
+
const dbConfigPath: string = path.join(
|
|
23
|
+
Sonamu.apiRootPath,
|
|
24
|
+
"/dist/configs/db"
|
|
25
|
+
);
|
|
29
26
|
try {
|
|
30
|
-
const knexfileModule = await import(
|
|
31
|
-
|
|
32
|
-
return this.knexfile;
|
|
27
|
+
const knexfileModule = await import(dbConfigPath);
|
|
28
|
+
return knexfileModule.default as SonamuDBConfig;
|
|
33
29
|
} catch {}
|
|
34
30
|
|
|
35
31
|
throw new ServiceUnavailableException(
|
|
36
|
-
`DB설정 파일을 찾을 수 없습니다. ${
|
|
32
|
+
`DB설정 파일을 찾을 수 없습니다. ${dbConfigPath}`
|
|
37
33
|
);
|
|
38
34
|
}
|
|
39
35
|
|
|
40
|
-
getKnexfile(): SonamuDBConfig {
|
|
41
|
-
if (this.knexfile) {
|
|
42
|
-
return this.knexfile;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw new ServiceUnavailableException("DB설정이 로드되지 않았습니다.");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
36
|
getDB(which: DBPreset): Knex {
|
|
49
|
-
const
|
|
37
|
+
const dbConfig = Sonamu.dbConfig;
|
|
50
38
|
|
|
51
39
|
const instanceName = which === "w" ? "wdb" : "rdb";
|
|
52
40
|
|
|
@@ -57,17 +45,17 @@ class DBClass {
|
|
|
57
45
|
case "staging":
|
|
58
46
|
config =
|
|
59
47
|
which === "w"
|
|
60
|
-
?
|
|
61
|
-
:
|
|
48
|
+
? dbConfig["development_master"]
|
|
49
|
+
: dbConfig["development_slave"] ?? dbConfig["development_master"];
|
|
62
50
|
break;
|
|
63
51
|
case "production":
|
|
64
52
|
config =
|
|
65
53
|
which === "w"
|
|
66
|
-
?
|
|
67
|
-
:
|
|
54
|
+
? dbConfig["production_master"]
|
|
55
|
+
: dbConfig["production_slave"] ?? dbConfig["production_master"];
|
|
68
56
|
break;
|
|
69
57
|
case "test":
|
|
70
|
-
config =
|
|
58
|
+
config = dbConfig["test"];
|
|
71
59
|
break;
|
|
72
60
|
default:
|
|
73
61
|
throw new Error(
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./api/code-converters";
|
|
2
2
|
export * from "./api/context";
|
|
3
3
|
export * from "./api/decorators";
|
|
4
|
-
export * from "./api/
|
|
4
|
+
export * from "./api/sonamu";
|
|
5
5
|
export * from "./database/base-model";
|
|
6
6
|
export * from "./database/db";
|
|
7
7
|
export * from "./database/upsert-builder";
|
package/src/smd/migrator.ts
CHANGED
|
@@ -49,17 +49,13 @@ import {
|
|
|
49
49
|
import { propIf } from "../utils/lodash-able";
|
|
50
50
|
import { SMDManager } from "./smd-manager";
|
|
51
51
|
import { SMD } from "./smd";
|
|
52
|
-
import {
|
|
52
|
+
import { Sonamu } from "../api";
|
|
53
53
|
|
|
54
54
|
type MigratorMode = "dev" | "deploy";
|
|
55
55
|
export type MigratorOptions = {
|
|
56
|
-
appRootPath: string;
|
|
57
|
-
knexfile: SonamuDBConfig;
|
|
58
56
|
readonly mode: MigratorMode;
|
|
59
57
|
};
|
|
60
58
|
export class Migrator {
|
|
61
|
-
appRootPath: string;
|
|
62
|
-
knexfile: SonamuDBConfig;
|
|
63
59
|
readonly mode: MigratorMode;
|
|
64
60
|
|
|
65
61
|
targets: {
|
|
@@ -70,23 +66,21 @@ export class Migrator {
|
|
|
70
66
|
};
|
|
71
67
|
|
|
72
68
|
constructor(options: MigratorOptions) {
|
|
73
|
-
this.appRootPath = options.appRootPath;
|
|
74
|
-
this.knexfile = options.knexfile;
|
|
75
69
|
this.mode = options.mode;
|
|
70
|
+
const { dbConfig } = Sonamu;
|
|
76
71
|
|
|
77
72
|
if (this.mode === "dev") {
|
|
78
|
-
const devDB = knex(
|
|
79
|
-
const testDB = knex(
|
|
80
|
-
const fixtureLocalDB = knex(
|
|
73
|
+
const devDB = knex(dbConfig.development_master);
|
|
74
|
+
const testDB = knex(dbConfig.test);
|
|
75
|
+
const fixtureLocalDB = knex(dbConfig.fixture_local);
|
|
81
76
|
|
|
82
77
|
const applyDBs = [devDB, testDB, fixtureLocalDB];
|
|
83
78
|
if (
|
|
84
|
-
(
|
|
79
|
+
(dbConfig.fixture_local.connection as Knex.MySql2ConnectionConfig)
|
|
85
80
|
.host !==
|
|
86
|
-
(
|
|
87
|
-
.host
|
|
81
|
+
(dbConfig.fixture_remote.connection as Knex.MySql2ConnectionConfig).host
|
|
88
82
|
) {
|
|
89
|
-
const fixtureRemoteDB = knex(
|
|
83
|
+
const fixtureRemoteDB = knex(dbConfig.fixture_remote);
|
|
90
84
|
applyDBs.push(fixtureRemoteDB);
|
|
91
85
|
}
|
|
92
86
|
|
|
@@ -97,8 +91,8 @@ export class Migrator {
|
|
|
97
91
|
apply: applyDBs,
|
|
98
92
|
};
|
|
99
93
|
} else if (this.mode === "deploy") {
|
|
100
|
-
const productionDB = knex(
|
|
101
|
-
const testDB = knex(
|
|
94
|
+
const productionDB = knex(Sonamu.dbConfig.production_master);
|
|
95
|
+
const testDB = knex(Sonamu.dbConfig.test);
|
|
102
96
|
|
|
103
97
|
this.targets = {
|
|
104
98
|
pending: productionDB,
|
|
@@ -118,7 +112,7 @@ export class Migrator {
|
|
|
118
112
|
directory: string;
|
|
119
113
|
}[]
|
|
120
114
|
];
|
|
121
|
-
const migrationsDir = `${
|
|
115
|
+
const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;
|
|
122
116
|
const delList = pendingList.map((df) => {
|
|
123
117
|
return path.join(migrationsDir, df.file).replace(".js", ".ts");
|
|
124
118
|
});
|
|
@@ -197,7 +191,7 @@ export class Migrator {
|
|
|
197
191
|
}
|
|
198
192
|
|
|
199
193
|
// 실제 코드 생성
|
|
200
|
-
const migrationsDir = `${
|
|
194
|
+
const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;
|
|
201
195
|
codes
|
|
202
196
|
.filter((code) => code.formatted)
|
|
203
197
|
.map((code, index) => {
|
|
@@ -226,8 +220,7 @@ export class Migrator {
|
|
|
226
220
|
const files = (["src", "dist"] as const).reduce(
|
|
227
221
|
(r, which) => {
|
|
228
222
|
const migrationPath = path.join(
|
|
229
|
-
|
|
230
|
-
"api",
|
|
223
|
+
Sonamu.apiRootPath,
|
|
231
224
|
which,
|
|
232
225
|
"migrations"
|
|
233
226
|
);
|
|
@@ -281,13 +274,7 @@ export class Migrator {
|
|
|
281
274
|
}
|
|
282
275
|
|
|
283
276
|
const filesToRm = diffOnDist.map((filename) => {
|
|
284
|
-
return path.join(
|
|
285
|
-
this.appRootPath,
|
|
286
|
-
"api",
|
|
287
|
-
"dist",
|
|
288
|
-
"migrations",
|
|
289
|
-
filename
|
|
290
|
-
);
|
|
277
|
+
return path.join(Sonamu.apiRootPath, "dist", "migrations", filename);
|
|
291
278
|
});
|
|
292
279
|
filesToRm.map((filePath) => {
|
|
293
280
|
unlinkSync(filePath);
|
|
@@ -298,8 +285,8 @@ export class Migrator {
|
|
|
298
285
|
|
|
299
286
|
async runShadowTest(): Promise<boolean> {
|
|
300
287
|
// ShadowDB 생성 후 테스트 진행
|
|
301
|
-
const tdb = knex(
|
|
302
|
-
const tdbConn =
|
|
288
|
+
const tdb = knex(Sonamu.dbConfig.test);
|
|
289
|
+
const tdbConn = Sonamu.dbConfig.test.connection as Knex.ConnectionConfig;
|
|
303
290
|
const shadowDatabase = tdbConn.database + "__migration_shadow";
|
|
304
291
|
const tmpSqlPath = `/tmp/${shadowDatabase}.sql`;
|
|
305
292
|
|
|
@@ -330,7 +317,7 @@ export class Migrator {
|
|
|
330
317
|
|
|
331
318
|
// shadow db 테스트 진행
|
|
332
319
|
const sdb = knex({
|
|
333
|
-
...
|
|
320
|
+
...Sonamu.dbConfig.test,
|
|
334
321
|
connection: {
|
|
335
322
|
...tdbConn,
|
|
336
323
|
database: shadowDatabase,
|
|
@@ -378,7 +365,7 @@ export class Migrator {
|
|
|
378
365
|
console.log({ rollbackAllResult });
|
|
379
366
|
console.timeEnd(chalk.red("rollback-all:"));
|
|
380
367
|
|
|
381
|
-
const migrationsDir = `${
|
|
368
|
+
const migrationsDir = `${Sonamu.apiRootPath}/src/migrations`;
|
|
382
369
|
console.time(chalk.red("delete migration files"));
|
|
383
370
|
execSync(`rm -f ${migrationsDir}/*`);
|
|
384
371
|
execSync(`rm -f ${migrationsDir.replace("/src/", "/dist/")}/*`);
|
package/src/smd/smd-manager.ts
CHANGED
|
@@ -5,7 +5,7 @@ import _ from "lodash";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { SMD } from "./smd";
|
|
7
7
|
import { SMDInput } from "../types/types";
|
|
8
|
-
import {
|
|
8
|
+
import { Sonamu } from "../api/sonamu";
|
|
9
9
|
|
|
10
10
|
export type SMDNamesRecord = Record<
|
|
11
11
|
| "fs"
|
|
@@ -33,10 +33,9 @@ class SMDManagerClass {
|
|
|
33
33
|
if (this.isAutoloaded) {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
const appRootPath = await findAppRootPath();
|
|
37
36
|
const pathPattern = path.join(
|
|
38
|
-
|
|
39
|
-
"/
|
|
37
|
+
Sonamu.apiRootPath,
|
|
38
|
+
"/dist/application/**/*.smd.js"
|
|
40
39
|
);
|
|
41
40
|
!doSilent && console.log(chalk.yellow(`autoload ${pathPattern}`));
|
|
42
41
|
|
package/src/smd/smd.ts
CHANGED
|
@@ -21,7 +21,7 @@ import path from "path";
|
|
|
21
21
|
import { existsSync } from "fs";
|
|
22
22
|
import { z } from "zod";
|
|
23
23
|
import { EnumsLabelKo } from "../types/types";
|
|
24
|
-
import {
|
|
24
|
+
import { Sonamu } from "../api/sonamu";
|
|
25
25
|
|
|
26
26
|
export class SMD {
|
|
27
27
|
id: string;
|
|
@@ -437,7 +437,6 @@ export class SMD {
|
|
|
437
437
|
|
|
438
438
|
registerModulePaths() {
|
|
439
439
|
const basePath = `${this.names.fs}`;
|
|
440
|
-
const appRootPath = Syncer.getInstance().config.appRootPath;
|
|
441
440
|
|
|
442
441
|
// base-scheme
|
|
443
442
|
SMDManager.setModulePath(
|
|
@@ -465,9 +464,9 @@ export class SMD {
|
|
|
465
464
|
|
|
466
465
|
// types
|
|
467
466
|
const typesModulePath = `${basePath}/${this.names.fs}.types`;
|
|
468
|
-
const typesFileDistPath = path.
|
|
469
|
-
|
|
470
|
-
`
|
|
467
|
+
const typesFileDistPath = path.join(
|
|
468
|
+
Sonamu.apiRootPath,
|
|
469
|
+
`dist/application/${typesModulePath}.js`
|
|
471
470
|
);
|
|
472
471
|
|
|
473
472
|
if (existsSync(typesFileDistPath)) {
|
|
@@ -485,9 +484,9 @@ export class SMD {
|
|
|
485
484
|
|
|
486
485
|
// enums
|
|
487
486
|
const enumsModulePath = `${basePath}/${this.names.fs}.enums`;
|
|
488
|
-
const enumsFileDistPath = path.
|
|
489
|
-
|
|
490
|
-
|
|
487
|
+
const enumsFileDistPath = path.join(
|
|
488
|
+
Sonamu.apiRootPath,
|
|
489
|
+
`/dist/application/${enumsModulePath}.js`
|
|
491
490
|
);
|
|
492
491
|
if (existsSync(enumsFileDistPath)) {
|
|
493
492
|
const importPath = path.relative(__dirname, enumsFileDistPath);
|
package/src/syncer/syncer.ts
CHANGED
|
@@ -82,12 +82,8 @@ import { Template__view_enums_buttonset } from "../templates/view_enums_buttonse
|
|
|
82
82
|
import { Template__view_search_input } from "../templates/view_search_input.template";
|
|
83
83
|
import { Template__view_list_columns } from "../templates/view_list_columns.template";
|
|
84
84
|
import { Template__generated_http } from "../templates/generated_http.template";
|
|
85
|
+
import { Sonamu } from "../api/sonamu";
|
|
85
86
|
|
|
86
|
-
type SyncerConfig = {
|
|
87
|
-
appRootPath: string;
|
|
88
|
-
checksumsPath: string;
|
|
89
|
-
targets: string[];
|
|
90
|
-
};
|
|
91
87
|
type FileType = "model" | "types" | "enums" | "smd" | "generated";
|
|
92
88
|
type GlobPattern = {
|
|
93
89
|
[key in FileType]: string;
|
|
@@ -112,15 +108,6 @@ export type RenderedTemplate = {
|
|
|
112
108
|
};
|
|
113
109
|
|
|
114
110
|
export class Syncer {
|
|
115
|
-
private static instance: Syncer;
|
|
116
|
-
public static getInstance(config?: Partial<SyncerConfig>) {
|
|
117
|
-
if (this.instance && config !== undefined) {
|
|
118
|
-
throw new Error("Syncer has already configured.");
|
|
119
|
-
}
|
|
120
|
-
return this.instance ?? (this.instance = new this(config));
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
config: SyncerConfig;
|
|
124
111
|
apis: {
|
|
125
112
|
typeParameters: ApiParamType.TypeParam[];
|
|
126
113
|
parameters: ApiParam[];
|
|
@@ -131,22 +118,19 @@ export class Syncer {
|
|
|
131
118
|
options: ApiDecoratorOptions;
|
|
132
119
|
}[] = [];
|
|
133
120
|
types: { [typeName: string]: z.ZodObject<any> } = {};
|
|
121
|
+
models: { [modelName: string]: unknown } = {};
|
|
134
122
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
config?.appRootPath ?? path.resolve(__dirname, "../../");
|
|
138
|
-
this.config = {
|
|
139
|
-
appRootPath,
|
|
140
|
-
checksumsPath: `${appRootPath}/api/.tf-checksum`,
|
|
141
|
-
targets: ["web"],
|
|
142
|
-
...config,
|
|
143
|
-
};
|
|
123
|
+
get checksumsPath(): string {
|
|
124
|
+
return path.join(Sonamu.apiRootPath, "/.tf-checksum");
|
|
144
125
|
}
|
|
126
|
+
public constructor() {}
|
|
145
127
|
|
|
146
128
|
async sync(): Promise<void> {
|
|
129
|
+
const { targets } = Sonamu.config.sync;
|
|
130
|
+
|
|
147
131
|
// 트리거와 무관하게 shared 분배
|
|
148
132
|
await Promise.all(
|
|
149
|
-
|
|
133
|
+
targets.map(async (target) => {
|
|
150
134
|
const srcCodePath = path
|
|
151
135
|
.join(__dirname, `../shared/${target}.shared.ts.txt`)
|
|
152
136
|
.replace("/dist/", "/src/");
|
|
@@ -155,7 +139,7 @@ export class Syncer {
|
|
|
155
139
|
}
|
|
156
140
|
|
|
157
141
|
const dstCodePath = path.join(
|
|
158
|
-
|
|
142
|
+
Sonamu.appRootPath,
|
|
159
143
|
target,
|
|
160
144
|
"src/services/sonamu.shared.ts"
|
|
161
145
|
);
|
|
@@ -233,16 +217,14 @@ export class Syncer {
|
|
|
233
217
|
// 트리거: model
|
|
234
218
|
if (diffTypes.includes("model")) {
|
|
235
219
|
const smdIds = this.getSMDIdFromPath(diffGroups["model"]);
|
|
236
|
-
|
|
237
220
|
console.log("// 액션: 서비스 생성");
|
|
238
221
|
await this.actionGenerateServices(smdIds);
|
|
239
|
-
|
|
240
222
|
console.log("// 액션: HTTP파일 생성");
|
|
241
223
|
await this.actionGenerateHttps(smdIds);
|
|
242
224
|
}
|
|
243
225
|
|
|
244
226
|
// 저장
|
|
245
|
-
await this.saveChecksums(
|
|
227
|
+
await this.saveChecksums(await this.getCurrentChecksums());
|
|
246
228
|
}
|
|
247
229
|
|
|
248
230
|
getSMDIdFromPath(filePaths: string[]): string[] {
|
|
@@ -328,13 +310,16 @@ export class Syncer {
|
|
|
328
310
|
}
|
|
329
311
|
|
|
330
312
|
async actionSyncFilesToTargets(tsPaths: string[]): Promise<string[]> {
|
|
313
|
+
const { targets } = Sonamu.config.sync;
|
|
314
|
+
const { dir: apiDir } = Sonamu.config.api;
|
|
315
|
+
|
|
331
316
|
return (
|
|
332
317
|
await Promise.all(
|
|
333
|
-
|
|
318
|
+
targets.map(async (target) =>
|
|
334
319
|
Promise.all(
|
|
335
320
|
tsPaths.map(async (src) => {
|
|
336
321
|
const dst = src
|
|
337
|
-
.replace(
|
|
322
|
+
.replace(`/${apiDir}/`, `/${target}/`)
|
|
338
323
|
.replace("/application/", "/services/");
|
|
339
324
|
const dir = dirname(dst);
|
|
340
325
|
if (!existsSync(dir)) {
|
|
@@ -352,13 +337,12 @@ export class Syncer {
|
|
|
352
337
|
async getCurrentChecksums(): Promise<PathAndChecksum[]> {
|
|
353
338
|
const PatternGroup: GlobPattern = {
|
|
354
339
|
/* TS 체크 */
|
|
355
|
-
types:
|
|
356
|
-
enums:
|
|
357
|
-
generated:
|
|
358
|
-
this.config.appRootPath + "/api/src/application/**/*.generated.ts",
|
|
340
|
+
types: Sonamu.apiRootPath + "/src/application/**/*.types.ts",
|
|
341
|
+
enums: Sonamu.apiRootPath + "/src/application/**/*.enums.ts",
|
|
342
|
+
generated: Sonamu.apiRootPath + "/src/application/**/*.generated.ts",
|
|
359
343
|
/* compiled-JS 체크 */
|
|
360
|
-
model:
|
|
361
|
-
smd:
|
|
344
|
+
model: Sonamu.apiRootPath + "/dist/application/**/*.model.js",
|
|
345
|
+
smd: Sonamu.apiRootPath + "/dist/application/**/*.smd.js",
|
|
362
346
|
};
|
|
363
347
|
|
|
364
348
|
const filePaths = (
|
|
@@ -386,19 +370,19 @@ export class Syncer {
|
|
|
386
370
|
}
|
|
387
371
|
|
|
388
372
|
async getPreviousChecksums(): Promise<PathAndChecksum[]> {
|
|
389
|
-
if (existsSync(this.
|
|
373
|
+
if (existsSync(this.checksumsPath) === false) {
|
|
390
374
|
return [];
|
|
391
375
|
}
|
|
392
376
|
|
|
393
377
|
const previousChecksums = (await readJSON(
|
|
394
|
-
this.
|
|
378
|
+
this.checksumsPath
|
|
395
379
|
)) as PathAndChecksum[];
|
|
396
380
|
return previousChecksums;
|
|
397
381
|
}
|
|
398
382
|
|
|
399
383
|
async saveChecksums(checksums: PathAndChecksum[]): Promise<void> {
|
|
400
|
-
await writeJSON(this.
|
|
401
|
-
console.debug("checksum saved", this.
|
|
384
|
+
await writeJSON(this.checksumsPath, checksums);
|
|
385
|
+
console.debug("checksum saved", this.checksumsPath);
|
|
402
386
|
}
|
|
403
387
|
|
|
404
388
|
async getChecksumOfFile(filePath: string): Promise<string> {
|
|
@@ -671,10 +655,10 @@ export class Syncer {
|
|
|
671
655
|
return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
|
|
672
656
|
}
|
|
673
657
|
|
|
674
|
-
async autoloadApis(
|
|
658
|
+
async autoloadApis() {
|
|
675
659
|
const pathPattern = path.join(
|
|
676
|
-
|
|
677
|
-
"
|
|
660
|
+
Sonamu.apiRootPath,
|
|
661
|
+
"/src/application/**/*.model.ts"
|
|
678
662
|
);
|
|
679
663
|
// console.debug(chalk.yellow(`autoload:APIs @ ${pathPattern}`));
|
|
680
664
|
|
|
@@ -686,12 +670,10 @@ export class Syncer {
|
|
|
686
670
|
return this.apis;
|
|
687
671
|
}
|
|
688
672
|
|
|
689
|
-
async autoloadModels(
|
|
690
|
-
basePath: string
|
|
691
|
-
): Promise<{ [modelName: string]: unknown }> {
|
|
673
|
+
async autoloadModels(): Promise<{ [modelName: string]: unknown }> {
|
|
692
674
|
const pathPattern = path.join(
|
|
693
|
-
|
|
694
|
-
"
|
|
675
|
+
Sonamu.apiRootPath,
|
|
676
|
+
"dist/application/**/*.model.js"
|
|
695
677
|
);
|
|
696
678
|
// console.debug(chalk.yellow(`autoload:models @ ${pathPattern}`));
|
|
697
679
|
|
|
@@ -700,22 +682,21 @@ export class Syncer {
|
|
|
700
682
|
const functions = modules
|
|
701
683
|
.map(({ imported }) => Object.entries(imported))
|
|
702
684
|
.flat();
|
|
703
|
-
|
|
685
|
+
this.models = Object.fromEntries(
|
|
704
686
|
functions.filter(([name]) => name.endsWith("Model"))
|
|
705
687
|
);
|
|
688
|
+
return this.models;
|
|
706
689
|
}
|
|
707
690
|
|
|
708
|
-
async autoloadTypes(
|
|
709
|
-
basePath: string
|
|
710
|
-
): Promise<{ [typeName: string]: z.ZodObject<any> }> {
|
|
691
|
+
async autoloadTypes(): Promise<{ [typeName: string]: z.ZodObject<any> }> {
|
|
711
692
|
if (Object.keys(this.types).length > 0) {
|
|
712
693
|
return this.types;
|
|
713
694
|
}
|
|
714
695
|
|
|
715
696
|
const pathPatterns = [
|
|
716
|
-
path.join(
|
|
717
|
-
path.join(
|
|
718
|
-
path.join(
|
|
697
|
+
path.join(Sonamu.apiRootPath, "/dist/application/**/*.types.js"),
|
|
698
|
+
path.join(Sonamu.apiRootPath, "/dist/application/**/*.enums.js"),
|
|
699
|
+
path.join(Sonamu.apiRootPath, "/dist/application/**/*.generated.js"),
|
|
719
700
|
];
|
|
720
701
|
// console.debug(chalk.magenta(`autoload:types @ ${pathPatterns.join("\n")}`));
|
|
721
702
|
|
|
@@ -784,9 +765,9 @@ export class Syncer {
|
|
|
784
765
|
if (key === "service" || key === "generated_http") {
|
|
785
766
|
// service 필요 정보 (API 리스트)
|
|
786
767
|
const smd = SMDManager.get(options.smdId);
|
|
787
|
-
const modelTsPath = `${path.
|
|
788
|
-
|
|
789
|
-
"
|
|
768
|
+
const modelTsPath = `${path.join(
|
|
769
|
+
Sonamu.apiRootPath,
|
|
770
|
+
"/src/application"
|
|
790
771
|
)}/${smd.names.fs}/${smd.names.fs}.model.ts`;
|
|
791
772
|
extra = [await this.readApisFromFile(modelTsPath)];
|
|
792
773
|
} else if (key === "view_list" || key === "model") {
|
|
@@ -890,8 +871,8 @@ export class Syncer {
|
|
|
890
871
|
}
|
|
891
872
|
|
|
892
873
|
async writeCodeToPath(pathAndCode: PathAndCode): Promise<string[]> {
|
|
893
|
-
const {
|
|
894
|
-
const filePath = `${appRootPath}/${pathAndCode.path}`;
|
|
874
|
+
const { targets } = Sonamu.config.sync;
|
|
875
|
+
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;
|
|
895
876
|
|
|
896
877
|
const dstFilePaths = uniq(
|
|
897
878
|
targets.map((target) => filePath.replace("/:target/", `/${target}/`))
|
|
@@ -949,8 +930,8 @@ export class Syncer {
|
|
|
949
930
|
} else {
|
|
950
931
|
filteredPathAndCodes = pathAndCodes.filter((pathAndCode, index) => {
|
|
951
932
|
if (index === 0) {
|
|
952
|
-
const {
|
|
953
|
-
const filePath = `${appRootPath}/${pathAndCode.path}`;
|
|
933
|
+
const { targets } = Sonamu.config.sync;
|
|
934
|
+
const filePath = `${Sonamu.appRootPath}/${pathAndCode.path}`;
|
|
954
935
|
const dstFilePaths = targets.map((target) =>
|
|
955
936
|
filePath.replace("/:target/", `/${target}/`)
|
|
956
937
|
);
|
|
@@ -991,21 +972,22 @@ export class Syncer {
|
|
|
991
972
|
enumsKeys.map((componentId) => {
|
|
992
973
|
const { target, path: p } = tpl.getTargetAndPath(names, componentId);
|
|
993
974
|
result[`${key}__${componentId}`] = existsSync(
|
|
994
|
-
path.join(
|
|
975
|
+
path.join(Sonamu.appRootPath, target, p)
|
|
995
976
|
);
|
|
996
977
|
});
|
|
997
978
|
return result;
|
|
998
979
|
}
|
|
999
980
|
|
|
1000
981
|
const { target, path: p } = tpl.getTargetAndPath(names);
|
|
982
|
+
const { targets } = Sonamu.config.sync;
|
|
1001
983
|
if (target.includes(":target")) {
|
|
1002
|
-
|
|
984
|
+
targets.map((t) => {
|
|
1003
985
|
result[`${key}__${t}`] = existsSync(
|
|
1004
|
-
path.join(
|
|
986
|
+
path.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
1005
987
|
);
|
|
1006
988
|
});
|
|
1007
989
|
} else {
|
|
1008
|
-
result[key] = existsSync(path.join(
|
|
990
|
+
result[key] = existsSync(path.join(Sonamu.appRootPath, target, p));
|
|
1009
991
|
}
|
|
1010
992
|
|
|
1011
993
|
return result;
|
|
@@ -1015,8 +997,7 @@ export class Syncer {
|
|
|
1015
997
|
async getZodTypeById(zodTypeId: string): Promise<z.ZodTypeAny> {
|
|
1016
998
|
const modulePath = SMDManager.getModulePath(zodTypeId);
|
|
1017
999
|
const moduleAbsPath = path.join(
|
|
1018
|
-
|
|
1019
|
-
"api",
|
|
1000
|
+
Sonamu.apiRootPath,
|
|
1020
1001
|
"dist",
|
|
1021
1002
|
"application",
|
|
1022
1003
|
modulePath + ".js"
|
|
@@ -7,7 +7,7 @@ import { ExtendedApi } from "../api/decorators";
|
|
|
7
7
|
import { Template } from "./base-template";
|
|
8
8
|
import prettier from "prettier";
|
|
9
9
|
import { DateTime } from "luxon";
|
|
10
|
-
import {
|
|
10
|
+
import { Sonamu } from "../api/sonamu";
|
|
11
11
|
|
|
12
12
|
export class Template__generated_http extends Template {
|
|
13
13
|
constructor() {
|
|
@@ -23,7 +23,7 @@ export class Template__generated_http extends Template {
|
|
|
23
23
|
|
|
24
24
|
render({ smdId }: TemplateOptions["generated"], apis: ExtendedApi[]) {
|
|
25
25
|
const names = SMDManager.getNamesFromId(smdId);
|
|
26
|
-
const references =
|
|
26
|
+
const references = Sonamu.syncer.types;
|
|
27
27
|
|
|
28
28
|
const lines = apis.map((api) => {
|
|
29
29
|
const reqObject = this.resolveApiParams(api, references);
|