@simplysm/sd-cli 7.0.249 → 7.0.267

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 (138) hide show
  1. package/README.md +95 -0
  2. package/assets/client-files/assets/icons/icon-128x128.png +0 -0
  3. package/assets/client-files/assets/icons/icon-144x144.png +0 -0
  4. package/assets/client-files/assets/icons/icon-152x152.png +0 -0
  5. package/assets/client-files/assets/icons/icon-192x192.png +0 -0
  6. package/assets/client-files/assets/icons/icon-384x384.png +0 -0
  7. package/assets/client-files/assets/icons/icon-512x512.png +0 -0
  8. package/assets/client-files/assets/icons/icon-72x72.png +0 -0
  9. package/assets/client-files/assets/icons/icon-96x96.png +0 -0
  10. package/assets/client-files/favicon.ico +0 -0
  11. package/dist/bin/sd-cli.mjs +212 -15
  12. package/dist/build-tool/SdCliCordova.mjs +3 -3
  13. package/dist/build-tool/SdCliElectron.mjs +3 -2
  14. package/dist/build-tool/SdCliIndexFileGenerator.mjs +2 -3
  15. package/dist/builder/SdCliClientBuilder.d.ts +2 -0
  16. package/dist/builder/SdCliClientBuilder.mjs +57 -20
  17. package/dist/builder/SdCliServerBuilder.d.ts +2 -0
  18. package/dist/builder/SdCliServerBuilder.mjs +27 -13
  19. package/dist/builder/SdCliTsLibBuilder.mjs +18 -12
  20. package/dist/commons.d.ts +6 -1
  21. package/dist/entry-points/SdCliPrepare.mjs +34 -34
  22. package/dist/entry-points/SdCliProjectGenerator.d.ts +44 -0
  23. package/dist/entry-points/SdCliProjectGenerator.mjs +320 -0
  24. package/dist/entry-points/SdCliWorkspace.d.ts +6 -6
  25. package/dist/entry-points/SdCliWorkspace.mjs +61 -107
  26. package/dist/entry-points/file/base/fc_package_eslintrc.d.ts +3 -0
  27. package/dist/entry-points/file/base/fc_package_eslintrc.mjs +31 -0
  28. package/dist/entry-points/file/base/fc_package_npmconfig.d.ts +9 -0
  29. package/dist/entry-points/file/base/fc_package_npmconfig.mjs +32 -0
  30. package/dist/entry-points/file/base/fc_package_tsconfig.d.ts +5 -0
  31. package/dist/entry-points/file/base/fc_package_tsconfig.mjs +13 -0
  32. package/dist/entry-points/file/client/fc_package_AppModule.d.ts +1 -0
  33. package/dist/entry-points/file/client/fc_package_AppModule.mjs +37 -0
  34. package/dist/entry-points/file/client/fc_package_AppPage.d.ts +1 -0
  35. package/dist/entry-points/file/client/fc_package_AppPage.mjs +14 -0
  36. package/dist/entry-points/file/client/fc_package_Page.d.ts +4 -0
  37. package/dist/entry-points/file/client/fc_package_Page.mjs +19 -0
  38. package/dist/entry-points/file/client/fc_package_client_main.d.ts +1 -0
  39. package/dist/entry-points/file/client/fc_package_client_main.mjs +19 -0
  40. package/dist/entry-points/file/client/fc_package_index.d.ts +3 -0
  41. package/dist/entry-points/file/client/fc_package_index.mjs +88 -0
  42. package/dist/entry-points/file/client/fc_package_manifest.d.ts +5 -0
  43. package/dist/entry-points/file/client/fc_package_manifest.mjs +54 -0
  44. package/dist/entry-points/file/client/fc_package_polyfills.d.ts +1 -0
  45. package/dist/entry-points/file/client/fc_package_polyfills.mjs +11 -0
  46. package/dist/entry-points/file/client/fc_package_styles.d.ts +1 -0
  47. package/dist/entry-points/file/client/fc_package_styles.mjs +7 -0
  48. package/dist/entry-points/file/db/fc_package_DbContext.d.ts +3 -0
  49. package/dist/entry-points/file/db/fc_package_DbContext.mjs +14 -0
  50. package/dist/entry-points/file/db/fc_package_DbModel.d.ts +4 -0
  51. package/dist/entry-points/file/db/fc_package_DbModel.mjs +12 -0
  52. package/dist/entry-points/file/project/fc_project_editor_config.d.ts +1 -0
  53. package/dist/entry-points/file/project/fc_project_editor_config.mjs +22 -0
  54. package/dist/entry-points/file/project/fc_project_eslintrc.d.ts +1 -0
  55. package/dist/entry-points/file/project/fc_project_eslintrc.mjs +30 -0
  56. package/dist/entry-points/file/project/fc_project_gitattributes.d.ts +1 -0
  57. package/dist/entry-points/file/project/fc_project_gitattributes.mjs +6 -0
  58. package/dist/entry-points/file/project/fc_project_gitignore.d.ts +1 -0
  59. package/dist/entry-points/file/project/fc_project_gitignore.mjs +17 -0
  60. package/dist/entry-points/file/project/fc_project_npmconfig.d.ts +7 -0
  61. package/dist/entry-points/file/project/fc_project_npmconfig.mjs +35 -0
  62. package/dist/entry-points/file/project/fc_project_readme.d.ts +3 -0
  63. package/dist/entry-points/file/project/fc_project_readme.mjs +13 -0
  64. package/dist/entry-points/file/project/fc_project_simplysm.d.ts +1 -0
  65. package/dist/entry-points/file/project/fc_project_simplysm.mjs +2 -0
  66. package/dist/entry-points/file/project/fc_project_tsconfig.d.ts +1 -0
  67. package/dist/entry-points/file/project/fc_project_tsconfig.mjs +25 -0
  68. package/dist/entry-points/file/server/fc_package_server_main.d.ts +4 -0
  69. package/dist/entry-points/file/server/fc_package_server_main.mjs +60 -0
  70. package/dist/index.d.ts +23 -0
  71. package/dist/index.mjs +24 -1
  72. package/dist/ng-tools/SdCliNgModuleGenerator.mjs +35 -36
  73. package/dist/packages/SdCliPackage.d.ts +1 -0
  74. package/dist/packages/SdCliPackage.mjs +69 -63
  75. package/dist/utils/SdCliBuildResultUtil.mjs +2 -2
  76. package/docs/client-add-page.md +8 -0
  77. package/docs/client-router.md +85 -0
  78. package/docs/client-sw.md +101 -0
  79. package/docs/conf-orm.md +81 -0
  80. package/docs/conf-usage.md +5 -0
  81. package/docs/lib-local-update.md +50 -0
  82. package/docs/lib-ts-paths.md +25 -0
  83. package/package.json +10 -8
  84. package/src/SdCliBuildResultError.ts +9 -9
  85. package/src/bin/sd-cli.ts +244 -15
  86. package/src/build-tool/SdCliCacheCompilerHost.ts +77 -77
  87. package/src/build-tool/SdCliCordova.ts +2 -2
  88. package/src/build-tool/SdCliElectron.ts +2 -1
  89. package/src/build-tool/SdCliGithubApi.ts +110 -110
  90. package/src/build-tool/SdCliIndexFileGenerator.ts +79 -80
  91. package/src/build-tool/SdCliNgCacheCompilerHost.ts +58 -58
  92. package/src/build-tool/SdCliPackageLinter.ts +74 -74
  93. package/src/builder/SdCliClientBuilder.ts +73 -22
  94. package/src/builder/SdCliJsLibBuilder.ts +70 -70
  95. package/src/builder/SdCliServerBuilder.ts +34 -14
  96. package/src/builder/SdCliTsLibBuilder.ts +450 -445
  97. package/src/commons.ts +6 -1
  98. package/src/entry-points/SdCliFileCrypto.ts +87 -87
  99. package/src/entry-points/SdCliPrepare.ts +55 -55
  100. package/src/entry-points/SdCliProjectGenerator.ts +395 -0
  101. package/src/entry-points/SdCliWorkspace.ts +74 -122
  102. package/src/entry-points/file/base/fc_package_eslintrc.ts +30 -0
  103. package/src/entry-points/file/base/fc_package_npmconfig.ts +43 -0
  104. package/src/entry-points/file/base/fc_package_tsconfig.ts +12 -0
  105. package/src/entry-points/file/client/fc_package_AppModule.ts +36 -0
  106. package/src/entry-points/file/client/fc_package_AppPage.ts +13 -0
  107. package/src/entry-points/file/client/fc_package_Page.ts +19 -0
  108. package/src/entry-points/file/client/fc_package_client_main.ts +18 -0
  109. package/src/entry-points/file/client/fc_package_index.ts +87 -0
  110. package/src/entry-points/file/client/fc_package_manifest.ts +53 -0
  111. package/src/entry-points/file/client/fc_package_polyfills.ts +10 -0
  112. package/src/entry-points/file/client/fc_package_styles.ts +6 -0
  113. package/src/entry-points/file/db/fc_package_DbContext.ts +14 -0
  114. package/src/entry-points/file/db/fc_package_DbModel.ts +11 -0
  115. package/src/entry-points/file/project/fc_project_editor_config.ts +21 -0
  116. package/src/entry-points/file/project/fc_project_eslintrc.ts +29 -0
  117. package/src/entry-points/file/project/fc_project_gitattributes.ts +5 -0
  118. package/src/entry-points/file/project/fc_project_gitignore.ts +16 -0
  119. package/src/entry-points/file/project/fc_project_npmconfig.ts +34 -0
  120. package/src/entry-points/file/project/fc_project_readme.ts +12 -0
  121. package/src/entry-points/file/project/fc_project_simplysm.ts +1 -0
  122. package/src/entry-points/file/project/fc_project_tsconfig.ts +24 -0
  123. package/src/entry-points/file/server/fc_package_server_main.ts +62 -0
  124. package/src/index.ts +55 -32
  125. package/src/ng-tools/SdCliNgModuleGenerator.ts +639 -640
  126. package/src/ng-tools/babel/SdCliBbFileMetadata.ts +568 -568
  127. package/src/ng-tools/babel/SdCliBbRootMetadata.ts +239 -239
  128. package/src/ng-tools/babel/SdCliBbUtil.ts +15 -15
  129. package/src/ng-tools/babel/TSdCliBbNgMetadata.ts +234 -234
  130. package/src/ng-tools/babel/TSdCliBbTypeMetadata.ts +177 -177
  131. package/src/ng-tools/commons.ts +3 -3
  132. package/src/ng-tools/typescript/SdCliTsFileMetadata.ts +384 -384
  133. package/src/ng-tools/typescript/SdCliTsRootMetadata.ts +32 -32
  134. package/src/ng-tools/typescript/SdCliTsUtil.ts +29 -29
  135. package/src/packages/SdCliPackage.ts +76 -59
  136. package/src/utils/SdCliBuildResultUtil.ts +76 -76
  137. package/src/utils/SdCliConfigUtil.ts +94 -94
  138. package/src/utils/SdCliNpmConfigUtil.ts +16 -16
