@simplysm/sd-cli 7.3.2 → 10.0.4

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 (217) hide show
  1. package/.eslintrc.cjs +18 -0
  2. package/dist/build-cluster.js +75 -0
  3. package/dist/build-cluster.js.map +1 -0
  4. package/dist/builders/SdCliJsLibLinter.d.ts +18 -0
  5. package/dist/builders/SdCliJsLibLinter.js +69 -0
  6. package/dist/builders/SdCliJsLibLinter.js.map +1 -0
  7. package/dist/builders/SdCliTsLibBuilder.d.ts +20 -0
  8. package/dist/builders/SdCliTsLibBuilder.js +205 -0
  9. package/dist/builders/SdCliTsLibBuilder.js.map +1 -0
  10. package/dist/commons.d.ts +3 -117
  11. package/dist/commons.js +2 -0
  12. package/dist/commons.js.map +1 -0
  13. package/dist/entry/SdCliProject.d.ts +28 -0
  14. package/dist/entry/SdCliProject.js +269 -0
  15. package/dist/entry/SdCliProject.js.map +1 -0
  16. package/dist/sd-cli.js +118 -0
  17. package/dist/sd-cli.js.map +1 -0
  18. package/dist/utils/SdCliBuildResultUtil.d.ts +1 -4
  19. package/dist/utils/SdCliBuildResultUtil.js +37 -0
  20. package/dist/utils/SdCliBuildResultUtil.js.map +1 -0
  21. package/dist/utils/SdCliConfigUtil.js +69 -0
  22. package/dist/utils/SdCliConfigUtil.js.map +1 -0
  23. package/package.json +10 -59
  24. package/src/build-cluster.ts +82 -0
  25. package/src/builders/SdCliJsLibLinter.ts +84 -0
  26. package/src/builders/SdCliTsLibBuilder.ts +265 -0
  27. package/src/commons.ts +3 -123
  28. package/src/entry/SdCliProject.ts +351 -0
  29. package/src/sd-cli.ts +135 -0
  30. package/src/utils/SdCliBuildResultUtil.ts +5 -38
  31. package/tsconfig.json +18 -0
  32. package/README.md +0 -105
  33. package/assets/client-files/assets/icons/icon-128x128.png +0 -0
  34. package/assets/client-files/assets/icons/icon-144x144.png +0 -0
  35. package/assets/client-files/assets/icons/icon-152x152.png +0 -0
  36. package/assets/client-files/assets/icons/icon-192x192.png +0 -0
  37. package/assets/client-files/assets/icons/icon-384x384.png +0 -0
  38. package/assets/client-files/assets/icons/icon-512x512.png +0 -0
  39. package/assets/client-files/assets/icons/icon-72x72.png +0 -0
  40. package/assets/client-files/assets/icons/icon-96x96.png +0 -0
  41. package/assets/client-files/favicon.ico +0 -0
  42. package/dist/SdCliBuildResultError.d.ts +0 -5
  43. package/dist/SdCliBuildResultError.mjs +0 -8
  44. package/dist/bin/sd-cli.d.ts +0 -2
  45. package/dist/bin/sd-cli.mjs +0 -410
  46. package/dist/build-tool/SdCliCacheCompilerHost.d.ts +0 -10
  47. package/dist/build-tool/SdCliCacheCompilerHost.mjs +0 -51
  48. package/dist/build-tool/SdCliCordova.d.ts +0 -16
  49. package/dist/build-tool/SdCliCordova.mjs +0 -212
  50. package/dist/build-tool/SdCliElectron.d.ts +0 -9
  51. package/dist/build-tool/SdCliElectron.mjs +0 -71
  52. package/dist/build-tool/SdCliGithubApi.d.ts +0 -13
  53. package/dist/build-tool/SdCliGithubApi.mjs +0 -92
  54. package/dist/build-tool/SdCliIndexFileGenerator.d.ts +0 -13
  55. package/dist/build-tool/SdCliIndexFileGenerator.mjs +0 -62
  56. package/dist/build-tool/SdCliNgCacheCompilerHost.d.ts +0 -12
  57. package/dist/build-tool/SdCliNgCacheCompilerHost.mjs +0 -43
  58. package/dist/build-tool/SdCliPackageLinter.d.ts +0 -8
  59. package/dist/build-tool/SdCliPackageLinter.mjs +0 -62
  60. package/dist/builder/SdCliClientBuilder.d.ts +0 -26
  61. package/dist/builder/SdCliClientBuilder.mjs +0 -761
  62. package/dist/builder/SdCliJsLibBuilder.d.ts +0 -14
  63. package/dist/builder/SdCliJsLibBuilder.mjs +0 -54
  64. package/dist/builder/SdCliServerBuilder.d.ts +0 -28
  65. package/dist/builder/SdCliServerBuilder.mjs +0 -482
  66. package/dist/builder/SdCliTsLibBuilder.d.ts +0 -35
  67. package/dist/builder/SdCliTsLibBuilder.mjs +0 -317
  68. package/dist/commons.mjs +0 -2
  69. package/dist/entry-points/SdCliFileCrypto.d.ts +0 -7
  70. package/dist/entry-points/SdCliFileCrypto.mjs +0 -72
  71. package/dist/entry-points/SdCliLocalUpdate.d.ts +0 -13
  72. package/dist/entry-points/SdCliLocalUpdate.mjs +0 -100
  73. package/dist/entry-points/SdCliPrepare.d.ts +0 -5
  74. package/dist/entry-points/SdCliPrepare.mjs +0 -86
  75. package/dist/entry-points/SdCliProject.d.ts +0 -34
  76. package/dist/entry-points/SdCliProject.mjs +0 -416
  77. package/dist/entry-points/SdCliProjectGenerator.d.ts +0 -44
  78. package/dist/entry-points/SdCliProjectGenerator.mjs +0 -326
  79. package/dist/entry-points/file/base/fc_package_eslintrc.d.ts +0 -3
  80. package/dist/entry-points/file/base/fc_package_eslintrc.mjs +0 -31
  81. package/dist/entry-points/file/base/fc_package_npmconfig.d.ts +0 -9
  82. package/dist/entry-points/file/base/fc_package_npmconfig.mjs +0 -32
  83. package/dist/entry-points/file/base/fc_package_tsconfig.d.ts +0 -5
  84. package/dist/entry-points/file/base/fc_package_tsconfig.mjs +0 -13
  85. package/dist/entry-points/file/client/fc_package_AppModule.d.ts +0 -1
  86. package/dist/entry-points/file/client/fc_package_AppModule.mjs +0 -37
  87. package/dist/entry-points/file/client/fc_package_AppPage.d.ts +0 -1
  88. package/dist/entry-points/file/client/fc_package_AppPage.mjs +0 -14
  89. package/dist/entry-points/file/client/fc_package_Page.d.ts +0 -4
  90. package/dist/entry-points/file/client/fc_package_Page.mjs +0 -19
  91. package/dist/entry-points/file/client/fc_package_client_main.d.ts +0 -1
  92. package/dist/entry-points/file/client/fc_package_client_main.mjs +0 -19
  93. package/dist/entry-points/file/client/fc_package_index.d.ts +0 -3
  94. package/dist/entry-points/file/client/fc_package_index.mjs +0 -88
  95. package/dist/entry-points/file/client/fc_package_manifest.d.ts +0 -5
  96. package/dist/entry-points/file/client/fc_package_manifest.mjs +0 -54
  97. package/dist/entry-points/file/client/fc_package_polyfills.d.ts +0 -1
  98. package/dist/entry-points/file/client/fc_package_polyfills.mjs +0 -11
  99. package/dist/entry-points/file/client/fc_package_styles.d.ts +0 -1
  100. package/dist/entry-points/file/client/fc_package_styles.mjs +0 -7
  101. package/dist/entry-points/file/db/fc_package_DbContext.d.ts +0 -3
  102. package/dist/entry-points/file/db/fc_package_DbContext.mjs +0 -14
  103. package/dist/entry-points/file/db/fc_package_DbModel.d.ts +0 -4
  104. package/dist/entry-points/file/db/fc_package_DbModel.mjs +0 -12
  105. package/dist/entry-points/file/project/fc_project_editor_config.d.ts +0 -1
  106. package/dist/entry-points/file/project/fc_project_editor_config.mjs +0 -22
  107. package/dist/entry-points/file/project/fc_project_eslintrc.d.ts +0 -1
  108. package/dist/entry-points/file/project/fc_project_eslintrc.mjs +0 -30
  109. package/dist/entry-points/file/project/fc_project_gitattributes.d.ts +0 -1
  110. package/dist/entry-points/file/project/fc_project_gitattributes.mjs +0 -6
  111. package/dist/entry-points/file/project/fc_project_gitignore.d.ts +0 -1
  112. package/dist/entry-points/file/project/fc_project_gitignore.mjs +0 -27
  113. package/dist/entry-points/file/project/fc_project_npmconfig.d.ts +0 -7
  114. package/dist/entry-points/file/project/fc_project_npmconfig.mjs +0 -37
  115. package/dist/entry-points/file/project/fc_project_readme.d.ts +0 -3
  116. package/dist/entry-points/file/project/fc_project_readme.mjs +0 -13
  117. package/dist/entry-points/file/project/fc_project_simplysm.d.ts +0 -1
  118. package/dist/entry-points/file/project/fc_project_simplysm.mjs +0 -2
  119. package/dist/entry-points/file/project/fc_project_tsconfig.d.ts +0 -1
  120. package/dist/entry-points/file/project/fc_project_tsconfig.mjs +0 -25
  121. package/dist/entry-points/file/server/fc_package_server_main.d.ts +0 -5
  122. package/dist/entry-points/file/server/fc_package_server_main.mjs +0 -60
  123. package/dist/index.d.ts +0 -54
  124. package/dist/index.mjs +0 -55
  125. package/dist/ng-tools/SdCliNgModuleGenerator.d.ts +0 -29
  126. package/dist/ng-tools/SdCliNgModuleGenerator.mjs +0 -502
  127. package/dist/ng-tools/babel/SdCliBbFileMetadata.d.ts +0 -25
  128. package/dist/ng-tools/babel/SdCliBbFileMetadata.mjs +0 -539
  129. package/dist/ng-tools/babel/SdCliBbRootMetadata.d.ts +0 -23
  130. package/dist/ng-tools/babel/SdCliBbRootMetadata.mjs +0 -247
  131. package/dist/ng-tools/babel/SdCliBbUtil.d.ts +0 -5
  132. package/dist/ng-tools/babel/SdCliBbUtil.mjs +0 -14
  133. package/dist/ng-tools/babel/TSdCliBbNgMetadata.d.ts +0 -42
  134. package/dist/ng-tools/babel/TSdCliBbNgMetadata.mjs +0 -216
  135. package/dist/ng-tools/babel/TSdCliBbTypeMetadata.d.ts +0 -55
  136. package/dist/ng-tools/babel/TSdCliBbTypeMetadata.mjs +0 -151
  137. package/dist/ng-tools/commons.d.ts +0 -9
  138. package/dist/ng-tools/commons.mjs +0 -2
  139. package/dist/ng-tools/typescript/SdCliTsFileMetadata.d.ts +0 -61
  140. package/dist/ng-tools/typescript/SdCliTsFileMetadata.mjs +0 -325
  141. package/dist/ng-tools/typescript/SdCliTsRootMetadata.d.ts +0 -8
  142. package/dist/ng-tools/typescript/SdCliTsRootMetadata.mjs +0 -28
  143. package/dist/ng-tools/typescript/SdCliTsUtil.d.ts +0 -5
  144. package/dist/ng-tools/typescript/SdCliTsUtil.mjs +0 -28
  145. package/dist/packages/SdCliPackage.d.ts +0 -22
  146. package/dist/packages/SdCliPackage.mjs +0 -206
  147. package/dist/utils/SdCliBuildResultUtil.mjs +0 -63
  148. package/dist/utils/SdCliConfigUtil.mjs +0 -69
  149. package/dist/utils/SdCliNpmConfigUtil.d.ts +0 -7
  150. package/dist/utils/SdCliNpmConfigUtil.mjs +0 -15
  151. package/dist/worker/build-worker.mjs +0 -67
  152. package/dist/worker/server-worker.mjs +0 -67
  153. package/docs/client-add-page.md +0 -8
  154. package/docs/client-router.md +0 -85
  155. package/docs/client-sw.md +0 -101
  156. package/docs/conf-orm.md +0 -81
  157. package/docs/conf-usage.md +0 -5
  158. package/docs/lib-local-update.md +0 -50
  159. package/docs/lib-ts-paths.md +0 -25
  160. package/lib/cordova-entry.js +0 -22
  161. package/src/SdCliBuildResultError.ts +0 -9
  162. package/src/bin/sd-cli.ts +0 -493
  163. package/src/build-tool/SdCliCacheCompilerHost.ts +0 -79
  164. package/src/build-tool/SdCliCordova.ts +0 -263
  165. package/src/build-tool/SdCliElectron.ts +0 -84
  166. package/src/build-tool/SdCliGithubApi.ts +0 -111
  167. package/src/build-tool/SdCliIndexFileGenerator.ts +0 -79
  168. package/src/build-tool/SdCliNgCacheCompilerHost.ts +0 -58
  169. package/src/build-tool/SdCliPackageLinter.ts +0 -74
  170. package/src/builder/SdCliClientBuilder.ts +0 -871
  171. package/src/builder/SdCliJsLibBuilder.ts +0 -70
  172. package/src/builder/SdCliServerBuilder.ts +0 -552
  173. package/src/builder/SdCliTsLibBuilder.ts +0 -450
  174. package/src/entry-points/SdCliFileCrypto.ts +0 -87
  175. package/src/entry-points/SdCliLocalUpdate.ts +0 -121
  176. package/src/entry-points/SdCliPrepare.ts +0 -86
  177. package/src/entry-points/SdCliProject.ts +0 -491
  178. package/src/entry-points/SdCliProjectGenerator.ts +0 -402
  179. package/src/entry-points/file/base/fc_package_eslintrc.ts +0 -30
  180. package/src/entry-points/file/base/fc_package_npmconfig.ts +0 -43
  181. package/src/entry-points/file/base/fc_package_tsconfig.ts +0 -12
  182. package/src/entry-points/file/client/fc_package_AppModule.ts +0 -36
  183. package/src/entry-points/file/client/fc_package_AppPage.ts +0 -13
  184. package/src/entry-points/file/client/fc_package_Page.ts +0 -19
  185. package/src/entry-points/file/client/fc_package_client_main.ts +0 -18
  186. package/src/entry-points/file/client/fc_package_index.ts +0 -87
  187. package/src/entry-points/file/client/fc_package_manifest.ts +0 -53
  188. package/src/entry-points/file/client/fc_package_polyfills.ts +0 -10
  189. package/src/entry-points/file/client/fc_package_styles.ts +0 -6
  190. package/src/entry-points/file/db/fc_package_DbContext.ts +0 -14
  191. package/src/entry-points/file/db/fc_package_DbModel.ts +0 -11
  192. package/src/entry-points/file/project/fc_project_editor_config.ts +0 -21
  193. package/src/entry-points/file/project/fc_project_eslintrc.ts +0 -29
  194. package/src/entry-points/file/project/fc_project_gitattributes.ts +0 -5
  195. package/src/entry-points/file/project/fc_project_gitignore.ts +0 -26
  196. package/src/entry-points/file/project/fc_project_npmconfig.ts +0 -36
  197. package/src/entry-points/file/project/fc_project_readme.ts +0 -12
  198. package/src/entry-points/file/project/fc_project_simplysm.ts +0 -1
  199. package/src/entry-points/file/project/fc_project_tsconfig.ts +0 -24
  200. package/src/entry-points/file/server/fc_package_server_main.ts +0 -62
  201. package/src/index.ts +0 -54
  202. package/src/ng-tools/SdCliNgModuleGenerator.ts +0 -672
  203. package/src/ng-tools/babel/SdCliBbFileMetadata.ts +0 -629
  204. package/src/ng-tools/babel/SdCliBbRootMetadata.ts +0 -292
  205. package/src/ng-tools/babel/SdCliBbUtil.ts +0 -15
  206. package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +0 -251
  207. package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +0 -212
  208. package/src/ng-tools/commons.ts +0 -3
  209. package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +0 -384
  210. package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +0 -32
  211. package/src/ng-tools/typescript/SdCliTsUtil.ts +0 -29
  212. package/src/packages/SdCliPackage.ts +0 -259
  213. package/src/utils/SdCliNpmConfigUtil.ts +0 -16
  214. package/src/worker/build-worker.ts +0 -73
  215. package/src/worker/server-worker.ts +0 -72
  216. /package/dist/{worker/build-worker.d.ts → build-cluster.d.ts} +0 -0
  217. /package/dist/{worker/server-worker.d.ts → sd-cli.d.ts} +0 -0
