expo-release-it 0.1.1 → 0.1.3

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 (100) hide show
  1. package/README.md +2 -0
  2. package/build/command/build.js +187 -130
  3. package/build/command/build.js.map +1 -1
  4. package/build/command/bump.js +35 -29
  5. package/build/command/bump.js.map +1 -1
  6. package/build/command/init.js +80 -68
  7. package/build/command/init.js.map +1 -1
  8. package/build/command/pull.d.ts +5 -0
  9. package/build/command/pull.js +568 -0
  10. package/build/command/pull.js.map +1 -0
  11. package/build/command/submit.js +171 -116
  12. package/build/command/submit.js.map +1 -1
  13. package/build/command/upload.js +186 -136
  14. package/build/command/upload.js.map +1 -1
  15. package/build/index.js +411 -283
  16. package/build/index.js.map +1 -1
  17. package/build/util/FastlaneOption.js +15 -19
  18. package/build/util/FastlaneOption.js.map +1 -1
  19. package/build/util/FileUtil.d.ts +2 -1
  20. package/build/util/FileUtil.js +4 -0
  21. package/build/util/FileUtil.js.map +1 -1
  22. package/build/util/MetadataSyncUtil.d.ts +4 -0
  23. package/build/util/MetadataSyncUtil.js +140 -0
  24. package/build/util/MetadataSyncUtil.js.map +1 -0
  25. package/build/util/OptionHolder.d.ts +2 -3
  26. package/build/util/OptionHolder.js +8 -9
  27. package/build/util/OptionHolder.js.map +1 -1
  28. package/build/util/generateAppStoreConnectApiKeyFile.d.ts +3 -0
  29. package/build/util/{setup/promptCommonInputs.js → generateAppStoreConnectApiKeyFile.js} +37 -21
  30. package/build/util/generateAppStoreConnectApiKeyFile.js.map +1 -0
  31. package/build/util/injectTemplatePlaceHolders.js +18 -30
  32. package/build/util/injectTemplatePlaceHolders.js.map +1 -1
  33. package/build/util/input/InqueryInputs.js +8 -9
  34. package/build/util/input/InqueryInputs.js.map +1 -1
  35. package/build/util/iterateAllFiles.js.map +1 -1
  36. package/build/util/logger.d.ts +1 -0
  37. package/build/util/logger.js +1 -0
  38. package/build/util/logger.js.map +1 -1
  39. package/build/util/{VersionUtil.js → setup/VersionUtil.js} +10 -10
  40. package/build/util/setup/VersionUtil.js.map +1 -0
  41. package/build/util/setup/execShellScript.d.ts +19 -0
  42. package/build/util/setup/execShellScript.js +19 -0
  43. package/build/util/setup/execShellScript.js.map +1 -0
  44. package/build/util/{hydrateKeyholderFileValues.js → setup/hydrateKeyholderFileValues.js} +15 -11
  45. package/build/util/setup/hydrateKeyholderFileValues.js.map +1 -0
  46. package/build/util/setup/prepareAndroid.js +103 -62
  47. package/build/util/setup/prepareAndroid.js.map +1 -1
  48. package/build/util/setup/prepareIos.js +107 -59
  49. package/build/util/setup/prepareIos.js.map +1 -1
  50. package/build/util/setup/setup.d.ts +2 -1
  51. package/build/util/setup/setup.js +31 -26
  52. package/build/util/setup/setup.js.map +1 -1
  53. package/build/util/spinner.d.ts +3 -0
  54. package/build/util/spinner.js +14 -0
  55. package/build/util/spinner.js.map +1 -0
  56. package/build/util/throwError.js +1 -0
  57. package/build/util/throwError.js.map +1 -1
  58. package/package.json +5 -5
  59. package/template/android/Gemfile +1 -1
  60. package/template/android/fastlane/Fastfile +4 -2
  61. package/template/ios/Gemfile +2 -1
  62. package/template/ios/fastlane/Fastfile +20 -3
  63. package/build/util/VersionUtil.js.map +0 -1
  64. package/build/util/hydrateKeyholderFileValues.js.map +0 -1
  65. package/build/util/setup/promptCommonInputs.d.ts +0 -3
  66. package/build/util/setup/promptCommonInputs.js.map +0 -1
  67. package/template/android/fastlane/Appfile +0 -2
  68. package/template/android/fastlane/metadata/android/ko-KR/changelogs/default.txt +0 -1
  69. package/template/android/fastlane/metadata/android/ko-KR/full_description.txt +0 -0
  70. package/template/android/fastlane/metadata/android/ko-KR/short_description.txt +0 -0
  71. package/template/android/fastlane/metadata/android/ko-KR/title.txt +0 -0
  72. package/template/android/fastlane/metadata/android/ko-KR/video.txt +0 -0
  73. package/template/ios/fastlane/Matchfile +0 -5
  74. package/template/ios/fastlane/metadata/copyright.txt +0 -0
  75. package/template/ios/fastlane/metadata/ko/apple_tv_privacy_policy.txt +0 -0
  76. package/template/ios/fastlane/metadata/ko/description.txt +0 -0
  77. package/template/ios/fastlane/metadata/ko/keywords.txt +0 -0
  78. package/template/ios/fastlane/metadata/ko/marketing_url.txt +0 -0
  79. package/template/ios/fastlane/metadata/ko/name.txt +0 -0
  80. package/template/ios/fastlane/metadata/ko/privacy_url.txt +0 -0
  81. package/template/ios/fastlane/metadata/ko/promotional_text.txt +0 -0
  82. package/template/ios/fastlane/metadata/ko/release_notes.txt +0 -0
  83. package/template/ios/fastlane/metadata/ko/subtitle.txt +0 -0
  84. package/template/ios/fastlane/metadata/ko/support_url.txt +0 -0
  85. package/template/ios/fastlane/metadata/primary_category.txt +0 -0
  86. package/template/ios/fastlane/metadata/primary_first_sub_category.txt +0 -1
  87. package/template/ios/fastlane/metadata/primary_second_sub_category.txt +0 -1
  88. package/template/ios/fastlane/metadata/review_information/demo_password.txt +0 -0
  89. package/template/ios/fastlane/metadata/review_information/demo_user.txt +0 -0
  90. package/template/ios/fastlane/metadata/review_information/email_address.txt +0 -0
  91. package/template/ios/fastlane/metadata/review_information/first_name.txt +0 -0
  92. package/template/ios/fastlane/metadata/review_information/last_name.txt +0 -0
  93. package/template/ios/fastlane/metadata/review_information/notes.txt +0 -1
  94. package/template/ios/fastlane/metadata/review_information/phone_number.txt +0 -0
  95. package/template/ios/fastlane/metadata/secondary_category.txt +0 -1
  96. package/template/ios/fastlane/metadata/secondary_first_sub_category.txt +0 -1
  97. package/template/ios/fastlane/metadata/secondary_second_sub_category.txt +0 -1
  98. package/template/ios/fastlane/screenshots/README.txt +0 -30
  99. /package/build/util/{VersionUtil.d.ts → setup/VersionUtil.d.ts} +0 -0
  100. /package/build/util/{hydrateKeyholderFileValues.d.ts → setup/hydrateKeyholderFileValues.d.ts} +0 -0
