@simplysm/sd-cli 6.4.6 → 7.0.12

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 (185) hide show
  1. package/.eslintrc.cjs +11 -0
  2. package/dist/bin/sd-cli.d.ts +1 -0
  3. package/dist/bin/sd-cli.mjs +86 -0
  4. package/dist/build-tool/SdCliCacheCompilerHost.d.ts +10 -0
  5. package/dist/build-tool/SdCliCacheCompilerHost.mjs +44 -0
  6. package/dist/build-tool/SdCliNgCacheCompilerHost.d.ts +11 -0
  7. package/dist/build-tool/SdCliNgCacheCompilerHost.mjs +36 -0
  8. package/dist/build-tool/SdCliPackageLinter.d.ts +8 -0
  9. package/dist/build-tool/SdCliPackageLinter.mjs +41 -0
  10. package/dist/builder/SdCliJsLibBuilder.d.ts +14 -0
  11. package/dist/builder/SdCliJsLibBuilder.mjs +50 -0
  12. package/dist/builder/SdCliTsLibBuilder.d.ts +27 -0
  13. package/dist/builder/SdCliTsLibBuilder.mjs +226 -0
  14. package/dist/commons.d.ts +46 -0
  15. package/dist/commons.mjs +2 -0
  16. package/dist/entry-points/SdCliWorkspace.d.ts +18 -0
  17. package/dist/entry-points/SdCliWorkspace.mjs +193 -0
  18. package/dist/packages/SdCliPackage.d.ts +19 -0
  19. package/dist/packages/SdCliPackage.mjs +89 -0
  20. package/dist/utils/SdCliBuildResultUtil.d.ts +6 -0
  21. package/dist/utils/SdCliBuildResultUtil.mjs +38 -0
  22. package/dist/utils/SdCliConfigUtil.d.ts +7 -0
  23. package/dist/utils/SdCliConfigUtil.mjs +69 -0
  24. package/lib/ts-node-esm-paths.mjs +15 -0
  25. package/package.json +27 -59
  26. package/src/bin/sd-cli.ts +86 -214
  27. package/src/build-tool/SdCliCacheCompilerHost.ts +71 -0
  28. package/src/build-tool/SdCliNgCacheCompilerHost.ts +50 -0
  29. package/src/build-tool/SdCliPackageLinter.ts +54 -0
  30. package/src/builder/SdCliJsLibBuilder.ts +66 -0
  31. package/src/builder/SdCliTsLibBuilder.ts +335 -0
  32. package/src/commons.ts +17 -122
  33. package/src/entry-points/SdCliWorkspace.ts +229 -0
  34. package/src/packages/SdCliPackage.ts +111 -0
  35. package/src/utils/SdCliBuildResultUtil.ts +43 -0
  36. package/src/utils/SdCliConfigUtil.ts +94 -0
  37. package/tsconfig-build.json +9 -0
  38. package/tsconfig.json +7 -18
  39. package/.eslintrc.js +0 -19
  40. package/dist-node/bin/sd-cli.js +0 -197
  41. package/dist-node/bin/sd-cli.js.map +0 -1
  42. package/dist-node/build-tools/SdCliCordova.js +0 -145
  43. package/dist-node/build-tools/SdCliCordova.js.map +0 -1
  44. package/dist-node/build-tools/SdCliIndexFileGenerator.js +0 -51
  45. package/dist-node/build-tools/SdCliIndexFileGenerator.js.map +0 -1
  46. package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js +0 -675
  47. package/dist-node/build-tools/SdCliNgModuleFilesGenerator.js.map +0 -1
  48. package/dist-node/build-tools/metadata/SdAotMetadataReader.js +0 -274
  49. package/dist-node/build-tools/metadata/SdAotMetadataReader.js.map +0 -1
  50. package/dist-node/build-tools/metadata/SdIvyMetadataReader.js +0 -124
  51. package/dist-node/build-tools/metadata/SdIvyMetadataReader.js.map +0 -1
  52. package/dist-node/build-tools/metadata/SdMetadataError.js +0 -13
  53. package/dist-node/build-tools/metadata/SdMetadataError.js.map +0 -1
  54. package/dist-node/build-tools/metadata/SdMyMetadataReader.js +0 -321
  55. package/dist-node/build-tools/metadata/SdMyMetadataReader.js.map +0 -1
  56. package/dist-node/builders/SdCliJavascriptLinter.js +0 -65
  57. package/dist-node/builders/SdCliJavascriptLinter.js.map +0 -1
  58. package/dist-node/builders/SdCliNgClientBuilder.js +0 -636
  59. package/dist-node/builders/SdCliNgClientBuilder.js.map +0 -1
  60. package/dist-node/builders/SdCliNgLibraryBuilder.js +0 -217
  61. package/dist-node/builders/SdCliNgLibraryBuilder.js.map +0 -1
  62. package/dist-node/builders/SdCliPublisher.js +0 -129
  63. package/dist-node/builders/SdCliPublisher.js.map +0 -1
  64. package/dist-node/builders/SdCliServerBuilder.js +0 -452
  65. package/dist-node/builders/SdCliServerBuilder.js.map +0 -1
  66. package/dist-node/builders/SdCliTypescriptBuilder.js +0 -347
  67. package/dist-node/builders/SdCliTypescriptBuilder.js.map +0 -1
  68. package/dist-node/commons.js +0 -3
  69. package/dist-node/commons.js.map +0 -1
  70. package/dist-node/entry-points/SdCliLocalUpdater.js +0 -88
  71. package/dist-node/entry-points/SdCliLocalUpdater.js.map +0 -1
  72. package/dist-node/entry-points/SdCliPrepare.js +0 -56
  73. package/dist-node/entry-points/SdCliPrepare.js.map +0 -1
  74. package/dist-node/entry-points/SdCliProject.js +0 -302
  75. package/dist-node/entry-points/SdCliProject.js.map +0 -1
  76. package/dist-node/packages/SdCliClientPackage.js +0 -91
  77. package/dist-node/packages/SdCliClientPackage.js.map +0 -1
  78. package/dist-node/packages/SdCliLibraryPackage.js +0 -99
  79. package/dist-node/packages/SdCliLibraryPackage.js.map +0 -1
  80. package/dist-node/packages/SdCliPackageBase.js +0 -33
  81. package/dist-node/packages/SdCliPackageBase.js.map +0 -1
  82. package/dist-node/packages/SdCliServerPackage.js +0 -69
  83. package/dist-node/packages/SdCliServerPackage.js.map +0 -1
  84. package/dist-node/packages/SdCliUnknownPackage.js +0 -15
  85. package/dist-node/packages/SdCliUnknownPackage.js.map +0 -1
  86. package/dist-node/utils/SdCliFileCrypto.js +0 -76
  87. package/dist-node/utils/SdCliFileCrypto.js.map +0 -1
  88. package/dist-node/utils/SdProjectConfigUtil.js +0 -62
  89. package/dist-node/utils/SdProjectConfigUtil.js.map +0 -1
  90. package/dist-node/utils/SdTsDiagnosticUtil.js +0 -45
  91. package/dist-node/utils/SdTsDiagnosticUtil.js.map +0 -1
  92. package/dist-node/utils/SdWebpackUtil.js +0 -63
  93. package/dist-node/utils/SdWebpackUtil.js.map +0 -1
  94. package/dist-node/workers/client-ng-gen-worker.js +0 -57
  95. package/dist-node/workers/client-ng-gen-worker.js.map +0 -1
  96. package/dist-node/workers/lib-build-worker.js +0 -88
  97. package/dist-node/workers/lib-build-worker.js.map +0 -1
  98. package/dist-types/bin/sd-cli.d.ts +0 -3
  99. package/dist-types/bin/sd-cli.d.ts.map +0 -1
  100. package/dist-types/build-tools/SdCliCordova.d.ts +0 -15
  101. package/dist-types/build-tools/SdCliCordova.d.ts.map +0 -1
  102. package/dist-types/build-tools/SdCliIndexFileGenerator.d.ts +0 -13
  103. package/dist-types/build-tools/SdCliIndexFileGenerator.d.ts.map +0 -1
  104. package/dist-types/build-tools/SdCliNgModuleFilesGenerator.d.ts +0 -43
  105. package/dist-types/build-tools/SdCliNgModuleFilesGenerator.d.ts.map +0 -1
  106. package/dist-types/build-tools/metadata/SdAotMetadataReader.d.ts +0 -58
  107. package/dist-types/build-tools/metadata/SdAotMetadataReader.d.ts.map +0 -1
  108. package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts +0 -43
  109. package/dist-types/build-tools/metadata/SdIvyMetadataReader.d.ts.map +0 -1
  110. package/dist-types/build-tools/metadata/SdMetadataError.d.ts +0 -7
  111. package/dist-types/build-tools/metadata/SdMetadataError.d.ts.map +0 -1
  112. package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts +0 -59
  113. package/dist-types/build-tools/metadata/SdMyMetadataReader.d.ts.map +0 -1
  114. package/dist-types/builders/SdCliJavascriptLinter.d.ts +0 -14
  115. package/dist-types/builders/SdCliJavascriptLinter.d.ts.map +0 -1
  116. package/dist-types/builders/SdCliNgClientBuilder.d.ts +0 -29
  117. package/dist-types/builders/SdCliNgClientBuilder.d.ts.map +0 -1
  118. package/dist-types/builders/SdCliNgLibraryBuilder.d.ts +0 -30
  119. package/dist-types/builders/SdCliNgLibraryBuilder.d.ts.map +0 -1
  120. package/dist-types/builders/SdCliPublisher.d.ts +0 -9
  121. package/dist-types/builders/SdCliPublisher.d.ts.map +0 -1
  122. package/dist-types/builders/SdCliServerBuilder.d.ts +0 -31
  123. package/dist-types/builders/SdCliServerBuilder.d.ts.map +0 -1
  124. package/dist-types/builders/SdCliTypescriptBuilder.d.ts +0 -56
  125. package/dist-types/builders/SdCliTypescriptBuilder.d.ts.map +0 -1
  126. package/dist-types/commons.d.ts +0 -134
  127. package/dist-types/commons.d.ts.map +0 -1
  128. package/dist-types/entry-points/SdCliLocalUpdater.d.ts +0 -12
  129. package/dist-types/entry-points/SdCliLocalUpdater.d.ts.map +0 -1
  130. package/dist-types/entry-points/SdCliPrepare.d.ts +0 -6
  131. package/dist-types/entry-points/SdCliPrepare.d.ts.map +0 -1
  132. package/dist-types/entry-points/SdCliProject.d.ts +0 -32
  133. package/dist-types/entry-points/SdCliProject.d.ts.map +0 -1
  134. package/dist-types/packages/SdCliClientPackage.d.ts +0 -17
  135. package/dist-types/packages/SdCliClientPackage.d.ts.map +0 -1
  136. package/dist-types/packages/SdCliLibraryPackage.d.ts +0 -20
  137. package/dist-types/packages/SdCliLibraryPackage.d.ts.map +0 -1
  138. package/dist-types/packages/SdCliPackageBase.d.ts +0 -11
  139. package/dist-types/packages/SdCliPackageBase.d.ts.map +0 -1
  140. package/dist-types/packages/SdCliServerPackage.d.ts +0 -16
  141. package/dist-types/packages/SdCliServerPackage.d.ts.map +0 -1
  142. package/dist-types/packages/SdCliUnknownPackage.d.ts +0 -9
  143. package/dist-types/packages/SdCliUnknownPackage.d.ts.map +0 -1
  144. package/dist-types/utils/SdCliFileCrypto.d.ts +0 -8
  145. package/dist-types/utils/SdCliFileCrypto.d.ts.map +0 -1
  146. package/dist-types/utils/SdProjectConfigUtil.d.ts +0 -7
  147. package/dist-types/utils/SdProjectConfigUtil.d.ts.map +0 -1
  148. package/dist-types/utils/SdTsDiagnosticUtil.d.ts +0 -6
  149. package/dist-types/utils/SdTsDiagnosticUtil.d.ts.map +0 -1
  150. package/dist-types/utils/SdWebpackUtil.d.ts +0 -7
  151. package/dist-types/utils/SdWebpackUtil.d.ts.map +0 -1
  152. package/dist-types/workers/client-ng-gen-worker.d.ts +0 -2
  153. package/dist-types/workers/client-ng-gen-worker.d.ts.map +0 -1
  154. package/dist-types/workers/lib-build-worker.d.ts +0 -2
  155. package/dist-types/workers/lib-build-worker.d.ts.map +0 -1
  156. package/schema/schema.json +0 -447
  157. package/sd-tsconfig.node.json +0 -18
  158. package/src/build-tools/SdCliCordova.ts +0 -242
  159. package/src/build-tools/SdCliIndexFileGenerator.ts +0 -61
  160. package/src/build-tools/SdCliNgModuleFilesGenerator.ts +0 -894
  161. package/src/build-tools/metadata/SdAotMetadataReader.ts +0 -374
  162. package/src/build-tools/metadata/SdIvyMetadataReader.ts +0 -183
  163. package/src/build-tools/metadata/SdMetadataError.ts +0 -7
  164. package/src/build-tools/metadata/SdMyMetadataReader.ts +0 -407
  165. package/src/builders/SdCliJavascriptLinter.ts +0 -81
  166. package/src/builders/SdCliNgClientBuilder.ts +0 -793
  167. package/src/builders/SdCliNgLibraryBuilder.ts +0 -301
  168. package/src/builders/SdCliPublisher.ts +0 -144
  169. package/src/builders/SdCliServerBuilder.ts +0 -555
  170. package/src/builders/SdCliTypescriptBuilder.ts +0 -552
  171. package/src/entry-points/SdCliLocalUpdater.ts +0 -114
  172. package/src/entry-points/SdCliPrepare.ts +0 -104
  173. package/src/entry-points/SdCliProject.ts +0 -405
  174. package/src/packages/SdCliClientPackage.ts +0 -111
  175. package/src/packages/SdCliLibraryPackage.ts +0 -118
  176. package/src/packages/SdCliPackageBase.ts +0 -34
  177. package/src/packages/SdCliServerPackage.ts +0 -85
  178. package/src/packages/SdCliUnknownPackage.ts +0 -14
  179. package/src/utils/SdCliFileCrypto.ts +0 -87
  180. package/src/utils/SdCliUtils.ts +0 -56
  181. package/src/utils/SdProjectConfigUtil.ts +0 -145
  182. package/src/utils/SdTsDiagnosticUtil.ts +0 -46
  183. package/src/utils/SdWebpackUtil.ts +0 -71
  184. package/src/workers/client-ng-gen-worker.ts +0 -63
  185. package/src/workers/lib-build-worker.ts +0 -97