@@ -1,86 +0,0 @@
1
- import { FsUtil, Logger } from "@simplysm/sd-core-node";
2
- import { fileURLToPath } from "url";
3
-
4
- export class SdCliPrepare {
5
- private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
6
-
7
- public async prepareAsync(): Promise<void> {
8
- // 타입체크 속도 지연 메시지 추가
9
- const r1 = await this._modifyTypescriptCodeForTypeCheckPerformanceWarning();
10
- this._logger.log(`[모듈수정] 타입체크 속도 지연 메시지 추가 (${r1 ? "O" : "X"})`);
11
- }
12
-
13
- private async _modifyTypescriptCodeForTypeCheckPerformanceWarning(): Promise<boolean> {
14
- const fileUrl = await import.meta.resolve!("typescript");
15
- const filePath = fileURLToPath(fileUrl);
16
- const fileContent = await FsUtil.readFileAsync(filePath);
17
- const modifiedFileContent = fileContent.replace(`
18
- function checkSourceElement(node) {
19
- if (node) {
20
- var saveCurrentNode = currentNode;
21
- currentNode = node;
22
- instantiationCount = 0;
23
- checkSourceElementWorker(node);
24
- currentNode = saveCurrentNode;
25
- }
26
- }`, `
27
-
28
- function checkSourceElement(node) {
29
- if (node) {
30
- const prevUsage = process.cpuUsage();
31
-
32
- var saveCurrentNode = currentNode;
33
- currentNode = node;
34
- instantiationCount = 0;
35
- checkSourceElementWorker(node);
36
- currentNode = saveCurrentNode;
37
-
38
- const usage = process.cpuUsage(prevUsage);
39
- const usageMs = Math.round((usage.user + usage.system) / 1000);
40
- node.parent.childrenUsages = [...node.parent.childrenUsages ?? [], {
41
- node,
42
- usageMs,
43
- childrenUsages: node.childrenUsages
44
- }];
45
- if (node.hasChildPerformanceWarning) {
46
- node.parent.hasChildPerformanceWarning = true;
47
- }
48
- else if (usageMs > 1000 && node.kind !== 253) {
49
- const sf = ts.getSourceFileOfNode(node);
50
-
51
- const fn = (children, depth) => {
52
- let result = "";
53
-
54
- const largeChildren = children
55
- .filter((item) => item.usageMs > 50)
56
- .sort((p, n) => p.usageMs > n.usageMs ? -1 : p.usageMs < n.usageMs ? 1 : 0);
57
- for (const child of largeChildren) {
58
- const pos = sf.getLineAndCharacterOfPosition(child.node.getStart());
59
- for(let i = 0 ; i < depth; i++){
60
- result += " ";
61
- }
62
- result += sf.fileName.replace(/\\//g, "\\\\") + "(" + (pos.line + 1) + ", " + (pos.character + 1) + "): " + child.usageMs + "ms/cpu\\n";
63
-
64
- result += fn(child.childrenUsages ?? [], depth + 1);
65
- }
66
-
67
- return result;
68
- };
69
-
70
- const tree = fn(node.childrenUsages ?? [], 1);
71
-
72
- error(node, {
73
- code: 9000,
74
- category: ts.DiagnosticCategory.Warning,
75
- key: "simplysm_check_source_element_performance_slow",
76
- message: ("소스코드 타입분석에 너무 오랜 시간이 소요됩니다. [" + usageMs + "ms/cpu]\\n" + tree).trim()
77
- });
78
-
79
- node.parent.hasChildPerformanceWarning = true;
80
- }
81
- }
82
- }`);
83
- await FsUtil.writeFileAsync(filePath, modifiedFileContent);
84
- return modifiedFileContent.includes("const prevUsage = process.cpuUsage();");
85
- }
86
- }
@@ -1,491 +0,0 @@
1
- import { FsUtil, Logger, SdProcess } from "@simplysm/sd-core-node";
2
- import path from "path";
3
- import { INpmConfig, ISdCliConfig, ISdCliPackageBuildResult } from "../commons";
4
- import { SdCliPackage } from "../packages/SdCliPackage";
5
- import { JsonConvert, Wait } from "@simplysm/sd-core-common";
6
- import os from "os";
7
- import { SdCliBuildResultUtil } from "../utils/SdCliBuildResultUtil";
8
- import semver from "semver/preload";
9
- import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
10
- import { SdCliLocalUpdate } from "./SdCliLocalUpdate";
11
- import { fileURLToPath } from "url";
12
- import cp from "child_process";
13
-
14
- export class SdCliProject {
15
- private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
16
-
17
- private readonly _npmConfig: INpmConfig;
18
- private readonly _serverInfoMap = new Map<string, IServerInfo>();
19
-
20
- public constructor(private readonly _rootPath: string) {
21
- const npmConfigFilePath = path.resolve(this._rootPath, "package.json");
22
- this._npmConfig = FsUtil.readJson(npmConfigFilePath);
23
- }
24
-
25
- public async watchAsync(opt: { confFileRelPath: string; optNames: string[]; pkgs: string[] }): Promise<void> {
26
- this._logger.debug("프로젝트 설정 가져오기...");
27
- const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), true, opt.optNames);
28
-
29
- if (config.localUpdates) {
30
- this._logger.debug("로컬 라이브러리 업데이트 변경감지 시작...");
31
- await new SdCliLocalUpdate(this._rootPath).watchAsync({ confFileRelPath: opt.confFileRelPath });
32
- }
33
-
34
- this._logger.debug("패키지 목록 구성...");
35
- const allPkgs = await this._getPackagesAsync(config);
36
- const pkgs = allPkgs.filter((pkg) => opt.pkgs.length === 0 || opt.pkgs.includes(path.basename(pkg.rootPath)));
37
-
38
- this._logger.debug("패키지 이벤트 설정...");
39
- let changeCount = 0;
40
- let changePkgs: SdCliPackage[] = [];
41
- const totalResultMap = new Map<string, ISdCliPackageBuildResult[]>();
42
- for (const pkg of pkgs) {
43
- pkg
44
- .on("change", () => {
45
- if (changeCount === 0) {
46
- this._logger.log("빌드를 시작합니다...");
47
- }
48
- changeCount++;
49
- this._logger.debug(`[${pkg.name}] 빌드를 시작합니다...`);
50
- })
51
- .on("complete", (results) => {
52
- changePkgs.push(pkg);
53
-
54
- this._logger.debug(`[${pkg.name}] 빌드가 완료되었습니다.`);
55
- totalResultMap.set(pkg.name, results);
56
-
57
- setTimeout(async () => {
58
- changeCount--;
59
- if (changeCount === 0) {
60
- const currChangePkgs = [...changePkgs].distinct(true);
61
- changePkgs = [];
62
-
63
- for (const changePkg of currChangePkgs) {
64
- if (changePkg.config.type === "server" && !results.some((item) => item.severity === "error")) {
65
- await this._restartServerAsync(changePkg);
66
- }
67
-
68
- if (changePkg.config.type === "client") {
69
- if (typeof changePkg.config.server === "string") {
70
- const serverInfo = this._serverInfoMap.get(changePkg.config.server);
71
- if (serverInfo) {
72
- await this._sendServerWorkerBroadcastReloadAsync(serverInfo);
73
- }
74
- }
75
- else {
76
- const serverInfo = this._serverInfoMap.get("PORT:" + changePkg.config.server.port);
77
- if (serverInfo) {
78
- await this._sendServerWorkerBroadcastReloadAsync(serverInfo);
79
- }
80
- }
81
- }
82
- }
83
-
84
- this._loggingResults(totalResultMap);
85
- this._loggingOpenClientHrefs();
86
- this._logger.info("모든 빌드가 완료되었습니다.");
87
- }
88
- }, 500);
89
- });
90
- }
91
-
92
-
93
- if (changeCount === 0) {
94
- this._logger.log("빌드를 시작합니다...");
95
- }
96
- changeCount++;
97
-
98
- try {
99
- const pkgNames = pkgs.map((item) => item.name);
100
- const buildCompletedPackageNames: string[] = [];
101
- await pkgs.parallelAsync(async (pkg) => {
102
- await Wait.until(() => !pkg.allDependencies.some((dep) => pkgNames.includes(dep) && !buildCompletedPackageNames.includes(dep)));
103
- if (pkg.config.type === "client") {
104
- await pkg.watchAsync();
105
-
106
- if (typeof pkg.config.server === "string") {
107
- const serverInfo = this._serverInfoMap.getOrCreate(pkg.config.server, { pathProxy: [], clientInfos: [] });
108
-
109
- serverInfo.pathProxy.push({
110
- from: pkg.name.split("/").last()!,
111
- to: path.resolve(pkg.rootPath, "dist")
112
- });
113
- await this._reloadServerWorkerPathProxyAsync(serverInfo);
114
-
115
- serverInfo.clientInfos.push({
116
- pkgKey: pkg.name.split("/").last()!,
117
- platforms: pkg.config.builder ? Object.keys(pkg.config.builder) : ["web"],
118
- cordovaTargets: pkg.config.builder?.cordova?.target ? Object.keys(pkg.config.builder.cordova.target) : ["browser"]
119
- });
120
- }
121
- else { // DEV SERVER
122
- const serverInfo = this._serverInfoMap.getOrCreate("PORT:" + pkg.config.server.port, {
123
- pathProxy: [],
124
- clientInfos: []
125
- });
126
- if (serverInfo.worker === undefined) {
127
- const serverWorkerInfo = await this._runServerWorkerAsync(pkg.config.server);
128
- serverInfo.worker = serverWorkerInfo.worker;
129
- serverInfo.url = serverWorkerInfo.url;
130
-
131
- serverInfo.pathProxy.push({
132
- from: pkg.name.split("/").last()!,
133
- to: path.resolve(pkg.rootPath, "dist")
134
- });
135
- await this._reloadServerWorkerPathProxyAsync(serverInfo);
136
-
137
- serverInfo.clientInfos.push({
138
- pkgKey: pkg.name.split("/").last()!,
139
- platforms: pkg.config.builder ? Object.keys(pkg.config.builder) : ["web"],
140
- cordovaTargets: pkg.config.builder?.cordova?.target ? Object.keys(pkg.config.builder.cordova.target) : ["browser"]
141
- });
142
- }
143
- }
144
- }
145
- else {
146
- await pkg.watchAsync();
147
- }
148
- buildCompletedPackageNames.push(pkg.name);
149
- });
150
- }
151
- catch (err) {
152
- this._loggingResults(totalResultMap);
153
- this._loggingOpenClientHrefs();
154
- throw err;
155
- }
156
-
157
- changeCount--;
158
- if (changeCount === 0) {
159
- this._loggingResults(totalResultMap);
160
- this._loggingOpenClientHrefs();
161
- this._logger.info("모든 빌드가 완료되었습니다.");
162
- }
163
- }
164
-
165
- public async buildAsync(opt: { confFileRelPath: string; optNames: string[]; pkgs: string[] }): Promise<void> {
166
- this._logger.debug("프로젝트 설정 가져오기...");
167
- const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false, opt.optNames);
168
-
169
- this._logger.debug("패키지 목록 구성...");
170
- const allPkgs = await this._getPackagesAsync(config);
171
- const pkgs = allPkgs.filter((pkg) => opt.pkgs.length === 0 || opt.pkgs.includes(path.basename(pkg.rootPath)));
172
-
173
- this._logger.debug("프로젝트 및 패키지 버전 설정...");
174
- await this._upgradeVersionAsync(allPkgs);
175
-
176
- // 빌드
177
- await this._buildPkgsAsync(pkgs);
178
- }
179
-
180
- public async publishAsync(opt: { noBuild: boolean; confFileRelPath: string; optNames: string[]; pkgs: string[] }): Promise<void> {
181
- this._logger.debug("프로젝트 설정 가져오기...");
182
- const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false, opt.optNames);
183
-
184
- if (opt.noBuild) {
185
- this._logger.warn("빌드하지 않고, 배포하는것은 상당히 위험합니다.");
186
- await this._waitSecMessageAsync("프로세스를 중지하려면, 'CTRL+C'를 누르세요.", 5);
187
- }
188
-
189
- // GIT 사용중일 경우, 커밋되지 않은 수정사항이 있는지 확인
190
- if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
191
- this._logger.debug("GIT 커밋여부 확인...");
192
- const gitStatusResult = await SdProcess.spawnAsync("git status");
193
- if (gitStatusResult.includes("Changes") || gitStatusResult.includes("Untracked")) {
194
- throw new Error("커밋되지 않은 정보가 있습니다.\n" + gitStatusResult);
195
- }
196
- }
197
-
198
- this._logger.debug("패키지 목록 구성...");
199
- const allPkgs = await this._getPackagesAsync(config);
200
- const pkgs = allPkgs.filter((pkg) => opt.pkgs.length === 0 || opt.pkgs.includes(path.basename(pkg.rootPath)));
201
-
202
- this._logger.debug("프로젝트 및 패키지 버전 설정...");
203
- await this._upgradeVersionAsync(allPkgs);
204
-
205
- // 빌드
206
- if (!opt.noBuild) {
207
- // this._logger.debug("노드패키지 업데이트...");
208
- // await new SdCliNpm(this._rootPath).updateAsync();
209
-
210
- this._logger.debug("빌드를 시작합니다...");
211
- await this._buildPkgsAsync(pkgs);
212
- }
213
-
214
- // GIT 사용중일경우, 새 버전 커밋 및 TAG 생성
215
- if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
216
- this._logger.debug("새 버전 커밋 및 TAG 생성...");
217
- await SdProcess.spawnAsync("git add .");
218
- await SdProcess.spawnAsync(`git commit -m "v${this._npmConfig.version}"`);
219
- await SdProcess.spawnAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
220
-
221
- this._logger.debug("새 버전 푸쉬...");
222
- await SdProcess.spawnAsync("git push");
223
- await SdProcess.spawnAsync("git push --tags");
224
- }
225
-
226
- this._logger.debug("배포 시작...");
227
- await pkgs.parallelAsync(async (pkg) => {
228
- if (pkg.config.publish == null) return;
229
-
230
- this._logger.debug(`[${pkg.name}] 배포를 시작합니다...`);
231
- await pkg.publishAsync();
232
- this._logger.debug(`[${pkg.name}] 배포가 완료되었습니다.`);
233
- });
234
- this._logger.info(`모든 배포가 완료되었습니다. (v${this._npmConfig.version})`);
235
- }
236
-
237
- private async _runServerWorkerAsync(filePathOrOpt: string | { port: number }): Promise<{ worker: cp.ChildProcess; url: string }> {
238
- const workerPath = fileURLToPath(await import.meta.resolve!("../worker/server-worker"));
239
- return await new Promise<{ worker: cp.ChildProcess; url: string }>((resolve, reject) => {
240
- const worker = cp.fork(workerPath, [
241
- JsonConvert.stringify(filePathOrOpt)
242
- ], {
243
- stdio: ["pipe", "pipe", "pipe", "ipc"],
244
- env: process.env
245
- });
246
-
247
- worker.on("error", (err) => {
248
- reject(err);
249
- });
250
-
251
- worker.stdout!.pipe(process.stdout);
252
- worker.stderr!.pipe(process.stderr);
253
-
254
- worker.on("message", (url: string) => {
255
- resolve({ worker, url });
256
- });
257
- });
258
- }
259
-
260
- private async _reloadServerWorkerPathProxyAsync(serverInfo: IServerInfo): Promise<void> {
261
- if (!serverInfo.worker) return;
262
-
263
- await new Promise<void>((resolve, reject) => {
264
- serverInfo.worker!.send(JsonConvert.stringify(serverInfo.pathProxy), (err) => {
265
- if (err) {
266
- reject(err);
267
- return;
268
- }
269
- resolve();
270
- });
271
- });
272
- }
273
-
274
- private async _sendServerWorkerBroadcastReloadAsync(serverInfo: IServerInfo): Promise<void> {
275
- if (!serverInfo.worker) return;
276
-
277
- await new Promise<void>((resolve, reject) => {
278
- serverInfo.worker!.send("broadcastReload", (err) => {
279
- if (err) {
280
- reject(err);
281
- return;
282
- }
283
- resolve();
284
- });
285
- });
286
- }
287
-
288
- private _isServerRestarting = false;
289
-
290
- private async _restartServerAsync(pkg: SdCliPackage): Promise<void> {
291
- await Wait.until(() => !this._isServerRestarting);
292
-
293
- this._isServerRestarting = true;
294
- const entryFileRelPath = pkg.main;
295
- if (entryFileRelPath === undefined) {
296
- this._logger.error(`서버패키지(${pkg.name})의 'package.json'에서 'main'필드를 찾을 수 없습니다.`);
297
- this._isServerRestarting = false;
298
- return;
299
- }
300
- const entryFilePath = path.resolve(pkg.rootPath, entryFileRelPath);
301
-
302
- try {
303
- const serverInfo = this._serverInfoMap.getOrCreate(path.basename(pkg.rootPath), {
304
- pathProxy: [],
305
- clientInfos: []
306
- });
307
- if (serverInfo.worker) {
308
- this._logger.log(`[${pkg.name}] 기존 서버 중지...`);
309
- cp.exec(`taskkill /pid ${serverInfo.worker.pid} /F /T`);
310
- delete serverInfo.worker;
311
- delete serverInfo.url;
312
- }
313
-
314
- this._logger.log(`[${pkg.name}] 서버 시작중...`);
315
-
316
- const serverWorkerInfo = await this._runServerWorkerAsync(entryFilePath);
317
- serverInfo.worker = serverWorkerInfo.worker;
318
- serverInfo.url = serverWorkerInfo.url;
319
- await this._reloadServerWorkerPathProxyAsync(serverInfo);
320
-
321
- this._logger.log(`[${pkg.name}] 서버가 시작되었습니다.`);
322
- }
323
- catch (err) {
324
- this._logger.error(`서버(${pkg.name}) 재시작중 오류 발생`, err);
325
- }
326
-
327
- this._isServerRestarting = false;
328
- }
329
-
330
- private async _buildPkgsAsync(pkgs: SdCliPackage[]): Promise<void> {
331
- this._logger.debug("빌드를 시작합니다...");
332
- const pkgNames = pkgs.map((item) => item.name);
333
- const buildCompletedPackageNames: string[] = [];
334
- const totalResultMap = new Map<string, ISdCliPackageBuildResult[]>();
335
- try {
336
- await pkgs.parallelAsync(async (pkg) => {
337
- await Wait.until(() => !pkg.allDependencies.some((dep) => pkgNames.includes(dep) && !buildCompletedPackageNames.includes(dep)));
338
-
339
- this._logger.debug(`[${pkg.name}] 빌드를 시작합니다...`);
340
- totalResultMap.set(pkg.name, await pkg.buildAsync());
341
- this._logger.debug(`[${pkg.name}] 빌드가 완료되었습니다.`);
342
-
343
- buildCompletedPackageNames.push(pkg.name);
344
- });
345
-
346
- this._loggingResults(totalResultMap);
347
- if (Array.from(totalResultMap.values()).mapMany().some((item) => item.severity === "error")) {
348
- throw new Error("빌드중 오류가 발생하였습니다.");
349
- }
350
- else {
351
- this._logger.info("모든 빌드가 완료되었습니다.");
352
- }
353
- }
354
- catch (err) {
355
- this._loggingResults(totalResultMap);
356
- throw err;
357
- }
358
- }
359
-
360
- private async _upgradeVersionAsync(pkgs: SdCliPackage[]): Promise<void> {
361
- // 작업공간 package.json 버전 설정
362
- const newVersion = semver.inc(this._npmConfig.version, "patch")!;
363
- this._npmConfig.version = newVersion;
364
-
365
- const pkgNames = pkgs.map((item) => item.name);
366
-
367
- const updateDepVersion = (deps: Record<string, string> | undefined): void => {
368
- if (!deps) return;
369
- for (const depName of Object.keys(deps)) {
370
- if (pkgNames.includes(depName)) {
371
- deps[depName] = newVersion;
372
- }
373
- }
374
- };
375
- updateDepVersion(this._npmConfig.dependencies);
376
- updateDepVersion(this._npmConfig.optionalDependencies);
377
- updateDepVersion(this._npmConfig.devDependencies);
378
- updateDepVersion(this._npmConfig.peerDependencies);
379
-
380
- const npmConfigFilePath = path.resolve(this._rootPath, "package.json");
381
- await FsUtil.writeJsonAsync(npmConfigFilePath, this._npmConfig, { space: 2 });
382
-
383
- // 각 패키지 package.json 버전 설정
384
- await pkgs.parallelAsync(async (pkg) => {
385
- await pkg.setNewVersionAsync(newVersion, pkgNames);
386
- });
387
- }
388
-
389
- private async _waitSecMessageAsync(msg: string, sec: number): Promise<void> {
390
- for (let i = sec; i > 0; i--) {
391
- if (i !== sec) {
392
- process.stdout.cursorTo(0);
393
- }
394
- process.stdout.write(`${msg} ${i}`);
395
- await Wait.time(1000);
396
- }
397
-
398
- process.stdout.cursorTo(0);
399
- process.stdout.clearLine(0);
400
- }
401
-
402
- private async _getPackagesAsync(conf: ISdCliConfig): Promise<SdCliPackage[]> {
403
- const pkgRootPaths = await this._npmConfig.workspaces?.mapManyAsync(async (item) => await FsUtil.globAsync(item));
404
- if (!pkgRootPaths) {
405
- throw new Error("최상위 'package.json'에서 'workspaces'를 찾을 수 없습니다.");
406
- }
407
-
408
- return pkgRootPaths.map((pkgRootPath) => {
409
- // if (pkgs.length > 0 && !pkgs.includes(path.basename(pkgRootPath))) return undefined;
410
- const pkgConfig = conf.packages[path.basename(pkgRootPath)];
411
- if (!pkgConfig) return undefined;
412
- return new SdCliPackage(this._rootPath, pkgRootPath, pkgConfig);
413
- }).filterExists();
414
- }
415
-
416
- private _loggingResults(totalResultMap: Map<string, ISdCliPackageBuildResult[]>): void {
417
- const totalResults = Array.from(totalResultMap.entries())
418
- .mapMany((item) => item[1].map((item1) => ({
419
- pkgName: item[0],
420
- ...item1
421
- })))
422
- .orderBy((item) => `${item.pkgName}_${item.filePath}`);
423
-
424
- const warnings = totalResults
425
- .filter((item) => item.severity === "warning")
426
- .map((item) => `${SdCliBuildResultUtil.getMessage(item)} (${item.pkgName})`)
427
- .distinct();
428
-
429
- const errors = totalResults
430
- .filter((item) => item.severity === "error")
431
- .map((item) => `${SdCliBuildResultUtil.getMessage(item)} (${item.pkgName})`)
432
- .distinct();
433
-
434
- if (warnings.length > 0) {
435
- this._logger.warn(`경고 발생${os.EOL}`, warnings.join(os.EOL));
436
- }
437
- if (errors.length > 0) {
438
- this._logger.error(`오류 발생${os.EOL}`, errors.join(os.EOL));
439
- }
440
-
441
- if (errors.length > 0) {
442
- this._logger.error(`경고: ${warnings.length}건, 오류: ${errors.length}건`);
443
- }
444
- else if (warnings.length > 0) {
445
- this._logger.warn(`경고: ${warnings.length}건, 오류: ${errors.length}건`);
446
- }
447
- }
448
-
449
- private _loggingOpenClientHrefs(): void {
450
- const clientHrefs: string[] = [];
451
-
452
- const serverInfos = Array.from(this._serverInfoMap.values());
453
- for (const serverInfo of serverInfos) {
454
- if (!serverInfo.worker) continue;
455
-
456
- /*const protocolStr = serverInfo.server.options.ssl ? "https" : "http";
457
- const portStr = serverInfo.server.options.port.toString();*/
458
-
459
- for (const clientInfo of serverInfo.clientInfos) {
460
- for (const platform of clientInfo.platforms) {
461
- if (platform === "web") {
462
- clientHrefs.push(`${serverInfo.url}/${clientInfo.pkgKey}/`);
463
- }
464
- else if (platform === "electron") {
465
- clientHrefs.push(`sd-cli run-electron ${clientInfo.pkgKey} ${serverInfo.url}`);
466
- }
467
- else if (platform === "cordova") {
468
- for (const target of clientInfo.cordovaTargets) {
469
- if (target === "browser") {
470
- clientHrefs.push(`${serverInfo.url}/${clientInfo.pkgKey}/${platform}/`);
471
- }
472
- else {
473
- clientHrefs.push(`sd-cli run-cordova ${target} ${clientInfo.pkgKey} ${serverInfo.url}`);
474
- }
475
- }
476
- }
477
- }
478
- }
479
- }
480
- if (clientHrefs.length > 0) {
481
- this._logger.log(`오픈된 클라이언트:\n${clientHrefs.join("\n")}`);
482
- }
483
- }
484
- }
485
-
486
- interface IServerInfo {
487
- worker?: cp.ChildProcess;
488
- url?: string;
489
- pathProxy: { from: string; to: string }[];
490
- clientInfos: { pkgKey: string; platforms: string[]; cordovaTargets: string[] }[];
491
- }