sonamu 0.0.41 → 0.1.0
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 +1968 -956
- package/.pnp.loader.mjs +1816 -54
- package/.yarnrc.yml +1 -1
- package/dist/api/caster.d.ts +2 -4
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/code-converters.d.ts +3 -3
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +5 -15
- package/dist/api/code-converters.js.map +1 -1
- package/dist/api/context.d.ts +1 -1
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/decorators.d.ts +3 -3
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/sonamu.d.ts +3 -3
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +6 -6
- package/dist/api/sonamu.js.map +1 -1
- package/dist/bin/cli.js +240 -26
- package/dist/bin/cli.js.map +1 -1
- package/dist/database/db.d.ts +2 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +1 -1
- package/dist/database/db.js.map +1 -1
- package/dist/database/upsert-builder.d.ts +2 -2
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +10 -8
- package/dist/database/upsert-builder.js.map +1 -1
- package/dist/entity/entity-manager.d.ts +29 -0
- package/dist/entity/entity-manager.d.ts.map +1 -0
- package/dist/entity/entity-manager.js +128 -0
- package/dist/entity/entity-manager.js.map +1 -0
- package/dist/entity/entity-utils.d.ts +61 -0
- package/dist/entity/entity-utils.d.ts.map +1 -0
- package/dist/entity/entity-utils.js +121 -0
- package/dist/entity/entity-utils.js.map +1 -0
- package/dist/entity/entity.d.ts +49 -0
- package/dist/entity/entity.d.ts.map +1 -0
- package/dist/entity/entity.js +504 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/migrator.d.ts +143 -0
- package/dist/entity/migrator.d.ts.map +1 -0
- package/dist/entity/migrator.js +1385 -0
- package/dist/entity/migrator.js.map +1 -0
- package/dist/entity/smd-utils.d.ts +61 -0
- package/dist/entity/smd-utils.d.ts.map +1 -0
- package/dist/entity/smd-utils.js +121 -0
- package/dist/entity/smd-utils.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/smd/entity-manager.d.ts +28 -0
- package/dist/smd/entity-manager.d.ts.map +1 -0
- package/dist/smd/entity-manager.js +119 -0
- package/dist/smd/entity-manager.js.map +1 -0
- package/dist/smd/entity.d.ts +40 -0
- package/dist/smd/entity.d.ts.map +1 -0
- package/dist/smd/entity.js +430 -0
- package/dist/smd/entity.js.map +1 -0
- package/dist/smd/migrator.d.ts +2 -2
- package/dist/smd/migrator.d.ts.map +1 -1
- package/dist/smd/migrator.js +5 -5
- package/dist/smd/migrator.js.map +1 -1
- package/dist/smd/smd-manager.d.ts +3 -3
- package/dist/smd/smd-manager.d.ts.map +1 -1
- package/dist/smd/smd-manager.js +2 -2
- package/dist/smd/smd-manager.js.map +1 -1
- package/dist/smd/smd-utils.d.ts +4 -4
- package/dist/smd/smd-utils.d.ts.map +1 -1
- package/dist/smd/smd-utils.js.map +1 -1
- package/dist/smd/smd.d.ts +5 -6
- package/dist/smd/smd.d.ts.map +1 -1
- package/dist/smd/smd.js +3 -3
- package/dist/smd/smd.js.map +1 -1
- package/dist/syncer/syncer.d.ts +15 -11
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +134 -74
- package/dist/syncer/syncer.js.map +1 -1
- package/dist/templates/base-template.d.ts +2 -2
- package/dist/templates/base-template.d.ts.map +1 -1
- package/dist/templates/entity.template.d.ts +17 -0
- package/dist/templates/entity.template.d.ts.map +1 -0
- package/dist/templates/entity.template.js +46 -0
- package/dist/templates/entity.template.js.map +1 -0
- package/dist/templates/generated.template.d.ts +11 -7
- package/dist/templates/generated.template.d.ts.map +1 -1
- package/dist/templates/generated.template.js +72 -43
- package/dist/templates/generated.template.js.map +1 -1
- package/dist/templates/generated_http.template.d.ts +3 -3
- package/dist/templates/generated_http.template.d.ts.map +1 -1
- package/dist/templates/generated_http.template.js +3 -3
- package/dist/templates/generated_http.template.js.map +1 -1
- package/dist/templates/init_enums.template.d.ts +2 -2
- package/dist/templates/init_enums.template.d.ts.map +1 -1
- package/dist/templates/init_enums.template.js +2 -2
- package/dist/templates/init_enums.template.js.map +1 -1
- package/dist/templates/init_generated.template.d.ts +3 -3
- package/dist/templates/init_generated.template.d.ts.map +1 -1
- package/dist/templates/init_generated.template.js +13 -14
- package/dist/templates/init_generated.template.js.map +1 -1
- package/dist/templates/init_types.template.d.ts +3 -3
- package/dist/templates/init_types.template.d.ts.map +1 -1
- package/dist/templates/init_types.template.js +10 -10
- package/dist/templates/init_types.template.js.map +1 -1
- package/dist/templates/model.template.d.ts +3 -3
- package/dist/templates/model.template.d.ts.map +1 -1
- package/dist/templates/model.template.js +28 -28
- package/dist/templates/model.template.js.map +1 -1
- package/dist/templates/model_test.template.d.ts +3 -3
- package/dist/templates/model_test.template.d.ts.map +1 -1
- package/dist/templates/model_test.template.js +4 -4
- package/dist/templates/model_test.template.js.map +1 -1
- package/dist/templates/service.template.d.ts +3 -3
- package/dist/templates/service.template.d.ts.map +1 -1
- package/dist/templates/service.template.js +3 -3
- package/dist/templates/service.template.js.map +1 -1
- package/dist/templates/smd.template.d.ts +2 -2
- package/dist/templates/smd.template.d.ts.map +1 -1
- package/dist/templates/smd.template.js +2 -2
- package/dist/templates/smd.template.js.map +1 -1
- package/dist/templates/view_enums_buttonset.template.d.ts +3 -3
- package/dist/templates/view_enums_buttonset.template.d.ts.map +1 -1
- package/dist/templates/view_enums_buttonset.template.js +4 -4
- package/dist/templates/view_enums_buttonset.template.js.map +1 -1
- package/dist/templates/view_enums_dropdown.template.d.ts +3 -3
- package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -1
- package/dist/templates/view_enums_dropdown.template.js +3 -3
- package/dist/templates/view_enums_dropdown.template.js.map +1 -1
- package/dist/templates/view_enums_select.template.d.ts +3 -3
- package/dist/templates/view_enums_select.template.d.ts.map +1 -1
- package/dist/templates/view_enums_select.template.js +3 -3
- package/dist/templates/view_enums_select.template.js.map +1 -1
- package/dist/templates/view_form.template.d.ts +25 -29
- package/dist/templates/view_form.template.d.ts.map +1 -1
- package/dist/templates/view_form.template.js +19 -19
- package/dist/templates/view_form.template.js.map +1 -1
- package/dist/templates/view_id_all_select.template.d.ts +3 -3
- package/dist/templates/view_id_all_select.template.d.ts.map +1 -1
- package/dist/templates/view_id_all_select.template.js +4 -4
- package/dist/templates/view_id_all_select.template.js.map +1 -1
- package/dist/templates/view_id_async_select.template.d.ts +3 -3
- package/dist/templates/view_id_async_select.template.d.ts.map +1 -1
- package/dist/templates/view_id_async_select.template.js +6 -6
- package/dist/templates/view_id_async_select.template.js.map +1 -1
- package/dist/templates/view_list.template.d.ts +30 -34
- package/dist/templates/view_list.template.d.ts.map +1 -1
- package/dist/templates/view_list.template.js +40 -40
- package/dist/templates/view_list.template.js.map +1 -1
- package/dist/templates/view_list_columns.template.d.ts +3 -3
- package/dist/templates/view_list_columns.template.d.ts.map +1 -1
- package/dist/templates/view_list_columns.template.js +3 -3
- package/dist/templates/view_list_columns.template.js.map +1 -1
- package/dist/templates/view_search_input.template.d.ts +3 -3
- package/dist/templates/view_search_input.template.d.ts.map +1 -1
- package/dist/templates/view_search_input.template.js +3 -3
- package/dist/templates/view_search_input.template.js.map +1 -1
- package/dist/testing/fixture-manager.d.ts +2 -3
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +21 -42
- package/dist/testing/fixture-manager.js.map +1 -1
- package/dist/types/smd.types.d.ts +741 -0
- package/dist/types/smd.types.d.ts.map +1 -0
- package/dist/types/smd.types.js +292 -0
- package/dist/types/smd.types.js.map +1 -0
- package/dist/types/types.d.ts +185 -190
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +22 -30
- package/dist/types/types.js.map +1 -1
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +14 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/main.d.ts +4 -0
- package/dist/ui/main.d.ts.map +1 -0
- package/dist/ui/main.js +15 -0
- package/dist/ui/main.js.map +1 -0
- package/dist/utils/model.d.ts +2 -2
- package/dist/utils/model.d.ts.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 +6 -2
- package/dist/utils/utils.js.map +1 -1
- package/package.json +11 -8
- package/src/api/code-converters.ts +9 -17
- package/src/api/sonamu.ts +10 -6
- package/src/bin/cli.ts +247 -26
- package/src/database/upsert-builder.ts +2 -2
- package/src/entity/entity-manager.ts +150 -0
- package/src/{smd/smd-utils.ts → entity/entity-utils.ts} +4 -7
- package/src/entity/entity.ts +666 -0
- package/src/{smd → entity}/migrator.ts +426 -106
- package/src/index.ts +3 -3
- package/src/smd/smd-manager.ts +3 -13
- package/src/smd/smd.ts +13 -10
- package/src/syncer/syncer.ts +125 -73
- package/src/templates/base-template.ts +2 -2
- package/src/templates/entity.template.ts +50 -0
- package/src/templates/generated.template.ts +93 -57
- package/src/templates/generated_http.template.ts +4 -4
- package/src/templates/init_types.template.ts +11 -11
- package/src/templates/model.template.ts +29 -29
- package/src/templates/model_test.template.ts +5 -5
- package/src/templates/service.template.ts +4 -4
- package/src/templates/view_enums_buttonset.template.ts +5 -5
- package/src/templates/view_enums_dropdown.template.ts +4 -4
- package/src/templates/view_enums_select.template.ts +8 -4
- package/src/templates/view_form.template.ts +21 -21
- package/src/templates/view_id_all_select.template.ts +5 -5
- package/src/templates/view_id_async_select.template.ts +9 -7
- package/src/templates/view_list.template.ts +54 -44
- package/src/templates/view_list_columns.template.ts +4 -4
- package/src/templates/view_search_input.template.ts +4 -4
- package/src/testing/fixture-manager.ts +19 -60
- package/src/types/types.ts +59 -41
- package/src/utils/utils.ts +4 -0
- package/tsconfig.json +4 -1
- package/src/templates/init_enums.template.ts +0 -71
- package/src/templates/init_generated.template.ts +0 -51
- package/src/templates/smd.template.ts +0 -53
package/src/bin/cli.ts
CHANGED
|
@@ -7,13 +7,24 @@ dotenv.config();
|
|
|
7
7
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { BaseModel } from "../database/base-model";
|
|
10
|
-
import {
|
|
11
|
-
import { Migrator } from "../
|
|
10
|
+
import { EntityManager } from "../entity/entity-manager";
|
|
11
|
+
import { Migrator } from "../entity/migrator";
|
|
12
12
|
import { FixtureManager } from "../testing/fixture-manager";
|
|
13
13
|
import { tsicli } from "tsicli";
|
|
14
14
|
import { execSync } from "child_process";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
existsSync,
|
|
17
|
+
mkdirSync,
|
|
18
|
+
readdirSync,
|
|
19
|
+
unlinkSync,
|
|
20
|
+
writeFileSync,
|
|
21
|
+
} from "fs";
|
|
16
22
|
import { Sonamu } from "../api";
|
|
23
|
+
import knex, { Knex } from "knex";
|
|
24
|
+
import { camelize } from "inflection";
|
|
25
|
+
import prettier from "prettier";
|
|
26
|
+
import { SMDManager } from "../smd/smd-manager";
|
|
27
|
+
import process from "process";
|
|
17
28
|
|
|
18
29
|
let migrator: Migrator;
|
|
19
30
|
|
|
@@ -22,20 +33,21 @@ async function bootstrap() {
|
|
|
22
33
|
|
|
23
34
|
await tsicli(process.argv, {
|
|
24
35
|
types: {
|
|
25
|
-
"#
|
|
36
|
+
"#entityId": {
|
|
26
37
|
type: "autocomplete",
|
|
27
|
-
name: "#
|
|
28
|
-
message: "Please input #
|
|
29
|
-
choices:
|
|
30
|
-
title:
|
|
31
|
-
value:
|
|
38
|
+
name: "#entityId",
|
|
39
|
+
message: "Please input #entityId",
|
|
40
|
+
choices: EntityManager.getAllParentIds().map((entityId) => ({
|
|
41
|
+
title: entityId,
|
|
42
|
+
value: entityId,
|
|
32
43
|
})),
|
|
33
44
|
},
|
|
34
45
|
"#recordIds": "number[]",
|
|
35
46
|
"#name": "string",
|
|
36
47
|
},
|
|
37
48
|
args: [
|
|
38
|
-
["fixture", "
|
|
49
|
+
["fixture", "init"],
|
|
50
|
+
["fixture", "import", "#entityId", "#recordIds"],
|
|
39
51
|
["fixture", "sync"],
|
|
40
52
|
["migrate", "run"],
|
|
41
53
|
["migrate", "check"],
|
|
@@ -43,11 +55,13 @@ async function bootstrap() {
|
|
|
43
55
|
["migrate", "reset"],
|
|
44
56
|
["migrate", "clear"],
|
|
45
57
|
["stub", "practice", "#name"],
|
|
46
|
-
["stub", "
|
|
47
|
-
["scaffold", "model", "#
|
|
48
|
-
["scaffold", "model_test", "#
|
|
49
|
-
["scaffold", "view_list", "#
|
|
50
|
-
["scaffold", "view_form", "#
|
|
58
|
+
["stub", "entity", "#name"],
|
|
59
|
+
["scaffold", "model", "#entityId"],
|
|
60
|
+
["scaffold", "model_test", "#entityId"],
|
|
61
|
+
["scaffold", "view_list", "#entityId"],
|
|
62
|
+
["scaffold", "view_form", "#entityId"],
|
|
63
|
+
["ui"],
|
|
64
|
+
["smd_migration"],
|
|
51
65
|
],
|
|
52
66
|
runners: {
|
|
53
67
|
migrate_run,
|
|
@@ -55,14 +69,17 @@ async function bootstrap() {
|
|
|
55
69
|
migrate_rollback,
|
|
56
70
|
migrate_clear,
|
|
57
71
|
migrate_reset,
|
|
72
|
+
fixture_init,
|
|
58
73
|
fixture_import,
|
|
59
74
|
fixture_sync,
|
|
60
75
|
stub_practice,
|
|
61
|
-
|
|
76
|
+
stub_entity,
|
|
62
77
|
scaffold_model,
|
|
63
78
|
scaffold_model_test,
|
|
79
|
+
ui,
|
|
64
80
|
// scaffold_view_list,
|
|
65
81
|
// scaffold_view_form,
|
|
82
|
+
smd_migration,
|
|
66
83
|
},
|
|
67
84
|
});
|
|
68
85
|
}
|
|
@@ -120,10 +137,84 @@ async function migrate_reset() {
|
|
|
120
137
|
await migrator.resetAll();
|
|
121
138
|
}
|
|
122
139
|
|
|
123
|
-
async function
|
|
140
|
+
async function fixture_init() {
|
|
141
|
+
const srcConfig = Sonamu.dbConfig.development_master;
|
|
142
|
+
const targets = [
|
|
143
|
+
{
|
|
144
|
+
label: "(REMOTE) Fixture DB",
|
|
145
|
+
config: Sonamu.dbConfig.fixture_remote,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: "(LOCAL) Fixture DB",
|
|
149
|
+
config: Sonamu.dbConfig.fixture_local,
|
|
150
|
+
toSkip: (() => {
|
|
151
|
+
const remoteConn = Sonamu.dbConfig.fixture_remote
|
|
152
|
+
.connection as Knex.ConnectionConfig;
|
|
153
|
+
const localConn = Sonamu.dbConfig.fixture_local
|
|
154
|
+
.connection as Knex.ConnectionConfig;
|
|
155
|
+
return (
|
|
156
|
+
remoteConn.host === localConn.host &&
|
|
157
|
+
remoteConn.database === localConn.database
|
|
158
|
+
);
|
|
159
|
+
})(),
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
label: "(LOCAL) Testing DB",
|
|
163
|
+
config: Sonamu.dbConfig.test,
|
|
164
|
+
},
|
|
165
|
+
] as {
|
|
166
|
+
label: string;
|
|
167
|
+
config: Knex.Config;
|
|
168
|
+
toSkip?: boolean;
|
|
169
|
+
}[];
|
|
170
|
+
|
|
171
|
+
// 1. 기준DB 스키마를 덤프
|
|
172
|
+
console.log("DUMP...");
|
|
173
|
+
const dumpFilename = `/tmp/sonamu-fixture-init-${Date.now()}.sql`;
|
|
174
|
+
const srcConn = srcConfig.connection as Knex.ConnectionConfig;
|
|
175
|
+
execSync(
|
|
176
|
+
`mysqldump -h${srcConn.host} -u${srcConn.user} -p${srcConn.password} --single-transaction -d --no-create-db --triggers ${srcConn.database} > ${dumpFilename}`
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// 2. 대상DB 각각에 대하여 존재여부 확인 후 붓기
|
|
180
|
+
for await (const { label, config, toSkip } of targets) {
|
|
181
|
+
const conn = config.connection as Knex.ConnectionConfig;
|
|
182
|
+
|
|
183
|
+
if (toSkip === true) {
|
|
184
|
+
console.log(chalk.red(`${label}: Skipped!`));
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const db = knex({
|
|
189
|
+
...config,
|
|
190
|
+
connection: {
|
|
191
|
+
...((config.connection ?? {}) as Knex.ConnectionConfig),
|
|
192
|
+
database: undefined,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
const [[row]] = await db.raw(`SHOW DATABASES LIKE "${conn.database}"`);
|
|
196
|
+
if (row) {
|
|
197
|
+
console.log(
|
|
198
|
+
chalk.yellow(`${label}: Database "${conn.database} Already exists`)
|
|
199
|
+
);
|
|
200
|
+
await db.destroy();
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
console.log(`SYNC to ${label}...`);
|
|
205
|
+
const mysqlCmd = `mysql -h${conn.host} -u${conn.user} -p${conn.password}`;
|
|
206
|
+
execSync(`${mysqlCmd} -e 'DROP DATABASE IF EXISTS ${conn.database}'`);
|
|
207
|
+
execSync(`${mysqlCmd} -e 'CREATE DATABASE ${conn.database}'`);
|
|
208
|
+
execSync(`${mysqlCmd} ${conn.database} < ${dumpFilename}`);
|
|
209
|
+
|
|
210
|
+
await db.destroy();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function fixture_import(entityId: string, recordIds: number[]) {
|
|
124
215
|
await setupFixtureManager();
|
|
125
216
|
|
|
126
|
-
await FixtureManager.importFixture(
|
|
217
|
+
await FixtureManager.importFixture(entityId, recordIds);
|
|
127
218
|
await FixtureManager.sync();
|
|
128
219
|
}
|
|
129
220
|
|
|
@@ -188,20 +279,150 @@ async function stub_practice(name: string) {
|
|
|
188
279
|
execSync(`echo "${runCode}" | pbcopy`);
|
|
189
280
|
}
|
|
190
281
|
|
|
191
|
-
async function
|
|
192
|
-
await Sonamu.syncer.
|
|
193
|
-
smdId: name,
|
|
194
|
-
});
|
|
282
|
+
async function stub_entity(entityId: string) {
|
|
283
|
+
await Sonamu.syncer.createEntity(entityId);
|
|
195
284
|
}
|
|
196
285
|
|
|
197
|
-
async function scaffold_model(
|
|
286
|
+
async function scaffold_model(entityId: string) {
|
|
198
287
|
await Sonamu.syncer.generateTemplate("model", {
|
|
199
|
-
|
|
288
|
+
entityId,
|
|
200
289
|
});
|
|
201
290
|
}
|
|
202
291
|
|
|
203
|
-
async function scaffold_model_test(
|
|
292
|
+
async function scaffold_model_test(entityId: string) {
|
|
204
293
|
await Sonamu.syncer.generateTemplate("model_test", {
|
|
205
|
-
|
|
294
|
+
entityId,
|
|
206
295
|
});
|
|
207
296
|
}
|
|
297
|
+
|
|
298
|
+
async function ui() {
|
|
299
|
+
try {
|
|
300
|
+
const sonamuUI: {
|
|
301
|
+
startServers: (appRootPath: string) => void;
|
|
302
|
+
} = await import("@sonamu-kit/ui" as string);
|
|
303
|
+
sonamuUI.startServers(Sonamu.appRootPath);
|
|
304
|
+
} catch (e: unknown) {
|
|
305
|
+
if (e instanceof Error && e.message.includes("isn't declared")) {
|
|
306
|
+
console.log(`You need to install ${chalk.blue(`@sonamu-kit/ui`)} first.`);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
throw e;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async function smd_migration() {
|
|
314
|
+
await SMDManager.autoload();
|
|
315
|
+
const smdIds = SMDManager.getAllIds();
|
|
316
|
+
|
|
317
|
+
function enumLabelsToEntityEnums(
|
|
318
|
+
entityId: string,
|
|
319
|
+
enumLabels: {
|
|
320
|
+
[enumName: string]: { [name: string]: { ko: string } };
|
|
321
|
+
}
|
|
322
|
+
): { [enumName: string]: { [name: string]: string } } {
|
|
323
|
+
return Object.fromEntries(
|
|
324
|
+
Object.entries(enumLabels).map(([enumLabelName, enumLabel]) => {
|
|
325
|
+
const enumName =
|
|
326
|
+
entityId + camelize(enumLabelName.toLowerCase(), false);
|
|
327
|
+
return [
|
|
328
|
+
enumName,
|
|
329
|
+
Object.fromEntries(
|
|
330
|
+
Object.entries(enumLabel).map(([name, { ko }]) => [name, ko])
|
|
331
|
+
),
|
|
332
|
+
];
|
|
333
|
+
})
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
for await (const smdId of smdIds) {
|
|
337
|
+
const smd = SMDManager.get(smdId);
|
|
338
|
+
const entityJson = {
|
|
339
|
+
id: smd.id,
|
|
340
|
+
...(smd.parentId ? { parentId: smd.parentId } : {}),
|
|
341
|
+
title: smd.title,
|
|
342
|
+
props: smd.props,
|
|
343
|
+
indexes: smd.indexes,
|
|
344
|
+
subsets: smd.subsets,
|
|
345
|
+
enums: enumLabelsToEntityEnums(smd.id, smd.enumLabels),
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const parentNames = SMDManager.getNamesFromId(smd.parentId ?? smd.id);
|
|
349
|
+
const names = SMDManager.getNamesFromId(smd.id);
|
|
350
|
+
const dstPath = path.join(
|
|
351
|
+
Sonamu.apiRootPath,
|
|
352
|
+
"src",
|
|
353
|
+
"application",
|
|
354
|
+
parentNames.fs,
|
|
355
|
+
`${names.fs}.entity.json`
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
const formatted = prettier.format(JSON.stringify(entityJson), {
|
|
359
|
+
parser: "json",
|
|
360
|
+
});
|
|
361
|
+
writeFileSync(dstPath, formatted);
|
|
362
|
+
console.log(chalk.blue(`CREATED: ${dstPath}`));
|
|
363
|
+
|
|
364
|
+
// smd.ts, enums.ts, genereated.ts 삭제 (트랜스파일 된 js파일도 삭제)
|
|
365
|
+
const srcSmdPath = path.join(
|
|
366
|
+
Sonamu.apiRootPath,
|
|
367
|
+
"src",
|
|
368
|
+
"application",
|
|
369
|
+
parentNames.fs,
|
|
370
|
+
`${names.fs}.smd.ts`
|
|
371
|
+
);
|
|
372
|
+
const dstSmdPath = srcSmdPath
|
|
373
|
+
.replace("/src/", "/dist/")
|
|
374
|
+
.replace(/\.ts$/, ".js");
|
|
375
|
+
const srcEnumsPath = path.join(
|
|
376
|
+
Sonamu.apiRootPath,
|
|
377
|
+
"src",
|
|
378
|
+
"application",
|
|
379
|
+
parentNames.fs,
|
|
380
|
+
`${names.fs}.enums.ts`
|
|
381
|
+
);
|
|
382
|
+
const dstEnumsPath = srcEnumsPath
|
|
383
|
+
.replace("/src/", "/dist/")
|
|
384
|
+
.replace(/\.ts$/, ".js");
|
|
385
|
+
const srcGeneratedPath = path.join(
|
|
386
|
+
Sonamu.apiRootPath,
|
|
387
|
+
"src",
|
|
388
|
+
"application",
|
|
389
|
+
parentNames.fs,
|
|
390
|
+
`${names.fs}.generated.ts`
|
|
391
|
+
);
|
|
392
|
+
const dstGeneratedPath = srcGeneratedPath
|
|
393
|
+
.replace("/src/", "/dist/")
|
|
394
|
+
.replace(/\.ts$/, ".js");
|
|
395
|
+
|
|
396
|
+
[
|
|
397
|
+
srcSmdPath,
|
|
398
|
+
dstSmdPath,
|
|
399
|
+
srcEnumsPath,
|
|
400
|
+
dstEnumsPath,
|
|
401
|
+
...Sonamu.config.sync.targets.map((target) =>
|
|
402
|
+
srcEnumsPath
|
|
403
|
+
.replace(Sonamu.apiRootPath, path.join(Sonamu.appRootPath, target))
|
|
404
|
+
.replace("/src/application/", "/src/services/")
|
|
405
|
+
),
|
|
406
|
+
srcGeneratedPath,
|
|
407
|
+
dstGeneratedPath,
|
|
408
|
+
].map((p) => {
|
|
409
|
+
if (existsSync(p) === false) {
|
|
410
|
+
console.log(chalk.yellow(`NOT FOUND: ${p}`));
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
unlinkSync(p);
|
|
414
|
+
console.log(chalk.red(`DELETED: ${p}`));
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Entity로 reload
|
|
419
|
+
console.log("Entity로 다시 로드합니다.");
|
|
420
|
+
EntityManager.isAutoloaded = false;
|
|
421
|
+
await EntityManager.autoload();
|
|
422
|
+
|
|
423
|
+
// Entity를 통해 generated.ts 재생성
|
|
424
|
+
const entityIds = EntityManager.getAllParentIds();
|
|
425
|
+
for await (const entityId of entityIds) {
|
|
426
|
+
await Sonamu.syncer.generateTemplate("generated", { entityId });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from "uuid";
|
|
2
2
|
import _, { chunk, defaults, groupBy } from "lodash";
|
|
3
3
|
import { Knex } from "knex";
|
|
4
|
-
import {
|
|
4
|
+
import { EntityManager } from "../entity/entity-manager";
|
|
5
5
|
|
|
6
6
|
type TableData = {
|
|
7
7
|
references: Set<string>;
|
|
@@ -34,7 +34,7 @@ export class UpsertBuilder {
|
|
|
34
34
|
if (table === undefined) {
|
|
35
35
|
const tableSpec = (() => {
|
|
36
36
|
try {
|
|
37
|
-
return
|
|
37
|
+
return EntityManager.getTableSpec(tableName);
|
|
38
38
|
} catch {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { glob } from "glob";
|
|
3
|
+
import { dasherize, underscore, pluralize, camelize } from "inflection";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { Entity } from "./entity";
|
|
7
|
+
import { EntityJson } from "../types/types";
|
|
8
|
+
import { Sonamu } from "../api/sonamu";
|
|
9
|
+
import { readFileSync } from "fs";
|
|
10
|
+
|
|
11
|
+
export type EntityNamesRecord = Record<
|
|
12
|
+
| "fs"
|
|
13
|
+
| "fsPlural"
|
|
14
|
+
| "camel"
|
|
15
|
+
| "camelPlural"
|
|
16
|
+
| "capital"
|
|
17
|
+
| "capitalPlural"
|
|
18
|
+
| "upper"
|
|
19
|
+
| "constant",
|
|
20
|
+
string
|
|
21
|
+
>;
|
|
22
|
+
type TableSpec = {
|
|
23
|
+
name: string;
|
|
24
|
+
uniqueColumns: string[];
|
|
25
|
+
};
|
|
26
|
+
class EntityManagerClass {
|
|
27
|
+
private entities: Map<string, Entity> = new Map();
|
|
28
|
+
public modulePaths: Map<string, string> = new Map();
|
|
29
|
+
private tableSpecs: Map<string, TableSpec> = new Map();
|
|
30
|
+
public isAutoloaded: boolean = false;
|
|
31
|
+
|
|
32
|
+
// 경로 전달받아 모든 entity.json 파일 로드
|
|
33
|
+
async autoload(doSilent: boolean = false) {
|
|
34
|
+
if (this.isAutoloaded) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const pathPattern = path.join(
|
|
38
|
+
Sonamu.apiRootPath,
|
|
39
|
+
"/src/application/**/*.entity.json"
|
|
40
|
+
);
|
|
41
|
+
!doSilent && console.log(chalk.yellow(`autoload ${pathPattern}`));
|
|
42
|
+
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
glob(path.resolve(pathPattern!), (_err, files) => {
|
|
45
|
+
Promise.all(
|
|
46
|
+
files.map(async (file) => {
|
|
47
|
+
this.register(JSON.parse(readFileSync(file).toString()));
|
|
48
|
+
})
|
|
49
|
+
).then(() => {
|
|
50
|
+
resolve("ok");
|
|
51
|
+
this.isAutoloaded = true;
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async reload(doSilent: boolean = false) {
|
|
58
|
+
this.entities.clear();
|
|
59
|
+
this.modulePaths.clear();
|
|
60
|
+
this.tableSpecs.clear();
|
|
61
|
+
this.isAutoloaded = false;
|
|
62
|
+
|
|
63
|
+
return this.autoload(doSilent);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
register(json: EntityJson): void {
|
|
67
|
+
const entity = new Entity(json);
|
|
68
|
+
this.entities.set(json.id, entity);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get(entityId: string): Entity {
|
|
72
|
+
const entity = this.entities.get(entityId);
|
|
73
|
+
if (entity === undefined) {
|
|
74
|
+
throw new Error(`존재하지 않는 Entity 요청 ${entityId}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return entity;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exists(entityId: string): boolean {
|
|
81
|
+
const entity = this.entities.get(entityId);
|
|
82
|
+
return entity !== undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getAllIds(): string[] {
|
|
86
|
+
return Array.from(EntityManager.entities.keys());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getAllParentIds(): string[] {
|
|
90
|
+
return this.getAllIds().filter((entityId) => {
|
|
91
|
+
const entity = this.get(entityId);
|
|
92
|
+
return entity.parentId === undefined;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getChildrenIds(parentId: string): string[] {
|
|
97
|
+
return this.getAllIds().filter((entityId) => {
|
|
98
|
+
const entity = this.get(entityId);
|
|
99
|
+
return entity.parentId === parentId;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
setModulePath(key: string, modulePath: string): void {
|
|
104
|
+
// console.debug(chalk.cyan(`setModulePath :: ${key} :: ${modulePath}`));
|
|
105
|
+
this.modulePaths.set(key, modulePath);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
getModulePath(key: string): string {
|
|
109
|
+
const modulePath = this.modulePaths.get(key);
|
|
110
|
+
if (modulePath === undefined) {
|
|
111
|
+
throw new Error(`존재하지 않는 모듈 패스 요청 ${key}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return modulePath;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
setTableSpec(tableSpec: TableSpec) {
|
|
118
|
+
this.tableSpecs.set(tableSpec.name, tableSpec);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
getTableSpec(key: string): TableSpec {
|
|
122
|
+
const tableSpec = this.tableSpecs.get(key);
|
|
123
|
+
if (tableSpec === undefined) {
|
|
124
|
+
throw new Error(`존재하지 않는 테이블 스펙 요청 ${key}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return tableSpec;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getNamesFromId(entityId: string): EntityNamesRecord {
|
|
131
|
+
// entityId가 단복수 동형 단어인 경우 List 붙여서 생성
|
|
132
|
+
const pluralized =
|
|
133
|
+
pluralize(entityId) === entityId
|
|
134
|
+
? `${entityId}List`
|
|
135
|
+
: pluralize(entityId);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
fs: dasherize(underscore(entityId)).toLowerCase(),
|
|
139
|
+
fsPlural: dasherize(underscore(pluralized)).toLowerCase(),
|
|
140
|
+
camel: camelize(entityId, true),
|
|
141
|
+
camelPlural: camelize(pluralized, true),
|
|
142
|
+
capital: entityId,
|
|
143
|
+
capitalPlural: pluralized,
|
|
144
|
+
upper: entityId.toUpperCase(),
|
|
145
|
+
constant: underscore(entityId).toUpperCase(),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const EntityManager = new EntityManagerClass();
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
JsonProp,
|
|
16
16
|
ManyToManyRelationProp,
|
|
17
17
|
OneToOneRelationProp,
|
|
18
|
-
|
|
18
|
+
EntityIndex,
|
|
19
19
|
StringProp,
|
|
20
20
|
TextProp,
|
|
21
21
|
TimeProp,
|
|
@@ -212,10 +212,7 @@ function enums(
|
|
|
212
212
|
}
|
|
213
213
|
function virtual(
|
|
214
214
|
name: string,
|
|
215
|
-
option: Omit<
|
|
216
|
-
VirtualProp,
|
|
217
|
-
"name" | "type" | "index" | "unique" | "dbDefault" | "toFilter"
|
|
218
|
-
>
|
|
215
|
+
option: Omit<VirtualProp, "name" | "type" | "dbDefault" | "toFilter">
|
|
219
216
|
): VirtualProp {
|
|
220
217
|
return {
|
|
221
218
|
name,
|
|
@@ -276,14 +273,14 @@ export const i = {
|
|
|
276
273
|
unique,
|
|
277
274
|
};
|
|
278
275
|
|
|
279
|
-
function index(columns: string | string[]):
|
|
276
|
+
function index(columns: string | string[]): EntityIndex {
|
|
280
277
|
return {
|
|
281
278
|
type: "index",
|
|
282
279
|
columns: asArray(columns),
|
|
283
280
|
};
|
|
284
281
|
}
|
|
285
282
|
|
|
286
|
-
function unique(columns: string | string[]):
|
|
283
|
+
function unique(columns: string | string[]): EntityIndex {
|
|
287
284
|
return {
|
|
288
285
|
type: "unique",
|
|
289
286
|
columns: asArray(columns),
|