@simplysm/sd-cli 10.0.45 → 10.0.49
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/builders/SdCliClientBuilder.js +10 -4
- package/dist/builders/SdCliClientBuilder.js.map +1 -1
- package/dist/builders/SdCliServerBuilder.js +88 -6
- package/dist/builders/SdCliServerBuilder.js.map +1 -1
- package/dist/commons.d.ts +14 -1
- package/dist/entry/SdCliElectron.js +2 -2
- package/dist/entry/SdCliElectron.js.map +1 -1
- package/dist/entry/SdCliLocalUpdate.d.ts +12 -0
- package/dist/entry/SdCliLocalUpdate.js +98 -0
- package/dist/entry/SdCliLocalUpdate.js.map +1 -0
- package/dist/entry/SdCliProject.js +27 -20
- package/dist/entry/SdCliProject.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/sd-cli.js +20 -1
- package/dist/sd-cli.js.map +1 -1
- package/package.json +11 -11
- package/src/builders/SdCliClientBuilder.ts +12 -5
- package/src/builders/SdCliServerBuilder.ts +102 -6
- package/src/commons.ts +15 -1
- package/src/entry/SdCliElectron.ts +2 -2
- package/src/entry/SdCliLocalUpdate.ts +127 -0
- package/src/entry/SdCliProject.ts +33 -20
- package/src/index.ts +1 -0
- package/src/sd-cli.ts +24 -1
|
@@ -17,7 +17,7 @@ export class SdCliElectron {
|
|
|
17
17
|
|
|
18
18
|
logger.log("설정 가져오기...");
|
|
19
19
|
const projConf = (await import(pathToFileURL(path.resolve(process.cwd(), opt.confFileRelPath)).href)).default(true, opt.optNames) as TSdCliConfig;
|
|
20
|
-
const pkgConf = projConf[opt.pkgName];
|
|
20
|
+
const pkgConf = projConf.packages[opt.pkgName];
|
|
21
21
|
if (pkgConf?.type !== "client" || pkgConf.builder?.electron === undefined) {
|
|
22
22
|
throw new Error();
|
|
23
23
|
}
|
|
@@ -67,7 +67,7 @@ export class SdCliElectron {
|
|
|
67
67
|
|
|
68
68
|
logger.log("설정 가져오기...");
|
|
69
69
|
const projConf = (await import(pathToFileURL(path.resolve(process.cwd(), opt.confFileRelPath)).href)).default(true, opt.optNames) as TSdCliConfig;
|
|
70
|
-
const pkgConf = projConf[opt.pkgName];
|
|
70
|
+
const pkgConf = projConf.packages[opt.pkgName];
|
|
71
71
|
if (pkgConf?.type !== "client" || pkgConf.builder?.electron === undefined) {
|
|
72
72
|
throw new Error();
|
|
73
73
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {FsUtil, Logger, PathUtil, SdFsWatcher} from "@simplysm/sd-core-node";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import {pathToFileURL} from "url";
|
|
4
|
+
import {TSdCliConfig} from "../commons";
|
|
5
|
+
|
|
6
|
+
export class SdCliLocalUpdate {
|
|
7
|
+
public static async runAsync(opt: {
|
|
8
|
+
confFileRelPath: string;
|
|
9
|
+
optNames: string[];
|
|
10
|
+
}): Promise<void> {
|
|
11
|
+
const logger = Logger.get(["simplysm", "sd-cli", "SdCliLocalUpdate", "runAsync"]);
|
|
12
|
+
|
|
13
|
+
logger.debug("프로젝트 설정 가져오기...");
|
|
14
|
+
const projConf = (await import(pathToFileURL(path.resolve(process.cwd(), opt.confFileRelPath)).href)).default(true, opt.optNames) as TSdCliConfig;
|
|
15
|
+
if (!projConf.localUpdates) return;
|
|
16
|
+
|
|
17
|
+
const updatePathInfos = await this._getUpdatePathInfosAsync(projConf.localUpdates);
|
|
18
|
+
logger.debug("로컬 업데이트 구성", updatePathInfos);
|
|
19
|
+
|
|
20
|
+
logger.log("로컬 라이브러리 업데이트 시작...");
|
|
21
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
22
|
+
if (!FsUtil.exists(updatePathInfo.source)) {
|
|
23
|
+
logger.warn(`소스경로를 찾을 수 없어 무시됩니다(${updatePathInfo.source})`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 소스경로에서 대상경로로 파일 복사
|
|
28
|
+
await FsUtil.copyAsync(updatePathInfo.source, updatePathInfo.target, (src) => {
|
|
29
|
+
return !src.includes("node_modules") && !src.endsWith("package.json");
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
logger.info("로컬 라이브러리 업데이트 완료");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public static async watchAsync(opt: {
|
|
36
|
+
confFileRelPath: string;
|
|
37
|
+
optNames: string[];
|
|
38
|
+
}): Promise<void> {
|
|
39
|
+
const logger = Logger.get(["simplysm", "sd-cli", "SdCliLocalUpdate", "watchAsync"]);
|
|
40
|
+
|
|
41
|
+
logger.debug("프로젝트 설정 가져오기...");
|
|
42
|
+
const projConf = (await import(pathToFileURL(path.resolve(process.cwd(), opt.confFileRelPath)).href)).default(true, opt.optNames) as TSdCliConfig;
|
|
43
|
+
if (!projConf.localUpdates) return;
|
|
44
|
+
|
|
45
|
+
const updatePathInfos = await this._getUpdatePathInfosAsync(projConf.localUpdates);
|
|
46
|
+
logger.debug("로컬 업데이트 구성");
|
|
47
|
+
|
|
48
|
+
const watchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
49
|
+
|
|
50
|
+
const watcher = SdFsWatcher.watch(watchPaths);
|
|
51
|
+
watcher.onChange({delay: 1000}, async (changedInfos) => {
|
|
52
|
+
const changeFilePaths = changedInfos.filter((item) => ["add", "change", "unlink"].includes(item.event)).map((item) => item.path);
|
|
53
|
+
if (changeFilePaths.length === 0) return;
|
|
54
|
+
|
|
55
|
+
logger.log("로컬 라이브러리 변경감지...");
|
|
56
|
+
for (const changedFilePath of changeFilePaths) {
|
|
57
|
+
if (!FsUtil.exists(changedFilePath)) continue;
|
|
58
|
+
|
|
59
|
+
for (const updatePathInfo of updatePathInfos) {
|
|
60
|
+
if (!PathUtil.isChildPath(changedFilePath, updatePathInfo.source)) continue;
|
|
61
|
+
|
|
62
|
+
const sourceRelPath = path.relative(updatePathInfo.source, changedFilePath);
|
|
63
|
+
if (sourceRelPath.includes("node_modules")) continue;
|
|
64
|
+
if (sourceRelPath.includes("package.json")) continue;
|
|
65
|
+
|
|
66
|
+
const targetFilePath = path.resolve(updatePathInfo.target, sourceRelPath);
|
|
67
|
+
|
|
68
|
+
logger.debug(`변경파일감지(복사): ${changedFilePath} => ${targetFilePath}`);
|
|
69
|
+
await FsUtil.copyAsync(changedFilePath, targetFilePath);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const watchWatchPaths = (await updatePathInfos.mapManyAsync(async (item) => await this._getWatchPathsAsync(item.source))).distinct();
|
|
74
|
+
watcher.add(watchWatchPaths);
|
|
75
|
+
|
|
76
|
+
logger.info("로컬 라이브러리 복사 완료");
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private static async _getUpdatePathInfosAsync(record: Record<string, string>): Promise<IUpdatePathInfo[]> {
|
|
81
|
+
const result: IUpdatePathInfo[] = [];
|
|
82
|
+
for (const pkgGlobPath of Object.keys(record)) {
|
|
83
|
+
// "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
|
|
84
|
+
const targetPaths = [
|
|
85
|
+
...await FsUtil.globAsync(path.resolve(process.cwd(), "node_modules", pkgGlobPath)),
|
|
86
|
+
...await FsUtil.globAsync(path.resolve(process.cwd(), "packages", "*", "node_modules", pkgGlobPath))
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
result.push(
|
|
90
|
+
...targetPaths
|
|
91
|
+
.map((targetPath) => {
|
|
92
|
+
// 대상의 명칭 추출
|
|
93
|
+
const regexpText = pkgGlobPath.replace(/[\\/.*]/g, (item) => (
|
|
94
|
+
item === "/" ? "[\\\\\\/]"
|
|
95
|
+
: item === "." ? "\\."
|
|
96
|
+
: item === "*" ? "(.*)"
|
|
97
|
+
: item
|
|
98
|
+
));
|
|
99
|
+
const targetNameMatch = new RegExp(regexpText).exec(targetPath);
|
|
100
|
+
if (!targetNameMatch || typeof targetNameMatch[1] === "undefined") return undefined;
|
|
101
|
+
const targetName = targetNameMatch[1];
|
|
102
|
+
|
|
103
|
+
// 가져올 소스 경로 추출
|
|
104
|
+
const sourcePath = path.resolve(record[pkgGlobPath].replace(/\*/g, targetName));
|
|
105
|
+
return {source: sourcePath, target: targetPath};
|
|
106
|
+
})
|
|
107
|
+
.filterExists()
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private static async _getWatchPathsAsync(sourcePath: string): Promise<string[]> {
|
|
115
|
+
return await FsUtil.globAsync(path.resolve(sourcePath, "**"), {
|
|
116
|
+
ignore: [
|
|
117
|
+
"**/node_modules/**",
|
|
118
|
+
"**/package.json"
|
|
119
|
+
]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
interface IUpdatePathInfo {
|
|
125
|
+
source: string;
|
|
126
|
+
target: string;
|
|
127
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
ISdCliBuildClusterReqMessage,
|
|
6
6
|
ISdCliBuildClusterResMessage,
|
|
7
7
|
ISdCliPackageBuildResult,
|
|
8
|
+
ISdCliServerPackageConfig,
|
|
8
9
|
TSdCliConfig,
|
|
9
10
|
TSdCliPackageConfig
|
|
10
11
|
} from "../commons";
|
|
@@ -36,20 +37,20 @@ export class SdCliProject {
|
|
|
36
37
|
throw new Error("프로젝트 package.json에 workspaces가 설정되어있지 않습니다.");
|
|
37
38
|
}
|
|
38
39
|
const allPkgPaths = await projNpmConf.workspaces.mapManyAsync(async (item) => await FsUtil.globAsync(item));
|
|
39
|
-
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf);
|
|
40
|
+
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf.packages);
|
|
40
41
|
if (opt.pkgNames.length !== 0) {
|
|
41
42
|
pkgPaths = pkgPaths.filter((pkgPath) => opt.pkgNames.includes(path.basename(pkgPath)));
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
logger.debug("패키지 존재 확인...");
|
|
45
|
-
const notExistsPkgs = Object.keys(projConf).filter((pkgConfKey) => allPkgPaths.every((pkgPath) => path.basename(pkgPath) !== pkgConfKey));
|
|
46
|
+
const notExistsPkgs = Object.keys(projConf.packages).filter((pkgConfKey) => allPkgPaths.every((pkgPath) => path.basename(pkgPath) !== pkgConfKey));
|
|
46
47
|
if (notExistsPkgs.length > 0) {
|
|
47
48
|
throw new Error("패키지를 찾을 수 없습니다. (" + notExistsPkgs.join(", ") + ")");
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
logger.debug("라이브러리 INDEX 파일 생성...");
|
|
51
52
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
52
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
53
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
53
54
|
if (pkgConf.type === "library" && FsUtil.exists(path.resolve(pkgPath, "tsconfig.json"))) {
|
|
54
55
|
await SdCliIndexFileGenerator.watchAsync(pkgPath, pkgConf.polyfills);
|
|
55
56
|
}
|
|
@@ -131,7 +132,11 @@ export class SdCliProject {
|
|
|
131
132
|
if (serverInfo.pkgPath !== undefined && serverInfo.hasChanges) {
|
|
132
133
|
logger.debug("서버 재시작...");
|
|
133
134
|
try {
|
|
134
|
-
const restartServerResult = await this._restartServerAsync(
|
|
135
|
+
const restartServerResult = await this._restartServerAsync(
|
|
136
|
+
serverInfo.pkgPath,
|
|
137
|
+
projConf.packages[path.basename(serverInfo.pkgPath)] as ISdCliServerPackageConfig,
|
|
138
|
+
serverInfo.worker
|
|
139
|
+
);
|
|
135
140
|
serverInfo.worker = restartServerResult.worker;
|
|
136
141
|
serverInfo.port = restartServerResult.port;
|
|
137
142
|
serverInfo.hasChanges = false;
|
|
@@ -177,15 +182,15 @@ export class SdCliProject {
|
|
|
177
182
|
logger.log("빌드를 시작합니다...");
|
|
178
183
|
|
|
179
184
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
180
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
185
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
181
186
|
if (pkgConf.type === "client") {
|
|
182
187
|
const builderKeys = Object.keys(pkgConf.builder ?? {web: {}});
|
|
183
188
|
await builderKeys.parallelAsync(async (builderKey) => {
|
|
184
|
-
await this._runCommandAsync(cluster, "watch", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
189
|
+
await this._runCommandAsync(cluster, "watch", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
185
190
|
});
|
|
186
191
|
}
|
|
187
192
|
else {
|
|
188
|
-
await this._runCommandAsync(cluster, "watch", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint);
|
|
193
|
+
await this._runCommandAsync(cluster, "watch", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint);
|
|
189
194
|
}
|
|
190
195
|
});
|
|
191
196
|
|
|
@@ -215,7 +220,7 @@ export class SdCliProject {
|
|
|
215
220
|
throw new Error("프로젝트 package.json에 workspaces가 설정되어있지 않습니다.");
|
|
216
221
|
}
|
|
217
222
|
const allPkgPaths = await projNpmConf.workspaces.mapManyAsync(async (item) => await FsUtil.globAsync(item));
|
|
218
|
-
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf);
|
|
223
|
+
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf.packages);
|
|
219
224
|
if (opt.pkgNames.length !== 0) {
|
|
220
225
|
pkgPaths = pkgPaths.filter((pkgPath) => opt.pkgNames.includes(path.basename(pkgPath)));
|
|
221
226
|
}
|
|
@@ -225,7 +230,7 @@ export class SdCliProject {
|
|
|
225
230
|
|
|
226
231
|
logger.debug("라이브러리 INDEX 파일 생성...");
|
|
227
232
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
228
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
233
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
229
234
|
if (pkgConf.type === "library" && FsUtil.exists(path.resolve(pkgPath, "tsconfig.json"))) {
|
|
230
235
|
await SdCliIndexFileGenerator.runAsync(pkgPath, pkgConf.polyfills);
|
|
231
236
|
}
|
|
@@ -237,15 +242,15 @@ export class SdCliProject {
|
|
|
237
242
|
logger.debug("빌드 프로세스 명령 전달...");
|
|
238
243
|
const results = (
|
|
239
244
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
240
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
245
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
241
246
|
if (pkgConf.type === "client") {
|
|
242
247
|
const builderKeys = Object.keys(pkgConf.builder ?? {web: {}});
|
|
243
248
|
return (await builderKeys.parallelAsync(async (builderKey) => {
|
|
244
|
-
return await this._runCommandAsync(cluster, "build", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
249
|
+
return await this._runCommandAsync(cluster, "build", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
245
250
|
})).mapMany();
|
|
246
251
|
}
|
|
247
252
|
else {
|
|
248
|
-
return await this._runCommandAsync(cluster, "build", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint);
|
|
253
|
+
return await this._runCommandAsync(cluster, "build", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint);
|
|
249
254
|
}
|
|
250
255
|
})
|
|
251
256
|
).mapMany();
|
|
@@ -290,7 +295,7 @@ export class SdCliProject {
|
|
|
290
295
|
throw new Error("프로젝트 package.json에 workspaces가 설정되어있지 않습니다.");
|
|
291
296
|
}
|
|
292
297
|
const allPkgPaths = await projNpmConf.workspaces.mapManyAsync(async (item) => await FsUtil.globAsync(item));
|
|
293
|
-
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf);
|
|
298
|
+
let pkgPaths = allPkgPaths.filter((pkgPath) => path.basename(pkgPath) in projConf.packages);
|
|
294
299
|
if (opt.pkgNames.length !== 0) {
|
|
295
300
|
pkgPaths = pkgPaths.filter((pkgPath) => opt.pkgNames.includes(path.basename(pkgPath)));
|
|
296
301
|
}
|
|
@@ -302,7 +307,7 @@ export class SdCliProject {
|
|
|
302
307
|
if (!opt.noBuild) {
|
|
303
308
|
logger.debug("라이브러리 INDEX 파일 생성...");
|
|
304
309
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
305
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
310
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
306
311
|
if (pkgConf.type === "library" && FsUtil.exists(path.resolve(pkgPath, "tsconfig.json"))) {
|
|
307
312
|
await SdCliIndexFileGenerator.runAsync(pkgPath, pkgConf.polyfills);
|
|
308
313
|
}
|
|
@@ -314,15 +319,15 @@ export class SdCliProject {
|
|
|
314
319
|
logger.debug("빌드 프로세스 명령 전달...");
|
|
315
320
|
const results = (
|
|
316
321
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
317
|
-
const pkgConf = projConf[path.basename(pkgPath)]!;
|
|
322
|
+
const pkgConf = projConf.packages[path.basename(pkgPath)]!;
|
|
318
323
|
if (pkgConf.type === "client") {
|
|
319
324
|
const builderKeys = Object.keys(pkgConf.builder ?? {web: {}});
|
|
320
325
|
return (await builderKeys.parallelAsync(async (builderKey) => {
|
|
321
|
-
return await this._runCommandAsync(cluster, "build", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
326
|
+
return await this._runCommandAsync(cluster, "build", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint, builderKey);
|
|
322
327
|
})).mapMany();
|
|
323
328
|
}
|
|
324
329
|
else {
|
|
325
|
-
return await this._runCommandAsync(cluster, "build", pkgPath, projConf[path.basename(pkgPath)]!, opt.withLint);
|
|
330
|
+
return await this._runCommandAsync(cluster, "build", pkgPath, projConf.packages[path.basename(pkgPath)]!, opt.withLint);
|
|
326
331
|
}
|
|
327
332
|
})
|
|
328
333
|
).mapMany();
|
|
@@ -348,7 +353,7 @@ export class SdCliProject {
|
|
|
348
353
|
logger.debug("배포 시작...");
|
|
349
354
|
await pkgPaths.parallelAsync(async (pkgPath) => {
|
|
350
355
|
const pkgName = path.basename(pkgPath);
|
|
351
|
-
const pkgConf = projConf[pkgName];
|
|
356
|
+
const pkgConf = projConf.packages[pkgName];
|
|
352
357
|
if (pkgConf?.publish == null) return;
|
|
353
358
|
|
|
354
359
|
logger.debug(`[${pkgName}] 배포 시작...`);
|
|
@@ -545,7 +550,7 @@ export class SdCliProject {
|
|
|
545
550
|
cluster.kill("SIGKILL");
|
|
546
551
|
}
|
|
547
552
|
|
|
548
|
-
private static async _restartServerAsync(pkgPath: string, prevServerProcess?: cp.ChildProcess): Promise<{
|
|
553
|
+
private static async _restartServerAsync(pkgPath: string, pkgConf: ISdCliServerPackageConfig, prevServerProcess?: cp.ChildProcess): Promise<{
|
|
549
554
|
worker: cp.ChildProcess,
|
|
550
555
|
port: number
|
|
551
556
|
}> {
|
|
@@ -555,6 +560,8 @@ export class SdCliProject {
|
|
|
555
560
|
prevServerProcess.kill("SIGKILL");
|
|
556
561
|
}
|
|
557
562
|
|
|
563
|
+
const npmConf = (await FsUtil.readJsonAsync(path.resolve(pkgPath, "package.json"))) as INpmConfig;
|
|
564
|
+
|
|
558
565
|
return await new Promise<{
|
|
559
566
|
worker: cp.ChildProcess,
|
|
560
567
|
port: number
|
|
@@ -564,7 +571,13 @@ export class SdCliProject {
|
|
|
564
571
|
[pkgPath],
|
|
565
572
|
{
|
|
566
573
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
567
|
-
env:
|
|
574
|
+
env: {
|
|
575
|
+
...process.env,
|
|
576
|
+
NODE_ENV: "development",
|
|
577
|
+
TZ: "Asia/Seoul",
|
|
578
|
+
SD_VERSION: npmConf.version,
|
|
579
|
+
...pkgConf.env
|
|
580
|
+
}
|
|
568
581
|
}
|
|
569
582
|
);
|
|
570
583
|
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./builders/SdCliServerBuilder";
|
|
|
7
7
|
export * from "./builders/SdCliTsLibBuilder";
|
|
8
8
|
export * from "./commons";
|
|
9
9
|
export * from "./entry/SdCliElectron";
|
|
10
|
+
export * from "./entry/SdCliLocalUpdate";
|
|
10
11
|
export * from "./entry/SdCliProject";
|
|
11
12
|
export * from "./utils/getElectronReactExternals";
|
|
12
13
|
export * from "./utils/SdCliBuildResultUtil";
|
package/src/sd-cli.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {SdCliProject} from "./entry/SdCliProject";
|
|
|
6
6
|
import {Logger, LoggerSeverity} from "@simplysm/sd-core-node";
|
|
7
7
|
import {EventEmitter} from "events";
|
|
8
8
|
import {SdCliElectron} from "./entry/SdCliElectron";
|
|
9
|
+
import {SdCliLocalUpdate} from "./entry/SdCliLocalUpdate";
|
|
9
10
|
|
|
10
11
|
Error.stackTraceLimit = Infinity;
|
|
11
12
|
EventEmitter.defaultMaxListeners = 0;
|
|
@@ -21,6 +22,22 @@ const argv = (
|
|
|
21
22
|
default: false
|
|
22
23
|
}
|
|
23
24
|
})
|
|
25
|
+
.command(
|
|
26
|
+
"local-update",
|
|
27
|
+
"로컬 라이브러리 업데이트를 수행합니다.",
|
|
28
|
+
(cmd) => cmd.version(false).hide("help").hide("debug")
|
|
29
|
+
.options({
|
|
30
|
+
config: {
|
|
31
|
+
string: true,
|
|
32
|
+
describe: "simplysm.cjs 파일 경로"
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
string: true,
|
|
36
|
+
array: true,
|
|
37
|
+
describe: "옵션 설정"
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
)
|
|
24
41
|
.command(
|
|
25
42
|
"watch",
|
|
26
43
|
"프로젝트의 각 패키지에 대한 변경감지 빌드를 수행합니다.",
|
|
@@ -163,7 +180,13 @@ else {
|
|
|
163
180
|
});
|
|
164
181
|
}
|
|
165
182
|
|
|
166
|
-
if (argv._[0] === "
|
|
183
|
+
if (argv._[0] === "local-update") {
|
|
184
|
+
await SdCliLocalUpdate.runAsync({
|
|
185
|
+
confFileRelPath: argv.config ?? "simplysm.cjs",
|
|
186
|
+
optNames: argv.options ?? [],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else if (argv._[0] === "watch") {
|
|
167
190
|
await SdCliProject
|
|
168
191
|
.watchAsync({
|
|
169
192
|
confFileRelPath: argv.config ?? "simplysm.cjs",
|