package/README.md CHANGED
@@ -52,6 +52,8 @@ npx expo-release-it (init|bump|build|upload|submit) [options]
52
52
 
53
53
  ## bump
54
54
 
55
+ ## pull
56
+
55
57
  ## build
56
58
 
57
59
  ## upload
@@ -1,31 +1,28 @@
1
- // src/util/setup/prepareAndroid.ts
2
- import { spinner, $ } from "zx";
3
-
4
1
  // src/util/FileUtil.ts
5
2
  import fs from "fs-extra";
6
3
  import * as path from "path";
7
4
  var join2 = path.join;
8
5
  var resolve2 = path.resolve;
9
- function exist(path3) {
10
- return fs.existsSync(path3);
6
+ function exist(path2) {
7
+ return fs.existsSync(path2);
11
8
  }
12
- function isDir(path3) {
13
- return exist(path3) && fs.lstatSync(path3).isDirectory();
9
+ function isDir(path2) {
10
+ return exist(path2) && fs.lstatSync(path2).isDirectory();
14
11
  }
15
12
  function relativePath(from, to) {
16
13
  return path.relative(from, to);
17
14
  }
18
- function isFile(path3) {
19
- return exist(path3) && fs.lstatSync(path3).isFile();
15
+ function isFile(path2) {
16
+ return exist(path2) && fs.lstatSync(path2).isFile();
20
17
  }
21
- function read(path3) {
22
- return fs.readFileSync(path3, { encoding: "utf8" });
18
+ function read(path2) {
19
+ return fs.readFileSync(path2, { encoding: "utf8" });
23
20
  }
24
- function readdir(path3) {
25
- return fs.readdirSync(path3);
21
+ function readdir(path2) {
22
+ return fs.readdirSync(path2);
26
23
  }
27
- function readJsonSlow(path3) {
28
- return fs.readJSONSync(path3);
24
+ function readJsonSlow(path2) {
25
+ return fs.readJSONSync(path2);
29
26
  }
30
27
  function write(p, content) {
31
28
  const dir = path.dirname(p);
@@ -37,21 +34,21 @@ function write(p, content) {
37
34
  function copy(src, dest, options) {
38
35
  fs.copySync(src, dest, options);
39
36
  }
40
- function remove(path3) {
41
- if (!exist(path3)) {
37
+ function remove(path2) {
38
+ if (!exist(path2)) {
42
39
  return;
43
40
  }
44
- if (fs.lstatSync(path3).isDirectory()) {
45
- return fs.rmSync(path3, { force: true, recursive: true });
41
+ if (fs.lstatSync(path2).isDirectory()) {
42
+ return fs.rmSync(path2, { force: true, recursive: true });
46
43
  } else {
47
- return fs.rmSync(path3, { force: true });
44
+ return fs.rmSync(path2, { force: true });
48
45
  }
49
46
  }
50
- async function iterateDir(path3, fn) {
51
- if (!isDir(path3)) {
47
+ async function iterateDir(path2, fn) {
48
+ if (!isDir(path2)) {
52
49
  return;
53
50
  }
54
- for (const file of fs.readdirSync(path3)) {
51
+ for (const file of fs.readdirSync(path2)) {
55
52
  await fn(file);
56
53
  }
57
54
  }
@@ -61,11 +58,11 @@ var package_default = {
61
58
  name: "expo-release-it",
62
59
  module: "src/index.ts",
63
60
  type: "module",
64
- version: "0.1.0",
61
+ version: "0.1.2",
65
62
  license: "MIT",
66
63
  scripts: {
67
64
  build: "tsup",
68
- dev: "bun run build && NODE_ENV=development node bin/expo-release-it.mjs",
65
+ dev: "yarn run build && NODE_ENV=development node bin/expo-release-it.mjs",
69
66
  release: "yarn build && release-it",
70
67
  android: "expo run:android",
71
68
  ios: "expo run:ios",
@@ -76,15 +73,15 @@ var package_default = {
76
73
  "@mj-studio/js-util": "^1.1.20",
77
74
  chalk: "^5.4.1",
78
75
  commander: "^13.1.0",
76
+ execa: "^9.5.2",
79
77
  "fs-extra": "^11.3.0",
78
+ ora: "^8.2.0",
80
79
  react: "18.3.1",
81
80
  "react-native": "0.76.9",
82
81
  semver: "^7.7.1",
83
- url: "^0.11.4",
84
- zx: "^8.5.3"
82
+ url: "^0.11.4"
85
83
  },
86
84
  devDependencies: {
87
- "@types/bun": "latest",
88
85
  "@types/fs-extra": "^11.0.4",
89
86
  "@types/semver": "^7.7.0",
90
87
  prettier: "3.5.3",
@@ -117,26 +114,13 @@ var OptionHolder = {
117
114
  input: {},
118
115
  keyholderMap: {},
119
116
  templateDirNames: ["key"],
120
- iosBundleIdentifier: "",
121
- androidPackageName: "",
122
117
  projectDir: "",
123
- outputOfInitDir: "",
118
+ resourcesDir: "",
124
119
  keyDir: "",
125
120
  keyholderFilePath: "",
126
121
  versionName: "",
127
- versionCode: ""
128
- };
129
-
130
- // src/util/logger.ts
131
- import chalk from "chalk";
132
- var logger = {
133
- success: (...msg) => console.log(chalk.green(`\u2714 ${msg.join(", ")}`)),
134
- error: (...msg) => console.log(chalk.red(`\u2716 ${msg.join(", ")}`)),
135
- warn: (...msg) => console.log(chalk.yellow(`\u26A0 ${msg.join(", ")}`)),
136
- info: (...msg) => console.log(chalk.cyan(`\u2139 ${msg.join(", ")}`)),
137
- title: (...msg) => console.log(chalk.bold.blue(`
138
- ${msg.join(", ")}`)),
139
- dim: (...msg) => console.log(chalk.dim(msg.join(", ")))
122
+ versionCode: "",
123
+ tempDir: ""
140
124
  };
141
125
 
142
126
  // src/util/iterateAllFiles.ts
@@ -155,41 +139,120 @@ async function iterateAllFiles(root, callback) {
155
139
  }
156
140
 
157
141
  // src/util/injectTemplatePlaceHolders.ts
158
- import { path as path2 } from "zx";
159
142
  async function injectTemplatePlaceHolders(root) {
160
143
  await iterateAllFiles(root, async (filePath) => {
161
- const dirPath = path2.dirname(filePath);
162
144
  let content = read(filePath);
163
145
  for (const [key, value] of Object.entries(OptionHolder.keyholderMap)) {
164
146
  content = content.replaceAll(`{{${key}}}`, value);
165
147
  }
166
- content = content.replaceAll(
167
- "{{key_dir_relative_path}}",
168
- relativePath(dirPath, OptionHolder.keyDir)
169
- );
170
148
  write(filePath, content);
171
149
  });
172
150
  }
173
151
 
152
+ // src/util/spinner.ts
153
+ import { oraPromise } from "ora";
154
+ import chalk from "chalk";
155
+ async function spinner(text, promise) {
156
+ return oraPromise(promise, {
157
+ text,
158
+ successText: chalk.green(`${text} - Done`),
159
+ failText: chalk.red(`${text} - Failed`)
160
+ });
161
+ }
162
+
163
+ // src/util/setup/execShellScript.ts
164
+ import { execa } from "execa";
165
+ var exe = execa({
166
+ stdin: "pipe",
167
+ stdout: "inherit",
168
+ stderr: "inherit",
169
+ shell: false
170
+ });
171
+ var yesShell = (command, args = [], options) => {
172
+ const subProcess = exe(command, args, { ...options, stdin: "pipe" });
173
+ subProcess.stdin?.write("y\n");
174
+ subProcess.stdin?.end();
175
+ return subProcess;
176
+ };
177
+
178
+ // src/util/logger.ts
179
+ import chalk2 from "chalk";
180
+ var logger = {
181
+ success: (...msg) => console.log(chalk2.green(`\u2714 ${msg.join(", ")}`)),
182
+ done: (...msg) => console.log(chalk2.green(`\u2714 ${msg.join(", ")} - Done`)),
183
+ error: (...msg) => console.log(chalk2.red(`\u2716 ${msg.join(", ")}`)),
184
+ warn: (...msg) => console.log(chalk2.yellow(`\u26A0 ${msg.join(", ")}`)),
185
+ info: (...msg) => console.log(chalk2.cyan(`\u2139 ${msg.join(", ")}`)),
186
+ title: (...msg) => console.log(chalk2.bold.blue(`
187
+ ${msg.join(", ")}`)),
188
+ dim: (...msg) => console.log(chalk2.dim(msg.join(", ")))
189
+ };
190
+
191
+ // src/util/MetadataSyncUtil.ts
192
+ import chalk3 from "chalk";
193
+ function copyIosMetadata(to) {
194
+ const iosDir = join2(OptionHolder.projectDir, "ios");
195
+ const nativeDir = join2(iosDir, "fastlane");
196
+ const metadataNativeDir = join2(nativeDir, "metadata");
197
+ const screenshotsNativeDir = join2(nativeDir, "screenshots");
198
+ const resourcesDir = join2(OptionHolder.resourcesDir, "metadata/ios");
199
+ const metadataResourcesDir = join2(resourcesDir, "metadata");
200
+ const screenshotsResourcesDir = join2(resourcesDir, "screenshots");
201
+ if (to === "resources") {
202
+ copy(metadataNativeDir, metadataResourcesDir);
203
+ copy(screenshotsNativeDir, screenshotsResourcesDir);
204
+ logger.done(
205
+ `iOS Metadata saved in ${chalk3.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`
206
+ );
207
+ } else {
208
+ copy(metadataResourcesDir, metadataNativeDir);
209
+ copy(screenshotsResourcesDir, screenshotsNativeDir);
210
+ logger.done(
211
+ `iOS Metadata copyed to ${chalk3.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
212
+ );
213
+ }
214
+ }
215
+ function copyAndroidMetadata(to) {
216
+ const androidDir = join2(OptionHolder.projectDir, "android");
217
+ const nativeDir = join2(androidDir, "fastlane/metadata/android");
218
+ const resourcesDir = join2(OptionHolder.resourcesDir, "metadata/android");
219
+ if (to === "resouces") {
220
+ copy(nativeDir, resourcesDir);
221
+ logger.done(
222
+ `Android Metadata saved in ${chalk3.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`
223
+ );
224
+ } else {
225
+ copy(resourcesDir, nativeDir);
226
+ logger.done(
227
+ `Android Metadata copyed to ${chalk3.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
228
+ );
229
+ }
230
+ }
231
+
174
232
  // src/util/setup/prepareAndroid.ts
175
233
  async function prepareAndroid() {
176
234
  const srcDir = resolve2(OptionHolder.cli.templateDir, "android");
177
235
  const destDir = resolve2(OptionHolder.projectDir, "android");
236
+ await yesShell("expo", ["prebuild", "-p", "android", "--no-install"], {
237
+ cwd: OptionHolder.projectDir
238
+ });
239
+ logger.success("Expo Prebuild - Done");
178
240
  await spinner(
179
- "Prebuild Android",
180
- () => $`cd ${OptionHolder.projectDir} && expo prebuild -p android --no-install`
241
+ "Inject Templates",
242
+ iterateDir(srcDir, async (file) => {
243
+ const filePath = resolve2(srcDir, file);
244
+ remove(resolve2(destDir, file));
245
+ copy(filePath, resolve2(destDir, file));
246
+ })
181
247
  );
182
- logger.success("expo prebuild");
183
- await iterateDir(srcDir, async (file) => {
184
- const filePath = resolve2(srcDir, file);
185
- remove(resolve2(destDir, file));
186
- copy(filePath, resolve2(destDir, file));
187
- });
188
- logger.success("Inject Android templates");
189
- await replaceAndroidSigningConfig(destDir);
190
- logger.success("Overwrite Android Release Signing Config");
191
- await injectTemplatePlaceHolders(resolve2(destDir, "fastlane"));
192
- logger.success("Hydrate template placeholders");
248
+ await spinner("Overwrite Android Release Signing Config", replaceAndroidSigningConfig(destDir));
249
+ await spinner(
250
+ "Hydrate template placeholders",
251
+ injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
252
+ );
253
+ await exe({ cwd: destDir })`bundle install`;
254
+ logger.success("Bunder Install - Done");
255
+ copyAndroidMetadata("native");
193
256
  }
194
257
  async function replaceAndroidSigningConfig(destDir) {
195
258
  const buildGradleDirPath = resolve2(destDir, "app");
@@ -204,7 +267,7 @@ async function replaceAndroidSigningConfig(destDir) {
204
267
  `
205
268
  signingConfigs {
206
269
  debug {
207
- storeFile file('${relativePath(buildGradleDirPath, resolve2(OptionHolder.outputOfInitDir, "key", "android_release_keystore.jks"))}')
270
+ storeFile file('${relativePath(buildGradleDirPath, resolve2(OptionHolder.resourcesDir, "key", "android_release_keystore.jks"))}')
208
271
  storePassword '${android_keystore_store_password}'
209
272
  keyAlias '${android_keystore_key_alias}'
210
273
  keyPassword '${android_keystore_key_password}'
@@ -215,21 +278,11 @@ async function replaceAndroidSigningConfig(destDir) {
215
278
  write(buildGradlePath, content);
216
279
  }
217
280
 
218
- // src/util/EnvUtil.ts
219
- var isDev = process.env.NODE_ENV === "development";
220
- var isWin = process.platform.startsWith("win");
221
-
222
- // src/util/setup/promptCommonInputs.ts
223
- async function promptCommonInputs() {
224
- OptionHolder.projectDir = isDev ? resolve2("example") : resolve2(".");
225
- OptionHolder.outputOfInitDir = resolve2(OptionHolder.projectDir, "expo-release-it");
226
- OptionHolder.keyDir = resolve2(OptionHolder.outputOfInitDir, "key");
227
- OptionHolder.keyholderFilePath = resolve2(OptionHolder.outputOfInitDir, "keyholder.json");
228
- }
229
-
230
- // src/util/hydrateKeyholderFileValues.ts
281
+ // src/util/setup/hydrateKeyholderFileValues.ts
231
282
  async function hydrateKeyholderFileValues() {
232
- Object.assign(OptionHolder.keyholderMap, readJsonSlow(OptionHolder.keyholderFilePath));
283
+ if (exist(OptionHolder.keyholderFilePath)) {
284
+ Object.assign(OptionHolder.keyholderMap, readJsonSlow(OptionHolder.keyholderFilePath));
285
+ }
233
286
  }
234
287
 
235
288
  // src/util/throwError.ts
@@ -242,7 +295,7 @@ function throwError(message, e) {
242
295
  process.exit(1);
243
296
  }
244
297
 
245
- // src/util/VersionUtil.ts
298
+ // src/util/setup/VersionUtil.ts
246
299
  import semver from "semver";
247
300
  async function parseBinaryVersions() {
248
301
  const files = readdir(OptionHolder.projectDir);
@@ -299,36 +352,51 @@ async function parseBinaryVersions() {
299
352
  }
300
353
  }
301
354
 
355
+ // src/util/EnvUtil.ts
356
+ var isDev = process.env.NODE_ENV === "development";
357
+ var isWin = process.platform.startsWith("win");
358
+
302
359
  // src/util/setup/setup.ts
303
360
  async function setup() {
304
- await promptCommonInputs();
361
+ await setupBasicOptions();
305
362
  await hydrateKeyholderFileValues();
306
363
  await parseBinaryVersions();
307
364
  }
365
+ async function setupBasicOptions() {
366
+ OptionHolder.projectDir = isDev ? resolve2("example") : resolve2(".");
367
+ OptionHolder.resourcesDir = resolve2(OptionHolder.projectDir, "expo-release-it");
368
+ OptionHolder.keyDir = resolve2(OptionHolder.resourcesDir, "key");
369
+ OptionHolder.keyholderFilePath = resolve2(OptionHolder.resourcesDir, "keyholder.json");
370
+ OptionHolder.tempDir = resolve2(OptionHolder.resourcesDir, ".temp");
371
+ }
308
372
 
309
373
  // src/util/setup/prepareIos.ts
310
- import { $ as $2, spinner as spinner2 } from "zx";
311
374
  async function prepareIos() {
312
375
  const srcDir = resolve2(OptionHolder.cli.templateDir, "ios");
313
376
  const destDir = resolve2(OptionHolder.projectDir, "ios");
314
- await spinner2(
315
- "Prebuild iOS",
316
- () => $2`cd ${OptionHolder.projectDir} && expo prebuild -p ios --no-install`
317
- );
318
- logger.success("expo prebuild");
319
- await iterateDir(srcDir, async (file) => {
320
- const filePath = resolve2(srcDir, file);
321
- remove(resolve2(destDir, file));
322
- copy(filePath, resolve2(destDir, file));
377
+ await yesShell("expo", ["prebuild", "-p", "ios", "--no-install"], {
378
+ cwd: OptionHolder.projectDir
323
379
  });
324
- logger.success("Inject iOS templates");
325
- await injectTemplatePlaceHolders(resolve2(destDir, "fastlane"));
326
- logger.success("Hydrate template placeholders");
380
+ logger.success("Expo Prebuild - Done");
381
+ await spinner(
382
+ "Inject templates",
383
+ iterateDir(srcDir, async (file) => {
384
+ const filePath = resolve2(srcDir, file);
385
+ remove(resolve2(destDir, file));
386
+ copy(filePath, resolve2(destDir, file));
387
+ })
388
+ );
389
+ await spinner(
390
+ "Hydrate template placeholders",
391
+ injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
392
+ );
393
+ await exe({ cwd: destDir })`bundle install`;
394
+ logger.success("Bunder Install - Done");
395
+ copyIosMetadata("native");
327
396
  }
328
397
 
329
398
  // src/command/build.ts
330
- import { spinner as spinner3, $ as $3 } from "zx";
331
- import chalk3 from "chalk";
399
+ import chalk5 from "chalk";
332
400
 
333
401
  // src/util/calculateElapsed.ts
334
402
  import { padZero } from "@mj-studio/js-util";
@@ -342,7 +410,7 @@ function calculateElapsed(t) {
342
410
  // src/util/input/InqueryInputs.ts
343
411
  import { select } from "@inquirer/prompts";
344
412
  import { is } from "@mj-studio/js-util";
345
- import chalk2 from "chalk";
413
+ import chalk4 from "chalk";
346
414
  var InqueryInputs = {
347
415
  platform: async () => {
348
416
  if (!OptionHolder.input.platform) {
@@ -406,19 +474,19 @@ function constructInquirerFormattedMessage({
406
474
  referUrl,
407
475
  name
408
476
  }) {
409
- let ret = `${chalk2.bold(name)}`;
477
+ let ret = `${chalk4.bold(name)}`;
410
478
  if (explanation) {
411
479
  ret += `
412
480
 
413
- ${chalk2.italic.blue(explanation)}`;
481
+ ${chalk4.italic.blue(explanation)}`;
414
482
  }
415
483
  if (example) {
416
484
  ret += `
417
- ${chalk2.italic(`${chalk2.greenBright("example :")} ${example}`)}`;
485
+ ${chalk4.italic(`${chalk4.greenBright("example :")} ${example}`)}`;
418
486
  }
419
487
  if (referUrl) {
420
488
  ret += `
421
- ${chalk2.italic(`${chalk2.greenBright("references :")} ${chalk2.underline.blue(referUrl)}`)}`;
489
+ ${chalk4.italic(`${chalk4.greenBright("references :")} ${chalk4.underline.blue(referUrl)}`)}`;
422
490
  }
423
491
  if (explanation) {
424
492
  ret += "\n";
@@ -432,17 +500,13 @@ ${chalk2.italic(`${chalk2.greenBright("references :")} ${chalk2.underline.blue(r
432
500
  // src/util/FastlaneOption.ts
433
501
  function getIosFastlaneOptions() {
434
502
  return [
503
+ ...Object.entries(OptionHolder.keyholderMap).map(([k, v]) => `${k}:${v}`),
435
504
  `version_name:${OptionHolder.versionName}`,
436
505
  `version_code:${OptionHolder.versionCode}`,
437
- `ios_app_identifier:${OptionHolder.iosBundleIdentifier}`,
438
- `ios_xcode_project_target:${OptionHolder.keyholderMap.ios_xcode_project_target}`,
439
- `ios_developer_team_id:${OptionHolder.keyholderMap.ios_developer_team_id}`,
440
- `ios_app_store_connect_api_key_id:${OptionHolder.keyholderMap.ios_app_store_connect_api_key_id}`,
441
- `ios_app_store_connect_api_key_issuer_id:${OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id}`,
442
506
  `api_key_filepath:${resolve2(OptionHolder.keyDir, "ios_testflight_upload_api_key.p8")}`,
443
507
  `upload_metadata:${OptionHolder.input.uploadMetadata}`,
444
- `ipa_path:${resolve2(OptionHolder.outputOfInitDir, "output", "ios", "app.ipa")}`,
445
- `ipa_dir:${resolve2(OptionHolder.outputOfInitDir, "output", "ios")}`,
508
+ `ipa_path:${resolve2(OptionHolder.resourcesDir, "output", "ios", "app.ipa")}`,
509
+ `ipa_dir:${resolve2(OptionHolder.resourcesDir, "output", "ios")}`,
446
510
  `ipa_name:app.ipa`
447
511
  ];
448
512
  }
@@ -457,10 +521,10 @@ async function build({ options }) {
457
521
  logger.info(`Version: ${OptionHolder.versionName}(${OptionHolder.versionCode})`);
458
522
  if (OptionHolder.input.platform === "ios") {
459
523
  await buildIos();
460
- logger.success(`iOS Build ${chalk3.bold.inverse(calculateElapsed(startTime))}`);
524
+ logger.success(`iOS Build ${chalk5.bold.inverse(calculateElapsed(startTime))}`);
461
525
  } else {
462
526
  await buildAndroid();
463
- logger.success(`Android Build ${chalk3.bold.inverse(calculateElapsed(startTime))}`);
527
+ logger.success(`Android Build ${chalk5.bold.inverse(calculateElapsed(startTime))}`);
464
528
  }
465
529
  }
466
530
  async function promptInputs() {
@@ -470,8 +534,7 @@ async function promptInputs() {
470
534
  }
471
535
  async function buildIos() {
472
536
  const iosDir = resolve2(OptionHolder.projectDir, "ios");
473
- const $$ = $3({
474
- verbose: false,
537
+ const exeEnv = exe({
475
538
  cwd: iosDir,
476
539
  env: {
477
540
  MATCH_PASSWORD: OptionHolder.keyholderMap.ios_match_password
@@ -480,43 +543,37 @@ async function buildIos() {
480
543
  await prepareIos();
481
544
  await fastlane();
482
545
  async function fastlane() {
483
- await spinner3("Bundler Install", () => $$`bundle install`);
484
- logger.success("Bundler Install");
485
546
  if (OptionHolder.input.pod) {
486
- await spinner3("Pod Install", () => $$`bundle exec pod install`);
487
- logger.success("Pod Install");
547
+ await exeEnv("bundle", ["exec", "pod", "install"]);
548
+ logger.done("Pod Install");
488
549
  }
489
550
  remove(resolve2(iosDir, ".xcode.env.local"));
490
- await spinner3("Fastlane", () => $$`bundle exec fastlane build ${getIosFastlaneOptions()}`);
551
+ await exeEnv("bundle", ["exec", "fastlane", "build", ...getIosFastlaneOptions()]);
552
+ logger.success(
553
+ `artifact generated: ${relativePath(OptionHolder.projectDir, resolve2(OptionHolder.resourcesDir, "output", "ios", "app.ipa"))}`
554
+ );
491
555
  }
492
556
  }
493
557
  async function buildAndroid() {
494
558
  const androidDir = resolve2(OptionHolder.projectDir, "android");
495
- const $$ = $3({
496
- verbose: false,
559
+ const exeEnv = exe({
497
560
  cwd: androidDir
498
561
  });
499
562
  await prepareAndroid();
500
563
  await fastlane();
501
564
  async function fastlane() {
502
- await spinner3("Bundler Install", () => $$`bundle install`);
503
- logger.success("Bundler Install");
504
565
  let buildOutputDir;
505
566
  let outputDir;
506
567
  if (OptionHolder.input.androidOutput === "aab") {
507
- await spinner3(
508
- "Bundle AAB",
509
- () => $$`${isWin ? "gradle.bat" : "./gradlew"} app:bundleRelease`
510
- );
568
+ await exeEnv(isWin ? "gradle.bat" : "./gradlew", ["app:bundleRelease"]);
569
+ logger.done("Bundle AAB");
511
570
  buildOutputDir = resolve2(androidDir, "app", "build", "outputs", "bundle", "release");
512
- outputDir = resolve2(OptionHolder.outputOfInitDir, "output", "android", "aab");
571
+ outputDir = resolve2(OptionHolder.resourcesDir, "output", "android", "aab");
513
572
  } else {
514
- await spinner3(
515
- "Bundle APK",
516
- () => $$`${isWin ? "gradle.bat" : "./gradlew"} app:assembleRelease`
517
- );
573
+ await exeEnv(isWin ? "gradle.bat" : "./gradlew", ["app:assembleRelease"]);
574
+ logger.done("Assemble APK");
518
575
  buildOutputDir = resolve2(androidDir, "app", "build", "outputs", "apk", "release");
519
- outputDir = resolve2(OptionHolder.outputOfInitDir, "output", "android", "apk");
576
+ outputDir = resolve2(OptionHolder.resourcesDir, "output", "android", "apk");
520
577
  }
521
578
  remove(outputDir);
522
579
  copy(buildOutputDir, outputDir);