expo-release-it 0.6.6 → 0.7.0

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 (140) hide show
  1. package/README.md +2 -0
  2. package/build/{EnvUtil-C6QbCIoV.js → EnvUtil-D5sfaKZs.js} +1 -1
  3. package/build/{EnvUtil-C6QbCIoV.js.map → EnvUtil-D5sfaKZs.js.map} +1 -1
  4. package/build/FastlaneOption-y0DYOkjC.js +50 -0
  5. package/build/FastlaneOption-y0DYOkjC.js.map +1 -0
  6. package/build/{FileUtil-Dbvp87_g.js → FileUtil-B9JnWobK.js} +1 -1
  7. package/build/{FileUtil-Dbvp87_g.js.map → FileUtil-B9JnWobK.js.map} +1 -1
  8. package/build/{InqueryInputs-hizV8u_U.js → InqueryInputs-CyW-i_4N.js} +2 -16
  9. package/build/InqueryInputs-CyW-i_4N.js.map +1 -0
  10. package/build/{MetadataSyncUtil-BbrQb4Bc.js → MetadataSyncUtil-BqWEE06B.js} +9 -9
  11. package/build/MetadataSyncUtil-BqWEE06B.js.map +1 -0
  12. package/build/NativeEnvironment-BAohR8aj.js +50 -0
  13. package/build/NativeEnvironment-BAohR8aj.js.map +1 -0
  14. package/build/{OptionHolder-CJ5tzHpp.js → OptionHolder-ooRZtG0l.js} +6 -6
  15. package/build/OptionHolder-ooRZtG0l.js.map +1 -0
  16. package/build/RubyEnvironment-CqupQjgn.js +113 -0
  17. package/build/RubyEnvironment-CqupQjgn.js.map +1 -0
  18. package/build/RubyEnvironment-K1nIGrMJ.d.ts +28 -0
  19. package/build/{VersionUtil-BPRjtPK_.js → VersionUtil-CttA4ATC.js} +4 -4
  20. package/build/{VersionUtil-BPRjtPK_.js.map → VersionUtil-CttA4ATC.js.map} +1 -1
  21. package/build/build-R29EBnOC.js +64 -0
  22. package/build/build-R29EBnOC.js.map +1 -0
  23. package/build/{bump-BBGyihtk.js → bump-NbU_02fP.js} +9 -9
  24. package/build/{bump-BBGyihtk.js.map → bump-NbU_02fP.js.map} +1 -1
  25. package/build/command/build.js +19 -20
  26. package/build/command/bump.js +12 -12
  27. package/build/command/init.js +11 -11
  28. package/build/command/pull.js +16 -20
  29. package/build/command/submit.js +16 -20
  30. package/build/command/upload.js +16 -20
  31. package/build/execShellScript-ZLVCvae2.js +32 -0
  32. package/build/execShellScript-ZLVCvae2.js.map +1 -0
  33. package/build/{generateAppStoreConnectApiKeyFile-DeuJUndI.js → generateAppStoreConnectApiKeyFile-Bt2nK7lP.js} +3 -3
  34. package/build/{generateAppStoreConnectApiKeyFile-DeuJUndI.js.map → generateAppStoreConnectApiKeyFile-Bt2nK7lP.js.map} +1 -1
  35. package/build/{hydrateKeyholderFileValues-BKnI9nbx.js → hydrateKeyholderFileValues-Cwmc5iwo.js} +3 -3
  36. package/build/{hydrateKeyholderFileValues-BKnI9nbx.js.map → hydrateKeyholderFileValues-Cwmc5iwo.js.map} +1 -1
  37. package/build/index.js +26 -28
  38. package/build/index.js.map +1 -1
  39. package/build/{init-Cce02h7G.js → init-DwlkVt7G.js} +22 -25
  40. package/build/init-DwlkVt7G.js.map +1 -0
  41. package/build/{iterateAllFiles-CcRtjpos.js → iterateAllFiles-Yx59MXv2.js} +2 -2
  42. package/build/{iterateAllFiles-CcRtjpos.js.map → iterateAllFiles-Yx59MXv2.js.map} +1 -1
  43. package/build/logger-CSZA77Zt.js +21 -0
  44. package/build/logger-CSZA77Zt.js.map +1 -0
  45. package/build/{parseConfigFile-Bv50df4o.js → parseConfigFile-DTkIYMK1.js} +7 -5
  46. package/build/parseConfigFile-DTkIYMK1.js.map +1 -0
  47. package/build/prepareAndroid-BQBbb44J.js +29 -0
  48. package/build/prepareAndroid-BQBbb44J.js.map +1 -0
  49. package/build/prepareFastlane-BmFwr96S.js +23 -0
  50. package/build/prepareFastlane-BmFwr96S.js.map +1 -0
  51. package/build/prepareIos-CGc-nhwf.js +63 -0
  52. package/build/prepareIos-CGc-nhwf.js.map +1 -0
  53. package/build/{pull-CVuxaHAJ.js → pull-COg4G-1u.js} +28 -24
  54. package/build/pull-COg4G-1u.js.map +1 -0
  55. package/build/{setup-BhGhMcG5.js → setup-Be5UwL9d.js} +8 -8
  56. package/build/setup-Be5UwL9d.js.map +1 -0
  57. package/build/submit-BaL5kRHE.js +28 -0
  58. package/build/submit-BaL5kRHE.js.map +1 -0
  59. package/build/{throwError-bsy4sijK.js → throwError-ebp_0a_3.js} +3 -3
  60. package/build/{throwError-bsy4sijK.js.map → throwError-ebp_0a_3.js.map} +1 -1
  61. package/build/type/ExpoReleaseItConfiguration.d.ts +15 -1
  62. package/build/upload-BY1mGc-G.js +32 -0
  63. package/build/upload-BY1mGc-G.js.map +1 -0
  64. package/build/util/EnvUtil.js +1 -1
  65. package/build/util/FastlaneOption.d.ts +4 -3
  66. package/build/util/FastlaneOption.js +4 -4
  67. package/build/util/FileUtil.js +1 -1
  68. package/build/util/MetadataSyncUtil.d.ts +2 -2
  69. package/build/util/MetadataSyncUtil.js +4 -4
  70. package/build/util/OptionHolder.d.ts +5 -2
  71. package/build/util/OptionHolder.js +2 -2
  72. package/build/util/generateAppStoreConnectApiKeyFile.js +3 -3
  73. package/build/util/injectTemplatePlaceHolders.js +15 -5
  74. package/build/util/injectTemplatePlaceHolders.js.map +1 -0
  75. package/build/util/input/InqueryInputs.d.ts +0 -1
  76. package/build/util/input/InqueryInputs.js +3 -3
  77. package/build/util/iterateAllFiles.js +2 -2
  78. package/build/util/logger.d.ts +2 -1
  79. package/build/util/logger.js +4 -2
  80. package/build/util/parseConfigFile.js +3 -3
  81. package/build/util/replaceStringIfNotContain.js +9 -2
  82. package/build/util/replaceStringIfNotContain.js.map +1 -0
  83. package/build/util/setup/NativeEnvironment.d.ts +5 -0
  84. package/build/util/setup/NativeEnvironment.js +7 -0
  85. package/build/util/setup/RubyEnvironment.d.ts +2 -0
  86. package/build/util/setup/RubyEnvironment.js +7 -0
  87. package/build/util/setup/VersionUtil.js +6 -6
  88. package/build/util/setup/execShellScript.d.ts +11 -14
  89. package/build/util/setup/execShellScript.js +5 -2
  90. package/build/util/setup/hydrateKeyholderFileValues.js +3 -3
  91. package/build/util/setup/prepareAndroid.d.ts +8 -2
  92. package/build/util/setup/prepareAndroid.js +4 -11
  93. package/build/util/setup/prepareFastlane.d.ts +21 -0
  94. package/build/util/setup/prepareFastlane.js +9 -0
  95. package/build/util/setup/prepareIos.d.ts +19 -2
  96. package/build/util/setup/prepareIos.js +4 -10
  97. package/build/util/setup/setup.js +9 -9
  98. package/build/util/spinner.js +14 -2
  99. package/build/util/spinner.js.map +1 -0
  100. package/build/util/throwError.js +5 -3
  101. package/expo-release-it.schema.json +16 -2
  102. package/package.json +4 -4
  103. package/template/android/fastlane/Fastfile +8 -2
  104. package/template/android/release-signing.gradle +15 -0
  105. package/template/ios/fastlane/Fastfile +52 -18
  106. package/template/ruby/Gemfile +10 -0
  107. package/template/ruby/Gemfile.lock +330 -0
  108. package/build/FastlaneOption-CxjO9q-w.js +0 -35
  109. package/build/FastlaneOption-CxjO9q-w.js.map +0 -1
  110. package/build/InqueryInputs-hizV8u_U.js.map +0 -1
  111. package/build/MetadataSyncUtil-BbrQb4Bc.js.map +0 -1
  112. package/build/OptionHolder-CJ5tzHpp.js.map +0 -1
  113. package/build/build-I9mcpo6x.js +0 -88
  114. package/build/build-I9mcpo6x.js.map +0 -1
  115. package/build/execShellScript-Bd5xbFX5.js +0 -22
  116. package/build/execShellScript-Bd5xbFX5.js.map +0 -1
  117. package/build/init-Cce02h7G.js.map +0 -1
  118. package/build/injectTemplatePlaceHolders-BzxCkQrW.js +0 -16
  119. package/build/injectTemplatePlaceHolders-BzxCkQrW.js.map +0 -1
  120. package/build/logger-DvQ7ScMQ.js +0 -16
  121. package/build/logger-DvQ7ScMQ.js.map +0 -1
  122. package/build/parseConfigFile-Bv50df4o.js.map +0 -1
  123. package/build/prepareAndroid-bUMPHe4p.js +0 -53
  124. package/build/prepareAndroid-bUMPHe4p.js.map +0 -1
  125. package/build/prepareIos-D1ar2VGf.js +0 -33
  126. package/build/prepareIos-D1ar2VGf.js.map +0 -1
  127. package/build/pull-CVuxaHAJ.js.map +0 -1
  128. package/build/replaceStringIfNotContain-BncPMRZq.js +0 -10
  129. package/build/replaceStringIfNotContain-BncPMRZq.js.map +0 -1
  130. package/build/setup-BhGhMcG5.js.map +0 -1
  131. package/build/spinner-BVmbE9I_.js +0 -15
  132. package/build/spinner-BVmbE9I_.js.map +0 -1
  133. package/build/submit-BQ3IEiKv.js +0 -65
  134. package/build/submit-BQ3IEiKv.js.map +0 -1
  135. package/build/upload-DJXVLkT_.js +0 -68
  136. package/build/upload-DJXVLkT_.js.map +0 -1
  137. package/template/android/Gemfile +0 -3
  138. package/template/ios/Gemfile +0 -5
  139. package/template/ios/fastlane/Appfile +0 -2
  140. package/template/ios/fastlane/Matchfile +0 -14
