@simplysm/sd-cli 12.15.39 → 12.15.40
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/entry/SdCliCordova.d.ts +33 -1
- package/dist/entry/SdCliCordova.js +84 -88
- package/dist/entry/SdCliElectron.d.ts +5 -1
- package/dist/entry/SdCliElectron.js +21 -21
- package/dist/entry/SdCliLocalUpdate.d.ts +1 -1
- package/dist/entry/SdCliLocalUpdate.js +3 -3
- package/dist/entry/SdCliProject.d.ts +4 -1
- package/dist/entry/SdCliProject.js +11 -11
- package/dist/pkg-builders/SdProjectBuildRunner.d.ts +6 -1
- package/dist/pkg-builders/SdProjectBuildRunner.js +27 -27
- package/dist/pkg-builders/client/SdClientBuildRunner.d.ts +2 -1
- package/dist/pkg-builders/client/SdClientBuildRunner.js +8 -10
- package/dist/pkg-builders/client/SdNgBundler.d.ts +22 -1
- package/dist/pkg-builders/client/SdNgBundler.js +70 -80
- package/dist/pkg-builders/client/SdNgBundlerContext.d.ts +3 -1
- package/dist/pkg-builders/client/SdNgBundlerContext.js +9 -10
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.d.ts +2 -1
- package/dist/pkg-builders/lib/SdCliIndexFileGenerator.js +5 -5
- package/dist/pkg-builders/lib/SdJsLibBuildRunner.d.ts +1 -1
- package/dist/pkg-builders/lib/SdJsLibBuildRunner.js +2 -2
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.d.ts +1 -1
- package/dist/pkg-builders/lib/SdTsLibBuildRunner.js +2 -3
- package/dist/pkg-builders/lib/SdTsLibBuilder.d.ts +2 -1
- package/dist/pkg-builders/lib/SdTsLibBuilder.js +7 -8
- package/dist/pkg-builders/server/SdServerBuildRunner.d.ts +3 -1
- package/dist/pkg-builders/server/SdServerBuildRunner.js +6 -7
- package/dist/pkg-builders/server/SdServerBundler.d.ts +6 -1
- package/dist/pkg-builders/server/SdServerBundler.js +21 -23
- package/dist/ts-compiler/ScopePathSet.d.ts +1 -1
- package/dist/ts-compiler/ScopePathSet.js +3 -4
- package/dist/ts-compiler/SdDepCache.d.ts +45 -1
- package/dist/ts-compiler/SdDepCache.js +71 -69
- package/dist/ts-compiler/SdStyleBundler.d.ts +5 -1
- package/dist/ts-compiler/SdStyleBundler.js +25 -26
- package/dist/ts-compiler/SdTsCompiler.d.ts +20 -1
- package/dist/ts-compiler/SdTsCompiler.js +122 -129
- package/dist/utils/SdCliPerformanceTimer.d.ts +2 -1
- package/dist/utils/SdCliPerformanceTimer.js +9 -9
- package/package.json +8 -8
- package/src/entry/SdCliCordova.ts +89 -89
- package/src/entry/SdCliElectron.ts +21 -21
- package/src/entry/SdCliLocalUpdate.ts +3 -3
- package/src/entry/SdCliProject.ts +11 -11
- package/src/pkg-builders/SdProjectBuildRunner.ts +27 -27
- package/src/pkg-builders/client/SdClientBuildRunner.ts +10 -10
- package/src/pkg-builders/client/SdNgBundler.ts +78 -78
- package/src/pkg-builders/client/SdNgBundlerContext.ts +10 -10
- package/src/pkg-builders/lib/SdCliIndexFileGenerator.ts +5 -5
- package/src/pkg-builders/lib/SdJsLibBuildRunner.ts +2 -2
- package/src/pkg-builders/lib/SdTsLibBuildRunner.ts +3 -3
- package/src/pkg-builders/lib/SdTsLibBuilder.ts +8 -8
- package/src/pkg-builders/server/SdServerBuildRunner.ts +7 -7
- package/src/pkg-builders/server/SdServerBundler.ts +23 -23
- package/src/ts-compiler/ScopePathSet.ts +4 -4
- package/src/ts-compiler/SdDepCache.ts +47 -47
- package/src/ts-compiler/SdStyleBundler.ts +26 -26
- package/src/ts-compiler/SdTsCompiler.ts +130 -130
- package/src/utils/SdCliPerformanceTimer.ts +9 -9
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
import { ISdClientBuilderCordovaConfig } from "../types/config/ISdProjectConfig";
|
|
2
2
|
export declare class SdCliCordova {
|
|
3
|
-
#private;
|
|
4
3
|
private readonly _opt;
|
|
4
|
+
private readonly _CORDOVA_DIR_NAME;
|
|
5
|
+
private readonly _PLATFORMS_DIR_NAME;
|
|
6
|
+
private readonly _WWW_DIR_NAME;
|
|
7
|
+
private readonly _PLUGINS_DIR_NAME;
|
|
8
|
+
private readonly _PLUGINS_FETCH_FILE;
|
|
9
|
+
private readonly _ANDROID_SDK_VERSION;
|
|
10
|
+
private readonly _KEYSTORE_FILE_NAME;
|
|
11
|
+
private readonly _CONFIG_XML_FILE_NAME;
|
|
12
|
+
private readonly _CONFIG_XML_BACKUP_FILE_NAME;
|
|
13
|
+
private readonly _BUILD_JSON_FILE_NAME;
|
|
14
|
+
private readonly _ANDROID_SIGNING_PROP_PATH;
|
|
15
|
+
private readonly _ICON_DIR_PATH;
|
|
16
|
+
private readonly _SPLASH_SCREEN_DIR_PATH;
|
|
17
|
+
private readonly _SPLASH_SCREEN_XML_FILE;
|
|
18
|
+
private readonly _platforms;
|
|
19
|
+
private readonly _npmConfig;
|
|
5
20
|
constructor(_opt: {
|
|
6
21
|
pkgPath: string;
|
|
7
22
|
config: ISdClientBuilderCordovaConfig;
|
|
8
23
|
});
|
|
24
|
+
private static readonly _logger;
|
|
25
|
+
private static _execAsync;
|
|
9
26
|
initializeAsync(): Promise<void>;
|
|
27
|
+
private _initializeCordovaProjectAsync;
|
|
28
|
+
private _managePlatformsAsync;
|
|
29
|
+
private _managePluginsAsync;
|
|
30
|
+
private _removeUnusedPluginsAsync;
|
|
31
|
+
private _installNewPluginsAsync;
|
|
32
|
+
private _setupAndroidSign;
|
|
33
|
+
private _createBuildConfig;
|
|
34
|
+
private _setupIconAndSplashScreen;
|
|
35
|
+
private _configureXml;
|
|
36
|
+
private _configureBasicXmlSettings;
|
|
37
|
+
private _configureAndroidXmlSettings;
|
|
10
38
|
buildAsync(outPath: string): Promise<void>;
|
|
39
|
+
private _processBuildOutputAsync;
|
|
40
|
+
private _copyAndroidBuildOutput;
|
|
41
|
+
private _createUpdateZipAsync;
|
|
42
|
+
private _addFilesToZip;
|
|
11
43
|
static runWebviewOnDeviceAsync(opt: {
|
|
12
44
|
platform: string;
|
|
13
45
|
package: string;
|
|
@@ -1,83 +1,80 @@
|
|
|
1
|
-
var _a;
|
|
2
1
|
import * as path from "path";
|
|
3
2
|
import { FsUtils, PathUtils, SdLogger, SdProcess } from "@simplysm/sd-core-node";
|
|
4
3
|
import { SdZip, XmlConvert } from "@simplysm/sd-core-common";
|
|
5
4
|
export class SdCliCordova {
|
|
6
|
-
// 상수 정의
|
|
7
|
-
#CORDOVA_DIR_NAME = ".cordova";
|
|
8
|
-
#PLATFORMS_DIR_NAME = "platforms";
|
|
9
|
-
#WWW_DIR_NAME = "www";
|
|
10
|
-
#PLUGINS_DIR_NAME = "plugins";
|
|
11
|
-
#PLUGINS_FETCH_FILE = "fetch.json";
|
|
12
|
-
#ANDROID_SDK_VERSION = "35"; //cordova-android@14
|
|
13
|
-
#KEYSTORE_FILE_NAME = "android.keystore";
|
|
14
|
-
#CONFIG_XML_FILE_NAME = "config.xml";
|
|
15
|
-
#CONFIG_XML_BACKUP_FILE_NAME = "config.xml.bak";
|
|
16
|
-
#BUILD_JSON_FILE_NAME = "build.json";
|
|
17
|
-
#ANDROID_SIGNING_PROP_PATH = "platforms/android/release-signing.properties";
|
|
18
|
-
#ICON_DIR_PATH = "res/icons";
|
|
19
|
-
#SPLASH_SCREEN_DIR_PATH = "res/screen/android";
|
|
20
|
-
#SPLASH_SCREEN_XML_FILE = "splashscreen.xml";
|
|
21
|
-
#platforms;
|
|
22
|
-
#npmConfig;
|
|
23
5
|
constructor(_opt) {
|
|
24
6
|
this._opt = _opt;
|
|
25
|
-
|
|
26
|
-
this
|
|
7
|
+
// 상수 정의
|
|
8
|
+
this._CORDOVA_DIR_NAME = ".cordova";
|
|
9
|
+
this._PLATFORMS_DIR_NAME = "platforms";
|
|
10
|
+
this._WWW_DIR_NAME = "www";
|
|
11
|
+
this._PLUGINS_DIR_NAME = "plugins";
|
|
12
|
+
this._PLUGINS_FETCH_FILE = "fetch.json";
|
|
13
|
+
this._ANDROID_SDK_VERSION = "35"; //cordova-android@14
|
|
14
|
+
this._KEYSTORE_FILE_NAME = "android.keystore";
|
|
15
|
+
this._CONFIG_XML_FILE_NAME = "config.xml";
|
|
16
|
+
this._CONFIG_XML_BACKUP_FILE_NAME = "config.xml.bak";
|
|
17
|
+
this._BUILD_JSON_FILE_NAME = "build.json";
|
|
18
|
+
this._ANDROID_SIGNING_PROP_PATH = "platforms/android/release-signing.properties";
|
|
19
|
+
this._ICON_DIR_PATH = "res/icons";
|
|
20
|
+
this._SPLASH_SCREEN_DIR_PATH = "res/screen/android";
|
|
21
|
+
this._SPLASH_SCREEN_XML_FILE = "splashscreen.xml";
|
|
22
|
+
this._platforms = Object.keys(this._opt.config.platform ?? { browser: {} });
|
|
23
|
+
this._npmConfig = FsUtils.readJson(path.resolve(this._opt.pkgPath, "package.json"));
|
|
27
24
|
}
|
|
28
|
-
static
|
|
29
|
-
static async
|
|
30
|
-
this
|
|
25
|
+
static { this._logger = SdLogger.get(["simplysm", "sd-cli", "SdCliCordova"]); }
|
|
26
|
+
static async _execAsync(cmd, args, cwd) {
|
|
27
|
+
this._logger.debug(`실행 명령: ${cmd + " " + args.join(" ")}`);
|
|
31
28
|
const msg = await SdProcess.spawnAsync(cmd, args, { cwd });
|
|
32
|
-
this
|
|
29
|
+
this._logger.debug(`실행 결과: ${msg}`);
|
|
33
30
|
}
|
|
34
31
|
async initializeAsync() {
|
|
35
|
-
const cordovaPath = path.resolve(this._opt.pkgPath, this
|
|
32
|
+
const cordovaPath = path.resolve(this._opt.pkgPath, this._CORDOVA_DIR_NAME);
|
|
36
33
|
// 1. Cordova 프로젝트 초기화
|
|
37
|
-
await this
|
|
34
|
+
await this._initializeCordovaProjectAsync(cordovaPath);
|
|
38
35
|
// 2. 플랫폼 관리
|
|
39
|
-
await this
|
|
36
|
+
await this._managePlatformsAsync(cordovaPath);
|
|
40
37
|
// 3. 플러그인 관리
|
|
41
|
-
await this
|
|
38
|
+
await this._managePluginsAsync(cordovaPath);
|
|
42
39
|
// 4. 안드로이드 서명 설정
|
|
43
|
-
this
|
|
40
|
+
this._setupAndroidSign(cordovaPath);
|
|
44
41
|
// 5. 빌드 설정 파일 생성
|
|
45
|
-
this
|
|
42
|
+
this._createBuildConfig(cordovaPath);
|
|
46
43
|
// 6. 아이콘 및 스플래시 스크린 설정
|
|
47
|
-
this
|
|
44
|
+
this._setupIconAndSplashScreen(cordovaPath);
|
|
48
45
|
// 7. XML 설정 구성
|
|
49
|
-
this
|
|
46
|
+
this._configureXml(cordovaPath);
|
|
50
47
|
// 8. 각 플랫폼 www 준비
|
|
51
|
-
await
|
|
48
|
+
await SdCliCordova._execAsync("npx", ["cordova", "prepare"], cordovaPath);
|
|
52
49
|
}
|
|
53
50
|
// 1. Cordova 프로젝트 초기화
|
|
54
|
-
async
|
|
51
|
+
async _initializeCordovaProjectAsync(cordovaPath) {
|
|
55
52
|
if (FsUtils.exists(cordovaPath)) {
|
|
56
|
-
|
|
53
|
+
SdCliCordova._logger.log("이미 생성되어있는 '.cordova'를 사용합니다.");
|
|
57
54
|
}
|
|
58
55
|
else {
|
|
59
56
|
// await SdCliCordova.#execAsync("npx", ["cordova", "telemetry", "on"], this._opt.pkgPath);
|
|
60
57
|
// 프로젝트 생성
|
|
61
|
-
await
|
|
58
|
+
await SdCliCordova._execAsync("npx", ["cordova", "create", cordovaPath, this._opt.config.appId, this._opt.config.appName], process.cwd());
|
|
62
59
|
}
|
|
63
60
|
// platforms 폴더 혹시 없으면 생성
|
|
64
|
-
FsUtils.mkdirs(path.resolve(cordovaPath, this
|
|
61
|
+
FsUtils.mkdirs(path.resolve(cordovaPath, this._PLATFORMS_DIR_NAME));
|
|
65
62
|
// www 폴더 혹시 없으면 생성
|
|
66
|
-
FsUtils.mkdirs(path.resolve(cordovaPath, this
|
|
63
|
+
FsUtils.mkdirs(path.resolve(cordovaPath, this._WWW_DIR_NAME));
|
|
67
64
|
}
|
|
68
65
|
// 2. 플랫폼 관리
|
|
69
|
-
async
|
|
70
|
-
const alreadyPlatforms = FsUtils.readdir(path.resolve(cordovaPath, this
|
|
66
|
+
async _managePlatformsAsync(cordovaPath) {
|
|
67
|
+
const alreadyPlatforms = FsUtils.readdir(path.resolve(cordovaPath, this._PLATFORMS_DIR_NAME));
|
|
71
68
|
// 미설치 빌드 플랫폼 신규 생성
|
|
72
|
-
for (const platform of this
|
|
69
|
+
for (const platform of this._platforms) {
|
|
73
70
|
if (alreadyPlatforms.includes(platform))
|
|
74
71
|
continue;
|
|
75
|
-
await
|
|
72
|
+
await SdCliCordova._execAsync("npx", ["cordova", "platform", "add", platform], cordovaPath);
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
// 3. 플러그인 관리
|
|
79
|
-
async
|
|
80
|
-
const pluginsFetchPath = path.resolve(cordovaPath, this
|
|
76
|
+
async _managePluginsAsync(cordovaPath) {
|
|
77
|
+
const pluginsFetchPath = path.resolve(cordovaPath, this._PLUGINS_DIR_NAME, this._PLUGINS_FETCH_FILE);
|
|
81
78
|
const pluginsFetch = FsUtils.exists(pluginsFetchPath) ? FsUtils.readJson(pluginsFetchPath) : {};
|
|
82
79
|
const alreadyPlugins = Object.keys(pluginsFetch).map((key) => ({
|
|
83
80
|
name: key,
|
|
@@ -86,14 +83,14 @@ export class SdCliCordova {
|
|
|
86
83
|
}));
|
|
87
84
|
const usePlugins = (this._opt.config.plugins ?? []).distinct();
|
|
88
85
|
// 사용하지 않는 플러그인 제거 및 새 플러그인 설치 - 의존성 때문에 순차 처리
|
|
89
|
-
await this
|
|
90
|
-
await this
|
|
86
|
+
await this._removeUnusedPluginsAsync(cordovaPath, alreadyPlugins, usePlugins);
|
|
87
|
+
await this._installNewPluginsAsync(cordovaPath, alreadyPlugins, usePlugins);
|
|
91
88
|
}
|
|
92
|
-
async
|
|
89
|
+
async _removeUnusedPluginsAsync(cordovaPath, alreadyPlugins, usePlugins) {
|
|
93
90
|
for (const alreadyPlugin of alreadyPlugins) {
|
|
94
91
|
if (!usePlugins.includes(alreadyPlugin.id) && !usePlugins.includes(alreadyPlugin.name)) {
|
|
95
92
|
try {
|
|
96
|
-
await
|
|
93
|
+
await SdCliCordova._execAsync("npx", ["cordova", "plugin", "remove", alreadyPlugin.name], cordovaPath);
|
|
97
94
|
}
|
|
98
95
|
catch (err) {
|
|
99
96
|
// 의존성으로 인한 skip 메시지는 무시 (로그 생략)
|
|
@@ -105,19 +102,19 @@ export class SdCliCordova {
|
|
|
105
102
|
}
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
|
-
async
|
|
105
|
+
async _installNewPluginsAsync(cordovaPath, alreadyPlugins, usePlugins) {
|
|
109
106
|
// 병렬로 플러그인을 설치하면 충돌이 발생할 수 있으므로 순차 처리
|
|
110
107
|
for (const usePlugin of usePlugins) {
|
|
111
108
|
const isPluginAlreadyInstalled = alreadyPlugins.some((plugin) => usePlugin === plugin.id || usePlugin === plugin.name);
|
|
112
109
|
if (!isPluginAlreadyInstalled) {
|
|
113
|
-
await
|
|
110
|
+
await SdCliCordova._execAsync("npx", ["cordova", "plugin", "add", usePlugin], cordovaPath);
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
// 4. 안드로이드 서명 설정
|
|
118
|
-
|
|
119
|
-
const keystorePath = path.resolve(cordovaPath, this
|
|
120
|
-
const signingPropsPath = path.resolve(cordovaPath, this
|
|
115
|
+
_setupAndroidSign(cordovaPath) {
|
|
116
|
+
const keystorePath = path.resolve(cordovaPath, this._KEYSTORE_FILE_NAME);
|
|
117
|
+
const signingPropsPath = path.resolve(cordovaPath, this._ANDROID_SIGNING_PROP_PATH);
|
|
121
118
|
if (this._opt.config.platform?.android?.sign) {
|
|
122
119
|
FsUtils.copy(path.resolve(this._opt.pkgPath, this._opt.config.platform.android.sign.keystore), keystorePath);
|
|
123
120
|
}
|
|
@@ -128,9 +125,9 @@ export class SdCliCordova {
|
|
|
128
125
|
}
|
|
129
126
|
}
|
|
130
127
|
// 5. 빌드 설정 파일 생성
|
|
131
|
-
|
|
132
|
-
const buildJsonPath = path.resolve(cordovaPath, this
|
|
133
|
-
const keystorePath = path.resolve(cordovaPath, this
|
|
128
|
+
_createBuildConfig(cordovaPath) {
|
|
129
|
+
const buildJsonPath = path.resolve(cordovaPath, this._BUILD_JSON_FILE_NAME);
|
|
130
|
+
const keystorePath = path.resolve(cordovaPath, this._KEYSTORE_FILE_NAME);
|
|
134
131
|
const androidConfig = this._opt.config.platform?.android
|
|
135
132
|
? {
|
|
136
133
|
android: {
|
|
@@ -152,10 +149,10 @@ export class SdCliCordova {
|
|
|
152
149
|
FsUtils.writeJson(buildJsonPath, androidConfig);
|
|
153
150
|
}
|
|
154
151
|
// 6. 아이콘 및 스플래시 스크린 설정
|
|
155
|
-
|
|
156
|
-
const iconDirPath = path.resolve(cordovaPath, this
|
|
157
|
-
const splashScreenPath = path.resolve(cordovaPath, this
|
|
158
|
-
const splashScreenXmlPath = path.resolve(splashScreenPath, this
|
|
152
|
+
_setupIconAndSplashScreen(cordovaPath) {
|
|
153
|
+
const iconDirPath = path.resolve(cordovaPath, this._ICON_DIR_PATH);
|
|
154
|
+
const splashScreenPath = path.resolve(cordovaPath, this._SPLASH_SCREEN_DIR_PATH);
|
|
155
|
+
const splashScreenXmlPath = path.resolve(splashScreenPath, this._SPLASH_SCREEN_XML_FILE);
|
|
159
156
|
// ICON 파일 복사
|
|
160
157
|
if (this._opt.config.icon != null) {
|
|
161
158
|
FsUtils.mkdirs(iconDirPath);
|
|
@@ -179,10 +176,10 @@ export class SdCliCordova {
|
|
|
179
176
|
}
|
|
180
177
|
}
|
|
181
178
|
// 7. XML 설정 구성
|
|
182
|
-
|
|
179
|
+
_configureXml(cordovaPath) {
|
|
183
180
|
// CONFIG: 초기값 백업
|
|
184
|
-
const configFilePath = path.resolve(cordovaPath, this
|
|
185
|
-
const configBackFilePath = path.resolve(cordovaPath, this
|
|
181
|
+
const configFilePath = path.resolve(cordovaPath, this._CONFIG_XML_FILE_NAME);
|
|
182
|
+
const configBackFilePath = path.resolve(cordovaPath, this._CONFIG_XML_BACKUP_FILE_NAME);
|
|
186
183
|
if (!FsUtils.exists(configBackFilePath)) {
|
|
187
184
|
FsUtils.copy(configFilePath, configBackFilePath);
|
|
188
185
|
}
|
|
@@ -190,10 +187,10 @@ export class SdCliCordova {
|
|
|
190
187
|
const configFileContent = FsUtils.readFile(configBackFilePath);
|
|
191
188
|
const configXml = XmlConvert.parse(configFileContent);
|
|
192
189
|
// CONFIG: 기본 설정
|
|
193
|
-
this
|
|
190
|
+
this._configureBasicXmlSettings(configXml);
|
|
194
191
|
// CONFIG: 안드로이드 설정
|
|
195
192
|
if (this._opt.config.platform?.android) {
|
|
196
|
-
this
|
|
193
|
+
this._configureAndroidXmlSettings(configXml);
|
|
197
194
|
}
|
|
198
195
|
// CONFIG: 파일 새로 쓰기
|
|
199
196
|
const configResultContent = XmlConvert.stringify(configXml, {
|
|
@@ -201,15 +198,15 @@ export class SdCliCordova {
|
|
|
201
198
|
});
|
|
202
199
|
FsUtils.writeFile(configFilePath, configResultContent);
|
|
203
200
|
}
|
|
204
|
-
|
|
201
|
+
_configureBasicXmlSettings(configXml) {
|
|
205
202
|
// 버전 설정
|
|
206
|
-
configXml.widget.$.version = this
|
|
203
|
+
configXml.widget.$.version = this._npmConfig.version;
|
|
207
204
|
// ICON 설정
|
|
208
205
|
if (this._opt.config.icon != null) {
|
|
209
206
|
configXml.widget.icon = [
|
|
210
207
|
{
|
|
211
208
|
$: {
|
|
212
|
-
src: `${this
|
|
209
|
+
src: `${this._ICON_DIR_PATH}/${path.basename(this._opt.config.icon)}`,
|
|
213
210
|
},
|
|
214
211
|
},
|
|
215
212
|
];
|
|
@@ -221,7 +218,7 @@ export class SdCliCordova {
|
|
|
221
218
|
configXml.widget["allow-intent"] = [{ $: { href: "*" } }];
|
|
222
219
|
configXml.widget.preference = [{ $: { name: "MixedContentMode", value: "1" } }];
|
|
223
220
|
}
|
|
224
|
-
|
|
221
|
+
_configureAndroidXmlSettings(configXml) {
|
|
225
222
|
configXml.widget.$["xmlns:android"] = "http://schemas.android.com/apk/res/android";
|
|
226
223
|
configXml.widget.$["xmlns:tools"] = "http://schemas.android.com/tools";
|
|
227
224
|
configXml.widget.platform = configXml.widget.platform ?? [];
|
|
@@ -233,7 +230,7 @@ export class SdCliCordova {
|
|
|
233
230
|
{
|
|
234
231
|
$: {
|
|
235
232
|
name: "AndroidWindowSplashScreenAnimatedIcon",
|
|
236
|
-
value: `${this
|
|
233
|
+
value: `${this._SPLASH_SCREEN_DIR_PATH}/${this._SPLASH_SCREEN_XML_FILE}`,
|
|
237
234
|
},
|
|
238
235
|
},
|
|
239
236
|
],
|
|
@@ -295,7 +292,7 @@ export class SdCliCordova {
|
|
|
295
292
|
{
|
|
296
293
|
$: {
|
|
297
294
|
name: "android-compileSdkVersion",
|
|
298
|
-
value: this
|
|
295
|
+
value: this._ANDROID_SDK_VERSION,
|
|
299
296
|
},
|
|
300
297
|
},
|
|
301
298
|
]);
|
|
@@ -328,26 +325,26 @@ export class SdCliCordova {
|
|
|
328
325
|
configXml.widget.platform.push(androidPlatform);
|
|
329
326
|
}
|
|
330
327
|
async buildAsync(outPath) {
|
|
331
|
-
const cordovaPath = path.resolve(this._opt.pkgPath, this
|
|
328
|
+
const cordovaPath = path.resolve(this._opt.pkgPath, this._CORDOVA_DIR_NAME);
|
|
332
329
|
// 빌드 실행 - 병렬 처리로 개선
|
|
333
330
|
const buildType = this._opt.config.debug ? "debug" : "release";
|
|
334
331
|
// 모든 플랫폼 동시에 빌드
|
|
335
|
-
await Promise.all(this
|
|
332
|
+
await Promise.all(this._platforms.map((platform) => SdCliCordova._execAsync("npx", ["cordova", "build", platform, `--${buildType}`], cordovaPath)));
|
|
336
333
|
// 결과물 복사 및 ZIP 파일 생성 - 병렬 처리
|
|
337
334
|
await Promise.all(Object.keys(this._opt.config.platform ?? {}).map(async (platform) => {
|
|
338
|
-
await this
|
|
335
|
+
await this._processBuildOutputAsync(cordovaPath, outPath, platform, buildType);
|
|
339
336
|
}));
|
|
340
337
|
}
|
|
341
|
-
async
|
|
338
|
+
async _processBuildOutputAsync(cordovaPath, outPath, platform, buildType) {
|
|
342
339
|
const targetOutPath = path.resolve(outPath, platform);
|
|
343
340
|
// 결과물 복사: ANDROID
|
|
344
341
|
if (platform === "android") {
|
|
345
|
-
this
|
|
342
|
+
this._copyAndroidBuildOutput(cordovaPath, targetOutPath, buildType);
|
|
346
343
|
}
|
|
347
344
|
// 자동업데이트를 위한 파일 생성
|
|
348
|
-
await this
|
|
345
|
+
await this._createUpdateZipAsync(cordovaPath, outPath, platform);
|
|
349
346
|
}
|
|
350
|
-
|
|
347
|
+
_copyAndroidBuildOutput(cordovaPath, targetOutPath, buildType) {
|
|
351
348
|
const apkFileName = this._opt.config.platform.android.sign
|
|
352
349
|
? `app-${buildType}.apk`
|
|
353
350
|
: `app-${buildType}-unsigned.apk`;
|
|
@@ -355,20 +352,20 @@ export class SdCliCordova {
|
|
|
355
352
|
FsUtils.mkdirs(targetOutPath);
|
|
356
353
|
FsUtils.copy(path.resolve(cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName), path.resolve(targetOutPath, latestDistApkFileName));
|
|
357
354
|
// 업데이트파일
|
|
358
|
-
FsUtils.copy(path.resolve(cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName), path.resolve(targetOutPath, "updates", `${this
|
|
355
|
+
FsUtils.copy(path.resolve(cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName), path.resolve(targetOutPath, "updates", `${this._npmConfig.version}.apk`));
|
|
359
356
|
}
|
|
360
|
-
async
|
|
357
|
+
async _createUpdateZipAsync(cordovaPath, outPath, platform) {
|
|
361
358
|
const zip = new SdZip();
|
|
362
|
-
const wwwPath = path.resolve(cordovaPath, this
|
|
363
|
-
const platformWwwPath = path.resolve(cordovaPath, this
|
|
364
|
-
this
|
|
365
|
-
this
|
|
359
|
+
const wwwPath = path.resolve(cordovaPath, this._WWW_DIR_NAME);
|
|
360
|
+
const platformWwwPath = path.resolve(cordovaPath, this._PLATFORMS_DIR_NAME, platform, "platform_www");
|
|
361
|
+
this._addFilesToZip(zip, wwwPath);
|
|
362
|
+
this._addFilesToZip(zip, platformWwwPath);
|
|
366
363
|
// ZIP 파일 생성
|
|
367
364
|
const updateDirPath = path.resolve(outPath, platform, "updates");
|
|
368
365
|
FsUtils.mkdirs(updateDirPath);
|
|
369
|
-
FsUtils.writeFile(path.resolve(updateDirPath, this
|
|
366
|
+
FsUtils.writeFile(path.resolve(updateDirPath, this._npmConfig.version + ".zip"), await zip.compressAsync());
|
|
370
367
|
}
|
|
371
|
-
|
|
368
|
+
_addFilesToZip(zip, dirPath) {
|
|
372
369
|
const files = FsUtils.glob(path.resolve(dirPath, "**/*"), { nodir: true });
|
|
373
370
|
for (const file of files) {
|
|
374
371
|
const relFilePath = path.relative(dirPath, file);
|
|
@@ -391,7 +388,6 @@ export class SdCliCordova {
|
|
|
391
388
|
}, 3000);
|
|
392
389
|
</script>`.trim());
|
|
393
390
|
}
|
|
394
|
-
await this
|
|
391
|
+
await this._execAsync("npx", ["cordova", "run", opt.platform, "--device"], cordovaPath);
|
|
395
392
|
}
|
|
396
393
|
}
|
|
397
|
-
_a = SdCliCordova;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ISdClientBuilderElectronConfig } from "../types/config/ISdProjectConfig";
|
|
2
2
|
export declare class SdCliElectron {
|
|
3
|
-
|
|
3
|
+
private static readonly _logger;
|
|
4
4
|
static runAsync(opt: {
|
|
5
5
|
package: string;
|
|
6
6
|
config: string;
|
|
@@ -15,4 +15,8 @@ export declare class SdCliElectron {
|
|
|
15
15
|
pkgPath: string;
|
|
16
16
|
electronConfig: ISdClientBuilderElectronConfig;
|
|
17
17
|
}): Promise<void>;
|
|
18
|
+
private static _loadDevConfig;
|
|
19
|
+
private static _prepareAsync;
|
|
20
|
+
private static _buildAsync;
|
|
21
|
+
private static _canCreateSymlink;
|
|
18
22
|
}
|
|
@@ -4,31 +4,31 @@ import os from "os";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { loadProjConfAsync } from "../utils/loadProjConfAsync";
|
|
6
6
|
export class SdCliElectron {
|
|
7
|
-
static
|
|
7
|
+
static { this._logger = SdLogger.get(["simplysm", "sd-cli", "SdCliElectron"]); }
|
|
8
8
|
static async runAsync(opt) {
|
|
9
|
-
this
|
|
10
|
-
const { pkgPath, electronPath, electronConfig } = await this
|
|
11
|
-
this
|
|
12
|
-
await this
|
|
13
|
-
this
|
|
9
|
+
this._logger.log("설정 가져오기...");
|
|
10
|
+
const { pkgPath, electronPath, electronConfig } = await this._loadDevConfig(opt);
|
|
11
|
+
this._logger.log("준비...");
|
|
12
|
+
await this._prepareAsync({ pkgPath, electronPath, electronConfig });
|
|
13
|
+
this._logger.log("실행...");
|
|
14
14
|
await SdProcess.spawnAsync("npx", ["electron", "."], { cwd: electronPath, showMessage: true });
|
|
15
15
|
}
|
|
16
16
|
static async buildForDevAsync(opt) {
|
|
17
|
-
this
|
|
18
|
-
const { pkgPath, electronPath, electronConfig } = await this
|
|
19
|
-
this
|
|
20
|
-
const { npmConfig } = await this
|
|
21
|
-
this
|
|
17
|
+
this._logger.log("설정 가져오기...");
|
|
18
|
+
const { pkgPath, electronPath, electronConfig } = await this._loadDevConfig(opt);
|
|
19
|
+
this._logger.log("준비...");
|
|
20
|
+
const { npmConfig } = await this._prepareAsync({ pkgPath, electronPath, electronConfig });
|
|
21
|
+
this._logger.log("빌드...");
|
|
22
22
|
const electronDistPath = path.resolve(pkgPath, ".electron/dist");
|
|
23
|
-
await this
|
|
23
|
+
await this._buildAsync({ pkgPath, electronPath, electronDistPath, npmConfig, electronConfig });
|
|
24
24
|
}
|
|
25
25
|
static async buildAsync(opt) {
|
|
26
|
-
this
|
|
26
|
+
this._logger.log("준비...");
|
|
27
27
|
const electronPath = path.resolve(opt.pkgPath, ".electron/src");
|
|
28
|
-
const { npmConfig } = await this
|
|
29
|
-
this
|
|
28
|
+
const { npmConfig } = await this._prepareAsync({ ...opt, electronPath });
|
|
29
|
+
this._logger.log("빌드...");
|
|
30
30
|
const electronDistPath = path.resolve(opt.pkgPath, ".electron/dist");
|
|
31
|
-
await this
|
|
31
|
+
await this._buildAsync({
|
|
32
32
|
pkgPath: opt.pkgPath,
|
|
33
33
|
electronPath,
|
|
34
34
|
electronDistPath,
|
|
@@ -36,7 +36,7 @@ export class SdCliElectron {
|
|
|
36
36
|
electronConfig: opt.electronConfig,
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
static async
|
|
39
|
+
static async _loadDevConfig(opt) {
|
|
40
40
|
const projConf = await loadProjConfAsync(process.cwd(), true, opt);
|
|
41
41
|
const pkgConf = projConf.packages[opt.package];
|
|
42
42
|
if (pkgConf?.type !== "client" || pkgConf.builder?.electron === undefined) {
|
|
@@ -50,7 +50,7 @@ export class SdCliElectron {
|
|
|
50
50
|
electronConfig: pkgConf.builder.electron,
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
static async
|
|
53
|
+
static async _prepareAsync(opt) {
|
|
54
54
|
const npmConfig = FsUtils.readJson(path.resolve(opt.pkgPath, `package.json`));
|
|
55
55
|
const reinstallPkgNames = opt.electronConfig.reinstallDependencies ?? [];
|
|
56
56
|
FsUtils.writeJson(path.resolve(opt.electronPath, `package.json`), {
|
|
@@ -74,8 +74,8 @@ export class SdCliElectron {
|
|
|
74
74
|
});
|
|
75
75
|
return { npmConfig };
|
|
76
76
|
}
|
|
77
|
-
static async
|
|
78
|
-
if (!this
|
|
77
|
+
static async _buildAsync(opt) {
|
|
78
|
+
if (!this._canCreateSymlink()) {
|
|
79
79
|
throw new Error("'Electron 빌드'를 위해서는 'Symlink 생성' 권한이 필요합니다. 윈도우의 개발자모드를 활성화하세요.");
|
|
80
80
|
}
|
|
81
81
|
const electronConfig = {
|
|
@@ -105,7 +105,7 @@ export class SdCliElectron {
|
|
|
105
105
|
FsUtils.copy(path.resolve(opt.electronDistPath, `${opt.npmConfig.description} ${opt.electronConfig.portable ? "" : "Setup "}${opt.npmConfig.version}.exe`), path.resolve(opt.pkgPath, `dist/electron/${opt.npmConfig.description}${opt.electronConfig.portable ? "-portable" : ""}-latest.exe`));
|
|
106
106
|
FsUtils.copy(path.resolve(opt.electronDistPath, `${opt.npmConfig.description} ${opt.electronConfig.portable ? "" : "Setup "}${opt.npmConfig.version}.exe`), path.resolve(opt.pkgPath, `dist/electron/updates/${opt.npmConfig.version}.exe`));
|
|
107
107
|
}
|
|
108
|
-
static
|
|
108
|
+
static _canCreateSymlink() {
|
|
109
109
|
const tmpDir = os.tmpdir();
|
|
110
110
|
const testTarget = path.join(tmpDir, "symlink-test-target.txt");
|
|
111
111
|
const testLink = path.join(tmpDir, "symlink-test-link.txt");
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare class SdCliLocalUpdate {
|
|
2
|
-
#private;
|
|
3
2
|
static runAsync(opt: {
|
|
4
3
|
config: string;
|
|
5
4
|
options?: string[];
|
|
@@ -8,4 +7,5 @@ export declare class SdCliLocalUpdate {
|
|
|
8
7
|
config: string;
|
|
9
8
|
options?: string[];
|
|
10
9
|
}): Promise<void>;
|
|
10
|
+
private static _getUpdatePathInfos;
|
|
11
11
|
}
|
|
@@ -8,7 +8,7 @@ export class SdCliLocalUpdate {
|
|
|
8
8
|
const projConf = await loadProjConfAsync(process.cwd(), true, opt);
|
|
9
9
|
if (!projConf.localUpdates)
|
|
10
10
|
return;
|
|
11
|
-
const updatePathInfos = this
|
|
11
|
+
const updatePathInfos = this._getUpdatePathInfos(projConf.localUpdates);
|
|
12
12
|
logger.debug("로컬 업데이트 구성");
|
|
13
13
|
logger.log("로컬 라이브러리 업데이트 시작...");
|
|
14
14
|
await updatePathInfos.parallelAsync(async (updatePathInfo) => {
|
|
@@ -29,7 +29,7 @@ export class SdCliLocalUpdate {
|
|
|
29
29
|
const projConf = await loadProjConfAsync(process.cwd(), true, opt);
|
|
30
30
|
if (!projConf.localUpdates)
|
|
31
31
|
return;
|
|
32
|
-
const updatePathInfos = this
|
|
32
|
+
const updatePathInfos = this._getUpdatePathInfos(projConf.localUpdates);
|
|
33
33
|
logger.debug("로컬 업데이트 구성");
|
|
34
34
|
const watcher = await SdFsWatcher.watchAsync(updatePathInfos.map((item) => item.source));
|
|
35
35
|
watcher.onChange({ delay: 300 }, async (changedInfos) => {
|
|
@@ -56,7 +56,7 @@ export class SdCliLocalUpdate {
|
|
|
56
56
|
logger.info("로컬 라이브러리 복사 완료");
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
static
|
|
59
|
+
static _getUpdatePathInfos(record) {
|
|
60
60
|
const result = [];
|
|
61
61
|
for (const pkgGlobPath of Object.keys(record)) {
|
|
62
62
|
// "node_modules'에서 로컬업데이트 설정에 맞는 패키지를 "glob"하여 대상 패키지경로 목록 가져오기
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare class SdCliProject {
|
|
2
|
-
#private;
|
|
3
2
|
static watchAsync(opt: {
|
|
4
3
|
config: string;
|
|
5
4
|
options?: string[];
|
|
@@ -18,4 +17,8 @@ export declare class SdCliProject {
|
|
|
18
17
|
packages?: string[];
|
|
19
18
|
noBuild?: boolean;
|
|
20
19
|
}): Promise<void>;
|
|
20
|
+
private static _publishPkgAsync;
|
|
21
|
+
private static _waitSecMessageAsync;
|
|
22
|
+
private static _upgradeVersion;
|
|
23
|
+
private static _logging;
|
|
21
24
|
}
|
|
@@ -46,7 +46,7 @@ export class SdCliProject {
|
|
|
46
46
|
logger.debug("빌드를 시작합니다...");
|
|
47
47
|
},
|
|
48
48
|
onComplete: (messages) => {
|
|
49
|
-
this
|
|
49
|
+
this._logging(messages, logger);
|
|
50
50
|
},
|
|
51
51
|
});
|
|
52
52
|
}
|
|
@@ -73,14 +73,14 @@ export class SdCliProject {
|
|
|
73
73
|
throw new Error("패키지를 찾을 수 없습니다. (" + notExistsPkgs.join(", ") + ")");
|
|
74
74
|
}
|
|
75
75
|
logger.debug("프로젝트 및 패키지 버전 설정...");
|
|
76
|
-
this
|
|
76
|
+
this._upgradeVersion(projNpmConf, allPkgPaths);
|
|
77
77
|
logger.debug("빌드 프로세스 시작...");
|
|
78
78
|
const messages = await SdProjectBuildRunner.buildAsync({
|
|
79
79
|
allPkgPaths,
|
|
80
80
|
pkgPaths,
|
|
81
81
|
projConf,
|
|
82
82
|
});
|
|
83
|
-
this
|
|
83
|
+
this._logging(messages, logger);
|
|
84
84
|
}
|
|
85
85
|
static async publishAsync(opt) {
|
|
86
86
|
const logger = SdLogger.get(["simplysm", "sd-cli", "SdCliProject", "publishAsync"]);
|
|
@@ -90,7 +90,7 @@ export class SdCliProject {
|
|
|
90
90
|
const projNpmConf = FsUtils.readJson(path.resolve(process.cwd(), "package.json"));
|
|
91
91
|
if (opt.noBuild) {
|
|
92
92
|
logger.warn("빌드하지 않고, 배포하는것은 상당히 위험합니다.");
|
|
93
|
-
await this
|
|
93
|
+
await this._waitSecMessageAsync("프로세스를 중지하려면, 'CTRL+C'를 누르세요.", 5);
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
96
|
// GIT 사용중일 경우, 커밋되지 않은 수정사항이 있는지 확인
|
|
@@ -132,7 +132,7 @@ export class SdCliProject {
|
|
|
132
132
|
}
|
|
133
133
|
if (!opt.noBuild) {
|
|
134
134
|
logger.debug("프로젝트 및 패키지 버전 설정...");
|
|
135
|
-
this
|
|
135
|
+
this._upgradeVersion(projNpmConf, allPkgPaths);
|
|
136
136
|
// 빌드
|
|
137
137
|
try {
|
|
138
138
|
logger.debug("빌드 프로세스 시작...");
|
|
@@ -141,7 +141,7 @@ export class SdCliProject {
|
|
|
141
141
|
pkgPaths,
|
|
142
142
|
projConf,
|
|
143
143
|
});
|
|
144
|
-
this
|
|
144
|
+
this._logging(messages, logger);
|
|
145
145
|
}
|
|
146
146
|
catch (err) {
|
|
147
147
|
await SdProcess.spawnAsync("git", ["checkout", "."]);
|
|
@@ -171,7 +171,7 @@ export class SdCliProject {
|
|
|
171
171
|
if (pkgConf?.publish == null)
|
|
172
172
|
return;
|
|
173
173
|
logger.debug(`[${pkgName}] 배포 시작...`);
|
|
174
|
-
await this
|
|
174
|
+
await this._publishPkgAsync(pkgPath, pkgConf.publish);
|
|
175
175
|
logger.debug(`[${pkgName}] 배포 완료`);
|
|
176
176
|
});
|
|
177
177
|
if (projConf.postPublish && projConf.postPublish.length > 0) {
|
|
@@ -200,7 +200,7 @@ export class SdCliProject {
|
|
|
200
200
|
}
|
|
201
201
|
logger.info(`모든 배포가 완료되었습니다. (v${projNpmConf.version})`);
|
|
202
202
|
}
|
|
203
|
-
static async
|
|
203
|
+
static async _publishPkgAsync(pkgPath, pkgPubConf) {
|
|
204
204
|
if (pkgPubConf === "npm") {
|
|
205
205
|
await SdProcess.spawnAsync("yarn", ["npm", "publish", "--access", "public"], {
|
|
206
206
|
cwd: pkgPath,
|
|
@@ -244,7 +244,7 @@ export class SdCliProject {
|
|
|
244
244
|
throw new NeverEntryError();
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
static async
|
|
247
|
+
static async _waitSecMessageAsync(msg, sec) {
|
|
248
248
|
for (let i = sec; i > 0; i--) {
|
|
249
249
|
if (i !== sec) {
|
|
250
250
|
process.stdout.cursorTo(0);
|
|
@@ -255,7 +255,7 @@ export class SdCliProject {
|
|
|
255
255
|
process.stdout.cursorTo(0);
|
|
256
256
|
process.stdout.clearLine(0);
|
|
257
257
|
}
|
|
258
|
-
static
|
|
258
|
+
static _upgradeVersion(projNpmConf, allPkgPaths) {
|
|
259
259
|
// 작업공간 package.json 버전 설정
|
|
260
260
|
const newVersion = semver.inc(projNpmConf.version, "patch");
|
|
261
261
|
projNpmConf.version = newVersion;
|
|
@@ -296,7 +296,7 @@ export class SdCliProject {
|
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
-
static
|
|
299
|
+
static _logging(buildResults, logger) {
|
|
300
300
|
const messageMap = buildResults.toSetMap((item) => item.severity, (item) => SdCliConvertMessageUtils.getBuildMessageString(item));
|
|
301
301
|
if (messageMap.has("message")) {
|
|
302
302
|
logger.log(`알림\n${Array.from(messageMap.get("message")).join("\n")}`);
|