@@ -1,552 +0,0 @@
1
- import * as ts from "typescript";
2
- import { INpmConfig, ISdAutoIndexConfig, ISdPackageBuildResult, ITsconfig } from "../commons";
3
- import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
4
- import { NeverEntryError } from "@simplysm/sd-core-common";
5
- import { EventEmitter } from "events";
6
- import * as path from "path";
7
- import { SdTsDiagnosticUtil } from "../utils/SdTsDiagnosticUtil";
8
- import { ESLint, Linter } from "eslint";
9
- import { createHash } from "crypto";
10
- import { SdCliIndexFileGenerator } from "../build-tools/SdCliIndexFileGenerator";
11
- import ParserOptions = Linter.ParserOptions;
12
-
13
- export class SdCliTypescriptBuilder extends EventEmitter {
14
- protected readonly _logger: Logger;
15
-
16
- protected _tsconfig: ITsconfig;
17
- public readonly npmConfig: INpmConfig;
18
-
19
- protected _moduleResolutionCache?: ts.ModuleResolutionCache;
20
- protected _cacheCompilerHost?: ts.CompilerHost;
21
- protected _program?: ts.Program;
22
- protected _builder?: ts.BuilderProgram | ts.SemanticDiagnosticsBuilderProgram;
23
- protected readonly _fileCache = new Map<string, ITsBuildFileCache>();
24
-
25
- private readonly _indexFileGenerator?: SdCliIndexFileGenerator;
26
-
27
- private _watcher?: SdFsWatcher;
28
-
29
- public skipProcesses: string[];
30
-
31
- public constructor(public rootPath: string,
32
- public tsconfigFilePath: string,
33
- skipProcesses: ("emit" | "check" | "lint" | "genIndex")[],
34
- public autoIndexConfig: ISdAutoIndexConfig | undefined) {
35
- super();
36
- this.skipProcesses = skipProcesses;
37
-
38
- this._tsconfig = FsUtil.readJson(this.tsconfigFilePath);
39
-
40
- this.npmConfig = FsUtil.readJson(path.resolve(this.rootPath, "package.json"));
41
- this._logger = Logger.get(["simplysm", "sd-cli", this.constructor.name, this.npmConfig.name]);
42
-
43
- if (this.autoIndexConfig) {
44
- this._indexFileGenerator = new SdCliIndexFileGenerator(this.rootPath, this.autoIndexConfig);
45
- }
46
- }
47
-
48
- public on(event: "change", listener: () => void): this;
49
- public on(event: "complete", listener: (results: ISdPackageBuildResult[]) => void): this;
50
- public on(event: string | symbol, listener: (...args: any[]) => void): this {
51
- return super.on(event, listener);
52
- }
53
-
54
- public async buildAsync(watch: boolean): Promise<void> {
55
- this.emit("change");
56
-
57
- const parsedTsconfig = ts.parseJsonConfigFileContent(this._tsconfig, ts.sys, this.rootPath);
58
-
59
- // DIST 비우기
60
- await FsUtil.removeAsync(parsedTsconfig.options.outDir!);
61
- if (parsedTsconfig.options.declarationDir !== undefined) {
62
- await FsUtil.removeAsync(parsedTsconfig.options.declarationDir);
63
- }
64
-
65
- // 프로그램 리로드
66
- const buildResult: ISdPackageBuildResult[] = [];
67
- const reloadProgramResult = await this.reloadProgramAsync(watch);
68
- buildResult.push(...reloadProgramResult.result);
69
-
70
- // 자동생성할 소스파일들 생성 및 리로드 (index.ts등)
71
- const buildGenAdditionalResult = await this.generateAdditionalFilesAsync(reloadProgramResult.dirtyFilePaths, watch);
72
- buildResult.push(...buildGenAdditionalResult.result);
73
- reloadProgramResult.dirtyFilePaths.push(...buildGenAdditionalResult.dirtyFilePaths);
74
-
75
- // 빌드시, 빌드 수행하고 종료
76
- if (!watch) {
77
- const buildDoAllResults = await this.doAllAsync(reloadProgramResult.dirtyFilePaths.distinct());
78
- buildResult.push(...buildDoAllResults);
79
- this.emit("complete", buildResult.distinct());
80
- return;
81
- }
82
-
83
- // 변경감지용, 변경감지기 시작
84
- const resultMap = new Map<string, ISdPackageBuildResult[]>();
85
-
86
- const watchPaths = this.getWatchPaths();
87
- this._watcher = new SdFsWatcher();
88
- this._watcher
89
- .onChange(async (changeInfos) => {
90
- try {
91
- // 변경파일 중, 유효한 파일 추출
92
- const changedFilePaths = changeInfos
93
- .map((item) => PathUtil.posix(item.filePath))
94
- .filter((item) => path.basename(item).includes("."))
95
- .distinct();
96
- if (changedFilePaths.length === 0) return;
97
-
98
- // 변경감지 이벤트 발생
99
- this.emit("change");
100
-
101
- // 변경파일에 대한 프로그램 리로드
102
- const reloadChangedProgramResult = await this.reloadChangedProgramAsync(changedFilePaths, watch);
103
- const watchDirtyFilePaths = reloadChangedProgramResult.dirtyFilePaths;
104
- if (watchDirtyFilePaths.length === 0) {
105
- this.emit("complete", Array.from(resultMap.values()).mapMany());
106
- return;
107
- }
108
-
109
- // 변경파일에 대해 자동생성할 소스파일들 생성 및 리로드 (index.ts등)
110
- const watchGenAdditionalResult = await this.generateAdditionalFilesAsync([...changedFilePaths, ...watchDirtyFilePaths], watch);
111
- watchDirtyFilePaths.push(...watchGenAdditionalResult.dirtyFilePaths);
112
- watchDirtyFilePaths.distinctThis();
113
-
114
- // 변경파일에 대한 빌드 및 린트
115
- const watchDoAllResults = await this.doAllAsync(watchDirtyFilePaths);
116
-
117
- // 결과 MAP에서 DIRTY FILE 삭제
118
- resultMap.delete("undefined");
119
- for (const dirtyFilePath of watchDirtyFilePaths) {
120
- resultMap.delete(dirtyFilePath);
121
- }
122
-
123
- // 결과 MAP 구성
124
- const result = [...reloadChangedProgramResult.result, ...watchGenAdditionalResult.result, ...watchDoAllResults].distinct();
125
- for (const resultItem of result) {
126
- const posixFilePath = resultItem.filePath !== undefined ? PathUtil.posix(resultItem.filePath) : "undefined";
127
- const resultMapValue = resultMap.getOrCreate(posixFilePath, []);
128
- resultMapValue.push(resultItem);
129
- }
130
-
131
- this.emit("complete", Array.from(resultMap.values()).mapMany());
132
- }
133
- catch (err) {
134
- if (err instanceof Error) {
135
- this.emit("complete", [{
136
- filePath: undefined,
137
- severity: "error",
138
- message: err.stack ?? err.message
139
- }]);
140
- }
141
- else {
142
- throw err;
143
- }
144
- }
145
- })
146
- .watch(watchPaths);
147
-
148
- // 변경감지용, 최초 빌드
149
-
150
- // 빌드 및 린트
151
- const buildDoAllResults = await this.doAllAsync(reloadProgramResult.dirtyFilePaths.distinct());
152
- buildResult.push(...buildDoAllResults);
153
-
154
- // 결과 MAP 구성
155
- buildResult.distinctThis();
156
- for (const buildResultItem of buildResult) {
157
- const posixFilePath = buildResultItem.filePath !== undefined ? PathUtil.posix(buildResultItem.filePath) : "undefined";
158
- const resultMapValue = resultMap.getOrCreate(posixFilePath, []);
159
- resultMapValue.push(buildResultItem);
160
- resultMapValue.distinctThis();
161
- }
162
- this.emit("complete", Array.from(resultMap.values()).mapMany());
163
- }
164
-
165
- public async generateAdditionalFilesAsync(dirtyFilePaths: string[], watch: boolean): Promise<ITsGenResult> {
166
- return await this._generateIndexFileAsync(watch);
167
- }
168
-
169
- protected async _generateIndexFileAsync(watch: boolean): Promise<ITsGenResult> {
170
- this._logger.debug("index.ts 생성");
171
-
172
- const result: ITsGenResult = { dirtyFilePaths: [], result: [] };
173
-
174
- if (!this.skipProcesses.includes("genIndex") && this._indexFileGenerator && this.autoIndexConfig) {
175
- const generateResult = await this._indexFileGenerator.generateAsync();
176
- result.result.push(...generateResult.result);
177
- if (generateResult.changed) {
178
- const reloadChangedProgramResult = await this.reloadChangedProgramAsync([this._indexFileGenerator.indexFilePath], watch);
179
- result.dirtyFilePaths = reloadChangedProgramResult.dirtyFilePaths;
180
- result.result.push(...reloadChangedProgramResult.result);
181
- }
182
- }
183
-
184
- this._logger.debug("index.ts 생성 결과", result);
185
-
186
- return result;
187
- }
188
-
189
- protected _reloadWatchPaths(): void {
190
- if (this._watcher) {
191
- this._watcher.replaceWatchPaths(this.getWatchPaths());
192
- }
193
- }
194
-
195
- public async doAllAsync(dirtyFilePaths: string[]): Promise<ISdPackageBuildResult[]> {
196
- return (
197
- await Promise.all([
198
- this._runProgramAsync(dirtyFilePaths),
199
- this._lintAsync(dirtyFilePaths)
200
- ])
201
- ).mapMany();
202
- }
203
-
204
- protected async _lintAsync(dirtyFilePaths: string[]): Promise<ISdPackageBuildResult[]> {
205
- if (!this.skipProcesses.includes("lint")) {
206
- this._logger.debug("LINT");
207
-
208
- const linter = new ESLint({
209
- overrideConfig: {
210
- overrides: [
211
- {
212
- files: ["*.ts"],
213
- parserOptions: {
214
- program: this._program
215
- } as ParserOptions,
216
- settings: {
217
- "import/resolver": {
218
- typescript: {
219
- project: this.tsconfigFilePath
220
- }
221
- }
222
- }
223
- }
224
- ]
225
- }
226
- });
227
-
228
- const filePaths = await dirtyFilePaths
229
- .filterAsync(async (item) => (
230
- !item.includes("node_modules")
231
- && PathUtil.isChildPath(item, this.rootPath)
232
- && FsUtil.exists(item)
233
- && !FsUtil.isDirectory(item)
234
- && Boolean(this._program?.getSourceFiles().some((item1) => PathUtil.posix(item1.fileName) === PathUtil.posix(item)))
235
- && !await linter.isPathIgnored(item)
236
- ));
237
-
238
- const lintResults = await linter.lintFiles(filePaths);
239
-
240
- const result = lintResults.mapMany((report) => (
241
- report.messages.map((msg) => {
242
- const severity: "warning" | "error" = msg.severity === 1 ? "warning" : "error";
243
-
244
- return {
245
- type: "lint",
246
- filePath: report.filePath,
247
- severity,
248
- message: `${report.filePath}(${msg.line}, ${msg.column}): ${msg.ruleId ?? ""}: ${severity} ${msg.message}`
249
- };
250
- })
251
- ));
252
-
253
- this._logger.debug("LINT 결과", result);
254
-
255
- return result;
256
- }
257
-
258
- return [];
259
- }
260
-
261
- /*protected _getAllDependencies(filePath: string): string[] {
262
- this._logger.debug("파일 의존성 확인", filePath);
263
-
264
- const sourceFile = this._builder!.getSourceFile(filePath);
265
- if (!sourceFile) {
266
- this._logger.debug("파일 의존성 확인 결과", []);
267
- return [];
268
- }
269
- const result = [...this._builder!.getAllDependencies(sourceFile)];
270
-
271
- this._logger.debug("파일 의존성 확인 결과", result);
272
- return result;
273
- }*/
274
-
275
- public getWatchPaths(): string[] {
276
- // const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
277
-
278
- const result: string[] = [];
279
- for (const sourceFile of this._builder!.getSourceFiles()) {
280
- // result.push(sourceFile.fileName, ...this._getAllDependencies(sourceFile.fileName));
281
- result.push(sourceFile.fileName);
282
- }
283
- return result.map((item) => PathUtil.posix(path.dirname(item))).filter((item) => FsUtil.exists(item)).distinct();
284
- }
285
-
286
- /*protected _getRelativeFilePaths(filePath: string): string[] {
287
- const builder = this._builder as ts.EmitAndSemanticDiagnosticsBuilderProgram;
288
-
289
- const result: string[] = [];
290
- for (const sourceFile of builder.getSourceFiles()) {
291
- const dependencies = this._getAllDependencies(sourceFile.fileName);
292
- if (dependencies.includes(filePath)) {
293
- result.push(sourceFile.fileName);
294
- }
295
- }
296
-
297
- return result;
298
- }*/
299
-
300
- protected _deleteFileCaches(filePaths: string[]): void {
301
- for (const filePath of filePaths) {
302
- this._fileCache.delete(filePath);
303
- }
304
- }
305
-
306
- // eslint-disable-next-line @typescript-eslint/require-await
307
- protected async _runProgramAsync(dirtyFilePaths: string[]): Promise<ISdPackageBuildResult[]> {
308
- this._logger.debug("빌드");
309
-
310
- if (!this._builder) throw new NeverEntryError();
311
-
312
- const diagnostics: ts.Diagnostic[] = [];
313
-
314
- if (!this.skipProcesses.includes("check")) {
315
- diagnostics.push(
316
- ...this._builder.getOptionsDiagnostics(),
317
- ...this._builder.getGlobalDiagnostics()
318
- );
319
-
320
- for (const sourceFile of this._builder.getSourceFiles()) {
321
- /*for (const dirtyFilePath of dirtyFilePaths) {
322
- const sourceFile = this._builder.getSourceFile(dirtyFilePath);
323
- if (!sourceFile) continue;*/
324
-
325
- if (sourceFile.isDeclarationFile) continue;
326
-
327
- diagnostics.push(
328
- ...this._builder.getSyntacticDiagnostics(sourceFile),
329
- ...this._builder.getSemanticDiagnostics(sourceFile)
330
- );
331
- }
332
- }
333
-
334
- if (!this.skipProcesses.includes("emit")) {
335
- for (const dirtyFilePath of dirtyFilePaths) {
336
- const sourceFile = this._builder.getSourceFile(dirtyFilePath);
337
- if (!sourceFile) continue;
338
- if (sourceFile.isDeclarationFile) continue;
339
-
340
- this._builder.emit(sourceFile);
341
- }
342
- }
343
-
344
- const result = diagnostics.map((item) => SdTsDiagnosticUtil.convertDiagnosticsToResult(item)).filterExists();
345
-
346
- this._logger.debug("빌드", result);
347
-
348
- return result;
349
- }
350
-
351
- public async reloadChangedProgramAsync(changedFilePaths: string[], watch: boolean): Promise<{ dirtyFilePaths: string[]; result: ISdPackageBuildResult[] }> {
352
- this._logger.debug("변경 프로그램 리로드", changedFilePaths);
353
-
354
- // 캐시 삭제
355
- // const delCachePaths = changedFilePaths.mapMany((item) => [item, ...this._getRelativeFilePaths(item)]).distinct();
356
- // this._deleteFileCaches(delCachePaths);
357
- this._deleteFileCaches(changedFilePaths);
358
-
359
- // 프로그램 리로드
360
- const reloadProgramResult = await this.reloadProgramAsync(watch);
361
-
362
- // 변경사항 있을 경우, 변경감지중이면, 변경감지 경로 리로드
363
- if (reloadProgramResult.dirtyFilePaths.length > 0 && watch) {
364
- this._reloadWatchPaths();
365
- }
366
-
367
- /*dirtyFilePaths.push(...changedFilePaths.filter((key) => this._fileCache.has(key)));
368
- dirtyFilePaths.distinctThis();*/
369
-
370
- this._logger.debug("변경 프로그램 리로드 결과", reloadProgramResult.dirtyFilePaths);
371
- return reloadProgramResult;
372
- }
373
-
374
- public getParsedTsconfig(): ts.ParsedCommandLine {
375
- return ts.parseJsonConfigFileContent(this._tsconfig, ts.sys, this.rootPath);
376
- }
377
-
378
- public configProgram(parsedTsconfig: ts.ParsedCommandLine): void {
379
- this._program = ts.createProgram(
380
- parsedTsconfig.fileNames,
381
- parsedTsconfig.options,
382
- this._cacheCompilerHost,
383
- this._program
384
- );
385
- }
386
-
387
- public getSemanticDiagnosticsOfNextAffectedFiles(): string[] | undefined {
388
- const builder = this._builder as ts.SemanticDiagnosticsBuilderProgram;
389
- const result = builder.getSemanticDiagnosticsOfNextAffectedFile();
390
-
391
- if (result && "fileName" in result.affected) {
392
- return [result.affected.fileName];
393
- }
394
- if (!result) {
395
- return undefined;
396
- }
397
-
398
- return [];
399
- }
400
-
401
- public async reloadProgramAsync(watch: boolean): Promise<{ dirtyFilePaths: string[]; result: ISdPackageBuildResult[] }> {
402
- this._logger.debug("프로그램 리로드");
403
-
404
- const parsedTsconfig = this.getParsedTsconfig();
405
-
406
- this._moduleResolutionCache = ts.createModuleResolutionCache(this.rootPath, (s) => s, parsedTsconfig.options);
407
- this._cacheCompilerHost = await this._createCacheCompilerHostAsync(parsedTsconfig, this._moduleResolutionCache);
408
-
409
- this.configProgram(parsedTsconfig);
410
-
411
- const baseGetSourceFiles = this._program!.getSourceFiles;
412
- this._program!.getSourceFiles = function (...parameters) {
413
- const files: readonly (ts.SourceFile & { version?: string })[] = baseGetSourceFiles(...parameters);
414
-
415
- for (const file of files) {
416
- if (file.version === undefined) {
417
- file.version = createHash("sha256").update(file.text).digest("hex");
418
- }
419
- }
420
-
421
- return files;
422
- };
423
-
424
- if (watch) {
425
- if (this.skipProcesses.includes("emit")) {
426
- this._builder = ts.createSemanticDiagnosticsBuilderProgram(
427
- this._program!,
428
- this._cacheCompilerHost,
429
- this._builder as ts.SemanticDiagnosticsBuilderProgram
430
- );
431
- }
432
- else {
433
- this._builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(
434
- this._program!,
435
- this._cacheCompilerHost,
436
- this._builder as ts.EmitAndSemanticDiagnosticsBuilderProgram
437
- );
438
- }
439
-
440
- const buildResults: ISdPackageBuildResult[] = [];
441
- let seq = 0;
442
- const affectedFilePathSet = new Set<string>();
443
- while (true) {
444
- if (process.env.SD_CLI_LOGGER_SEVERITY === "DEBUG") {
445
- this._logger.debug(`프로그램 리로드 > 변경파일 목록구성: [SEQ: ${++seq}]`);
446
- }
447
-
448
- const affectedFilePaths = this.getSemanticDiagnosticsOfNextAffectedFiles();
449
-
450
- if (affectedFilePaths) {
451
- if (affectedFilePaths.length > 0) {
452
- affectedFilePathSet.adds(...affectedFilePaths.distinct());
453
- }
454
-
455
- if (process.env.SD_CLI_LOGGER_SEVERITY === "DEBUG") {
456
- this._logger.debug(`프로그램 리로드 > 변경파일 목록구성: [SEQ: ${seq}, SIZE:${affectedFilePathSet.size}]\n` + affectedFilePaths.map((item) => "- " + item).join("\n"));
457
- }
458
- }
459
- else {
460
- break;
461
- }
462
- }
463
-
464
- const dirtyFilePaths = Array.from(affectedFilePathSet.values());
465
-
466
- this._logger.debug("프로그램 리로드 결과", dirtyFilePaths);
467
-
468
- return { dirtyFilePaths, result: buildResults };
469
- }
470
- else {
471
- this._builder = ts.createAbstractBuilder(this._program!, this._cacheCompilerHost);
472
- const dirtyFilePaths = this._builder.getSourceFiles().map((item) => item.fileName).distinct();
473
-
474
- this._logger.debug("프로그램 리로드 결과", dirtyFilePaths);
475
-
476
- return { dirtyFilePaths, result: [] };
477
- }
478
- }
479
-
480
- // eslint-disable-next-line @typescript-eslint/require-await
481
- protected async _createCacheCompilerHostAsync(parsedTsconfig: ts.ParsedCommandLine, moduleResolutionCache: ts.ModuleResolutionCache): Promise<ts.CompilerHost> {
482
- const compilerHost = ts.createIncrementalCompilerHost(parsedTsconfig.options);
483
-
484
- const cacheCompilerHost = { ...compilerHost };
485
- cacheCompilerHost.fileExists = (fileName: string) => {
486
- const cache = this._fileCache.getOrCreate(PathUtil.posix(fileName), {});
487
- if (cache.exists === undefined) {
488
- cache.exists = compilerHost.fileExists.call(cacheCompilerHost, fileName);
489
- }
490
- return cache.exists;
491
- };
492
-
493
- cacheCompilerHost.getSourceFile = (fileName: string, languageVersion: ts.ScriptTarget) => {
494
- const cache = this._fileCache.getOrCreate(PathUtil.posix(fileName), {});
495
- if (!cache.sourceFile) {
496
- cache.sourceFile = compilerHost.getSourceFile.call(cacheCompilerHost, fileName, languageVersion);
497
- }
498
- return cache.sourceFile;
499
- };
500
-
501
- cacheCompilerHost.writeFile = (fileName: string,
502
- data: string,
503
- writeByteOrderMark: boolean,
504
- onError?: (message: string) => void,
505
- sourceFiles?: readonly ts.SourceFile[]) => {
506
- if (sourceFiles) {
507
- sourceFiles.forEach((source) => {
508
- const cache = this._fileCache.getOrCreate(PathUtil.posix(source.fileName), {});
509
- cache.distFilePaths = (cache.distFilePaths ?? []).concat([PathUtil.posix(fileName)]).distinct();
510
- });
511
- }
512
-
513
- if (!FsUtil.exists(fileName) || FsUtil.readFile(fileName) !== data) {
514
- compilerHost.writeFile.call(cacheCompilerHost, fileName, data, writeByteOrderMark, onError, sourceFiles);
515
- }
516
- };
517
-
518
- cacheCompilerHost.readFile = (fileName: string) => {
519
- const cache = this._fileCache.getOrCreate(PathUtil.posix(fileName), {});
520
- if (cache.content === undefined) {
521
- cache.content = compilerHost.readFile.call(cacheCompilerHost, fileName);
522
- }
523
- return cache.content;
524
- };
525
-
526
- cacheCompilerHost.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
527
- return moduleNames.map((moduleName) => {
528
- return ts.resolveModuleName(
529
- moduleName,
530
- containingFile,
531
- parsedTsconfig.options,
532
- compilerHost,
533
- moduleResolutionCache
534
- ).resolvedModule;
535
- });
536
- };
537
-
538
- return cacheCompilerHost;
539
- }
540
- }
541
-
542
- export interface ITsBuildFileCache {
543
- exists?: boolean;
544
- sourceFile?: ts.SourceFile;
545
- distFilePaths?: string[];
546
- content?: string;
547
- }
548
-
549
- export interface ITsGenResult {
550
- dirtyFilePaths: string[];
551
- result: ISdPackageBuildResult[];
552
- }
@@ -1,114 +0,0 @@
1
- import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
2
- import { SdProjectConfigUtil } from "../utils/SdProjectConfigUtil";
3
- import * as path from "path";
4
-
5
- export class SdCliLocalUpdater {
6
- private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
7
-
8
- public constructor(private readonly _rootPath: string) {
9
- }
10
-
11
- public async localUpdateAsync(watch: boolean, opt?: { config?: string }): Promise<void> {
12
- this._logger.debug("프로젝트 설정 가져오기...");
13
- const config = await SdProjectConfigUtil.loadConfigAsync(this._rootPath, watch, undefined, opt?.config);
14
-
15
- if (config.localUpdates) {
16
- const updatePathInfos = await this._getUpdatePathInfosAsync(config.localUpdates);
17
-
18
- if (watch) {
19
- const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
20
-
21
- const watcher = new SdFsWatcher();
22
- watcher
23
- .onChange(async (changedInfos) => {
24
- this._logger.log("로컬 라이브러리 변경감지...");
25
-
26
- const watchPaths2 = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
27
- watcher.replaceWatchPaths(watchPaths2);
28
-
29
- const changedFilePaths = changedInfos.map((item) => item.filePath).distinct();
30
- for (const changedFilePath of changedFilePaths) {
31
- if (changedFilePath.includes("node_modules") || changedFilePath.endsWith("package.json")) {
32
- continue;
33
- }
34
-
35
- const currentUpdatePathInfos = updatePathInfos.filter((item) => PathUtil.isChildPath(changedFilePath, item.source));
36
- const targetFilePaths = currentUpdatePathInfos.map((item) => path.resolve(item.target, path.relative(item.source, changedFilePath)));
37
-
38
- if (FsUtil.exists(changedFilePath)) {
39
- this._logger.debug(`변경파일감지(복사): ${changedFilePath}`);
40
- for (const targetFilePath of targetFilePaths) {
41
- await FsUtil.copyAsync(changedFilePath, targetFilePath);
42
- }
43
- }
44
- /*else {
45
- this._logger.debug(`변경파일감지(삭제): ${changedFilePath}`);
46
- for (const targetFilePath of targetFilePaths) {
47
- await FsUtil.removeAsync(targetFilePath);
48
- }
49
- }*/
50
- }
51
-
52
- this._logger.info("로컬 라이브러리 변경감지 및 복사 완료");
53
- })
54
- .watch(watchPaths);
55
- }
56
- else {
57
- this._logger.log("로컬 라이브러리 업데이트 시작...");
58
- for (const updatePathInfo of updatePathInfos) {
59
- await this._runAsync(updatePathInfo);
60
- }
61
- this._logger.info("로컬 라이브러리 업데이트 완료");
62
- }
63
- }
64
- }
65
-
66
- private async _runAsync(updatePath: { source: string; target: string }): Promise<void> {
67
- if (!FsUtil.exists(updatePath.source)) {
68
- this._logger.warn(`소스경로를 찾을 수 없어 무시됩니다(${updatePath.source})`);
69
- return;
70
- }
71
-
72
- // 소스경로에서 대상경로로 파일 복사
73
- await FsUtil.copyAsync(updatePath.source, updatePath.target, (src) => {
74
- return !src.includes("node_modules") && !src.endsWith("package.json");
75
- });
76
- }
77
-
78
- protected async _getWatchPathsAsync(updateSourcePath: string): Promise<string[]> {
79
- return (await FsUtil.globAsync(path.resolve(updateSourcePath, "**")))
80
- .filter((item) => (
81
- !item.includes("node_modules")
82
- && FsUtil.exists(item)
83
- && FsUtil.isDirectory(item)
84
- ));
85
- }
86
-
87
- private async _getUpdatePathInfosAsync(record: Record<string, string>): Promise<{ source: string; target: string }[]> {
88
- return (
89
- await Object.keys(record).parallelAsync(async (packageGlobPath) => {
90
- // "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
91
- const targetPaths = await FsUtil.globAsync(path.resolve(process.cwd(), "node_modules", packageGlobPath));
92
-
93
- return targetPaths
94
- .map((targetPath) => {
95
- // 대상의 명칭 추출
96
- const regexpText = packageGlobPath.replace(/[\\/.*]/g, (item) => (
97
- item === "/" ? "[\\\\\\/]"
98
- : item === "." ? "\\."
99
- : item === "*" ? "(.*)"
100
- : item
101
- ));
102
- const targetNameMatch = new RegExp(regexpText).exec(targetPath);
103
- if (!targetNameMatch || typeof targetNameMatch[1] === "undefined") return undefined;
104
- const targetName = targetNameMatch[1];
105
-
106
- // 가져올 소스 경로 추출
107
- const sourcePath = path.resolve(record[packageGlobPath].replace(/\*/g, targetName));
108
- return { source: sourcePath, target: targetPath };
109
- })
110
- .filterExists();
111
- })
112
- ).mapMany();
113
- }
114
- }