package/README.md CHANGED
@@ -18,6 +18,8 @@ Visit our [Documentation Site](https://expo-release-it.mjstudio.net)
18
18
  - 🚀 Upload artifacts to Google Play Console Internal Testing Track and iOS TestFlight
19
19
  - ✅ Submit releases for store review
20
20
 
21
+ The CLI owns release orchestration, integration with Expo-generated projects, and its managed Ruby toolchain. Prepare a toolchain supported by your project's Expo and React Native versions. Upstream native dependency or compiler incompatibilities are outside this library's scope; it does not patch Expo/RN, Pods source, or Xcode to repair them.
22
+
21
23
  # Licenses
22
24
 
23
25
  - See [LICENSE](/LICENSE)
@@ -5,4 +5,4 @@ const isTest = process.env.NODE_ENV === "test";
5
5
 
6
6
  //#endregion
7
7
  export { isDev, isTest, isWin };
8
- //# sourceMappingURL=EnvUtil-C6QbCIoV.js.map
8
+ //# sourceMappingURL=EnvUtil-D5sfaKZs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnvUtil-C6QbCIoV.js","names":[],"sources":["../src/util/EnvUtil.ts"],"sourcesContent":["export const isDev = process.env.NODE_ENV === 'development';\nexport const isWin = process.platform.startsWith('win');\nexport const isTest = process.env.NODE_ENV === 'test';\n"],"mappings":";AAAA,MAAa,QAAQ,QAAQ,IAAI,aAAa;AAC9C,MAAa,QAAQ,QAAQ,SAAS,WAAW,MAAM;AACvD,MAAa,SAAS,QAAQ,IAAI,aAAa"}
1
+ {"version":3,"file":"EnvUtil-D5sfaKZs.js","names":[],"sources":["../src/util/EnvUtil.ts"],"sourcesContent":["export const isDev = process.env.NODE_ENV === 'development';\nexport const isWin = process.platform.startsWith('win');\nexport const isTest = process.env.NODE_ENV === 'test';\n"],"mappings":";AAAA,MAAa,QAAQ,QAAQ,IAAI,aAAa;AAC9C,MAAa,QAAQ,QAAQ,SAAS,WAAW,MAAM;AACvD,MAAa,SAAS,QAAQ,IAAI,aAAa"}
@@ -0,0 +1,50 @@
1
+ import { resolve } from "./FileUtil-B9JnWobK.js";
2
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
3
+
4
+ //#region src/util/FastlaneOption.ts
5
+ async function runFastlane(ruby, lane) {
6
+ const { keyholderMap: keys, input, resourcesDir, keyDir } = OptionHolder;
7
+ const options = {
8
+ version_name: OptionHolder.versionName,
9
+ version_code: OptionHolder.versionCode,
10
+ upload_metadata: input.uploadMetadata,
11
+ upload_screenshot: input.uploadScreenshot,
12
+ ...input.platform === "ios" ? {
13
+ ios_app_identifier: keys.ios_app_identifier,
14
+ ios_developer_team_id: keys.ios_developer_team_id,
15
+ ios_match_git_url: keys.ios_match_git_url,
16
+ ios_app_store_connect_api_key_id: keys.ios_app_store_connect_api_key_id,
17
+ ios_app_store_connect_api_key_issuer_id: keys.ios_app_store_connect_api_key_issuer_id,
18
+ api_key_filepath: resolve(keyDir, "ios_app_store_connect_api_key.p8"),
19
+ project: input.iosProject,
20
+ target: input.iosTarget,
21
+ scheme: input.iosScheme,
22
+ workspace: input.iosWorkspace,
23
+ no_sign: input.sign === false,
24
+ ipa_path: resolve(resourcesDir, "output", "ios", "app.ipa"),
25
+ ipa_dir: resolve(resourcesDir, "output", "ios"),
26
+ ipa_name: "app.ipa",
27
+ archive_path: resolve(resourcesDir, "output", "ios", "app.xcarchive")
28
+ } : {
29
+ android_package_name: keys.android_package_name,
30
+ json_key: resolve(keyDir, "android_play_console_service_account.json"),
31
+ aab_path: resolve(resourcesDir, "output", "android", "aab", "app-release.aab"),
32
+ apk_path: resolve(resourcesDir, "output", "android", "apk", "app-release.apk"),
33
+ skip_upload_apk: input.androidOutput !== "apk",
34
+ skip_upload_aab: input.androidOutput !== "aab"
35
+ }
36
+ };
37
+ await ruby.bundle([
38
+ "exec",
39
+ "fastlane",
40
+ input.platform,
41
+ lane
42
+ ], { env: {
43
+ EXPO_RELEASE_IT_OPTIONS: JSON.stringify(options),
44
+ MATCH_PASSWORD: lane === "build" && input.sign !== false ? keys.ios_match_password ?? "" : ""
45
+ } });
46
+ }
47
+
48
+ //#endregion
49
+ export { runFastlane };
50
+ //# sourceMappingURL=FastlaneOption-y0DYOkjC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FastlaneOption-y0DYOkjC.js","names":["ruby: RubyEnvironment","lane: 'build' | 'upload' | 'submit'"],"sources":["../src/util/FastlaneOption.ts"],"sourcesContent":["import { resolve } from './FileUtil';\nimport { OptionHolder } from './OptionHolder';\nimport type { RubyEnvironment } from './setup/RubyEnvironment';\n\nexport async function runFastlane(ruby: RubyEnvironment, lane: 'build' | 'upload' | 'submit') {\n const { keyholderMap: keys, input, resourcesDir, keyDir } = OptionHolder;\n const options = {\n version_name: OptionHolder.versionName,\n version_code: OptionHolder.versionCode,\n upload_metadata: input.uploadMetadata,\n upload_screenshot: input.uploadScreenshot,\n ...(input.platform === 'ios'\n ? {\n ios_app_identifier: keys.ios_app_identifier,\n ios_developer_team_id: keys.ios_developer_team_id,\n ios_match_git_url: keys.ios_match_git_url,\n ios_app_store_connect_api_key_id: keys.ios_app_store_connect_api_key_id,\n ios_app_store_connect_api_key_issuer_id: keys.ios_app_store_connect_api_key_issuer_id,\n api_key_filepath: resolve(keyDir, 'ios_app_store_connect_api_key.p8'),\n project: input.iosProject,\n target: input.iosTarget,\n scheme: input.iosScheme,\n workspace: input.iosWorkspace,\n no_sign: input.sign === false,\n ipa_path: resolve(resourcesDir, 'output', 'ios', 'app.ipa'),\n ipa_dir: resolve(resourcesDir, 'output', 'ios'),\n ipa_name: 'app.ipa',\n archive_path: resolve(resourcesDir, 'output', 'ios', 'app.xcarchive'),\n }\n : {\n android_package_name: keys.android_package_name,\n json_key: resolve(keyDir, 'android_play_console_service_account.json'),\n aab_path: resolve(resourcesDir, 'output', 'android', 'aab', 'app-release.aab'),\n apk_path: resolve(resourcesDir, 'output', 'android', 'apk', 'app-release.apk'),\n skip_upload_apk: input.androidOutput !== 'apk',\n skip_upload_aab: input.androidOutput !== 'aab',\n }),\n };\n await ruby.bundle(['exec', 'fastlane', input.platform, lane], {\n env: {\n EXPO_RELEASE_IT_OPTIONS: JSON.stringify(options),\n MATCH_PASSWORD:\n lane === 'build' && input.sign !== false ? (keys.ios_match_password ?? '') : '',\n },\n });\n}\n"],"mappings":";;;;AAIA,eAAsB,YAAYA,MAAuBC,MAAqC;CAC5F,MAAM,EAAE,cAAc,MAAM,OAAO,cAAc,QAAQ,GAAG;CAC5D,MAAM,UAAU;EACd,cAAc,aAAa;EAC3B,cAAc,aAAa;EAC3B,iBAAiB,MAAM;EACvB,mBAAmB,MAAM;EACzB,GAAI,MAAM,aAAa,QACnB;GACE,oBAAoB,KAAK;GACzB,uBAAuB,KAAK;GAC5B,mBAAmB,KAAK;GACxB,kCAAkC,KAAK;GACvC,yCAAyC,KAAK;GAC9C,kBAAkB,QAAQ,QAAQ,mCAAmC;GACrE,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,WAAW,MAAM;GACjB,SAAS,MAAM,SAAS;GACxB,UAAU,QAAQ,cAAc,UAAU,OAAO,UAAU;GAC3D,SAAS,QAAQ,cAAc,UAAU,MAAM;GAC/C,UAAU;GACV,cAAc,QAAQ,cAAc,UAAU,OAAO,gBAAgB;EACtE,IACD;GACE,sBAAsB,KAAK;GAC3B,UAAU,QAAQ,QAAQ,4CAA4C;GACtE,UAAU,QAAQ,cAAc,UAAU,WAAW,OAAO,kBAAkB;GAC9E,UAAU,QAAQ,cAAc,UAAU,WAAW,OAAO,kBAAkB;GAC9E,iBAAiB,MAAM,kBAAkB;GACzC,iBAAiB,MAAM,kBAAkB;EAC1C;CACN;AACD,OAAM,KAAK,OAAO;EAAC;EAAQ;EAAY,MAAM;EAAU;CAAK,GAAE,EAC5D,KAAK;EACH,yBAAyB,KAAK,UAAU,QAAQ;EAChD,gBACE,SAAS,WAAW,MAAM,SAAS,QAAS,KAAK,sBAAsB,KAAM;CAChF,EACF,EAAC;AACH"}
@@ -54,4 +54,4 @@ async function iterateDir(path$1, fn) {
54
54
 
55
55
  //#endregion
56
56
  export { copy, exist, isDir, isFile, iterateDir, join, move, read, readJsonSlow, readdir, relativePath, remove, resolve, write, writeJson };
57
- //# sourceMappingURL=FileUtil-Dbvp87_g.js.map
57
+ //# sourceMappingURL=FileUtil-B9JnWobK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileUtil-Dbvp87_g.js","names":["path: string","path","from: string","to: string","p: string","content: string","src: string","dest: string","options?: fs.CopyOptionsSync","options?: fs.MoveOptions","json: any","fn: (file: string) => Promise<void> | void"],"sources":["../src/util/FileUtil.ts"],"sourcesContent":["import * as path from 'node:path';\n\nimport fs from 'fs-extra';\n\nexport const join = path.join;\nexport const resolve = path.resolve;\n\nexport function exist(path: string) {\n return fs.existsSync(path);\n}\n\nexport function isDir(path: string) {\n return exist(path) && fs.lstatSync(path).isDirectory();\n}\n\nexport function relativePath(from: string, to: string) {\n return path.relative(from, to);\n}\n\nexport function isFile(path: string) {\n return exist(path) && fs.lstatSync(path).isFile();\n}\n\nexport function read(path: string) {\n return fs.readFileSync(path, { encoding: 'utf8' });\n}\n\nexport function readdir(path: string) {\n return fs.readdirSync(path);\n}\n\n// you should require when possible(optimized in js)\nexport function readJsonSlow(path: string) {\n return fs.readJSONSync(path);\n}\n\nexport function write(p: string, content: string) {\n const dir = path.dirname(p);\n if (!exist(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n return fs.writeFileSync(p, content);\n}\nexport function copy(src: string, dest: string, options?: fs.CopyOptionsSync) {\n fs.copySync(src, dest, options);\n}\nexport function move(src: string, dest: string, options?: fs.MoveOptions) {\n fs.moveSync(src, dest, options);\n}\n\nexport function writeJson(path: string, json: any) {\n return write(path, JSON.stringify(json, null, 2));\n}\n\nexport function remove(path: string) {\n if (!exist(path)) {\n return;\n }\n\n if (fs.lstatSync(path).isDirectory()) {\n return fs.rmSync(path, { force: true, recursive: true });\n } else {\n return fs.rmSync(path, { force: true });\n }\n}\n\nexport async function iterateDir(path: string, fn: (file: string) => Promise<void> | void) {\n if (!isDir(path)) {\n return;\n }\n\n for (const file of fs.readdirSync(path)) {\n await fn(file);\n }\n}\n"],"mappings":";;;;AAIA,MAAa,OAAO,KAAK;AACzB,MAAa,UAAU,KAAK;AAE5B,SAAgB,MAAMA,QAAc;AAClC,QAAO,GAAG,WAAWC,OAAK;AAC3B;AAED,SAAgB,MAAMD,QAAc;AAClC,QAAO,MAAMC,OAAK,IAAI,GAAG,UAAUA,OAAK,CAAC,aAAa;AACvD;AAED,SAAgB,aAAaC,MAAcC,IAAY;AACrD,QAAO,KAAK,SAAS,MAAM,GAAG;AAC/B;AAED,SAAgB,OAAOH,QAAc;AACnC,QAAO,MAAMC,OAAK,IAAI,GAAG,UAAUA,OAAK,CAAC,QAAQ;AAClD;AAED,SAAgB,KAAKD,QAAc;AACjC,QAAO,GAAG,aAAaC,QAAM,EAAE,UAAU,OAAQ,EAAC;AACnD;AAED,SAAgB,QAAQD,QAAc;AACpC,QAAO,GAAG,YAAYC,OAAK;AAC5B;AAGD,SAAgB,aAAaD,QAAc;AACzC,QAAO,GAAG,aAAaC,OAAK;AAC7B;AAED,SAAgB,MAAMG,GAAWC,SAAiB;CAChD,MAAM,MAAM,KAAK,QAAQ,EAAE;AAC3B,MAAK,MAAM,IAAI,CACb,IAAG,UAAU,KAAK,EAAE,WAAW,KAAM,EAAC;AAGxC,QAAO,GAAG,cAAc,GAAG,QAAQ;AACpC;AACD,SAAgB,KAAKC,KAAaC,MAAcC,SAA8B;AAC5E,IAAG,SAAS,KAAK,MAAM,QAAQ;AAChC;AACD,SAAgB,KAAKF,KAAaC,MAAcE,SAA0B;AACxE,IAAG,SAAS,KAAK,MAAM,QAAQ;AAChC;AAED,SAAgB,UAAUT,QAAcU,MAAW;AACjD,QAAO,MAAMT,QAAM,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAClD;AAED,SAAgB,OAAOD,QAAc;AACnC,MAAK,MAAMC,OAAK,CACd;AAGF,KAAI,GAAG,UAAUA,OAAK,CAAC,aAAa,CAClC,QAAO,GAAG,OAAOA,QAAM;EAAE,OAAO;EAAM,WAAW;CAAM,EAAC;KAExD,QAAO,GAAG,OAAOA,QAAM,EAAE,OAAO,KAAM,EAAC;AAE1C;AAED,eAAsB,WAAWD,QAAcW,IAA4C;AACzF,MAAK,MAAMV,OAAK,CACd;AAGF,MAAK,MAAM,QAAQ,GAAG,YAAYA,OAAK,CACrC,OAAM,GAAG,KAAK;AAEjB"}
1
+ {"version":3,"file":"FileUtil-B9JnWobK.js","names":["path: string","path","from: string","to: string","p: string","content: string","src: string","dest: string","options?: fs.CopyOptionsSync","options?: fs.MoveOptions","json: any","fn: (file: string) => Promise<void> | void"],"sources":["../src/util/FileUtil.ts"],"sourcesContent":["import * as path from 'node:path';\n\nimport fs from 'fs-extra';\n\nexport const join = path.join;\nexport const resolve = path.resolve;\n\nexport function exist(path: string) {\n return fs.existsSync(path);\n}\n\nexport function isDir(path: string) {\n return exist(path) && fs.lstatSync(path).isDirectory();\n}\n\nexport function relativePath(from: string, to: string) {\n return path.relative(from, to);\n}\n\nexport function isFile(path: string) {\n return exist(path) && fs.lstatSync(path).isFile();\n}\n\nexport function read(path: string) {\n return fs.readFileSync(path, { encoding: 'utf8' });\n}\n\nexport function readdir(path: string) {\n return fs.readdirSync(path);\n}\n\n// you should require when possible(optimized in js)\nexport function readJsonSlow(path: string) {\n return fs.readJSONSync(path);\n}\n\nexport function write(p: string, content: string) {\n const dir = path.dirname(p);\n if (!exist(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n return fs.writeFileSync(p, content);\n}\nexport function copy(src: string, dest: string, options?: fs.CopyOptionsSync) {\n fs.copySync(src, dest, options);\n}\nexport function move(src: string, dest: string, options?: fs.MoveOptions) {\n fs.moveSync(src, dest, options);\n}\n\nexport function writeJson(path: string, json: any) {\n return write(path, JSON.stringify(json, null, 2));\n}\n\nexport function remove(path: string) {\n if (!exist(path)) {\n return;\n }\n\n if (fs.lstatSync(path).isDirectory()) {\n return fs.rmSync(path, { force: true, recursive: true });\n } else {\n return fs.rmSync(path, { force: true });\n }\n}\n\nexport async function iterateDir(path: string, fn: (file: string) => Promise<void> | void) {\n if (!isDir(path)) {\n return;\n }\n\n for (const file of fs.readdirSync(path)) {\n await fn(file);\n }\n}\n"],"mappings":";;;;AAIA,MAAa,OAAO,KAAK;AACzB,MAAa,UAAU,KAAK;AAE5B,SAAgB,MAAMA,QAAc;AAClC,QAAO,GAAG,WAAWC,OAAK;AAC3B;AAED,SAAgB,MAAMD,QAAc;AAClC,QAAO,MAAMC,OAAK,IAAI,GAAG,UAAUA,OAAK,CAAC,aAAa;AACvD;AAED,SAAgB,aAAaC,MAAcC,IAAY;AACrD,QAAO,KAAK,SAAS,MAAM,GAAG;AAC/B;AAED,SAAgB,OAAOH,QAAc;AACnC,QAAO,MAAMC,OAAK,IAAI,GAAG,UAAUA,OAAK,CAAC,QAAQ;AAClD;AAED,SAAgB,KAAKD,QAAc;AACjC,QAAO,GAAG,aAAaC,QAAM,EAAE,UAAU,OAAQ,EAAC;AACnD;AAED,SAAgB,QAAQD,QAAc;AACpC,QAAO,GAAG,YAAYC,OAAK;AAC5B;AAGD,SAAgB,aAAaD,QAAc;AACzC,QAAO,GAAG,aAAaC,OAAK;AAC7B;AAED,SAAgB,MAAMG,GAAWC,SAAiB;CAChD,MAAM,MAAM,KAAK,QAAQ,EAAE;AAC3B,MAAK,MAAM,IAAI,CACb,IAAG,UAAU,KAAK,EAAE,WAAW,KAAM,EAAC;AAGxC,QAAO,GAAG,cAAc,GAAG,QAAQ;AACpC;AACD,SAAgB,KAAKC,KAAaC,MAAcC,SAA8B;AAC5E,IAAG,SAAS,KAAK,MAAM,QAAQ;AAChC;AACD,SAAgB,KAAKF,KAAaC,MAAcE,SAA0B;AACxE,IAAG,SAAS,KAAK,MAAM,QAAQ;AAChC;AAED,SAAgB,UAAUT,QAAcU,MAAW;AACjD,QAAO,MAAMT,QAAM,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAClD;AAED,SAAgB,OAAOD,QAAc;AACnC,MAAK,MAAMC,OAAK,CACd;AAGF,KAAI,GAAG,UAAUA,OAAK,CAAC,aAAa,CAClC,QAAO,GAAG,OAAOA,QAAM;EAAE,OAAO;EAAM,WAAW;CAAM,EAAC;KAExD,QAAO,GAAG,OAAOA,QAAM,EAAE,OAAO,KAAM,EAAC;AAE1C;AAED,eAAsB,WAAWD,QAAcW,IAA4C;AACzF,MAAK,MAAMV,OAAK,CACd;AAGF,MAAK,MAAM,QAAQ,GAAG,YAAYA,OAAK,CACrC,OAAM,GAAG,KAAK;AAEjB"}
@@ -1,4 +1,4 @@
1
- import { OptionHolder } from "./OptionHolder-CJ5tzHpp.js";
1
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
2
2
  import chalk from "chalk";
3
3
  import { is } from "@mj-studio/js-util";
4
4
  import { select } from "@inquirer/prompts";
@@ -22,20 +22,6 @@ const InqueryInputs = {
22
22
  }]
23
23
  });