@@ -1,32 +1,32 @@
1
- import path from "path";
2
- import ts from "typescript";
3
- import { FsUtil } from "@simplysm/sd-core-node";
4
- import { SdCliTsFileMetadata } from "./SdCliTsFileMetadata";
5
-
6
- export class SdCliTsRootMetadata {
7
- private readonly _fileMetaCache = new Map<string, SdCliTsFileMetadata>();
8
-
9
- public constructor(private readonly _packagePath: string) {
10
- }
11
-
12
- public removeCaches(filePaths: string[]): void {
13
- for (const filePath of filePaths) {
14
- this._fileMetaCache.delete(filePath);
15
- }
16
- }
17
-
18
- public getFileMetas(): SdCliTsFileMetadata[] {
19
- const tsconfigPath = path.resolve(this._packagePath, "tsconfig-build.json");
20
- const tsconfig = FsUtil.readJson(tsconfigPath);
21
- const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._packagePath, tsconfig.angularCompilerOptions);
22
-
23
- const result: SdCliTsFileMetadata[] = [];
24
- for (const fileName of parsedTsconfig.fileNames) {
25
- const filePath = path.resolve(fileName);
26
- const fileMeta = this._fileMetaCache.getOrCreate(filePath, () => new SdCliTsFileMetadata(filePath));
27
- result.push(fileMeta);
28
- }
29
-
30
- return result;
31
- }
32
- }
1
+ import path from "path";
2
+ import ts from "typescript";
3
+ import { FsUtil } from "@simplysm/sd-core-node";
4
+ import { SdCliTsFileMetadata } from "./SdCliTsFileMetadata";
5
+
6
+ export class SdCliTsRootMetadata {
7
+ private readonly _fileMetaCache = new Map<string, SdCliTsFileMetadata>();
8
+
9
+ public constructor(private readonly _packagePath: string) {
10
+ }
11
+
12
+ public removeCaches(filePaths: string[]): void {
13
+ for (const filePath of filePaths) {
14
+ this._fileMetaCache.delete(filePath);
15
+ }
16
+ }
17
+
18
+ public getFileMetas(): SdCliTsFileMetadata[] {
19
+ const tsconfigPath = path.resolve(this._packagePath, "tsconfig-build.json");
20
+ const tsconfig = FsUtil.readJson(tsconfigPath);
21
+ const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this._packagePath, tsconfig.angularCompilerOptions);
22
+
23
+ const result: SdCliTsFileMetadata[] = [];
24
+ for (const fileName of parsedTsconfig.fileNames) {
25
+ const filePath = path.resolve(fileName);
26
+ const fileMeta = this._fileMetaCache.getOrCreate(filePath, () => new SdCliTsFileMetadata(filePath));
27
+ result.push(fileMeta);
28
+ }
29
+
30
+ return result;
31
+ }
32
+ }
@@ -1,29 +1,29 @@
1
- import ts from "typescript";
2
- import { SdCliBuildResultError } from "../../SdCliBuildResultError";
3
- import path from "path";
4
-
5
- export class SdCliTsUtil {
6
- public static error(message: string, sourceFile: ts.SourceFile, meta?: ts.Node): SdCliBuildResultError {
7
- if (meta) {
8
- const pos = sourceFile.getLineAndCharacterOfPosition(meta.getStart());
9
- return new SdCliBuildResultError({
10
- filePath: path.resolve(sourceFile.fileName),
11
- line: pos.line,
12
- char: pos.character,
13
- code: undefined,
14
- severity: "error",
15
- message: message
16
- });
17
- }
18
- else {
19
- return new SdCliBuildResultError({
20
- filePath: path.resolve(sourceFile.fileName),
21
- line: undefined,
22
- char: undefined,
23
- code: undefined,
24
- severity: "error",
25
- message: message
26
- });
27
- }
28
- }
29
- }
1
+ import ts from "typescript";
2
+ import { SdCliBuildResultError } from "../../SdCliBuildResultError";
3
+ import path from "path";
4
+
5
+ export class SdCliTsUtil {
6
+ public static error(message: string, sourceFile: ts.SourceFile, meta?: ts.Node): SdCliBuildResultError {
7
+ if (meta) {
8
+ const pos = sourceFile.getLineAndCharacterOfPosition(meta.getStart());
9
+ return new SdCliBuildResultError({
10
+ filePath: path.resolve(sourceFile.fileName),
11
+ line: pos.line,
12
+ char: pos.character,
13
+ code: undefined,
14
+ severity: "error",
15
+ message: message
16
+ });
17
+ }
18
+ else {
19
+ return new SdCliBuildResultError({
20
+ filePath: path.resolve(sourceFile.fileName),
21
+ line: undefined,
22
+ char: undefined,
23
+ code: undefined,
24
+ severity: "error",
25
+ message: message
26
+ });
27
+ }
28
+ }
29
+ }
@@ -74,41 +74,27 @@ export class SdCliPackage extends EventEmitter {
74
74
  await this._genBuildTsconfigAsync();
75
75
  }
