@simplysm/sd-cli 12.5.21 → 12.5.22

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.
Files changed (195) hide show
  1. package/dist/{build-tools → entry}/SdCliCordova.d.ts +5 -6
  2. package/dist/{build-tools → entry}/SdCliCordova.js +117 -99
  3. package/dist/entry/SdCliCordova.js.map +1 -0
  4. package/dist/entry/SdCliElectron.d.ts +2 -2
  5. package/dist/entry/SdCliElectron.js +50 -40
  6. package/dist/entry/SdCliElectron.js.map +1 -1
  7. package/dist/entry/SdCliLocalUpdate.d.ts +1 -2
  8. package/dist/entry/SdCliLocalUpdate.js +26 -27
  9. package/dist/entry/SdCliLocalUpdate.js.map +1 -1
  10. package/dist/entry/SdCliProject.d.ts +1 -5
  11. package/dist/entry/SdCliProject.js +62 -288
  12. package/dist/entry/SdCliProject.js.map +1 -1
  13. package/dist/index.d.ts +23 -20
  14. package/dist/index.js +23 -20
  15. package/dist/index.js.map +1 -1
  16. package/dist/pkg-builders/SdMultiBuildRunner.d.ts +21 -0
  17. package/dist/pkg-builders/SdMultiBuildRunner.js +174 -0
  18. package/dist/pkg-builders/SdMultiBuildRunner.js.map +1 -0
  19. package/dist/pkg-builders/client/SdCliNgRoutesFileGenerator.d.ts +4 -0
  20. package/dist/{build-tools → pkg-builders/client}/SdCliNgRoutesFileGenerator.js +7 -7
  21. package/dist/pkg-builders/client/SdCliNgRoutesFileGenerator.js.map +1 -0
  22. package/dist/pkg-builders/client/SdClientBuildRunner.d.ts +20 -0
  23. package/dist/pkg-builders/client/SdClientBuildRunner.js +135 -0
  24. package/dist/pkg-builders/client/SdClientBuildRunner.js.map +1 -0
  25. package/dist/pkg-builders/client/SdNgBundler.d.ts +29 -0
  26. package/dist/{build-tools → pkg-builders/client}/SdNgBundler.js +100 -95
  27. package/dist/pkg-builders/client/SdNgBundler.js.map +1 -0
  28. package/dist/{build-tools → pkg-builders/client}/SdNgBundlerContext.d.ts +1 -2
  29. package/dist/{build-tools → pkg-builders/client}/SdNgBundlerContext.js +19 -45
  30. package/dist/pkg-builders/client/SdNgBundlerContext.js.map +1 -0
  31. package/dist/pkg-builders/client/createSdNgPlugin.d.ts +10 -0
  32. package/dist/{bundle-plugins/sdNgPlugin.js → pkg-builders/client/createSdNgPlugin.js} +32 -33
  33. package/dist/pkg-builders/client/createSdNgPlugin.js.map +1 -0
  34. package/dist/pkg-builders/lib/SdCliIndexFileGenerator.d.ts +5 -0
  35. package/dist/{build-tools → pkg-builders/lib}/SdCliIndexFileGenerator.js +11 -11
  36. package/dist/pkg-builders/lib/SdCliIndexFileGenerator.js.map +1 -0
  37. package/dist/pkg-builders/lib/SdJsLibBuildRunner.d.ts +16 -0
  38. package/dist/pkg-builders/lib/SdJsLibBuildRunner.js +81 -0
  39. package/dist/pkg-builders/lib/SdJsLibBuildRunner.js.map +1 -0
  40. package/dist/pkg-builders/lib/SdTsLibBuildRunner.d.ts +13 -0
  41. package/dist/pkg-builders/lib/SdTsLibBuildRunner.js +89 -0
  42. package/dist/pkg-builders/lib/SdTsLibBuildRunner.js.map +1 -0
  43. package/dist/pkg-builders/lib/SdTsLibBuilder.d.ts +14 -0
  44. package/dist/pkg-builders/lib/SdTsLibBuilder.js +54 -0
  45. package/dist/pkg-builders/lib/SdTsLibBuilder.js.map +1 -0
  46. package/dist/pkg-builders/server/SdServerBuildRunner.d.ts +17 -0
  47. package/dist/{builders/SdCliServerBuilder.js → pkg-builders/server/SdServerBuildRunner.js} +48 -53
  48. package/dist/pkg-builders/server/SdServerBuildRunner.js.map +1 -0
  49. package/dist/pkg-builders/server/SdServerBundler.d.ts +19 -0
  50. package/dist/{build-tools → pkg-builders/server}/SdServerBundler.js +25 -30
  51. package/dist/pkg-builders/server/SdServerBundler.js.map +1 -0
  52. package/dist/pkg-builders/server/createSdServerPlugin.d.ts +10 -0
  53. package/dist/pkg-builders/server/createSdServerPlugin.js +53 -0
  54. package/dist/pkg-builders/server/createSdServerPlugin.js.map +1 -0
  55. package/dist/sd-cli.js +61 -54
  56. package/dist/sd-cli.js.map +1 -1
  57. package/dist/ts-builder/SdTsCompileWorker.d.ts +9 -0
  58. package/dist/ts-builder/SdTsCompileWorker.js +16 -0
  59. package/dist/ts-builder/SdTsCompileWorker.js.map +1 -0
  60. package/dist/ts-builder/SdTsCompiler.d.ts +7 -0
  61. package/dist/{build-tools → ts-builder}/SdTsCompiler.js +226 -212
  62. package/dist/ts-builder/SdTsCompiler.js.map +1 -0
  63. package/dist/types/build-plugin.type.d.ts +14 -0
  64. package/dist/types/build-plugin.type.js +2 -0
  65. package/dist/types/build-plugin.type.js.map +1 -0
  66. package/dist/types/build.type.d.ts +15 -0
  67. package/dist/types/build.type.js +2 -0
  68. package/dist/types/build.type.js.map +1 -0
  69. package/dist/types/common-configs.type.d.ts +22 -0
  70. package/dist/types/common-configs.type.js +2 -0
  71. package/dist/types/common-configs.type.js.map +1 -0
  72. package/dist/types/sd-configs.type.d.ts +99 -0
  73. package/dist/types/sd-configs.type.js +2 -0
  74. package/dist/types/sd-configs.type.js.map +1 -0
  75. package/dist/types/ts-compiler.type.d.ts +29 -0
  76. package/dist/types/ts-compiler.type.js +2 -0
  77. package/dist/types/ts-compiler.type.js.map +1 -0
  78. package/dist/types/workers.type.d.ts +49 -0
  79. package/dist/types/workers.type.js +2 -0
  80. package/dist/types/workers.type.js.map +1 -0
  81. package/dist/utils/SdCliConvertMessageUtil.d.ts +21 -0
  82. package/dist/utils/SdCliConvertMessageUtil.js +137 -0
  83. package/dist/utils/SdCliConvertMessageUtil.js.map +1 -0
  84. package/dist/workers/compile-worker.js +27 -0
  85. package/dist/workers/compile-worker.js.map +1 -0
  86. package/dist/workers/lint-worker.js +36 -0
  87. package/dist/workers/lint-worker.js.map +1 -0
  88. package/dist/workers/server-worker.d.ts +1 -0
  89. package/dist/workers/server-worker.js +49 -0
  90. package/dist/workers/server-worker.js.map +1 -0
  91. package/lib/dev-worker.cjs +5 -0
  92. package/package.json +7 -10
  93. package/src/entry/SdCliCordova.ts +363 -0
  94. package/src/entry/SdCliElectron.ts +96 -69
  95. package/src/entry/SdCliLocalUpdate.ts +43 -44
  96. package/src/entry/SdCliProject.ts +72 -417
  97. package/src/index.ts +23 -20
  98. package/src/pkg-builders/SdMultiBuildRunner.ts +250 -0
  99. package/src/{build-tools → pkg-builders/client}/SdCliNgRoutesFileGenerator.ts +7 -7
  100. package/src/pkg-builders/client/SdClientBuildRunner.ts +191 -0
  101. package/src/{build-tools → pkg-builders/client}/SdNgBundler.ts +125 -121
  102. package/src/pkg-builders/client/SdNgBundlerContext.ts +111 -0
  103. package/src/{bundle-plugins/sdNgPlugin.ts → pkg-builders/client/createSdNgPlugin.ts} +43 -46
  104. package/src/{build-tools → pkg-builders/lib}/SdCliIndexFileGenerator.ts +11 -11
  105. package/src/pkg-builders/lib/SdJsLibBuildRunner.ts +105 -0
  106. package/src/pkg-builders/lib/SdTsLibBuildRunner.ts +128 -0
  107. package/src/pkg-builders/lib/SdTsLibBuilder.ts +69 -0
  108. package/src/{builders/SdCliServerBuilder.ts → pkg-builders/server/SdServerBuildRunner.ts} +66 -78
  109. package/src/{build-tools → pkg-builders/server}/SdServerBundler.ts +40 -41
  110. package/src/pkg-builders/server/createSdServerPlugin.ts +77 -0
  111. package/src/sd-cli.ts +197 -211
  112. package/src/ts-builder/SdTsCompileWorker.ts +21 -0
  113. package/src/ts-builder/SdTsCompiler.ts +758 -0
  114. package/src/types/build-plugin.type.ts +16 -0
  115. package/src/types/build.type.ts +17 -0
  116. package/src/types/common-configs.type.ts +27 -0
  117. package/src/types/sd-configs.type.ts +114 -0
  118. package/src/types/ts-compiler.type.ts +29 -0
  119. package/src/types/workers.type.ts +27 -0
  120. package/src/utils/SdCliConvertMessageUtil.ts +177 -0
  121. package/src/workers/compile-worker.ts +31 -0
  122. package/src/workers/lint-worker.ts +44 -0
  123. package/src/workers/server-worker.ts +52 -0
  124. package/tsconfig.json +7 -1
  125. package/dist/build-cluster.js +0 -201
  126. package/dist/build-cluster.js.map +0 -1
  127. package/dist/build-tools/SdCliCordova.js.map +0 -1
  128. package/dist/build-tools/SdCliIndexFileGenerator.d.ts +0 -5
  129. package/dist/build-tools/SdCliIndexFileGenerator.js.map +0 -1
  130. package/dist/build-tools/SdCliNgRoutesFileGenerator.d.ts +0 -4
  131. package/dist/build-tools/SdCliNgRoutesFileGenerator.js.map +0 -1
  132. package/dist/build-tools/SdLinter.d.ts +0 -5
  133. package/dist/build-tools/SdLinter.js +0 -49
  134. package/dist/build-tools/SdLinter.js.map +0 -1
  135. package/dist/build-tools/SdNgBundler.d.ts +0 -29
  136. package/dist/build-tools/SdNgBundler.js.map +0 -1
  137. package/dist/build-tools/SdNgBundlerContext.js.map +0 -1
  138. package/dist/build-tools/SdReactBundler.d.ts +0 -25
  139. package/dist/build-tools/SdReactBundler.js +0 -295
  140. package/dist/build-tools/SdReactBundler.js.map +0 -1
  141. package/dist/build-tools/SdReactBundlerContext.d.ts +0 -14
  142. package/dist/build-tools/SdReactBundlerContext.js +0 -59
  143. package/dist/build-tools/SdReactBundlerContext.js.map +0 -1
  144. package/dist/build-tools/SdServerBundler.d.ts +0 -20
  145. package/dist/build-tools/SdServerBundler.js.map +0 -1
  146. package/dist/build-tools/SdTsCompiler.d.ts +0 -34
  147. package/dist/build-tools/SdTsCompiler.js.map +0 -1
  148. package/dist/build-tools/SdTsLibBundler.d.ts +0 -13
  149. package/dist/build-tools/SdTsLibBundler.js +0 -58
  150. package/dist/build-tools/SdTsLibBundler.js.map +0 -1
  151. package/dist/builders/SdCliClientBuilder.d.ts +0 -18
  152. package/dist/builders/SdCliClientBuilder.js +0 -172
  153. package/dist/builders/SdCliClientBuilder.js.map +0 -1
  154. package/dist/builders/SdCliJsLibLinter.d.ts +0 -13
  155. package/dist/builders/SdCliJsLibLinter.js +0 -60
  156. package/dist/builders/SdCliJsLibLinter.js.map +0 -1
  157. package/dist/builders/SdCliServerBuilder.d.ts +0 -15
  158. package/dist/builders/SdCliServerBuilder.js.map +0 -1
  159. package/dist/builders/SdCliTsLibBuilder.d.ts +0 -12
  160. package/dist/builders/SdCliTsLibBuilder.js +0 -90
  161. package/dist/builders/SdCliTsLibBuilder.js.map +0 -1
  162. package/dist/bundle-plugins/sdNgPlugin.d.ts +0 -16
  163. package/dist/bundle-plugins/sdNgPlugin.js.map +0 -1
  164. package/dist/bundle-plugins/sdReactPlugin.d.ts +0 -16
  165. package/dist/bundle-plugins/sdReactPlugin.js +0 -117
  166. package/dist/bundle-plugins/sdReactPlugin.js.map +0 -1
  167. package/dist/bundle-plugins/sdServerPlugin.d.ts +0 -16
  168. package/dist/bundle-plugins/sdServerPlugin.js +0 -63
  169. package/dist/bundle-plugins/sdServerPlugin.js.map +0 -1
  170. package/dist/commons.d.ts +0 -145
  171. package/dist/commons.js +0 -2
  172. package/dist/commons.js.map +0 -1
  173. package/dist/server-worker.js +0 -57
  174. package/dist/server-worker.js.map +0 -1
  175. package/dist/utils/SdCliBuildResultUtil.d.ts +0 -16
  176. package/dist/utils/SdCliBuildResultUtil.js +0 -54
  177. package/dist/utils/SdCliBuildResultUtil.js.map +0 -1
  178. package/src/build-cluster.ts +0 -212
  179. package/src/build-tools/SdCliCordova.ts +0 -340
  180. package/src/build-tools/SdLinter.ts +0 -65
  181. package/src/build-tools/SdNgBundlerContext.ts +0 -137
  182. package/src/build-tools/SdReactBundler.ts +0 -372
  183. package/src/build-tools/SdReactBundlerContext.ts +0 -71
  184. package/src/build-tools/SdTsCompiler.ts +0 -754
  185. package/src/build-tools/SdTsLibBundler.ts +0 -72
  186. package/src/builders/SdCliClientBuilder.ts +0 -233
  187. package/src/builders/SdCliJsLibLinter.ts +0 -72
  188. package/src/builders/SdCliTsLibBuilder.ts +0 -126
  189. package/src/bundle-plugins/sdReactPlugin.ts +0 -164
  190. package/src/bundle-plugins/sdServerPlugin.ts +0 -94
  191. package/src/commons.ts +0 -171
  192. package/src/server-worker.ts +0 -65
  193. package/src/utils/SdCliBuildResultUtil.ts +0 -63
  194. /package/dist/{build-cluster.d.ts → workers/compile-worker.d.ts} +0 -0
  195. /package/dist/{server-worker.d.ts → workers/lint-worker.d.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/sd-cli",
3
- "version": "12.5.21",
3
+ "version": "12.5.22",
4
4
  "description": "심플리즘 패키지 - CLI",
5
5
  "author": "김석래",
6
6
  "repository": {
@@ -21,29 +21,26 @@
21
21
  "@angular/compiler": "^18.2.7",
22
22
  "@angular/compiler-cli": "^18.2.7",
23
23
  "@electron/rebuild": "^3.6.2",
24
- "@simplysm/sd-core-common": "12.5.21",
25
- "@simplysm/sd-core-node": "12.5.21",
26
- "@simplysm/sd-service-server": "12.5.21",
27
- "@simplysm/sd-storage": "12.5.21",
28
- "autoprefixer": "^10.4.20",
24
+ "@simplysm/sd-core-common": "12.5.22",
25
+ "@simplysm/sd-core-node": "12.5.22",
26
+ "@simplysm/sd-service-server": "12.5.22",
27
+ "@simplysm/sd-storage": "12.5.22",
29
28
  "browserslist": "^4.24.0",
30
29
  "cordova": "^12.0.0",
31
30
  "css-has-pseudo": "^7.0.0",
32
31
  "electron": "^32.1.2",
33
- "electron-builder": "^25.1.7",
32
+ "electron-builder": "^25.1.8",
34
33
  "esbuild": "^0.24.0",
35
- "eslint": "^9.11.1",
34
+ "eslint": "^9.12.0",
36
35
  "glob": "^11.0.0",
37
36
  "jszip": "^3.10.1",
38
37
  "node-stdlib-browser": "^1.2.1",
39
38
  "postcss": "^8.4.47",
40
- "postcss-url": "^10.1.3",
41
39
  "rxjs": "^7.8.1",
42
40
  "sass": "^1.79.4",
43
41
  "semver": "^7.6.3",
44
42
  "specifier-resolution-node": "^1.1.4",
45
43
  "typescript": "~5.5.4",
46
- "workbox-build": "^7.1.1",
47
44
  "xml2js": "^0.6.2",
48
45
  "yargs": "^17.7.2"
49
46
  },
@@ -0,0 +1,363 @@
1
+ import * as path from "path";
2
+ import { FsUtil, Logger, SdProcess } from "@simplysm/sd-core-node";
3
+ import xml2js from "xml2js";
4
+ import JSZip from "jszip";
5
+ import { INpmConfig } from "../types/common-configs.type";
6
+ import { ISdClientBuilderCordovaConfig } from "../types/sd-configs.type";
7
+
8
+ const BIN_PATH = path.resolve(process.cwd(), "node_modules/.bin/cordova.cmd");
9
+
10
+ export class SdCliCordova {
11
+ private _logger = Logger.get(["simplysm", "sd-cli", "SdCliCordova"]);
12
+
13
+ private _platforms: string[];
14
+ private _npmConfig: INpmConfig;
15
+
16
+ constructor(private readonly _opt: { pkgPath: string; config: ISdClientBuilderCordovaConfig }) {
17
+ this._platforms = Object.keys(this._opt.config.platform ?? { browser: {} });
18
+ this._npmConfig = FsUtil.readJson(path.resolve(this._opt.pkgPath, "package.json"));
19
+ // this._logger = Logger.get(["simplysm", "sd-cli", this.constructor.name, this._npmConfig.name]);
20
+ }
21
+
22
+ private async _execAsync(cmd: string, cwd: string): Promise<void> {
23
+ this._logger.debug(cmd);
24
+ const msg = await SdProcess.spawnAsync(cmd, { cwd });
25
+ this._logger.debug(msg);
26
+ }
27
+
28
+ public async initializeAsync(): Promise<void> {
29
+ const cordovaPath = path.resolve(this._opt.pkgPath, ".cordova");
30
+
31
+ if (FsUtil.exists(cordovaPath)) {
32
+ this._logger.log("이미 생성되어있는 '.cordova'를 사용합니다.");
33
+ } else {
34
+ await this._execAsync(`${BIN_PATH} telemetry on`, this._opt.pkgPath);
35
+
36
+ // 프로젝트 생성
37
+ await this._execAsync(
38
+ `${BIN_PATH} create "${cordovaPath}" "${this._opt.config.appId}" "${this._opt.config.appName}"`,
39
+ process.cwd(),
40
+ );
41
+ }
42
+
43
+ // platforms 폴더 혹시 없으면 생성
44
+ FsUtil.mkdirs(path.resolve(cordovaPath, "platforms"));
45
+
46
+ // www 폴더 혹시 없으면 생성
47
+ FsUtil.mkdirs(path.resolve(cordovaPath, "www"));
48
+
49
+ // 미설치 빌드 플랫폼 신규 생성
50
+ const alreadyPlatforms = FsUtil.readdir(path.resolve(cordovaPath, "platforms"));
51
+ for (const platform of this._platforms) {
52
+ if (!alreadyPlatforms.includes(platform)) {
53
+ if (platform === "android") {
54
+ await this._execAsync(`${BIN_PATH} platform add ${platform}@12.0.0`, cordovaPath);
55
+ } else {
56
+ await this._execAsync(`${BIN_PATH} platform add ${platform}`, cordovaPath);
57
+ }
58
+ }
59
+ }
60
+
61
+ // 설치 미빌드 플랫폼 삭제
62
+ for (const alreadyPlatform of alreadyPlatforms) {
63
+ if (!this._platforms.includes(alreadyPlatform)) {
64
+ await this._execAsync(`${BIN_PATH} platform remove ${alreadyPlatform}`, cordovaPath);
65
+ }
66
+ }
67
+
68
+ // 설치된 미사용 플러그인 삭제
69
+ const pluginsFetch = FsUtil.exists(path.resolve(cordovaPath, "plugins/fetch.json"))
70
+ ? FsUtil.readJson(path.resolve(cordovaPath, "plugins/fetch.json"))
71
+ : undefined;
72
+ const alreadyPluginIds =
73
+ pluginsFetch != undefined
74
+ ? Object.keys(pluginsFetch)
75
+ : // Object.values(pluginsFetch).map((item: any) => item.source.id ?? item.source.url ?? item.source.path)
76
+ [];
77
+ const usePlugins = ["cordova-plugin-ionic-webview", ...(this._opt.config.plugins ?? [])].distinct();
78
+
79
+ for (const alreadyPluginId of alreadyPluginIds) {
80
+ let hasPlugin = false;
81
+ for (const usePlugin of usePlugins) {
82
+ if (alreadyPluginId === usePlugin) {
83
+ hasPlugin = true;
84
+ break;
85
+ }
86
+ /*if (
87
+ (usePlugin.includes("@") && alreadyPluginId === usePlugin) ||
88
+ (!usePlugin.includes("@") && alreadyPluginId.replace(/@.*$/, "") === usePlugin)
89
+ ) {
90
+ hasPlugin = true;
91
+ break;
92
+ }*/
93
+ }
94
+
95
+ if (!hasPlugin) {
96
+ await this._execAsync(`${BIN_PATH} plugin remove ${alreadyPluginId}`, cordovaPath);
97
+ }
98
+ }
99
+
100
+ // 미설치 플러그인들 설치
101
+ for (const usePlugin of usePlugins) {
102
+ if (
103
+ (usePlugin.includes("@") && !alreadyPluginIds.includes(usePlugin)) ||
104
+ (!usePlugin.includes("@") &&
105
+ !alreadyPluginIds.map((alreadyPluginId) => alreadyPluginId.replace(/@.*$/, "")).includes(usePlugin))
106
+ ) {
107
+ await this._execAsync(`${BIN_PATH} plugin add ${usePlugin}`, cordovaPath);
108
+ }
109
+ }
110
+
111
+ // ANDROID SIGN 파일 복사
112
+ if (this._opt.config.platform?.android?.sign) {
113
+ FsUtil.copy(
114
+ path.resolve(this._opt.pkgPath, "src", this._opt.config.platform.android.sign.keystore),
115
+ path.resolve(cordovaPath, "android.keystore"),
116
+ );
117
+ } else {
118
+ FsUtil.remove(path.resolve(cordovaPath, "android.keystore"));
119
+ // SIGN을 안쓸경우 아래 파일이 생성되어 있으면 오류남
120
+ FsUtil.remove(path.resolve(cordovaPath, "platforms/android/release-signing.properties"));
121
+ }
122
+
123
+ // 빌드 옵션 파일 생성
124
+ FsUtil.writeJson(path.resolve(cordovaPath, "build.json"), {
125
+ ...(this._opt.config.platform?.android
126
+ ? {
127
+ android: {
128
+ release: {
129
+ packageType: this._opt.config.platform.android.bundle ? "bundle" : "apk",
130
+ ...(this._opt.config.platform.android.sign
131
+ ? {
132
+ keystore: path.resolve(cordovaPath, "android.keystore"),
133
+ storePassword: this._opt.config.platform.android.sign.storePassword,
134
+ alias: this._opt.config.platform.android.sign.alias,
135
+ password: this._opt.config.platform.android.sign.password,
136
+ keystoreType: this._opt.config.platform.android.sign.keystoreType,
137
+ }
138
+ : {}),
139
+ },
140
+ },
141
+ }
142
+ : {}),
143
+ });
144
+
145
+ // ICON 파일 복사
146
+ if (this._opt.config.icon != null) {
147
+ FsUtil.copy(
148
+ path.resolve(this._opt.pkgPath, "src", this._opt.config.icon),
149
+ path.resolve(cordovaPath, "res/icons", path.basename(this._opt.config.icon)),
150
+ );
151
+ } else {
152
+ FsUtil.remove(path.resolve(cordovaPath, "res/icons"));
153
+ }
154
+
155
+ // SplashScreen 파일 생성
156
+ if (this._opt.config.platform?.android && this._opt.config.icon != null) {
157
+ FsUtil.writeFile(
158
+ path.resolve(cordovaPath, "res/screen/android/splashscreen.xml"),
159
+ `
160
+ <?xml version="1.0" encoding="utf-8"?>
161
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
162
+ <item
163
+ android:width="48dp"
164
+ android:height="48dp"
165
+ android:drawable="@mipmap/ic_launcher"
166
+ android:gravity="center" />
167
+ </layer-list>`.trim(),
168
+ );
169
+ }
170
+
171
+ // CONFIG: 초기값 백업
172
+ const configFilePath = path.resolve(cordovaPath, "config.xml");
173
+ const configBackFilePath = path.resolve(cordovaPath, "config.xml.bak");
174
+ if (!FsUtil.exists(configBackFilePath)) {
175
+ FsUtil.copy(configFilePath, configBackFilePath);
176
+ }
177
+
178
+ // CONFIG: 초기값 읽기
179
+ const configFileContent = FsUtil.readFile(configBackFilePath);
180
+ const configXml = await xml2js.parseStringPromise(configFileContent);
181
+
182
+ // CONFIG: 버전 설정
183
+ configXml.widget.$.version = this._npmConfig.version;
184
+
185
+ // CONFIG: ICON 설정
186
+ if (this._opt.config.icon != null) {
187
+ configXml["widget"]["icon"] = [{ $: { src: "res/icons/" + path.basename(this._opt.config.icon) } }];
188
+ }
189
+
190
+ // CONFIG: 접근허용 세팅
191
+ configXml["widget"]["access"] = [{ $: { origin: "*" } }];
192
+ configXml["widget"]["allow-navigation"] = [{ $: { href: "*" } }];
193
+ configXml["widget"]["allow-intent"] = [{ $: { href: "*" } }];
194
+ configXml["widget"]["preference"] = [{ $: { name: "MixedContentMode", value: "0" } }];
195
+
196
+ // CONFIG: ANDROID usesCleartextTraffic 설정 및 splashscreen 파일 설정
197
+ if (this._opt.config.platform?.android) {
198
+ configXml.widget.$["xmlns:android"] = "http://schemas.android.com/apk/res/android";
199
+
200
+ configXml["widget"]["platform"] = configXml["widget"]["platform"] ?? [];
201
+
202
+ const androidPlatform = {
203
+ "$": {
204
+ name: "android",
205
+ },
206
+ "preference": [
207
+ {
208
+ $: {
209
+ name: "AndroidWindowSplashScreenAnimatedIcon",
210
+ value: "res/screen/android/splashscreen.xml",
211
+ },
212
+ },
213
+ ],
214
+ "edit-config": [
215
+ {
216
+ $: {
217
+ file: "app/src/main/AndroidManifest.xml",
218
+ mode: "merge",
219
+ target: "/manifest/application",
220
+ },
221
+ application: [
222
+ {
223
+ $: {
224
+ "android:usesCleartextTraffic": "true",
225
+ },
226
+ },
227
+ ],
228
+ },
229
+ ],
230
+ };
231
+
232
+ if (this._opt.config.platform.android.sdkVersion != null) {
233
+ androidPlatform.preference.push(
234
+ ...[
235
+ {
236
+ $: {
237
+ name: "android-maxSdkVersion",
238
+ value: `${this._opt.config.platform.android.sdkVersion}`,
239
+ },
240
+ },
241
+ {
242
+ $: {
243
+ name: "android-minSdkVersion",
244
+ value: `${this._opt.config.platform.android.sdkVersion}`,
245
+ },
246
+ },
247
+ {
248
+ $: {
249
+ name: "android-targetSdkVersion",
250
+ value: `${this._opt.config.platform.android.sdkVersion}`,
251
+ },
252
+ },
253
+ {
254
+ $: {
255
+ name: "android-compileSdkVersion",
256
+ value: `33`,
257
+ },
258
+ },
259
+ ],
260
+ );
261
+ }
262
+
263
+ if (this._opt.config.platform.android.permissions) {
264
+ androidPlatform["config-file"] = androidPlatform["config-file"] ?? [];
265
+ androidPlatform["config-file"].push({
266
+ "$": {
267
+ target: "AndroidManifest.xml",
268
+ parent: "/*",
269
+ },
270
+ "uses-permission": this._opt.config.platform.android.permissions.map((perm) => ({
271
+ $: {
272
+ "android:name": `android.permission.${perm.name}`,
273
+ ...(perm.maxSdkVersion != null
274
+ ? {
275
+ "android:maxSdkVersion": `${perm.maxSdkVersion}`,
276
+ }
277
+ : {}),
278
+ },
279
+ })),
280
+ });
281
+ }
282
+
283
+ configXml["widget"]["platform"].push(androidPlatform);
284
+ }
285
+
286
+ // CONFIG: 파일 새로 쓰기
287
+ const configResultContent = new xml2js.Builder().buildObject(configXml);
288
+ FsUtil.writeFile(configFilePath, configResultContent);
289
+
290
+ // 각 플랫폼 www 준비
291
+ await this._execAsync(`${BIN_PATH} prepare`, cordovaPath);
292
+ }
293
+
294
+ public async buildAsync(outPath: string): Promise<void> {
295
+ const cordovaPath = path.resolve(this._opt.pkgPath, ".cordova");
296
+
297
+ // 실행
298
+ const buildType = this._opt.config.debug ? "debug" : "release";
299
+ for (const platform of this._platforms) {
300
+ await this._execAsync(`${BIN_PATH} build ${platform} --${buildType}`, cordovaPath);
301
+ }
302
+
303
+ for (const platform of Object.keys(this._opt.config.platform ?? {})) {
304
+ const targetOutPath = path.resolve(outPath, platform);
305
+
306
+ // 결과물 복사: ANDROID
307
+ if (platform === "android") {
308
+ const apkFileName = this._opt.config.platform!.android!.sign
309
+ ? `app-${buildType}.apk`
310
+ : `app-${buildType}-unsigned.apk`;
311
+ const latestDistApkFileName = path.basename(
312
+ `${this._opt.config.appName}${this._opt.config.platform!.android!.sign ? "" : "-unsigned"}-latest.apk`,
313
+ );
314
+ FsUtil.mkdirs(targetOutPath);
315
+ FsUtil.copy(
316
+ path.resolve(cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName),
317
+ path.resolve(targetOutPath, latestDistApkFileName),
318
+ );
319
+ }
320
+
321
+ // 자동업데이트를 위한 파일 쓰기 (ZIP)
322
+ const zip = new JSZip();
323
+ const wwwFiles = FsUtil.glob(path.resolve(cordovaPath, "www/**/*"), { nodir: true });
324
+ for (const wwwFile of wwwFiles) {
325
+ const relFilePath = path.relative(path.resolve(cordovaPath, "www"), wwwFile);
326
+ const fileBuffer = FsUtil.readFileBuffer(wwwFile);
327
+ zip.file(relFilePath, fileBuffer);
328
+ }
329
+ const platformWwwFiles = FsUtil.glob(path.resolve(cordovaPath, "platforms", platform, "platform_www/**/*"), {
330
+ nodir: true,
331
+ });
332
+ for (const platformWwwFile of platformWwwFiles) {
333
+ const relFilePath = path.relative(
334
+ path.resolve(cordovaPath, "platforms", platform, "platform_www"),
335
+ platformWwwFile,
336
+ );
337
+ const fileBuffer = FsUtil.readFileBuffer(platformWwwFile);
338
+ zip.file(relFilePath, fileBuffer);
339
+ }
340
+
341
+ FsUtil.writeFile(
342
+ path.resolve(path.resolve(outPath, platform, "updates"), this._npmConfig.version + ".zip"),
343
+ await zip.generateAsync({ type: "nodebuffer" }),
344
+ );
345
+ }
346
+ }
347
+
348
+ public static async runWebviewOnDeviceAsync(opt: { platform: string; pkgName: string; url?: string }): Promise<void> {
349
+ const cordovaPath = path.resolve(process.cwd(), `packages/${opt.pkgName}/.cordova/`);
350
+
351
+ if (opt.url !== undefined) {
352
+ FsUtil.remove(path.resolve(cordovaPath, "www"));
353
+ FsUtil.mkdirs(path.resolve(cordovaPath, "www"));
354
+ FsUtil.writeFile(
355
+ path.resolve(cordovaPath, "www/index.html"),
356
+ `'${opt.url}'로 이동중... <script>setTimeout(function () {window.location.href = "${opt.url.replace(/\/$/, "")}/${opt.pkgName}/cordova/"}, 3000);</script>`.trim(),
357
+ );
358
+ }
359
+
360
+ const binPath = path.resolve(process.cwd(), "node_modules/.bin/cordova.cmd");
361
+ await SdProcess.spawnAsync(`${binPath} run ${opt.platform} --device`, { cwd: cordovaPath }, true);
362
+ }
363
+ }