@simplysm/sd-cli 7.0.100 → 7.0.151
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 +29 -9
- package/dist/build-tool/SdCliCordova.d.ts +1 -1
- package/dist/build-tool/SdCliCordova.mjs +22 -21
- package/dist/build-tool/SdCliElectron.d.ts +7 -1
- package/dist/build-tool/SdCliElectron.mjs +56 -11
- package/dist/build-tool/SdCliGithubApi.d.ts +13 -0
- package/dist/build-tool/SdCliGithubApi.mjs +92 -0
- package/dist/builder/SdCliClientBuilder.mjs +58 -42
- package/dist/builder/SdCliServerBuilder.mjs +6 -7
- package/dist/commons.d.ts +17 -5
- package/dist/entry-points/SdCliWorkspace.mjs +32 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +2 -1
- package/dist/packages/SdCliPackage.mjs +13 -2
- package/package.json +10 -8
- package/src/bin/sd-cli.ts +34 -9
- package/src/build-tool/SdCliCordova.ts +22 -20
- package/src/build-tool/SdCliElectron.ts +62 -11
- package/src/build-tool/SdCliGithubApi.ts +111 -0
- package/src/builder/SdCliClientBuilder.ts +60 -42
- package/src/builder/SdCliServerBuilder.ts +6 -7
- package/src/commons.ts +16 -10
- package/src/entry-points/SdCliWorkspace.ts +33 -5
- package/src/index.ts +1 -0
- package/src/packages/SdCliPackage.ts +18 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import https from "https";
|
|
2
|
+
import { SdProcess } from "@simplysm/sd-core-node";
|
|
3
|
+
import mime from "mime";
|
|
4
|
+
|
|
5
|
+
export class SdCliGithubApi {
|
|
6
|
+
public constructor(private readonly _apiKey: string,
|
|
7
|
+
private readonly _repoOwner: string,
|
|
8
|
+
private readonly _repoName: string) {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async uploadAsync(version: string, files: { name: string; buffer: Buffer }[]): Promise<void> {
|
|
12
|
+
const releaseId = await this._createReleaseTagAsync(version);
|
|
13
|
+
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
await this._uploadFileAsync(releaseId, file.name, file.buffer);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private async _uploadFileAsync(releaseId: number, fileName: string, buffer: Buffer): Promise<void> {
|
|
20
|
+
const contentLength = buffer.length;
|
|
21
|
+
|
|
22
|
+
await new Promise<void>((resolve, reject) => {
|
|
23
|
+
const req = https.request(
|
|
24
|
+
`https://uploads.github.com/repos/${this._repoOwner}/${this._repoName}/releases/${releaseId}/assets?name=${fileName}&label=${fileName}`,
|
|
25
|
+
{
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Authorization": `token ${this._apiKey}`,
|
|
29
|
+
"Accept": "application/vnd.github.v3+json",
|
|
30
|
+
"User-Agent": "@simplysm/sd-cli:publish",
|
|
31
|
+
"Content-Length": contentLength,
|
|
32
|
+
"Content-Type": mime.getType(fileName)!
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
(res) => {
|
|
36
|
+
let dataBuffer = Buffer.from([]);
|
|
37
|
+
res.on("data", data => {
|
|
38
|
+
dataBuffer = Buffer.concat([dataBuffer, data]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
res.on("end", () => {
|
|
42
|
+
if (res.statusCode !== 201) {
|
|
43
|
+
const errObj = JSON.parse(dataBuffer.toString());
|
|
44
|
+
throw new Error(errObj.message + "(" + errObj.documentation_url + ")");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
resolve();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
req.on("error", (error) => {
|
|
54
|
+
reject(error);
|
|
55
|
+
});
|
|
56
|
+
req.write(buffer);
|
|
57
|
+
req.end();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async _createReleaseTagAsync(ver: string): Promise<number> {
|
|
62
|
+
const currentBranch = (await SdProcess.spawnAsync("git branch --show-current")).trim();
|
|
63
|
+
|
|
64
|
+
return await new Promise<number>((resolve, reject) => {
|
|
65
|
+
const req = https.request(
|
|
66
|
+
`https://api.github.com/repos/${this._repoOwner}/${this._repoName}/releases`,
|
|
67
|
+
{
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"Authorization": `token ${this._apiKey}`,
|
|
71
|
+
"Accept": "application/vnd.github.v3+json",
|
|
72
|
+
"User-Agent": "@simplysm/sd-cli:publish"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
(res) => {
|
|
76
|
+
let dataBuffer = Buffer.from([]);
|
|
77
|
+
res.on("data", data => {
|
|
78
|
+
dataBuffer = Buffer.concat([dataBuffer, data]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
res.on("end", () => {
|
|
82
|
+
if (res.statusCode !== 201) {
|
|
83
|
+
const errObj = JSON.parse(dataBuffer.toString());
|
|
84
|
+
throw new Error(errObj.message + "(" + errObj.documentation_url + ")");
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// console.log(JSON.parse(dataBuffer.toString()));
|
|
88
|
+
const resData = JSON.parse(dataBuffer.toString());
|
|
89
|
+
resolve(resData.id);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
req.on("error", (error) => {
|
|
96
|
+
reject(error);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
req.write(JSON.stringify({
|
|
100
|
+
tag_name: `v${ver}`,
|
|
101
|
+
target_commitish: currentBranch,
|
|
102
|
+
name: `v${ver}`,
|
|
103
|
+
body: `v${ver}`,
|
|
104
|
+
draft: false,
|
|
105
|
+
prerelease: false
|
|
106
|
+
}));
|
|
107
|
+
|
|
108
|
+
req.end();
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -7,7 +7,6 @@ import ts from "typescript";
|
|
|
7
7
|
import { SdCliBuildResultUtil } from "../utils/SdCliBuildResultUtil";
|
|
8
8
|
import { NamedChunksPlugin } from "@angular-devkit/build-angular/src/webpack/plugins/named-chunks-plugin";
|
|
9
9
|
import {
|
|
10
|
-
CommonJsUsageWarnPlugin,
|
|
11
10
|
DedupeModuleResolvePlugin,
|
|
12
11
|
JavaScriptOptimizerPlugin,
|
|
13
12
|
SuppressExtractedTextChunksWebpackPlugin
|
|
@@ -35,7 +34,6 @@ import { SdCliNgModuleGenerator } from "../ng-tools/SdCliNgModuleGenerator";
|
|
|
35
34
|
import { SdCliCordova } from "../build-tool/SdCliCordova";
|
|
36
35
|
import { SdCliNpmConfigUtil } from "../utils/SdCliNpmConfigUtil";
|
|
37
36
|
import electronBuilder from "electron-builder";
|
|
38
|
-
import { NeverEntryError } from "@simplysm/sd-core-common";
|
|
39
37
|
import LintResult = ESLint.LintResult;
|
|
40
38
|
|
|
41
39
|
export class SdCliClientBuilder extends EventEmitter {
|
|
@@ -85,8 +83,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
85
83
|
} : undefined);
|
|
86
84
|
|
|
87
85
|
// CORDOVA
|
|
88
|
-
if (this._config.
|
|
89
|
-
this._cordova = new SdCliCordova(this._rootPath, this._config.
|
|
86
|
+
if (this._config.builder?.cordova) {
|
|
87
|
+
this._cordova = new SdCliCordova(this._rootPath, this._config.builder.cordova);
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
90
|
|
|
@@ -111,7 +109,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
111
109
|
}
|
|
112
110
|
|
|
113
111
|
// 빌드 준비
|
|
114
|
-
const webpackConfigs = (Object.keys(this._config.
|
|
112
|
+
const webpackConfigs = (Object.keys(this._config.builder ?? { web: {} }) as ("web" | "cordova" | "electron")[])
|
|
115
113
|
.map((builderType) => this._getWebpackConfig(true, builderType));
|
|
116
114
|
const multiCompiler = webpack(webpackConfigs);
|
|
117
115
|
return await new Promise<NextHandleFunction[]>((resolve, reject) => {
|
|
@@ -193,7 +191,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
193
191
|
|
|
194
192
|
// 빌드
|
|
195
193
|
this._logger.debug("Webpack 빌드 수행...");
|
|
196
|
-
const builderTypes = (Object.keys(this._config.
|
|
194
|
+
const builderTypes = (Object.keys(this._config.builder ?? { web: {} }) as ("web" | "cordova" | "electron")[]);
|
|
197
195
|
const webpackConfigs = builderTypes.map((builderType) => this._getWebpackConfig(false, builderType));
|
|
198
196
|
const multipleCompiler = webpack(webpackConfigs);
|
|
199
197
|
const buildResults = await new Promise<ISdCliPackageBuildResult[]>((resolve, reject) => {
|
|
@@ -218,8 +216,8 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
218
216
|
const packageKey = this._getNpmConfig(this._rootPath)!.name.split("/").last()!;
|
|
219
217
|
await augmentAppWithServiceWorker(
|
|
220
218
|
PathUtil.posix(path.relative(this._workspaceRootPath, this._rootPath)) as any,
|
|
221
|
-
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._parsedTsconfig.options.outDir
|
|
222
|
-
`/${packageKey}
|
|
219
|
+
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._parsedTsconfig.options.outDir!))) as any,
|
|
220
|
+
`/${packageKey}/`,
|
|
223
221
|
PathUtil.posix(path.relative(this._workspaceRootPath, path.resolve(this._rootPath, "ngsw-config.json")))
|
|
224
222
|
);
|
|
225
223
|
}
|
|
@@ -234,14 +232,23 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
234
232
|
}
|
|
235
233
|
|
|
236
234
|
// ELECTRON
|
|
237
|
-
if (this._config.
|
|
235
|
+
if (this._config.builder?.electron) {
|
|
238
236
|
const npmConfig = this._getNpmConfig(this._rootPath)!;
|
|
239
237
|
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
const electronVersion = npmConfig.dependencies?.["electron"];
|
|
239
|
+
if (electronVersion === undefined) {
|
|
240
|
+
throw new Error("ELECTRON 빌드 패키지의 'dependencies'에는 'electron'이 반드시 포함되어야 합니다.");
|
|
242
241
|
}
|
|
243
242
|
|
|
244
|
-
|
|
243
|
+
const dotenvVersion = npmConfig.dependencies?.["dotenv"];
|
|
244
|
+
if (dotenvVersion === undefined) {
|
|
245
|
+
throw new Error("ELECTRON 빌드 패키지의 'dependencies'에는 'dotenv'가 반드시 포함되어야 합니다.");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const electronSrcPath = path.resolve(this._rootPath, `.electron/src`);
|
|
249
|
+
const electronDistPath = path.resolve(this._rootPath, `.electron/dist`);
|
|
250
|
+
|
|
251
|
+
await FsUtil.writeJsonAsync(path.resolve(electronSrcPath, `package.json`), {
|
|
245
252
|
name: npmConfig.name,
|
|
246
253
|
version: npmConfig.version,
|
|
247
254
|
description: npmConfig.description,
|
|
@@ -249,24 +256,34 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
249
256
|
author: npmConfig.author,
|
|
250
257
|
license: npmConfig.license,
|
|
251
258
|
devDependencies: {
|
|
252
|
-
"electron":
|
|
259
|
+
"electron": electronVersion.replace("^", "")
|
|
260
|
+
},
|
|
261
|
+
dependencies: {
|
|
262
|
+
"dotenv": dotenvVersion
|
|
253
263
|
}
|
|
254
264
|
});
|
|
255
265
|
|
|
256
|
-
await FsUtil.writeFileAsync(path.resolve(
|
|
266
|
+
await FsUtil.writeFileAsync(path.resolve(electronSrcPath, `.env`), [
|
|
267
|
+
"NODE_ENV=production",
|
|
268
|
+
`SD_VERSION=${npmConfig.version}`,
|
|
269
|
+
(this._config.builder.electron.icon !== undefined) ? `SD_ELECTRON_ICON=${this._config.builder.electron.icon}` : `SD_ELECTRON_ICON=favicon.ico`,
|
|
270
|
+
...(this._config.env !== undefined) ? Object.keys(this._config.env).map((key) => `${key}=${this._config.env![key]}`) : []
|
|
271
|
+
].filterExists().join("\n"));
|
|
257
272
|
|
|
258
|
-
await FsUtil.
|
|
273
|
+
let electronTsFileContent = await FsUtil.readFileAsync(path.resolve(this._rootPath, `src/electron.ts`));
|
|
274
|
+
electronTsFileContent = "require(\"dotenv\").config({ path: `${__dirname}\\\\.env` });\n" + electronTsFileContent;
|
|
275
|
+
const result = ts.transpileModule(electronTsFileContent, { compilerOptions: { module: ts.ModuleKind.CommonJS } });
|
|
276
|
+
await FsUtil.writeFileAsync(path.resolve(electronSrcPath, "electron.js"), result.outputText);
|
|
259
277
|
|
|
260
278
|
await electronBuilder.build({
|
|
261
279
|
targets: electronBuilder.Platform.WINDOWS.createTarget(),
|
|
262
280
|
config: {
|
|
263
|
-
appId: this._config.
|
|
281
|
+
appId: this._config.builder.electron.appId,
|
|
264
282
|
productName: npmConfig.description,
|
|
265
|
-
asar: true,
|
|
266
283
|
nsis: {},
|
|
267
284
|
directories: {
|
|
268
|
-
app:
|
|
269
|
-
output:
|
|
285
|
+
app: electronSrcPath,
|
|
286
|
+
output: electronDistPath
|
|
270
287
|
}
|
|
271
288
|
}
|
|
272
289
|
});
|
|
@@ -300,20 +317,21 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
300
317
|
const internalModuleCachePaths = watch ? this._getInternalModuleCachePaths(workspaceName) : undefined;
|
|
301
318
|
|
|
302
319
|
const npmConfig = this._getNpmConfig(this._rootPath)!;
|
|
303
|
-
const pkgVersion = npmConfig.version;
|
|
304
|
-
const ngVersion = this._getNpmConfig(FsUtil.findAllParentChildDirPaths("node_modules/@angular/core", this._rootPath, this._workspaceRootPath)[0])!.version;
|
|
320
|
+
// const pkgVersion = npmConfig.version;
|
|
321
|
+
// const ngVersion = this._getNpmConfig(FsUtil.findAllParentChildDirPaths("node_modules/@angular/core", this._rootPath, this._workspaceRootPath)[0])!.version;
|
|
322
|
+
|
|
323
|
+
const workspacePkgLockContent = FsUtil.readFile(path.resolve(this._workspaceRootPath, "package-lock.json"));
|
|
305
324
|
|
|
306
325
|
const pkgKey = npmConfig.name.split("/").last()!;
|
|
307
|
-
const publicPath =
|
|
326
|
+
const publicPath = builderType === "web" ? `/${pkgKey}/` : watch ? `/${pkgKey}/${builderType}/` : ``;
|
|
308
327
|
|
|
309
328
|
const cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
310
|
-
const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
329
|
+
// const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
311
330
|
|
|
312
|
-
const distPath = (builderType === "cordova" && !watch)
|
|
313
|
-
? path.resolve(this.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
: `${this._parsedTsconfig.options.outDir}/${builderType}`;
|
|
331
|
+
const distPath = (builderType === "cordova" && !watch) ? path.resolve(this._cordova!.cordovaPath, "www")
|
|
332
|
+
: (builderType === "electron" && !watch) ? path.resolve(this._rootPath, ".electron/src")
|
|
333
|
+
: builderType === "web" ? this._parsedTsconfig.options.outDir
|
|
334
|
+
: `${this._parsedTsconfig.options.outDir}/${builderType}`;
|
|
317
335
|
|
|
318
336
|
const sassImplementation = new SassWorkerImplementation();
|
|
319
337
|
|
|
@@ -376,14 +394,15 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
376
394
|
cache: {
|
|
377
395
|
type: "filesystem",
|
|
378
396
|
profile: watch ? undefined : false,
|
|
379
|
-
cacheDirectory: path.resolve(
|
|
397
|
+
cacheDirectory: path.resolve(cacheBasePath, "angular-webpack"),
|
|
380
398
|
maxMemoryGenerations: 1,
|
|
381
399
|
name: createHash("sha1")
|
|
382
|
-
.update(
|
|
383
|
-
.update(
|
|
400
|
+
.update(workspacePkgLockContent)
|
|
401
|
+
// .update(pkgVersion)
|
|
402
|
+
// .update(ngVersion)
|
|
384
403
|
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
385
|
-
.update(this._workspaceRootPath)
|
|
386
|
-
.update(this._rootPath)
|
|
404
|
+
// .update(this._workspaceRootPath)
|
|
405
|
+
// .update(this._rootPath)
|
|
387
406
|
.update(JSON.stringify(this._config))
|
|
388
407
|
.update(watch.toString())
|
|
389
408
|
.digest("hex")
|
|
@@ -490,7 +509,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
490
509
|
{
|
|
491
510
|
loader: "@angular-devkit/build-angular/src/babel/webpack-loader",
|
|
492
511
|
options: {
|
|
493
|
-
cacheDirectory: path.resolve(
|
|
512
|
+
cacheDirectory: path.resolve(cacheBasePath, "babel-webpack"),
|
|
494
513
|
scriptTarget: ts.ScriptTarget.ES2017,
|
|
495
514
|
aot: true,
|
|
496
515
|
optimize: !watch,
|
|
@@ -564,7 +583,9 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
564
583
|
]
|
|
565
584
|
},
|
|
566
585
|
plugins: [
|
|
567
|
-
new NodePolyfillPlugin(
|
|
586
|
+
new NodePolyfillPlugin({
|
|
587
|
+
excludeAliases: builderType === "electron" ? ["process"] : []
|
|
588
|
+
}),
|
|
568
589
|
new NamedChunksPlugin(),
|
|
569
590
|
new DedupeModuleResolvePlugin(),
|
|
570
591
|
new webpack.ProgressPlugin({
|
|
@@ -578,9 +599,6 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
578
599
|
}
|
|
579
600
|
}
|
|
580
601
|
}),
|
|
581
|
-
new CommonJsUsageWarnPlugin({
|
|
582
|
-
allowedDependencies: ["@fortawesome"]
|
|
583
|
-
}),
|
|
584
602
|
...watch ? [] : [
|
|
585
603
|
new LicenseWebpackPlugin({
|
|
586
604
|
stats: { warnings: false, errors: false },
|
|
@@ -612,18 +630,18 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
612
630
|
{
|
|
613
631
|
context: this._cordova!.cordovaPath,
|
|
614
632
|
to: `cordova-${platform}/plugins`,
|
|
615
|
-
from: `platforms/${platform}/
|
|
633
|
+
from: `platforms/${platform}/platform_www/plugins`,
|
|
616
634
|
noErrorOnMissing: true
|
|
617
635
|
},
|
|
618
636
|
{
|
|
619
637
|
context: this._cordova!.cordovaPath,
|
|
620
638
|
to: `cordova-${platform}/cordova.js`,
|
|
621
|
-
from: `platforms/${platform}/
|
|
639
|
+
from: `platforms/${platform}/platform_www/cordova.js`
|
|
622
640
|
},
|
|
623
641
|
{
|
|
624
642
|
context: this._cordova!.cordovaPath,
|
|
625
643
|
to: `cordova-${platform}/cordova_plugins.js`,
|
|
626
|
-
from: `platforms/${platform}/
|
|
644
|
+
from: `platforms/${platform}/platform_www/cordova_plugins.js`,
|
|
627
645
|
noErrorOnMissing: true
|
|
628
646
|
},
|
|
629
647
|
{
|
|
@@ -685,7 +703,7 @@ export class SdCliClientBuilder extends EventEmitter {
|
|
|
685
703
|
cache: {
|
|
686
704
|
enabled: true,
|
|
687
705
|
basePath: cacheBasePath,
|
|
688
|
-
path:
|
|
706
|
+
path: path.resolve(cacheBasePath, "index-webpack")
|
|
689
707
|
},
|
|
690
708
|
postTransform: undefined,
|
|
691
709
|
optimization: {
|
|
@@ -187,11 +187,12 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
187
187
|
|
|
188
188
|
const npmConfig = this._getNpmConfig(this._rootPath)!;
|
|
189
189
|
const pkgKey = npmConfig.name.split("/").last()!;
|
|
190
|
-
const pkgVersion = npmConfig.version;
|
|
190
|
+
// const pkgVersion = npmConfig.version;
|
|
191
191
|
|
|
192
|
-
const
|
|
193
|
-
const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
192
|
+
const workspacePkgLockContent = FsUtil.readFile(path.resolve(this._workspaceRootPath, "package-lock.json"));
|
|
194
193
|
|
|
194
|
+
const cacheBasePath = path.resolve(this._rootPath, ".cache");
|
|
195
|
+
// const cachePath = path.resolve(cacheBasePath, pkgVersion);
|
|
195
196
|
|
|
196
197
|
let prevProgressMessage = "";
|
|
197
198
|
return {
|
|
@@ -241,13 +242,11 @@ export class SdCliServerBuilder extends EventEmitter {
|
|
|
241
242
|
cache: {
|
|
242
243
|
type: "filesystem",
|
|
243
244
|
profile: watch ? undefined : false,
|
|
244
|
-
cacheDirectory: path.resolve(
|
|
245
|
+
cacheDirectory: path.resolve(cacheBasePath, "server-webpack"),
|
|
245
246
|
maxMemoryGenerations: 1,
|
|
246
247
|
name: createHash("sha1")
|
|
247
|
-
.update(
|
|
248
|
+
.update(workspacePkgLockContent)
|
|
248
249
|
.update(JSON.stringify(this._parsedTsconfig.options))
|
|
249
|
-
.update(this._workspaceRootPath)
|
|
250
|
-
.update(this._rootPath)
|
|
251
250
|
.update(JSON.stringify(this._config))
|
|
252
251
|
.update(watch.toString())
|
|
253
252
|
.digest("hex")
|
package/src/commons.ts
CHANGED
|
@@ -4,6 +4,11 @@ export interface INpmConfig {
|
|
|
4
4
|
description?: string;
|
|
5
5
|
author?: string;
|
|
6
6
|
license?: string;
|
|
7
|
+
repository: string | {
|
|
8
|
+
type: string;
|
|
9
|
+
url: string;
|
|
10
|
+
directory?: string;
|
|
11
|
+
};
|
|
7
12
|
type?: "module";
|
|
8
13
|
workspaces?: string[];
|
|
9
14
|
main?: string;
|
|
@@ -66,7 +71,7 @@ export interface ISdCliServerPackageConfig {
|
|
|
66
71
|
|
|
67
72
|
export interface ISdCliClientPackageConfig {
|
|
68
73
|
type: "client";
|
|
69
|
-
|
|
74
|
+
builder?: {
|
|
70
75
|
web?: ISdCliClientBuilderWebConfig;
|
|
71
76
|
cordova?: ISdCliClientBuilderCordovaConfig;
|
|
72
77
|
electron?: ISdCliClientBuilderElectronConfig;
|
|
@@ -77,7 +82,7 @@ export interface ISdCliClientPackageConfig {
|
|
|
77
82
|
publish?: TSdCliPublishConfig;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
export type TSdCliPublishConfig = ISdCliFtpPublishConfig | ISdCliLocalDirectoryPublishConfig;
|
|
85
|
+
export type TSdCliPublishConfig = ISdCliFtpPublishConfig | ISdCliLocalDirectoryPublishConfig | ISdCliGithubPublishConfig;
|
|
81
86
|
|
|
82
87
|
export interface ISdCliFtpPublishConfig {
|
|
83
88
|
type: "ftp" | "ftps" | "sftp";
|
|
@@ -93,17 +98,22 @@ export interface ISdCliLocalDirectoryPublishConfig {
|
|
|
93
98
|
path: string;
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
export interface ISdCliGithubPublishConfig {
|
|
102
|
+
type: "github";
|
|
103
|
+
apiKey: string;
|
|
104
|
+
files: { from: string; to: string }[];
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
export interface ISdCliClientBuilderWebConfig {
|
|
97
108
|
}
|
|
98
109
|
|
|
99
110
|
export interface ISdCliClientBuilderCordovaConfig {
|
|
100
|
-
type: "cordova";
|
|
101
111
|
appId: string;
|
|
102
112
|
appName: string;
|
|
103
113
|
plugins?: string[];
|
|
104
114
|
icon?: string;
|
|
105
115
|
debug?: boolean;
|
|
106
|
-
|
|
116
|
+
target?: {
|
|
107
117
|
browser?: {};
|
|
108
118
|
android?: {
|
|
109
119
|
bundle?: boolean;
|
|
@@ -120,9 +130,5 @@ export interface ISdCliClientBuilderCordovaConfig {
|
|
|
120
130
|
|
|
121
131
|
export interface ISdCliClientBuilderElectronConfig {
|
|
122
132
|
appId: string;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
export type TSdCliClientBuilderConfig =
|
|
126
|
-
ISdCliClientBuilderWebConfig
|
|
127
|
-
| ISdCliClientBuilderCordovaConfig
|
|
128
|
-
| ISdCliClientBuilderElectronConfig;
|
|
133
|
+
icon?: string;
|
|
134
|
+
}
|
|
@@ -83,7 +83,11 @@ export class SdCliWorkspace {
|
|
|
83
83
|
if (typeof pkg.config.server === "string") {
|
|
84
84
|
const serverInfo = this._serverInfoMap.getOrCreate(pkg.config.server, { middlewares: [], clientInfos: [] });
|
|
85
85
|
serverInfo.middlewares.push(...middlewares);
|
|
86
|
-
serverInfo.clientInfos.push({
|
|
86
|
+
serverInfo.clientInfos.push({
|
|
87
|
+
pkgKey: pkg.name.split("/").last()!,
|
|
88
|
+
platforms: pkg.config.builder ? Object.keys(pkg.config.builder) : ["web"],
|
|
89
|
+
cordovaTargets: pkg.config.builder?.cordova?.target ? Object.keys(pkg.config.builder.cordova.target) : ["browser"]
|
|
90
|
+
});
|
|
87
91
|
}
|
|
88
92
|
else { // DEV SERVER
|
|
89
93
|
const serverInfo = this._serverInfoMap.getOrCreate("_", { middlewares: [], clientInfos: [] });
|
|
@@ -96,7 +100,11 @@ export class SdCliWorkspace {
|
|
|
96
100
|
await server.listenAsync();
|
|
97
101
|
serverInfo.server = server;
|
|
98
102
|
serverInfo.server.devMiddlewares = middlewares;
|
|
99
|
-
serverInfo.clientInfos.push({
|
|
103
|
+
serverInfo.clientInfos.push({
|
|
104
|
+
pkgKey: pkg.name.split("/").last()!,
|
|
105
|
+
platforms: pkg.config.builder ? Object.keys(pkg.config.builder) : ["web"],
|
|
106
|
+
cordovaTargets: pkg.config.builder?.cordova?.target ? Object.keys(pkg.config.builder.cordova.target) : ["browser"]
|
|
107
|
+
});
|
|
100
108
|
}
|
|
101
109
|
}
|
|
102
110
|
}
|
|
@@ -250,6 +258,9 @@ export class SdCliWorkspace {
|
|
|
250
258
|
await SdProcess.spawnAsync("git add .");
|
|
251
259
|
await SdProcess.spawnAsync(`git commit -m "v${this._npmConfig.version}"`);
|
|
252
260
|
await SdProcess.spawnAsync(`git tag -a "v${this._npmConfig.version}" -m "v${this._npmConfig.version}"`);
|
|
261
|
+
|
|
262
|
+
this._logger.debug("새 버전 푸쉬...");
|
|
263
|
+
await SdProcess.spawnAsync("git push --tags");
|
|
253
264
|
}
|
|
254
265
|
|
|
255
266
|
this._logger.debug("배포 시작...");
|
|
@@ -361,11 +372,28 @@ export class SdCliWorkspace {
|
|
|
361
372
|
const portStr = serverInfo.server.options.port.toString();
|
|
362
373
|
|
|
363
374
|
for (const clientInfo of serverInfo.clientInfos) {
|
|
364
|
-
|
|
375
|
+
for (const platform of clientInfo.platforms) {
|
|
376
|
+
if (platform === "web") {
|
|
377
|
+
clientHrefs.push(`${protocolStr}://localhost:${portStr}/${clientInfo.pkgKey}/`);
|
|
378
|
+
}
|
|
379
|
+
else if (platform === "electron") {
|
|
380
|
+
clientHrefs.push(`sd-cli run-electron ${clientInfo.pkgKey} http://localhost:${portStr}`);
|
|
381
|
+
}
|
|
382
|
+
else if (platform === "cordova") {
|
|
383
|
+
for (const target of clientInfo.cordovaTargets) {
|
|
384
|
+
if (target === "browser") {
|
|
385
|
+
clientHrefs.push(`${protocolStr}://localhost:${portStr}/${clientInfo.pkgKey}/${platform}/`);
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
clientHrefs.push(`sd-cli run-cordova ${clientInfo.pkgKey} http://[IP]:${portStr}`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
365
393
|
}
|
|
366
394
|
}
|
|
367
395
|
if (clientHrefs.length > 0) {
|
|
368
|
-
this._logger.log(`오픈된
|
|
396
|
+
this._logger.log(`오픈된 클라이언트:\n${clientHrefs.join("\n")}`);
|
|
369
397
|
}
|
|
370
398
|
}
|
|
371
399
|
}
|
|
@@ -373,5 +401,5 @@ export class SdCliWorkspace {
|
|
|
373
401
|
interface IServerInfo {
|
|
374
402
|
server?: SdServiceServer;
|
|
375
403
|
middlewares: NextHandleFunction[];
|
|
376
|
-
clientInfos: { pkgKey: string }[];
|
|
404
|
+
clientInfos: { pkgKey: string; platforms: string[]; cordovaTargets: string[] }[];
|
|
377
405
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./build-tool/SdCliCacheCompilerHost";
|
|
2
2
|
export * from "./build-tool/SdCliCordova";
|
|
3
3
|
export * from "./build-tool/SdCliElectron";
|
|
4
|
+
export * from "./build-tool/SdCliGithubApi";
|
|
4
5
|
export * from "./build-tool/SdCliIndexFileGenerator";
|
|
5
6
|
export * from "./build-tool/SdCliNgCacheCompilerHost";
|
|
6
7
|
export * from "./build-tool/SdCliPackageLinter";
|
|
@@ -11,6 +11,7 @@ import { SdCliClientBuilder } from "../builder/SdCliClientBuilder";
|
|
|
11
11
|
import { NextHandleFunction } from "connect";
|
|
12
12
|
import { SdStorage } from "@simplysm/sd-storage";
|
|
13
13
|
import ts from "typescript";
|
|
14
|
+
import { SdCliGithubApi } from "../build-tool/SdCliGithubApi";
|
|
14
15
|
|
|
15
16
|
export class SdCliPackage extends EventEmitter {
|
|
16
17
|
private readonly _npmConfig: INpmConfig;
|
|
@@ -96,7 +97,23 @@ export class SdCliPackage extends EventEmitter {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
else {
|
|
99
|
-
if (this.config.publish.type === "
|
|
100
|
+
if (this.config.publish.type === "github") {
|
|
101
|
+
const repoUrl = typeof this._npmConfig.repository === "string" ? this._npmConfig.repository : this._npmConfig.repository.url;
|
|
102
|
+
const repoOwner = repoUrl.split("/").slice(-2)[0];
|
|
103
|
+
const repoName = repoUrl.split("/").slice(-2)[1].replace(/\..*/g, "");
|
|
104
|
+
|
|
105
|
+
const github = new SdCliGithubApi(
|
|
106
|
+
this.config.publish.apiKey,
|
|
107
|
+
repoOwner,
|
|
108
|
+
repoName
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
await github.uploadAsync(this._npmConfig.version, this.config.publish.files.map((item) => ({
|
|
112
|
+
buffer: FsUtil.readFileBuffer(path.resolve(this.rootPath, "dist", item.from)),
|
|
113
|
+
name: item.to
|
|
114
|
+
})));
|
|
115
|
+
}
|
|
116
|
+
else if (this.config.publish.type === "ftp" || this.config.publish.type === "ftps" || this.config.publish.type === "sftp") {
|
|
100
117
|
const tsconfigPath = path.resolve(this.rootPath, "tsconfig-build.json");
|
|
101
118
|
const tsconfig = FsUtil.readJson(tsconfigPath);
|
|
102
119
|
const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, this.rootPath, tsconfig.angularCompilerOptions);
|