76
76
 
77
- const workerPath = fileURLToPath(await import.meta.resolve!("../worker/build-worker"));
78
- await new Promise<void>((resolve, reject) => {
79
- const worker = cp.fork(workerPath, [
80
- "watch",
81
- this.rootPath,
82
- JsonConvert.stringify(this.config),
83
- this._workspaceRootPath
84
- ], {
85
- stdio: ["pipe", "pipe", "pipe", "ipc"],
86
- env: process.env
87
- });
88
-
89
- worker.on("error", (err) => {
90
- reject(err);
91
- });
92
-
93
- worker.stdout!.pipe(process.stdout);
94
- worker.stderr!.pipe(process.stderr);
95
-
96
- worker.on("message", (json: string) => {
97
- const msg = JsonConvert.parse(json);
77
+ await this._runBuildWorkerAsync(
78
+ "watch",
79
+ (message) => {
80
+ const msg = JsonConvert.parse(message);
98
81
  if (msg.event === "ready") {
99
- resolve();
82
+ return true;
100
83
  }
101
84
  else if (msg.event === "change") {
102
85
  this.emit("change");
86
+ return undefined;
103
87
  }
104
88
  else if (msg.event === "complete") {
105
89
  this.emit("complete", msg.body);
90
+ return undefined;
106
91
  }
107
92
  else {
108
- throw new NeverEntryError();
93
+ return new NeverEntryError();
109
94
  }
110
- });
111
- });
95
+ },
96
+ (err) => err
97
+ );
112
98
  }
