sonamu 0.0.42 → 0.1.2

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.
Files changed (208) hide show
  1. package/.pnp.cjs +1963 -951
  2. package/.pnp.loader.mjs +1816 -54
  3. package/.yarnrc.yml +1 -1
  4. package/dist/api/code-converters.d.ts +3 -3
  5. package/dist/api/code-converters.d.ts.map +1 -1
  6. package/dist/api/code-converters.js +5 -15
  7. package/dist/api/code-converters.js.map +1 -1
  8. package/dist/api/context.d.ts +1 -1
  9. package/dist/api/context.d.ts.map +1 -1
  10. package/dist/api/decorators.d.ts +3 -3
  11. package/dist/api/decorators.d.ts.map +1 -1
  12. package/dist/api/sonamu.d.ts +3 -3
  13. package/dist/api/sonamu.d.ts.map +1 -1
  14. package/dist/api/sonamu.js +6 -6
  15. package/dist/api/sonamu.js.map +1 -1
  16. package/dist/bin/cli.js +132 -33
  17. package/dist/bin/cli.js.map +1 -1
  18. package/dist/database/db.d.ts +2 -2
  19. package/dist/database/db.d.ts.map +1 -1
  20. package/dist/database/db.js +1 -1
  21. package/dist/database/db.js.map +1 -1
  22. package/dist/database/upsert-builder.d.ts +2 -2
  23. package/dist/database/upsert-builder.d.ts.map +1 -1
  24. package/dist/database/upsert-builder.js +10 -8
  25. package/dist/database/upsert-builder.js.map +1 -1
  26. package/dist/entity/entity-manager.d.ts +29 -0
  27. package/dist/entity/entity-manager.d.ts.map +1 -0
  28. package/dist/entity/entity-manager.js +128 -0
  29. package/dist/entity/entity-manager.js.map +1 -0
  30. package/dist/entity/entity-utils.d.ts +61 -0
  31. package/dist/entity/entity-utils.d.ts.map +1 -0
  32. package/dist/entity/entity-utils.js +121 -0
  33. package/dist/entity/entity-utils.js.map +1 -0
  34. package/dist/entity/entity.d.ts +54 -0
  35. package/dist/entity/entity.d.ts.map +1 -0
  36. package/dist/entity/entity.js +596 -0
  37. package/dist/entity/entity.js.map +1 -0
  38. package/dist/entity/migrator.d.ts +143 -0
  39. package/dist/entity/migrator.d.ts.map +1 -0
  40. package/dist/entity/migrator.js +1385 -0
  41. package/dist/entity/migrator.js.map +1 -0
  42. package/dist/entity/smd-utils.d.ts +61 -0
  43. package/dist/entity/smd-utils.d.ts.map +1 -0
  44. package/dist/entity/smd-utils.js +121 -0
  45. package/dist/entity/smd-utils.js.map +1 -0
  46. package/dist/index.d.ts +3 -3
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +3 -3
  49. package/dist/index.js.map +1 -1
  50. package/dist/smd/entity-manager.d.ts +28 -0
  51. package/dist/smd/entity-manager.d.ts.map +1 -0
  52. package/dist/smd/entity-manager.js +119 -0
  53. package/dist/smd/entity-manager.js.map +1 -0
  54. package/dist/smd/entity.d.ts +40 -0
  55. package/dist/smd/entity.d.ts.map +1 -0
  56. package/dist/smd/entity.js +430 -0
  57. package/dist/smd/entity.js.map +1 -0
  58. package/dist/smd/migrator.d.ts +2 -2
  59. package/dist/smd/migrator.d.ts.map +1 -1
  60. package/dist/smd/migrator.js +5 -5
  61. package/dist/smd/migrator.js.map +1 -1
  62. package/dist/smd/smd-manager.d.ts +3 -3
  63. package/dist/smd/smd-manager.d.ts.map +1 -1
  64. package/dist/smd/smd-manager.js +2 -2
  65. package/dist/smd/smd-manager.js.map +1 -1
  66. package/dist/smd/smd-utils.d.ts +3 -3
  67. package/dist/smd/smd-utils.d.ts.map +1 -1
  68. package/dist/smd/smd.d.ts +5 -6
  69. package/dist/smd/smd.d.ts.map +1 -1
  70. package/dist/smd/smd.js +3 -3
  71. package/dist/smd/smd.js.map +1 -1
  72. package/dist/syncer/syncer.d.ts +15 -11
  73. package/dist/syncer/syncer.d.ts.map +1 -1
  74. package/dist/syncer/syncer.js +134 -74
  75. package/dist/syncer/syncer.js.map +1 -1
  76. package/dist/templates/base-template.d.ts +2 -2
  77. package/dist/templates/base-template.d.ts.map +1 -1
  78. package/dist/templates/entity.template.d.ts +17 -0
  79. package/dist/templates/entity.template.d.ts.map +1 -0
  80. package/dist/templates/entity.template.js +46 -0
  81. package/dist/templates/entity.template.js.map +1 -0
  82. package/dist/templates/generated.template.d.ts +11 -7
  83. package/dist/templates/generated.template.d.ts.map +1 -1
  84. package/dist/templates/generated.template.js +72 -43
  85. package/dist/templates/generated.template.js.map +1 -1
  86. package/dist/templates/generated_http.template.d.ts +3 -3
  87. package/dist/templates/generated_http.template.d.ts.map +1 -1
  88. package/dist/templates/generated_http.template.js +3 -3
  89. package/dist/templates/generated_http.template.js.map +1 -1
  90. package/dist/templates/init_enums.template.d.ts +2 -2
  91. package/dist/templates/init_enums.template.d.ts.map +1 -1
  92. package/dist/templates/init_enums.template.js +2 -2
  93. package/dist/templates/init_enums.template.js.map +1 -1
  94. package/dist/templates/init_generated.template.d.ts +3 -3
  95. package/dist/templates/init_generated.template.d.ts.map +1 -1
  96. package/dist/templates/init_generated.template.js +13 -14
  97. package/dist/templates/init_generated.template.js.map +1 -1
  98. package/dist/templates/init_types.template.d.ts +3 -3
  99. package/dist/templates/init_types.template.d.ts.map +1 -1
  100. package/dist/templates/init_types.template.js +10 -10
  101. package/dist/templates/init_types.template.js.map +1 -1
  102. package/dist/templates/model.template.d.ts +3 -3
  103. package/dist/templates/model.template.d.ts.map +1 -1
  104. package/dist/templates/model.template.js +28 -28
  105. package/dist/templates/model.template.js.map +1 -1
  106. package/dist/templates/model_test.template.d.ts +3 -3
  107. package/dist/templates/model_test.template.d.ts.map +1 -1
  108. package/dist/templates/model_test.template.js +4 -4
  109. package/dist/templates/model_test.template.js.map +1 -1
  110. package/dist/templates/service.template.d.ts +3 -3
  111. package/dist/templates/service.template.d.ts.map +1 -1
  112. package/dist/templates/service.template.js +3 -3
  113. package/dist/templates/service.template.js.map +1 -1
  114. package/dist/templates/smd.template.d.ts +2 -2
  115. package/dist/templates/smd.template.d.ts.map +1 -1
  116. package/dist/templates/smd.template.js +2 -2
  117. package/dist/templates/smd.template.js.map +1 -1
  118. package/dist/templates/view_enums_buttonset.template.d.ts +3 -3
  119. package/dist/templates/view_enums_buttonset.template.d.ts.map +1 -1
  120. package/dist/templates/view_enums_buttonset.template.js +4 -4
  121. package/dist/templates/view_enums_buttonset.template.js.map +1 -1
  122. package/dist/templates/view_enums_dropdown.template.d.ts +3 -3
  123. package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -1
  124. package/dist/templates/view_enums_dropdown.template.js +3 -3
  125. package/dist/templates/view_enums_dropdown.template.js.map +1 -1
  126. package/dist/templates/view_enums_select.template.d.ts +3 -3
  127. package/dist/templates/view_enums_select.template.d.ts.map +1 -1
  128. package/dist/templates/view_enums_select.template.js +3 -3
  129. package/dist/templates/view_enums_select.template.js.map +1 -1
  130. package/dist/templates/view_form.template.d.ts +25 -29
  131. package/dist/templates/view_form.template.d.ts.map +1 -1
  132. package/dist/templates/view_form.template.js +19 -19
  133. package/dist/templates/view_form.template.js.map +1 -1
  134. package/dist/templates/view_id_all_select.template.d.ts +3 -3
  135. package/dist/templates/view_id_all_select.template.d.ts.map +1 -1
  136. package/dist/templates/view_id_all_select.template.js +4 -4
  137. package/dist/templates/view_id_all_select.template.js.map +1 -1
  138. package/dist/templates/view_id_async_select.template.d.ts +3 -3
  139. package/dist/templates/view_id_async_select.template.d.ts.map +1 -1
  140. package/dist/templates/view_id_async_select.template.js +6 -6
  141. package/dist/templates/view_id_async_select.template.js.map +1 -1
  142. package/dist/templates/view_list.template.d.ts +30 -34
  143. package/dist/templates/view_list.template.d.ts.map +1 -1
  144. package/dist/templates/view_list.template.js +40 -40
  145. package/dist/templates/view_list.template.js.map +1 -1
  146. package/dist/templates/view_list_columns.template.d.ts +3 -3
  147. package/dist/templates/view_list_columns.template.d.ts.map +1 -1
  148. package/dist/templates/view_list_columns.template.js +3 -3
  149. package/dist/templates/view_list_columns.template.js.map +1 -1
  150. package/dist/templates/view_search_input.template.d.ts +3 -3
  151. package/dist/templates/view_search_input.template.d.ts.map +1 -1
  152. package/dist/templates/view_search_input.template.js +3 -3
  153. package/dist/templates/view_search_input.template.js.map +1 -1
  154. package/dist/testing/fixture-manager.d.ts +2 -2
  155. package/dist/testing/fixture-manager.d.ts.map +1 -1
  156. package/dist/testing/fixture-manager.js +18 -16
  157. package/dist/testing/fixture-manager.js.map +1 -1
  158. package/dist/types/smd.types.d.ts +741 -0
  159. package/dist/types/smd.types.d.ts.map +1 -0
  160. package/dist/types/smd.types.js +292 -0
  161. package/dist/types/smd.types.js.map +1 -0
  162. package/dist/types/types.d.ts +187 -190
  163. package/dist/types/types.d.ts.map +1 -1
  164. package/dist/types/types.js +22 -30
  165. package/dist/types/types.js.map +1 -1
  166. package/dist/utils/model.d.ts +2 -2
  167. package/dist/utils/model.d.ts.map +1 -1
  168. package/dist/utils/utils.d.ts +1 -0
  169. package/dist/utils/utils.d.ts.map +1 -1
  170. package/dist/utils/utils.js +6 -2
  171. package/dist/utils/utils.js.map +1 -1
  172. package/package.json +11 -8
  173. package/src/api/code-converters.ts +9 -17
  174. package/src/api/sonamu.ts +10 -6
  175. package/src/bin/cli.ts +156 -27
  176. package/src/database/upsert-builder.ts +2 -2
  177. package/src/entity/entity-manager.ts +150 -0
  178. package/src/{smd/smd-utils.ts → entity/entity-utils.ts} +3 -3
  179. package/src/entity/entity.ts +774 -0
  180. package/src/{smd → entity}/migrator.ts +426 -106
  181. package/src/index.ts +3 -3
  182. package/src/smd/smd-manager.ts +3 -13
  183. package/src/smd/smd.ts +13 -10
  184. package/src/syncer/syncer.ts +125 -73
  185. package/src/templates/base-template.ts +2 -2
  186. package/src/templates/entity.template.ts +50 -0
  187. package/src/templates/generated.template.ts +93 -57
  188. package/src/templates/generated_http.template.ts +4 -4
  189. package/src/templates/init_types.template.ts +11 -11
  190. package/src/templates/model.template.ts +29 -29
  191. package/src/templates/model_test.template.ts +5 -5
  192. package/src/templates/service.template.ts +4 -4
  193. package/src/templates/view_enums_buttonset.template.ts +5 -5
  194. package/src/templates/view_enums_dropdown.template.ts +4 -4
  195. package/src/templates/view_enums_select.template.ts +8 -4
  196. package/src/templates/view_form.template.ts +21 -21
  197. package/src/templates/view_id_all_select.template.ts +5 -5
  198. package/src/templates/view_id_async_select.template.ts +9 -7
  199. package/src/templates/view_list.template.ts +54 -44
  200. package/src/templates/view_list_columns.template.ts +4 -4
  201. package/src/templates/view_search_input.template.ts +4 -4
  202. package/src/testing/fixture-manager.ts +12 -12
  203. package/src/types/types.ts +59 -39
  204. package/src/utils/utils.ts +4 -0
  205. package/tsconfig.json +4 -1
  206. package/src/templates/init_enums.template.ts +0 -71
  207. package/src/templates/init_generated.template.ts +0 -51
  208. package/src/templates/smd.template.ts +0 -53
