sonamu 0.0.1 → 0.0.3

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 (257) hide show
  1. package/dist/api/caster.d.ts +12 -0
  2. package/dist/api/caster.d.ts.map +1 -0
  3. package/dist/api/caster.js +72 -0
  4. package/dist/api/caster.js.map +1 -0
  5. package/dist/api/code-converters.d.ts +21 -0
  6. package/dist/api/code-converters.d.ts.map +1 -0
  7. package/dist/api/code-converters.js +446 -0
  8. package/dist/api/code-converters.js.map +1 -0
  9. package/dist/api/context.d.ts +11 -0
  10. package/dist/api/context.d.ts.map +1 -0
  11. package/dist/api/context.js +3 -0
  12. package/dist/api/context.js.map +1 -0
  13. package/dist/api/decorators.d.ts +27 -0
  14. package/dist/api/decorators.d.ts.map +1 -0
  15. package/dist/api/decorators.js +23 -0
  16. package/dist/api/decorators.js.map +1 -0
  17. package/dist/api/index.d.ts +6 -0
  18. package/dist/api/index.d.ts.map +1 -0
  19. package/dist/api/index.js +22 -0
  20. package/dist/api/index.js.map +1 -0
  21. package/dist/api/init.d.ts +13 -0
  22. package/dist/api/init.d.ts.map +1 -0
  23. package/dist/api/init.js +110 -0
  24. package/dist/api/init.js.map +1 -0
  25. package/dist/database/base-model.d.ts +36 -0
  26. package/dist/database/base-model.d.ts.map +1 -0
  27. package/dist/database/base-model.js +222 -0
  28. package/dist/database/base-model.js.map +1 -0
  29. package/dist/database/db.d.ts +23 -0
  30. package/dist/database/db.d.ts.map +1 -0
  31. package/dist/database/db.js +109 -0
  32. package/dist/database/db.js.map +1 -0
  33. package/dist/database/f9-base-model.d.ts +39 -0
  34. package/dist/database/f9-base-model.d.ts.map +1 -0
  35. package/dist/database/f9-base-model.js +229 -0
  36. package/dist/database/f9-base-model.js.map +1 -0
  37. package/dist/database/f9-db.d.ts +23 -0
  38. package/dist/database/f9-db.d.ts.map +1 -0
  39. package/dist/database/f9-db.js +109 -0
  40. package/dist/database/f9-db.js.map +1 -0
  41. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +2 -0
  42. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +1 -0
  43. package/dist/database/knex-plugins/knex-on-duplicate-update.js +37 -0
  44. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +1 -0
  45. package/dist/database/upsert-builder.d.ts +29 -0
  46. package/dist/database/upsert-builder.d.ts.map +1 -0
  47. package/dist/database/upsert-builder.js +230 -0
  48. package/dist/database/upsert-builder.js.map +1 -0
  49. package/dist/exceptions/error-handler.d.ts +3 -0
  50. package/dist/exceptions/error-handler.d.ts.map +1 -0
  51. package/dist/exceptions/error-handler.js +32 -0
  52. package/dist/exceptions/error-handler.js.map +1 -0
  53. package/dist/exceptions/exceptions.d.ts +48 -0
  54. package/dist/exceptions/exceptions.d.ts.map +1 -0
  55. package/dist/exceptions/exceptions.js +105 -0
  56. package/dist/exceptions/exceptions.js.map +1 -0
  57. package/dist/exceptions/f9-exception.d.ts +48 -0
  58. package/dist/exceptions/f9-exception.d.ts.map +1 -0
  59. package/dist/exceptions/f9-exception.js +105 -0
  60. package/dist/exceptions/f9-exception.js.map +1 -0
  61. package/dist/exceptions/index.d.ts +3 -0
  62. package/dist/exceptions/index.d.ts.map +1 -0
  63. package/dist/exceptions/index.js +19 -0
  64. package/dist/exceptions/index.js.map +1 -0
  65. package/dist/exceptions/so-exceptions.d.ts +48 -0
  66. package/dist/exceptions/so-exceptions.d.ts.map +1 -0
  67. package/dist/exceptions/so-exceptions.js +105 -0
  68. package/dist/exceptions/so-exceptions.js.map +1 -0
  69. package/dist/f9-md/f9-md.d.ts +29 -0
  70. package/dist/f9-md/f9-md.d.ts.map +1 -0
  71. package/dist/f9-md/f9-md.js +148 -0
  72. package/dist/f9-md/f9-md.js.map +1 -0
  73. package/dist/f9-md/index.d.ts +5 -0
  74. package/dist/f9-md/index.d.ts.map +1 -0
  75. package/dist/f9-md/index.js +21 -0
  76. package/dist/f9-md/index.js.map +1 -0
  77. package/dist/f9-md/md-utils.d.ts +55 -0
  78. package/dist/f9-md/md-utils.d.ts.map +1 -0
  79. package/dist/f9-md/md-utils.js +104 -0
  80. package/dist/f9-md/md-utils.js.map +1 -0
  81. package/dist/f9-md/migrator.d.ts +79 -0
  82. package/dist/f9-md/migrator.d.ts.map +1 -0
  83. package/dist/f9-md/migrator.js +1084 -0
  84. package/dist/f9-md/migrator.js.map +1 -0
  85. package/dist/f9-md/model-definition.d.ts +40 -0
  86. package/dist/f9-md/model-definition.d.ts.map +1 -0
  87. package/dist/f9-md/model-definition.js +409 -0
  88. package/dist/f9-md/model-definition.js.map +1 -0
  89. package/dist/index.d.ts +18 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/smd/migrator.d.ts +79 -0
  93. package/dist/smd/migrator.d.ts.map +1 -0
  94. package/dist/smd/migrator.js +1084 -0
  95. package/dist/smd/migrator.js.map +1 -0
  96. package/dist/smd/smd-manager.d.ts +28 -0
  97. package/dist/smd/smd-manager.d.ts.map +1 -0
  98. package/dist/smd/smd-manager.js +140 -0
  99. package/dist/smd/smd-manager.js.map +1 -0
  100. package/dist/smd/smd-utils.d.ts +55 -0
  101. package/dist/smd/smd-utils.d.ts.map +1 -0
  102. package/dist/smd/smd-utils.js +104 -0
  103. package/dist/smd/smd-utils.js.map +1 -0
  104. package/dist/smd/smd.d.ts +40 -0
  105. package/dist/smd/smd.d.ts.map +1 -0
  106. package/dist/smd/smd.js +409 -0
  107. package/dist/smd/smd.js.map +1 -0
  108. package/dist/syncer/index.d.ts +2 -0
  109. package/dist/syncer/index.d.ts.map +1 -0
  110. package/dist/syncer/index.js +18 -0
  111. package/dist/syncer/index.js.map +1 -0
  112. package/dist/syncer/syncer.d.ts +103 -0
  113. package/dist/syncer/syncer.d.ts.map +1 -0
  114. package/dist/syncer/syncer.js +1001 -0
  115. package/dist/syncer/syncer.js.map +1 -0
  116. package/dist/templates/base-template.d.ts +13 -0
  117. package/dist/templates/base-template.d.ts.map +1 -0
  118. package/dist/templates/base-template.js +10 -0
  119. package/dist/templates/base-template.js.map +1 -0
  120. package/dist/templates/bridge.template.d.ts +17 -0
  121. package/dist/templates/bridge.template.d.ts.map +1 -0
  122. package/dist/templates/bridge.template.js +79 -0
  123. package/dist/templates/bridge.template.js.map +1 -0
  124. package/dist/templates/generated.template.d.ts +31 -0
  125. package/dist/templates/generated.template.d.ts.map +1 -0
  126. package/dist/templates/generated.template.js +180 -0
  127. package/dist/templates/generated.template.js.map +1 -0
  128. package/dist/templates/generated_http.template.d.ts +25 -0
  129. package/dist/templates/generated_http.template.d.ts.map +1 -0
  130. package/dist/templates/generated_http.template.js +114 -0
  131. package/dist/templates/generated_http.template.js.map +1 -0
  132. package/dist/templates/index.d.ts +2 -0
  133. package/dist/templates/index.d.ts.map +1 -0
  134. package/dist/templates/index.js +18 -0
  135. package/dist/templates/index.js.map +1 -0
  136. package/dist/templates/init_enums.template.d.ts +17 -0
  137. package/dist/templates/init_enums.template.d.ts.map +1 -0
  138. package/dist/templates/init_enums.template.js +54 -0
  139. package/dist/templates/init_enums.template.js.map +1 -0
  140. package/dist/templates/init_generated.template.d.ts +17 -0
  141. package/dist/templates/init_generated.template.d.ts.map +1 -0
  142. package/dist/templates/init_generated.template.js +40 -0
  143. package/dist/templates/init_generated.template.js.map +1 -0
  144. package/dist/templates/init_types.template.d.ts +17 -0
  145. package/dist/templates/init_types.template.d.ts.map +1 -0
  146. package/dist/templates/init_types.template.js +34 -0
  147. package/dist/templates/init_types.template.js.map +1 -0
  148. package/dist/templates/md.template.d.ts +17 -0
  149. package/dist/templates/md.template.d.ts.map +1 -0
  150. package/dist/templates/md.template.js +45 -0
  151. package/dist/templates/md.template.js.map +1 -0
  152. package/dist/templates/model.template.d.ts +17 -0
  153. package/dist/templates/model.template.d.ts.map +1 -0
  154. package/dist/templates/model.template.js +159 -0
  155. package/dist/templates/model.template.js.map +1 -0
  156. package/dist/templates/model_test.template.d.ts +17 -0
  157. package/dist/templates/model_test.template.d.ts.map +1 -0
  158. package/dist/templates/model_test.template.js +35 -0
  159. package/dist/templates/model_test.template.js.map +1 -0
  160. package/dist/templates/service.template.d.ts +28 -0
  161. package/dist/templates/service.template.d.ts.map +1 -0
  162. package/dist/templates/service.template.js +162 -0
  163. package/dist/templates/service.template.js.map +1 -0
  164. package/dist/templates/smd.template.d.ts +17 -0
  165. package/dist/templates/smd.template.d.ts.map +1 -0
  166. package/dist/templates/smd.template.js +45 -0
  167. package/dist/templates/smd.template.js.map +1 -0
  168. package/dist/templates/view_enums_buttonset.template.d.ts +17 -0
  169. package/dist/templates/view_enums_buttonset.template.d.ts.map +1 -0
  170. package/dist/templates/view_enums_buttonset.template.js +30 -0
  171. package/dist/templates/view_enums_buttonset.template.js.map +1 -0
  172. package/dist/templates/view_enums_dropdown.template.d.ts +18 -0
  173. package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -0
  174. package/dist/templates/view_enums_dropdown.template.js +59 -0
  175. package/dist/templates/view_enums_dropdown.template.js.map +1 -0
  176. package/dist/templates/view_enums_select.template.d.ts +17 -0
  177. package/dist/templates/view_enums_select.template.d.ts.map +1 -0
  178. package/dist/templates/view_enums_select.template.js +56 -0
  179. package/dist/templates/view_enums_select.template.js.map +1 -0
  180. package/dist/templates/view_form.template.d.ts +83 -0
  181. package/dist/templates/view_form.template.d.ts.map +1 -0
  182. package/dist/templates/view_form.template.js +332 -0
  183. package/dist/templates/view_form.template.js.map +1 -0
  184. package/dist/templates/view_id_all_select.template.d.ts +17 -0
  185. package/dist/templates/view_id_all_select.template.d.ts.map +1 -0
  186. package/dist/templates/view_id_all_select.template.js +30 -0
  187. package/dist/templates/view_id_all_select.template.js.map +1 -0
  188. package/dist/templates/view_id_async_select.template.d.ts +17 -0
  189. package/dist/templates/view_id_async_select.template.d.ts.map +1 -0
  190. package/dist/templates/view_id_async_select.template.js +96 -0
  191. package/dist/templates/view_id_async_select.template.js.map +1 -0
  192. package/dist/templates/view_list.template.d.ts +96 -0
  193. package/dist/templates/view_list.template.d.ts.map +1 -0
  194. package/dist/templates/view_list.template.js +552 -0
  195. package/dist/templates/view_list.template.js.map +1 -0
  196. package/dist/templates/view_list_columns.template.d.ts +17 -0
  197. package/dist/templates/view_list_columns.template.d.ts.map +1 -0
  198. package/dist/templates/view_list_columns.template.js +47 -0
  199. package/dist/templates/view_list_columns.template.js.map +1 -0
  200. package/dist/templates/view_search_input.template.d.ts +17 -0
  201. package/dist/templates/view_search_input.template.d.ts.map +1 -0
  202. package/dist/templates/view_search_input.template.js +63 -0
  203. package/dist/templates/view_search_input.template.js.map +1 -0
  204. package/dist/testing/f9-fixture-manager.d.ts +16 -0
  205. package/dist/testing/f9-fixture-manager.d.ts.map +1 -0
  206. package/dist/testing/f9-fixture-manager.js +211 -0
  207. package/dist/testing/f9-fixture-manager.js.map +1 -0
  208. package/dist/testing/fixture-manager.d.ts +16 -0
  209. package/dist/testing/fixture-manager.d.ts.map +1 -0
  210. package/dist/testing/fixture-manager.js +212 -0
  211. package/dist/testing/fixture-manager.js.map +1 -0
  212. package/dist/types/index.d.ts +2 -0
  213. package/dist/types/index.d.ts.map +1 -0
  214. package/dist/types/index.js +18 -0
  215. package/dist/types/index.js.map +1 -0
  216. package/dist/types/shared.d.ts +725 -0
  217. package/dist/types/shared.d.ts.map +1 -0
  218. package/dist/types/shared.js +288 -0
  219. package/dist/types/shared.js.map +1 -0
  220. package/dist/types/types.d.ts +725 -0
  221. package/dist/types/types.d.ts.map +1 -0
  222. package/dist/types/types.js +288 -0
  223. package/dist/types/types.js.map +1 -0
  224. package/dist/utils/controller.d.ts +8 -0
  225. package/dist/utils/controller.d.ts.map +1 -0
  226. package/dist/utils/controller.js +32 -0
  227. package/dist/utils/controller.js.map +1 -0
  228. package/dist/utils/f9-cache.d.ts +1 -0
  229. package/dist/utils/f9-cache.d.ts.map +1 -0
  230. package/dist/utils/f9-cache.js +113 -0
  231. package/dist/utils/f9-cache.js.map +1 -0
  232. package/dist/utils/index.d.ts +4 -0
  233. package/dist/utils/index.d.ts.map +1 -0
  234. package/dist/utils/index.js +20 -0
  235. package/dist/utils/index.js.map +1 -0
  236. package/dist/utils/lodash-able.d.ts +3 -0
  237. package/dist/utils/lodash-able.d.ts.map +1 -0
  238. package/dist/utils/lodash-able.js +13 -0
  239. package/dist/utils/lodash-able.js.map +1 -0
  240. package/dist/utils/model.d.ts +17 -0
  241. package/dist/utils/model.d.ts.map +1 -0
  242. package/dist/utils/model.js +26 -0
  243. package/dist/utils/model.js.map +1 -0
  244. package/dist/utils/tf-utils.d.ts +6 -0
  245. package/dist/utils/tf-utils.d.ts.map +1 -0
  246. package/dist/utils/tf-utils.js +67 -0
  247. package/dist/utils/tf-utils.js.map +1 -0
  248. package/dist/utils/utils.d.ts +6 -0
  249. package/dist/utils/utils.d.ts.map +1 -0
  250. package/dist/utils/utils.js +67 -0
  251. package/dist/utils/utils.js.map +1 -0
  252. package/package.json +4 -2
  253. package/src/syncer/syncer.ts +1 -1
  254. package/src/templates/generated.template.ts +2 -2
  255. package/src/templates/model.template.ts +1 -1
  256. package/src/templates/model_test.template.ts +1 -1
  257. package/src/templates/smd.template.ts +1 -1