113
99
 
114
100
  public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
@@ -118,40 +104,18 @@ export class SdCliPackage extends EventEmitter {
118
104
  await this._genBuildTsconfigAsync();
119
105
  }
120
106
 
121
- const workerPath = fileURLToPath(await import.meta.resolve!("../worker/build-worker"));
122
- return await new Promise<ISdCliPackageBuildResult[]>((resolve, reject) => {
123
- const worker = cp.fork(workerPath, [
124
- "build",
125
- this.rootPath,
126
- JsonConvert.stringify(this.config),
127
- this._workspaceRootPath
128
- ], {
129
- stdio: ["pipe", "pipe", "pipe", "ipc"],
130
- env: process.env
131
- });
107
+ let result: ISdCliPackageBuildResult[] = [];
132
108
 
133
- worker.on("error", (err) => {
134
- reject(err);
135
- });
136
-
137
- worker.stdout!.pipe(process.stdout);
138
- worker.stderr!.pipe(process.stderr);
139
-
140
- let result: ISdCliPackageBuildResult[] = [];
141
-
142
- worker.on("message", (json: string) => {
143
- result = JsonConvert.parse(json);
144
- });
145
-
146
- worker.on("exit", (code) => {
147
- if (code !== 0) {
148
- reject(new Error(`오류와 함께 닫힘 (${code})`));
149
- return;
150
- }
109
+ await this._runBuildWorkerAsync(
110
+ "build",
111
+ (message) => {
112
+ result = JsonConvert.parse(message);
113
+ return undefined;
114
+ },
115
+ err => err
116
+ );
151
117
 
152
- resolve(result);
153
- });
154
- });
118
+ return result;
155
119
  }
