@radhya/mach 2.6.2 → 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Cloud Build & Delivery for React Native, Expo, and Flutter**
4
4
 
5
- Mach is a CLI that builds, signs, audits, versions, and submits Flutter, React Native, and Expo apps locally or in the cloud.
5
+ Mach is a CLI that builds, signs, audits, versions, submits, and deploys static web releases for Flutter, React Native, and Expo apps locally or in the cloud.
6
6
 
7
7
  ## Installation
8
8
 
@@ -67,9 +67,121 @@ mach build --platform web # Flutter projects
67
67
  | `mach audit` | Check project health, delivery impact, and security locally |
68
68
  | `mach agent` | Manage the local device discovery agent for Install Hub |
69
69
  | `mach host` | Set up S3 static hosting and CloudFront |
70
+ | `mach web` | Deploy and manage static web releases through Mach Web Hosting |
70
71
  | `mach sitemap` | Generate sitemap.xml from Expo Router app routes |
71
72
  | `mach deeplink` | Configure and verify universal links and Android App Links |
72
73
 
74
+ ## Static Web Hosting
75
+
76
+ `mach web` is Mach's managed static release workflow for Expo web, React Native
77
+ Web, Flutter web, and any finished static site. It is deliberately separate
78
+ from both `mach host` (the existing AWS S3 + CloudFront setup) and OTA updates.
79
+
80
+ Build your app on a developer machine or in CI, then upload only its finished
81
+ static directory. Each deployment receives an immutable preview URL. Mach
82
+ aliases point to immutable releases, so a promotion or rollback never rebuilds
83
+ or overwrites a previously published site.
84
+
85
+ | Address | Example for `shop` |
86
+ | --- | --- |
87
+ | Production | `https://shop.getmach.dev` |
88
+ | Staging | `https://shop--staging.getmach.dev` |
89
+ | Immutable preview | `https://shop--d_<deployment-id>.getmach.dev` |
90
+
91
+ Before the first web deployment, the project owner chooses the Production
92
+ subdomain in **Dashboard → Web Hosting**. The project slug is the default. The
93
+ name is reserved globally and locks after the first deployment so shared URLs
94
+ remain permanent.
95
+
96
+ ### Reuse existing mobile profiles
97
+
98
+ Do not rename mobile profiles to match a hostname. Add an explicit `web` block
99
+ to the profiles you already use. It maps release intent to a web alias and tells
100
+ Mach where the finished static output is written:
101
+
102
+ ```json
103
+ {
104
+ "build": {
105
+ "qa-mobile": {
106
+ "distribution": "internal",
107
+ "web": { "alias": "staging", "output": "dist" }
108
+ },
109
+ "store-release": {
110
+ "distribution": "store",
111
+ "web": { "alias": "production", "output": "dist" }
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ `web.alias` accepts `production` or `staging`; it defaults to `production`.
118
+ `web.output` is the output folder, such as `dist` for Expo/React Native Web or
119
+ `build/web` for Flutter. Mach does not infer an address from a profile name and
120
+ does not inject mobile profile secrets into static browser files.
121
+
122
+ ### Deploy releases
123
+
124
+ The output directory must have `index.html` at its root.
125
+
126
+ ```bash
127
+ # Upload a finished Expo or React Native Web export
128
+ mach web deploy --output dist
129
+
130
+ # Run Expo export locally, then upload the result
131
+ mach web deploy --build --profile store-release
132
+
133
+ # Run flutter build web --release locally, then upload build/web
134
+ mach web deploy --build --profile qa-mobile
135
+
136
+ # Create an immutable review link without moving any alias
137
+ mach web deploy --output build/web --alias staging --no-promote
138
+ ```
139
+
140
+ Use the deployment ID to control aliases without another build:
141
+
142
+ ```bash
143
+ mach web list
144
+ mach web promote d_0123abcd --alias production
145
+ mach web rollback --alias production
146
+ mach web status
147
+ ```
148
+
149
+ The dashboard Web Hosting page provides the same controls and shows the
150
+ deployment's file count, size, profile, Git branch, commit, immutable preview,
151
+ and active aliases. Web deployments also appear in Release History alongside
152
+ native builds.
153
+
154
+ ### CI
155
+
156
+ Install the CLI with a scoped `MACH_TOKEN`, then use the same committed profile
157
+ mapping that developers use locally:
158
+
159
+ ```bash
160
+ npm install -g @radhya/mach@latest
161
+ mach web deploy --build --profile store-release --message "$GIT_COMMIT"
162
+ ```
163
+
164
+ For pull requests, use `--no-promote`; promote the reviewed deployment in a
165
+ protected release step. File uploads go directly from the CLI to private R2
166
+ storage using short-lived signed URLs. The Mach API stores release metadata and
167
+ does not proxy your static files.
168
+
169
+ ### Scope and customer domains
170
+
171
+ Mach Web Hosting serves static assets and SPA navigation fallback. It does not
172
+ deploy customer serverless functions, SSR, databases, or server code. A web app
173
+ can call your normal API, but browser-visible values are public: keep database
174
+ credentials and privileged secrets in a backend.
175
+
176
+ The included `*.getmach.dev` project addresses are available immediately.
177
+ Customer-owned domains are a Premium capability enabled only after Cloudflare
178
+ SSL for SaaS is configured by the Mach operator. When enabled, customer domains
179
+ always point to Production for now:
180
+
181
+ ```bash
182
+ mach web domain add --domain www.customer.com
183
+ ```
184
+
73
185
  ## Managed Maestro Testing
74
186
 
75
187
  Mach's E2E testing layer is being implemented to run Maestro without requiring Maestro Cloud:
@@ -519,6 +631,8 @@ and continue to use `"."`.
519
631
  | `flutter.dartDefinesFromEnv` | Environment-key names passed with `--dart-define`. Values are compiled into the app and must not be secrets |
520
632
  | `flutter.obfuscate` | Obfuscate Dart code for Android/iOS release builds and retain downloadable split debug symbols |
521
633
  | `flutter.splitDebugInfo` | Retain downloadable split debug symbols without otherwise changing app behavior |
634
+ | `web.alias` | Web release alias for this profile: `production` or `staging`; defaults to `production` |
635
+ | `web.output` | Finished static output directory for `mach web deploy`, such as `dist` or `build/web` |
522
636
  | `preBuild` / `postBuild` | Shell command or script reference to run around the build |
523
637
  | `envGroups` | Array of environment group names to merge into this profile |
524
638
 
@@ -1,4 +1,4 @@
1
- import{a as A,h as U,i as Mt,k as kn}from"./chunk-QFXPWC5D.js";import{log as g,spinner as ct,text as Oe,password as ht,select as be,confirm as Pi,isCancel as L,cancel as q,intro as wc,outro as vc,note as Ec}from"@clack/prompts";import{log as ie,spinner as Ct,text as He,select as ft,isCancel as Ce,cancel as Fe,note as rn,confirm as Di}from"@clack/prompts";import fe from"chalk";import{spawnSync as jt}from"child_process";import Ae from"fs";import $e from"path";import Ln from"os";import qt from"fs";import{log as Bo}from"@clack/prompts";var jo=["react-native","expo","flutter"],$l="react-native",$i=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},_i=e=>$i(e)?.toUpperCase()||void 0,en=(...e)=>{for(let t of e){let n=$i(t);if(n)return n}};function Lo(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="react-native"||t==="react_native"||t==="reactnative")return"react-native";if(t==="expo")return"expo";if(t==="flutter")return"flutter"}function _n(e){let t=Lo(e?.framework);if(t)return t;let n=jo.map(i=>`"${i}"`).join(", ");throw e?.framework?new Error(`${A.configFileName} has invalid framework "${e.framework}". Use one of: ${n}.`):new Error(`${A.configFileName} is missing required field "framework". Add one of: ${n}.`)}function Vt(e,t=Ge(e,"store","production")){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=_i(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=en(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:en(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:_i(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:en(n.providerId,i.providerId,r.providerId,s),providerName:en(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function Oi(e){if(e){if(!qt.existsSync(e))return null;try{return JSON.parse(qt.readFileSync(e,"utf-8"))}catch{return null}}if(!qt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(qt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function Te(e,t,n=new Set){if(n.has(t))throw new Error(`Circular inheritance detected in profile: ${t}`);n.add(t);let i=e.build?.[t];if(!i)return null;let r={...i};if(i.extends){let o=Te(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android},flutter:{...o.flutter,...i.flutter}})}if(r.envGroups&&Array.isArray(r.envGroups)){let o={};for(let s of r.envGroups){let a=e.envGroups?.[s];a?Object.assign(o,a):Bo.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function Ge(e,t="first",n="production"){let i=Object.keys(e?.build||{});return i.length===0?n:t==="first"?i[0]:i.find(o=>{let s=Te(e,o)||{},a=String(s.distribution||"").trim().toLowerCase().replace(/_/g,"-"),l=String(s.environment||"").trim().toLowerCase().replace(/_/g,"-"),c=String(s.iosExportMethod||s.ios?.exportMethod||"").trim().toLowerCase().replace(/_/g,"-");return t==="development"?s.developmentClient===!0||s.simulator===!0||s.ios?.simulator===!0||s.flutter?.mode==="debug"||a==="development"||l==="development":a==="store"||c==="app-store"||l==="production"||l==="store"})||i[0]}function bt(e,t){let n=t?Te(e,t)||{}:{};if(n.android?.package)return n.android.package;if(n.androidPackage)return n.androidPackage;if(e.android?.package)return e.android.package;if(e.expo?.android?.package)return e.expo.android.package}function nt(e,t){let n=t?Te(e,t)||{}:{};if(n.ios?.bundleIdentifier)return n.ios.bundleIdentifier;if(n.iosBundleIdentifier)return n.iosBundleIdentifier;if(e.ios?.bundleIdentifier)return e.ios.bundleIdentifier;if(e.ios?.bundleId)return e.ios.bundleId;if(e.expo?.ios?.bundleIdentifier)return e.expo.ios.bundleIdentifier}var Ol=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],l=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${l}_`):n[l]=String(a)}};return i(e,t),n};import{cancel as On,confirm as Uo,isCancel as Tn,log as dt,select as Wo,text as Go}from"@clack/prompts";import ut from"chalk";import Fn from"fs";import{createRequire as Zo}from"module";import Ho from"os";import tn from"path";var Xo=Zo(import.meta.url),$n=null;function Ko(){return $n||($n=Xo("@expo/apple-utils")),$n}function nn(e){if(!e)return!1;try{return Fn.readdirSync(tn.join(e,"gems"),{withFileTypes:!0}).some(t=>t.isDirectory()&&t.name.startsWith("fastlane-"))}catch{return!1}}function Jo(){let e=["/opt/homebrew/opt/fastlane/libexec","/usr/local/opt/fastlane/libexec"];for(let n of e)if(nn(n))return n;let t=["/opt/homebrew/Cellar/fastlane","/usr/local/Cellar/fastlane"];for(let n of t)try{let i=Fn.readdirSync(n,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,o)=>o.localeCompare(r,void 0,{numeric:!0}));for(let r of i){let o=tn.join(n,r,"libexec");if(nn(o))return o}}catch{}}function St(){let e=process.env.HOME||Ho.homedir(),t=tn.join(e,".local/share/fastlane/3.4.0"),n=process.env.FASTLANE_GEM_HOME?.trim(),i=nn(n)?n:Jo()||(nn(t)?t:n||t);return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,tn.join(i,"bin"),"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin",process.env.PATH].filter(Boolean).join(":"),GEM_HOME:i,GEM_PATH:[i,process.env.GEM_PATH].filter(Boolean).join(":"),FASTLANE_INSTALLED_VIA_HOMEBREW:"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1",LANG:process.env.LANG||"en_US.UTF-8",LC_ALL:process.env.LC_ALL||"en_US.UTF-8",CI:"1"}}function Yo(e,t=Ge(e,"store","production")){return e.submit||(e.submit={}),e.submit[t]||(e.submit[t]={}),e.submit[t].ios||(e.submit[t].ios={}),e.submit[t].ios}function zo(e,t,n=Ge(e,"store","production")){if(!e||!t.id)return;let i=Yo(e,n);i.appleTeamId=t.id;try{Fn.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function Qo(e){let t=String(e?.teamId||e?.id||"").trim().toUpperCase();return t?{id:t,name:String(e?.name||"").trim()||void 0,type:String(e?.type||"").trim()||void 0}:null}async function qo(e){try{let{Auth:t,Teams:n}=Ko(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let c of o||[]){let d=Qo(c);d&&s.set(d.id,d)}let a=Array.from(s.values()),l=r?a.find(c=>c.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:l}}catch(t){let n=t instanceof Error?t.message:String(t||"");return dt.warn(ut.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Ti(){dt.warn(ut.yellow(`
1
+ import{a as A,h as U,i as Mt,k as kn}from"./chunk-QFXPWC5D.js";import{log as g,spinner as ct,text as Oe,password as ht,select as be,confirm as Pi,isCancel as L,cancel as q,intro as wc,outro as vc,note as Ec}from"@clack/prompts";import{log as ie,spinner as Ct,text as He,select as ft,isCancel as Ce,cancel as Fe,note as rn,confirm as Di}from"@clack/prompts";import fe from"chalk";import{spawnSync as jt}from"child_process";import Ae from"fs";import $e from"path";import Ln from"os";import qt from"fs";import{log as Bo}from"@clack/prompts";var jo=["react-native","expo","flutter"],$l="react-native",$i=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},_i=e=>$i(e)?.toUpperCase()||void 0,en=(...e)=>{for(let t of e){let n=$i(t);if(n)return n}};function Lo(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="react-native"||t==="react_native"||t==="reactnative")return"react-native";if(t==="expo")return"expo";if(t==="flutter")return"flutter"}function _n(e){let t=Lo(e?.framework);if(t)return t;let n=jo.map(i=>`"${i}"`).join(", ");throw e?.framework?new Error(`${A.configFileName} has invalid framework "${e.framework}". Use one of: ${n}.`):new Error(`${A.configFileName} is missing required field "framework". Add one of: ${n}.`)}function Vt(e,t=Ge(e,"store","production")){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=_i(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=en(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:en(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:_i(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:en(n.providerId,i.providerId,r.providerId,s),providerName:en(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function Oi(e){if(e){if(!qt.existsSync(e))return null;try{return JSON.parse(qt.readFileSync(e,"utf-8"))}catch{return null}}if(!qt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(qt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function Te(e,t,n=new Set){if(n.has(t))throw new Error(`Circular inheritance detected in profile: ${t}`);n.add(t);let i=e.build?.[t];if(!i)return null;let r={...i};if(i.extends){let o=Te(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android},flutter:{...o.flutter,...i.flutter},web:{...o.web,...i.web}})}if(r.envGroups&&Array.isArray(r.envGroups)){let o={};for(let s of r.envGroups){let a=e.envGroups?.[s];a?Object.assign(o,a):Bo.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function Ge(e,t="first",n="production"){let i=Object.keys(e?.build||{});return i.length===0?n:t==="first"?i[0]:i.find(o=>{let s=Te(e,o)||{},a=String(s.distribution||"").trim().toLowerCase().replace(/_/g,"-"),l=String(s.environment||"").trim().toLowerCase().replace(/_/g,"-"),c=String(s.iosExportMethod||s.ios?.exportMethod||"").trim().toLowerCase().replace(/_/g,"-");return t==="development"?s.developmentClient===!0||s.simulator===!0||s.ios?.simulator===!0||s.flutter?.mode==="debug"||a==="development"||l==="development":a==="store"||c==="app-store"||l==="production"||l==="store"})||i[0]}function bt(e,t){let n=t?Te(e,t)||{}:{};if(n.android?.package)return n.android.package;if(n.androidPackage)return n.androidPackage;if(e.android?.package)return e.android.package;if(e.expo?.android?.package)return e.expo.android.package}function nt(e,t){let n=t?Te(e,t)||{}:{};if(n.ios?.bundleIdentifier)return n.ios.bundleIdentifier;if(n.iosBundleIdentifier)return n.iosBundleIdentifier;if(e.ios?.bundleIdentifier)return e.ios.bundleIdentifier;if(e.ios?.bundleId)return e.ios.bundleId;if(e.expo?.ios?.bundleIdentifier)return e.expo.ios.bundleIdentifier}var Ol=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],l=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${l}_`):n[l]=String(a)}};return i(e,t),n};import{cancel as On,confirm as Uo,isCancel as Tn,log as dt,select as Wo,text as Go}from"@clack/prompts";import ut from"chalk";import Fn from"fs";import{createRequire as Zo}from"module";import Ho from"os";import tn from"path";var Xo=Zo(import.meta.url),$n=null;function Ko(){return $n||($n=Xo("@expo/apple-utils")),$n}function nn(e){if(!e)return!1;try{return Fn.readdirSync(tn.join(e,"gems"),{withFileTypes:!0}).some(t=>t.isDirectory()&&t.name.startsWith("fastlane-"))}catch{return!1}}function Jo(){let e=["/opt/homebrew/opt/fastlane/libexec","/usr/local/opt/fastlane/libexec"];for(let n of e)if(nn(n))return n;let t=["/opt/homebrew/Cellar/fastlane","/usr/local/Cellar/fastlane"];for(let n of t)try{let i=Fn.readdirSync(n,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,o)=>o.localeCompare(r,void 0,{numeric:!0}));for(let r of i){let o=tn.join(n,r,"libexec");if(nn(o))return o}}catch{}}function St(){let e=process.env.HOME||Ho.homedir(),t=tn.join(e,".local/share/fastlane/3.4.0"),n=process.env.FASTLANE_GEM_HOME?.trim(),i=nn(n)?n:Jo()||(nn(t)?t:n||t);return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,tn.join(i,"bin"),"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin",process.env.PATH].filter(Boolean).join(":"),GEM_HOME:i,GEM_PATH:[i,process.env.GEM_PATH].filter(Boolean).join(":"),FASTLANE_INSTALLED_VIA_HOMEBREW:"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1",LANG:process.env.LANG||"en_US.UTF-8",LC_ALL:process.env.LC_ALL||"en_US.UTF-8",CI:"1"}}function Yo(e,t=Ge(e,"store","production")){return e.submit||(e.submit={}),e.submit[t]||(e.submit[t]={}),e.submit[t].ios||(e.submit[t].ios={}),e.submit[t].ios}function zo(e,t,n=Ge(e,"store","production")){if(!e||!t.id)return;let i=Yo(e,n);i.appleTeamId=t.id;try{Fn.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function Qo(e){let t=String(e?.teamId||e?.id||"").trim().toUpperCase();return t?{id:t,name:String(e?.name||"").trim()||void 0,type:String(e?.type||"").trim()||void 0}:null}async function qo(e){try{let{Auth:t,Teams:n}=Ko(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let c of o||[]){let d=Qo(c);d&&s.set(d.id,d)}let a=Array.from(s.values()),l=r?a.find(c=>c.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:l}}catch(t){let n=t instanceof Error?t.message:String(t||"");return dt.warn(ut.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Ti(){dt.warn(ut.yellow(`
2
2
  Apple Team ID is required to fetch certificates.`)),dt.info(ut.dim("You can find this at: https://developer.apple.com/account -> Membership Details"));let e=await Go({message:"Enter your 10-character Apple Team ID:",placeholder:"e.g. SA56KTS33U",validate:t=>/^[A-Z0-9]{10}$/i.test(t.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});return Tn(e)?(On("Operation cancelled"),null):{id:e.trim().toUpperCase()}}function es(e){let t=[e.id,e.type].filter(Boolean);return t.length>0?t.join(" \xB7 "):void 0}async function ts(e,t){if(!e.config)return!1;if(e.persistConfig)return!0;if(!e.promptToPersistConfig)return!1;let n=e.profile||Ge(e.config,"store","production"),i=await Uo({message:`Save Apple Team ID ${t} to ${A.configFileName} for "${n}" profile?`,initialValue:!0});return Tn(i)?(On("Operation cancelled"),null):i}async function Bt(e){let t=e.initialTeam?.teamId?.trim().toUpperCase();if(t){let c=e.initialTeam?.developerTeamId?.trim().toUpperCase();return{...e.initialTeam,teamId:t,developerTeamId:c||t}}dt.info(ut.blue("Fetching Apple Developer teams..."));let{teams:n,selectedTeam:i}=await qo(e.appleId),r;if(i)r=i,dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length===1)r=n[0],dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length>1){let c=await Wo({message:"Select Apple Developer team:",options:[...n.map(d=>({value:d.id,label:d.name||d.id,hint:es(d)})),{value:"__manual__",label:"Enter Team ID manually",hint:"Use if your team is not listed"}]});if(Tn(c))return On("Operation cancelled"),null;r=c==="__manual__"?await Ti():n.find(d=>d.id===c)||{id:c}}else dt.warn(ut.yellow("Could not list Apple Developer teams automatically.")),r=await Ti();if(!r)return null;let o=r.id.trim().toUpperCase(),s=r.name?.trim(),a={...e.initialTeam,teamId:o,teamName:s||e.initialTeam?.teamName,developerTeamId:o},l=await ts(e,o);return l===null?null:(l&&zo(e.config,{...r,id:o,name:s},e.profile),e.saveTeamId&&await e.saveTeamId(o,s),a)}var ns="cmVxdWlyZSAnc3BhY2VzaGlwJwpyZXF1aXJlICdqc29uJwoKZGVmIHJlYWRfdGVhbV9maWVsZCh0ZWFtLCAqa2V5cykKICBrZXlzLmVhY2ggZG8gfGtleXwKICAgIGJlZ2luCiAgICAgIHZhbHVlID0gdGVhbVtrZXldIGlmIHRlYW0ucmVzcG9uZF90bz8oOltdKQogICAgICByZXR1cm4gdmFsdWUgaWYgdmFsdWUgJiYgdmFsdWUudG9fcy5sZW5ndGggPiAwCiAgICByZXNjdWUKICAgIGVuZAoKICAgIG1ldGhvZF9uYW1lID0ga2V5LnRvX3MKICAgIGlmIHRlYW0ucmVzcG9uZF90bz8obWV0aG9kX25hbWUpCiAgICAgIHZhbHVlID0gdGVhbS5wdWJsaWNfc2VuZChtZXRob2RfbmFtZSkKICAgICAgcmV0dXJuIHZhbHVlIGlmIHZhbHVlICYmIHZhbHVlLnRvX3MubGVuZ3RoID4gMAogICAgZW5kCiAgZW5kCgogIG5pbAplbmQKCmRlZiBub3JtYWxpemVfdGVhbV9uYW1lKG5hbWUpCiAgbmFtZS50b19zLmRvd25jYXNlLmdzdWIoL1teYS16MC05XSsvLCAnICcpLnN0cmlwCmVuZAoKZGVmIHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtX2lkID0gRU5WWydGQVNUTEFORV9URUFNX0lEJ10udG9fcwogIHRlYW1zID0gU3BhY2VzaGlwOjpQb3J0YWwuY2xpZW50LnRlYW1zCiAgdGVhbXMgPSB0ZWFtcy52YWx1ZXMgaWYgdGVhbXMuaXNfYT8oSGFzaCkKCiAgdGVhbSA9IEFycmF5KHRlYW1zKS5maW5kIGRvIHx0fAogICAgWwogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1JZCcsIDp0ZWFtSWQpLAogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1faWQnLCA6dGVhbV9pZCksCiAgICAgIHJlYWRfdGVhbV9maWVsZCh0LCAnaWQnLCA6aWQpCiAgICBdLmNvbXBhY3QubWFwKCY6dG9fcykuaW5jbHVkZT8odGVhbV9pZCkKICBlbmQKCiAgcmVhZF90ZWFtX2ZpZWxkKHRlYW0sICduYW1lJywgOm5hbWUsICd0ZWFtTmFtZScsIDp0ZWFtTmFtZSwgJ2Rpc3BsYXlOYW1lJywgOmRpc3BsYXlOYW1lKQpyZXNjdWUgPT4gZQogICRzdGRlcnIucHV0cyAiREVCVUc6IENvdWxkIG5vdCByZXNvbHZlIERldmVsb3BlciBQb3J0YWwgdGVhbSBuYW1lOiAje2UubWVzc2FnZX0iCiAgbmlsCmVuZAoKZGVmIHR1bmVzX3RlYW1faWQodGVhbSkKICByZWFkX3RlYW1fZmllbGQoCiAgICB0ZWFtLAogICAgJ3Byb3ZpZGVySWQnLCA6cHJvdmlkZXJJZCwKICAgICdwcm92aWRlcl9pZCcsIDpwcm92aWRlcl9pZCwKICAgICdjb250ZW50UHJvdmlkZXJJZCcsIDpjb250ZW50UHJvdmlkZXJJZCwKICAgICdjb250ZW50X3Byb3ZpZGVyX2lkJywgOmNvbnRlbnRfcHJvdmlkZXJfaWQsCiAgICAndGVhbUlkJywgOnRlYW1JZCwKICAgICd0ZWFtX2lkJywgOnRlYW1faWQsCiAgICAnaWQnLCA6aWQKICApLnRvX3MKZW5kCgpkZWYgdHVuZXNfdGVhbV9uYW1lKHRlYW0pCiAgcmVhZF90ZWFtX2ZpZWxkKAogICAgdGVhbSwKICAgICduYW1lJywgOm5hbWUsCiAgICAnY29udGVudFByb3ZpZGVyTmFtZScsIDpjb250ZW50UHJvdmlkZXJOYW1lLAogICAgJ2NvbnRlbnRfcHJvdmlkZXJfbmFtZScsIDpjb250ZW50X3Byb3ZpZGVyX25hbWUsCiAgICAndGVhbU5hbWUnLCA6dGVhbU5hbWUsCiAgICAnZGlzcGxheU5hbWUnLCA6ZGlzcGxheU5hbWUKICApLnRvX3MKZW5kCgpkZWYgYXZhaWxhYmxlX3R1bmVzX3RlYW1zCiAgdGVhbXMgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudC50ZWFtcwogIHRlYW1zID0gdGVhbXMudmFsdWVzIGlmIHRlYW1zLmlzX2E/KEhhc2gpCiAgQXJyYXkodGVhbXMpCnJlc2N1ZSA9PiBlCiAgJHN0ZGVyci5wdXRzICJERUJVRzogQ291bGQgbm90IGluc3BlY3QgQXBwIFN0b3JlIENvbm5lY3QgdGVhbXM6ICN7ZS5tZXNzYWdlfSIKICBbXQplbmQKCmRlZiBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogIGV4cGxpY2l0X3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX0lUQ19URUFNX0lEJ10gfHwgRU5WWydGQVNUTEFORV9BU0NfVEVBTV9JRCddCiAgaWYgZXhwbGljaXRfdGVhbV9pZCAmJiBleHBsaWNpdF90ZWFtX2lkLnRvX3MubGVuZ3RoID4gMAogICAgU3BhY2VzaGlwOjpUdW5lcy5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBleHBsaWNpdF90ZWFtX2lkKQogICAgcmV0dXJuIGV4cGxpY2l0X3RlYW1faWQKICBlbmQKCiAgZGV2ZWxvcGVyX3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXS50b19zCiAgZGV2ZWxvcGVyX3RlYW1fbmFtZSA9IHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtcyA9IGF2YWlsYWJsZV90dW5lc190ZWFtcwoKICBpZiBkZXZlbG9wZXJfdGVhbV9uYW1lICYmIGRldmVsb3Blcl90ZWFtX25hbWUubGVuZ3RoID4gMAogICAgbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZSA9IG5vcm1hbGl6ZV90ZWFtX25hbWUoZGV2ZWxvcGVyX3RlYW1fbmFtZSkKICAgIG1hdGNoZWRfdGVhbSA9IHRlYW1zLmZpbmQgeyB8dGVhbXwgbm9ybWFsaXplX3RlYW1fbmFtZSh0dW5lc190ZWFtX25hbWUodGVhbSkpID09IG5vcm1hbGl6ZWRfZGV2ZWxvcGVyX25hbWUgfQoKICAgIGlmIG1hdGNoZWRfdGVhbQogICAgICBtYXRjaGVkX2lkID0gdHVuZXNfdGVhbV9pZChtYXRjaGVkX3RlYW0pCiAgICAgIG1hdGNoZWRfbmFtZSA9IHR1bmVzX3RlYW1fbmFtZShtYXRjaGVkX3RlYW0pCiAgICAgIFNwYWNlc2hpcDo6VHVuZXMuc2VsZWN0X3RlYW0odGVhbV9pZDogbWF0Y2hlZF9pZCkKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogQXV0by1zZWxlY3RlZCBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7bWF0Y2hlZF9pZH0gKCN7bWF0Y2hlZF9uYW1lfSkgZm9yIERldmVsb3BlciBUZWFtICN7ZGV2ZWxvcGVyX3RlYW1faWR9IgogICAgICByZXR1cm4gbWF0Y2hlZF9pZAogICAgZW5kCiAgZW5kCgogIGlmIHRlYW1zLmxlbmd0aCA9PSAxCiAgICBvbmx5X3RlYW0gPSB0ZWFtcy5maXJzdAogICAgb25seV90ZWFtX2lkID0gdHVuZXNfdGVhbV9pZChvbmx5X3RlYW0pCiAgICBTcGFjZXNoaXA6OlR1bmVzLnNlbGVjdF90ZWFtKHRlYW1faWQ6IG9ubHlfdGVhbV9pZCkKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEF1dG8tc2VsZWN0ZWQgb25seSBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7b25seV90ZWFtX2lkfSAoI3t0dW5lc190ZWFtX25hbWUob25seV90ZWFtKX0pIgogICAgcmV0dXJuIG9ubHlfdGVhbV9pZAogIGVuZAoKICAkc3RkZXJyLnB1dHMgIkVSUk9SOiBDb3VsZCBub3QgbWFwIEFwcGxlIERldmVsb3BlciBUZWFtIElEICcje2RldmVsb3Blcl90ZWFtX2lkfScje2RldmVsb3Blcl90ZWFtX25hbWUgPyAiICgje2RldmVsb3Blcl90ZWFtX25hbWV9KSIgOiAnJ30gdG8gQXBwIFN0b3JlIENvbm5lY3QuIgogICRzdGRlcnIucHV0cyAiQXZhaWxhYmxlIEFwcCBTdG9yZSBDb25uZWN0IHRlYW1zOiIKICB0ZWFtcy5lYWNoIGRvIHx0ZWFtfAogICAgJHN0ZGVyci5wdXRzICItICN7dHVuZXNfdGVhbV9pZCh0ZWFtKX0gKCN7dHVuZXNfdGVhbV9uYW1lKHRlYW0pfSkiCiAgZW5kCiAgZXhpdCAxCmVuZAoKZGVmIGxpc3RfdGVhbXMKICBiZWdpbgogICAgU3BhY2VzaGlwOjpQb3J0YWwubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBTcGFjZXNoaXA6OlBvcnRhbC5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXSkKCiAgICBkZXZlbG9wZXJfdGVhbV9uYW1lID0gcG9ydGFsX3RlYW1fbmFtZQoKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lID0gbm9ybWFsaXplX3RlYW1fbmFtZShkZXZlbG9wZXJfdGVhbV9uYW1lKQogICAgdGVhbXMgPSBhdmFpbGFibGVfdHVuZXNfdGVhbXMubWFwIGRvIHx0ZWFtfAogICAgICB0ZWFtX25hbWUgPSB0dW5lc190ZWFtX25hbWUodGVhbSkKICAgICAgewogICAgICAgIGlkOiB0dW5lc190ZWFtX2lkKHRlYW0pLAogICAgICAgIG5hbWU6IHRlYW1fbmFtZSwKICAgICAgICByZWNvbW1lbmRlZDogbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZS5sZW5ndGggPiAwICYmIG5vcm1hbGl6ZV90ZWFtX25hbWUodGVhbV9uYW1lKSA9PSBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lCiAgICAgIH0KICAgIGVuZAoKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyB7CiAgICAgIGRldmVsb3BlclRlYW1JZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10sCiAgICAgIGRldmVsb3BlclRlYW1OYW1lOiBkZXZlbG9wZXJfdGVhbV9uYW1lLAogICAgICB0ZWFtczogdGVhbXMKICAgIH0udG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBleGl0IDEKICBlbmQKZW5kCgpkZWYgbGlzdF9rZXlzCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICAjIFVzZSBUdW5lcyBjbGllbnQgd2hpY2ggcG9pbnRzIHRvIGFwcHN0b3JlY29ubmVjdC5hcHBsZS5jb20KICAgIGNsaWVudCA9IFNwYWNlc2hpcDo6VHVuZXMuY2xpZW50CiAgICAjIFVzZSByb290LXJlbGF0aXZlIFVSTCB0byByZXBsYWNlIHRoZSBkZWZhdWx0IFR1bmVzIHBhdGggKC9XZWJPYmplY3RzLy4uLikKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOmdldCwgJy9pcmlzL3YxL2FwaUtleXMnKQogICAgCiAgICBpZiByZXNwb25zZS5ib2R5Lm5pbD8gfHwgIXJlc3BvbnNlLmJvZHkuaXNfYT8oSGFzaCkKICAgICAgcmFpc2UgIkFQSSByZXR1cm5lZCBlbXB0eSBvciBpbnZhbGlkIHJlc3BvbnNlIGJvZHkgZm9yIGxpc3Rpbmcga2V5cyIKICAgIGVuZAogICAgCiAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGdWxsIExpc3QgUmVzcG9uc2U6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAga2V5cyA9IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXSB8fCBbXQogICAgCiAgICBvdXRwdXQgPSBrZXlzLm1hcCBkbyB8a3wKICAgICAgYXR0ciA9IGtbJ2F0dHJpYnV0ZXMnXSB8fCB7fQogICAgICB7CiAgICAgICAgaWQ6IGtbJ2lkJ10sCiAgICAgICAgbmFtZTogYXR0clsnbmFtZSddLAogICAgICAgIGlzc3VlcklkOiBhdHRyWydpc3N1ZXJJZCddLAogICAgICAgIHJvbGU6IGF0dHJbJ3JvbGVzJ10mLmZpcnN0LAogICAgICAgIHJldm9jYWJsZTogYXR0clsncmV2b2NhYmxlJ10KICAgICAgfQogICAgZW5kCiAgICAKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyBvdXRwdXQudG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBpZiBkZWZpbmVkPyhyZXNwb25zZSkgJiYgcmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keQogICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGNyZWF0ZV9rZXkobmFtZSwgcm9sZSA9ICdBRE1JTicpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgCiAgICAjIFRydW5jYXRlIG5pY2tuYW1lIHRvIDMwIGNoYXJzIGFzIHBlciBBcHBsZSdzIGxpbWl0CiAgICAjIFdlIGtlZXAgdGhlIG9yaWdpbmFsICduYW1lJyBmb3IgbG9nZ2luZyBidXQgc2VuZCB0cnVuY2F0ZWQgJ25pY2tuYW1lJyB0byBBUEkKICAgIHNhZmVfbmlja25hbWUgPSBuYW1lWzAsIDMwXQogICAgCiAgICBwYXlsb2FkID0gewogICAgICBkYXRhOiB7CiAgICAgICAgdHlwZTogImFwaUtleXMiLAogICAgICAgIGF0dHJpYnV0ZXM6IHsKICAgICAgICAgIG5pY2tuYW1lOiBzYWZlX25pY2tuYW1lLAogICAgICAgICAga2V5VHlwZTogIlBVQkxJQ19BUEkiLAogICAgICAgICAgcm9sZXM6IFtyb2xlXSwKICAgICAgICAgIGFsbEFwcHNWaXNpYmxlOiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOnBvc3QpIGRvIHxyZXF8CiAgICAgIHJlcS51cmwgIi9pcmlzL3YxL2FwaUtleXMiCiAgICAgIHJlcS5ib2R5ID0gcGF5bG9hZC50b19qc29uCiAgICAgIHJlcS5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJwogICAgICByZXEuaGVhZGVyc1snQWNjZXB0J10gPSAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uLCBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJwogICAgICByZXEuaGVhZGVyc1snWC1SZXF1ZXN0ZWQtV2l0aCddID0gJ1hNTEh0dHBSZXF1ZXN0JwogICAgICByZXEuaGVhZGVyc1snUmVmZXJlciddID0gJ2h0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9hY2Nlc3MvYXBpJwogICAgICByZXEuaGVhZGVyc1snWC1BcHBsZS1XaWRnZXQtS2V5J10gPSBjbGllbnQud2lkZ2V0X2tleSBpZiBjbGllbnQucmVzcG9uZF90bz8oOndpZGdldF9rZXkpCiAgICBlbmQKICAgIAogICAgIyBERUJVRzogSW5zcGVjdCB0aGUgcmF3IHJlc3BvbnNlIG9iamVjdAogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgQ2xhc3M6ICN7cmVzcG9uc2UuY2xhc3N9IgogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgSGVhZGVyczogI3tyZXNwb25zZS5oZWFkZXJzfSIKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAgaWYgcmVzcG9uc2UuYm9keS5uaWw/IHx8ICFyZXNwb25zZS5ib2R5LmlzX2E/KEhhc2gpIHx8IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXS5uaWw/CiAgICAgIGVycm9yX21zZyA9ICJBUEkgZmFpbGVkIHRvIGNyZWF0ZSBrZXkuIgogICAgICBpZiByZXNwb25zZS5ib2R5ICYmIHJlc3BvbnNlLmJvZHlbJ2Vycm9ycyddCiAgICAgICAgZXJyb3JfbXNnICs9ICIgRXJyb3JzOiAiICsgcmVzcG9uc2UuYm9keVsnZXJyb3JzJ10ubWFwe3xlfCBlWydkZXRhaWwnXX0uam9pbignLCAnKQogICAgICBlbmQKICAgICAgcmFpc2UgZXJyb3JfbXNnCiAgICBlbmQKICAgIAogICAga2V5X2RhdGEgPSByZXNwb25zZS5ib2R5WydkYXRhJ10KICAgIGF0dHIgPSBrZXlfZGF0YVsnYXR0cmlidXRlcyddIHx8IHt9CgogICAgIyBUaGUgLnA4IGNvbnRlbnQgaXMgdXN1YWxseSBpbiAncHJpdmF0ZUtleScgb3IgJ2tleUNvbnRlbnQnIG9uIHRoZSBJTklUSUFMIENSRUFURSByZXNwb25zZQogICAgcDhfY29udGVudCA9IGF0dHJbJ3ByaXZhdGVLZXknXSB8fCBhdHRyWydrZXlDb250ZW50J10KICAgIAogICAgaWYgcDhfY29udGVudC5uaWw/CiAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEtleSBjb250ZW50IG1pc3NpbmcgaW4gcmVzcG9uc2UuIEF0dGVtcHRpbmcgcmV0cmlldmFsIHZpYSBkb3dubG9hZC9leHBvcnQgZW5kcG9pbnRzLi4uIiAKICAgICAgCiAgICAgIHBhdGhzX3RvX3RyeSA9IFsKICAgICAgICAiaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2lyaXMvdjEvYXBpS2V5cy8je2tleV9kYXRhWydpZCddfS9kb3dubG9hZCIsCiAgICAgICAgImh0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9pcmlzL3YxL2FwaUtleXMvI3trZXlfZGF0YVsnaWQnXX0vZXhwb3J0IgogICAgICBdCiAgICAgIAogICAgICBwYXRoc190b190cnkuZWFjaCBkbyB8cGF0aHwKICAgICAgICBiZWdpbgogICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogVHJ5aW5nICN7cGF0aH0uLi4iCiAgICAgICAgICBkb3dubG9hZF9yZXNwID0gY2xpZW50LnJlcXVlc3QoOmdldCkgZG8gfHJlcXwKICAgICAgICAgICAgcmVxLnVybCBwYXRoCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydBY2NlcHQnXSA9ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24sIGFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCwgKi8qOyBxPTAuMDEnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydSZWZlcmVyJ10gPSAnaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2FjY2Vzcy9hcGknCiAgICAgICAgICBlbmQKICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIENsYXNzOiAje2Rvd25sb2FkX3Jlc3AuYm9keS5jbGFzc30iCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBTdGF0dXM6ICN7ZG93bmxvYWRfcmVzcC5zdGF0dXN9IiBpZiBkb3dubG9hZF9yZXNwLnJlc3BvbmRfdG8/KDpzdGF0dXMpCiAgICAgICAgICAKICAgICAgICAgIGlmIGRvd25sb2FkX3Jlc3AuYm9keSAmJiAhZG93bmxvYWRfcmVzcC5ib2R5LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKQogICAgICAgICAgICAgaWYgZG93bmxvYWRfcmVzcC5ib2R5LmlzX2E/KEhhc2gpCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHlbJ2tleUNvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHlbJ2NvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHkuZGlnKCdkYXRhJywgJ2F0dHJpYnV0ZXMnLCAncHJpdmF0ZUtleScpCiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHkKICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgCiAgICAgICAgICAgICBpZiBwOF9jb250ZW50ICYmIHA4X2NvbnRlbnQudG9fcy5zdGFydF93aXRoPygnLS0tLS1CRUdJTicpCiAgICAgICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJldHJpZXZhbCB2aWEgI3twYXRofSBzdWNjZXNzZnVsISBDb250ZW50IGxlbmd0aDogI3twOF9jb250ZW50LnRvX3MubGVuZ3RofSIKICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgZnJvbSAje3BhdGh9IGRpZCBub3QgY29udGFpbiBhIHZhbGlkIHByaXZhdGUga2V5LiIKICAgICAgICAgICAgICAgcDhfY29udGVudCA9IG5pbAogICAgICAgICAgICAgZW5kCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBmcm9tICN7cGF0aH0gZW1wdHkgb3IgY29udGFpbnMgZXJyb3JzLiIKICAgICAgICAgIGVuZAogICAgICAgIHJlc2N1ZSA9PiBlCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBBdHRlbXB0IGZvciAje3BhdGh9IGZhaWxlZDogI3tlLm1lc3NhZ2V9IgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAoKICAgICMgRklOQUwgVkFMSURBVElPTjogRW5zdXJlIGl0J3Mgbm90IGEgUnVieSBoYXNoIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBlcnJvcgogICAgaWYgcDhfY29udGVudC5pc19hPyhIYXNoKSB8fCBwOF9jb250ZW50LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKSB8fCAhcDhfY29udGVudC50b19zLnN0YXJ0X3dpdGg/KCctLS0tLUJFR0lOJykKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogSW52YWxpZCBrZXkgY29udGVudCBkZXRlY3RlZC4iCiAgICAgIHA4X2NvbnRlbnQgPSBuaWwKICAgIGVuZAoKICAgIGlmIHA4X2NvbnRlbnQubmlsPwogICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGYWlsZWQgdG8gcmV0cmlldmUga2V5IGNvbnRlbnQuIgogICAgZW5kCiAgICAKICAgIHJlc3VsdCA9IHsKICAgICAgaWQ6IGtleV9kYXRhWydpZCddLAogICAgICBuYW1lOiBhdHRyWyduaWNrbmFtZSddIHx8IGF0dHJbJ25hbWUnXSwKICAgICAgaXNzdWVySWQ6IGF0dHJbJ2lzc3VlcklkJ10sCiAgICAgIGtleUNvbnRlbnQ6IHA4X2NvbnRlbnQsCiAgICAgIHJhd19yZXNwb25zZTogcmVzcG9uc2UuYm9keSAjIEluY2x1ZGUgdGhpcyBmb3IgZGVidWdnaW5nIHdoZW4ga2V5Q29udGVudCBpcyBuaWwKICAgIH0KICAgIAogICAgcHV0cyAiX19fTUFDSF9KU09OX1NUQVJUX19fIiArIHJlc3VsdC50b19qc29uICsgIl9fX01BQ0hfSlNPTl9FTkRfX18iCiAgcmVzY3VlID0+IGUKICAgICRzdGRlcnIucHV0cyAiRVJST1I6ICN7ZS5tZXNzYWdlfSIKICAgIGlmIGRlZmluZWQ/KHJlc3BvbnNlKSAmJiByZXNwb25zZSAmJiByZXNwb25zZS5ib2R5CiAgICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGRlbGV0ZV9rZXkoaWQpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgY2xpZW50LnJlcXVlc3QoOmRlbGV0ZSwgIi9pcmlzL3YxL2FwaUtleXMvI3tpZH0iKQogICAgcHV0cyAiU1VDQ0VTUyIKICByZXNjdWUgPT4gZQogICAgJHN0ZGVyci5wdXRzICJFUlJPUjogI3tlLm1lc3NhZ2V9IgogICAgZXhpdCAxCiAgZW5kCmVuZAoKY29tbWFuZCA9IEFSR1ZbMF0KaWYgY29tbWFuZCA9PSAnbGlzdCcKICBsaXN0X2tleXMKZWxzaWYgY29tbWFuZCA9PSAndGVhbXMnCiAgbGlzdF90ZWFtcwplbHNpZiBjb21tYW5kID09ICdjcmVhdGUnCiAgY3JlYXRlX2tleShBUkdWWzFdIHx8ICJNYWNoIEFQSSBLZXkgI3tUaW1lLm5vdy50b19pfSIpCmVsc2lmIGNvbW1hbmQgPT0gJ2RlbGV0ZScKICBkZWxldGVfa2V5KEFSR1ZbMV0pCmVuZAo=";function Mn(){let e=$e.join(Ln.tmpdir(),A.nameLower);Ae.existsSync(e)||Ae.mkdirSync(e,{recursive:!0});let t=$e.join(e,"manage_asc_keys.rb");return Ae.writeFileSync(t,Buffer.from(ns,"base64").toString("utf-8"),{mode:493}),t}function Vn(){return St()}function Un(e){let t=new Map,n=/-\s+(\d+)\s+\(([^)]+)\)/g,i=/\d+\)\s+"([^"]+)"\s+\((\d+)\)/g,r;for(;(r=n.exec(e))!==null;)t.set(r[1],{id:r[1],name:r[2]});for(;(r=i.exec(e))!==null;)t.set(r[2],{id:r[2],name:r[1]});return Array.from(t.values())}function Mi(e,t=Ge(e,"store","production")){return Vt(e,t).appStoreConnectTeamId}function Vi(e,t,n){return{...Vn(),FASTLANE_USER:e,FASTLANE_TEAM_ID:t,...n?{FASTLANE_ITC_TEAM_ID:n,FASTLANE_ASC_TEAM_ID:n}:{}}}function pt(e,t=Ge(e,"store","production"),n={}){let i=Vt(e,t),r=n.teamId||i.teamId,o=n.appStoreConnectTeamId||i.appStoreConnectTeamId;return{teamId:r,teamName:n.teamName||i.teamName,developerTeamId:n.developerTeamId||i.developerTeamId||r,appStoreConnectTeamId:o,providerId:n.providerId||i.providerId||o,providerName:n.providerName||i.providerName}}function is(e,t,n=Ge(e,"store","production")){if(!t.id)return;e.submit||(e.submit={}),e.submit[n]||(e.submit[n]={}),e.submit[n].ios||(e.submit[n].ios={});let i=e.submit[n].ios;i.appStoreConnectTeamId=t.id,delete i.providerId,delete i.appStoreConnectTeamName,delete i.providerName,delete i.appleTeamName}function Wn(e,t,n){is(e,t,n);try{Ae.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}async function rs(e,t,n,i,r){let o=Ct();o.start("Fetching App Store Connect providers...");let s=jt("ruby",[e,"teams"],{env:Vi(n,i),stdio:["inherit","pipe","pipe"],encoding:"utf-8"});if(s.status!==0){o.stop("Could not fetch providers");let p=Un(`${s.stdout||""}
3
3
  ${s.stderr||""}`);if(p.length>0)return Bn(t,p,"Select the App Store Connect provider for this API key:",void 0,r);ie.warn(fe.yellow(`Could not list App Store Connect providers: ${s.stderr||"Unknown error"}`));return}let a=(s.stdout||"").match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!a){o.stop("Could not parse providers");return}let l=JSON.parse(a[1]),c=(l.teams||[]).filter(p=>p.id&&p.name);if(o.stop(c.length===1?"Found 1 provider":`Found ${c.length} providers`),c.length===0)return;if(c.length===1){ie.success(fe.green(`\u2713 Using App Store Connect provider ${c[0].name} (${c[0].id})`));let p={...c[0],developerTeamName:l.developerTeamName};return Wn(t,p,r),p}let d=c.filter(p=>p.recommended),u=c.filter(p=>!p.recommended);return Bn(t,[...d,...u],`Select the App Store Connect provider for Developer Team ${l.developerTeamName||i}:`,l.developerTeamName,r)}async function Bn(e,t,n,i,r){let o=await ft({message:n,options:t.map(c=>({value:c.id,label:c.name,hint:`${c.id}${c.recommended?" \xB7 recommended":""}`}))});if(Ce(o))return Fe("Operation cancelled"),null;let s=o,l={...t.find(c=>c.id===s)||{id:s,name:s},developerTeamName:i};return Wn(e,l,r),ie.success(fe.green(`\u2713 Using App Store Connect provider ${l.name} (${l.id})`)),l}var Lt=e=>typeof e=="string"&&e.trim()?e.trim():void 0,Fi=e=>Lt(e)?.toUpperCase();function os(e,t){let n=Fi(t.developerTeamId||t.teamId),i=Lt(t.appStoreConnectTeamId||t.providerId);return e.filter(r=>{let o=Fi(r.teamId),s=Lt(r.appStoreConnectTeamId||r.providerId);return!(n&&o!==n||i&&s!==i)})}function Dn(e){let t=Lt(e.name)||"App Store Connect API key",n=Lt(e.sourceProjectName)||e.sourceProjectId;return`${t} \xB7 ${n}`}function ss(e){return[e.teamId?`Apple Team ${e.teamId}`:void 0,e.appStoreConnectTeamId||e.providerId?`ASC provider ${e.appStoreConnectTeamId||e.providerId}`:void 0,e.keyId?`Key ${e.keyId}`:void 0].filter(Boolean).join(" \xB7 ")}async function as(e,t,n){let i=pt(t,n),r=i.developerTeamId||i.teamId,o=i.appStoreConnectTeamId||i.providerId;if(!r){ie.error(`Set ios.appleTeamId or submit.${n}.ios.appleTeamId in ${A.configFileName} before reusing an App Store Connect API key.`);return}let s=Ct(),a=[];try{s.start("Looking for compatible saved App Store Connect API keys...");let d=await U.get("/credentials/reusable",{params:{projectId:e,type:"asc_api_key"}});a=os(Array.isArray(d.data?.credentials)?d.data.credentials:[],i),s.stop(a.length===1?"Found 1 compatible saved API key":`Found ${a.length} compatible saved API keys`)}catch(d){s.stop("Could not load saved API keys"),ie.error(`Could not load reusable App Store Connect API keys: ${d.response?.data?.message||d.message}. You need administrator access to this project and the source project.`);return}if(a.length===0){let d=o?`Apple Team ${r} and App Store Connect provider ${o}`:`Apple Team ${r}`;ie.info(`No compatible saved API keys were found for ${d}.`);return}let l=await ft({message:"Select a saved App Store Connect API key to reuse:",options:[...a.map((d,u)=>({value:String(u),label:Dn(d),hint:ss(d)})),{value:"cancel",label:"Cancel"}]});if(Ce(l)||l==="cancel"){Fe("Operation cancelled");return}let c=a[Number(l)];if(!c){ie.error("The selected App Store Connect API key is no longer available.");return}try{s.start(`Copying ${Dn(c)} into this project...`),await U.post("/credentials/reuse",{projectId:e,sourceProjectId:c.sourceProjectId,credentialId:c.credentialId,type:"asc_api_key"}),s.stop("Saved API key copied to this project");let d=c.appStoreConnectTeamId||c.providerId;d&&Wn(t,{id:d,name:c.providerName||d},n),ie.success(fe.green(`\u2713 Reused ${Dn(c)} for this project.`))}catch(d){s.stop("Could not reuse saved API key"),ie.error(`Could not reuse the selected App Store Connect API key: ${d.response?.data?.message||d.message}.`)}}var Bi=async e=>{let t=Ct(),n=e.platform,i=`./${A.configFileName}`;if(!Ae.existsSync(i)){ie.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(Ae.readFileSync(i,"utf-8")),{projectId:o}=r,s=e.profile||Ge(r,"store","production");if(!o){ie.error(`${A.configFileName} is missing projectId.`);return}let a=e.file,l=n==="android"?e.packageName||e.bundleId:e.bundleId||nt(r,s)||"*";if(n==="android"&&!l&&(l=await cs(o,r,s),l===null))return;if(n==="ios"&&!a){let p=await ft({message:"Manage App Store Connect API Key:",options:[{value:"magic",label:"\u2728 Create new automatically",hint:"Requires Apple ID + 2FA"},{value:"reuse",label:"\u267B\uFE0F Use a saved API Key",hint:"Copy a compatible key from another Mach project"},{value:"manual",label:"\u{1F50D} Configure manually",hint:"Provide existing .p8 file"},{value:"delete",label:"\u{1F5D1}\uFE0F Delete an existing Key"}]});if(Ce(p)){Fe("Operation cancelled");return}if(p==="magic"){await us(o,r,s);return}if(p==="reuse"){await as(o,r,s);return}if(p==="delete"){await ps(o,r,s);return}}if(!a){let p=n==="ios"?"https://appstoreconnect.apple.com/access/api":"https://console.cloud.google.com/apis/credentials";rn(`To submit to the ${n==="ios"?"App Store":"Google Play Store"}, you need a Service Key:
4
4
 
@@ -1 +1 @@
1
- import{fa as a,ga as b,ha as c,ia as d,ja as e}from"./chunk-SGLXKXUK.js";import"./chunk-QFXPWC5D.js";export{c as credentialsMainCommand,d as credentialsSetupCommand,e as downloadCredentialsCommand,b as normalizeCredentialsPlatform,a as resolveAndroidCredentialDistributionType};
1
+ import{fa as a,ga as b,ha as c,ia as d,ja as e}from"./chunk-3JTATPDQ.js";import"./chunk-QFXPWC5D.js";export{c as credentialsMainCommand,d as credentialsSetupCommand,e as downloadCredentialsCommand,b as normalizeCredentialsPlatform,a as resolveAndroidCredentialDistributionType};