@@ -0,0 +1,1001 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.Syncer = void 0;
39
+ const path_1 = __importStar(require("path"));
40
+ const utils_1 = require("../utils/utils");
41
+ const fs_extra_1 = __importStar(require("fs-extra"));
42
+ const crypto_1 = __importDefault(require("crypto"));
43
+ const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
44
+ const lodash_1 = require("lodash");
45
+ const inflection_1 = require("inflection");
46
+ const smd_manager_1 = require("../smd/smd-manager");
47
+ const ts = __importStar(require("typescript"));
48
+ const types_1 = require("../types/types");
49
+ const decorators_1 = require("../api/decorators");
50
+ const zod_1 = require("zod");
51
+ const chalk_1 = __importDefault(require("chalk"));
52
+ const types_2 = require("../types/types");
53
+ const so_exceptions_1 = require("../exceptions/so-exceptions");
54
+ const lodash_able_1 = require("../utils/lodash-able");
55
+ const code_converters_1 = require("../api/code-converters");
56
+ const generated_template_1 = require("../templates/generated.template");
57
+ const init_enums_template_1 = require("../templates/init_enums.template");
58
+ const init_generated_template_1 = require("../templates/init_generated.template");
59
+ const init_types_template_1 = require("../templates/init_types.template");
60
+ const smd_template_1 = require("../templates/smd.template");
61
+ const model_template_1 = require("../templates/model.template");
62
+ const model_test_template_1 = require("../templates/model_test.template");
63
+ const service_template_1 = require("../templates/service.template");
64
+ const view_form_template_1 = require("../templates/view_form.template");
65
+ const view_list_template_1 = require("../templates/view_list.template");
66
+ const prettier_1 = __importDefault(require("prettier"));
67
+ const view_id_all_select_template_1 = require("../templates/view_id_all_select.template");
68
+ const view_id_async_select_template_1 = require("../templates/view_id_async_select.template");
69
+ const view_enums_dropdown_template_1 = require("../templates/view_enums_dropdown.template");
70
+ const view_enums_select_template_1 = require("../templates/view_enums_select.template");
71
+ const view_enums_buttonset_template_1 = require("../templates/view_enums_buttonset.template");
72
+ const view_search_input_template_1 = require("../templates/view_search_input.template");
73
+ const view_list_columns_template_1 = require("../templates/view_list_columns.template");
74
+ const generated_http_template_1 = require("../templates/generated_http.template");
75
+ class Syncer {
76
+ constructor(config) {
77
+ var _a;
78
+ this.apis = [];
79
+ this.types = {};
80
+ this.resolveParamDec = (paramDec, index = 0) => {
81
+ const name = paramDec.name;
82
+ const type = this.resolveTypeNode(paramDec.type);
83
+ if (name === undefined) {
84
+ console.log({ name, type, paramDec });
85
+ }
86
+ return {
87
+ name: name.escapedText ? name.escapedText.toString() : `nonameAt${index}`,
88
+ type,
89
+ optional: paramDec.optional === true,
90
+ defaultDef: paramDec === null || paramDec === void 0 ? void 0 : paramDec.defaultDef,
91
+ };
92
+ };
93
+ const appRootPath = (_a = config === null || config === void 0 ? void 0 : config.appRootPath) !== null && _a !== void 0 ? _a : path_1.default.resolve(__dirname, "../../");
94
+ this.config = Object.assign({ appRootPath, checksumsPath: `${appRootPath}/api/.tf-checksum`, targets: ["web"] }, config);
95
+ }
96
+ static getInstance(config) {
97
+ var _a;
98
+ if (this.instance && config !== undefined) {
99
+ throw new Error("Syncer has already configured.");
100
+ }
101
+ return (_a = this.instance) !== null && _a !== void 0 ? _a : (this.instance = new this(config));
102
+ }
103
+ sync() {
104
+ var _a, _b, _c;
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ // 트리거와 무관하게 shared 분배
107
+ yield Promise.all(this.config.targets.map((target) => __awaiter(this, void 0, void 0, function* () {
108
+ const srcCodePath = path_1.default
109
+ .join(__dirname, `../shared/${target}.shared.ts.txt`)
110
+ .replace("/dist/", "/src/");
111
+ if (!(0, fs_extra_1.existsSync)(srcCodePath)) {
112
+ return;
113
+ }
114
+ const dstCodePath = path_1.default.join(this.config.appRootPath, target, "src/services/sonamu.shared.ts");
115
+ const srcChecksum = yield this.getChecksumOfFile(srcCodePath);
116
+ const dstChecksum = yield (() => __awaiter(this, void 0, void 0, function* () {
117
+ if ((0, fs_extra_1.existsSync)(dstCodePath) === false) {
118
+ return "";
119
+ }
120
+ return this.getChecksumOfFile(dstCodePath);
121
+ }))();
122
+ if (srcChecksum === dstChecksum) {
123
+ return;
124
+ }
125
+ (0, fs_extra_1.writeFileSync)(dstCodePath, (0, fs_extra_1.readFileSync)(srcCodePath));
126
+ })));
127
+ // 현재 checksums
128
+ const currentChecksums = yield this.getCurrentChecksums();
129
+ // 이전 checksums
130
+ const previousChecksums = yield this.getPreviousChecksums();
131
+ // 비교
132
+ const isSame = (0, fast_deep_equal_1.default)(currentChecksums, previousChecksums);
133
+ if (isSame) {
134
+ const msg = "Every files are synced!";
135
+ const margin = (process.stdout.columns - msg.length) / 2;
136
+ console.log(chalk_1.default.black.bgGreen(" ".repeat(margin) + msg + " ".repeat(margin)));
137
+ return;
138
+ }
139
+ // 변경된 파일 찾기
140
+ const diff = (0, lodash_1.differenceWith)(currentChecksums, previousChecksums, lodash_1.isEqual);
141
+ const diffFiles = diff.map((r) => r.path);
142
+ console.log("Changed Files: ", diffFiles);
143
+ // 다른 부분 찾아 액션
144
+ const diffGroups = (0, lodash_1.groupBy)(diffFiles, (r) => {
145
+ const matched = r.match(/\.(model|types|enums|smd|generated)\.[tj]s/);
146
+ return matched[1];
147
+ });
148
+ // 변경된 파일들을 타입별로 분리하여 각 타입별 액션 처리
149
+ const diffTypes = Object.keys(diffGroups);
150
+ // 트리거: smd
151
+ // 액션: 스키마 생성
152
+ if (diffTypes.includes("smd")) {
153
+ console.log("// 액션: 스키마 생성");
154
+ const smdIds = this.getSMDIdFromPath(diffGroups["smd"]);
155
+ yield this.actionGenerateSchemas(smdIds);
156
+ }
157
+ // 트리거: types, enums, generated 변경시
158
+ // 액션: 파일 싱크 types, enums, generated
159
+ if (diffTypes.includes("types") ||
160
+ diffTypes.includes("enums") ||
161
+ diffTypes.includes("generated")) {
162
+ console.log("// 액션: 파일 싱크 types / enums / generated");
163
+ const tsPaths = [
164
+ ...((_a = diffGroups["types"]) !== null && _a !== void 0 ? _a : []),
165
+ ...((_b = diffGroups["enums"]) !== null && _b !== void 0 ? _b : []),
166
+ ...((_c = diffGroups["generated"]) !== null && _c !== void 0 ? _c : []),
167
+ ].map((p) => p.replace("/dist/", "/src/").replace(".js", ".ts"));
168
+ yield this.actionSyncFilesToTargets(tsPaths);
169
+ }
170
+ // 트리거: model
171
+ if (diffTypes.includes("model")) {
172
+ const smdIds = this.getSMDIdFromPath(diffGroups["model"]);
173
+ console.log("// 액션: 서비스 생성");
174
+ yield this.actionGenerateServices(smdIds);
175
+ console.log("// 액션: HTTP파일 생성");
176
+ yield this.actionGenerateHttps(smdIds);
177
+ }
178
+ // 저장
179
+ yield this.saveChecksums(currentChecksums);
180
+ });
181
+ }
182
+ getSMDIdFromPath(filePaths) {
183
+ return filePaths.map((p) => {
184
+ const matched = p.match(/application\/(.+)\//);
185
+ return (0, inflection_1.camelize)(matched[1].replace(/\-/g, "_"));
186
+ });
187
+ }
188
+ actionGenerateSchemas(smdIds) {
189
+ return __awaiter(this, void 0, void 0, function* () {
190
+ return (yield Promise.all(smdIds.map((smdId) => __awaiter(this, void 0, void 0, function* () {
191
+ return this.generateTemplate("generated", {
192
+ smdId,
193
+ }, {
194
+ overwrite: true,
195
+ });
196
+ }))))
197
+ .flat()
198
+ .flat();
199
+ });
200
+ }
201
+ actionGenerateServices(smdIds) {
202
+ return __awaiter(this, void 0, void 0, function* () {
203
+ return (yield Promise.all(smdIds.map((smdId) => __awaiter(this, void 0, void 0, function* () {
204
+ return this.generateTemplate("service", {
205
+ smdId,
206
+ }, {
207
+ overwrite: true,
208
+ });
209
+ }))))
210
+ .flat()
211
+ .flat();
212
+ });
213
+ }
214
+ actionGenerateHttps(smdIds) {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ return (yield Promise.all(smdIds.map((smdId) => __awaiter(this, void 0, void 0, function* () {
217
+ return this.generateTemplate("generated_http", {
218
+ smdId,
219
+ }, {
220
+ overwrite: true,
221
+ });
222
+ }))))
223
+ .flat()
224
+ .flat();
225
+ });
226
+ }
227
+ copyFileWithReplaceCoreToShared(fromPath, toPath) {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ if (!(0, fs_extra_1.existsSync)(fromPath)) {
230
+ return;
231
+ }
232
+ const oldFileContent = (0, fs_extra_1.readFileSync)(fromPath).toString();
233
+ const newFileContent = oldFileContent
234
+ .replace(/from "sonamu"/g, `from "../sonamu.shared"`)
235
+ .replace(/\/\* BEGIN- Server-side Only \*\/[\s\S]*\/\* END Server-side Only \*\/\n*/g, "");
236
+ return (0, fs_extra_1.writeFile)(toPath, newFileContent);
237
+ });
238
+ }
239
+ actionSyncFilesToTargets(tsPaths) {
240
+ return __awaiter(this, void 0, void 0, function* () {
241
+ return (yield Promise.all(this.config.targets.map((target) => __awaiter(this, void 0, void 0, function* () {
242
+ return Promise.all(tsPaths.map((src) => __awaiter(this, void 0, void 0, function* () {
243
+ const dst = src
244
+ .replace("/api/", `/${target}/`)
245
+ .replace("/application/", "/services/");
246
+ const dir = (0, path_1.dirname)(dst);
247
+ if (!(0, fs_extra_1.existsSync)(dir)) {
248
+ (0, fs_extra_1.mkdirSync)(dir, { recursive: true });
249
+ }
250
+ yield this.copyFileWithReplaceCoreToShared(src, dst);
251
+ return dst;
252
+ })));
253
+ })))).flat();
254
+ });
255
+ }
256
+ getCurrentChecksums() {
257
+ return __awaiter(this, void 0, void 0, function* () {
258
+ const PatternGroup = {
259
+ /* TS 체크 */
260
+ types: this.config.appRootPath + "/api/src/application/**/*.types.ts",
261
+ enums: this.config.appRootPath + "/api/src/application/**/*.enums.ts",
262
+ generated: this.config.appRootPath + "/api/src/application/**/*.generated.ts",
263
+ /* compiled-JS 체크 */
264
+ model: this.config.appRootPath + "/api/dist/application/**/*.model.js",
265
+ smd: this.config.appRootPath + "/api/dist/application/**/*.smd.js",
266
+ };
267
+ const filePaths = (yield Promise.all(Object.entries(PatternGroup).map(([_fileType, pattern]) => __awaiter(this, void 0, void 0, function* () {
268
+ return (0, utils_1.globAsync)(pattern);
269
+ }))))
270
+ .flat()
271
+ .sort();
272
+ const fileChecksums = yield Promise.all(filePaths.map((filePath) => __awaiter(this, void 0, void 0, function* () {
273
+ return {
274
+ path: filePath,
275
+ checksum: yield this.getChecksumOfFile(filePath),
276
+ };
277
+ })));
278
+ return fileChecksums;
279
+ });
280
+ }
281
+ getPreviousChecksums() {
282
+ return __awaiter(this, void 0, void 0, function* () {
283
+ if ((0, fs_extra_1.existsSync)(this.config.checksumsPath) === false) {
284
+ return [];
285
+ }
286
+ const previousChecksums = (yield (0, fs_extra_1.readJSON)(this.config.checksumsPath));
287
+ return previousChecksums;
288
+ });
289
+ }
290
+ saveChecksums(checksums) {
291
+ return __awaiter(this, void 0, void 0, function* () {
292
+ yield (0, fs_extra_1.writeJSON)(this.config.checksumsPath, checksums);
293
+ console.debug("checksum saved", this.config.checksumsPath);
294
+ });
295
+ }
296
+ getChecksumOfFile(filePath) {
297
+ return __awaiter(this, void 0, void 0, function* () {
298
+ return new Promise((resolve, reject) => {
299
+ const hash = crypto_1.default.createHash("sha1");
300
+ const input = fs_extra_1.default.createReadStream(filePath);
301
+ input.on("error", reject);
302
+ input.on("data", function (chunk) {
303
+ hash.update(chunk);
304
+ });
305
+ input.on("close", function () {
306
+ resolve(hash.digest("hex"));
307
+ });
308
+ });
309
+ });
310
+ }
311
+ readApisFromFile(filePath) {
312
+ return __awaiter(this, void 0, void 0, function* () {
313
+ const sourceFile = ts.createSourceFile(filePath, (0, fs_extra_1.readFileSync)(filePath).toString(), ts.ScriptTarget.Latest);
314
+ const methods = [];
315
+ let modelName = "UnknownModel";
316
+ let methodName = "unknownMethod";
317
+ const visitor = (node) => {
318
+ var _a;
319
+ if (ts.isClassDeclaration(node)) {
320
+ if (node.name && ts.isIdentifier(node.name)) {
321
+ modelName = node.name.escapedText.toString().replace(/Class$/, "");
322
+ }
323
+ }
324
+ if (ts.isMethodDeclaration(node)) {
325
+ if (ts.isIdentifier(node.name)) {
326
+ methodName = node.name.escapedText.toString();
327
+ }
328
+ const typeParameters = ((_a = node.typeParameters) !== null && _a !== void 0 ? _a : []).map((typeParam) => {
329
+ const tp = typeParam;
330
+ return {
331
+ t: "type-param",
332
+ id: tp.name.escapedText.toString(),
333
+ constraint: tp.constraint
334
+ ? this.resolveTypeNode(tp.constraint)
335
+ : undefined,
336
+ };
337
+ });
338
+ const parameters = node.parameters.map((paramDec, index) => {
339
+ const defaultDef = this.printNode(paramDec.initializer, sourceFile);
340
+ return this.resolveParamDec({
341
+ name: paramDec.name,
342
+ type: paramDec.type,
343
+ optional: paramDec.questionToken !== undefined ||
344
+ paramDec.initializer !== undefined,
345
+ defaultDef,
346
+ }, index);
347
+ });
348
+ const returnType = this.resolveTypeNode(node.type);
349
+ methods.push({
350
+ modelName,
351
+ methodName,
352
+ typeParameters,
353
+ parameters,
354
+ returnType,
355
+ });
356
+ }
357
+ ts.forEachChild(node, visitor);
358
+ };
359
+ visitor(sourceFile);
360
+ if (methods.length === 0) {
361
+ return [];
362
+ }
363
+ // 현재 파일의 등록된 API 필터
364
+ const currentModelApis = decorators_1.registeredApis.filter((api) => {
365
+ return methods.find((method) => method.modelName === api.modelName &&
366
+ method.methodName === api.methodName);
367
+ });
368
+ // 등록된 API에 현재 메소드 타입 정보 확장
369
+ const extendedApis = currentModelApis.map((api) => {
370
+ const foundMethod = methods.find((method) => method.modelName === api.modelName &&
371
+ method.methodName === api.methodName);
372
+ return Object.assign(Object.assign({}, api), { typeParameters: foundMethod.typeParameters, parameters: foundMethod.parameters, returnType: foundMethod.returnType });
373
+ });
374
+ return extendedApis;
375
+ });
376
+ }
377
+ resolveTypeNode(typeNode) {
378
+ var _a;
379
+ switch (typeNode === null || typeNode === void 0 ? void 0 : typeNode.kind) {
380
+ case ts.SyntaxKind.AnyKeyword:
381
+ return "any";
382
+ case ts.SyntaxKind.UnknownKeyword:
383
+ return "unknown";
384
+ case ts.SyntaxKind.StringKeyword:
385
+ return "string";
386
+ case ts.SyntaxKind.NumberKeyword:
387
+ return "number";
388
+ case ts.SyntaxKind.BooleanKeyword:
389
+ return "boolean";
390
+ case ts.SyntaxKind.UndefinedKeyword:
391
+ return "undefined";
392
+ case ts.SyntaxKind.NullKeyword:
393
+ return "null";
394
+ case ts.SyntaxKind.VoidKeyword:
395
+ return "void";
396
+ case ts.SyntaxKind.LiteralType:
397
+ const literal = typeNode.literal;
398
+ if (ts.isStringLiteral(literal)) {
399
+ return {
400
+ t: "string-literal",
401
+ value: literal.text,
402
+ };
403
+ }
404
+ else if (ts.isNumericLiteral(literal)) {
405
+ return {
406
+ t: "numeric-literal",
407
+ value: Number(literal.text),
408
+ };
409
+ }
410
+ else {
411
+ if (literal.kind === ts.SyntaxKind.NullKeyword) {
412
+ return "null";
413
+ }
414
+ else if (literal.kind === ts.SyntaxKind.UndefinedKeyword) {
415
+ return "undefined";
416
+ }
417
+ else if (literal.kind === ts.SyntaxKind.TrueKeyword) {
418
+ return "true";
419
+ }
420
+ else if (literal.kind === ts.SyntaxKind.FalseKeyword) {
421
+ return "false";
422
+ }
423
+ throw new Error("알 수 없는 리터럴");
424
+ }
425
+ case ts.SyntaxKind.ArrayType:
426
+ const arrNode = typeNode;
427
+ return {
428
+ t: "array",
429
+ elementsType: this.resolveTypeNode(arrNode.elementType),
430
+ };
431
+ case ts.SyntaxKind.TypeLiteral:
432
+ const literalNode = typeNode;
433
+ return {
434
+ t: "object",
435
+ props: literalNode.members.map((member) => {
436
+ if (ts.isIndexSignatureDeclaration(member)) {
437
+ const res = this.resolveParamDec({
438
+ name: member.parameters[0].name,
439
+ type: member.parameters[0].type,
440
+ });
441
+ return this.resolveParamDec({
442
+ name: {
443
+ escapedText: `[${res.name}${res.optional ? "?" : ""}: ${res.type}]`,
444
+ },
445
+ type: member.type,
446
+ });
447
+ }
448
+ else {
449
+ return this.resolveParamDec({
450
+ name: member.name,
451
+ type: member.type,
452
+ });
453
+ }
454
+ }),
455
+ };
456
+ case ts.SyntaxKind.TypeReference:
457
+ return {
458
+ t: "ref",
459
+ id: typeNode.typeName.escapedText.toString(),
460
+ args: (_a = typeNode.typeArguments) === null || _a === void 0 ? void 0 : _a.map((typeArg) => this.resolveTypeNode(typeArg)),
461
+ };
462
+ case ts.SyntaxKind.UnionType:
463
+ return {
464
+ t: "union",
465
+ types: typeNode.types.map((type) => this.resolveTypeNode(type)),
466
+ };
467
+ case ts.SyntaxKind.IntersectionType:
468
+ return {
469
+ t: "intersection",
470
+ types: typeNode.types.map((type) => this.resolveTypeNode(type)),
471
+ };
472
+ case ts.SyntaxKind.IndexedAccessType:
473
+ return {
474
+ t: "indexed-access",
475
+ object: this.resolveTypeNode(typeNode.objectType),
476
+ index: this.resolveTypeNode(typeNode.indexType),
477
+ };
478
+ case ts.SyntaxKind.TupleType:
479
+ if (ts.isTupleTypeNode(typeNode)) {
480
+ return {
481
+ t: "tuple-type",
482
+ elements: typeNode.elements.map((elem) => this.resolveTypeNode(elem)),
483
+ };
484
+ }
485
+ break;
486
+ }
487
+ console.debug(typeNode);
488
+ throw new Error(`알 수 없는 SyntaxKind ${typeNode.kind}`);
489
+ }
490
+ printNode(node, sourceFile) {
491
+ if (node === undefined) {
492
+ return undefined;
493
+ }
494
+ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
495
+ return printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
496
+ }
497
+ autoloadApis(basePath) {
498
+ return __awaiter(this, void 0, void 0, function* () {
499
+ const pathPattern = path_1.default.join(basePath, "api/src/application/**/*.model.ts");
500
+ // console.debug(chalk.yellow(`autoload:APIs @ ${pathPattern}`));
501
+ const filePaths = yield (0, utils_1.globAsync)(pathPattern);
502
+ const result = yield Promise.all(filePaths.map((filePath) => this.readApisFromFile(filePath)));
503
+ this.apis = result.flat();
504
+ return this.apis;
505
+ });
506
+ }
507
+ autoloadModels(basePath) {
508
+ return __awaiter(this, void 0, void 0, function* () {
509
+ const pathPattern = path_1.default.join(basePath, "api/dist/application/**/*.model.js");
510
+ // console.debug(chalk.yellow(`autoload:models @ ${pathPattern}`));
511
+ const filePaths = yield (0, utils_1.globAsync)(pathPattern);
512
+ const modules = yield (0, utils_1.importMultiple)(filePaths);
513
+ const functions = modules
514
+ .map(({ imported }) => Object.entries(imported))
515
+ .flat();
516
+ return Object.fromEntries(functions.filter(([name]) => name.endsWith("Model")));
517
+ });
518
+ }
519
+ autoloadTypes(basePath) {
520
+ return __awaiter(this, void 0, void 0, function* () {
521
+ if (Object.keys(this.types).length > 0) {
522
+ return this.types;
523
+ }
524
+ const pathPatterns = [
525
+ path_1.default.join(basePath, "api/dist/application/**/*.types.js"),
526
+ path_1.default.join(basePath, "api/dist/application/**/*.enums.js"),
527
+ path_1.default.join(basePath, "api/dist/application/**/*.generated.js"),
528
+ ];
529
+ // console.debug(chalk.magenta(`autoload:types @ ${pathPatterns.join("\n")}`));
530
+ const filePaths = (yield Promise.all(pathPatterns.map((pattern) => (0, utils_1.globAsync)(pattern)))).flat();
531
+ const modules = yield (0, utils_1.importMultiple)(filePaths);
532
+ const functions = modules
533
+ .map(({ imported }) => Object.entries(imported))
534
+ .flat();
535
+ this.types = Object.fromEntries(functions.filter(([, f]) => f instanceof zod_1.z.ZodType));
536
+ return this.types;
537
+ });
538
+ }
539
+ getTemplate(key) {
540
+ if (key === "smd") {
541
+ return new smd_template_1.Template__smd();
542
+ }
543
+ else if (key === "init_enums") {
544
+ return new init_enums_template_1.Template__init_enums();
545
+ }
546
+ else if (key === "init_types") {
547
+ return new init_types_template_1.Template__init_types();
548
+ }
549
+ else if (key === "init_generated") {
550
+ return new init_generated_template_1.Template__init_generated();
551
+ }
552
+ else if (key === "generated") {
553
+ return new generated_template_1.Template__generated();
554
+ }
555
+ else if (key === "generated_http") {
556
+ return new generated_http_template_1.Template__generated_http();
557
+ }
558
+ else if (key === "model") {
559
+ return new model_template_1.Template__model();
560
+ }
561
+ else if (key === "model_test") {
562
+ return new model_test_template_1.Template__model_test();
563
+ }
564
+ else if (key === "service") {
565
+ return new service_template_1.Template__service();
566
+ }
567
+ else if (key === "view_list") {
568
+ return new view_list_template_1.Template__view_list();
569
+ }
570
+ else if (key === "view_list_columns") {
571
+ return new view_list_columns_template_1.Template__view_list_columns();
572
+ }
573
+ else if (key === "view_search_input") {
574
+ return new view_search_input_template_1.Template__view_search_input();
575
+ }
576
+ else if (key === "view_form") {
577
+ return new view_form_template_1.Template__view_form();
578
+ }
579
+ else if (key === "view_id_all_select") {
580
+ return new view_id_all_select_template_1.Template__view_id_all_select();
581
+ }
582
+ else if (key === "view_id_async_select") {
583
+ return new view_id_async_select_template_1.Template__view_id_async_select();
584
+ }
585
+ else if (key === "view_enums_select") {
586
+ return new view_enums_select_template_1.Template__view_enums_select();
587
+ }
588
+ else if (key === "view_enums_dropdown") {
589
+ return new view_enums_dropdown_template_1.Template__view_enums_dropdown();
590
+ }
591
+ else if (key === "view_enums_buttonset") {
592
+ return new view_enums_buttonset_template_1.Template__view_enums_buttonset();
593
+ }
594
+ else {
595
+ throw new so_exceptions_1.BadRequestException(`잘못된 템플릿 키 ${key}`);
596
+ }
597
+ }
598
+ renderTemplate(key, options) {
599
+ return __awaiter(this, void 0, void 0, function* () {
600
+ const template = this.getTemplate(key);
601
+ let extra = [];
602
+ if (key === "service" || key === "generated_http") {
603
+ // service 필요 정보 (API 리스트)
604
+ const smd = smd_manager_1.SMDManager.get(options.smdId);
605
+ const modelTsPath = `${path_1.default.resolve(this.config.appRootPath, "api/src/application")}/${smd.names.fs}/${smd.names.fs}.model.ts`;
606
+ extra = [yield this.readApisFromFile(modelTsPath)];
607
+ }
608
+ else if (key === "view_list" || key === "model") {
609
+ // view_list 필요 정보 (컬럼 노드, 리스트파라미터 노드)
610
+ const columnsNode = yield this.getColumnsNode(options.smdId, "A");
611
+ const listParamsZodType = yield this.getZodTypeById(`${options.smdId}ListParams`);
612
+ const listParamsNode = this.zodTypeToRenderingNode(listParamsZodType);
613
+ extra = [columnsNode, listParamsNode];
614
+ }
615
+ else if (key === "view_form") {
616
+ // view_form 필요 정보 (세이브파라미터 노드)
617
+ const saveParamsZodType = yield this.getZodTypeById(`${options.smdId}SaveParams`);
618
+ const saveParamsNode = this.zodTypeToRenderingNode(saveParamsZodType);
619
+ extra = [saveParamsNode];
620
+ }
621
+ const rendered = template.render(options, ...extra);
622
+ const resolved = this.resolveRenderedTemplate(key, rendered);
623
+ let preTemplateResolved = [];
624
+ if (rendered.preTemplates) {
625
+ preTemplateResolved = (yield Promise.all(rendered.preTemplates.map(({ key, options }) => {
626
+ return this.renderTemplate(key, options);
627
+ }))).flat();
628
+ }
629
+ return [resolved, ...preTemplateResolved];
630
+ });
631
+ }
632
+ resolveRenderedTemplate(key, result) {
633
+ const { target, path: filePath, body, importKeys, customHeaders } = result;
634
+ // import 할 대상의 대상 path 추출
635
+ const importDefs = importKeys
636
+ .reduce((r, importKey) => {
637
+ const modulePath = smd_manager_1.SMDManager.getModulePath(importKey);
638
+ let importPath = modulePath;
639
+ if (modulePath.includes("/")) {
640
+ importPath = (0, lodash_able_1.wrapIf)(path_1.default.relative(path_1.default.dirname(filePath), modulePath), (p) => [p.startsWith(".") === false, "./" + p]);
641
+ }
642
+ // 같은 파일에서 import 하는 경우 keys 로 나열 처리
643
+ const existsOne = r.find((importDef) => importDef.from === importPath);
644
+ if (existsOne) {
645
+ existsOne.keys = (0, lodash_1.uniq)(existsOne.keys.concat(importKey));
646
+ }
647
+ else {
648
+ r.push({
649
+ keys: [importKey],
650
+ from: importPath,
651
+ });
652
+ }
653
+ return r;
654
+ }, [])
655
+ // 셀프 참조 방지
656
+ .filter((importDef) => filePath.endsWith(importDef.from.replace("./", "") + ".ts") === false);
657
+ // 커스텀 헤더 포함하여 헤더 생성
658
+ const header = [
659
+ ...(customHeaders !== null && customHeaders !== void 0 ? customHeaders : []),
660
+ ...importDefs.map((importDef) => `import { ${importDef.keys.join(", ")} } from '${importDef.from}'`),
661
+ ].join("\n");
662
+ const formatted = key === "generated_http"
663
+ ? [header, body].join("\n\n")
664
+ : prettier_1.default.format([header, body].join("\n\n"), {
665
+ parser: "typescript",
666
+ });
667
+ return {
668
+ path: target + "/" + filePath,
669
+ code: formatted,
670
+ };
671
+ }
672
+ writeCodeToPath(pathAndCode) {
673
+ return __awaiter(this, void 0, void 0, function* () {
674
+ const { appRootPath, targets } = this.config;
675
+ const filePath = `${appRootPath}/${pathAndCode.path}`;
676
+ const dstFilePaths = (0, lodash_1.uniq)(targets.map((target) => filePath.replace("/:target/", `/${target}/`)));
677
+ return yield Promise.all(dstFilePaths.map((dstFilePath) => __awaiter(this, void 0, void 0, function* () {
678
+ const dir = path_1.default.dirname(dstFilePath);
679
+ if ((0, fs_extra_1.existsSync)(dir) === false) {
680
+ (0, fs_extra_1.mkdirSync)(dir, { recursive: true });
681
+ }
682
+ (0, fs_extra_1.writeFileSync)(dstFilePath, pathAndCode.code);
683
+ console.log("GENERATED ", chalk_1.default.blue(dstFilePath));
684
+ return dstFilePath;
685
+ })));
686
+ });
687
+ }
688
+ generateTemplate(key, templateOptions, _generateOptions) {
689
+ return __awaiter(this, void 0, void 0, function* () {
690
+ const generateOptions = Object.assign({ overwrite: false }, _generateOptions);
691
+ // 키 children
692
+ let keys = [key];
693
+ if (key === "smd") {
694
+ keys = ["smd", "init_enums", "init_generated", "init_types"];
695
+ }
696
+ // 템플릿 렌더
697
+ const pathAndCodes = (yield Promise.all(keys.map((key) => __awaiter(this, void 0, void 0, function* () {
698
+ return this.renderTemplate(key, templateOptions);
699
+ })))).flat();
700
+ /*
701
+ overwrite가 true일 때
702
+ - 생각하지 않고 그냥 다 덮어씀
703
+ overwrite가 false일 때
704
+ - 옵션1 (현재구현): 그냥 파일 하나라도 있으면 코드 생성 안함
705
+ - 옵션2 : 있는 파일은 전부 그대로 두고 없는 파일만 싹 생성함
706
+ - 옵션3 : 메인 파일만 그대로 두고, 파생 파일은 전부 생성함 => 이게 맞지 않나?
707
+ */
708
+ let filteredPathAndCodes = [];
709
+ if (generateOptions.overwrite === true) {
710
+ filteredPathAndCodes = pathAndCodes;
711
+ }
712
+ else {
713
+ filteredPathAndCodes = pathAndCodes.filter((pathAndCode, index) => {
714
+ if (index === 0) {
715
+ const { appRootPath, targets } = this.config;
716
+ const filePath = `${appRootPath}/${pathAndCode.path}`;
717
+ const dstFilePaths = targets.map((target) => filePath.replace("/:target/", `/${target}/`));
718
+ return dstFilePaths.every((dstPath) => (0, fs_extra_1.existsSync)(dstPath) === false);
719
+ }
720
+ else {
721
+ return true;
722
+ }
723
+ });
724
+ if (filteredPathAndCodes.length === 0) {
725
+ throw new so_exceptions_1.AlreadyProcessedException("이미 경로에 모든 파일이 존재합니다.");
726
+ }
727
+ }
728
+ return Promise.all(filteredPathAndCodes.map((pathAndCode) => this.writeCodeToPath(pathAndCode)));
729
+ });
730
+ }
731
+ checkExists(smdId, enums) {
732
+ const keys = types_2.TemplateKey.options;
733
+ const names = smd_manager_1.SMDManager.getNamesFromId(smdId);
734
+ const enumsKeys = Object.keys(enums).filter((name) => name !== names.constant);
735
+ return keys.reduce((result, key) => {
736
+ const tpl = this.getTemplate(key);
737
+ if (key.startsWith("view_enums")) {
738
+ enumsKeys.map((componentId) => {
739
+ const { target, path: p } = tpl.getTargetAndPath(names, componentId);
740
+ result[`${key}__${componentId}`] = (0, fs_extra_1.existsSync)(path_1.default.join(this.config.appRootPath, target, p));
741
+ });
742
+ return result;
743
+ }
744
+ const { target, path: p } = tpl.getTargetAndPath(names);
745
+ if (target.includes(":target")) {
746
+ this.config.targets.map((t) => {
747
+ result[`${key}__${t}`] = (0, fs_extra_1.existsSync)(path_1.default.join(this.config.appRootPath, target.replace(":target", t), p));
748
+ });
749
+ }
750
+ else {
751
+ result[key] = (0, fs_extra_1.existsSync)(path_1.default.join(this.config.appRootPath, target, p));
752
+ }
753
+ return result;
754
+ }, {});
755
+ }
756
+ getZodTypeById(zodTypeId) {
757
+ return __awaiter(this, void 0, void 0, function* () {
758
+ const modulePath = smd_manager_1.SMDManager.getModulePath(zodTypeId);
759
+ const moduleAbsPath = path_1.default.join(this.config.appRootPath, "api", "dist", "application", modulePath + ".js");
760
+ const importPath = "./" + path_1.default.relative(__dirname, moduleAbsPath);
761
+ const imported = yield Promise.resolve().then(() => __importStar(require(importPath)));
762
+ if (!imported[zodTypeId]) {
763
+ throw new Error(`존재하지 않는 zodTypeId ${zodTypeId}`);
764
+ }
765
+ return imported[zodTypeId].describe(zodTypeId);
766
+ });
767
+ }
768
+ propNodeToZodType(propNode) {
769
+ var _a;
770
+ return __awaiter(this, void 0, void 0, function* () {
771
+ if (propNode.nodeType === "plain") {
772
+ return this.propToZodType(propNode.prop);
773
+ }
774
+ else if (propNode.nodeType === "array") {
775
+ if (propNode.prop === undefined) {
776
+ throw new Error();
777
+ }
778
+ else if (propNode.children.length > 0) {
779
+ return (yield this.propNodeToZodType(Object.assign(Object.assign({}, propNode), { nodeType: "object" }))).array();
780
+ }
781
+ else {
782
+ const innerType = yield this.propToZodType(propNode.prop);
783
+ if (propNode.prop.nullable === true) {
784
+ return zod_1.z.array(innerType).nullable();
785
+ }
786
+ else {
787
+ return zod_1.z.array(innerType);
788
+ }
789
+ }
790
+ }
791
+ else if (propNode.nodeType === "object") {
792
+ const obj = yield propNode.children.reduce((promise, childPropNode) => __awaiter(this, void 0, void 0, function* () {
793
+ const result = yield promise;
794
+ result[childPropNode.prop.name] = yield this.propNodeToZodType(childPropNode);
795
+ return result;
796
+ }), {});
797
+ if (((_a = propNode.prop) === null || _a === void 0 ? void 0 : _a.nullable) === true) {
798
+ return zod_1.z.object(obj).nullable();
799
+ }
800
+ else {
801
+ return zod_1.z.object(obj);
802
+ }
803
+ }
804
+ else {
805
+ throw Error;
806
+ }
807
+ });
808
+ }
809
+ propToZodType(prop) {
810
+ return __awaiter(this, void 0, void 0, function* () {
811
+ let zodType = zod_1.z.unknown();
812
+ if ((0, types_1.isIntegerProp)(prop)) {
813
+ zodType = zod_1.z.number().int();
814
+ }
815
+ else if ((0, types_1.isBigIntegerProp)(prop)) {
816
+ zodType = zod_1.z.bigint();
817
+ }
818
+ else if ((0, types_1.isTextProp)(prop)) {
819
+ zodType = zod_1.z.string().max((0, code_converters_1.getTextTypeLength)(prop.textType));
820
+ }
821
+ else if ((0, types_1.isEnumProp)(prop)) {
822
+ zodType = yield this.getZodTypeById(prop.id);
823
+ }
824
+ else if ((0, types_1.isStringProp)(prop)) {
825
+ zodType = zod_1.z.string().max(prop.length);
826
+ }
827
+ else if ((0, types_1.isFloatProp)(prop) || (0, types_1.isDoubleProp)(prop) || (0, types_1.isDecimalProp)(prop)) {
828
+ zodType = zod_1.z.number();
829
+ }
830
+ else if ((0, types_1.isBooleanProp)(prop)) {
831
+ zodType = zod_1.z.boolean();
832
+ }
833
+ else if ((0, types_1.isDateProp)(prop)) {
834
+ zodType = zod_1.z.string().length(10);
835
+ }
836
+ else if ((0, types_1.isTimeProp)(prop)) {
837
+ zodType = zod_1.z.string().length(8);
838
+ }
839
+ else if ((0, types_1.isDateTimeProp)(prop)) {
840
+ zodType = types_1.SQLDateTimeString;
841
+ }
842
+ else if ((0, types_1.isTimestampProp)(prop)) {
843
+ zodType = types_1.SQLDateTimeString;
844
+ }
845
+ else if ((0, types_1.isJsonProp)(prop)) {
846
+ if (prop.as instanceof zod_1.z.ZodType) {
847
+ zodType = prop.as;
848
+ }
849
+ else {
850
+ zodType = yield this.getZodTypeById(prop.as.ref);
851
+ }
852
+ }
853
+ else if ((0, types_1.isUuidProp)(prop)) {
854
+ zodType = zod_1.z.string().uuid();
855
+ }
856
+ else if ((0, types_1.isVirtualProp)(prop)) {
857
+ if (prop.as instanceof zod_1.z.ZodType) {
858
+ zodType = prop.as;
859
+ }
860
+ else {
861
+ zodType = yield this.getZodTypeById(prop.as.ref);
862
+ }
863
+ }
864
+ else if ((0, types_1.isRelationProp)(prop)) {
865
+ if ((0, types_1.isBelongsToOneRelationProp)(prop) ||
866
+ ((0, types_1.isOneToOneRelationProp)(prop) && prop.hasJoinColumn)) {
867
+ zodType = zod_1.z.number().int();
868
+ throw new Error("여기를 들어온다고?");
869
+ }
870
+ }
871
+ else {
872
+ throw new Error(`prop을 zodType으로 변환하는데 실패 ${prop}}`);
873
+ }
874
+ if (prop.unsigned) {
875
+ zodType = zodType.nonnegative();
876
+ }
877
+ if (prop.nullable) {
878
+ zodType = zodType.nullable();
879
+ }
880
+ return zodType;
881
+ });
882
+ }
883
+ resolveRenderType(key, zodType) {
884
+ if (zodType instanceof zod_1.z.ZodString) {
885
+ if (key.includes("img") || key.includes("image")) {
886
+ return "string-image";
887
+ }
888
+ else if (zodType.description === "SQLDateTimeString") {
889
+ return "string-datetime";
890
+ }
891
+ else {
892
+ return "string-plain";
893
+ }
894
+ }
895
+ else if (zodType instanceof zod_1.z.ZodNumber) {
896
+ if (key === "id") {
897
+ return "number-id";
898
+ }
899
+ else if (key.endsWith("_id")) {
900
+ return "number-fk_id";
901
+ }
902
+ else {
903
+ return "number-plain";
904
+ }
905
+ }
906
+ else if (zodType instanceof zod_1.z.ZodBoolean) {
907
+ return "boolean";
908
+ }
909
+ else if (zodType instanceof zod_1.z.ZodEnum) {
910
+ return "enums";
911
+ }
912
+ else if (zodType instanceof zod_1.z.ZodAny) {
913
+ return "string-plain";
914
+ }
915
+ else {
916
+ throw new Error(`타입 파싱 불가 ${key} ${zodType._def.typeName}`);
917
+ }
918
+ }
919
+ zodTypeToRenderingNode(zodType, baseKey = "root") {
920
+ const def = {
921
+ name: baseKey,
922
+ label: (0, inflection_1.camelize)(baseKey, false),
923
+ zodType,
924
+ };
925
+ if (zodType instanceof zod_1.z.ZodObject) {
926
+ const columnKeys = Object.keys(zodType.shape);
927
+ const children = columnKeys.map((key) => {
928
+ const innerType = zodType.shape[key];
929
+ return this.zodTypeToRenderingNode(innerType, key);
930
+ });
931
+ return Object.assign(Object.assign({}, def), { renderType: "object", children });
932
+ }
933
+ else if (zodType instanceof zod_1.z.ZodArray) {
934
+ const innerType = zodType._def.type;
935
+ if (innerType instanceof zod_1.z.ZodString && baseKey.includes("images")) {
936
+ return Object.assign(Object.assign({}, def), { renderType: "array-images" });
937
+ }
938
+ return Object.assign(Object.assign({}, def), { renderType: "array", element: this.zodTypeToRenderingNode(innerType, baseKey) });
939
+ }
940
+ else if (zodType instanceof zod_1.z.ZodUnion) {
941
+ const optionNodes = zodType._def.options.map((opt) => this.zodTypeToRenderingNode(opt, baseKey));
942
+ // TODO: ZodUnion이 들어있는 경우 핸들링
943
+ return optionNodes[0];
944
+ }
945
+ else if (zodType instanceof zod_1.z.ZodOptional) {
946
+ return Object.assign(Object.assign({}, this.zodTypeToRenderingNode(zodType._def.innerType, baseKey)), { optional: true });
947
+ }
948
+ else if (zodType instanceof zod_1.z.ZodNullable) {
949
+ return Object.assign(Object.assign({}, this.zodTypeToRenderingNode(zodType._def.innerType, baseKey)), { nullable: true });
950
+ }
951
+ else {
952
+ return Object.assign(Object.assign({}, def), { renderType: this.resolveRenderType(baseKey, zodType) });
953
+ }
954
+ }
955
+ getColumnsNode(smdId, subsetKey) {
956
+ return __awaiter(this, void 0, void 0, function* () {
957
+ const smd = yield smd_manager_1.SMDManager.get(smdId);
958
+ const subsetA = smd.subsets[subsetKey];
959
+ if (subsetA === undefined) {
960
+ throw new so_exceptions_1.ServiceUnavailableException("SubsetA 가 없습니다.");
961
+ }
962
+ const propNodes = smd.fieldExprsToPropNodes(subsetA);
963
+ const rootPropNode = {
964
+ nodeType: "object",
965
+ children: propNodes,
966
+ };
967
+ const columnsZodType = (yield this.propNodeToZodType(rootPropNode));
968
+ const columnsNode = this.zodTypeToRenderingNode(columnsZodType);
969
+ columnsNode.children = columnsNode.children.map((child) => {
970
+ if (child.renderType === "object") {
971
+ const pickedCol = child.children.find((cc) => ["title", "name"].includes(cc.name));
972
+ if (pickedCol) {
973
+ return Object.assign(Object.assign({}, child), { renderType: "object-pick", config: {
974
+ picked: pickedCol.name,
975
+ } });
976
+ }
977
+ else {
978
+ return child;
979
+ }
980
+ }
981
+ else if (child.renderType === "array" &&
982
+ child.element &&
983
+ child.element.renderType === "object") {
984
+ const pickedCol = child.element.children.find((cc) => ["title", "name"].includes(cc.name));
985
+ if (pickedCol) {
986
+ return Object.assign(Object.assign({}, child), { element: Object.assign(Object.assign({}, child.element), { renderType: "object-pick", config: {
987
+ picked: pickedCol.name,
988
+ } }) });
989
+ }
990
+ else {
991
+ return child;
992
+ }
993
+ }
994
+ return child;
995
+ });
996
+ return columnsNode;
997
+ });
998
+ }
999
+ }
1000
+ exports.Syncer = Syncer;
1001
+ //# sourceMappingURL=syncer.js.map