156
120
 
157
121
  public async publishAsync(): Promise<void> {
@@ -167,7 +131,11 @@ export class SdCliPackage extends EventEmitter {
167
131
  }
168
132
  else {
169
133
  if (this.config.publish.type === "github") {
170
- const repoUrl = typeof this._npmConfig.repository === "string" ? this._npmConfig.repository : this._npmConfig.repository.url;
134
+ if (!this._npmConfig.repository) {
135
+ throw new Error("패키지의 package.json에 repository가 설정되지 않아 github로 배포할 수 없습니다.");
136
+ }
137
+
138
+ const repoUrl = this._npmConfig.repository.url;
171
139
  const repoOwner = repoUrl.split("/").slice(-2)[0];
172
140
  const repoName = repoUrl.split("/").slice(-2)[1].replace(/\..*/g, "");
173
141
 
@@ -210,7 +178,7 @@ export class SdCliPackage extends EventEmitter {
210
178
  return process.env[envName] ?? item;
211
179
  });
212
180
 
213
- const filePaths = await FsUtil.globAsync(path.resolve(this.rootPath, "**", "*"), {
181
+ const filePaths = await FsUtil.globAsync(path.resolve(parsedTsconfig.options.outDir!, "**", "*"), {
214
182
  dot: true,
215
183
  nodir: true
216
184
  });
@@ -239,4 +207,53 @@ export class SdCliPackage extends EventEmitter {
239
207
  const buildTsconfigFilePath = path.resolve(this.rootPath, "tsconfig-build.json");
240
208
  await FsUtil.writeJsonAsync(buildTsconfigFilePath, buildTsconfig, { space: 2 });
241
209
  }
210
+
211
+ private async _runBuildWorkerAsync(cmd: string, success: (message: string) => undefined | true | Error, error: (err: Error) => undefined | true | Error): Promise<void> {
212
+ return await new Promise<void>(async (resolve, reject) => {
213
+ const worker = cp.fork(
214
+ fileURLToPath(await import.meta.resolve!("../worker/build-worker")),
215
+ [
216
+ cmd,
217
+ this.rootPath,
218
+ JsonConvert.stringify(this.config),
219
+ this._workspaceRootPath
220
+ ],
221
+ {
222
+ stdio: ["pipe", "pipe", "pipe", "ipc"],
223
+ env: process.env
224
+ });
225
+
226
+ worker.on("error", (err) => {
227
+ const r = error(err);
228
+ if (r === true) {
229
+ resolve();
230
+ }
231
+ else if (r != null) {
232
+ reject(r);
233
+ }
234
+ });
235
+
236
+ worker.stdout!.pipe(process.stdout);
237
+ worker.stderr!.pipe(process.stderr);
238
+
239
+ worker.on("message", (json: string) => {
240
+ const r = success(json);
241
+ if (r === true) {
242
+ resolve();
243
+ }
244
+ else if (r != null) {
245
+ reject(r);
246
+ }
247
+ });
248
+
249
+ worker.on("exit", (code) => {
250
+ if (code !== 0) {
251
+ reject(new Error(`오류와 함께 닫힘 (${code})`));
252
+ return;
253
+ }
254
+
255
+ resolve();
256
+ });
257
+ });
258
+ }
242
259
  }
@@ -1,76 +1,76 @@
1
- import ts from "typescript";
2
- import os from "os";
3
- import path from "path";
4
- import { ISdCliPackageBuildResult } from "../commons";
5
- import webpack from "webpack";
6
-
7
- export class SdCliBuildResultUtil {
8
- public static convertFromTsDiag(diag: ts.Diagnostic): ISdCliPackageBuildResult | undefined {
9
- const severity = diag.category === ts.DiagnosticCategory.Error ? "error"
10
- : diag.category === ts.DiagnosticCategory.Warning ? "warning"
11
- : undefined;
12
- if (!severity) return undefined;
13
-
14
- const code = `TS${diag.code}`;
15
- const message = ts.flattenDiagnosticMessageText(diag.messageText, os.EOL);
16
-
17
-
18
- const filePath = diag.file ? path.resolve(diag.file.fileName) : undefined;
19
- const position = diag.file && diag.start !== undefined ? diag.file.getLineAndCharacterOfPosition(diag.start) : undefined;
20
- const line = position ? position.line + 1 : undefined;
21
- const char = position ? position.character + 1 : undefined;
22
-
23
- return {
24
- filePath,
25
- line,
26
- char,
27
- code,
28
- severity,
29
- message
30
- };
31
- }
32
-
33
- public static convertFromWebpackStats(stats: webpack.Stats): ISdCliPackageBuildResult[] {
34
- const results: ISdCliPackageBuildResult[] = [];
35
-
36
- for (const statWarn of stats.compilation.warnings) {
37
- if (stats.compilation.options.ignoreWarnings?.some((ignoreWarning) => ignoreWarning(statWarn, stats.compilation))) continue;
38
-
39
- results.push(this._convertFromWebpackError("warning", statWarn));
40
- }
41
-
42
- for (const statErr of stats.compilation.errors) {
43
- results.push(this._convertFromWebpackError("error", statErr));
44
- }
45
-
46
- return results;
47
- }
48
-
49
- private static _convertFromWebpackError(severity: "warning" | "error", err: webpack.WebpackError): ISdCliPackageBuildResult {
50
- return {
51
- filePath: err.file,
52
- line: err.file ? err.loc["start"]?.line : undefined,
53
- char: err.file ? err.loc["start"]?.column : undefined,
54
- code: err.name,
55
- severity,
56
- message: err.message
57
- };
58
- }
59
-
60
-
61
- public static getMessage(result: ISdCliPackageBuildResult): string {
62
- if (result.code === "ESLintError") {
63
- return result.message;
64
- }
65
-
66
- let str = "";
67
- if (result.filePath !== undefined) {
68
- str += `${result.filePath}(${result.line ?? 0}, ${result.char ?? 0}): `;
69
- }
70
- if (result.code !== undefined) {
71
- str += `${result.code}: `;
72
- }
73
- str += `${result.severity} ${result.message}`;
74
- return str;
75
- }
76
- }
1
+ import ts from "typescript";
2
+ import os from "os";
3
+ import path from "path";
4
+ import { ISdCliPackageBuildResult } from "../commons";
5
+ import webpack from "webpack";
6
+
7
+ export class SdCliBuildResultUtil {
8
+ public static convertFromTsDiag(diag: ts.Diagnostic): ISdCliPackageBuildResult | undefined {
9
+ const severity = diag.category === ts.DiagnosticCategory.Error ? "error"
10
+ : diag.category === ts.DiagnosticCategory.Warning ? "warning"
11
+ : undefined;
12
+ if (!severity) return undefined;
13
+
14
+ const code = `TS${diag.code}`;
15
+ const message = ts.flattenDiagnosticMessageText(diag.messageText, os.EOL);
16
+
17
+
18
+ const filePath = diag.file ? path.resolve(diag.file.fileName) : undefined;
19
+ const position = diag.file && diag.start !== undefined ? diag.file.getLineAndCharacterOfPosition(diag.start) : undefined;
20
+ const line = position ? position.line + 1 : undefined;
21
+ const char = position ? position.character + 1 : undefined;
22
+
23
+ return {
24
+ filePath,
25
+ line,
26
+ char,
27
+ code,
28
+ severity,
29
+ message
30
+ };
31
+ }
32
+
33
+ public static convertFromWebpackStats(stats: webpack.Stats): ISdCliPackageBuildResult[] {
34
+ const results: ISdCliPackageBuildResult[] = [];
35
+
36
+ for (const statWarn of stats.compilation.warnings) {
37
+ if (stats.compilation.options.ignoreWarnings?.some((ignoreWarning) => ignoreWarning(statWarn, stats.compilation))) continue;
38
+
39
+ results.push(this._convertFromWebpackError("warning", statWarn));
40
+ }
41
+
42
+ for (const statErr of stats.compilation.errors) {
43
+ results.push(this._convertFromWebpackError("error", statErr));
44
+ }
45
+
46
+ return results;
47
+ }
48
+
49
+ private static _convertFromWebpackError(severity: "warning" | "error", err: webpack.WebpackError): ISdCliPackageBuildResult {
50
+ return {
51
+ filePath: (err.file as string | undefined) ?? (err.module as webpack.Module | undefined)?.["request"],
52
+ line: err.file ? err.loc["start"]?.line : undefined,
53
+ char: err.file ? err.loc["start"]?.column : undefined,
54
+ code: err.name,
55
+ severity,
56
+ message: err.message
57
+ };
58
+ }
59
+
60
+
61
+ public static getMessage(result: ISdCliPackageBuildResult): string {
62
+ if (result.code === "ESLintError") {
63
+ return result.message;
64
+ }
65
+
66
+ let str = "";
67
+ if (result.filePath !== undefined) {
68
+ str += `${result.filePath}(${result.line ?? 0}, ${result.char ?? 0}): `;
69
+ }
70
+ if (result.code !== undefined) {
71
+ str += `${result.code}: `;
72
+ }
73
+ str += `${result.severity} ${result.message}`;
74
+ return str;
75
+ }
76
+ }
@@ -1,94 +1,94 @@
1
- import { ISdCliConfig, TSdCliPackageConfig } from "../commons";
2
- import { FsUtil } from "@simplysm/sd-core-node";
3
- import { ObjectUtil } from "@simplysm/sd-core-common";
4
- import path from "path";
5
-
6
- export class SdCliConfigUtil {
7
- public static async loadConfigAsync(confFilePath: string, isDev: boolean, opts?: string[]): Promise<ISdCliConfig> {
8
- const confFileCont = await FsUtil.readJsonAsync(confFilePath);
9
- let conf = this._getConfigFromFileContent(confFileCont, isDev, opts);
10
-
11
- // extends
12
- if (conf.extends) {
13
- for (const extConfFilePath of conf.extends) {
14
- const extConf = await this.loadConfigAsync(path.resolve(path.dirname(confFilePath), extConfFilePath), isDev, opts);
15
- conf = this._mergeObj(extConf, conf);
16
- }
17
- }
18
- delete conf["extends"];
19
-
20
- return conf as ISdCliConfig;
21
- }
22
-
23
- private static _getConfigFromFileContent(confFileCont: ISdCliConfigFileContent, isDev: boolean, opts?: string[]): ISdCliConfigFileContent {
24
- const conf = ObjectUtil.clone(confFileCont);
25
-
26
- if (conf.packages) {
27
- for (const pkgName of Object.keys(conf.packages)) {
28
- conf.packages[pkgName] = this._getPkgConfigFromFileContent(conf, conf.packages[pkgName], isDev, opts);
29
- }
30
- }
31
- return conf;
32
- }
33
-
34
- private static _getPkgConfigFromFileContent(confFileCont: ISdCliConfigFileContent, pkgConfFileCont: TSdCliPackageConfigFileContent, isDev: boolean, opts?: string[]): TSdCliPackageConfig {
35
- let pkgConf = ObjectUtil.clone(pkgConfFileCont);
36
-
37
- // override
38
- const pkgOvrNames = pkgConf.overrides;
39
- if (pkgOvrNames) {
40
- for (const pkgOvrName of pkgOvrNames) {
41
- const rootOvr = confFileCont.overrides?.[pkgOvrName];
42
- if (rootOvr) {
43
- const ovrConf = this._getPkgConfigFromFileContent(confFileCont, rootOvr, isDev, opts);
44
- pkgConf = this._mergeObj(pkgConf, ovrConf);
45
- }
46
- }
47
- delete pkgConf.overrides;
48
- }
49
-
50
-
51
- // mode 처리
52
- const mode = isDev ? "dev" : "prod";
53
- if (pkgConf[mode] !== undefined) {
54
- const modeConf = this._getPkgConfigFromFileContent(confFileCont, pkgConf[mode], isDev, opts);
55
- pkgConf = this._mergeObj(pkgConf, modeConf);
56
- }
57
- delete pkgConf["dev"];
58
- delete pkgConf["prod"];
59
-
60
- // options
61
- if (opts && opts.length > 0) {
62
- const pkgOpts = Object.keys(pkgConf).filter((key) => key.startsWith("@") && opts.some((opt) => opt === key.slice(1)));
63
-
64
- for (const pkgOpt of pkgOpts) {
65
- const optConf = this._getPkgConfigFromFileContent(confFileCont, pkgConf[pkgOpt], isDev, opts);
66
- pkgConf = this._mergeObj(pkgConf, optConf);
67
- }
68
-
69
- for (const optKey of Object.keys(pkgConf).filter((item) => item.startsWith("@"))) {
70
- delete pkgConf[optKey];
71
- }
72
- }
73
-
74
- return pkgConf;
75
- }
76
-
77
- private static _mergeObj<A, B>(orig: A, target: B): A & B {
78
- return ObjectUtil.merge(orig, target, {
79
- arrayProcess: "replace",
80
- useDelTargetNull: true
81
- });
82
- }
83
- }
84
-
85
- interface ISdCliConfigFileContent {
86
- packages?: Record<string, TSdCliPackageConfigFileContent>;
87
- overrides?: Record<string, TSdCliPackageConfigFileContent>;
88
- extends?: string[];
89
- }
90
-
91
- type TSdCliPackageConfigFileContent =
92
- TSdCliPackageConfig
93
- & { overrides?: string[] }
94
- & Record<string, any>;
1
+ import { ISdCliConfig, TSdCliPackageConfig } from "../commons";
2
+ import { FsUtil } from "@simplysm/sd-core-node";
3
+ import { ObjectUtil } from "@simplysm/sd-core-common";
4
+ import path from "path";
5
+
6
+ export class SdCliConfigUtil {
7
+ public static async loadConfigAsync(confFilePath: string, isDev: boolean, opts?: string[]): Promise<ISdCliConfig> {
8
+ const confFileCont = await FsUtil.readJsonAsync(confFilePath);
9
+ let conf = this._getConfigFromFileContent(confFileCont, isDev, opts);
10
+
11
+ // extends
12
+ if (conf.extends) {
13
+ for (const extConfFilePath of conf.extends) {
14
+ const extConf = await this.loadConfigAsync(path.resolve(path.dirname(confFilePath), extConfFilePath), isDev, opts);
15
+ conf = this._mergeObj(extConf, conf);
16
+ }
17
+ }
18
+ delete conf["extends"];
19
+
20
+ return conf as ISdCliConfig;
21
+ }
22
+
23
+ private static _getConfigFromFileContent(confFileCont: ISdCliConfigFileContent, isDev: boolean, opts?: string[]): ISdCliConfigFileContent {
24
+ const conf = ObjectUtil.clone(confFileCont);
25
+
26
+ if (conf.packages) {
27
+ for (const pkgName of Object.keys(conf.packages)) {
28
+ conf.packages[pkgName] = this._getPkgConfigFromFileContent(conf, conf.packages[pkgName], isDev, opts);
29
+ }
30
+ }
31
+ return conf;
32
+ }
33
+
34
+ private static _getPkgConfigFromFileContent(confFileCont: ISdCliConfigFileContent, pkgConfFileCont: TSdCliPackageConfigFileContent, isDev: boolean, opts?: string[]): TSdCliPackageConfig {
35
+ let pkgConf = ObjectUtil.clone(pkgConfFileCont);
36
+
37
+ // override
38
+ const pkgOvrNames = pkgConf.overrides;
39
+ if (pkgOvrNames) {
40
+ for (const pkgOvrName of pkgOvrNames) {
41
+ const rootOvr = confFileCont.overrides?.[pkgOvrName];
42
+ if (rootOvr) {
43
+ const ovrConf = this._getPkgConfigFromFileContent(confFileCont, rootOvr, isDev, opts);
44
+ pkgConf = this._mergeObj(pkgConf, ovrConf);
45
+ }
46
+ }
47
+ delete pkgConf.overrides;
48
+ }
49
+
50
+
51
+ // mode 처리
52
+ const mode = isDev ? "dev" : "prod";
53
+ if (pkgConf[mode] !== undefined) {
54
+ const modeConf = this._getPkgConfigFromFileContent(confFileCont, pkgConf[mode], isDev, opts);
55
+ pkgConf = this._mergeObj(pkgConf, modeConf);
56
+ }
57
+ delete pkgConf["dev"];
58
+ delete pkgConf["prod"];
59
+
60
+ // options
61
+ if (opts && opts.length > 0) {
62
+ const pkgOpts = Object.keys(pkgConf).filter((key) => key.startsWith("@") && opts.some((opt) => opt === key.slice(1)));
63
+
64
+ for (const pkgOpt of pkgOpts) {
65
+ const optConf = this._getPkgConfigFromFileContent(confFileCont, pkgConf[pkgOpt], isDev, opts);
66
+ pkgConf = this._mergeObj(pkgConf, optConf);
67
+ }
68
+
69
+ for (const optKey of Object.keys(pkgConf).filter((item) => item.startsWith("@"))) {
70
+ delete pkgConf[optKey];
71
+ }
72
+ }
73
+
74
+ return pkgConf;
75
+ }
76
+
77
+ private static _mergeObj<A, B>(orig: A, target: B): A & B {
78
+ return ObjectUtil.merge(orig, target, {
79
+ arrayProcess: "replace",
80
+ useDelTargetNull: true
81
+ });
82
+ }
83
+ }
84
+
85
+ interface ISdCliConfigFileContent {
86
+ packages?: Record<string, TSdCliPackageConfigFileContent>;
87
+ overrides?: Record<string, TSdCliPackageConfigFileContent>;
88
+ extends?: string[];
89
+ }
90
+
91
+ type TSdCliPackageConfigFileContent =
92
+ TSdCliPackageConfig
93
+ & { overrides?: string[] }
94
+ & Record<string, any>;