@simplysm/sd-cli 7.0.25 → 7.0.39
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/.eslintrc.cjs +2 -2
- package/dist/bin/sd-cli.mjs +3 -1
- package/dist/build-tool/SdCliNgCacheCompilerHost.mjs +3 -3
- package/dist/builder/SdCliClientBuilder.d.ts +20 -0
- package/dist/builder/SdCliClientBuilder.mjs +417 -0
- package/dist/builder/SdCliJsLibBuilder.mjs +2 -2
- package/dist/builder/SdCliServerBuilder.d.ts +6 -4
- package/dist/builder/SdCliServerBuilder.mjs +175 -100
- package/dist/builder/SdCliTsLibBuilder.d.ts +5 -3
- package/dist/builder/SdCliTsLibBuilder.mjs +20 -21
- package/dist/commons.d.ts +10 -1
- package/dist/entry-points/SdCliLocalUpdate.mjs +15 -9
- package/dist/entry-points/SdCliNpm.mjs +8 -4
- package/dist/entry-points/SdCliPrepare.mjs +3 -2
- package/dist/entry-points/SdCliWorkspace.d.ts +1 -0
- package/dist/entry-points/SdCliWorkspace.mjs +57 -24
- package/dist/packages/SdCliPackage.d.ts +4 -4
- package/dist/packages/SdCliPackage.mjs +17 -17
- package/dist/utils/SdCliBuildResultUtil.mjs +4 -5
- package/dist/utils/SdCliNpmConfigUtil.d.ts +7 -0
- package/dist/utils/SdCliNpmConfigUtil.mjs +15 -0
- package/package.json +18 -7
- package/src/bin/sd-cli.ts +2 -0
- package/src/build-tool/SdCliNgCacheCompilerHost.ts +3 -3
- package/src/builder/SdCliClientBuilder.ts +451 -0
- package/src/builder/SdCliJsLibBuilder.ts +2 -2
- package/src/builder/SdCliServerBuilder.ts +195 -100
- package/src/builder/SdCliTsLibBuilder.ts +29 -24
- package/src/commons.ts +9 -1
- package/src/entry-points/SdCliLocalUpdate.ts +14 -8
- package/src/entry-points/SdCliNpm.ts +7 -3
- package/src/entry-points/SdCliPrepare.ts +2 -1
- package/src/entry-points/SdCliWorkspace.ts +65 -26
- package/src/packages/SdCliPackage.ts +18 -18
- package/src/utils/SdCliBuildResultUtil.ts +3 -4
- package/src/utils/SdCliNpmConfigUtil.ts +16 -0
- package/tsconfig.json +1 -1
|
@@ -9,6 +9,8 @@ import semver from "semver/preload";
|
|
|
9
9
|
import { SdCliConfigUtil } from "../utils/SdCliConfigUtil";
|
|
10
10
|
import { SdServiceServer } from "@simplysm/sd-service/server";
|
|
11
11
|
import { SdCliNpm } from "./SdCliNpm";
|
|
12
|
+
import { SdCliLocalUpdate } from "./SdCliLocalUpdate";
|
|
13
|
+
import { NextHandleFunction } from "connect";
|
|
12
14
|
|
|
13
15
|
export class SdCliWorkspace {
|
|
14
16
|
private readonly _logger = Logger.get(["simplysm", "sd-cli", this.constructor.name]);
|
|
@@ -25,6 +27,11 @@ export class SdCliWorkspace {
|
|
|
25
27
|
this._logger.debug("프로젝트 설정 가져오기...");
|
|
26
28
|
const config = await SdCliConfigUtil.loadConfigAsync(path.resolve(this._rootPath, opt.confFileRelPath), true, opt.optNames);
|
|
27
29
|
|
|
30
|
+
if (config.localUpdates) {
|
|
31
|
+
this._logger.debug("로컬 라이브러리 업데이트 변경감지 시작...");
|
|
32
|
+
await new SdCliLocalUpdate(this._rootPath).watchAsync({ confFileRelPath: opt.confFileRelPath });
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
this._logger.debug("패키지 목록 구성...");
|
|
29
36
|
const pkgs = await this._getPackagesAsync(config);
|
|
30
37
|
|
|
@@ -41,11 +48,7 @@ export class SdCliWorkspace {
|
|
|
41
48
|
this._logger.debug(`[${pkg.name}] 빌드를 시작합니다...`);
|
|
42
49
|
})
|
|
43
50
|
.on("complete", async (results) => {
|
|
44
|
-
if (pkg.type === "server") {
|
|
45
|
-
if (results.some((item) => item.severity === "error")) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
51
|
+
if (pkg.config.type === "server" && !results.some((item) => item.severity === "error")) {
|
|
49
52
|
await this._restartServerAsync(pkg);
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -56,6 +59,7 @@ export class SdCliWorkspace {
|
|
|
56
59
|
changeCount--;
|
|
57
60
|
if (changeCount === 0) {
|
|
58
61
|
this._loggingResults(totalResultMap);
|
|
62
|
+
this._loggingOpenClientHrefs();
|
|
59
63
|
this._logger.info("모든 빌드가 완료되었습니다.");
|
|
60
64
|
}
|
|
61
65
|
}, 500);
|
|
@@ -67,7 +71,16 @@ export class SdCliWorkspace {
|
|
|
67
71
|
const buildCompletedPackageNames: string[] = [];
|
|
68
72
|
await pkgs.parallelAsync(async (pkg) => {
|
|
69
73
|
await Wait.until(() => !pkg.allDependencies.some((dep) => pkgNames.includes(dep) && !buildCompletedPackageNames.includes(dep)));
|
|
70
|
-
|
|
74
|
+
if (pkg.config.type === "client") {
|
|
75
|
+
const middlewares = (await pkg.watchAsync()) as NextHandleFunction[];
|
|
76
|
+
|
|
77
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.config.server, { middlewares: [], clientInfos: [] });
|
|
78
|
+
serverInfo.middlewares.push(...middlewares);
|
|
79
|
+
serverInfo.clientInfos.push({ pkgKey: pkg.name.split("/").last()! });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await pkg.watchAsync();
|
|
83
|
+
}
|
|
71
84
|
buildCompletedPackageNames.push(pkg.name);
|
|
72
85
|
});
|
|
73
86
|
}
|
|
@@ -81,21 +94,26 @@ export class SdCliWorkspace {
|
|
|
81
94
|
const entryFilePath = path.resolve(pkg.rootPath, entryFileRelPath);
|
|
82
95
|
|
|
83
96
|
this._logger.log(`서버(${pkg.name}) 재시작...`);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
serverInfo.server = (await import("file:///" + entryFilePath + "?update=" + Uuid.new().toString())).default as SdServiceServer | undefined;
|
|
91
|
-
if (!serverInfo.server) {
|
|
92
|
-
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
97
|
+
try {
|
|
98
|
+
const serverInfo = this._serverInfoMap.getOrCreate(pkg.name, { middlewares: [], clientInfos: [] });
|
|
99
|
+
if (serverInfo.server) {
|
|
100
|
+
await serverInfo.server.closeAsync();
|
|
101
|
+
delete serverInfo.server;
|
|
102
|
+
}
|
|
95
103
|
|
|
96
|
-
|
|
104
|
+
serverInfo.server = (await import("file:///" + entryFilePath + "?update=" + Uuid.new().toString())).default as SdServiceServer | undefined;
|
|
105
|
+
if (!serverInfo.server) {
|
|
106
|
+
this._logger.error(`${entryFilePath}(0, 0): 'SdServiceServer'를 'export'해야 합니다.`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
serverInfo.server.devMiddlewares = serverInfo.middlewares;
|
|
110
|
+
await Wait.until(() => serverInfo.server!.isOpen);
|
|
97
111
|
|
|
98
|
-
|
|
112
|
+
this._logger.log(`서버(${pkg.name}) 재시작 완료`);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
this._logger.error(`서버(${pkg.name}) 재시작중 오류 발생`, err);
|
|
116
|
+
}
|
|
99
117
|
}
|
|
100
118
|
|
|
101
119
|
public async buildAsync(opt: { confFileRelPath: string; optNames: string[] }): Promise<void> {
|
|
@@ -148,9 +166,9 @@ export class SdCliWorkspace {
|
|
|
148
166
|
// GIT 사용중일 경우, 커밋되지 않은 수정사항이 있는지 확인
|
|
149
167
|
if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
|
|
150
168
|
this._logger.debug("GIT 커밋여부 확인...");
|
|
151
|
-
const gitStatusResult = await SdProcess.
|
|
169
|
+
const gitStatusResult = await SdProcess.spawnAsync("git status");
|
|
152
170
|
if (gitStatusResult.includes("Changes") || gitStatusResult.includes("Untracked")) {
|
|
153
|
-
throw new Error("커밋되지 않은 정보가
|
|
171
|
+
throw new Error("커밋되지 않은 정보가 있습니다.\n" + gitStatusResult);
|
|
154
172
|
}
|
|
155
173
|
}
|
|
156
174
|
|
|
@@ -172,9 +190,9 @@ export class SdCliWorkspace {
|
|
|
172
190
|
// GIT 사용중일경우, 새 버전 커밋 및 TAG 생성
|
|
173
191
|
if (FsUtil.exists(path.resolve(process.cwd(), ".git"))) {
|
|
174
192
|
this._logger.debug("새 버전 커밋 및 TAG 생성...");
|
|
175
|
-
await SdProcess.
|
|
176
|
-
await SdProcess.
|
|
177
|
-
await SdProcess.
|
|
193
|
+
await SdProcess.spawnAsync("git add .");
|
|
194
|
+
await SdProcess.spawnAsync(`git commit -m "v${this._npmConfig.version}"`);
|
|
195
|
+
await SdProcess.spawnAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
|
|
178
196
|
}
|
|
179
197
|
|
|
180
198
|
this._logger.debug("배포 시작...");
|
|
@@ -220,7 +238,7 @@ export class SdCliWorkspace {
|
|
|
220
238
|
if (i !== sec) {
|
|
221
239
|
process.stdout.cursorTo(0);
|
|
222
240
|
}
|
|
223
|
-
process.stdout.write(msg
|
|
241
|
+
process.stdout.write(`${msg} ${i}`);
|
|
224
242
|
await Wait.time(1000);
|
|
225
243
|
}
|
|
226
244
|
|
|
@@ -246,7 +264,7 @@ export class SdCliWorkspace {
|
|
|
246
264
|
pkgName: item[0],
|
|
247
265
|
...item1
|
|
248
266
|
})))
|
|
249
|
-
.orderBy((item) => item.pkgName
|
|
267
|
+
.orderBy((item) => `${item.pkgName}_${item.filePath}`);
|
|
250
268
|
|
|
251
269
|
const warnings = totalResults
|
|
252
270
|
.filter((item) => item.severity === "warning")
|
|
@@ -272,8 +290,29 @@ export class SdCliWorkspace {
|
|
|
272
290
|
this._logger.warn(`경고: ${warnings.length}건, 오류: ${errors.length}건`);
|
|
273
291
|
}
|
|
274
292
|
}
|
|
293
|
+
|
|
294
|
+
private _loggingOpenClientHrefs(): void {
|
|
295
|
+
const clientHrefs: string[] = [];
|
|
296
|
+
|
|
297
|
+
const serverInfos = Array.from(this._serverInfoMap.values());
|
|
298
|
+
for (const serverInfo of serverInfos) {
|
|
299
|
+
if (!serverInfo.server) continue;
|
|
300
|
+
|
|
301
|
+
const protocolStr = serverInfo.server.options.ssl ? "https" : "http";
|
|
302
|
+
const portStr = serverInfo.server.options.port.toString();
|
|
303
|
+
|
|
304
|
+
for (const clientInfo of serverInfo.clientInfos) {
|
|
305
|
+
clientHrefs.push(`${protocolStr}://localhost:${portStr}/${clientInfo.pkgKey}/`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (clientHrefs.length > 0) {
|
|
309
|
+
this._logger.log(`오픈된 클라이언트: ${clientHrefs.join(", ")}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
275
312
|
}
|
|
276
313
|
|
|
277
314
|
interface IServerInfo {
|
|
278
315
|
server?: SdServiceServer;
|
|
316
|
+
middlewares: NextHandleFunction[];
|
|
317
|
+
clientInfos: { pkgKey: string }[];
|
|
279
318
|
}
|
|
@@ -6,6 +6,9 @@ import { ObjectUtil } from "@simplysm/sd-core-common";
|
|
|
6
6
|
import { SdCliTsLibBuilder } from "../builder/SdCliTsLibBuilder";
|
|
7
7
|
import { SdCliJsLibBuilder } from "../builder/SdCliJsLibBuilder";
|
|
8
8
|
import { SdCliServerBuilder } from "../builder/SdCliServerBuilder";
|
|
9
|
+
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
10
|
+
import { SdCliClientBuilder } from "../builder/SdCliClientBuilder";
|
|
11
|
+
import { NextHandleFunction } from "connect";
|
|
9
12
|
|
|
10
13
|
export class SdCliPackage extends EventEmitter {
|
|
11
14
|
private readonly _npmConfig: INpmConfig;
|
|
@@ -22,22 +25,16 @@ export class SdCliPackage extends EventEmitter {
|
|
|
22
25
|
return this._npmConfig.main;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
public get type(): TSdCliPackageConfig["type"] {
|
|
26
|
-
return this._config.type;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
28
|
public get allDependencies(): string[] {
|
|
30
29
|
return [
|
|
31
|
-
...
|
|
32
|
-
...
|
|
33
|
-
// ...Object.keys(this._npmConfig.devDependencies ?? {}),
|
|
34
|
-
...Object.keys(this._npmConfig.peerDependencies ?? {})
|
|
30
|
+
...SdCliNpmConfigUtil.getDependencies(this._npmConfig).defaults,
|
|
31
|
+
...SdCliNpmConfigUtil.getDependencies(this._npmConfig).optionals
|
|
35
32
|
].distinct();
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
public constructor(private readonly _workspaceRootPath: string,
|
|
39
36
|
public readonly rootPath: string,
|
|
40
|
-
|
|
37
|
+
public readonly config: TSdCliPackageConfig) {
|
|
41
38
|
super();
|
|
42
39
|
|
|
43
40
|
const npmConfigFilePath = path.resolve(this.rootPath, "package.json");
|
|
@@ -70,8 +67,8 @@ export class SdCliPackage extends EventEmitter {
|
|
|
70
67
|
await FsUtil.writeJsonAsync(npmConfigFilePath, this._npmConfig, { space: 2 });
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
public async watchAsync(): Promise<void> {
|
|
74
|
-
await (await this._createBuilderAsync())
|
|
70
|
+
public async watchAsync(): Promise<NextHandleFunction[] | void> {
|
|
71
|
+
return await (await this._createBuilderAsync())
|
|
75
72
|
.on("change", () => {
|
|
76
73
|
this.emit("change");
|
|
77
74
|
})
|
|
@@ -86,24 +83,27 @@ export class SdCliPackage extends EventEmitter {
|
|
|
86
83
|
}
|
|
87
84
|
|
|
88
85
|
public async publishAsync(): Promise<void> {
|
|
89
|
-
if (this.
|
|
90
|
-
await SdProcess.
|
|
86
|
+
if (this.config.type === "library" && this.config.publish === "npm") {
|
|
87
|
+
await SdProcess.spawnAsync("npm publish --quiet --access public", { cwd: this.rootPath });
|
|
91
88
|
}
|
|
92
89
|
}
|
|
93
90
|
|
|
94
|
-
private async _createBuilderAsync(): Promise<SdCliJsLibBuilder | SdCliTsLibBuilder | SdCliServerBuilder> {
|
|
91
|
+
private async _createBuilderAsync(): Promise<SdCliJsLibBuilder | SdCliTsLibBuilder | SdCliServerBuilder | SdCliClientBuilder> {
|
|
95
92
|
const isTs = FsUtil.exists(path.resolve(this.rootPath, "tsconfig.json"));
|
|
96
93
|
|
|
97
94
|
if (isTs) {
|
|
98
95
|
await this._genBuildTsconfigAsync();
|
|
99
96
|
}
|
|
100
97
|
|
|
101
|
-
if (this.
|
|
102
|
-
const isAngular = isTs && this.allDependencies.includes("@angular/core");
|
|
103
|
-
return isTs ? new SdCliTsLibBuilder(this.rootPath
|
|
98
|
+
if (this.config.type === "library") {
|
|
99
|
+
// const isAngular = isTs && this.allDependencies.includes("@angular/core");
|
|
100
|
+
return isTs ? new SdCliTsLibBuilder(this.rootPath) : new SdCliJsLibBuilder(this.rootPath);
|
|
101
|
+
}
|
|
102
|
+
else if (this.config.type === "server") {
|
|
103
|
+
return new SdCliServerBuilder(this.rootPath, this.config, this._workspaceRootPath);
|
|
104
104
|
}
|
|
105
105
|
else {
|
|
106
|
-
return new
|
|
106
|
+
return new SdCliClientBuilder(this.rootPath, this.config, this._workspaceRootPath);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -11,7 +11,7 @@ export class SdCliBuildResultUtil {
|
|
|
11
11
|
: undefined;
|
|
12
12
|
if (!severity) return undefined;
|
|
13
13
|
|
|
14
|
-
const code =
|
|
14
|
+
const code = `TS${diag.code}`;
|
|
15
15
|
const message = ts.flattenDiagnosticMessageText(diag.messageText, os.EOL);
|
|
16
16
|
|
|
17
17
|
|
|
@@ -47,11 +47,10 @@ export class SdCliBuildResultUtil {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
private static _convertFromWebpackError(severity: "warning" | "error", err: webpack.WebpackError): ISdCliPackageBuildResult {
|
|
50
|
-
console.log(err);
|
|
51
50
|
return {
|
|
52
51
|
filePath: err.file,
|
|
53
|
-
line: err.loc["start"]
|
|
54
|
-
char: err.loc["start"]
|
|
52
|
+
line: err.file ? err.loc["start"]?.line : undefined,
|
|
53
|
+
char: err.file ? err.loc["start"]?.column : undefined,
|
|
55
54
|
code: err.name,
|
|
56
55
|
severity,
|
|
57
56
|
message: err.message
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { INpmConfig } from "../commons";
|
|
2
|
+
|
|
3
|
+
export class SdCliNpmConfigUtil {
|
|
4
|
+
public static getDependencies(npmConfig: INpmConfig): { defaults: string[]; optionals: string[] } {
|
|
5
|
+
return {
|
|
6
|
+
defaults: [
|
|
7
|
+
...Object.keys(npmConfig.dependencies ?? {}),
|
|
8
|
+
...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => !npmConfig.peerDependenciesMeta?.[item].optional)
|
|
9
|
+
].distinct(),
|
|
10
|
+
optionals: [
|
|
11
|
+
...Object.keys(npmConfig.optionalDependencies ?? {}),
|
|
12
|
+
...Object.keys(npmConfig.peerDependencies ?? {}).filter((item) => npmConfig.peerDependenciesMeta?.[item].optional)
|
|
13
|
+
].distinct()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|