@simplysm/sd-cli 7.0.237 → 7.0.241
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.
- package/dist/bin/sd-cli.mjs +1 -1
- package/dist/build-tool/SdCliCordova.d.ts +1 -1
- package/dist/build-tool/SdCliCordova.mjs +35 -16
- package/dist/builder/SdCliClientBuilder.mjs +35 -22
- package/dist/entry-points/SdCliLocalUpdate.mjs +2 -2
- package/dist/entry-points/SdCliWorkspace.mjs +2 -2
- package/dist/worker/build-worker.mjs +1 -1
- package/lib/cordova-entry.js +22 -0
- package/package.json +6 -6
- package/src/bin/sd-cli.ts +1 -1
- package/src/build-tool/SdCliCordova.ts +40 -16
- package/src/builder/SdCliClientBuilder.ts +35 -21
- package/src/entry-points/SdCliLocalUpdate.ts +121 -121
- package/src/entry-points/SdCliWorkspace.ts +455 -455
- package/src/worker/build-worker.ts +73 -74
- package/tsconfig.json +38 -38
|
@@ -64,4 +64,4 @@ else {
|
|
|
64
64
|
process.exit(1);
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtd29ya2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmtlci9idWlsZC13b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDakUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDeEUsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd2RCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsS0FBSyxPQUFPLEVBQUU7SUFDckQsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNmLE9BQU8sRUFBRTtZQUNQLEtBQUssRUFBRSxjQUFjLENBQUMsS0FBSztTQUM1QjtLQUNGLENBQUMsQ0FBQztDQUNKO0tBQ0k7SUFDSCxNQUFNLENBQUMsU0FBUyxDQUFDO1FBQ2YsR0FBRyxFQUFFLElBQUk7S0FDVixDQUFDLENBQUM7Q0FDSjtBQUVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUF3QixDQUFDO0FBQ3BELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakMsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUF3QixDQUFDO0FBQ3pFLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FB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
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
const script = document.createElement("script");
|
|
4
|
+
script.onload = () => {
|
|
5
|
+
console.log("cordova.js Loaded");
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
9
|
+
script.src = "cordova.js";
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
if (navigator.userAgent.toLowerCase().indexOf("android") !== -1) {
|
|
13
|
+
script.src = "cordova-android/cordova.js";
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
script.src = "cordova-browser/cordova.js";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
script.defer = true;
|
|
21
|
+
|
|
22
|
+
document.body.appendChild(script);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/sd-cli",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.241",
|
|
4
4
|
"description": "심플리즘 패키지 - CLI",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"repository": {
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"@babel/parser": "^7.17.0",
|
|
24
24
|
"@babel/types": "^7.17.0",
|
|
25
25
|
"@ngtools/webpack": "^13.2.2",
|
|
26
|
-
"@simplysm/sd-core-common": "7.0.
|
|
27
|
-
"@simplysm/sd-core-node": "7.0.
|
|
28
|
-
"@simplysm/sd-service-common": "7.0.
|
|
29
|
-
"@simplysm/sd-service-server": "7.0.
|
|
30
|
-
"@simplysm/sd-storage": "7.0.
|
|
26
|
+
"@simplysm/sd-core-common": "7.0.241",
|
|
27
|
+
"@simplysm/sd-core-node": "7.0.241",
|
|
28
|
+
"@simplysm/sd-service-common": "7.0.241",
|
|
29
|
+
"@simplysm/sd-service-server": "7.0.241",
|
|
30
|
+
"@simplysm/sd-storage": "7.0.241",
|
|
31
31
|
"browserslist": "^4.19.1",
|
|
32
32
|
"chokidar": "^3.5.3",
|
|
33
33
|
"connect": "^3.7.0",
|
package/src/bin/sd-cli.ts
CHANGED
|
@@ -62,25 +62,40 @@ export class SdCliCordova {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
//
|
|
65
|
+
// 설치된 미사용 플러그인 삭제
|
|
66
66
|
const pluginsFetch = FsUtil.exists(path.resolve(this.cordovaPath, "plugins/fetch.json"))
|
|
67
67
|
? await FsUtil.readJsonAsync(path.resolve(this.cordovaPath, "plugins/fetch.json"))
|
|
68
68
|
: undefined;
|
|
69
|
-
const
|
|
69
|
+
const alreadyPluginIds = pluginsFetch != undefined
|
|
70
70
|
? Object.values(pluginsFetch)
|
|
71
|
-
.map((item: any) => (item.source.id !== undefined ? item.source.id
|
|
71
|
+
.map((item: any) => (item.source.id !== undefined ? item.source.id : item.source.url))
|
|
72
72
|
: [];
|
|
73
|
+
const usePlugins = ["cordova-plugin-ionic-webview", ...this._config.plugins ?? []].distinct();
|
|
74
|
+
|
|
75
|
+
for (const alreadyPluginId of alreadyPluginIds) {
|
|
76
|
+
let hasPlugin = false;
|
|
77
|
+
for (const usePlugin of usePlugins) {
|
|
78
|
+
if (
|
|
79
|
+
(usePlugin.includes("@") && alreadyPluginId === usePlugin) ||
|
|
80
|
+
(!usePlugin.includes("@") && alreadyPluginId.replace(/@.*$/, "") === usePlugin)
|
|
81
|
+
) {
|
|
82
|
+
hasPlugin = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
await this._execAsync(`${this._binPath} plugin add ${plugin}`, this.cordovaPath);
|
|
87
|
+
if (!hasPlugin) {
|
|
88
|
+
await this._execAsync(`${this._binPath} plugin remove ${alreadyPluginId.replace(/@.*$/, "")}`, this.cordovaPath);
|
|
77
89
|
}
|
|
78
90
|
}
|
|
79
91
|
|
|
80
|
-
//
|
|
81
|
-
for (const
|
|
82
|
-
if (
|
|
83
|
-
|
|
92
|
+
// 미설치 플러그인들 설치
|
|
93
|
+
for (const usePlugin of usePlugins) {
|
|
94
|
+
if (
|
|
95
|
+
(usePlugin.includes("@") && !alreadyPluginIds.includes(usePlugin)) ||
|
|
96
|
+
(!usePlugin.includes("@") && !alreadyPluginIds.map((alreadyPluginId) => alreadyPluginId.replace(/@.*$/, "")).includes(usePlugin))
|
|
97
|
+
) {
|
|
98
|
+
await this._execAsync(`${this._binPath} plugin add ${usePlugin}`, this.cordovaPath);
|
|
84
99
|
}
|
|
85
100
|
}
|
|
86
101
|
|
|
@@ -93,6 +108,8 @@ export class SdCliCordova {
|
|
|
93
108
|
}
|
|
94
109
|
else {
|
|
95
110
|
await FsUtil.removeAsync(path.resolve(this.cordovaPath, "android.keystore"));
|
|
111
|
+
// SIGN을 안쓸경우 아래 파일이 생성되어 있으면 오류남
|
|
112
|
+
await FsUtil.removeAsync(path.resolve(this.cordovaPath, "platforms/android/release-signing.properties"));
|
|
96
113
|
}
|
|
97
114
|
|
|
98
115
|
// 빌드 옵션 파일 생성
|
|
@@ -145,7 +162,11 @@ export class SdCliCordova {
|
|
|
145
162
|
}
|
|
146
163
|
|
|
147
164
|
// CONFIG: 접근허용 세팅
|
|
148
|
-
configXml["widget"]["
|
|
165
|
+
configXml["widget"]["access"] = [{ "$": { "origin": "*" } }];
|
|
166
|
+
configXml["widget"]["allow-navigation"] = [{ "$": { "href": "*" } }];
|
|
167
|
+
configXml["widget"]["allow-intent"] = [{ "$": { "href": "*" } }];
|
|
168
|
+
configXml["widget"]["preference"] = [{ "$": { "name": "MixedContentMode", "value": "0" } }];
|
|
169
|
+
// configXml["widget"]["preference"] = [{ "$": { "name": "AndroidPersistentFileLocation", "value": "Compatibility" } }];
|
|
149
170
|
|
|
150
171
|
// CONFIG: ANDROID usesCleartextTraffic 설정
|
|
151
172
|
if (this._config.target?.android) {
|
|
@@ -212,7 +233,7 @@ export class SdCliCordova {
|
|
|
212
233
|
});
|
|
213
234
|
for (const resultFile of resultFiles) {
|
|
214
235
|
const contentBuffer = await FsUtil.readFileBufferAsync(resultFile);
|
|
215
|
-
const relativePath = path.relative(path.resolve(this.cordovaPath, "www"), resultFile);
|
|
236
|
+
const relativePath = path.relative(path.resolve(this.cordovaPath, "platforms", "android", "app", "src", "main", "assets", "www"), resultFile);
|
|
216
237
|
zip.file("/" + relativePath, contentBuffer);
|
|
217
238
|
}
|
|
218
239
|
|
|
@@ -223,14 +244,17 @@ export class SdCliCordova {
|
|
|
223
244
|
}
|
|
224
245
|
}
|
|
225
246
|
|
|
226
|
-
public static async runWebviewOnDeviceAsync(rootPath: string, platform: "browser" | "android", pkgName: string, url
|
|
247
|
+
public static async runWebviewOnDeviceAsync(rootPath: string, platform: "browser" | "android", pkgName: string, url?: string): Promise<void> {
|
|
227
248
|
const cordovaPath = path.resolve(rootPath, `packages/${pkgName}/.cordova/`);
|
|
228
249
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
250
|
+
if (url !== undefined) {
|
|
251
|
+
await FsUtil.removeAsync(path.resolve(cordovaPath, "www"));
|
|
252
|
+
await FsUtil.mkdirsAsync(path.resolve(cordovaPath, "www"));
|
|
253
|
+
await FsUtil.writeFileAsync(path.resolve(cordovaPath, "www/index.html"), `'${url}'로 이동중... <script>setTimeout(function () {window.location.href = "${url.replace(/\/$/, "")}/${pkgName}/cordova/"}, 3000);</script>`.trim());
|
|
254
|
+
}
|
|
232
255
|
|
|
233
256
|
const binPath = path.resolve(process.cwd(), "node_modules/.bin/cordova.cmd");
|
|
257
|
+
// await SdProcess.spawnAsync(`${binPath} build ${platform}`, { cwd: cordovaPath }, true);
|
|
234
258
|
await SdProcess.spawnAsync(`${binPath} run ${platform} --device`, { cwd: cordovaPath }, true);
|
|
235
259
|
}
|
|
236
260
|
}
|
|
@@ -31,6 +31,8 @@ import { SdCliCordova } from "../build-tool/SdCliCordova";
|
|
|
31
31
|
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
32
32
|
import electronBuilder from "electron-builder";
|
|
33
33
|
import LintResult = ESLint.LintResult;
|
|
34
|
+
import { fileURLToPath } from "url";
|
|
35
|
+
import { Entrypoint } from "@angular-devkit/build-angular/src/utils/index-file/augment-index-html";
|
|
34
36
|
|
|
35
37
|
export class SdCliClientBuilder extends EventEmitter {
|
|
36
38
|
private readonly _logger: Logger;
|
|
@@ -165,13 +167,17 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
165
167
|
|
|
166
168
|
public async buildAsync(): Promise<ISdCliPackageBuildResult[]> {
|
|
167
169
|
// DIST 비우기
|
|
170
|
+
this._logger.debug("removeAsync:1");
|
|
168
171
|
await FsUtil.removeAsync(path.resolve(this._rootPath, ".electron"));
|
|
172
|
+
this._logger.debug("removeAsync:2");
|
|
169
173
|
await FsUtil.removeAsync(this._parsedTsconfig.options.outDir!);
|
|
170
174
|
|
|
171
175
|
// NgModule 생성
|
|
176
|
+
this._logger.debug("ngModule");
|
|
172
177
|
await this._ngModuleGenerator.runAsync();
|
|
173
178
|
|
|
174
179
|
// CORDOVA 초기화
|
|
180
|
+
this._logger.debug("Cordova");
|
|
175
181
|
if (this._cordova) {
|
|
176
182
|
this._logger.debug("CORDOVA 구성...");
|
|
177
183
|
await this._cordova.initializeAsync();
|
|
@@ -213,7 +219,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
213
219
|
// CORDOVA 빌드
|
|
214
220
|
if (this._cordova) {
|
|
215
221
|
this._logger.debug("CORDOVA 빌드...");
|
|
216
|
-
await this._cordova.buildAsync(
|
|
222
|
+
await this._cordova.buildAsync(this._parsedTsconfig.options.outDir!);
|
|
217
223
|
}
|
|
218
224
|
|
|
219
225
|
// ELECTRON
|
|
@@ -356,7 +362,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
356
362
|
entry: {
|
|
357
363
|
main: [mainFilePath],
|
|
358
364
|
...FsUtil.exists(polyfillsFilePath) ? { polyfills: [polyfillsFilePath] } : {},
|
|
359
|
-
...FsUtil.exists(stylesFilePath) ? { styles: [stylesFilePath] } : {}
|
|
365
|
+
...FsUtil.exists(stylesFilePath) ? { styles: [stylesFilePath] } : {},
|
|
366
|
+
...builderType === "cordova" ? { "cordova-entry": path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../lib/cordova-entry.js`) } : {}
|
|
360
367
|
},
|
|
361
368
|
output: {
|
|
362
369
|
uniqueName: pkgKey,
|
|
@@ -385,19 +392,19 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
385
392
|
experiments: { backCompat: false, syncWebAssembly: true, asyncWebAssembly: true },
|
|
386
393
|
infrastructureLogging: { level: "error" },
|
|
387
394
|
stats: "errors-warnings",
|
|
388
|
-
cache: {
|
|
389
|
-
type: "filesystem",
|
|
390
|
-
profile: watch ? undefined : false,
|
|
391
|
-
cacheDirectory: path.resolve(cacheBasePath, "angular-webpack"),
|
|
392
|
-
maxMemoryGenerations: 1,
|
|
393
|
-
name: createHash("sha1")
|
|
394
|
-
.update(workspacePkgLockContent)
|
|
395
|
-
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
396
|
-
.update(JSON.stringify(this._config))
|
|
397
|
-
.update(watch.toString())
|
|
398
|
-
.digest("hex")
|
|
399
|
-
},
|
|
400
395
|
...watch ? {
|
|
396
|
+
cache: {
|
|
397
|
+
type: "filesystem",
|
|
398
|
+
profile: undefined,
|
|
399
|
+
cacheDirectory: path.resolve(cacheBasePath, "angular-webpack"),
|
|
400
|
+
maxMemoryGenerations: 1,
|
|
401
|
+
name: createHash("sha1")
|
|
402
|
+
.update(workspacePkgLockContent)
|
|
403
|
+
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
404
|
+
.update(JSON.stringify(this._config))
|
|
405
|
+
.update(watch.toString())
|
|
406
|
+
.digest("hex")
|
|
407
|
+
},
|
|
401
408
|
snapshot: {
|
|
402
409
|
immutablePaths: internalModuleCachePaths,
|
|
403
410
|
managedPaths: internalModuleCachePaths
|
|
@@ -477,7 +484,9 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
477
484
|
{
|
|
478
485
|
loader: "@angular-devkit/build-angular/src/babel/webpack-loader",
|
|
479
486
|
options: {
|
|
480
|
-
|
|
487
|
+
...watch ? {
|
|
488
|
+
cacheDirectory: path.resolve(cacheBasePath, "babel-webpack"),
|
|
489
|
+
} : {},
|
|
481
490
|
scriptTarget: ts.ScriptTarget.ES2017,
|
|
482
491
|
aot: true,
|
|
483
492
|
optimize: !watch,
|
|
@@ -675,15 +684,20 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
675
684
|
["polyfills", true],
|
|
676
685
|
["styles", false],
|
|
677
686
|
["vendor", true],
|
|
678
|
-
["main", true]
|
|
687
|
+
["main", true],
|
|
688
|
+
...builderType === "cordova" ? [
|
|
689
|
+
["cordova-entry", true] as Entrypoint
|
|
690
|
+
] : []
|
|
679
691
|
],
|
|
680
692
|
deployUrl: undefined,
|
|
681
693
|
sri: false,
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
694
|
+
...watch ? {
|
|
695
|
+
cache: {
|
|
696
|
+
enabled: true,
|
|
697
|
+
basePath: cacheBasePath,
|
|
698
|
+
path: path.resolve(cacheBasePath, "index-webpack")
|
|
699
|
+
}
|
|
700
|
+
} : {},
|
|
687
701
|
postTransform: undefined,
|
|
688
702
|
optimization: {
|
|
689
703
|
scripts: !watch,
|
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
|
|
2
|
-
import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
|
-
export class SdCliLocalUpdate {
|
|
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 runAsync(opt: { confFileRelPath: string }): Promise<void> {
|
|
12
|
-
this._logger.debug("프로젝트 설정 가져오기...");
|
|
13
|
-
const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
|
|
14
|
-
if (!conf.localUpdates) return;
|
|
15
|
-
|
|
16
|
-
const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
|
|
17
|
-
this._logger.debug("로컬 업데이트 구성");
|
|
18
|
-
|
|
19
|
-
this._logger.log("로컬 라이브러리 업데이트 시작...");
|
|
20
|
-
for (const updatePathInfo of updatePathInfos) {
|
|
21
|
-
if (!FsUtil.exists(updatePathInfo.source)) {
|
|
22
|
-
this._logger.warn(`소스경로를 찾을 수 없어 무시됩니다(${updatePathInfo.source})`);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 소스경로에서 대상경로로 파일 복사
|
|
27
|
-
await FsUtil.copyAsync(updatePathInfo.source, updatePathInfo.target, (src) => {
|
|
28
|
-
return !src.includes("node_modules") && !src.endsWith("package.json");
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
this._logger.info("로컬 라이브러리 업데이트 완료");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public async watchAsync(opt: { confFileRelPath: string }): Promise<void> {
|
|
35
|
-
this._logger.debug("프로젝트 설정 가져오기...");
|
|
36
|
-
const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
|
|
37
|
-
if (!conf.localUpdates) return;
|
|
38
|
-
|
|
39
|
-
const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
|
|
40
|
-
this._logger.debug("로컬 업데이트 구성");
|
|
41
|
-
|
|
42
|
-
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
43
|
-
|
|
44
|
-
const watcher = SdFsWatcher.watch(watchPaths);
|
|
45
|
-
watcher.onChange({ delay: 1000 }, async (changedInfos) => {
|
|
46
|
-
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
47
|
-
if (changeFilePaths.length === 0) return;
|
|
48
|
-
|
|
49
|
-
this._logger.log("로컬 라이브러리 변경감지...");
|
|
50
|
-
for (const changedFilePath of changeFilePaths) {
|
|
51
|
-
if (!FsUtil.exists(changedFilePath)) continue;
|
|
52
|
-
|
|
53
|
-
for (const updatePathInfo of updatePathInfos) {
|
|
54
|
-
if (!PathUtil.isChildPath(changedFilePath, updatePathInfo.source)) continue;
|
|
55
|
-
|
|
56
|
-
const sourceRelPath = path.relative(updatePathInfo.source, changedFilePath);
|
|
57
|
-
if (sourceRelPath.includes("node_modules")) continue;
|
|
58
|
-
if (sourceRelPath.includes("package.json")) continue;
|
|
59
|
-
|
|
60
|
-
const targetFilePath = path.resolve(updatePathInfo.target, sourceRelPath);
|
|
61
|
-
|
|
62
|
-
this._logger.debug(`변경파일감지(복사): ${changedFilePath} => ${targetFilePath}`);
|
|
63
|
-
await FsUtil.copyAsync(changedFilePath, targetFilePath);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const watchWatchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
68
|
-
watcher.add(watchWatchPaths);
|
|
69
|
-
|
|
70
|
-
this._logger.info("로컬 라이브러리 복사 완료");
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private async _getUpdatePathInfosAsync(record: Record<string, string>): Promise<IUpdatePathInfo[]> {
|
|
75
|
-
const result: IUpdatePathInfo[] = [];
|
|
76
|
-
for (const pkgGlobPath of Object.keys(record)) {
|
|
77
|
-
// "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
|
|
78
|
-
const targetPaths = [
|
|
79
|
-
...await FsUtil.globAsync(path.resolve(this._rootPath, "node_modules", pkgGlobPath)),
|
|
80
|
-
...await FsUtil.globAsync(path.resolve(this._rootPath, "packages", "*", "node_modules", pkgGlobPath))
|
|
81
|
-
];
|
|
82
|
-
|
|
83
|
-
result.push(
|
|
84
|
-
...targetPaths
|
|
85
|
-
.map((targetPath) => {
|
|
86
|
-
// 대상의 명칭 추출
|
|
87
|
-
const regexpText = pkgGlobPath.replace(/[\\/.*]/g, (item) => (
|
|
88
|
-
item === "/" ? "[\\\\\\/]"
|
|
89
|
-
: item === "." ? "\\."
|
|
90
|
-
: item === "*" ? "(.*)"
|
|
91
|
-
: item
|
|
92
|
-
));
|
|
93
|
-
const targetNameMatch = new RegExp(regexpText).exec(targetPath);
|
|
94
|
-
if (!targetNameMatch || typeof targetNameMatch[1] === "undefined") return undefined;
|
|
95
|
-
const targetName = targetNameMatch[1];
|
|
96
|
-
|
|
97
|
-
// 가져올 소스 경로 추출
|
|
98
|
-
const sourcePath = path.resolve(record[pkgGlobPath].replace(/\*/g, targetName));
|
|
99
|
-
return { source: sourcePath, target: targetPath };
|
|
100
|
-
})
|
|
101
|
-
.filterExists()
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
protected async _getWatchPathsAsync(sourcePath: string): Promise<string[]> {
|
|
109
|
-
return await FsUtil.globAsync(path.resolve(sourcePath, "**"), {
|
|
110
|
-
ignore: [
|
|
111
|
-
"**/node_modules/**",
|
|
112
|
-
"**/package.json"
|
|
113
|
-
]
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
interface IUpdatePathInfo {
|
|
119
|
-
source: string;
|
|
120
|
-
target: string;
|
|
121
|
-
}
|
|
1
|
+
import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
|
|
2
|
+
import { FsUtil, Logger, PathUtil, SdFsWatcher } from "@simplysm/sd-core-node";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
export class SdCliLocalUpdate {
|
|
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 runAsync(opt: { confFileRelPath: string }): Promise<void> {
|
|
12
|
+
this._logger.debug("프로젝트 설정 가져오기...");
|
|
13
|
+
const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
|
|
14
|
+
if (!conf.localUpdates) return;
|
|
15
|
+
|
|
16
|
+
const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
|
|
17
|
+
this._logger.debug("로컬 업데이트 구성", updatePathInfos);
|
|
18
|
+
|
|
19
|
+
this._logger.log("로컬 라이브러리 업데이트 시작...");
|
|
20
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
21
|
+
if (!FsUtil.exists(updatePathInfo.source)) {
|
|
22
|
+
this._logger.warn(`소스경로를 찾을 수 없어 무시됩니다(${updatePathInfo.source})`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 소스경로에서 대상경로로 파일 복사
|
|
27
|
+
await FsUtil.copyAsync(updatePathInfo.source, updatePathInfo.target, (src) => {
|
|
28
|
+
return !src.includes("node_modules") && !src.endsWith("package.json");
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
this._logger.info("로컬 라이브러리 업데이트 완료");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async watchAsync(opt: { confFileRelPath: string }): Promise<void> {
|
|
35
|
+
this._logger.debug("프로젝트 설정 가져오기...");
|
|
36
|
+
const conf = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), false);
|
|
37
|
+
if (!conf.localUpdates) return;
|
|
38
|
+
|
|
39
|
+
const updatePathInfos = await this._getUpdatePathInfosAsync(conf.localUpdates);
|
|
40
|
+
this._logger.debug("로컬 업데이트 구성");
|
|
41
|
+
|
|
42
|
+
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
43
|
+
|
|
44
|
+
const watcher = SdFsWatcher.watch(watchPaths);
|
|
45
|
+
watcher.onChange({ delay: 1000 }, async (changedInfos) => {
|
|
46
|
+
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
47
|
+
if (changeFilePaths.length === 0) return;
|
|
48
|
+
|
|
49
|
+
this._logger.log("로컬 라이브러리 변경감지...");
|
|
50
|
+
for (const changedFilePath of changeFilePaths) {
|
|
51
|
+
if (!FsUtil.exists(changedFilePath)) continue;
|
|
52
|
+
|
|
53
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
54
|
+
if (!PathUtil.isChildPath(changedFilePath, updatePathInfo.source)) continue;
|
|
55
|
+
|
|
56
|
+
const sourceRelPath = path.relative(updatePathInfo.source, changedFilePath);
|
|
57
|
+
if (sourceRelPath.includes("node_modules")) continue;
|
|
58
|
+
if (sourceRelPath.includes("package.json")) continue;
|
|
59
|
+
|
|
60
|
+
const targetFilePath = path.resolve(updatePathInfo.target, sourceRelPath);
|
|
61
|
+
|
|
62
|
+
this._logger.debug(`변경파일감지(복사): ${changedFilePath} => ${targetFilePath}`);
|
|
63
|
+
await FsUtil.copyAsync(changedFilePath, targetFilePath);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const watchWatchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
68
|
+
watcher.add(watchWatchPaths);
|
|
69
|
+
|
|
70
|
+
this._logger.info("로컬 라이브러리 복사 완료");
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private async _getUpdatePathInfosAsync(record: Record<string, string>): Promise<IUpdatePathInfo[]> {
|
|
75
|
+
const result: IUpdatePathInfo[] = [];
|
|
76
|
+
for (const pkgGlobPath of Object.keys(record)) {
|
|
77
|
+
// "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
|
|
78
|
+
const targetPaths = [
|
|
79
|
+
...await FsUtil.globAsync(path.resolve(this._rootPath, "node_modules", pkgGlobPath)),
|
|
80
|
+
...await FsUtil.globAsync(path.resolve(this._rootPath, "packages", "*", "node_modules", pkgGlobPath))
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
result.push(
|
|
84
|
+
...targetPaths
|
|
85
|
+
.map((targetPath) => {
|
|
86
|
+
// 대상의 명칭 추출
|
|
87
|
+
const regexpText = pkgGlobPath.replace(/[\\/.*]/g, (item) => (
|
|
88
|
+
item === "/" ? "[\\\\\\/]"
|
|
89
|
+
: item === "." ? "\\."
|
|
90
|
+
: item === "*" ? "(.*)"
|
|
91
|
+
: item
|
|
92
|
+
));
|
|
93
|
+
const targetNameMatch = new RegExp(regexpText).exec(targetPath);
|
|
94
|
+
if (!targetNameMatch || typeof targetNameMatch[1] === "undefined") return undefined;
|
|
95
|
+
const targetName = targetNameMatch[1];
|
|
96
|
+
|
|
97
|
+
// 가져올 소스 경로 추출
|
|
98
|
+
const sourcePath = path.resolve(record[pkgGlobPath].replace(/\*/g, targetName));
|
|
99
|
+
return { source: sourcePath, target: targetPath };
|
|
100
|
+
})
|
|
101
|
+
.filterExists()
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
protected async _getWatchPathsAsync(sourcePath: string): Promise<string[]> {
|
|
109
|
+
return await FsUtil.globAsync(path.resolve(sourcePath, "**"), {
|
|
110
|
+
ignore: [
|
|
111
|
+
"**/node_modules/**",
|
|
112
|
+
"**/package.json"
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface IUpdatePathInfo {
|
|
119
|
+
source: string;
|
|
120
|
+
target: string;
|
|
121
|
+
}
|