package/src/index.ts CHANGED
@@ -7,9 +7,9 @@ export * from "./database/db";
7
7
  export * from "./database/upsert-builder";
8
8
  export * from "./exceptions/error-handler";
9
9
  export * from "./exceptions/so-exceptions";
10
- export * from "./smd/smd-manager";
11
- export * from "./smd/smd-utils";
12
- export * from "./smd/migrator";
10
+ export * from "./entity/entity-manager";
11
+ export * from "./entity/entity-utils";
12
+ export * from "./entity/migrator";
13
13
  export * from "./syncer/syncer";
14
14
  export * from "./testing/fixture-manager";
15
15
  export * from "./types/types";
@@ -6,18 +6,8 @@ import path from "path";
6
6
  import { SMD } from "./smd";
7
7
  import { SMDInput } from "../types/types";
8
8
  import { Sonamu } from "../api/sonamu";
9
+ import { EntityNamesRecord } from "../entity/entity-manager";
9
10
 
10
- export type SMDNamesRecord = Record<
11
- | "fs"
12
- | "fsPlural"
13
- | "camel"
14
- | "camelPlural"
15
- | "capital"
16
- | "capitalPlural"
17
- | "upper"
18
- | "constant",
19
- string
20
- >;
21
11
  type TableSpec = {
22
12
  name: string;
23
13
  uniqueColumns: string[];
@@ -124,8 +114,8 @@ class SMDManagerClass {
124
114
  return tableSpec;
125
115
  }
126
116
 
127
- getNamesFromId(smdId: string): SMDNamesRecord {
128
- // smdId가 단복수 동형 단어인 경우 List 붙여서 생성
117
+ getNamesFromId(smdId: string): EntityNamesRecord {
118
+ // entityId가 단복수 동형 단어인 경우 List 붙여서 생성
129
119
  const pluralized =
130
120
  pluralize(smdId) === smdId ? `${smdId}List` : pluralize(smdId);
131
121
 
package/src/smd/smd.ts CHANGED
@@ -1,10 +1,8 @@
1
1
  import _, { uniq } from "lodash";
2
- import { SMDManager } from "./smd-manager";
3
2
  import { dasherize, pluralize, underscore } from "inflection";
4
3
  import {
5
- SMDProp,
4
+ EntityProp,
6
5
  RelationProp,
7
- SMDInput,
8
6
  isRelationProp,
9
7
  SubsetQuery,
10
8
  isVirtualProp,
@@ -12,17 +10,19 @@ import {
12
10
  isOneToOneRelationProp,
13
11
  isHasManyRelationProp,
14
12
  isManyToManyRelationProp,
15
- SMDPropNode,
13
+ EntityPropNode,
16
14
  isEnumProp,
17
15
  StringProp,
18
- SMDIndex,
16
+ EntityIndex,
17
+ EnumsLabelKo,
18
+ SMDInput,
19
19
  } from "../types/types";
20
20
  import inflection from "inflection";
21
21
  import path from "path";
22
22
  import { existsSync } from "fs";
23
23
  import { z } from "zod";
24
- import { EnumsLabelKo } from "../types/types";
25
24
  import { Sonamu } from "../api/sonamu";
25
+ import { SMDManager } from "./smd-manager";
26
26
 
27
27
  export class SMD {
28
28
  id: string;
@@ -33,14 +33,14 @@ export class SMD {
33
33
  fs: string;
34
34
  module: string;
35
35
  };
36
- props: SMDProp[];
36
+ props: EntityProp[];
37
37
  propsDict: {
38
- [key: string]: SMDProp;
38
+ [key: string]: EntityProp;
39
39
  };
40
40
  relations: {
41
41
  [key: string]: RelationProp;
42
42
  };
43
- indexes: SMDIndex[];
43
+ indexes: EntityIndex[];
44
44
  subsets: {
45
45
  [key: string]: string[];
46
46
  };
@@ -355,7 +355,10 @@ export class SMD {
355
355
  /*
356
356
  FieldExpr[] 을 SMDPropNode[] 로 변환
357
357
  */
358
- fieldExprsToPropNodes(fieldExprs: string[], smd: SMD = this): SMDPropNode[] {
358
+ fieldExprsToPropNodes(
359
+ fieldExprs: string[],
360
+ smd: SMD = this
361
+ ): EntityPropNode[] {
359
362
  const groups = fieldExprs.reduce(
360
363
  (result, fieldExpr) => {
361
364
  let key, value, elseExpr;
@@ -13,7 +13,7 @@ import crypto from "crypto";
13
13
  import equal from "fast-deep-equal";
14
14
  import { differenceWith, groupBy, isEqual, uniq } from "lodash";
15
15
  import { camelize } from "inflection";
16
- import { SMDManager } from "../smd/smd-manager";
16
+ import { EntityManager } from "../entity/entity-manager";
17
17
  import * as ts from "typescript";
18
18
  import {
19
19
  ApiParam,
@@ -37,8 +37,8 @@ import {
37
37
  isTimestampProp,
38
38
  isUuidProp,
39
39
  isVirtualProp,
40
- SMDProp,
41
- SMDPropNode,
40
+ EntityProp,
41
+ EntityPropNode,
42
42
  SQLDateTimeString,
43
43
  } from "../types/types";
44
44
  import {
@@ -64,10 +64,8 @@ import { wrapIf } from "../utils/lodash-able";
64
64
  import { getTextTypeLength } from "../api/code-converters";
65
65
  import { Template } from "../templates/base-template";
66
66
  import { Template__generated } from "../templates/generated.template";
67
- import { Template__init_enums } from "../templates/init_enums.template";
68
- import { Template__init_generated } from "../templates/init_generated.template";
69
67
  import { Template__init_types } from "../templates/init_types.template";
70
- import { Template__smd } from "../templates/smd.template";
68
+ import { Template__entity } from "../templates/entity.template";
71
69
  import { Template__model } from "../templates/model.template";
72
70
  import { Template__model_test } from "../templates/model_test.template";
73
71
  import { Template__service } from "../templates/service.template";
@@ -83,8 +81,9 @@ import { Template__view_search_input } from "../templates/view_search_input.temp
83
81
  import { Template__view_list_columns } from "../templates/view_list_columns.template";
84
82
  import { Template__generated_http } from "../templates/generated_http.template";
85
83
  import { Sonamu } from "../api/sonamu";
84
+ import { execSync } from "child_process";
86
85
 
87
- type FileType = "model" | "types" | "enums" | "smd" | "generated";
86
+ type FileType = "model" | "types" | "functions" | "generated" | "entity";
88
87
  type GlobPattern = {
89
88
  [key in FileType]: string;
90
89
  };
@@ -182,33 +181,35 @@ export class Syncer {
182
181
 
183
182
  // 다른 부분 찾아 액션
184
183
  const diffGroups = groupBy(diffFiles, (r) => {
185
- const matched = r.match(/\.(model|types|enums|smd|generated)\.[tj]s/);
184
+ const matched = r.match(
185
+ /\.(model|types|functions|entity|generated)\.[tj]s/
186
+ );
186
187
  return matched![1];
187
188
  }) as unknown as DiffGroups;
188
189
 
189
190
  // 변경된 파일들을 타입별로 분리하여 각 타입별 액션 처리
190
191
  const diffTypes = Object.keys(diffGroups);
191
192
 
192
- // 트리거: smd
193
+ // 트리거: entity
193
194
  // 액션: 스키마 생성
194
- if (diffTypes.includes("smd")) {
195
+ if (diffTypes.includes("entity")) {
195
196
  console.log("// 액션: 스키마 생성");
196
- const smdIds = this.getSMDIdFromPath(diffGroups["smd"]);
197
- await this.actionGenerateSchemas(smdIds);
197
+ const entityIds = this.getEntityIdFromPath(diffGroups["entity"]);
198
+ await this.actionGenerateSchemas(entityIds);
198
199
  }
199
200
 
200
201
  // 트리거: types, enums, generated 변경시
201
202
  // 액션: 파일 싱크 types, enums, generated
202
203
  if (
203
204
  diffTypes.includes("types") ||
204
- diffTypes.includes("enums") ||
205
+ diffTypes.includes("functions") ||
205
206
  diffTypes.includes("generated")
206
207
  ) {
207
- console.log("// 액션: 파일 싱크 types / enums / generated");
208
+ console.log("// 액션: 파일 싱크 types / functions / generated");
208
209
 
209
210
  const tsPaths = [
210
211
  ...(diffGroups["types"] ?? []),
211
- ...(diffGroups["enums"] ?? []),
212
+ ...(diffGroups["functions"] ?? []),
212
213
  ...(diffGroups["generated"] ?? []),
213
214
  ].map((p) => p.replace("/dist/", "/src/").replace(".js", ".ts"));
214
215
  await this.actionSyncFilesToTargets(tsPaths);
@@ -216,32 +217,32 @@ export class Syncer {
216
217
 
217
218
  // 트리거: model
218
219
  if (diffTypes.includes("model")) {
219
- const smdIds = this.getSMDIdFromPath(diffGroups["model"]);
220
+ const entityIds = this.getEntityIdFromPath(diffGroups["model"]);
220
221
  console.log("// 액션: 서비스 생성");
221
- await this.actionGenerateServices(smdIds);
222
+ await this.actionGenerateServices(entityIds);
222
223
  console.log("// 액션: HTTP파일 생성");
223
- await this.actionGenerateHttps(smdIds);
224
+ await this.actionGenerateHttps(entityIds);
224
225
  }
225
226
 
226
227
  // 저장
227
228
  await this.saveChecksums(currentChecksums);
228
229
  }
229
230
 
230
- getSMDIdFromPath(filePaths: string[]): string[] {
231
+ getEntityIdFromPath(filePaths: string[]): string[] {
231
232
  return filePaths.map((p) => {
232
233
  const matched = p.match(/application\/(.+)\//);
233
234
  return camelize(matched![1].replace(/\-/g, "_"));
234
235
  });
235
236
  }
236
237
 
237
- async actionGenerateSchemas(smdIds: string[]): Promise<string[]> {
238
+ async actionGenerateSchemas(entityIds: string[]): Promise<string[]> {
238
239
  return (
239
240
  await Promise.all(
240
- smdIds.map(async (smdId) =>
241
+ entityIds.map(async (entityId) =>
241
242
  this.generateTemplate(
242
243
  "generated",
243
244
  {
244
- smdId,
245
+ entityId,
245
246
  },
246
247
  {
247
248
  overwrite: true,
@@ -254,14 +255,14 @@ export class Syncer {
254
255
  .flat();
255
256
  }
256
257
 
257
- async actionGenerateServices(smdIds: string[]): Promise<string[]> {
258
+ async actionGenerateServices(entityIds: string[]): Promise<string[]> {
258
259
  return (
259
260
  await Promise.all(
260
- smdIds.map(async (smdId) =>
261
+ entityIds.map(async (entityId) =>
261
262
  this.generateTemplate(
262
263
  "service",
263
264
  {
264
- smdId,
265
+ entityId,
265
266
  },
266
267
  {
267
268
  overwrite: true,
@@ -274,14 +275,14 @@ export class Syncer {
274
275
  .flat();
275
276
  }
276
277
 
277
- async actionGenerateHttps(smdIds: string[]): Promise<string[]> {
278
+ async actionGenerateHttps(entityIds: string[]): Promise<string[]> {
278
279
  return (
279
280
  await Promise.all(
280
- smdIds.map(async (smdId) =>
281
+ entityIds.map(async (entityId) =>
281
282
  this.generateTemplate(
282
283
  "generated_http",
283
284
  {
284
- smdId,
285
+ entityId,
285
286
  },
286
287
  {
287
288
  overwrite: true,
@@ -342,13 +343,13 @@ export class Syncer {
342
343
 
343
344
  async getCurrentChecksums(): Promise<PathAndChecksum[]> {
344
345
  const PatternGroup: GlobPattern = {
345
- /* TS 체크 */
346
+ /* 원본 체크 */
347
+ entity: Sonamu.apiRootPath + "/src/application/**/*.entity.json",
346
348
  types: Sonamu.apiRootPath + "/src/application/**/*.types.ts",
347
- enums: Sonamu.apiRootPath + "/src/application/**/*.enums.ts",
348
349
  generated: Sonamu.apiRootPath + "/src/application/**/*.generated.ts",
350
+ functions: Sonamu.apiRootPath + "/src/application/**/*.functions.ts",
349
351
  /* compiled-JS 체크 */
350
352
  model: Sonamu.apiRootPath + "/dist/application/**/*.model.js",
351
- smd: Sonamu.apiRootPath + "/dist/application/**/*.smd.js",
352
353
  };
353
354
 
354
355
  const filePaths = (
@@ -708,7 +709,6 @@ export class Syncer {
708
709
 
709
710
  const pathPatterns = [
710
711
  path.join(Sonamu.apiRootPath, "/dist/application/**/*.types.js"),
711
- path.join(Sonamu.apiRootPath, "/dist/application/**/*.enums.js"),
712
712
  path.join(Sonamu.apiRootPath, "/dist/application/**/*.generated.js"),
713
713
  ];
714
714
  // console.debug(chalk.magenta(`autoload:types @ ${pathPatterns.join("\n")}`));
@@ -727,14 +727,10 @@ export class Syncer {
727
727
  }
728
728
 
729
729
  getTemplate(key: TemplateKey): Template {
730
- if (key === "smd") {
731
- return new Template__smd();
732
- } else if (key === "init_enums") {
733
- return new Template__init_enums();
730
+ if (key === "entity") {
731
+ return new Template__entity();
734
732
  } else if (key === "init_types") {
735
733
  return new Template__init_types();
736
- } else if (key === "init_generated") {
737
- return new Template__init_generated();
738
734
  } else if (key === "generated") {
739
735
  return new Template__generated();
740
736
  } else if (key === "generated_http") {
@@ -777,24 +773,24 @@ export class Syncer {
777
773
  let extra: unknown[] = [];
778
774
  if (key === "service" || key === "generated_http") {
779
775
  // service 필요 정보 (API 리스트)
780
- const smd = SMDManager.get(options.smdId);
776
+ const entity = EntityManager.get(options.entityId);
781
777
  const modelTsPath = `${path.join(
782
778
  Sonamu.apiRootPath,
783
779
  "/src/application"
784
- )}/${smd.names.fs}/${smd.names.fs}.model.ts`;
780
+ )}/${entity.names.fs}/${entity.names.fs}.model.ts`;
785
781
  extra = [await this.readApisFromFile(modelTsPath)];
786
782
  } else if (key === "view_list" || key === "model") {
787
783
  // view_list 필요 정보 (컬럼 노드, 리스트파라미터 노드)
788
- const columnsNode = await this.getColumnsNode(options.smdId, "A");
784
+ const columnsNode = await this.getColumnsNode(options.entityId, "A");
789
785
  const listParamsZodType = await this.getZodTypeById(
790
- `${options.smdId}ListParams`
786
+ `${options.entityId}ListParams`
791
787
  );
792
788
  const listParamsNode = this.zodTypeToRenderingNode(listParamsZodType);
793
789
  extra = [columnsNode, listParamsNode];
794
790
  } else if (key === "view_form") {
795
791
  // view_form 필요 정보 (세이브파라미터 노드)
796
792
  const saveParamsZodType = await this.getZodTypeById(
797
- `${options.smdId}SaveParams`
793
+ `${options.entityId}SaveParams`
798
794
  );
799
795
  const saveParamsNode = this.zodTypeToRenderingNode(saveParamsZodType);
800
796
  extra = [saveParamsNode];
@@ -827,7 +823,7 @@ export class Syncer {
827
823
  const importDefs = importKeys
828
824
  .reduce(
829
825
  (r, importKey) => {
830
- const modulePath = SMDManager.getModulePath(importKey);
826
+ const modulePath = EntityManager.getModulePath(importKey);
831
827
  let importPath = modulePath;
832
828
  if (modulePath.includes("/")) {
833
829
  importPath = wrapIf(
@@ -870,12 +866,15 @@ export class Syncer {
870
866
  ),
871
867
  ].join("\n");
872
868
 
873
- const formatted =
874
- key === "generated_http"
875
- ? [header, body].join("\n\n")
876
- : await prettier.format([header, body].join("\n\n"), {
877
- parser: "typescript",
878
- });
869
+ const formatted = await (async () => {
870
+ if (key === "generated_http") {
871
+ return [header, body].join("\n\n");
872
+ } else {
873
+ return await prettier.format([header, body].join("\n\n"), {
874
+ parser: key === "entity" ? "json" : "typescript",
875
+ });
876
+ }
877
+ })();
879
878
 
880
879
  return {
881
880
  path: target + "/" + filePath,
@@ -919,9 +918,9 @@ export class Syncer {
919
918
 
920
919
  // 키 children
921
920
  let keys: TemplateKey[] = [key];
922
- if (key === "smd") {
923
- keys = ["smd", "init_enums", "init_generated", "init_types"];
924
- }
921
+ // if (key === "entity") {
922
+ // keys = ["entity", "init_generated", "init_types"];
923
+ // }
925
924
 
926
925
  // 템플릿 렌더
927
926
  const pathAndCodes = (
@@ -972,13 +971,13 @@ export class Syncer {
972
971
  }
973
972
 
974
973
  checkExists(
975
- smdId: string,
974
+ entityId: string,
976
975
  enums: {
977
976
  [name: string]: z.ZodEnum<any>;
978
977
  }
979
978
  ): Record<`${TemplateKey}${string}`, boolean> {
980
979
  const keys: TemplateKey[] = TemplateKey.options;
981
- const names = SMDManager.getNamesFromId(smdId);
980
+ const names = EntityManager.getNamesFromId(entityId);
982
981
  const enumsKeys = Object.keys(enums).filter(
983
982
  (name) => name !== names.constant
984
983
  );
@@ -1012,7 +1011,7 @@ export class Syncer {
1012
1011
  }
1013
1012
 
1014
1013
  async getZodTypeById(zodTypeId: string): Promise<z.ZodTypeAny> {
1015
- const modulePath = SMDManager.getModulePath(zodTypeId);
1014
+ const modulePath = EntityManager.getModulePath(zodTypeId);
1016
1015
  const moduleAbsPath = path.join(
1017
1016
  Sonamu.apiRootPath,
1018
1017
  "dist",
@@ -1028,7 +1027,7 @@ export class Syncer {
1028
1027
  return imported[zodTypeId].describe(zodTypeId);
1029
1028
  }
1030
1029
 
1031
- async propNodeToZodType(propNode: SMDPropNode): Promise<z.ZodTypeAny> {
1030
+ async propNodeToZodType(propNode: EntityPropNode): Promise<z.ZodTypeAny> {
1032
1031
  if (propNode.nodeType === "plain") {
1033
1032
  return this.propToZodType(propNode.prop);
1034
1033
  } else if (propNode.nodeType === "array") {
@@ -1070,7 +1069,7 @@ export class Syncer {
1070
1069
  throw Error;
1071
1070
  }
1072
1071
  }
1073
- async propToZodType(prop: SMDProp): Promise<z.ZodTypeAny> {
1072
+ async propToZodType(prop: EntityProp): Promise<z.ZodTypeAny> {
1074
1073
  let zodType: z.ZodTypeAny = z.unknown();
1075
1074
  if (isIntegerProp(prop)) {
1076
1075
  zodType = z.number().int();
@@ -1097,19 +1096,11 @@ export class Syncer {
1097
1096
  } else if (isTimestampProp(prop)) {
1098
1097
  zodType = SQLDateTimeString;
1099
1098
  } else if (isJsonProp(prop)) {
1100
- if (prop.as instanceof z.ZodType) {
1101
- zodType = prop.as;
1102
- } else {
1103
- zodType = await this.getZodTypeById(prop.as.ref);
1104
- }
1099
+ zodType = await this.getZodTypeById(prop.id);
1105
1100
  } else if (isUuidProp(prop)) {
1106
1101
  zodType = z.string().uuid();
1107
1102
  } else if (isVirtualProp(prop)) {
1108
- if (prop.as instanceof z.ZodType) {
1109
- zodType = prop.as;
1110
- } else {
1111
- zodType = await this.getZodTypeById(prop.as.ref);
1112
- }
1103
+ zodType = await this.getZodTypeById(prop.id);
1113
1104
  } else if (isRelationProp(prop)) {
1114
1105
  if (
1115
1106
  isBelongsToOneRelationProp(prop) ||
@@ -1226,14 +1217,14 @@ export class Syncer {
1226
1217
  }
1227
1218
  }
1228
1219
 
1229
- async getColumnsNode(smdId: string, subsetKey: string) {
1230
- const smd = await SMDManager.get(smdId);
1231
- const subsetA = smd.subsets[subsetKey];
1220
+ async getColumnsNode(entityId: string, subsetKey: string) {
1221
+ const entity = await EntityManager.get(entityId);
1222
+ const subsetA = entity.subsets[subsetKey];
1232
1223
  if (subsetA === undefined) {
1233
1224
  throw new ServiceUnavailableException("SubsetA 가 없습니다.");
1234
1225
  }
1235
- const propNodes = smd.fieldExprsToPropNodes(subsetA);
1236
- const rootPropNode: SMDPropNode = {
1226
+ const propNodes = entity.fieldExprsToPropNodes(subsetA);
1227
+ const rootPropNode: EntityPropNode = {
1237
1228
  nodeType: "object",
1238
1229
  children: propNodes,
1239
1230
  };
@@ -1287,4 +1278,65 @@ export class Syncer {
1287
1278
 
1288
1279
  return columnsNode;
1289
1280
  }
1281
+
1282
+ async createEntity(
1283
+ entityId: string,
1284
+ parentId?: string,
1285
+ table?: string,
1286
+ title?: string
1287
+ ) {
1288
+ await this.generateTemplate("entity", {
1289
+ entityId,
1290
+ parentId,
1291
+ table,
1292
+ title,
1293
+ });
1294
+
1295
+ // reload entities
1296
+ await EntityManager.reload();
1297
+
1298
+ // generate schemas
1299
+ await this.actionGenerateSchemas([entityId]);
1300
+
1301
+ // generate types
1302
+ await this.generateTemplate("init_types", {
1303
+ entityId,
1304
+ });
1305
+ }
1306
+
1307
+ async delEntity(entityId: string): Promise<{ delPaths: string[] }> {
1308
+ const entity = EntityManager.get(entityId);
1309
+
1310
+ const delPaths = (() => {
1311
+ if (entity.parentId) {
1312
+ return [
1313
+ `${Sonamu.apiRootPath}/src/application/${entity.names.parentFs}/${entity.names.fs}.entity.json`,
1314
+ ];
1315
+ } else {
1316
+ return [
1317
+ `${Sonamu.apiRootPath}/src/application/${entity.names.fs}`,
1318
+ `${Sonamu.apiRootPath}/dist/application/${entity.names.fs}`,
1319
+ ...Sonamu.config.sync.targets
1320
+ .map((target) => [
1321
+ `${Sonamu.appRootPath}/${target}/src/services/${entity.names.fs}`,
1322
+ ])
1323
+ .flat(),
1324
+ ];
1325
+ }
1326
+ })(); // iife
1327
+
1328
+ for await (const delPath of delPaths) {
1329
+ if (existsSync(delPath)) {
1330
+ console.log(chalk.red(`DELETE ${delPath}`));
1331
+ execSync(`rm -rf ${delPath}`);
1332
+ } else {
1333
+ console.log(chalk.yellow(`NOT_EXISTS ${delPath}`));
1334
+ }
1335
+ }
1336
+
1337
+ // reload entities
1338
+ await EntityManager.reload();
1339
+
1340
+ return { delPaths };
1341
+ }
1290
1342
  }
@@ -1,5 +1,5 @@
1
1
  import { TemplateKey, TemplateOptions } from "../types/types";
2
- import { SMDNamesRecord } from "../smd/smd-manager";
2
+ import { EntityNamesRecord } from "../entity/entity-manager";
3
3
  import { RenderedTemplate } from "../syncer/syncer";
4
4
 
5
5
  export abstract class Template {
@@ -10,7 +10,7 @@ export abstract class Template {
10
10
  ): RenderedTemplate;
11
11
 
12
12
  public abstract getTargetAndPath(
13
- names: SMDNamesRecord,
13
+ names: EntityNamesRecord,
14
14
  ...extra: unknown[]
15
15
  ): {
16
16
  target: string;
@@ -0,0 +1,50 @@
1
+ import { TemplateOptions } from "../types/types";
2
+ import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
3
+ import { Template } from "./base-template";
4
+
5
+ export class Template__entity extends Template {
6
+ constructor() {
7
+ super("entity");
8
+ }
9
+
10
+ getTargetAndPath(names: EntityNamesRecord) {
11
+ return {
12
+ target: "api/src/application",
13
+ path: `${names.fs}/${names.fs}.entity.json`,
14
+ };
15
+ }
16
+
17
+ render(options: TemplateOptions["entity"]) {
18
+ const { entityId, title, parentId, table } = options;
19
+ const names = EntityManager.getNamesFromId(entityId);
20
+
21
+ return {
22
+ ...this.getTargetAndPath(names),
23
+ body: JSON.stringify({
24
+ id: entityId,
25
+ title: title ?? entityId,
26
+ parentId,
27
+ table: table ?? names.fsPlural.replace(/\-/g, "_"),
28
+ props: [
29
+ { name: "id", type: "integer", unsigned: true },
30
+ {
31
+ name: "created_at",
32
+ type: "timestamp",
33
+ dbDefault: "CURRENT_TIMESTAMP",
34
+ },
35
+ ],
36
+ indexes: [],
37
+ subsets: {
38
+ A: ["id", "created_at"],
39
+ },
40
+ enums: {
41
+ [`${names.capital}OrderBy`]: {
42
+ "id-desc": "ID최신순",
43
+ },
44
+ [`${names.capital}SearchField`]: { id: "ID" },
45
+ },
46
+ }).trim(),
47
+ importKeys: [],
48
+ };
49
+ }
50
+ }