24
24
  },
25
- podinstall: async () => {
26
- if (OptionHolder.input.platform === "ios" && !is.boolean(OptionHolder.input.pod)) OptionHolder.input.pod = await select({
27
- message: constructInquirerFormattedMessage({ name: "Install CocoaPods?" }),
28
- choices: [{
29
- name: "yes",
30
- value: true,
31
- description: "Install pods before release"
32
- }, {
33
- name: "no",
34
- value: false,
35
- description: "Skip pods install"
36
- }]
37
- });
38
- },
39
25
  androidBuildOutput: async () => {
40
26
  if (OptionHolder.input.platform === "android") {
41
27
  if (!OptionHolder.input.androidOutput) OptionHolder.input.androidOutput = await select({
@@ -109,4 +95,4 @@ function constructInquirerFormattedMessage({ example, explanation, referUrl, nam
109
95
 
110
96
  //#endregion
111
97
  export { InqueryInputs, constructInquirerFormattedMessage };
112
- //# sourceMappingURL=InqueryInputs-hizV8u_U.js.map
98
+ //# sourceMappingURL=InqueryInputs-CyW-i_4N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InqueryInputs-CyW-i_4N.js","names":[],"sources":["../src/util/input/InqueryInputs.ts"],"sourcesContent":["import { select } from '@inquirer/prompts';\nimport { is } from '@mj-studio/js-util';\nimport chalk from 'chalk';\n\nimport { OptionHolder } from '../OptionHolder';\n\nexport const InqueryInputs = {\n platform: async () => {\n if (!OptionHolder.input.platform) {\n OptionHolder.input.platform = await select({\n message: constructInquirerFormattedMessage({\n name: 'Platform',\n explanation: 'Platform to run action',\n }),\n choices: [\n { name: 'ios', value: 'ios', description: 'Release ios' },\n { name: 'android', value: 'android', description: 'Release android' },\n ],\n });\n }\n },\n androidBuildOutput: async () => {\n if (OptionHolder.input.platform === 'android') {\n if (!OptionHolder.input.androidOutput) {\n OptionHolder.input.androidOutput = await select({\n message: constructInquirerFormattedMessage({\n name: 'Android output artifact type',\n }),\n choices: [\n { name: 'aab', value: 'aab', description: 'Build as App bundle' },\n { name: 'apk', value: 'apk', description: 'Build as APK' },\n ],\n });\n }\n }\n },\n uploadMetadata: async () => {\n if (!is.boolean(OptionHolder.input.uploadMetadata)) {\n OptionHolder.input.uploadMetadata = await select({\n message: constructInquirerFormattedMessage({\n name: 'Upload Text Metadata(title, description, ...)',\n }),\n choices: [\n { name: 'yes', value: true, description: 'Upload' },\n { name: 'no', value: false, description: \"Don't Upload\" },\n ],\n });\n }\n },\n uploadScreenshot: async () => {\n if (!is.boolean(OptionHolder.input.uploadScreenshot)) {\n OptionHolder.input.uploadScreenshot = await select({\n message: constructInquirerFormattedMessage({\n name: 'Upload Screenshots & Images',\n }),\n choices: [\n { name: 'yes', value: true, description: 'Upload' },\n { name: 'no', value: false, description: \"Don't Upload\" },\n ],\n });\n }\n },\n useLiveVersionIos: async () => {\n if (\n !is.boolean(OptionHolder.input.useLiveVersionIos) &&\n OptionHolder.input.platform === 'ios'\n ) {\n OptionHolder.input.useLiveVersionIos = await select({\n message: constructInquirerFormattedMessage({\n name: 'Download metadatas from live version rather than draft',\n }),\n choices: [\n { name: 'yes', value: true, description: 'Download from live version' },\n { name: 'no', value: false, description: 'Download from draft' },\n ],\n });\n }\n },\n};\n\nexport function constructInquirerFormattedMessage({\n example,\n explanation,\n referUrl,\n name,\n}: {\n name: string;\n explanation?: string;\n example?: string;\n referUrl?: string;\n}) {\n let ret = `${chalk.bold(name)}`;\n if (explanation) {\n ret += `\\n\\n${chalk.italic.blue(explanation)}`;\n }\n if (example) {\n ret += `\\n${chalk.italic(`${chalk.greenBright('example :')} ${example}`)}`;\n }\n if (referUrl) {\n ret += `\\n${chalk.italic(`${chalk.greenBright('references :')} ${chalk.underline.blue(referUrl)}`)}`;\n }\n\n if (explanation) {\n ret += '\\n';\n if (example || referUrl) {\n ret += '\\n';\n }\n }\n\n return ret;\n}\n"],"mappings":";;;;;;AAMA,MAAa,gBAAgB;CAC3B,UAAU,YAAY;AACpB,OAAK,aAAa,MAAM,SACtB,cAAa,MAAM,WAAW,MAAM,OAAO;GACzC,SAAS,kCAAkC;IACzC,MAAM;IACN,aAAa;GACd,EAAC;GACF,SAAS,CACP;IAAE,MAAM;IAAO,OAAO;IAAO,aAAa;GAAe,GACzD;IAAE,MAAM;IAAW,OAAO;IAAW,aAAa;GAAmB,CACtE;EACF,EAAC;CAEL;CACD,oBAAoB,YAAY;AAC9B,MAAI,aAAa,MAAM,aAAa,WAClC;QAAK,aAAa,MAAM,cACtB,cAAa,MAAM,gBAAgB,MAAM,OAAO;IAC9C,SAAS,kCAAkC,EACzC,MAAM,+BACP,EAAC;IACF,SAAS,CACP;KAAE,MAAM;KAAO,OAAO;KAAO,aAAa;IAAuB,GACjE;KAAE,MAAM;KAAO,OAAO;KAAO,aAAa;IAAgB,CAC3D;GACF,EAAC;EACH;CAEJ;CACD,gBAAgB,YAAY;AAC1B,OAAK,GAAG,QAAQ,aAAa,MAAM,eAAe,CAChD,cAAa,MAAM,iBAAiB,MAAM,OAAO;GAC/C,SAAS,kCAAkC,EACzC,MAAM,gDACP,EAAC;GACF,SAAS,CACP;IAAE,MAAM;IAAO,OAAO;IAAM,aAAa;GAAU,GACnD;IAAE,MAAM;IAAM,OAAO;IAAO,aAAa;GAAgB,CAC1D;EACF,EAAC;CAEL;CACD,kBAAkB,YAAY;AAC5B,OAAK,GAAG,QAAQ,aAAa,MAAM,iBAAiB,CAClD,cAAa,MAAM,mBAAmB,MAAM,OAAO;GACjD,SAAS,kCAAkC,EACzC,MAAM,8BACP,EAAC;GACF,SAAS,CACP;IAAE,MAAM;IAAO,OAAO;IAAM,aAAa;GAAU,GACnD;IAAE,MAAM;IAAM,OAAO;IAAO,aAAa;GAAgB,CAC1D;EACF,EAAC;CAEL;CACD,mBAAmB,YAAY;AAC7B,OACG,GAAG,QAAQ,aAAa,MAAM,kBAAkB,IACjD,aAAa,MAAM,aAAa,MAEhC,cAAa,MAAM,oBAAoB,MAAM,OAAO;GAClD,SAAS,kCAAkC,EACzC,MAAM,yDACP,EAAC;GACF,SAAS,CACP;IAAE,MAAM;IAAO,OAAO;IAAM,aAAa;GAA8B,GACvE;IAAE,MAAM;IAAM,OAAO;IAAO,aAAa;GAAuB,CACjE;EACF,EAAC;CAEL;AACF;AAED,SAAgB,kCAAkC,EAChD,SACA,aACA,UACA,MAMD,EAAE;CACD,IAAI,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;AAC9B,KAAI,YACF,SAAQ,MAAM,MAAM,OAAO,KAAK,YAAY,CAAC;AAE/C,KAAI,QACF,SAAQ,IAAI,MAAM,QAAQ,EAAE,MAAM,YAAY,eAAe,CAAC,GAAG,QAAQ,EAAE,CAAC;AAE9E,KAAI,SACF,SAAQ,IAAI,MAAM,QAAQ,EAAE,MAAM,YAAY,eAAe,CAAC,GAAG,MAAM,UAAU,KAAK,SAAS,CAAC,EAAE,CAAC;AAGrG,KAAI,aAAa;AACf,SAAO;AACP,MAAI,WAAW,SACb,QAAO;CAEV;AAED,QAAO;AACR"}
@@ -1,11 +1,11 @@
1
- import { copy, exist, join, relativePath } from "./FileUtil-Dbvp87_g.js";
2
- import { OptionHolder } from "./OptionHolder-CJ5tzHpp.js";
3
- import { logger } from "./logger-DvQ7ScMQ.js";
1
+ import { copy, exist, join, relativePath } from "./FileUtil-B9JnWobK.js";
2
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
3
+ import { logger } from "./logger-CSZA77Zt.js";
4
4
  import chalk from "chalk";
5
5
 
6
6
  //#region src/util/MetadataSyncUtil.ts
7
- function copyIosMetadata(to) {
8
- const iosDir = join(OptionHolder.projectDir, "ios");
7
+ function copyIosMetadata(to, workspace) {
8
+ const iosDir = workspace;
9
9
  const nativeDir = join(iosDir, "fastlane");
10
10
  const metadataNativeDir = join(nativeDir, "metadata");
11
11
  const screenshotsNativeDir = join(nativeDir, "screenshots");
@@ -23,11 +23,11 @@ function copyIosMetadata(to) {
23
23
  logger.done(`iOS Metadata copyed to ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`);
24
24
  } else logger.warn(`iOS Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}`);
25
25
  }
26
- function copyAndroidMetadata(to) {
27
- const androidDir = join(OptionHolder.projectDir, "android");
26
+ function copyAndroidMetadata(to, workspace) {
27
+ const androidDir = workspace;
28
28
  const nativeDir = join(androidDir, "fastlane/metadata/android");
29
29
  const resourcesDir = join(OptionHolder.resourcesDir, "metadata/android");
30
- if (to === "resouces") if (exist(nativeDir)) {
30
+ if (to === "resources") if (exist(nativeDir)) {
31
31
  copy(nativeDir, resourcesDir);
32
32
  logger.done(`Android Metadata saved in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`);
33
33
  } else logger.warn(`Android Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`);
@@ -39,4 +39,4 @@ function copyAndroidMetadata(to) {
39
39
 
40
40
  //#endregion
41
41
  export { copyAndroidMetadata, copyIosMetadata };
42
- //# sourceMappingURL=MetadataSyncUtil-BbrQb4Bc.js.map
42
+ //# sourceMappingURL=MetadataSyncUtil-BqWEE06B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetadataSyncUtil-BqWEE06B.js","names":["to: 'resources' | 'workspace'","workspace: string"],"sources":["../src/util/MetadataSyncUtil.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { copy, exist, join, relativePath } from './FileUtil';\nimport { logger } from './logger';\nimport { OptionHolder } from './OptionHolder';\n\nexport function copyIosMetadata(to: 'resources' | 'workspace', workspace: string) {\n const iosDir = workspace;\n\n const nativeDir = join(iosDir, 'fastlane');\n const metadataNativeDir = join(nativeDir, 'metadata');\n const screenshotsNativeDir = join(nativeDir, 'screenshots');\n\n const resourcesDir = join(OptionHolder.resourcesDir, 'metadata/ios');\n const metadataResourcesDir = join(resourcesDir, 'metadata');\n const screenshotsResourcesDir = join(resourcesDir, 'screenshots');\n\n if (to === 'resources') {\n if (exist(metadataNativeDir) && exist(screenshotsNativeDir)) {\n copy(metadataNativeDir, metadataResourcesDir);\n copy(screenshotsNativeDir, screenshotsResourcesDir);\n\n logger.done(\n `iOS Metadata saved in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`,\n );\n } else {\n logger.warn(\n `iOS Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`,\n );\n }\n } else {\n if (exist(metadataResourcesDir) && exist(screenshotsResourcesDir)) {\n copy(metadataResourcesDir, metadataNativeDir);\n copy(screenshotsResourcesDir, screenshotsNativeDir);\n\n logger.done(\n `iOS Metadata copyed to ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`,\n );\n } else {\n logger.warn(\n `iOS Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}`,\n );\n }\n }\n}\n\nexport function copyAndroidMetadata(to: 'resources' | 'workspace', workspace: string) {\n const androidDir = workspace;\n\n const nativeDir = join(androidDir, 'fastlane/metadata/android');\n const resourcesDir = join(OptionHolder.resourcesDir, 'metadata/android');\n\n if (to === 'resources') {\n if (exist(nativeDir)) {\n copy(nativeDir, resourcesDir);\n logger.done(\n `Android Metadata saved in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`,\n );\n } else {\n logger.warn(\n `Android Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`,\n );\n }\n } else {\n if (exist(resourcesDir)) {\n copy(resourcesDir, nativeDir);\n logger.done(\n `Android Metadata copyed to ${chalk.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`,\n );\n } else {\n logger.warn(\n `Android Metadata not found in ${chalk.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}`,\n );\n }\n }\n}\n"],"mappings":";;;;;;AAMA,SAAgB,gBAAgBA,IAA+BC,WAAmB;CAChF,MAAM,SAAS;CAEf,MAAM,YAAY,KAAK,QAAQ,WAAW;CAC1C,MAAM,oBAAoB,KAAK,WAAW,WAAW;CACrD,MAAM,uBAAuB,KAAK,WAAW,cAAc;CAE3D,MAAM,eAAe,KAAK,aAAa,cAAc,eAAe;CACpE,MAAM,uBAAuB,KAAK,cAAc,WAAW;CAC3D,MAAM,0BAA0B,KAAK,cAAc,cAAc;AAEjE,KAAI,OAAO,YACT,KAAI,MAAM,kBAAkB,IAAI,MAAM,qBAAqB,EAAE;AAC3D,OAAK,mBAAmB,qBAAqB;AAC7C,OAAK,sBAAsB,wBAAwB;AAEnD,SAAO,MACJ,wBAAwB,MAAM,QAAQ,aAAa,aAAa,YAAY,aAAa,CAAC,CAAC,iCAC7F;CACF,MACC,QAAO,MACJ,4BAA4B,MAAM,QAAQ,aAAa,aAAa,YAAY,UAAU,CAAC,CAAC,EAC9F;UAGC,MAAM,qBAAqB,IAAI,MAAM,wBAAwB,EAAE;AACjE,OAAK,sBAAsB,kBAAkB;AAC7C,OAAK,yBAAyB,qBAAqB;AAEnD,SAAO,MACJ,yBAAyB,MAAM,QAAQ,aAAa,aAAa,YAAY,UAAU,CAAC,CAAC,EAC3F;CACF,MACC,QAAO,MACJ,4BAA4B,MAAM,QAAQ,aAAa,aAAa,YAAY,aAAa,CAAC,CAAC,EACjG;AAGN;AAED,SAAgB,oBAAoBD,IAA+BC,WAAmB;CACpF,MAAM,aAAa;CAEnB,MAAM,YAAY,KAAK,YAAY,4BAA4B;CAC/D,MAAM,eAAe,KAAK,aAAa,cAAc,mBAAmB;AAExE,KAAI,OAAO,YACT,KAAI,MAAM,UAAU,EAAE;AACpB,OAAK,WAAW,aAAa;AAC7B,SAAO,MACJ,4BAA4B,MAAM,QAAQ,aAAa,aAAa,YAAY,aAAa,CAAC,CAAC,iCACjG;CACF,MACC,QAAO,MACJ,gCAAgC,MAAM,QAAQ,aAAa,aAAa,YAAY,UAAU,CAAC,CAAC,EAClG;UAGC,MAAM,aAAa,EAAE;AACvB,OAAK,cAAc,UAAU;AAC7B,SAAO,MACJ,6BAA6B,MAAM,QAAQ,aAAa,aAAa,YAAY,UAAU,CAAC,CAAC,EAC/F;CACF,MACC,QAAO,MACJ,gCAAgC,MAAM,QAAQ,aAAa,aAAa,YAAY,aAAa,CAAC,CAAC,EACrG;AAGN"}
@@ -0,0 +1,50 @@
1
+ import { exist, readJsonSlow, resolve } from "./FileUtil-B9JnWobK.js";
2
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
3
+ import { logger } from "./logger-CSZA77Zt.js";
4
+ import { exe } from "./execShellScript-ZLVCvae2.js";
5
+ import { createRequire } from "node:module";
6
+ import { dirname } from "node:path";
7
+ import semver from "semver";
8
+
9
+ //#region src/util/setup/NativeEnvironment.ts
10
+ async function inspectNativeEnvironment() {
11
+ const platform = OptionHolder.input.platform;
12
+ if (platform === "ios" && process.platform !== "darwin") throw new Error("Local iOS builds require macOS and Xcode.");
13
+ const require = createRequire(resolve(OptionHolder.projectDir, "package.json"));
14
+ let expoPackage;
15
+ let nativePackage;
16
+ try {
17
+ expoPackage = require.resolve("expo/package.json");
18
+ nativePackage = require.resolve("react-native/package.json");
19
+ } catch {
20
+ throw new Error("Install Expo and React Native in the target project before building. CNG projects with Expo SDK 52 or newer are supported.");
21
+ }
22
+ const native = readJsonSlow(nativePackage);
23
+ if (native.engines?.node && !semver.satisfies(process.version, native.engines.node)) throw new Error(`Node ${process.version} at ${process.execPath} does not meet this React Native version's requirement: ${native.engines.node}. Activate a compatible Node before rerunning.`);
24
+ const expoCli = resolve(dirname(expoPackage), "bin", "cli");
25
+ if (!exist(expoCli)) throw new Error(`Project-local Expo CLI not found: ${expoCli}`);
26
+ await exe(platform === "ios" ? "xcodebuild" : "java", ["-version"], { cwd: OptionHolder.projectDir });
27
+ logger.info(`Node ${process.version}: ${process.execPath}; Expo CLI: ${expoCli}`);
28
+ const env = {
29
+ CI: "1",
30
+ PATH: `${dirname(process.execPath)}:${process.env.PATH ?? ""}`
31
+ };
32
+ return async function prebuild() {
33
+ await exe(process.execPath, [
34
+ expoCli,
35
+ "prebuild",
36
+ "--clean",
37
+ "--platform",
38
+ platform,
39
+ "--no-install"
40
+ ], {
41
+ cwd: OptionHolder.projectDir,
42
+ env
43
+ });
44
+ logger.done("Expo CNG prebuild");
45
+ };
46
+ }
47
+
48
+ //#endregion
49
+ export { inspectNativeEnvironment };
50
+ //# sourceMappingURL=NativeEnvironment-BAohR8aj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeEnvironment-BAohR8aj.js","names":["expoPackage: string","nativePackage: string"],"sources":["../src/util/setup/NativeEnvironment.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname } from 'node:path';\n\nimport semver from 'semver';\n\nimport { exist, readJsonSlow, resolve } from '../FileUtil';\nimport { logger } from '../logger';\nimport { OptionHolder } from '../OptionHolder';\nimport { exe } from './execShellScript';\n\nexport async function inspectNativeEnvironment() {\n const platform = OptionHolder.input.platform;\n if (platform === 'ios' && process.platform !== 'darwin') {\n throw new Error('Local iOS builds require macOS and Xcode.');\n }\n const require = createRequire(resolve(OptionHolder.projectDir, 'package.json'));\n let expoPackage: string;\n let nativePackage: string;\n try {\n expoPackage = require.resolve('expo/package.json');\n nativePackage = require.resolve('react-native/package.json');\n } catch {\n throw new Error(\n 'Install Expo and React Native in the target project before building. CNG projects with Expo SDK 52 or newer are supported.',\n );\n }\n const native = readJsonSlow(nativePackage) as { engines?: { node?: string } };\n if (native.engines?.node && !semver.satisfies(process.version, native.engines.node)) {\n throw new Error(\n `Node ${process.version} at ${process.execPath} does not meet this React Native version's requirement: ${native.engines.node}. Activate a compatible Node before rerunning.`,\n );\n }\n const expoCli = resolve(dirname(expoPackage), 'bin', 'cli');\n if (!exist(expoCli)) throw new Error(`Project-local Expo CLI not found: ${expoCli}`);\n await exe(platform === 'ios' ? 'xcodebuild' : 'java', ['-version'], {\n cwd: OptionHolder.projectDir,\n });\n logger.info(`Node ${process.version}: ${process.execPath}; Expo CLI: ${expoCli}`);\n const env = {\n CI: '1',\n PATH: `${dirname(process.execPath)}:${process.env.PATH ?? ''}`,\n };\n return async function prebuild() {\n await exe(\n process.execPath,\n [expoCli, 'prebuild', '--clean', '--platform', platform, '--no-install'],\n {\n cwd: OptionHolder.projectDir,\n env,\n },\n );\n logger.done('Expo CNG prebuild');\n };\n}\n"],"mappings":";;;;;;;;;AAUA,eAAsB,2BAA2B;CAC/C,MAAM,WAAW,aAAa,MAAM;AACpC,KAAI,aAAa,SAAS,QAAQ,aAAa,SAC7C,OAAM,IAAI,MAAM;CAElB,MAAM,UAAU,cAAc,QAAQ,aAAa,YAAY,eAAe,CAAC;CAC/E,IAAIA;CACJ,IAAIC;AACJ,KAAI;AACF,gBAAc,QAAQ,QAAQ,oBAAoB;AAClD,kBAAgB,QAAQ,QAAQ,4BAA4B;CAC7D,QAAO;AACN,QAAM,IAAI,MACR;CAEH;CACD,MAAM,SAAS,aAAa,cAAc;AAC1C,KAAI,OAAO,SAAS,SAAS,OAAO,UAAU,QAAQ,SAAS,OAAO,QAAQ,KAAK,CACjF,OAAM,IAAI,OACP,OAAO,QAAQ,QAAQ,MAAM,QAAQ,SAAS,0DAA0D,OAAO,QAAQ,KAAK;CAGjI,MAAM,UAAU,QAAQ,QAAQ,YAAY,EAAE,OAAO,MAAM;AAC3D,MAAK,MAAM,QAAQ,CAAE,OAAM,IAAI,OAAO,oCAAoC,QAAQ;AAClF,OAAM,IAAI,aAAa,QAAQ,eAAe,QAAQ,CAAC,UAAW,GAAE,EAClE,KAAK,aAAa,WACnB,EAAC;AACF,QAAO,MAAM,OAAO,QAAQ,QAAQ,IAAI,QAAQ,SAAS,cAAc,QAAQ,EAAE;CACjF,MAAM,MAAM;EACV,IAAI;EACJ,OAAO,EAAE,QAAQ,QAAQ,SAAS,CAAC,GAAG,QAAQ,IAAI,QAAQ,GAAG;CAC9D;AACD,QAAO,eAAe,WAAW;AAC/B,QAAM,IACJ,QAAQ,UACR;GAAC;GAAS;GAAY;GAAW;GAAc;GAAU;EAAe,GACxE;GACE,KAAK,aAAa;GAClB;EACD,EACF;AACD,SAAO,KAAK,oBAAoB;CACjC;AACF"}
@@ -1,9 +1,9 @@
1
- import { resolve } from "./FileUtil-Dbvp87_g.js";
1
+ import { resolve } from "./FileUtil-B9JnWobK.js";
2
2
  import { fileURLToPath } from "url";
3
3
 
4
4
  //#region package.json
5
5
  var name = "expo-release-it";
6
- var version = "0.6.6";
6
+ var version = "0.7.0";
7
7
  var homepage = "https://expo-release-it.mjstudio.net/";
8
8
  var license = "MIT";
9
9
  var repository = "https://github.com/mym0404/expo-release-it";
@@ -28,7 +28,9 @@ var scripts = {
28
28
  "format": "oxfmt --write .",
29
29
  "format:check": "oxfmt --check .",
30
30
  "changeset": "changeset",
31
- "version-packages": "changeset version && pnpm install --lockfile-only --ignore-scripts"
31
+ "version-packages": "changeset version && pnpm install --lockfile-only --ignore-scripts",
32
+ "test:e2e": "node test/e2e.mjs",
33
+ "test:ruby": "node test/ruby.mjs"
32
34
  };
33
35
  var dependencies = {
34
36
  "@inquirer/prompts": "^7.4.1",
@@ -50,8 +52,6 @@ var devDependencies = {
50
52
  "lefthook": "^1.11.11",
51
53
  "oxfmt": "0.75.0",
52
54
  "oxlint": "1.90.0",
53
- "react": "catalog:native",
54
- "react-native": "catalog:native",
55
55
  "tiny-glob": "^0.2.9",
56
56
  "tsdown": "^0.12.7",
57
57
  "typescript": "catalog:",
@@ -102,4 +102,4 @@ const OptionHolder = {
102
102
 
103
103
  //#endregion
104
104
  export { OptionHolder };
105
- //# sourceMappingURL=OptionHolder-CJ5tzHpp.js.map
105
+ //# sourceMappingURL=OptionHolder-ooRZtG0l.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionHolder-ooRZtG0l.js","names":["OptionHolder: {\n // cli specific options\n cli: {\n // cli version\n version: string;\n // cli project root directory\n rootDir: string;\n // cli template source directory\n templateDir: string;\n };\n input: {\n platform: 'android' | 'ios';\n uploadMetadata: boolean;\n uploadScreenshot: boolean;\n androidOutput: 'apk' | 'aab';\n sign?: boolean;\n iosProject?: string;\n iosTarget?: string;\n iosScheme?: string;\n iosWorkspace?: string;\n useLiveVersionIos: boolean;\n semverIncrement: 'major' | 'minor' | 'patch';\n config?: string;\n git: {\n commit?: boolean;\n commitMessage?: string;\n tag?: boolean;\n tagName?: string;\n push?: boolean;\n };\n };\n keyholderMap: {\n ios_app_identifier: string;\n ios_developer_team_id: string;\n ios_match_git_url: string;\n ios_app_store_connect_api_key_id: string;\n ios_app_store_connect_api_key_issuer_id: string;\n ios_match_password: string;\n\n android_keystore_store_password: string;\n android_keystore_key_alias: string;\n android_keystore_key_password: string;\n android_package_name: string;\n };\n templateDirNames: string[];\n // dest project root directory\n projectDir: string;\n // dest project output of init command direcotry\n resourcesDir: string;\n keyDir: string;\n keyholderFilePath: string;\n tempDir: string;\n versionName: string;\n versionCode: string;\n}","pkgJson"],"sources":["../package.json","../src/util/OptionHolder.ts"],"sourcesContent":["{\n \"name\": \"expo-release-it\",\n \"version\": \"0.7.0\",\n \"homepage\": \"https://expo-release-it.mjstudio.net/\",\n \"license\": \"MIT\",\n \"repository\": \"https://github.com/mym0404/expo-release-it\",\n \"bin\": \"./bin/expo-release-it.mjs\",\n \"files\": [\n \"build\",\n \"package.json\",\n \"bin\",\n \"template\",\n \"expo-release-it.schema.json\"\n ],\n \"type\": \"module\",\n \"module\": \"src/index.ts\",\n \"scripts\": {\n \"build\": \"pnpm build:json-schema-type && tsdown --silent\",\n \"build:json-schema-type\": \"json2ts --input expo-release-it.schema.json --output src/type/ExpoReleaseItConfiguration.d.ts && oxfmt --write src/type/ExpoReleaseItConfiguration.d.ts\",\n \"dev\": \"pnpm build && NODE_ENV=development node bin/expo-release-it.mjs\",\n \"release\": \"pnpm build && pnpm run t && changeset publish\",\n \"t\": \"lefthook run check\",\n \"lint\": \"oxlint --deny-warnings .\",\n \"lint:fix\": \"oxlint --fix .\",\n \"format\": \"oxfmt --write .\",\n \"format:check\": \"oxfmt --check .\",\n \"changeset\": \"changeset\",\n \"version-packages\": \"changeset version && pnpm install --lockfile-only --ignore-scripts\",\n \"test:e2e\": \"node test/e2e.mjs\",\n \"test:ruby\": \"node test/ruby.mjs\"\n },\n \"dependencies\": {\n \"@inquirer/prompts\": \"^7.4.1\",\n \"@mj-studio/js-util\": \"^1.1.20\",\n \"chalk\": \"^5.4.1\",\n \"commander\": \"^13.1.0\",\n \"execa\": \"^9.5.2\",\n \"fs-extra\": \"^11.3.0\",\n \"ora\": \"^8.2.0\",\n \"semver\": \"^7.7.1\",\n \"url\": \"^0.11.4\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^3.0.3\",\n \"@commitlint/config-conventional\": \"^19.8.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/semver\": \"^7.7.0\",\n \"json-schema-to-typescript\": \"^15.0.4\",\n \"lefthook\": \"^1.11.11\",\n \"oxfmt\": \"0.75.0\",\n \"oxlint\": \"1.90.0\",\n \"tiny-glob\": \"^0.2.9\",\n \"tsdown\": \"^0.12.7\",\n \"typescript\": \"catalog:\",\n \"vitest\": \"^3.1.2\"\n },\n \"commitlint\": {\n \"extends\": [\n \"@commitlint/config-conventional\"\n ]\n },\n \"packageManager\": \"pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39\"\n}\n","import { fileURLToPath } from 'url';\n\nimport pkgJson from '../../package.json';\nimport { resolve } from './FileUtil';\n\n/**\n * CLI Comprehensive options\n * Each values can be empty by command and timing.\n */\nexport const OptionHolder: {\n // cli specific options\n cli: {\n // cli version\n version: string;\n // cli project root directory\n rootDir: string;\n // cli template source directory\n templateDir: string;\n };\n input: {\n platform: 'android' | 'ios';\n uploadMetadata: boolean;\n uploadScreenshot: boolean;\n androidOutput: 'apk' | 'aab';\n sign?: boolean;\n iosProject?: string;\n iosTarget?: string;\n iosScheme?: string;\n iosWorkspace?: string;\n useLiveVersionIos: boolean;\n semverIncrement: 'major' | 'minor' | 'patch';\n config?: string;\n git: {\n commit?: boolean;\n commitMessage?: string;\n tag?: boolean;\n tagName?: string;\n push?: boolean;\n };\n };\n keyholderMap: {\n ios_app_identifier: string;\n ios_developer_team_id: string;\n ios_match_git_url: string;\n ios_app_store_connect_api_key_id: string;\n ios_app_store_connect_api_key_issuer_id: string;\n ios_match_password: string;\n\n android_keystore_store_password: string;\n android_keystore_key_alias: string;\n android_keystore_key_password: string;\n android_package_name: string;\n };\n templateDirNames: string[];\n // dest project root directory\n projectDir: string;\n // dest project output of init command direcotry\n resourcesDir: string;\n keyDir: string;\n keyholderFilePath: string;\n tempDir: string;\n versionName: string;\n versionCode: string;\n} = {\n cli: {\n version: pkgJson.version,\n rootDir: resolve(fileURLToPath(import.meta.url), '../..'),\n templateDir: resolve(fileURLToPath(import.meta.url), '../../template'),\n },\n input: {\n git: {},\n } as any,\n keyholderMap: {} as any,\n templateDirNames: ['key'],\n projectDir: '',\n resourcesDir: '',\n keyDir: '',\n keyholderFilePath: '',\n versionName: '',\n versionCode: '',\n tempDir: '',\n};\n"],"mappings":";;;;WACU;cACG;eACC;cACD;iBACG;UACP;YACE;CACP;CACA;CACA;CACA;CACA;AACD;WACO;aACE;cACC;CACT,SAAS;CACT,0BAA0B;CAC1B,OAAO;CACP,WAAW;CACX,KAAK;CACL,QAAQ;CACR,YAAY;CACZ,UAAU;CACV,gBAAgB;CAChB,aAAa;CACb,oBAAoB;CACpB,YAAY;CACZ,aAAa;AACd;mBACe;CACd,qBAAqB;CACrB,sBAAsB;CACtB,SAAS;CACT,aAAa;CACb,SAAS;CACT,YAAY;CACZ,OAAO;CACP,UAAU;CACV,OAAO;AACR;sBACkB;CACjB,mBAAmB;CACnB,mCAAmC;CACnC,mBAAmB;CACnB,iBAAiB;CACjB,6BAA6B;CAC7B,YAAY;CACZ,SAAS;CACT,UAAU;CACV,aAAa;CACb,UAAU;CACV,cAAc;CACd,UAAU;AACX;iBACa,EACZ,WAAW,CACT,iCACD,EACF;qBACiB;sBA7DpB;;;;;;;;;;;;;;;AA8DC;;;;;;;;ACrDD,MAAaA,eAsDT;CACF,KAAK;EACH,SAASC,gBAAQ;EACjB,SAAS,QAAQ,cAAc,OAAO,KAAK,IAAI,EAAE,QAAQ;EACzD,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,EAAE,iBAAiB;CACvE;CACD,OAAO,EACL,KAAK,CAAE,EACR;CACD,cAAc,CAAE;CAChB,kBAAkB,CAAC,KAAM;CACzB,YAAY;CACZ,cAAc;CACd,QAAQ;CACR,mBAAmB;CACnB,aAAa;CACb,aAAa;CACb,SAAS;AACV"}
@@ -0,0 +1,113 @@
1
+ import { copy, read, resolve, write } from "./FileUtil-B9JnWobK.js";
2
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
3
+ import { logger, redact } from "./logger-CSZA77Zt.js";
4
+ import { printRedactedOutput } from "./execShellScript-ZLVCvae2.js";
5
+ import { execa } from "execa";
6
+ import { dirname } from "node:path";
7
+ import semver from "semver";
8
+
9
+ //#region src/util/setup/RubyEnvironment.ts
10
+ const rubyRequirement = ">=3.3.0 <4.1.0";
11
+ const gemfileName = "Gemfile";
12
+ const lockfileName = "Gemfile.lock";
13
+ const bundleLauncher = "version = ARGV.shift; gem \"bundler\", version; load Gem.bin_path(\"bundler\", \"bundle\", version)";
14
+ function rubyProcessEnvironment() {
15
+ return Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith("BUNDLE_") && !["RUBYOPT", "RUBYLIB"].includes(key)));
16
+ }
17
+ async function inspectRubyEnvironment({ needsPods = false } = {}) {
18
+ const sourceDir = resolve(OptionHolder.cli.templateDir, "ruby");
19
+ const lockfile = read(resolve(sourceDir, lockfileName));
20
+ const bundlerVersion = /BUNDLED WITH\s+([\d.]+)/.exec(lockfile)?.[1] ?? "";
21
+ if (!bundlerVersion) throw new Error("The packaged Gemfile.lock has no Bundler version.");
22
+ const env = rubyProcessEnvironment();
23
+ const probe = await execa("ruby", [
24
+ "-rjson",
25
+ "-rrbconfig",
26
+ "-e",
27
+ "v = ARGV.first; s = Gem::Specification.find_all_by_name(\"bundler\", v).first; puts JSON.generate(ruby: RbConfig.ruby, version: RUBY_VERSION, engine: RUBY_ENGINE, platform: Gem::Platform.local.to_s, bundle: s && Gem.bin_path(\"bundler\", \"bundle\", v))",
28
+ bundlerVersion
29
+ ], {
30
+ cwd: OptionHolder.projectDir,
31
+ env,
32
+ extendEnv: false,
33
+ reject: false
34
+ });
35
+ if (probe.failed) throw new Error(`Ruby from PATH could not be inspected. Required: MRI Ruby ${rubyRequirement} and Bundler ${bundlerVersion}. Activate your prepared Ruby environment, then rerun.`);
36
+ const ruby = JSON.parse(probe.stdout);
37
+ logger.info(`Ruby ${ruby.version}: ${ruby.ruby}`);
38
+ if (ruby.engine !== "ruby" || !semver.satisfies(ruby.version, rubyRequirement)) throw new Error(`Found ${ruby.engine} ${ruby.version} at ${ruby.ruby}. Required: MRI Ruby ${rubyRequirement}. Activate Ruby 3.3 (recommended), then rerun. Ruby is never installed automatically.`);
39
+ if (!ruby.bundle) throw new Error(`Ruby ${ruby.version} at ${ruby.ruby} needs Bundler ${bundlerVersion}. In that Ruby environment run: gem install bundler -v ${bundlerVersion} --no-document. Then rerun the original command. Other Bundler versions can remain installed.`);
40
+ const version = await execa(ruby.ruby, [
41
+ "-e",
42
+ bundleLauncher,
43
+ bundlerVersion,
44
+ "--version"
45
+ ], {
46
+ cwd: OptionHolder.projectDir,
47
+ env,
48
+ extendEnv: false,
49
+ reject: false
50
+ });
51
+ if (version.failed || version.stdout.trim() !== `Bundler version ${bundlerVersion}`) throw new Error(`Bundler ${bundlerVersion} could not run with ${ruby.ruby}. Reinstall that Bundler in the selected Ruby environment.`);
52
+ logger.info(`Bundler ${bundlerVersion}: ${ruby.bundle}`);
53
+ const directory = resolve(OptionHolder.resourcesDir, ".ruby");
54
+ const workspace = resolve(directory, OptionHolder.input.platform);
55
+ const bundleEnv = {
56
+ ...env,
57
+ PATH: `${dirname(ruby.ruby)}:${dirname(process.execPath)}:${env.PATH ?? ""}`,
58
+ BUNDLE_IGNORE_CONFIG: "1",
59
+ BUNDLE_GEMFILE: resolve(directory, gemfileName),
60
+ BUNDLE_PATH: resolve(directory, "vendor", `${ruby.engine}-${ruby.version}-${ruby.platform}`),
61
+ BUNDLE_APP_CONFIG: resolve(directory, ".bundle"),
62
+ BUNDLE_USER_HOME: resolve(directory, ".bundle"),
63
+ BUNDLE_FROZEN: "true",
64
+ BUNDLE_DISABLE_SHARED_GEMS: "true",
65
+ BUNDLE_WITHOUT: needsPods ? "" : "ios",
66
+ FASTLANE_SKIP_UPDATE_CHECK: "1",
67
+ FASTLANE_HIDE_CHANGELOG: "1",
68
+ FASTLANE_OPT_OUT_USAGE: "1"
69
+ };
70
+ async function bundle(args, options = {}) {
71
+ const child = execa(ruby.ruby, [
72
+ "-e",
73
+ bundleLauncher,
74
+ bundlerVersion,
75
+ ...args
76
+ ], {
77
+ cwd: options.cwd ?? workspace,
78
+ env: {
79
+ ...bundleEnv,
80
+ ...options.env
81
+ },
82
+ extendEnv: false,
83
+ all: true,
84
+ reject: false
85
+ });
86
+ if (!options.capture && child.all) await printRedactedOutput(child.all);
87
+ const result = await child;
88
+ if (result.failed) {
89
+ if (options.capture) logger.error(redact(result.all ?? ""));
90
+ throw new Error(`Ruby command failed (exit ${result.exitCode ?? "unknown"}) using Ruby ${ruby.version}, Bundler ${bundlerVersion}, and ${bundleEnv.BUNDLE_GEMFILE}.`);
91
+ }
92
+ return { stdout: result.stdout };
93
+ }
94
+ async function install() {
95
+ copy(resolve(sourceDir, gemfileName), bundleEnv.BUNDLE_GEMFILE);
96
+ copy(resolve(sourceDir, lockfileName), resolve(directory, lockfileName));
97
+ write(resolve(directory, ".gitignore"), "*\n");
98
+ await bundle(["install"], { cwd: directory });
99
+ }
100
+ return {
101
+ bundle,
102
+ install,
103
+ directory,
104
+ workspace,
105
+ executable: ruby.ruby,
106
+ version: ruby.version,
107
+ bundlerVersion
108
+ };
109
+ }
110
+
111
+ //#endregion
112
+ export { inspectRubyEnvironment, rubyProcessEnvironment, rubyRequirement };
113
+ //# sourceMappingURL=RubyEnvironment-CqupQjgn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RubyEnvironment-CqupQjgn.js","names":["ruby: { ruby: string; version: string; engine: string; platform: string; bundle?: string }","args: string[]","options: { cwd?: string; env?: Record<string, string>; capture?: boolean }"],"sources":["../src/util/setup/RubyEnvironment.ts"],"sourcesContent":["import { dirname } from 'node:path';\n\nimport { execa } from 'execa';\nimport semver from 'semver';\n\nimport { copy, read, resolve, write } from '../FileUtil';\nimport { logger, redact } from '../logger';\nimport { OptionHolder } from '../OptionHolder';\nimport { printRedactedOutput } from './execShellScript';\n\nexport const rubyRequirement = '>=3.3.0 <4.1.0';\nconst gemfileName = 'Gemfile';\nconst lockfileName = 'Gemfile.lock';\nconst bundleLauncher =\n 'version = ARGV.shift; gem \"bundler\", version; load Gem.bin_path(\"bundler\", \"bundle\", version)';\n\nexport function rubyProcessEnvironment() {\n return Object.fromEntries(\n Object.entries(process.env).filter(\n ([key]) => !key.startsWith('BUNDLE_') && !['RUBYOPT', 'RUBYLIB'].includes(key),\n ),\n );\n}\n\nexport async function inspectRubyEnvironment({ needsPods = false } = {}) {\n const sourceDir = resolve(OptionHolder.cli.templateDir, 'ruby');\n const lockfile = read(resolve(sourceDir, lockfileName));\n const bundlerVersion = /BUNDLED WITH\\s+([\\d.]+)/.exec(lockfile)?.[1] ?? '';\n if (!bundlerVersion) throw new Error('The packaged Gemfile.lock has no Bundler version.');\n\n const env = rubyProcessEnvironment();\n const probe = await execa(\n 'ruby',\n [\n '-rjson',\n '-rrbconfig',\n '-e',\n 'v = ARGV.first; s = Gem::Specification.find_all_by_name(\"bundler\", v).first; puts JSON.generate(ruby: RbConfig.ruby, version: RUBY_VERSION, engine: RUBY_ENGINE, platform: Gem::Platform.local.to_s, bundle: s && Gem.bin_path(\"bundler\", \"bundle\", v))',\n bundlerVersion,\n ],\n { cwd: OptionHolder.projectDir, env, extendEnv: false, reject: false },\n );\n if (probe.failed) {\n throw new Error(\n `Ruby from PATH could not be inspected. Required: MRI Ruby ${rubyRequirement} and Bundler ${bundlerVersion}. Activate your prepared Ruby environment, then rerun.`,\n );\n }\n const ruby: { ruby: string; version: string; engine: string; platform: string; bundle?: string } =\n JSON.parse(probe.stdout);\n logger.info(`Ruby ${ruby.version}: ${ruby.ruby}`);\n if (ruby.engine !== 'ruby' || !semver.satisfies(ruby.version, rubyRequirement)) {\n throw new Error(\n `Found ${ruby.engine} ${ruby.version} at ${ruby.ruby}. Required: MRI Ruby ${rubyRequirement}. Activate Ruby 3.3 (recommended), then rerun. Ruby is never installed automatically.`,\n );\n }\n if (!ruby.bundle) {\n throw new Error(\n `Ruby ${ruby.version} at ${ruby.ruby} needs Bundler ${bundlerVersion}. In that Ruby environment run: gem install bundler -v ${bundlerVersion} --no-document. Then rerun the original command. Other Bundler versions can remain installed.`,\n );\n }\n const version = await execa(ruby.ruby, ['-e', bundleLauncher, bundlerVersion, '--version'], {\n cwd: OptionHolder.projectDir,\n env,\n extendEnv: false,\n reject: false,\n });\n if (version.failed || version.stdout.trim() !== `Bundler version ${bundlerVersion}`) {\n throw new Error(\n `Bundler ${bundlerVersion} could not run with ${ruby.ruby}. Reinstall that Bundler in the selected Ruby environment.`,\n );\n }\n logger.info(`Bundler ${bundlerVersion}: ${ruby.bundle}`);\n\n const directory = resolve(OptionHolder.resourcesDir, '.ruby');\n const workspace = resolve(directory, OptionHolder.input.platform);\n const bundleEnv = {\n ...env,\n PATH: `${dirname(ruby.ruby)}:${dirname(process.execPath)}:${env.PATH ?? ''}`,\n BUNDLE_IGNORE_CONFIG: '1',\n BUNDLE_GEMFILE: resolve(directory, gemfileName),\n BUNDLE_PATH: resolve(directory, 'vendor', `${ruby.engine}-${ruby.version}-${ruby.platform}`),\n BUNDLE_APP_CONFIG: resolve(directory, '.bundle'),\n BUNDLE_USER_HOME: resolve(directory, '.bundle'),\n BUNDLE_FROZEN: 'true',\n BUNDLE_DISABLE_SHARED_GEMS: 'true',\n BUNDLE_WITHOUT: needsPods ? '' : 'ios',\n FASTLANE_SKIP_UPDATE_CHECK: '1',\n FASTLANE_HIDE_CHANGELOG: '1',\n FASTLANE_OPT_OUT_USAGE: '1',\n };\n\n async function bundle(\n args: string[],\n options: { cwd?: string; env?: Record<string, string>; capture?: boolean } = {},\n ) {\n const child = execa(ruby.ruby, ['-e', bundleLauncher, bundlerVersion, ...args], {\n cwd: options.cwd ?? workspace,\n env: { ...bundleEnv, ...options.env },\n extendEnv: false,\n all: true,\n reject: false,\n });\n if (!options.capture && child.all) await printRedactedOutput(child.all);\n const result = await child;\n if (result.failed) {\n if (options.capture) logger.error(redact(result.all ?? ''));\n throw new Error(\n `Ruby command failed (exit ${result.exitCode ?? 'unknown'}) using Ruby ${ruby.version}, Bundler ${bundlerVersion}, and ${bundleEnv.BUNDLE_GEMFILE}.`,\n );\n }\n return { stdout: result.stdout };\n }\n\n async function install() {\n copy(resolve(sourceDir, gemfileName), bundleEnv.BUNDLE_GEMFILE);\n copy(resolve(sourceDir, lockfileName), resolve(directory, lockfileName));\n write(resolve(directory, '.gitignore'), '*\\n');\n await bundle(['install'], { cwd: directory });\n }\n\n return {\n bundle,\n install,\n directory,\n workspace,\n executable: ruby.ruby,\n version: ruby.version,\n bundlerVersion,\n };\n}\n\nexport type RubyEnvironment = Awaited<ReturnType<typeof inspectRubyEnvironment>>;\n"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ //#region src/util/setup/RubyEnvironment.d.ts
2
+ declare const rubyRequirement = ">=3.3.0 <4.1.0";
3
+ declare function rubyProcessEnvironment(): {
4
+ [k: string]: string | undefined;
5
+ };
6
+ declare function inspectRubyEnvironment({
7
+ needsPods
8
+ }?: {
9
+ needsPods?: boolean | undefined;
10
+ }): Promise<{
11
+ bundle: (args: string[], options?: {
12
+ cwd?: string;
13
+ env?: Record<string, string>;
14
+ capture?: boolean;
15
+ }) => Promise<{
16
+ stdout: string;
17
+ }>;
18
+ install: () => Promise<void>;
19
+ directory: string;
20
+ workspace: string;
21
+ executable: string;
22
+ version: string;
23
+ bundlerVersion: string;
24
+ }>;
25
+ type RubyEnvironment = Awaited<ReturnType<typeof inspectRubyEnvironment>>;
26
+ //#endregion
27
+ export { RubyEnvironment, inspectRubyEnvironment, rubyProcessEnvironment, rubyRequirement };
28
+ //# sourceMappingURL=RubyEnvironment-K1nIGrMJ.d.ts.map
@@ -1,6 +1,6 @@
1
- import { read, readJsonSlow, readdir, resolve, write, writeJson } from "./FileUtil-Dbvp87_g.js";
2
- import { OptionHolder } from "./OptionHolder-CJ5tzHpp.js";
3
- import { throwError } from "./throwError-bsy4sijK.js";
1
+ import { read, readJsonSlow, readdir, resolve, write, writeJson } from "./FileUtil-B9JnWobK.js";
2
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
3
+ import { throwError } from "./throwError-ebp_0a_3.js";
4
4
  import { padZero } from "@mj-studio/js-util";
5
5
  import semver from "semver";
6
6
 
@@ -98,4 +98,4 @@ function generateVersionCodeTiedWithVersionName(versionName) {
98
98
 
99
99
  //#endregion
100
100
  export { checkVersionCodeIsTiedWithVersionName, generateVersionCodeTiedWithVersionName, injectBinaryVersions, parseBinaryVersions };
101
- //# sourceMappingURL=VersionUtil-BPRjtPK_.js.map
101
+ //# sourceMappingURL=VersionUtil-CttA4ATC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VersionUtil-BPRjtPK_.js","names":["filename: string","versionName: string","versionCode: string"],"sources":["../src/util/setup/VersionUtil.ts"],"sourcesContent":["import { padZero } from '@mj-studio/js-util';\nimport semver from 'semver';\n\nimport { read, readdir, readJsonSlow, resolve, write, writeJson } from '../FileUtil';\nimport { OptionHolder } from '../OptionHolder';\nimport { throwError } from '../throwError';\n\nconst versionNameRegex = () => /const\\s+VERSION_NAME\\s*?=\\s*?['\"]([\\d.]*?)['\"]\\s*?;?/;\nconst versionCodeRegex = () => /const\\s+VERSION_CODE\\s*?=\\s*?(\\d+)\\s*?;?/;\n\nexport async function parseBinaryVersions() {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await parseFromJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await parseFromJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function parseFromJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const content = read(filePath);\n\n const VERSION_NAME = versionNameRegex().exec(content)?.[1];\n const VERSION_CODE = versionCodeRegex().exec(content)?.[1];\n\n if (!VERSION_NAME) {\n throwError('cannot parse version name');\n }\n if (!VERSION_CODE) {\n throwError('cannot parse version code');\n }\n\n if (!semver.valid(VERSION_NAME)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = VERSION_NAME;\n OptionHolder.versionCode = VERSION_CODE;\n }\n\n async function parseFromJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n const versionName = `${json.expo?.version}`;\n const iosVersionCode = `${json.expo?.ios?.buildNumber}`;\n const androidVersionCode = `${json.expo?.android?.versionCode}`;\n\n if (!/\\d+/.test(iosVersionCode)) {\n throwError('app.json expo.ios.buildNumber is not an integer');\n }\n\n if (!/\\d+/.test(androidVersionCode)) {\n throwError('app.json expo.android.versionCode is not an integer');\n }\n\n if (iosVersionCode !== androidVersionCode) {\n throwError('app.json expo.ios.buildNumber is not equal with expo.android.versionCode');\n }\n\n if (!semver.valid(versionName)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = versionName;\n OptionHolder.versionCode = iosVersionCode;\n }\n}\n\nexport async function injectBinaryVersions({\n versionCode,\n versionName,\n}: {\n versionName: string;\n versionCode: string;\n}) {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await injectToJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await injectToJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function injectToJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n let content = read(filePath);\n\n content = content.replace(versionNameRegex(), `const VERSION_NAME = '${versionName}';`);\n content = content.replace(versionCodeRegex(), `const VERSION_CODE = ${versionCode};`);\n\n write(filePath, content);\n }\n\n async function injectToJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n json.expo.version = versionName;\n json.expo.ios.buildNumber = versionCode;\n json.expo.android.versionCode = +versionCode;\n\n writeJson(filePath, json);\n }\n}\n\nexport function checkVersionCodeIsTiedWithVersionName(\n versionName: string,\n versionCode: string,\n): boolean {\n if (!semver.valid(versionName)) return false;\n return generateVersionCodeTiedWithVersionName(versionName) === versionCode;\n}\n\nexport function generateVersionCodeTiedWithVersionName(versionName: string) {\n if (!semver.valid(versionName))\n throwError(\n 'Version Name is not a valid semver format when running `generateVersionCodeTiedWithVersionName`',\n );\n const major = semver.major(versionName);\n const minor = semver.minor(versionName);\n const patch = semver.patch(versionName);\n\n return `${major}${padZero(minor, 3)}${padZero(patch, 3)}`;\n}\n"],"mappings":";;;;;;;AAOA,MAAM,mBAAmB,MAAM;AAC/B,MAAM,mBAAmB,MAAM;AAE/B,eAAsB,sBAAsB;CAC1C,MAAM,QAAQ,QAAQ,aAAa,WAAW;CAE9C,MAAM,gBAAgB;EAAC;EAAiB;EAAiB;EAAkB;CAAiB;CAC5F,MAAM,iBAAiB;AAEvB,MAAK,MAAM,gBAAgB,cACzB,KAAI,MAAM,SAAS,aAAa,EAAE;AAChC,QAAM,sBAAsB,aAAa;AACzC;CACD;AAGH,KAAI,MAAM,SAAS,eAAe,EAAE;AAClC,QAAM,wBAAwB,eAAe;AAC7C;CACD;AAED,YAAW,6BAA6B;CAExC,eAAe,sBAAsBA,UAAkB;EACrD,MAAM,WAAW,QAAQ,aAAa,YAAY,SAAS;EAC3D,MAAM,UAAU,KAAK,SAAS;EAE9B,MAAM,eAAe,kBAAkB,CAAC,KAAK,QAAQ,GAAG;EACxD,MAAM,eAAe,kBAAkB,CAAC,KAAK,QAAQ,GAAG;AAExD,OAAK,aACH,YAAW,4BAA4B;AAEzC,OAAK,aACH,YAAW,4BAA4B;AAGzC,OAAK,OAAO,MAAM,aAAa,CAC7B,YAAW,4CAA4C;AAGzD,eAAa,cAAc;AAC3B,eAAa,cAAc;CAC5B;CAED,eAAe,wBAAwBA,UAAkB;EACvD,MAAM,WAAW,QAAQ,aAAa,YAAY,SAAS;EAC3D,MAAM,OAAO,aAAa,SAAS;EAEnC,MAAM,eAAe,EAAE,KAAK,MAAM,QAAQ;EAC1C,MAAM,kBAAkB,EAAE,KAAK,MAAM,KAAK,YAAY;EACtD,MAAM,sBAAsB,EAAE,KAAK,MAAM,SAAS,YAAY;AAE9D,OAAK,MAAM,KAAK,eAAe,CAC7B,YAAW,kDAAkD;AAG/D,OAAK,MAAM,KAAK,mBAAmB,CACjC,YAAW,sDAAsD;AAGnE,MAAI,mBAAmB,mBACrB,YAAW,2EAA2E;AAGxF,OAAK,OAAO,MAAM,YAAY,CAC5B,YAAW,4CAA4C;AAGzD,eAAa,cAAc;AAC3B,eAAa,cAAc;CAC5B;AACF;AAED,eAAsB,qBAAqB,EACzC,aACA,aAID,EAAE;CACD,MAAM,QAAQ,QAAQ,aAAa,WAAW;CAE9C,MAAM,gBAAgB;EAAC;EAAiB;EAAiB;EAAkB;CAAiB;CAC5F,MAAM,iBAAiB;AAEvB,MAAK,MAAM,gBAAgB,cACzB,KAAI,MAAM,SAAS,aAAa,EAAE;AAChC,QAAM,qBAAqB,aAAa;AACxC;CACD;AAGH,KAAI,MAAM,SAAS,eAAe,EAAE;AAClC,QAAM,uBAAuB,eAAe;AAC5C;CACD;AAED,YAAW,6BAA6B;CAExC,eAAe,qBAAqBA,UAAkB;EACpD,MAAM,WAAW,QAAQ,aAAa,YAAY,SAAS;EAC3D,IAAI,UAAU,KAAK,SAAS;AAE5B,YAAU,QAAQ,QAAQ,kBAAkB,GAAG,wBAAwB,YAAY,IAAI;AACvF,YAAU,QAAQ,QAAQ,kBAAkB,GAAG,uBAAuB,YAAY,GAAG;AAErF,QAAM,UAAU,QAAQ;CACzB;CAED,eAAe,uBAAuBA,UAAkB;EACtD,MAAM,WAAW,QAAQ,aAAa,YAAY,SAAS;EAC3D,MAAM,OAAO,aAAa,SAAS;AAEnC,OAAK,KAAK,UAAU;AACpB,OAAK,KAAK,IAAI,cAAc;AAC5B,OAAK,KAAK,QAAQ,eAAe;AAEjC,YAAU,UAAU,KAAK;CAC1B;AACF;AAED,SAAgB,sCACdC,aACAC,aACS;AACT,MAAK,OAAO,MAAM,YAAY,CAAE,QAAO;AACvC,QAAO,uCAAuC,YAAY,KAAK;AAChE;AAED,SAAgB,uCAAuCD,aAAqB;AAC1E,MAAK,OAAO,MAAM,YAAY,CAC5B,YACE,kGACD;CACH,MAAM,QAAQ,OAAO,MAAM,YAAY;CACvC,MAAM,QAAQ,OAAO,MAAM,YAAY;CACvC,MAAM,QAAQ,OAAO,MAAM,YAAY;AAEvC,SAAQ,EAAE,MAAM,EAAE,QAAQ,OAAO,EAAE,CAAC,EAAE,QAAQ,OAAO,EAAE,CAAC;AACzD"}
1
+ {"version":3,"file":"VersionUtil-CttA4ATC.js","names":["filename: string","versionName: string","versionCode: string"],"sources":["../src/util/setup/VersionUtil.ts"],"sourcesContent":["import { padZero } from '@mj-studio/js-util';\nimport semver from 'semver';\n\nimport { read, readdir, readJsonSlow, resolve, write, writeJson } from '../FileUtil';\nimport { OptionHolder } from '../OptionHolder';\nimport { throwError } from '../throwError';\n\nconst versionNameRegex = () => /const\\s+VERSION_NAME\\s*?=\\s*?['\"]([\\d.]*?)['\"]\\s*?;?/;\nconst versionCodeRegex = () => /const\\s+VERSION_CODE\\s*?=\\s*?(\\d+)\\s*?;?/;\n\nexport async function parseBinaryVersions() {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await parseFromJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await parseFromJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function parseFromJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const content = read(filePath);\n\n const VERSION_NAME = versionNameRegex().exec(content)?.[1];\n const VERSION_CODE = versionCodeRegex().exec(content)?.[1];\n\n if (!VERSION_NAME) {\n throwError('cannot parse version name');\n }\n if (!VERSION_CODE) {\n throwError('cannot parse version code');\n }\n\n if (!semver.valid(VERSION_NAME)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = VERSION_NAME;\n OptionHolder.versionCode = VERSION_CODE;\n }\n\n async function parseFromJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n const versionName = `${json.expo?.version}`;\n const iosVersionCode = `${json.expo?.ios?.buildNumber}`;\n const androidVersionCode = `${json.expo?.android?.versionCode}`;\n\n if (!/\\d+/.test(iosVersionCode)) {\n throwError('app.json expo.ios.buildNumber is not an integer');\n }\n\n if (!/\\d+/.test(androidVersionCode)) {\n throwError('app.json expo.android.versionCode is not an integer');\n }\n\n if (iosVersionCode !== androidVersionCode) {\n throwError('app.json expo.ios.buildNumber is not equal with expo.android.versionCode');\n }\n\n if (!semver.valid(versionName)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = versionName;\n OptionHolder.versionCode = iosVersionCode;\n }\n}\n\nexport async function injectBinaryVersions({\n versionCode,\n versionName,\n}: {\n versionName: string;\n versionCode: string;\n}) {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await injectToJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await injectToJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function injectToJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n let content = read(filePath);\n\n content = content.replace(versionNameRegex(), `const VERSION_NAME = '${versionName}';`);\n content = content.replace(versionCodeRegex(), `const VERSION_CODE = ${versionCode};`);\n\n write(filePath, content);\n }\n\n async function injectToJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n json.expo.version = versionName;\n json.expo.ios.buildNumber = versionCode;\n json.expo.android.versionCode = +versionCode;\n\n writeJson(filePath, json);\n }\n}\n\nexport function checkVersionCodeIsTiedWithVersionName(\n versionName: string,\n versionCode: string,\n): boolean {\n if (!semver.valid(versionName)) return false;\n return generateVersionCodeTiedWithVersionName(versionName) === versionCode;\n}\n\nexport function generateVersionCodeTiedWithVersionName(versionName: string) {\n if (!semver.valid(versionName))\n throwError(\n 'Version Name is not a valid semver format when running `generateVersionCodeTiedWithVersionName`',\n );\n const major = semver.major(versionName);\n const minor = semver.minor(versionName);\n const patch = semver.patch(versionName);\n\n return `${major}${padZero(minor, 3)}${padZero(patch, 3)}`;\n}\n"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { calculateElapsed } from "./calculateElapsed-DORWymX3.js";
2
+ import { copy, exist, relativePath, remove, resolve } from "./FileUtil-B9JnWobK.js";
3
+ import { OptionHolder } from "./OptionHolder-ooRZtG0l.js";
4
+ import { runFastlane } from "./FastlaneOption-y0DYOkjC.js";
5
+ import { InqueryInputs } from "./InqueryInputs-CyW-i_4N.js";
6
+ import { logger } from "./logger-CSZA77Zt.js";
7
+ import { exe } from "./execShellScript-ZLVCvae2.js";
8
+ import { inspectNativeEnvironment } from "./NativeEnvironment-BAohR8aj.js";
9
+ import { androidSigningEnvironment, prepareAndroid } from "./prepareAndroid-BQBbb44J.js";
10
+ import { inspectRubyEnvironment } from "./RubyEnvironment-CqupQjgn.js";
11
+ import { prepareFastlane } from "./prepareFastlane-BmFwr96S.js";
12
+ import { prepareIos } from "./prepareIos-CGc-nhwf.js";
13
+ import { setup } from "./setup-Be5UwL9d.js";
14
+ import { dirname } from "node:path";
15
+ import chalk from "chalk";
16
+
17
+ //#region src/command/build.ts
18
+ async function build({ options }) {
19
+ Object.assign(OptionHolder.input, options);
20
+ const startTime = Date.now();
21
+ await setup();
22
+ await InqueryInputs.platform();
23
+ await InqueryInputs.androidBuildOutput();
24
+ const isIos = OptionHolder.input.platform === "ios";
25
+ if (!isIos && OptionHolder.input.sign === false) throw new Error("--no-sign is only supported for iOS. Android release builds require a signing key.");
26
+ const ruby = await inspectRubyEnvironment({ needsPods: isIos });
27
+ const signingEnv = isIos ? {} : androidSigningEnvironment();
28
+ const prebuild = await inspectNativeEnvironment();
29
+ await prepareFastlane(ruby);
30
+ let artifact;
31
+ if (isIos) {
32
+ await prepareIos({
33
+ ruby,
34
+ prebuild
35
+ });
36
+ await runFastlane(ruby, "build");
37
+ artifact = resolve(OptionHolder.resourcesDir, "output", "ios", OptionHolder.input.sign === false ? "app.xcarchive" : "app.ipa");
38
+ } else {
39
+ await prepareAndroid(prebuild);
40
+ const isAab = OptionHolder.input.androidOutput === "aab";
41
+ await exe("./gradlew", [isAab ? "app:bundleRelease" : "app:assembleRelease"], {
42
+ cwd: resolve(OptionHolder.projectDir, "android"),
43
+ env: {
44
+ ...signingEnv,
45
+ PATH: `${dirname(process.execPath)}:${process.env.PATH ?? ""}`
46
+ }
47
+ });
48
+ const output = isAab ? "aab" : "apk";
49
+ const outputDir = resolve(OptionHolder.resourcesDir, "output", "android", output);
50
+ const buildOutput = resolve(OptionHolder.projectDir, "android", "app", "build", "outputs", isAab ? "bundle" : "apk", "release");
51
+ const binary = resolve(buildOutput, `app-release.${output}`);
52
+ if (!exist(binary)) throw new Error(`Release build output is missing: ${binary}`);
53
+ remove(outputDir);
54
+ copy(buildOutput, outputDir);
55
+ artifact = resolve(outputDir, `app-release.${output}`);
56
+ }
57
+ if (!exist(artifact)) throw new Error(`Expected build artifact was not generated: ${artifact}`);
58
+ logger.success(`artifact generated: ${relativePath(OptionHolder.projectDir, artifact)}`);
59
+ logger.success(`${isIos ? "iOS" : "Android"} Build ${chalk.bold.inverse(calculateElapsed(startTime))}`);
60
+ }
61
+
62
+ //#endregion
63
+ export { build };
64
+ //# sourceMappingURL=build-R29EBnOC.js.map