@radhya/mach 2.2.4 → 2.2.5

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.
@@ -1,30 +1,30 @@
1
- import{a as A,h as Z,i as Ut,k as Rn}from"./chunk-LO6DP2SE.js";import{log as m,spinner as Je,text as ve,password as ut,select as Ee,confirm as bn,isCancel as j,cancel as Y,intro as ds,outro as ps,note as us}from"@clack/prompts";import{log as ne,spinner as At,text as Be,select as st,isCancel as ge,cancel as xe,note as Rt,confirm as Tn}from"@clack/prompts";import ie from"chalk";import{spawnSync as It}from"child_process";import de from"fs";import Se from"path";import qt from"os";import Pt from"fs";import{log as nr}from"@clack/prompts";var ir=["react-native","expo","flutter"],ya="react-native",xn=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},kn=e=>xn(e)?.toUpperCase()||void 0,Nt=(...e)=>{for(let t of e){let n=xn(t);if(n)return n}};function rr(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 Lt(e){let t=rr(e?.framework);if(t)return t;let n=ir.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 ht(e,t="production"){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=kn(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=Nt(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:Nt(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:kn(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:Nt(n.providerId,i.providerId,r.providerId,s),providerName:Nt(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function $n(e){if(e){if(!Pt.existsSync(e))return null;try{return JSON.parse(Pt.readFileSync(e,"utf-8"))}catch{return null}}if(!Pt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(Pt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function nt(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=nt(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android}})}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):nr.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function it(e,t){let n=t?nt(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 Ge(e,t){let n=t?nt(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 Ia=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],c=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${c}_`):n[c]=String(a)}};return i(e,t),n};import{cancel as Ht,confirm as or,isCancel as Kt,log as Ye,select as sr,text as ar}from"@clack/prompts";import ze from"chalk";import cr from"fs";import{createRequire as lr}from"module";import dr from"os";import _n from"path";var pr=lr(import.meta.url),Xt=null;function ur(){return Xt||(Xt=pr("@expo/apple-utils")),Xt}function rt(){let e=process.env.HOME||dr.homedir(),t=process.env.FASTLANE_GEM_HOME||_n.join(e,".local/share/fastlane/3.4.0");return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin","/usr/local/Cellar/fastlane/2.227.0/libexec/bin","/opt/homebrew/Cellar/fastlane/2.227.0/libexec/bin",_n.join(t,"bin"),process.env.PATH].filter(Boolean).join(":"),GEM_HOME:t,GEM_PATH:[t,"/usr/local/Cellar/fastlane/2.227.0/libexec","/opt/homebrew/Cellar/fastlane/2.227.0/libexec",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 fr(e,t="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 mr(e,t,n="production"){if(!e||!t.id)return;let i=fr(e,n);i.appleTeamId=t.id;try{cr.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function gr(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 hr(e){try{let{Auth:t,Teams:n}=ur(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let l of o||[]){let p=gr(l);p&&s.set(p.id,p)}let a=Array.from(s.values()),c=r?a.find(l=>l.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:c}}catch(t){let n=t instanceof Error?t.message:String(t||"");return Ye.warn(ze.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Fn(){Ye.warn(ze.yellow(`
2
- Apple Team ID is required to fetch certificates.`)),Ye.info(ze.dim("You can find this at: https://developer.apple.com/account -> Membership Details"));let e=await ar({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 Kt(e)?(Ht("Operation cancelled"),null):{id:e.trim().toUpperCase()}}function yr(e){let t=[e.id,e.type].filter(Boolean);return t.length>0?t.join(" \xB7 "):void 0}async function Ir(e,t){if(!e.config)return!1;if(e.persistConfig)return!0;if(!e.promptToPersistConfig)return!1;let n=e.profile||"production",i=await or({message:`Save Apple Team ID ${t} to ${A.configFileName} for "${n}" profile?`,initialValue:n==="production"});return Kt(i)?(Ht("Operation cancelled"),null):i}async function yt(e){let t=e.initialTeam?.teamId?.trim().toUpperCase();if(t){let l=e.initialTeam?.developerTeamId?.trim().toUpperCase();return{...e.initialTeam,teamId:t,developerTeamId:l||t}}Ye.info(ze.blue("Fetching Apple Developer teams..."));let{teams:n,selectedTeam:i}=await hr(e.appleId),r;if(i)r=i,Ye.success(ze.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length===1)r=n[0],Ye.success(ze.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length>1){let l=await sr({message:"Select Apple Developer team:",options:[...n.map(p=>({value:p.id,label:p.name||p.id,hint:yr(p)})),{value:"__manual__",label:"Enter Team ID manually",hint:"Use if your team is not listed"}]});if(Kt(l))return Ht("Operation cancelled"),null;r=l==="__manual__"?await Fn():n.find(p=>p.id===l)||{id:l}}else Ye.warn(ze.yellow("Could not list Apple Developer teams automatically.")),r=await Fn();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},c=await Ir(e,o);return c===null?null:(c&&mr(e.config,{...r,id:o,name:s},e.profile),e.saveTeamId&&await e.saveTeamId(o,s),a)}var Ar="cmVxdWlyZSAnc3BhY2VzaGlwJwpyZXF1aXJlICdqc29uJwoKZGVmIHJlYWRfdGVhbV9maWVsZCh0ZWFtLCAqa2V5cykKICBrZXlzLmVhY2ggZG8gfGtleXwKICAgIGJlZ2luCiAgICAgIHZhbHVlID0gdGVhbVtrZXldIGlmIHRlYW0ucmVzcG9uZF90bz8oOltdKQogICAgICByZXR1cm4gdmFsdWUgaWYgdmFsdWUgJiYgdmFsdWUudG9fcy5sZW5ndGggPiAwCiAgICByZXNjdWUKICAgIGVuZAoKICAgIG1ldGhvZF9uYW1lID0ga2V5LnRvX3MKICAgIGlmIHRlYW0ucmVzcG9uZF90bz8obWV0aG9kX25hbWUpCiAgICAgIHZhbHVlID0gdGVhbS5wdWJsaWNfc2VuZChtZXRob2RfbmFtZSkKICAgICAgcmV0dXJuIHZhbHVlIGlmIHZhbHVlICYmIHZhbHVlLnRvX3MubGVuZ3RoID4gMAogICAgZW5kCiAgZW5kCgogIG5pbAplbmQKCmRlZiBub3JtYWxpemVfdGVhbV9uYW1lKG5hbWUpCiAgbmFtZS50b19zLmRvd25jYXNlLmdzdWIoL1teYS16MC05XSsvLCAnICcpLnN0cmlwCmVuZAoKZGVmIHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtX2lkID0gRU5WWydGQVNUTEFORV9URUFNX0lEJ10udG9fcwogIHRlYW1zID0gU3BhY2VzaGlwOjpQb3J0YWwuY2xpZW50LnRlYW1zCiAgdGVhbXMgPSB0ZWFtcy52YWx1ZXMgaWYgdGVhbXMuaXNfYT8oSGFzaCkKCiAgdGVhbSA9IEFycmF5KHRlYW1zKS5maW5kIGRvIHx0fAogICAgWwogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1JZCcsIDp0ZWFtSWQpLAogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1faWQnLCA6dGVhbV9pZCksCiAgICAgIHJlYWRfdGVhbV9maWVsZCh0LCAnaWQnLCA6aWQpCiAgICBdLmNvbXBhY3QubWFwKCY6dG9fcykuaW5jbHVkZT8odGVhbV9pZCkKICBlbmQKCiAgcmVhZF90ZWFtX2ZpZWxkKHRlYW0sICduYW1lJywgOm5hbWUsICd0ZWFtTmFtZScsIDp0ZWFtTmFtZSwgJ2Rpc3BsYXlOYW1lJywgOmRpc3BsYXlOYW1lKQpyZXNjdWUgPT4gZQogICRzdGRlcnIucHV0cyAiREVCVUc6IENvdWxkIG5vdCByZXNvbHZlIERldmVsb3BlciBQb3J0YWwgdGVhbSBuYW1lOiAje2UubWVzc2FnZX0iCiAgbmlsCmVuZAoKZGVmIHR1bmVzX3RlYW1faWQodGVhbSkKICByZWFkX3RlYW1fZmllbGQoCiAgICB0ZWFtLAogICAgJ3Byb3ZpZGVySWQnLCA6cHJvdmlkZXJJZCwKICAgICdwcm92aWRlcl9pZCcsIDpwcm92aWRlcl9pZCwKICAgICdjb250ZW50UHJvdmlkZXJJZCcsIDpjb250ZW50UHJvdmlkZXJJZCwKICAgICdjb250ZW50X3Byb3ZpZGVyX2lkJywgOmNvbnRlbnRfcHJvdmlkZXJfaWQsCiAgICAndGVhbUlkJywgOnRlYW1JZCwKICAgICd0ZWFtX2lkJywgOnRlYW1faWQsCiAgICAnaWQnLCA6aWQKICApLnRvX3MKZW5kCgpkZWYgdHVuZXNfdGVhbV9uYW1lKHRlYW0pCiAgcmVhZF90ZWFtX2ZpZWxkKAogICAgdGVhbSwKICAgICduYW1lJywgOm5hbWUsCiAgICAnY29udGVudFByb3ZpZGVyTmFtZScsIDpjb250ZW50UHJvdmlkZXJOYW1lLAogICAgJ2NvbnRlbnRfcHJvdmlkZXJfbmFtZScsIDpjb250ZW50X3Byb3ZpZGVyX25hbWUsCiAgICAndGVhbU5hbWUnLCA6dGVhbU5hbWUsCiAgICAnZGlzcGxheU5hbWUnLCA6ZGlzcGxheU5hbWUKICApLnRvX3MKZW5kCgpkZWYgYXZhaWxhYmxlX3R1bmVzX3RlYW1zCiAgdGVhbXMgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudC50ZWFtcwogIHRlYW1zID0gdGVhbXMudmFsdWVzIGlmIHRlYW1zLmlzX2E/KEhhc2gpCiAgQXJyYXkodGVhbXMpCnJlc2N1ZSA9PiBlCiAgJHN0ZGVyci5wdXRzICJERUJVRzogQ291bGQgbm90IGluc3BlY3QgQXBwIFN0b3JlIENvbm5lY3QgdGVhbXM6ICN7ZS5tZXNzYWdlfSIKICBbXQplbmQKCmRlZiBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogIGV4cGxpY2l0X3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX0lUQ19URUFNX0lEJ10gfHwgRU5WWydGQVNUTEFORV9BU0NfVEVBTV9JRCddCiAgaWYgZXhwbGljaXRfdGVhbV9pZCAmJiBleHBsaWNpdF90ZWFtX2lkLnRvX3MubGVuZ3RoID4gMAogICAgU3BhY2VzaGlwOjpUdW5lcy5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBleHBsaWNpdF90ZWFtX2lkKQogICAgcmV0dXJuIGV4cGxpY2l0X3RlYW1faWQKICBlbmQKCiAgZGV2ZWxvcGVyX3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXS50b19zCiAgZGV2ZWxvcGVyX3RlYW1fbmFtZSA9IHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtcyA9IGF2YWlsYWJsZV90dW5lc190ZWFtcwoKICBpZiBkZXZlbG9wZXJfdGVhbV9uYW1lICYmIGRldmVsb3Blcl90ZWFtX25hbWUubGVuZ3RoID4gMAogICAgbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZSA9IG5vcm1hbGl6ZV90ZWFtX25hbWUoZGV2ZWxvcGVyX3RlYW1fbmFtZSkKICAgIG1hdGNoZWRfdGVhbSA9IHRlYW1zLmZpbmQgeyB8dGVhbXwgbm9ybWFsaXplX3RlYW1fbmFtZSh0dW5lc190ZWFtX25hbWUodGVhbSkpID09IG5vcm1hbGl6ZWRfZGV2ZWxvcGVyX25hbWUgfQoKICAgIGlmIG1hdGNoZWRfdGVhbQogICAgICBtYXRjaGVkX2lkID0gdHVuZXNfdGVhbV9pZChtYXRjaGVkX3RlYW0pCiAgICAgIG1hdGNoZWRfbmFtZSA9IHR1bmVzX3RlYW1fbmFtZShtYXRjaGVkX3RlYW0pCiAgICAgIFNwYWNlc2hpcDo6VHVuZXMuc2VsZWN0X3RlYW0odGVhbV9pZDogbWF0Y2hlZF9pZCkKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogQXV0by1zZWxlY3RlZCBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7bWF0Y2hlZF9pZH0gKCN7bWF0Y2hlZF9uYW1lfSkgZm9yIERldmVsb3BlciBUZWFtICN7ZGV2ZWxvcGVyX3RlYW1faWR9IgogICAgICByZXR1cm4gbWF0Y2hlZF9pZAogICAgZW5kCiAgZW5kCgogIGlmIHRlYW1zLmxlbmd0aCA9PSAxCiAgICBvbmx5X3RlYW0gPSB0ZWFtcy5maXJzdAogICAgb25seV90ZWFtX2lkID0gdHVuZXNfdGVhbV9pZChvbmx5X3RlYW0pCiAgICBTcGFjZXNoaXA6OlR1bmVzLnNlbGVjdF90ZWFtKHRlYW1faWQ6IG9ubHlfdGVhbV9pZCkKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEF1dG8tc2VsZWN0ZWQgb25seSBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7b25seV90ZWFtX2lkfSAoI3t0dW5lc190ZWFtX25hbWUob25seV90ZWFtKX0pIgogICAgcmV0dXJuIG9ubHlfdGVhbV9pZAogIGVuZAoKICAkc3RkZXJyLnB1dHMgIkVSUk9SOiBDb3VsZCBub3QgbWFwIEFwcGxlIERldmVsb3BlciBUZWFtIElEICcje2RldmVsb3Blcl90ZWFtX2lkfScje2RldmVsb3Blcl90ZWFtX25hbWUgPyAiICgje2RldmVsb3Blcl90ZWFtX25hbWV9KSIgOiAnJ30gdG8gQXBwIFN0b3JlIENvbm5lY3QuIgogICRzdGRlcnIucHV0cyAiQXZhaWxhYmxlIEFwcCBTdG9yZSBDb25uZWN0IHRlYW1zOiIKICB0ZWFtcy5lYWNoIGRvIHx0ZWFtfAogICAgJHN0ZGVyci5wdXRzICItICN7dHVuZXNfdGVhbV9pZCh0ZWFtKX0gKCN7dHVuZXNfdGVhbV9uYW1lKHRlYW0pfSkiCiAgZW5kCiAgZXhpdCAxCmVuZAoKZGVmIGxpc3RfdGVhbXMKICBiZWdpbgogICAgU3BhY2VzaGlwOjpQb3J0YWwubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBTcGFjZXNoaXA6OlBvcnRhbC5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXSkKCiAgICBkZXZlbG9wZXJfdGVhbV9uYW1lID0gcG9ydGFsX3RlYW1fbmFtZQoKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lID0gbm9ybWFsaXplX3RlYW1fbmFtZShkZXZlbG9wZXJfdGVhbV9uYW1lKQogICAgdGVhbXMgPSBhdmFpbGFibGVfdHVuZXNfdGVhbXMubWFwIGRvIHx0ZWFtfAogICAgICB0ZWFtX25hbWUgPSB0dW5lc190ZWFtX25hbWUodGVhbSkKICAgICAgewogICAgICAgIGlkOiB0dW5lc190ZWFtX2lkKHRlYW0pLAogICAgICAgIG5hbWU6IHRlYW1fbmFtZSwKICAgICAgICByZWNvbW1lbmRlZDogbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZS5sZW5ndGggPiAwICYmIG5vcm1hbGl6ZV90ZWFtX25hbWUodGVhbV9uYW1lKSA9PSBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lCiAgICAgIH0KICAgIGVuZAoKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyB7CiAgICAgIGRldmVsb3BlclRlYW1JZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10sCiAgICAgIGRldmVsb3BlclRlYW1OYW1lOiBkZXZlbG9wZXJfdGVhbV9uYW1lLAogICAgICB0ZWFtczogdGVhbXMKICAgIH0udG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBleGl0IDEKICBlbmQKZW5kCgpkZWYgbGlzdF9rZXlzCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICAjIFVzZSBUdW5lcyBjbGllbnQgd2hpY2ggcG9pbnRzIHRvIGFwcHN0b3JlY29ubmVjdC5hcHBsZS5jb20KICAgIGNsaWVudCA9IFNwYWNlc2hpcDo6VHVuZXMuY2xpZW50CiAgICAjIFVzZSByb290LXJlbGF0aXZlIFVSTCB0byByZXBsYWNlIHRoZSBkZWZhdWx0IFR1bmVzIHBhdGggKC9XZWJPYmplY3RzLy4uLikKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOmdldCwgJy9pcmlzL3YxL2FwaUtleXMnKQogICAgCiAgICBpZiByZXNwb25zZS5ib2R5Lm5pbD8gfHwgIXJlc3BvbnNlLmJvZHkuaXNfYT8oSGFzaCkKICAgICAgcmFpc2UgIkFQSSByZXR1cm5lZCBlbXB0eSBvciBpbnZhbGlkIHJlc3BvbnNlIGJvZHkgZm9yIGxpc3Rpbmcga2V5cyIKICAgIGVuZAogICAgCiAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGdWxsIExpc3QgUmVzcG9uc2U6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAga2V5cyA9IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXSB8fCBbXQogICAgCiAgICBvdXRwdXQgPSBrZXlzLm1hcCBkbyB8a3wKICAgICAgYXR0ciA9IGtbJ2F0dHJpYnV0ZXMnXSB8fCB7fQogICAgICB7CiAgICAgICAgaWQ6IGtbJ2lkJ10sCiAgICAgICAgbmFtZTogYXR0clsnbmFtZSddLAogICAgICAgIGlzc3VlcklkOiBhdHRyWydpc3N1ZXJJZCddLAogICAgICAgIHJvbGU6IGF0dHJbJ3JvbGVzJ10mLmZpcnN0LAogICAgICAgIHJldm9jYWJsZTogYXR0clsncmV2b2NhYmxlJ10KICAgICAgfQogICAgZW5kCiAgICAKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyBvdXRwdXQudG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBpZiBkZWZpbmVkPyhyZXNwb25zZSkgJiYgcmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keQogICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGNyZWF0ZV9rZXkobmFtZSwgcm9sZSA9ICdBRE1JTicpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgCiAgICAjIFRydW5jYXRlIG5pY2tuYW1lIHRvIDMwIGNoYXJzIGFzIHBlciBBcHBsZSdzIGxpbWl0CiAgICAjIFdlIGtlZXAgdGhlIG9yaWdpbmFsICduYW1lJyBmb3IgbG9nZ2luZyBidXQgc2VuZCB0cnVuY2F0ZWQgJ25pY2tuYW1lJyB0byBBUEkKICAgIHNhZmVfbmlja25hbWUgPSBuYW1lWzAsIDMwXQogICAgCiAgICBwYXlsb2FkID0gewogICAgICBkYXRhOiB7CiAgICAgICAgdHlwZTogImFwaUtleXMiLAogICAgICAgIGF0dHJpYnV0ZXM6IHsKICAgICAgICAgIG5pY2tuYW1lOiBzYWZlX25pY2tuYW1lLAogICAgICAgICAga2V5VHlwZTogIlBVQkxJQ19BUEkiLAogICAgICAgICAgcm9sZXM6IFtyb2xlXSwKICAgICAgICAgIGFsbEFwcHNWaXNpYmxlOiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOnBvc3QpIGRvIHxyZXF8CiAgICAgIHJlcS51cmwgIi9pcmlzL3YxL2FwaUtleXMiCiAgICAgIHJlcS5ib2R5ID0gcGF5bG9hZC50b19qc29uCiAgICAgIHJlcS5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJwogICAgICByZXEuaGVhZGVyc1snQWNjZXB0J10gPSAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uLCBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJwogICAgICByZXEuaGVhZGVyc1snWC1SZXF1ZXN0ZWQtV2l0aCddID0gJ1hNTEh0dHBSZXF1ZXN0JwogICAgICByZXEuaGVhZGVyc1snUmVmZXJlciddID0gJ2h0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9hY2Nlc3MvYXBpJwogICAgICByZXEuaGVhZGVyc1snWC1BcHBsZS1XaWRnZXQtS2V5J10gPSBjbGllbnQud2lkZ2V0X2tleSBpZiBjbGllbnQucmVzcG9uZF90bz8oOndpZGdldF9rZXkpCiAgICBlbmQKICAgIAogICAgIyBERUJVRzogSW5zcGVjdCB0aGUgcmF3IHJlc3BvbnNlIG9iamVjdAogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgQ2xhc3M6ICN7cmVzcG9uc2UuY2xhc3N9IgogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgSGVhZGVyczogI3tyZXNwb25zZS5oZWFkZXJzfSIKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAgaWYgcmVzcG9uc2UuYm9keS5uaWw/IHx8ICFyZXNwb25zZS5ib2R5LmlzX2E/KEhhc2gpIHx8IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXS5uaWw/CiAgICAgIGVycm9yX21zZyA9ICJBUEkgZmFpbGVkIHRvIGNyZWF0ZSBrZXkuIgogICAgICBpZiByZXNwb25zZS5ib2R5ICYmIHJlc3BvbnNlLmJvZHlbJ2Vycm9ycyddCiAgICAgICAgZXJyb3JfbXNnICs9ICIgRXJyb3JzOiAiICsgcmVzcG9uc2UuYm9keVsnZXJyb3JzJ10ubWFwe3xlfCBlWydkZXRhaWwnXX0uam9pbignLCAnKQogICAgICBlbmQKICAgICAgcmFpc2UgZXJyb3JfbXNnCiAgICBlbmQKICAgIAogICAga2V5X2RhdGEgPSByZXNwb25zZS5ib2R5WydkYXRhJ10KICAgIGF0dHIgPSBrZXlfZGF0YVsnYXR0cmlidXRlcyddIHx8IHt9CgogICAgIyBUaGUgLnA4IGNvbnRlbnQgaXMgdXN1YWxseSBpbiAncHJpdmF0ZUtleScgb3IgJ2tleUNvbnRlbnQnIG9uIHRoZSBJTklUSUFMIENSRUFURSByZXNwb25zZQogICAgcDhfY29udGVudCA9IGF0dHJbJ3ByaXZhdGVLZXknXSB8fCBhdHRyWydrZXlDb250ZW50J10KICAgIAogICAgaWYgcDhfY29udGVudC5uaWw/CiAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEtleSBjb250ZW50IG1pc3NpbmcgaW4gcmVzcG9uc2UuIEF0dGVtcHRpbmcgcmV0cmlldmFsIHZpYSBkb3dubG9hZC9leHBvcnQgZW5kcG9pbnRzLi4uIiAKICAgICAgCiAgICAgIHBhdGhzX3RvX3RyeSA9IFsKICAgICAgICAiaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2lyaXMvdjEvYXBpS2V5cy8je2tleV9kYXRhWydpZCddfS9kb3dubG9hZCIsCiAgICAgICAgImh0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9pcmlzL3YxL2FwaUtleXMvI3trZXlfZGF0YVsnaWQnXX0vZXhwb3J0IgogICAgICBdCiAgICAgIAogICAgICBwYXRoc190b190cnkuZWFjaCBkbyB8cGF0aHwKICAgICAgICBiZWdpbgogICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogVHJ5aW5nICN7cGF0aH0uLi4iCiAgICAgICAgICBkb3dubG9hZF9yZXNwID0gY2xpZW50LnJlcXVlc3QoOmdldCkgZG8gfHJlcXwKICAgICAgICAgICAgcmVxLnVybCBwYXRoCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydBY2NlcHQnXSA9ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24sIGFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCwgKi8qOyBxPTAuMDEnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydSZWZlcmVyJ10gPSAnaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2FjY2Vzcy9hcGknCiAgICAgICAgICBlbmQKICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIENsYXNzOiAje2Rvd25sb2FkX3Jlc3AuYm9keS5jbGFzc30iCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBTdGF0dXM6ICN7ZG93bmxvYWRfcmVzcC5zdGF0dXN9IiBpZiBkb3dubG9hZF9yZXNwLnJlc3BvbmRfdG8/KDpzdGF0dXMpCiAgICAgICAgICAKICAgICAgICAgIGlmIGRvd25sb2FkX3Jlc3AuYm9keSAmJiAhZG93bmxvYWRfcmVzcC5ib2R5LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKQogICAgICAgICAgICAgaWYgZG93bmxvYWRfcmVzcC5ib2R5LmlzX2E/KEhhc2gpCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHlbJ2tleUNvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHlbJ2NvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHkuZGlnKCdkYXRhJywgJ2F0dHJpYnV0ZXMnLCAncHJpdmF0ZUtleScpCiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHkKICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgCiAgICAgICAgICAgICBpZiBwOF9jb250ZW50ICYmIHA4X2NvbnRlbnQudG9fcy5zdGFydF93aXRoPygnLS0tLS1CRUdJTicpCiAgICAgICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJldHJpZXZhbCB2aWEgI3twYXRofSBzdWNjZXNzZnVsISBDb250ZW50IGxlbmd0aDogI3twOF9jb250ZW50LnRvX3MubGVuZ3RofSIKICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgZnJvbSAje3BhdGh9IGRpZCBub3QgY29udGFpbiBhIHZhbGlkIHByaXZhdGUga2V5LiIKICAgICAgICAgICAgICAgcDhfY29udGVudCA9IG5pbAogICAgICAgICAgICAgZW5kCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBmcm9tICN7cGF0aH0gZW1wdHkgb3IgY29udGFpbnMgZXJyb3JzLiIKICAgICAgICAgIGVuZAogICAgICAgIHJlc2N1ZSA9PiBlCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBBdHRlbXB0IGZvciAje3BhdGh9IGZhaWxlZDogI3tlLm1lc3NhZ2V9IgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAoKICAgICMgRklOQUwgVkFMSURBVElPTjogRW5zdXJlIGl0J3Mgbm90IGEgUnVieSBoYXNoIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBlcnJvcgogICAgaWYgcDhfY29udGVudC5pc19hPyhIYXNoKSB8fCBwOF9jb250ZW50LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKSB8fCAhcDhfY29udGVudC50b19zLnN0YXJ0X3dpdGg/KCctLS0tLUJFR0lOJykKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogSW52YWxpZCBrZXkgY29udGVudCBkZXRlY3RlZC4iCiAgICAgIHA4X2NvbnRlbnQgPSBuaWwKICAgIGVuZAoKICAgIGlmIHA4X2NvbnRlbnQubmlsPwogICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGYWlsZWQgdG8gcmV0cmlldmUga2V5IGNvbnRlbnQuIgogICAgZW5kCiAgICAKICAgIHJlc3VsdCA9IHsKICAgICAgaWQ6IGtleV9kYXRhWydpZCddLAogICAgICBuYW1lOiBhdHRyWyduaWNrbmFtZSddIHx8IGF0dHJbJ25hbWUnXSwKICAgICAgaXNzdWVySWQ6IGF0dHJbJ2lzc3VlcklkJ10sCiAgICAgIGtleUNvbnRlbnQ6IHA4X2NvbnRlbnQsCiAgICAgIHJhd19yZXNwb25zZTogcmVzcG9uc2UuYm9keSAjIEluY2x1ZGUgdGhpcyBmb3IgZGVidWdnaW5nIHdoZW4ga2V5Q29udGVudCBpcyBuaWwKICAgIH0KICAgIAogICAgcHV0cyAiX19fTUFDSF9KU09OX1NUQVJUX19fIiArIHJlc3VsdC50b19qc29uICsgIl9fX01BQ0hfSlNPTl9FTkRfX18iCiAgcmVzY3VlID0+IGUKICAgICRzdGRlcnIucHV0cyAiRVJST1I6ICN7ZS5tZXNzYWdlfSIKICAgIGlmIGRlZmluZWQ/KHJlc3BvbnNlKSAmJiByZXNwb25zZSAmJiByZXNwb25zZS5ib2R5CiAgICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGRlbGV0ZV9rZXkoaWQpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgY2xpZW50LnJlcXVlc3QoOmRlbGV0ZSwgIi9pcmlzL3YxL2FwaUtleXMvI3tpZH0iKQogICAgcHV0cyAiU1VDQ0VTUyIKICByZXNjdWUgPT4gZQogICAgJHN0ZGVyci5wdXRzICJFUlJPUjogI3tlLm1lc3NhZ2V9IgogICAgZXhpdCAxCiAgZW5kCmVuZAoKY29tbWFuZCA9IEFSR1ZbMF0KaWYgY29tbWFuZCA9PSAnbGlzdCcKICBsaXN0X2tleXMKZWxzaWYgY29tbWFuZCA9PSAndGVhbXMnCiAgbGlzdF90ZWFtcwplbHNpZiBjb21tYW5kID09ICdjcmVhdGUnCiAgY3JlYXRlX2tleShBUkdWWzFdIHx8ICJNYWNoIEFQSSBLZXkgI3tUaW1lLm5vdy50b19pfSIpCmVsc2lmIGNvbW1hbmQgPT0gJ2RlbGV0ZScKICBkZWxldGVfa2V5KEFSR1ZbMV0pCmVuZAo=";function Jt(){let e=Se.join(qt.tmpdir(),A.nameLower);de.existsSync(e)||de.mkdirSync(e,{recursive:!0});let t=Se.join(e,"manage_asc_keys.rb");return de.writeFileSync(t,Buffer.from(Ar,"base64").toString("utf-8"),{mode:493}),t}function Yt(){return rt()}function en(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 On(e){return ht(e).appStoreConnectTeamId}function Dn(e,t,n){return{...Yt(),FASTLANE_USER:e,FASTLANE_TEAM_ID:t,...n?{FASTLANE_ITC_TEAM_ID:n,FASTLANE_ASC_TEAM_ID:n}:{}}}function ot(e,t="production",n={}){let i=ht(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 Bn(e,t){if(t.id){e.submit||(e.submit={}),e.submit.production||(e.submit.production={}),e.submit.production.ios||(e.submit.production.ios={}),e.submit.production.ios.appStoreConnectTeamId=t.id,e.submit.production.ios.providerId=t.id,t.name&&(e.submit.production.ios.appStoreConnectTeamName=t.name,e.submit.production.ios.providerName=t.name),t.developerTeamName&&(e.submit.production.ios.appleTeamName=t.developerTeamName);try{de.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}}async function Cr(e,t,n,i){let r=At();r.start("Fetching App Store Connect providers...");let o=It("ruby",[e,"teams"],{env:Dn(n,i),stdio:["inherit","pipe","pipe"],encoding:"utf-8"});if(o.status!==0){r.stop("Could not fetch providers");let d=en(`${o.stdout||""}
3
- ${o.stderr||""}`);if(d.length>0)return zt(t,d,"Select the App Store Connect provider for this API key:");ne.warn(ie.yellow(`Could not list App Store Connect providers: ${o.stderr||"Unknown error"}`));return}let s=(o.stdout||"").match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!s){r.stop("Could not parse providers");return}let a=JSON.parse(s[1]),c=(a.teams||[]).filter(d=>d.id&&d.name);if(r.stop(c.length===1?"Found 1 provider":`Found ${c.length} providers`),c.length===0)return;if(c.length===1){ne.success(ie.green(`\u2713 Using App Store Connect provider ${c[0].name} (${c[0].id})`));let d={...c[0],developerTeamName:a.developerTeamName};return Bn(t,d),d}let l=c.filter(d=>d.recommended),p=c.filter(d=>!d.recommended);return zt(t,[...l,...p],`Select the App Store Connect provider for Developer Team ${a.developerTeamName||i}:`,a.developerTeamName)}async function zt(e,t,n,i){let r=await st({message:n,options:t.map(c=>({value:c.id,label:c.name,hint:`${c.id}${c.recommended?" \xB7 recommended":""}`}))});if(ge(r))return xe("Operation cancelled"),null;let o=r,a={...t.find(c=>c.id===o)||{id:o,name:o},developerTeamName:i};return Bn(e,a),ne.success(ie.green(`\u2713 Using App Store Connect provider ${a.name} (${a.id})`)),a}var Vn=async e=>{let t=At(),n=e.platform,i=`./${A.configFileName}`;if(!de.existsSync(i)){ne.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(de.readFileSync(i,"utf-8")),{projectId:o}=r,s=e.profile||"production";if(!o){ne.error(`${A.configFileName} is missing projectId.`);return}let a=e.file,c=n==="android"?e.packageName||e.bundleId:e.bundleId||Ge(r,s)||"*";if(n==="android"&&!c&&(c=await br(o,r,s),c===null))return;if(n==="ios"&&!a){let u=await st({message:"Manage App Store Connect API Key:",options:[{value:"magic",label:"\u2728 Create new automatically",hint:"Requires Apple ID + 2FA"},{value:"manual",label:"\u{1F50D} Configure manually",hint:"Provide existing .p8 file"},{value:"delete",label:"\u{1F5D1}\uFE0F Delete an existing Key"}]});if(ge(u)){xe("Operation cancelled");return}if(u==="magic"){await vr(o,r);return}if(u==="delete"){await Er(o,r);return}}if(!a){let u=n==="ios"?"https://appstoreconnect.apple.com/access/api":"https://console.cloud.google.com/apis/credentials";Rt(`To submit to the ${n==="ios"?"App Store":"Google Play Store"}, you need a Service Key:
1
+ import{a as A,h as Z,i as Ut,k as Rn}from"./chunk-LO6DP2SE.js";import{log as m,spinner as Je,text as ve,password as ut,select as Ee,confirm as bn,isCancel as j,cancel as Y,intro as ps,outro as us,note as fs}from"@clack/prompts";import{log as ne,spinner as At,text as Be,select as st,isCancel as ge,cancel as xe,note as Rt,confirm as Tn}from"@clack/prompts";import ie from"chalk";import{spawnSync as It}from"child_process";import de from"fs";import Se from"path";import qt from"os";import Pt from"fs";import{log as ir}from"@clack/prompts";var rr=["react-native","expo","flutter"],Ia="react-native",xn=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},kn=e=>xn(e)?.toUpperCase()||void 0,Nt=(...e)=>{for(let t of e){let n=xn(t);if(n)return n}};function or(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 Lt(e){let t=or(e?.framework);if(t)return t;let n=rr.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 ht(e,t="production"){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=kn(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=Nt(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:Nt(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:kn(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:Nt(n.providerId,i.providerId,r.providerId,s),providerName:Nt(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function $n(e){if(e){if(!Pt.existsSync(e))return null;try{return JSON.parse(Pt.readFileSync(e,"utf-8"))}catch{return null}}if(!Pt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(Pt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function nt(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=nt(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android}})}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):ir.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function it(e,t){let n=t?nt(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 Ge(e,t){let n=t?nt(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 Aa=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],c=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${c}_`):n[c]=String(a)}};return i(e,t),n};import{cancel as Ht,confirm as sr,isCancel as Kt,log as Ye,select as ar,text as cr}from"@clack/prompts";import ze from"chalk";import lr from"fs";import{createRequire as dr}from"module";import pr from"os";import _n from"path";var ur=dr(import.meta.url),Xt=null;function fr(){return Xt||(Xt=ur("@expo/apple-utils")),Xt}function rt(){let e=process.env.HOME||pr.homedir(),t=process.env.FASTLANE_GEM_HOME||_n.join(e,".local/share/fastlane/3.4.0");return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin","/usr/local/Cellar/fastlane/2.227.0/libexec/bin","/opt/homebrew/Cellar/fastlane/2.227.0/libexec/bin",_n.join(t,"bin"),process.env.PATH].filter(Boolean).join(":"),GEM_HOME:t,GEM_PATH:[t,"/usr/local/Cellar/fastlane/2.227.0/libexec","/opt/homebrew/Cellar/fastlane/2.227.0/libexec",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 mr(e,t="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 gr(e,t,n="production"){if(!e||!t.id)return;let i=mr(e,n);i.appleTeamId=t.id;try{lr.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function hr(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 yr(e){try{let{Auth:t,Teams:n}=fr(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let l of o||[]){let p=hr(l);p&&s.set(p.id,p)}let a=Array.from(s.values()),c=r?a.find(l=>l.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:c}}catch(t){let n=t instanceof Error?t.message:String(t||"");return Ye.warn(ze.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Fn(){Ye.warn(ze.yellow(`
2
+ Apple Team ID is required to fetch certificates.`)),Ye.info(ze.dim("You can find this at: https://developer.apple.com/account -> Membership Details"));let e=await cr({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 Kt(e)?(Ht("Operation cancelled"),null):{id:e.trim().toUpperCase()}}function Ir(e){let t=[e.id,e.type].filter(Boolean);return t.length>0?t.join(" \xB7 "):void 0}async function Ar(e,t){if(!e.config)return!1;if(e.persistConfig)return!0;if(!e.promptToPersistConfig)return!1;let n=e.profile||"production",i=await sr({message:`Save Apple Team ID ${t} to ${A.configFileName} for "${n}" profile?`,initialValue:n==="production"});return Kt(i)?(Ht("Operation cancelled"),null):i}async function yt(e){let t=e.initialTeam?.teamId?.trim().toUpperCase();if(t){let l=e.initialTeam?.developerTeamId?.trim().toUpperCase();return{...e.initialTeam,teamId:t,developerTeamId:l||t}}Ye.info(ze.blue("Fetching Apple Developer teams..."));let{teams:n,selectedTeam:i}=await yr(e.appleId),r;if(i)r=i,Ye.success(ze.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length===1)r=n[0],Ye.success(ze.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length>1){let l=await ar({message:"Select Apple Developer team:",options:[...n.map(p=>({value:p.id,label:p.name||p.id,hint:Ir(p)})),{value:"__manual__",label:"Enter Team ID manually",hint:"Use if your team is not listed"}]});if(Kt(l))return Ht("Operation cancelled"),null;r=l==="__manual__"?await Fn():n.find(p=>p.id===l)||{id:l}}else Ye.warn(ze.yellow("Could not list Apple Developer teams automatically.")),r=await Fn();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},c=await Ar(e,o);return c===null?null:(c&&gr(e.config,{...r,id:o,name:s},e.profile),e.saveTeamId&&await e.saveTeamId(o,s),a)}var Cr="cmVxdWlyZSAnc3BhY2VzaGlwJwpyZXF1aXJlICdqc29uJwoKZGVmIHJlYWRfdGVhbV9maWVsZCh0ZWFtLCAqa2V5cykKICBrZXlzLmVhY2ggZG8gfGtleXwKICAgIGJlZ2luCiAgICAgIHZhbHVlID0gdGVhbVtrZXldIGlmIHRlYW0ucmVzcG9uZF90bz8oOltdKQogICAgICByZXR1cm4gdmFsdWUgaWYgdmFsdWUgJiYgdmFsdWUudG9fcy5sZW5ndGggPiAwCiAgICByZXNjdWUKICAgIGVuZAoKICAgIG1ldGhvZF9uYW1lID0ga2V5LnRvX3MKICAgIGlmIHRlYW0ucmVzcG9uZF90bz8obWV0aG9kX25hbWUpCiAgICAgIHZhbHVlID0gdGVhbS5wdWJsaWNfc2VuZChtZXRob2RfbmFtZSkKICAgICAgcmV0dXJuIHZhbHVlIGlmIHZhbHVlICYmIHZhbHVlLnRvX3MubGVuZ3RoID4gMAogICAgZW5kCiAgZW5kCgogIG5pbAplbmQKCmRlZiBub3JtYWxpemVfdGVhbV9uYW1lKG5hbWUpCiAgbmFtZS50b19zLmRvd25jYXNlLmdzdWIoL1teYS16MC05XSsvLCAnICcpLnN0cmlwCmVuZAoKZGVmIHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtX2lkID0gRU5WWydGQVNUTEFORV9URUFNX0lEJ10udG9fcwogIHRlYW1zID0gU3BhY2VzaGlwOjpQb3J0YWwuY2xpZW50LnRlYW1zCiAgdGVhbXMgPSB0ZWFtcy52YWx1ZXMgaWYgdGVhbXMuaXNfYT8oSGFzaCkKCiAgdGVhbSA9IEFycmF5KHRlYW1zKS5maW5kIGRvIHx0fAogICAgWwogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1JZCcsIDp0ZWFtSWQpLAogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1faWQnLCA6dGVhbV9pZCksCiAgICAgIHJlYWRfdGVhbV9maWVsZCh0LCAnaWQnLCA6aWQpCiAgICBdLmNvbXBhY3QubWFwKCY6dG9fcykuaW5jbHVkZT8odGVhbV9pZCkKICBlbmQKCiAgcmVhZF90ZWFtX2ZpZWxkKHRlYW0sICduYW1lJywgOm5hbWUsICd0ZWFtTmFtZScsIDp0ZWFtTmFtZSwgJ2Rpc3BsYXlOYW1lJywgOmRpc3BsYXlOYW1lKQpyZXNjdWUgPT4gZQogICRzdGRlcnIucHV0cyAiREVCVUc6IENvdWxkIG5vdCByZXNvbHZlIERldmVsb3BlciBQb3J0YWwgdGVhbSBuYW1lOiAje2UubWVzc2FnZX0iCiAgbmlsCmVuZAoKZGVmIHR1bmVzX3RlYW1faWQodGVhbSkKICByZWFkX3RlYW1fZmllbGQoCiAgICB0ZWFtLAogICAgJ3Byb3ZpZGVySWQnLCA6cHJvdmlkZXJJZCwKICAgICdwcm92aWRlcl9pZCcsIDpwcm92aWRlcl9pZCwKICAgICdjb250ZW50UHJvdmlkZXJJZCcsIDpjb250ZW50UHJvdmlkZXJJZCwKICAgICdjb250ZW50X3Byb3ZpZGVyX2lkJywgOmNvbnRlbnRfcHJvdmlkZXJfaWQsCiAgICAndGVhbUlkJywgOnRlYW1JZCwKICAgICd0ZWFtX2lkJywgOnRlYW1faWQsCiAgICAnaWQnLCA6aWQKICApLnRvX3MKZW5kCgpkZWYgdHVuZXNfdGVhbV9uYW1lKHRlYW0pCiAgcmVhZF90ZWFtX2ZpZWxkKAogICAgdGVhbSwKICAgICduYW1lJywgOm5hbWUsCiAgICAnY29udGVudFByb3ZpZGVyTmFtZScsIDpjb250ZW50UHJvdmlkZXJOYW1lLAogICAgJ2NvbnRlbnRfcHJvdmlkZXJfbmFtZScsIDpjb250ZW50X3Byb3ZpZGVyX25hbWUsCiAgICAndGVhbU5hbWUnLCA6dGVhbU5hbWUsCiAgICAnZGlzcGxheU5hbWUnLCA6ZGlzcGxheU5hbWUKICApLnRvX3MKZW5kCgpkZWYgYXZhaWxhYmxlX3R1bmVzX3RlYW1zCiAgdGVhbXMgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudC50ZWFtcwogIHRlYW1zID0gdGVhbXMudmFsdWVzIGlmIHRlYW1zLmlzX2E/KEhhc2gpCiAgQXJyYXkodGVhbXMpCnJlc2N1ZSA9PiBlCiAgJHN0ZGVyci5wdXRzICJERUJVRzogQ291bGQgbm90IGluc3BlY3QgQXBwIFN0b3JlIENvbm5lY3QgdGVhbXM6ICN7ZS5tZXNzYWdlfSIKICBbXQplbmQKCmRlZiBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogIGV4cGxpY2l0X3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX0lUQ19URUFNX0lEJ10gfHwgRU5WWydGQVNUTEFORV9BU0NfVEVBTV9JRCddCiAgaWYgZXhwbGljaXRfdGVhbV9pZCAmJiBleHBsaWNpdF90ZWFtX2lkLnRvX3MubGVuZ3RoID4gMAogICAgU3BhY2VzaGlwOjpUdW5lcy5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBleHBsaWNpdF90ZWFtX2lkKQogICAgcmV0dXJuIGV4cGxpY2l0X3RlYW1faWQKICBlbmQKCiAgZGV2ZWxvcGVyX3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXS50b19zCiAgZGV2ZWxvcGVyX3RlYW1fbmFtZSA9IHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtcyA9IGF2YWlsYWJsZV90dW5lc190ZWFtcwoKICBpZiBkZXZlbG9wZXJfdGVhbV9uYW1lICYmIGRldmVsb3Blcl90ZWFtX25hbWUubGVuZ3RoID4gMAogICAgbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZSA9IG5vcm1hbGl6ZV90ZWFtX25hbWUoZGV2ZWxvcGVyX3RlYW1fbmFtZSkKICAgIG1hdGNoZWRfdGVhbSA9IHRlYW1zLmZpbmQgeyB8dGVhbXwgbm9ybWFsaXplX3RlYW1fbmFtZSh0dW5lc190ZWFtX25hbWUodGVhbSkpID09IG5vcm1hbGl6ZWRfZGV2ZWxvcGVyX25hbWUgfQoKICAgIGlmIG1hdGNoZWRfdGVhbQogICAgICBtYXRjaGVkX2lkID0gdHVuZXNfdGVhbV9pZChtYXRjaGVkX3RlYW0pCiAgICAgIG1hdGNoZWRfbmFtZSA9IHR1bmVzX3RlYW1fbmFtZShtYXRjaGVkX3RlYW0pCiAgICAgIFNwYWNlc2hpcDo6VHVuZXMuc2VsZWN0X3RlYW0odGVhbV9pZDogbWF0Y2hlZF9pZCkKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogQXV0by1zZWxlY3RlZCBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7bWF0Y2hlZF9pZH0gKCN7bWF0Y2hlZF9uYW1lfSkgZm9yIERldmVsb3BlciBUZWFtICN7ZGV2ZWxvcGVyX3RlYW1faWR9IgogICAgICByZXR1cm4gbWF0Y2hlZF9pZAogICAgZW5kCiAgZW5kCgogIGlmIHRlYW1zLmxlbmd0aCA9PSAxCiAgICBvbmx5X3RlYW0gPSB0ZWFtcy5maXJzdAogICAgb25seV90ZWFtX2lkID0gdHVuZXNfdGVhbV9pZChvbmx5X3RlYW0pCiAgICBTcGFjZXNoaXA6OlR1bmVzLnNlbGVjdF90ZWFtKHRlYW1faWQ6IG9ubHlfdGVhbV9pZCkKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEF1dG8tc2VsZWN0ZWQgb25seSBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7b25seV90ZWFtX2lkfSAoI3t0dW5lc190ZWFtX25hbWUob25seV90ZWFtKX0pIgogICAgcmV0dXJuIG9ubHlfdGVhbV9pZAogIGVuZAoKICAkc3RkZXJyLnB1dHMgIkVSUk9SOiBDb3VsZCBub3QgbWFwIEFwcGxlIERldmVsb3BlciBUZWFtIElEICcje2RldmVsb3Blcl90ZWFtX2lkfScje2RldmVsb3Blcl90ZWFtX25hbWUgPyAiICgje2RldmVsb3Blcl90ZWFtX25hbWV9KSIgOiAnJ30gdG8gQXBwIFN0b3JlIENvbm5lY3QuIgogICRzdGRlcnIucHV0cyAiQXZhaWxhYmxlIEFwcCBTdG9yZSBDb25uZWN0IHRlYW1zOiIKICB0ZWFtcy5lYWNoIGRvIHx0ZWFtfAogICAgJHN0ZGVyci5wdXRzICItICN7dHVuZXNfdGVhbV9pZCh0ZWFtKX0gKCN7dHVuZXNfdGVhbV9uYW1lKHRlYW0pfSkiCiAgZW5kCiAgZXhpdCAxCmVuZAoKZGVmIGxpc3RfdGVhbXMKICBiZWdpbgogICAgU3BhY2VzaGlwOjpQb3J0YWwubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBTcGFjZXNoaXA6OlBvcnRhbC5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXSkKCiAgICBkZXZlbG9wZXJfdGVhbV9uYW1lID0gcG9ydGFsX3RlYW1fbmFtZQoKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lID0gbm9ybWFsaXplX3RlYW1fbmFtZShkZXZlbG9wZXJfdGVhbV9uYW1lKQogICAgdGVhbXMgPSBhdmFpbGFibGVfdHVuZXNfdGVhbXMubWFwIGRvIHx0ZWFtfAogICAgICB0ZWFtX25hbWUgPSB0dW5lc190ZWFtX25hbWUodGVhbSkKICAgICAgewogICAgICAgIGlkOiB0dW5lc190ZWFtX2lkKHRlYW0pLAogICAgICAgIG5hbWU6IHRlYW1fbmFtZSwKICAgICAgICByZWNvbW1lbmRlZDogbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZS5sZW5ndGggPiAwICYmIG5vcm1hbGl6ZV90ZWFtX25hbWUodGVhbV9uYW1lKSA9PSBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lCiAgICAgIH0KICAgIGVuZAoKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyB7CiAgICAgIGRldmVsb3BlclRlYW1JZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10sCiAgICAgIGRldmVsb3BlclRlYW1OYW1lOiBkZXZlbG9wZXJfdGVhbV9uYW1lLAogICAgICB0ZWFtczogdGVhbXMKICAgIH0udG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBleGl0IDEKICBlbmQKZW5kCgpkZWYgbGlzdF9rZXlzCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICAjIFVzZSBUdW5lcyBjbGllbnQgd2hpY2ggcG9pbnRzIHRvIGFwcHN0b3JlY29ubmVjdC5hcHBsZS5jb20KICAgIGNsaWVudCA9IFNwYWNlc2hpcDo6VHVuZXMuY2xpZW50CiAgICAjIFVzZSByb290LXJlbGF0aXZlIFVSTCB0byByZXBsYWNlIHRoZSBkZWZhdWx0IFR1bmVzIHBhdGggKC9XZWJPYmplY3RzLy4uLikKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOmdldCwgJy9pcmlzL3YxL2FwaUtleXMnKQogICAgCiAgICBpZiByZXNwb25zZS5ib2R5Lm5pbD8gfHwgIXJlc3BvbnNlLmJvZHkuaXNfYT8oSGFzaCkKICAgICAgcmFpc2UgIkFQSSByZXR1cm5lZCBlbXB0eSBvciBpbnZhbGlkIHJlc3BvbnNlIGJvZHkgZm9yIGxpc3Rpbmcga2V5cyIKICAgIGVuZAogICAgCiAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGdWxsIExpc3QgUmVzcG9uc2U6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAga2V5cyA9IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXSB8fCBbXQogICAgCiAgICBvdXRwdXQgPSBrZXlzLm1hcCBkbyB8a3wKICAgICAgYXR0ciA9IGtbJ2F0dHJpYnV0ZXMnXSB8fCB7fQogICAgICB7CiAgICAgICAgaWQ6IGtbJ2lkJ10sCiAgICAgICAgbmFtZTogYXR0clsnbmFtZSddLAogICAgICAgIGlzc3VlcklkOiBhdHRyWydpc3N1ZXJJZCddLAogICAgICAgIHJvbGU6IGF0dHJbJ3JvbGVzJ10mLmZpcnN0LAogICAgICAgIHJldm9jYWJsZTogYXR0clsncmV2b2NhYmxlJ10KICAgICAgfQogICAgZW5kCiAgICAKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyBvdXRwdXQudG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBpZiBkZWZpbmVkPyhyZXNwb25zZSkgJiYgcmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keQogICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGNyZWF0ZV9rZXkobmFtZSwgcm9sZSA9ICdBRE1JTicpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgCiAgICAjIFRydW5jYXRlIG5pY2tuYW1lIHRvIDMwIGNoYXJzIGFzIHBlciBBcHBsZSdzIGxpbWl0CiAgICAjIFdlIGtlZXAgdGhlIG9yaWdpbmFsICduYW1lJyBmb3IgbG9nZ2luZyBidXQgc2VuZCB0cnVuY2F0ZWQgJ25pY2tuYW1lJyB0byBBUEkKICAgIHNhZmVfbmlja25hbWUgPSBuYW1lWzAsIDMwXQogICAgCiAgICBwYXlsb2FkID0gewogICAgICBkYXRhOiB7CiAgICAgICAgdHlwZTogImFwaUtleXMiLAogICAgICAgIGF0dHJpYnV0ZXM6IHsKICAgICAgICAgIG5pY2tuYW1lOiBzYWZlX25pY2tuYW1lLAogICAgICAgICAga2V5VHlwZTogIlBVQkxJQ19BUEkiLAogICAgICAgICAgcm9sZXM6IFtyb2xlXSwKICAgICAgICAgIGFsbEFwcHNWaXNpYmxlOiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOnBvc3QpIGRvIHxyZXF8CiAgICAgIHJlcS51cmwgIi9pcmlzL3YxL2FwaUtleXMiCiAgICAgIHJlcS5ib2R5ID0gcGF5bG9hZC50b19qc29uCiAgICAgIHJlcS5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJwogICAgICByZXEuaGVhZGVyc1snQWNjZXB0J10gPSAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uLCBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJwogICAgICByZXEuaGVhZGVyc1snWC1SZXF1ZXN0ZWQtV2l0aCddID0gJ1hNTEh0dHBSZXF1ZXN0JwogICAgICByZXEuaGVhZGVyc1snUmVmZXJlciddID0gJ2h0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9hY2Nlc3MvYXBpJwogICAgICByZXEuaGVhZGVyc1snWC1BcHBsZS1XaWRnZXQtS2V5J10gPSBjbGllbnQud2lkZ2V0X2tleSBpZiBjbGllbnQucmVzcG9uZF90bz8oOndpZGdldF9rZXkpCiAgICBlbmQKICAgIAogICAgIyBERUJVRzogSW5zcGVjdCB0aGUgcmF3IHJlc3BvbnNlIG9iamVjdAogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgQ2xhc3M6ICN7cmVzcG9uc2UuY2xhc3N9IgogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgSGVhZGVyczogI3tyZXNwb25zZS5oZWFkZXJzfSIKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAgaWYgcmVzcG9uc2UuYm9keS5uaWw/IHx8ICFyZXNwb25zZS5ib2R5LmlzX2E/KEhhc2gpIHx8IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXS5uaWw/CiAgICAgIGVycm9yX21zZyA9ICJBUEkgZmFpbGVkIHRvIGNyZWF0ZSBrZXkuIgogICAgICBpZiByZXNwb25zZS5ib2R5ICYmIHJlc3BvbnNlLmJvZHlbJ2Vycm9ycyddCiAgICAgICAgZXJyb3JfbXNnICs9ICIgRXJyb3JzOiAiICsgcmVzcG9uc2UuYm9keVsnZXJyb3JzJ10ubWFwe3xlfCBlWydkZXRhaWwnXX0uam9pbignLCAnKQogICAgICBlbmQKICAgICAgcmFpc2UgZXJyb3JfbXNnCiAgICBlbmQKICAgIAogICAga2V5X2RhdGEgPSByZXNwb25zZS5ib2R5WydkYXRhJ10KICAgIGF0dHIgPSBrZXlfZGF0YVsnYXR0cmlidXRlcyddIHx8IHt9CgogICAgIyBUaGUgLnA4IGNvbnRlbnQgaXMgdXN1YWxseSBpbiAncHJpdmF0ZUtleScgb3IgJ2tleUNvbnRlbnQnIG9uIHRoZSBJTklUSUFMIENSRUFURSByZXNwb25zZQogICAgcDhfY29udGVudCA9IGF0dHJbJ3ByaXZhdGVLZXknXSB8fCBhdHRyWydrZXlDb250ZW50J10KICAgIAogICAgaWYgcDhfY29udGVudC5uaWw/CiAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEtleSBjb250ZW50IG1pc3NpbmcgaW4gcmVzcG9uc2UuIEF0dGVtcHRpbmcgcmV0cmlldmFsIHZpYSBkb3dubG9hZC9leHBvcnQgZW5kcG9pbnRzLi4uIiAKICAgICAgCiAgICAgIHBhdGhzX3RvX3RyeSA9IFsKICAgICAgICAiaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2lyaXMvdjEvYXBpS2V5cy8je2tleV9kYXRhWydpZCddfS9kb3dubG9hZCIsCiAgICAgICAgImh0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9pcmlzL3YxL2FwaUtleXMvI3trZXlfZGF0YVsnaWQnXX0vZXhwb3J0IgogICAgICBdCiAgICAgIAogICAgICBwYXRoc190b190cnkuZWFjaCBkbyB8cGF0aHwKICAgICAgICBiZWdpbgogICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogVHJ5aW5nICN7cGF0aH0uLi4iCiAgICAgICAgICBkb3dubG9hZF9yZXNwID0gY2xpZW50LnJlcXVlc3QoOmdldCkgZG8gfHJlcXwKICAgICAgICAgICAgcmVxLnVybCBwYXRoCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydBY2NlcHQnXSA9ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24sIGFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCwgKi8qOyBxPTAuMDEnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydSZWZlcmVyJ10gPSAnaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2FjY2Vzcy9hcGknCiAgICAgICAgICBlbmQKICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIENsYXNzOiAje2Rvd25sb2FkX3Jlc3AuYm9keS5jbGFzc30iCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBTdGF0dXM6ICN7ZG93bmxvYWRfcmVzcC5zdGF0dXN9IiBpZiBkb3dubG9hZF9yZXNwLnJlc3BvbmRfdG8/KDpzdGF0dXMpCiAgICAgICAgICAKICAgICAgICAgIGlmIGRvd25sb2FkX3Jlc3AuYm9keSAmJiAhZG93bmxvYWRfcmVzcC5ib2R5LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKQogICAgICAgICAgICAgaWYgZG93bmxvYWRfcmVzcC5ib2R5LmlzX2E/KEhhc2gpCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHlbJ2tleUNvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHlbJ2NvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHkuZGlnKCdkYXRhJywgJ2F0dHJpYnV0ZXMnLCAncHJpdmF0ZUtleScpCiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHkKICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgCiAgICAgICAgICAgICBpZiBwOF9jb250ZW50ICYmIHA4X2NvbnRlbnQudG9fcy5zdGFydF93aXRoPygnLS0tLS1CRUdJTicpCiAgICAgICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJldHJpZXZhbCB2aWEgI3twYXRofSBzdWNjZXNzZnVsISBDb250ZW50IGxlbmd0aDogI3twOF9jb250ZW50LnRvX3MubGVuZ3RofSIKICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgZnJvbSAje3BhdGh9IGRpZCBub3QgY29udGFpbiBhIHZhbGlkIHByaXZhdGUga2V5LiIKICAgICAgICAgICAgICAgcDhfY29udGVudCA9IG5pbAogICAgICAgICAgICAgZW5kCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBmcm9tICN7cGF0aH0gZW1wdHkgb3IgY29udGFpbnMgZXJyb3JzLiIKICAgICAgICAgIGVuZAogICAgICAgIHJlc2N1ZSA9PiBlCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBBdHRlbXB0IGZvciAje3BhdGh9IGZhaWxlZDogI3tlLm1lc3NhZ2V9IgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAoKICAgICMgRklOQUwgVkFMSURBVElPTjogRW5zdXJlIGl0J3Mgbm90IGEgUnVieSBoYXNoIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBlcnJvcgogICAgaWYgcDhfY29udGVudC5pc19hPyhIYXNoKSB8fCBwOF9jb250ZW50LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKSB8fCAhcDhfY29udGVudC50b19zLnN0YXJ0X3dpdGg/KCctLS0tLUJFR0lOJykKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogSW52YWxpZCBrZXkgY29udGVudCBkZXRlY3RlZC4iCiAgICAgIHA4X2NvbnRlbnQgPSBuaWwKICAgIGVuZAoKICAgIGlmIHA4X2NvbnRlbnQubmlsPwogICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGYWlsZWQgdG8gcmV0cmlldmUga2V5IGNvbnRlbnQuIgogICAgZW5kCiAgICAKICAgIHJlc3VsdCA9IHsKICAgICAgaWQ6IGtleV9kYXRhWydpZCddLAogICAgICBuYW1lOiBhdHRyWyduaWNrbmFtZSddIHx8IGF0dHJbJ25hbWUnXSwKICAgICAgaXNzdWVySWQ6IGF0dHJbJ2lzc3VlcklkJ10sCiAgICAgIGtleUNvbnRlbnQ6IHA4X2NvbnRlbnQsCiAgICAgIHJhd19yZXNwb25zZTogcmVzcG9uc2UuYm9keSAjIEluY2x1ZGUgdGhpcyBmb3IgZGVidWdnaW5nIHdoZW4ga2V5Q29udGVudCBpcyBuaWwKICAgIH0KICAgIAogICAgcHV0cyAiX19fTUFDSF9KU09OX1NUQVJUX19fIiArIHJlc3VsdC50b19qc29uICsgIl9fX01BQ0hfSlNPTl9FTkRfX18iCiAgcmVzY3VlID0+IGUKICAgICRzdGRlcnIucHV0cyAiRVJST1I6ICN7ZS5tZXNzYWdlfSIKICAgIGlmIGRlZmluZWQ/KHJlc3BvbnNlKSAmJiByZXNwb25zZSAmJiByZXNwb25zZS5ib2R5CiAgICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGRlbGV0ZV9rZXkoaWQpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgY2xpZW50LnJlcXVlc3QoOmRlbGV0ZSwgIi9pcmlzL3YxL2FwaUtleXMvI3tpZH0iKQogICAgcHV0cyAiU1VDQ0VTUyIKICByZXNjdWUgPT4gZQogICAgJHN0ZGVyci5wdXRzICJFUlJPUjogI3tlLm1lc3NhZ2V9IgogICAgZXhpdCAxCiAgZW5kCmVuZAoKY29tbWFuZCA9IEFSR1ZbMF0KaWYgY29tbWFuZCA9PSAnbGlzdCcKICBsaXN0X2tleXMKZWxzaWYgY29tbWFuZCA9PSAndGVhbXMnCiAgbGlzdF90ZWFtcwplbHNpZiBjb21tYW5kID09ICdjcmVhdGUnCiAgY3JlYXRlX2tleShBUkdWWzFdIHx8ICJNYWNoIEFQSSBLZXkgI3tUaW1lLm5vdy50b19pfSIpCmVsc2lmIGNvbW1hbmQgPT0gJ2RlbGV0ZScKICBkZWxldGVfa2V5KEFSR1ZbMV0pCmVuZAo=";function Jt(){let e=Se.join(qt.tmpdir(),A.nameLower);de.existsSync(e)||de.mkdirSync(e,{recursive:!0});let t=Se.join(e,"manage_asc_keys.rb");return de.writeFileSync(t,Buffer.from(Cr,"base64").toString("utf-8"),{mode:493}),t}function Yt(){return rt()}function en(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 On(e){return ht(e).appStoreConnectTeamId}function Dn(e,t,n){return{...Yt(),FASTLANE_USER:e,FASTLANE_TEAM_ID:t,...n?{FASTLANE_ITC_TEAM_ID:n,FASTLANE_ASC_TEAM_ID:n}:{}}}function ot(e,t="production",n={}){let i=ht(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 Bn(e,t){if(t.id){e.submit||(e.submit={}),e.submit.production||(e.submit.production={}),e.submit.production.ios||(e.submit.production.ios={}),e.submit.production.ios.appStoreConnectTeamId=t.id,e.submit.production.ios.providerId=t.id,t.name&&(e.submit.production.ios.appStoreConnectTeamName=t.name,e.submit.production.ios.providerName=t.name),t.developerTeamName&&(e.submit.production.ios.appleTeamName=t.developerTeamName);try{de.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}}async function br(e,t,n,i){let r=At();r.start("Fetching App Store Connect providers...");let o=It("ruby",[e,"teams"],{env:Dn(n,i),stdio:["inherit","pipe","pipe"],encoding:"utf-8"});if(o.status!==0){r.stop("Could not fetch providers");let d=en(`${o.stdout||""}
3
+ ${o.stderr||""}`);if(d.length>0)return zt(t,d,"Select the App Store Connect provider for this API key:");ne.warn(ie.yellow(`Could not list App Store Connect providers: ${o.stderr||"Unknown error"}`));return}let s=(o.stdout||"").match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!s){r.stop("Could not parse providers");return}let a=JSON.parse(s[1]),c=(a.teams||[]).filter(d=>d.id&&d.name);if(r.stop(c.length===1?"Found 1 provider":`Found ${c.length} providers`),c.length===0)return;if(c.length===1){ne.success(ie.green(`\u2713 Using App Store Connect provider ${c[0].name} (${c[0].id})`));let d={...c[0],developerTeamName:a.developerTeamName};return Bn(t,d),d}let l=c.filter(d=>d.recommended),p=c.filter(d=>!d.recommended);return zt(t,[...l,...p],`Select the App Store Connect provider for Developer Team ${a.developerTeamName||i}:`,a.developerTeamName)}async function zt(e,t,n,i){let r=await st({message:n,options:t.map(c=>({value:c.id,label:c.name,hint:`${c.id}${c.recommended?" \xB7 recommended":""}`}))});if(ge(r))return xe("Operation cancelled"),null;let o=r,a={...t.find(c=>c.id===o)||{id:o,name:o},developerTeamName:i};return Bn(e,a),ne.success(ie.green(`\u2713 Using App Store Connect provider ${a.name} (${a.id})`)),a}var Vn=async e=>{let t=At(),n=e.platform,i=`./${A.configFileName}`;if(!de.existsSync(i)){ne.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(de.readFileSync(i,"utf-8")),{projectId:o}=r,s=e.profile||"production";if(!o){ne.error(`${A.configFileName} is missing projectId.`);return}let a=e.file,c=n==="android"?e.packageName||e.bundleId:e.bundleId||Ge(r,s)||"*";if(n==="android"&&!c&&(c=await wr(o,r,s),c===null))return;if(n==="ios"&&!a){let u=await st({message:"Manage App Store Connect API Key:",options:[{value:"magic",label:"\u2728 Create new automatically",hint:"Requires Apple ID + 2FA"},{value:"manual",label:"\u{1F50D} Configure manually",hint:"Provide existing .p8 file"},{value:"delete",label:"\u{1F5D1}\uFE0F Delete an existing Key"}]});if(ge(u)){xe("Operation cancelled");return}if(u==="magic"){await Er(o,r);return}if(u==="delete"){await Pr(o,r);return}}if(!a){let u=n==="ios"?"https://appstoreconnect.apple.com/access/api":"https://console.cloud.google.com/apis/credentials";Rt(`To submit to the ${n==="ios"?"App Store":"Google Play Store"}, you need a Service Key:
4
4
 
5
5
  1. Open: ${ie.cyan(u)}
6
6
  `+(n==="ios"?`2. Generate an "App Store Connect API Key" with ${ie.bold("Admin")} role.
7
7
  3. Download the ${ie.bold(".p8")} file.`:`2. Create a "Service Account", generate a ${ie.bold("JSON")} key.
8
- 3. Download the ${ie.bold(".json")} file.`),"Guided Setup"),t.start("Scanning for downloaded keys...");let h=Pr(n);if(t.stop(h.length>0?`Detected ${h.length} potential key(s)`:"No keys detected automatically"),h.length>0){let f=await st({message:"Found these potential keys. Use one of them?",options:[...h.map(v=>({value:v.path,label:`${Se.basename(v.path)} (${v.location})`})),{value:"manual",label:"Enter path manually..."}]});if(ge(f)){xe("Operation cancelled");return}f!=="manual"&&(a=f)}if(!a){let f=await Be({message:`Paste the path to your ${n==="ios"?".p8":".json"} file:`,validate:v=>de.existsSync(v)?void 0:"File not found"});if(ge(f)){xe("Operation cancelled");return}a=f}}let l=e.issuerId,p=e.keyId;if(n==="ios"){if(!p&&a){let u=Se.basename(a).match(/AuthKey_(.*)\.p8/);u&&(p=u[1],ne.info(`Auto-detected Key ID from filename: ${ie.green(p)}`))}if(!l){let u=await Be({message:"Enter App Store Connect Issuer ID (Found on the Keys page):",validate:h=>h.length>0?void 0:"Issuer ID is required"});if(ge(u)){xe("Operation cancelled");return}l=u}if(!p){let u=await Be({message:"Enter App Store Connect Key ID:",validate:h=>h.length>0?void 0:"Key ID is required"});if(ge(u)){xe("Operation cancelled");return}p=u}}if(n==="android"&&(!c||c==="*")){let u=await Wn();if(u===null)return;c=u}let d=n==="ios"?ot(r,s):{};await Qt(o,a,n,l,p,c,{...d})};async function br(e,t,n){let i=await wr(e),r=Sr(t,n);if(r&&!i.includes(r)&&i.unshift(r),i.length>0){let o=await st({message:"Select Android package for this Google Play service key:",options:[...i.map(s=>({value:s,label:s,hint:s===r?"from config":void 0})),{value:"manual",label:"Enter another package name..."}]});if(ge(o))return xe("Operation cancelled"),null;if(o==="manual")return Wn();if(o!=="manual")return o}if(r){let o=await Tn({message:`Use Android package from local config (${r})?`,initialValue:!0});if(ge(o))return xe("Operation cancelled"),null;if(o)return r}}async function Wn(){let e=await Be({message:"Android package name for this Google Play service key:",placeholder:"com.example.app",validate:t=>t.includes(".")?void 0:"Enter a valid package name"});return ge(e)?(xe("Operation cancelled"),null):e}async function wr(e){try{let n=(await Z.get(`/credentials/${e}`)).data.credentials||[],i=new Set;for(let r of n)(r.platform==="android"||r.type==="android_keystore"||r.type==="google_service_account")&&r.bundleId&&r.bundleId!=="*"&&i.add(r.bundleId);return Array.from(i).sort()}catch(t){return ne.warn(ie.yellow(`Could not fetch saved Android package identifiers: ${t.message}`)),[]}}function Sr(e,t){let n=it(e,t);if(n)return n;let i=Se.join(process.cwd(),"app.json");if(de.existsSync(i))try{return JSON.parse(de.readFileSync(i,"utf-8")).expo?.android?.package}catch{}let r=Se.join(process.cwd(),"app.config.json");if(de.existsSync(r))try{let o=JSON.parse(de.readFileSync(r,"utf-8"));return o.expo?.android?.package||o.android?.package}catch{}}async function vr(e,t){let n=At(),i=t.submit?.production?.ios?.appleId,r=ot(t).teamId,o=On(t);if(!i){let c=await Be({message:"Apple ID:",placeholder:"your-email@example.com"});if(ge(c))return;i=c}if(!r){let c=await yt({appleId:i,config:t,profile:"production",initialTeam:ot(t),promptToPersistConfig:!0});if(!c?.teamId)return;r=c.teamId}let s=await Be({message:"Enter a name for the new API Key:",initialValue:`[${A.name}] Project ${e}`});if(ge(s))return;let a=Jt();if(!de.existsSync(a)){ne.error(`Magic Error: Helper script not found at ${a}`);return}try{let c=await Cr(a,t,i,r);if(c===null)return;let l;if(c)l=c,o=c.id;else if(!o)return;n.start("Creating App Store Connect API Key...");let p=N=>It("ruby",[a,"create",s],{env:Dn(i,r,N),stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),d=p(o),u=d.stdout||"",h=d.stderr||"";if(d.status!==0){let N=en(`${u}
9
- ${h}`);if(N.length>0){n.stop("Select App Store Connect team"),Rt(`Apple Developer Team IDs look like ${ie.bold(r)}.
10
- App Store Connect API keys use a numeric provider/team ID instead.`,"Team ID mismatch");let $=await zt(t,N,"Select the App Store Connect provider for this API key:");if(!$)return;l=$,o=$.id,n.start("Creating API Key with selected App Store Connect team..."),d=p(o),u=d.stdout||"",h=d.stderr||""}}if(h&&(h.includes("DEBUG:")||h.includes("ERROR:"))&&h.split(`
11
- `).forEach(N=>{N.trim()&&ne.info(ie.dim(`[Ruby] ${N.trim()}`))}),d.status!==0){n.stop("Failed"),ne.error(`Magic creation failed: ${h}`);return}let f=u.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!f){n.stop("Parse Error"),ne.error("Could not parse response from Apple Portal.");return}let v=JSON.parse(f[1]),{id:b,issuerId:R,keyContent:k}=v,y=ot(t,"production",{teamId:r,teamName:l?.developerTeamName,developerTeamId:r,appStoreConnectTeamId:o,providerId:o,providerName:l?.name});if(n.stop("Key Created Successfully"),ne.success(`\u2713 Created Key ID: ${ie.green(b)}`),!R){Rt(`Your Issuer ID is shown at the top of:
8
+ 3. Download the ${ie.bold(".json")} file.`),"Guided Setup"),t.start("Scanning for downloaded keys...");let h=Nr(n);if(t.stop(h.length>0?`Detected ${h.length} potential key(s)`:"No keys detected automatically"),h.length>0){let f=await st({message:"Found these potential keys. Use one of them?",options:[...h.map(v=>({value:v.path,label:`${Se.basename(v.path)} (${v.location})`})),{value:"manual",label:"Enter path manually..."}]});if(ge(f)){xe("Operation cancelled");return}f!=="manual"&&(a=f)}if(!a){let f=await Be({message:`Paste the path to your ${n==="ios"?".p8":".json"} file:`,validate:v=>de.existsSync(v)?void 0:"File not found"});if(ge(f)){xe("Operation cancelled");return}a=f}}let l=e.issuerId,p=e.keyId;if(n==="ios"){if(!p&&a){let u=Se.basename(a).match(/AuthKey_(.*)\.p8/);u&&(p=u[1],ne.info(`Auto-detected Key ID from filename: ${ie.green(p)}`))}if(!l){let u=await Be({message:"Enter App Store Connect Issuer ID (Found on the Keys page):",validate:h=>h.length>0?void 0:"Issuer ID is required"});if(ge(u)){xe("Operation cancelled");return}l=u}if(!p){let u=await Be({message:"Enter App Store Connect Key ID:",validate:h=>h.length>0?void 0:"Key ID is required"});if(ge(u)){xe("Operation cancelled");return}p=u}}if(n==="android"&&(!c||c==="*")){let u=await Wn();if(u===null)return;c=u}let d=n==="ios"?ot(r,s):{};await Qt(o,a,n,l,p,c,{...d})};async function wr(e,t,n){let i=await Sr(e),r=vr(t,n);if(r&&!i.includes(r)&&i.unshift(r),i.length>0){let o=await st({message:"Select Android package for this Google Play service key:",options:[...i.map(s=>({value:s,label:s,hint:s===r?"from config":void 0})),{value:"manual",label:"Enter another package name..."}]});if(ge(o))return xe("Operation cancelled"),null;if(o==="manual")return Wn();if(o!=="manual")return o}if(r){let o=await Tn({message:`Use Android package from local config (${r})?`,initialValue:!0});if(ge(o))return xe("Operation cancelled"),null;if(o)return r}}async function Wn(){let e=await Be({message:"Android package name for this Google Play service key:",placeholder:"com.example.app",validate:t=>t.includes(".")?void 0:"Enter a valid package name"});return ge(e)?(xe("Operation cancelled"),null):e}async function Sr(e){try{let n=(await Z.get(`/credentials/${e}`)).data.credentials||[],i=new Set;for(let r of n)(r.platform==="android"||r.type==="android_keystore"||r.type==="google_service_account")&&r.bundleId&&r.bundleId!=="*"&&i.add(r.bundleId);return Array.from(i).sort()}catch(t){return ne.warn(ie.yellow(`Could not fetch saved Android package identifiers: ${t.message}`)),[]}}function vr(e,t){let n=it(e,t);if(n)return n;let i=Se.join(process.cwd(),"app.json");if(de.existsSync(i))try{return JSON.parse(de.readFileSync(i,"utf-8")).expo?.android?.package}catch{}let r=Se.join(process.cwd(),"app.config.json");if(de.existsSync(r))try{let o=JSON.parse(de.readFileSync(r,"utf-8"));return o.expo?.android?.package||o.android?.package}catch{}}async function Er(e,t){let n=At(),i=t.submit?.production?.ios?.appleId,r=ot(t).teamId,o=On(t);if(!i){let c=await Be({message:"Apple ID:",placeholder:"your-email@example.com"});if(ge(c))return;i=c}if(!r){let c=await yt({appleId:i,config:t,profile:"production",initialTeam:ot(t),promptToPersistConfig:!0});if(!c?.teamId)return;r=c.teamId}let s=await Be({message:"Enter a name for the new API Key:",initialValue:`[${A.name}] Project ${e}`});if(ge(s))return;let a=Jt();if(!de.existsSync(a)){ne.error(`Magic Error: Helper script not found at ${a}`);return}try{let c=await br(a,t,i,r);if(c===null)return;let l;if(c)l=c,o=c.id;else if(!o)return;n.start("Creating App Store Connect API Key...");let p=R=>It("ruby",[a,"create",s],{env:Dn(i,r,R),stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),d=p(o),u=d.stdout||"",h=d.stderr||"";if(d.status!==0){let R=en(`${u}
9
+ ${h}`);if(R.length>0){n.stop("Select App Store Connect team"),Rt(`Apple Developer Team IDs look like ${ie.bold(r)}.
10
+ App Store Connect API keys use a numeric provider/team ID instead.`,"Team ID mismatch");let $=await zt(t,R,"Select the App Store Connect provider for this API key:");if(!$)return;l=$,o=$.id,n.start("Creating API Key with selected App Store Connect team..."),d=p(o),u=d.stdout||"",h=d.stderr||""}}if(h&&(h.includes("DEBUG:")||h.includes("ERROR:"))&&h.split(`
11
+ `).forEach(R=>{R.trim()&&ne.info(ie.dim(`[Ruby] ${R.trim()}`))}),d.status!==0){n.stop("Failed"),ne.error(`Magic creation failed: ${h}`);return}let f=u.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!f){n.stop("Parse Error"),ne.error("Could not parse response from Apple Portal.");return}let v=JSON.parse(f[1]),{id:b,issuerId:x,keyContent:N}=v,I=ot(t,"production",{teamId:r,teamName:l?.developerTeamName,developerTeamId:r,appStoreConnectTeamId:o,providerId:o,providerName:l?.name});if(n.stop("Key Created Successfully"),ne.success(`\u2713 Created Key ID: ${ie.green(b)}`),!x){Rt(`Your Issuer ID is shown at the top of:
12
12
  ${ie.cyan("https://appstoreconnect.apple.com/access/integrations/api")}
13
13
 
14
- It looks like: ${ie.dim("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")}`,"One More Thing");let N=await Be({message:"Enter your App Store Connect Issuer ID:",validate:$=>$.trim().length>0?void 0:"Issuer ID is required"});if(ge(N)){xe("Operation cancelled.");return}R=N.trim()}if(k){let N=Se.join(qt.tmpdir(),`AuthKey_${b}.p8`);de.writeFileSync(N,k),await Qt(e,N,"ios",R,b,t.ios?.bundleIdentifier||"*",{...y}),de.unlinkSync(N)}else{ne.warn(ie.yellow("\u26A0\uFE0F Apple did not return the private key in the response.")),Rt(`Download the .p8 file manually:
14
+ It looks like: ${ie.dim("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")}`,"One More Thing");let R=await Be({message:"Enter your App Store Connect Issuer ID:",validate:$=>$.trim().length>0?void 0:"Issuer ID is required"});if(ge(R)){xe("Operation cancelled.");return}x=R.trim()}if(N){let R=Se.join(qt.tmpdir(),`AuthKey_${b}.p8`);de.writeFileSync(R,N),await Qt(e,R,"ios",x,b,t.ios?.bundleIdentifier||"*",{...I}),de.unlinkSync(R)}else{ne.warn(ie.yellow("\u26A0\uFE0F Apple did not return the private key in the response.")),Rt(`Download the .p8 file manually:
15
15
 
16
16
  1. Open: ${ie.cyan("https://appstoreconnect.apple.com/access/integrations/api")}
17
17
  2. Find Key ID: ${ie.green(b)}
18
18
  3. Click ${ie.bold("Download API Key")} (only available once)
19
- 4. Drag & drop the downloaded .p8 file below`,"Manual Step Required");let N=await Be({message:"Path to the downloaded .p8 file (drag & drop here):",validate:$=>de.existsSync($)?void 0:"File not found"});if(ge(N)){xe("Operation cancelled. Credential ID was registered but key content is missing.");return}await Qt(e,N,"ios",R,b,t.ios?.bundleIdentifier||"*",{...y})}}catch(c){n.stop("Error"),ne.error(`Error: ${c.message}`)}}async function Er(e,t){let n=At(),i=t.submit?.production?.ios?.appleId,r=ot(t).teamId,o=On(t);if(!i){let a=await Be({message:"Apple ID:"});if(ge(a))return;i=a}if(!r){let a=await yt({appleId:i,config:t,profile:"production",initialTeam:ot(t),promptToPersistConfig:!0});if(!a?.teamId)return;r=a.teamId}n.start("Fetching existing API Keys...");let s=Jt();if(!de.existsSync(s)){ne.error(`Magic Error: Helper script not found at ${s}`);return}try{let a=f=>It("ruby",[s,"list"],{env:{...Yt(),FASTLANE_USER:i,FASTLANE_TEAM_ID:r,...f?{FASTLANE_ITC_TEAM_ID:f,FASTLANE_ASC_TEAM_ID:f}:{}},stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),c=a(o);if(c.status!==0){let f=en(`${c.stdout||""}
20
- ${c.stderr||""}`);if(f.length>0){n.stop("Select App Store Connect team");let v=await st({message:"Select the App Store Connect team to list API keys:",options:f.map(b=>({value:b.id,label:b.name,hint:b.id}))});if(ge(v)){xe("Operation cancelled");return}o=v,n.start("Fetching existing API Keys..."),c=a(o)}}if(c.status!==0){n.stop("Failed"),ne.error(`Listing failed: ${c.stderr}`);return}let l=c.stdout.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!l){n.stop("Parse Error");return}let p=JSON.parse(l[1]);if(n.stop(`Found ${p.length} keys`),p.length===0){ne.info("No API Keys found on this team.");return}let d=await st({message:"Select a key to delete from Apple Developer Portal:",options:[...p.map(f=>({value:f.id,label:`ID: ${f.id} - ${f.name} (${f.role})`})),{value:"cancel",label:"Cancel"}]});if(ge(d)||d==="cancel")return;let u=await Tn({message:`Are you sure you want to delete Key ${d}? This cannot be undone.`});if(!u||ge(u))return;n.start(`Deleting Key ${d}...`);let h=It("ruby",[Jt(),"delete",d],{env:{...Yt(),FASTLANE_USER:i,FASTLANE_TEAM_ID:r,...o?{FASTLANE_ITC_TEAM_ID:o,FASTLANE_ASC_TEAM_ID:o}:{}},stdio:"pipe",encoding:"utf-8"});h.status===0?(n.stop("Deleted"),ne.success(`\u2713 Key ${d} has been removed from Apple Portal.`)):(n.stop("Deletion Failed"),ne.error(`Error: ${h.stderr}`))}catch(a){n.stop("Error"),ne.error(`Error: ${a.message}`)}}async function Qt(e,t,n,i,r,o="*",s={}){let a=At();a.start(`Uploading Service Credentials for ${n}...`);try{let c=n==="ios"?"asc_api_key":"google_service_account",l=new URL(import.meta.url),p=Se.dirname(l.pathname),d=[Se.join(p,"isolated-upload.js"),Se.join(p,"commands","isolated-upload.js"),Se.resolve(p,"../commands/isolated-upload.js"),Se.resolve(process.cwd(),`node_modules/.bin/${A.nameLower}-upload`)],u="";for(let f of d)if(de.existsSync(f)){u=f;break}if(!u)throw new Error("Could not locate isolated-upload.js. Ensure the CLI is properly installed.");let h=It("node",[u,e,t,c,o,"service","undefined","undefined",i||"undefined",r||"undefined","undefined","undefined","undefined",s.teamId||"undefined",s.teamName||"undefined",s.developerTeamId||"undefined",s.appStoreConnectTeamId||"undefined",s.providerId||"undefined",s.providerName||"undefined"],{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(h.status!==0){let f=h.stderr||h.stdout||"Unknown upload failure";a.stop("Upload Failed"),ne.error(ie.red(`Upload Failed: ${f}`));return}h.stdout.includes("SUCCESS")?(a.stop("Upload Success"),ne.success(ie.green(`\u2713 Service Credentials for ${n} uploaded successfully.`))):(a.stop("Upload Summary"),ne.warn(ie.yellow(`Upload finished but success not confirmed: ${h.stdout}`)))}catch(c){a.stop("Upload Error"),ne.error(ie.red(`Error: ${c.message}`))}}function Pr(e){let t=e==="ios"?".p8":".json",n=[],i=[{path:"./",label:"Project Root"},{path:Se.join(qt.homedir(),"Downloads"),label:"Downloads"}];for(let r of i)if(de.existsSync(r.path))try{let o=de.readdirSync(r.path);for(let s of o)if(s.endsWith(t)){if(e==="android"&&!de.readFileSync(Se.join(r.path,s),"utf8").includes("service_account")||e==="ios"&&!s.startsWith("AuthKey"))continue;n.push({path:Se.join(r.path,s),location:r.label})}}catch{}return n}import{spinner as _t}from"@clack/prompts";import q from"chalk";import{spawnSync as Qo}from"child_process";import le from"fs";import Ae from"path";import H from"fs";import te from"path";var Nr={expo:["src/app/_layout.tsx","src/app/_layout.ts","src/app/_layout.jsx","src/app/_layout.js","app/_layout.tsx","app/_layout.ts","app/_layout.jsx","app/_layout.js","src/App.tsx","src/App.ts","src/App.jsx","src/App.js","App.tsx","App.ts","App.jsx","App.js"],"react-native":["index.ts","index.tsx","index.js","index.jsx","src/index.ts","src/index.tsx","src/index.js","src/index.jsx","App.tsx","App.ts","App.jsx","App.js","src/App.tsx","src/App.ts","src/App.jsx","src/App.js"]};function Pe(e,t){return te.relative(e,t).split(te.sep).join("/")}function Rr(e,t){return t.find(n=>H.existsSync(te.join(e,n)))}function kr(e,t){return t.split(te.sep).join("/").startsWith("src/")?te.join(e,"src"):e}function xr(e){return e.endsWith(".ts")||e.endsWith(".tsx")}function $r(e,t){let n=t.replace(/\.(?:tsx?|jsx?)$/,""),i=te.relative(te.dirname(e),n).split(te.sep).join("/");return i.startsWith(".")||(i=`./${i}`),i}function _r(e,t){let n=H.readFileSync(e,"utf8");if(n.includes("MACH Push setup")||/(?:from\s+)?['"][^'"]*mach-push['"]/.test(n))return!1;let i=$r(e,t);return H.writeFileSync(e,`import '${i}'; // MACH Push setup
21
- ${n}`),!0}function Fr(e,t){let n={projectId:e.projectId};return e.appId&&e.publishableKey&&(n.appId=e.appId,n.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!=="https://mach-api.securejs.in"&&(n.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(n.environment=e.environment),`// Generated by \`mach push setup\`. Re-run the command to refresh.
19
+ 4. Drag & drop the downloaded .p8 file below`,"Manual Step Required");let R=await Be({message:"Path to the downloaded .p8 file (drag & drop here):",validate:$=>de.existsSync($)?void 0:"File not found"});if(ge(R)){xe("Operation cancelled. Credential ID was registered but key content is missing.");return}await Qt(e,R,"ios",x,b,t.ios?.bundleIdentifier||"*",{...I})}}catch(c){n.stop("Error"),ne.error(`Error: ${c.message}`)}}async function Pr(e,t){let n=At(),i=t.submit?.production?.ios?.appleId,r=ot(t).teamId,o=On(t);if(!i){let a=await Be({message:"Apple ID:"});if(ge(a))return;i=a}if(!r){let a=await yt({appleId:i,config:t,profile:"production",initialTeam:ot(t),promptToPersistConfig:!0});if(!a?.teamId)return;r=a.teamId}n.start("Fetching existing API Keys...");let s=Jt();if(!de.existsSync(s)){ne.error(`Magic Error: Helper script not found at ${s}`);return}try{let a=f=>It("ruby",[s,"list"],{env:{...Yt(),FASTLANE_USER:i,FASTLANE_TEAM_ID:r,...f?{FASTLANE_ITC_TEAM_ID:f,FASTLANE_ASC_TEAM_ID:f}:{}},stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),c=a(o);if(c.status!==0){let f=en(`${c.stdout||""}
20
+ ${c.stderr||""}`);if(f.length>0){n.stop("Select App Store Connect team");let v=await st({message:"Select the App Store Connect team to list API keys:",options:f.map(b=>({value:b.id,label:b.name,hint:b.id}))});if(ge(v)){xe("Operation cancelled");return}o=v,n.start("Fetching existing API Keys..."),c=a(o)}}if(c.status!==0){n.stop("Failed"),ne.error(`Listing failed: ${c.stderr}`);return}let l=c.stdout.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!l){n.stop("Parse Error");return}let p=JSON.parse(l[1]);if(n.stop(`Found ${p.length} keys`),p.length===0){ne.info("No API Keys found on this team.");return}let d=await st({message:"Select a key to delete from Apple Developer Portal:",options:[...p.map(f=>({value:f.id,label:`ID: ${f.id} - ${f.name} (${f.role})`})),{value:"cancel",label:"Cancel"}]});if(ge(d)||d==="cancel")return;let u=await Tn({message:`Are you sure you want to delete Key ${d}? This cannot be undone.`});if(!u||ge(u))return;n.start(`Deleting Key ${d}...`);let h=It("ruby",[Jt(),"delete",d],{env:{...Yt(),FASTLANE_USER:i,FASTLANE_TEAM_ID:r,...o?{FASTLANE_ITC_TEAM_ID:o,FASTLANE_ASC_TEAM_ID:o}:{}},stdio:"pipe",encoding:"utf-8"});h.status===0?(n.stop("Deleted"),ne.success(`\u2713 Key ${d} has been removed from Apple Portal.`)):(n.stop("Deletion Failed"),ne.error(`Error: ${h.stderr}`))}catch(a){n.stop("Error"),ne.error(`Error: ${a.message}`)}}async function Qt(e,t,n,i,r,o="*",s={}){let a=At();a.start(`Uploading Service Credentials for ${n}...`);try{let c=n==="ios"?"asc_api_key":"google_service_account",l=new URL(import.meta.url),p=Se.dirname(l.pathname),d=[Se.join(p,"isolated-upload.js"),Se.join(p,"commands","isolated-upload.js"),Se.resolve(p,"../commands/isolated-upload.js"),Se.resolve(process.cwd(),`node_modules/.bin/${A.nameLower}-upload`)],u="";for(let f of d)if(de.existsSync(f)){u=f;break}if(!u)throw new Error("Could not locate isolated-upload.js. Ensure the CLI is properly installed.");let h=It("node",[u,e,t,c,o,"service","undefined","undefined",i||"undefined",r||"undefined","undefined","undefined","undefined",s.teamId||"undefined",s.teamName||"undefined",s.developerTeamId||"undefined",s.appStoreConnectTeamId||"undefined",s.providerId||"undefined",s.providerName||"undefined"],{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(h.status!==0){let f=h.stderr||h.stdout||"Unknown upload failure";a.stop("Upload Failed"),ne.error(ie.red(`Upload Failed: ${f}`));return}h.stdout.includes("SUCCESS")?(a.stop("Upload Success"),ne.success(ie.green(`\u2713 Service Credentials for ${n} uploaded successfully.`))):(a.stop("Upload Summary"),ne.warn(ie.yellow(`Upload finished but success not confirmed: ${h.stdout}`)))}catch(c){a.stop("Upload Error"),ne.error(ie.red(`Error: ${c.message}`))}}function Nr(e){let t=e==="ios"?".p8":".json",n=[],i=[{path:"./",label:"Project Root"},{path:Se.join(qt.homedir(),"Downloads"),label:"Downloads"}];for(let r of i)if(de.existsSync(r.path))try{let o=de.readdirSync(r.path);for(let s of o)if(s.endsWith(t)){if(e==="android"&&!de.readFileSync(Se.join(r.path,s),"utf8").includes("service_account")||e==="ios"&&!s.startsWith("AuthKey"))continue;n.push({path:Se.join(r.path,s),location:r.label})}}catch{}return n}import{spinner as _t}from"@clack/prompts";import q from"chalk";import{spawnSync as qo}from"child_process";import le from"fs";import Ae from"path";import K from"fs";import te from"path";var Rr={expo:["src/app/_layout.tsx","src/app/_layout.ts","src/app/_layout.jsx","src/app/_layout.js","app/_layout.tsx","app/_layout.ts","app/_layout.jsx","app/_layout.js","src/App.tsx","src/App.ts","src/App.jsx","src/App.js","App.tsx","App.ts","App.jsx","App.js"],"react-native":["index.ts","index.tsx","index.js","index.jsx","src/index.ts","src/index.tsx","src/index.js","src/index.jsx","App.tsx","App.ts","App.jsx","App.js","src/App.tsx","src/App.ts","src/App.jsx","src/App.js"]};function Pe(e,t){return te.relative(e,t).split(te.sep).join("/")}function kr(e,t){return t.find(n=>K.existsSync(te.join(e,n)))}function xr(e,t){return t.split(te.sep).join("/").startsWith("src/")?te.join(e,"src"):e}function $r(e){return e.endsWith(".ts")||e.endsWith(".tsx")}function _r(e,t){let n=t.replace(/\.(?:tsx?|jsx?)$/,""),i=te.relative(te.dirname(e),n).split(te.sep).join("/");return i.startsWith(".")||(i=`./${i}`),i}function Fr(e,t){let n=K.readFileSync(e,"utf8");if(n.includes("MACH Push setup")||/(?:from\s+)?['"][^'"]*mach-push['"]/.test(n))return!1;let i=_r(e,t);return K.writeFileSync(e,`import '${i}'; // MACH Push setup
21
+ ${n}`),!0}function Tr(e,t){let n={projectId:e.projectId};return e.appId&&e.publishableKey&&(n.appId=e.appId,n.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!=="https://mach-api.securejs.in"&&(n.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(n.environment=e.environment),`// Generated by \`mach push setup\`. Re-run the command to refresh.
22
22
  // Public client configuration only. Provider credentials are never written here.
23
23
  ${t?`import type { MachPushConfig } from '@radhya/mach-push-react-native';
24
24
  `:""}
25
25
 
26
26
  export const machPushConfig${t?": MachPushConfig":""} = ${JSON.stringify(n,null,2)};
27
- `}function Tr(e,t){return t?`/**
27
+ `}function Or(e,t){return t?`/**
28
28
  * MACH Push application hooks.
29
29
  *
30
30
  * This file belongs to your app and is never overwritten by
@@ -137,7 +137,7 @@ export function startMachPush() {
137
137
  // The basic experience works immediately. Remove this line if your product
138
138
  // asks for notification permission at a later, contextual moment.
139
139
  void startMachPush()?.catch(() => undefined);
140
- `}function Zn(e,t,n){let i=[],r=[],o=Rr(e,Nr[t]);if(!o)return{written:i,notes:["Could not locate the application entry point. Import the generated mach-push file once from your root App or layout."]};let s=te.join(e,o),a=kr(e,o),c=xr(o)?"ts":"js",l=c==="ts",p=te.join(a,`mach-push.generated.${c}`),d=te.join(a,`mach-push.${c}`);return H.mkdirSync(a,{recursive:!0}),H.writeFileSync(p,Fr(n,l)),i.push(Pe(e,p)),H.existsSync(d)?r.push(`${Pe(e,d)} already exists; developer callbacks were preserved.`):(H.writeFileSync(d,Tr("./mach-push.generated",l)),i.push(Pe(e,d))),_r(s,d)?i.push(Pe(e,s)):r.push(`${Pe(e,s)} already starts MACH Push.`),{written:i,notes:r,editableFile:Pe(e,d),generatedFile:Pe(e,p),entryFile:Pe(e,s)}}function Mn(e,t){if(!H.existsSync(e))return[];let n=[];for(let i of H.readdirSync(e,{withFileTypes:!0})){if(i.name==="Pods"||i.name==="build")continue;let r=te.join(e,i.name);i.isDirectory()?n.push(...Mn(r,t)):t(r)&&n.push(r)}return n}function Or(e,t){if(H.mkdirSync(te.dirname(e),{recursive:!0}),!H.existsSync(e)){H.writeFileSync(e,`<?xml version="1.0" encoding="UTF-8"?>
140
+ `}function Zn(e,t,n){let i=[],r=[],o=kr(e,Rr[t]);if(!o)return{written:i,notes:["Could not locate the application entry point. Import the generated mach-push file once from your root App or layout."]};let s=te.join(e,o),a=xr(e,o),c=$r(o)?"ts":"js",l=c==="ts",p=te.join(a,`mach-push.generated.${c}`),d=te.join(a,`mach-push.${c}`);return K.mkdirSync(a,{recursive:!0}),K.writeFileSync(p,Tr(n,l)),i.push(Pe(e,p)),K.existsSync(d)?r.push(`${Pe(e,d)} already exists; developer callbacks were preserved.`):(K.writeFileSync(d,Or("./mach-push.generated",l)),i.push(Pe(e,d))),Fr(s,d)?i.push(Pe(e,s)):r.push(`${Pe(e,s)} already starts MACH Push.`),{written:i,notes:r,editableFile:Pe(e,d),generatedFile:Pe(e,p),entryFile:Pe(e,s)}}function Mn(e,t){if(!K.existsSync(e))return[];let n=[];for(let i of K.readdirSync(e,{withFileTypes:!0})){if(i.name==="Pods"||i.name==="build")continue;let r=te.join(e,i.name);i.isDirectory()?n.push(...Mn(r,t)):t(r)&&n.push(r)}return n}function Dr(e,t){if(K.mkdirSync(te.dirname(e),{recursive:!0}),!K.existsSync(e)){K.writeFileSync(e,`<?xml version="1.0" encoding="UTF-8"?>
141
141
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
142
142
  <plist version="1.0">
143
143
  <dict>
@@ -145,22 +145,22 @@ void startMachPush()?.catch(() => undefined);
145
145
  <string>${t}</string>
146
146
  </dict>
147
147
  </plist>
148
- `);return}let n=H.readFileSync(e,"utf8"),i=/(<key>aps-environment<\/key>\s*<string>)([^<]*)(<\/string>)/;if(i.test(n)){H.writeFileSync(e,n.replace(i,`$1${t}$3`));return}n.includes("</dict>")&&H.writeFileSync(e,n.replace("</dict>",` <key>aps-environment</key>
148
+ `);return}let n=K.readFileSync(e,"utf8"),i=/(<key>aps-environment<\/key>\s*<string>)([^<]*)(<\/string>)/;if(i.test(n)){K.writeFileSync(e,n.replace(i,`$1${t}$3`));return}n.includes("</dict>")&&K.writeFileSync(e,n.replace("</dict>",` <key>aps-environment</key>
149
149
  <string>${t}</string>
150
- </dict>`))}function Dr(e,t,n){let i=[],r=[],o=te.join(e,"ios");if(!H.existsSync(o))return r.push("iOS native project is not present; no APNs entitlement was changed."),{written:i,notes:r};let a=Mn(o,p=>p.endsWith(".xcodeproj/project.pbxproj"))[0];if(!a)return r.push("Could not locate an iOS Xcode project for the APNs entitlement."),{written:i,notes:r};let c=H.readFileSync(a,"utf8"),l=Array.from(c.matchAll(/CODE_SIGN_ENTITLEMENTS\s*=\s*"?([^";$]+\.entitlements)"?;/g),p=>p[1].trim());if(l.length===0&&t){let p=te.basename(te.dirname(a),".xcodeproj"),u=[H.existsSync(te.join(o,p))?p:"",`${p}.entitlements`].filter(Boolean).join("/"),h=!1;c=c.replace(/buildSettings = \{([\s\S]*?)\n(\s*)\};/g,(f,v,b)=>!new RegExp(`PRODUCT_BUNDLE_IDENTIFIER\\s*=\\s*"?${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"?;`).test(v)||v.includes("CODE_SIGN_ENTITLEMENTS")?f:(h=!0,f.replace(/(\n\s*PRODUCT_BUNDLE_IDENTIFIER\s*=)/,`
151
- ${b} CODE_SIGN_ENTITLEMENTS = ${u};$1`))),h&&(H.writeFileSync(a,c),i.push(Pe(e,a)),l.push(u))}if(l.length===0)return r.push("Could not safely identify the iOS app target. Enable the Push Notifications capability in Xcode."),{written:i,notes:r};for(let p of new Set(l)){let d=te.join(o,p);Or(d,n),i.push(Pe(e,d))}return r.push(`iOS APNs entitlement is configured for ${n}.`),{written:[...new Set(i)],notes:r}}function Br(e,t){let n=H.readFileSync(e,"utf8");if(n.includes("com.google.gms.google-services"))return!1;let i=/plugins\s*\{/.exec(n);if(i?.index!==void 0){let r=t?` id("com.google.gms.google-services")
150
+ </dict>`))}function Br(e,t,n){let i=[],r=[],o=te.join(e,"ios");if(!K.existsSync(o))return r.push("iOS native project is not present; no APNs entitlement was changed."),{written:i,notes:r};let a=Mn(o,p=>p.endsWith(".xcodeproj/project.pbxproj"))[0];if(!a)return r.push("Could not locate an iOS Xcode project for the APNs entitlement."),{written:i,notes:r};let c=K.readFileSync(a,"utf8"),l=Array.from(c.matchAll(/CODE_SIGN_ENTITLEMENTS\s*=\s*"?([^";$]+\.entitlements)"?;/g),p=>p[1].trim());if(l.length===0&&t){let p=te.basename(te.dirname(a),".xcodeproj"),u=[K.existsSync(te.join(o,p))?p:"",`${p}.entitlements`].filter(Boolean).join("/"),h=!1;c=c.replace(/buildSettings = \{([\s\S]*?)\n(\s*)\};/g,(f,v,b)=>!new RegExp(`PRODUCT_BUNDLE_IDENTIFIER\\s*=\\s*"?${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"?;`).test(v)||v.includes("CODE_SIGN_ENTITLEMENTS")?f:(h=!0,f.replace(/(\n\s*PRODUCT_BUNDLE_IDENTIFIER\s*=)/,`
151
+ ${b} CODE_SIGN_ENTITLEMENTS = ${u};$1`))),h&&(K.writeFileSync(a,c),i.push(Pe(e,a)),l.push(u))}if(l.length===0)return r.push("Could not safely identify the iOS app target. Enable the Push Notifications capability in Xcode."),{written:i,notes:r};for(let p of new Set(l)){let d=te.join(o,p);Dr(d,n),i.push(Pe(e,d))}return r.push(`iOS APNs entitlement is configured for ${n}.`),{written:[...new Set(i)],notes:r}}function Vr(e,t){let n=K.readFileSync(e,"utf8");if(n.includes("com.google.gms.google-services"))return!1;let i=/plugins\s*\{/.exec(n);if(i?.index!==void 0){let r=t?` id("com.google.gms.google-services")
152
152
  `:` id 'com.google.gms.google-services'
153
- `,o=i.index+i[0].length;H.writeFileSync(e,`${n.slice(0,o)}
153
+ `,o=i.index+i[0].length;K.writeFileSync(e,`${n.slice(0,o)}
154
154
  ${r}${n.slice(o)}`)}else{let r=t?`
155
155
  apply(plugin = "com.google.gms.google-services")
156
156
  `:`
157
157
  apply plugin: "com.google.gms.google-services"
158
- `;H.writeFileSync(e,`${n.trimEnd()}${r}`)}return!0}function Vr(e){let t=["settings.gradle.kts","settings.gradle"].map(a=>te.join(e,a)).find(a=>H.existsSync(a));if(t){let a=H.readFileSync(t,"utf8");if(a.includes("com.google.gms.google-services"))return;let c=/plugins\s*\{/.exec(a);if(c?.index!==void 0){let p=t.endsWith(".kts")?` id("com.google.gms.google-services") version "4.4.4" apply false
158
+ `;K.writeFileSync(e,`${n.trimEnd()}${r}`)}return!0}function Wr(e){let t=["settings.gradle.kts","settings.gradle"].map(a=>te.join(e,a)).find(a=>K.existsSync(a));if(t){let a=K.readFileSync(t,"utf8");if(a.includes("com.google.gms.google-services"))return;let c=/plugins\s*\{/.exec(a);if(c?.index!==void 0){let p=t.endsWith(".kts")?` id("com.google.gms.google-services") version "4.4.4" apply false
159
159
  `:` id "com.google.gms.google-services" version "4.4.4" apply false
160
- `,d=c.index+c[0].length;return H.writeFileSync(t,`${a.slice(0,d)}
161
- ${p}${a.slice(d)}`),t}}let n=["build.gradle.kts","build.gradle"].map(a=>te.join(e,a)).find(a=>H.existsSync(a));if(!n)return;let i=H.readFileSync(n,"utf8");if(i.includes("com.google.gms:google-services"))return;let r=/dependencies\s*\{/.exec(i);if(r?.index===void 0)return;let o=` classpath("com.google.gms:google-services:4.4.4")
162
- `,s=r.index+r[0].length;return H.writeFileSync(n,`${i.slice(0,s)}
163
- ${o}${i.slice(s)}`),n}function Wr(e,t){let n=[],i=[],r=te.join(e,"android");if(!H.existsSync(r))return i.push("Android native project is not present; no Firebase configuration was changed."),{written:n,notes:i};if(!t)return i.push("Android needs google-services.json. Add it at the project root and re-run mach push setup."),{written:n,notes:i};let o=te.resolve(e,t);if(!H.existsSync(o))return i.push(`Android Firebase file was not found at ${t}; re-run setup with --google-services-file.`),{written:n,notes:i};let s=te.join(r,"app/google-services.json");H.mkdirSync(te.dirname(s),{recursive:!0}),o!==s&&(H.copyFileSync(o,s),n.push(Pe(e,s)));let a=["build.gradle.kts","build.gradle"].map(l=>te.join(r,"app",l)).find(l=>H.existsSync(l));if(!a)return i.push("Could not locate android/app/build.gradle to enable Firebase."),{written:n,notes:i};Br(a,a.endsWith(".kts"))&&n.push(Pe(e,a));let c=Vr(r);return c&&n.push(Pe(e,c)),i.push("Android Firebase configuration and notification permission are wired."),{written:[...new Set(n)],notes:i}}function jn(e,t){let n=Dr(e,t.iosBundleId,t.iosEnvironment),i=Wr(e,t.googleServicesFile);return{written:[...new Set([...n.written,...i.written])],notes:[...n.notes,...i.notes]}}import{spinner as xt,log as S,isCancel as $t,confirm as Io,select as pn}from"@clack/prompts";import w from"chalk";import C from"fs";import I from"path";import{execFileSync as Me,execSync as J,spawn as ai}from"child_process";import he from"os";import Ao from"crypto";import Lr from"crypto";import{log as Ne}from"@clack/prompts";import Re from"chalk";import{execSync as Zr}from"child_process";import ke from"fs";import Ue from"path";var Gn={id:"expo",displayName:"Expo",applyLocalProcessEnv:e=>{e.developmentClient?(Ne.info(Re.blue("\u2139\uFE0F Configuring Expo build to INCLUDE expo-dev-client (Development Client mode)...")),delete process.env.EXPO_NO_DEV_CLIENT,delete process.env.EXPO_AUTOLINKING_EXCLUDE):(Ne.info(Re.blue("\u2139\uFE0F Configuring Expo build to EXCLUDE expo-dev-client (Production/Staging mode)...")),process.env.EXPO_NO_DEV_CLIENT="1",process.env.EXPO_AUTOLINKING_EXCLUDE="expo-dev-client")},localAndroidEnv:(e,t)=>({EXPO_NO_DOTENV:"1",MACH_FRAMEWORK:"expo",MACH_BUILD_PROFILE:t}),remoteEnvSetupScript:()=>`
160
+ `,d=c.index+c[0].length;return K.writeFileSync(t,`${a.slice(0,d)}
161
+ ${p}${a.slice(d)}`),t}}let n=["build.gradle.kts","build.gradle"].map(a=>te.join(e,a)).find(a=>K.existsSync(a));if(!n)return;let i=K.readFileSync(n,"utf8");if(i.includes("com.google.gms:google-services"))return;let r=/dependencies\s*\{/.exec(i);if(r?.index===void 0)return;let o=` classpath("com.google.gms:google-services:4.4.4")
162
+ `,s=r.index+r[0].length;return K.writeFileSync(n,`${i.slice(0,s)}
163
+ ${o}${i.slice(s)}`),n}function Zr(e,t){let n=[],i=[],r=te.join(e,"android");if(!K.existsSync(r))return i.push("Android native project is not present; no Firebase configuration was changed."),{written:n,notes:i};if(!t)return i.push("Android needs google-services.json. Add it at the project root and re-run mach push setup."),{written:n,notes:i};let o=te.resolve(e,t);if(!K.existsSync(o))return i.push(`Android Firebase file was not found at ${t}; re-run setup with --google-services-file.`),{written:n,notes:i};let s=te.join(r,"app/google-services.json");K.mkdirSync(te.dirname(s),{recursive:!0}),o!==s&&(K.copyFileSync(o,s),n.push(Pe(e,s)));let a=["build.gradle.kts","build.gradle"].map(l=>te.join(r,"app",l)).find(l=>K.existsSync(l));if(!a)return i.push("Could not locate android/app/build.gradle to enable Firebase."),{written:n,notes:i};Vr(a,a.endsWith(".kts"))&&n.push(Pe(e,a));let c=Wr(r);return c&&n.push(Pe(e,c)),i.push("Android Firebase configuration and notification permission are wired."),{written:[...new Set(n)],notes:i}}function jn(e,t){let n=Br(e,t.iosBundleId,t.iosEnvironment),i=Zr(e,t.googleServicesFile);return{written:[...new Set([...n.written,...i.written])],notes:[...n.notes,...i.notes]}}import{spinner as xt,log as S,isCancel as $t,confirm as Ao,select as pn}from"@clack/prompts";import w from"chalk";import C from"fs";import y from"path";import{execFileSync as Me,execSync as J,spawn as ai}from"child_process";import he from"os";import Co from"crypto";import Xr from"crypto";import{log as Ne}from"@clack/prompts";import Re from"chalk";import{execSync as Mr}from"child_process";import ke from"fs";import Ue from"path";var Gn={id:"expo",displayName:"Expo",applyLocalProcessEnv:e=>{e.developmentClient?(Ne.info(Re.blue("\u2139\uFE0F Configuring Expo build to INCLUDE expo-dev-client (Development Client mode)...")),delete process.env.EXPO_NO_DEV_CLIENT,delete process.env.EXPO_AUTOLINKING_EXCLUDE):(Ne.info(Re.blue("\u2139\uFE0F Configuring Expo build to EXCLUDE expo-dev-client (Production/Staging mode)...")),process.env.EXPO_NO_DEV_CLIENT="1",process.env.EXPO_AUTOLINKING_EXCLUDE="expo-dev-client")},localAndroidEnv:(e,t)=>({EXPO_NO_DOTENV:"1",MACH_FRAMEWORK:"expo",MACH_BUILD_PROFILE:t}),remoteEnvSetupScript:()=>`
164
164
  export MACH_FRAMEWORK="expo"
165
165
  echo "[ENV] MACH_FRAMEWORK=$MACH_FRAMEWORK"
166
166
  export EXPO_NO_DOTENV="\${EXPO_NO_DOTENV:-1}"
@@ -255,7 +255,7 @@ fi
255
255
  echo "expo.enableHermes=true" >> gradle.properties
256
256
  `,androidRemoteReleaseGradlePropertiesScript:()=>`
257
257
  echo "expo.enableProguardInReleaseBuilds=true" >> gradle.properties
258
- `,prepareLocalProject:async e=>{let{platform:t,options:n,appRoot:i,cacheMeta:r,cacheMetaDir:o,currentBuildEnv:s,reportStep:a,loggedRun:c,configureXcodeNodeBinary:l,podsFingerprint:p,writeCacheMeta:d}=e,u=n.iosBundleIdentifier||"",h=n.name||"",f=Ue.join(i,"app.json"),v=null;Ne.info(Re.blue(`Running Expo prebuild for ${t}...`));try{if(ke.existsSync(f)){v=ke.readFileSync(f,"utf-8");let R=JSON.parse(v);R.expo=R.expo||{},h||(h=R.expo.name||""),t==="ios"&&!u&&(u=R.expo?.ios?.bundleIdentifier||""),n.name&&(R.expo.name=n.name),n.scheme&&(R.expo.scheme=n.scheme),t==="ios"&&n.iosBundleIdentifier?(R.expo.ios=R.expo.ios||{},R.expo.ios.bundleIdentifier=n.iosBundleIdentifier):t==="android"&&n.androidPackage&&(R.expo.android=R.expo.android||{},R.expo.android.package=n.androidPackage),ke.writeFileSync(f,JSON.stringify(R,null,2))}let b=["exec","--","expo","prebuild","--platform",t,"--no-install"];if(await a("prebuild"),await c("npm",b,i,s()),t!=="ios"||!ke.existsSync(Ue.join(i,"ios")))return{appName:h,bundleId:u};await a("pods"),Ne.info(Re.blue("Running pod install..."));try{let R=Ue.join(i,"ios"),k=Ue.join(R,"Podfile");if(!ke.existsSync(k))throw new Error("ios/Podfile not found. Skipping pod install.");let y=s();l(R,y);let N=ke.readFileSync(k,"utf-8"),$=n.iosDeploymentTarget||"13.4";if(!n.developmentClient&&(Ne.info(Re.blue("\u2139\uFE0F Patching Podfile to EXCLUDE expo-dev-client...")),N.includes("use_expo_modules!")&&!N.includes("exclude:"))){let T=/use_expo_modules!(\s*)$/m;T.test(N)?N=N.replace(T,'use_expo_modules!(exclude: ["expo-dev-client"])$1'):N=N.replace("use_expo_modules!",'use_expo_modules!(exclude: ["expo-dev-client"])')}let G=`
258
+ `,prepareLocalProject:async e=>{let{platform:t,options:n,appRoot:i,cacheMeta:r,cacheMetaDir:o,currentBuildEnv:s,reportStep:a,loggedRun:c,configureXcodeNodeBinary:l,podsFingerprint:p,writeCacheMeta:d}=e,u=n.iosBundleIdentifier||"",h=n.name||"",f=Ue.join(i,"app.json"),v=null;Ne.info(Re.blue(`Running Expo prebuild for ${t}...`));try{if(ke.existsSync(f)){v=ke.readFileSync(f,"utf-8");let x=JSON.parse(v);x.expo=x.expo||{},h||(h=x.expo.name||""),t==="ios"&&!u&&(u=x.expo?.ios?.bundleIdentifier||""),n.name&&(x.expo.name=n.name),n.scheme&&(x.expo.scheme=n.scheme),t==="ios"&&n.iosBundleIdentifier?(x.expo.ios=x.expo.ios||{},x.expo.ios.bundleIdentifier=n.iosBundleIdentifier):t==="android"&&n.androidPackage&&(x.expo.android=x.expo.android||{},x.expo.android.package=n.androidPackage),ke.writeFileSync(f,JSON.stringify(x,null,2))}let b=["exec","--","expo","prebuild","--platform",t,"--no-install"];if(await a("prebuild"),await c("npm",b,i,s()),t!=="ios"||!ke.existsSync(Ue.join(i,"ios")))return{appName:h,bundleId:u};await a("pods"),Ne.info(Re.blue("Running pod install..."));try{let x=Ue.join(i,"ios"),N=Ue.join(x,"Podfile");if(!ke.existsSync(N))throw new Error("ios/Podfile not found. Skipping pod install.");let I=s();l(x,I);let R=ke.readFileSync(N,"utf-8"),$=n.iosDeploymentTarget||"13.4";if(!n.developmentClient&&(Ne.info(Re.blue("\u2139\uFE0F Patching Podfile to EXCLUDE expo-dev-client...")),R.includes("use_expo_modules!")&&!R.includes("exclude:"))){let T=/use_expo_modules!(\s*)$/m;T.test(R)?R=R.replace(T,'use_expo_modules!(exclude: ["expo-dev-client"])$1'):R=R.replace("use_expo_modules!",'use_expo_modules!(exclude: ["expo-dev-client"])')}let G=`
259
259
  installer.generated_projects.each do |project|
260
260
  project.targets.each do |target|
261
261
  target.build_configurations.each do |config|
@@ -268,13 +268,13 @@ echo "expo.enableProguardInReleaseBuilds=true" >> gradle.properties
268
268
  config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${$}'
269
269
  end
270
270
  end
271
- `,V=/post_install\s+do\s+\|installer\|/;if(V.test(N))Ne.info(Re.dim(`Injecting deployment target (${$}) into existing post_install hook...`)),N=N.replace(V,`post_install do |installer|
272
- ${G}`),ke.writeFileSync(k,N);else{Ne.info(Re.dim(`Appending new post_install hook for deployment target (${$})...`));let T=`
271
+ `,V=/post_install\s+do\s+\|installer\|/;if(V.test(R))Ne.info(Re.dim(`Injecting deployment target (${$}) into existing post_install hook...`)),R=R.replace(V,`post_install do |installer|
272
+ ${G}`),ke.writeFileSync(N,R);else{Ne.info(Re.dim(`Appending new post_install hook for deployment target (${$})...`));let T=`
273
273
  post_install do |installer|
274
274
  ${G}
275
275
  end
276
- `;ke.appendFileSync(k,T)}let B="/opt/homebrew/bin/pod",F=ke.existsSync(B)?B:"pod",K=p(R);ke.existsSync(Ue.join(R,"Pods"))&&r.pods&&r.pods!==K&&(await e.reportLog(`[CACHE] Podfile/Podfile.lock changed \u2014 wiping ios/Pods
277
- `),Ne.info(Re.dim("Podfile fingerprint changed \u2014 clearing Pods for clean install...")),ke.rmSync(Ue.join(R,"Pods"),{recursive:!0,force:!0})),Ne.info(Re.dim(`Using pod command: ${F} in ${R}`)),await c(F,["install"],R,y),r.pods=K,d(o,r)}catch(R){let k=R.message||"Unknown error";Ne.warn(Re.yellow(`Native "pod" command failed: ${k}`)),Ne.info(Re.dim("Falling back to npm exec pod-install..."));let y=s();l(Ue.join(i,"ios"),y),Ne.info(Re.magenta(`${A.nameUpper}_DEBUG: Executing pod-install override via npx --yes pod-install@latest`)),await c("npx",["--yes","pod-install@latest","ios"],i,y)}if(ke.existsSync(Ue.join(i,"ios/Pods"))){Ne.info(Re.dim("Disabling signing for Pod targets to prevent conflicts..."));try{Zr(`find ios/Pods -name "project.pbxproj" -exec sed -i '' 's/buildSettings = {/buildSettings = { CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; PROVISIONING_PROFILE_SPECIFIER = ""; EXPANDED_CODE_SIGN_IDENTITY = "";/g' {} +`,{cwd:i,stdio:"ignore"})}catch{}}return{appName:h,bundleId:u}}finally{v&&ke.writeFileSync(f,v)}}};import{log as Xe}from"@clack/prompts";import He from"chalk";import We from"fs";import Ct from"path";import{spawnSync as Mr}from"child_process";import Ve from"fs";import Le from"path";var Un=(e,t)=>Le.join(e,"node_modules",".bin",process.platform==="win32"?`${t}.cmd`:t),jr=e=>{try{return JSON.parse(Ve.readFileSync(Le.join(e,"package.json"),"utf-8"))}catch{return{}}};function tc(e,t){let n=jr(e);return!!(n.dependencies?.[t]||n.devDependencies?.[t])}function tn(e,t,n,i={}){let r=`${t} ${n.join(" ")}`,o=Mr(t,n,{cwd:e,stdio:"inherit",env:{...process.env,CI:process.env.CI||"1",EXPO_NO_TELEMETRY:"1",...i}});return o.error?{ok:!1,command:r,error:o.error.message}:o.status!==0?{ok:!1,command:r,error:`${t} exited with code ${o.status}`}:{ok:!0,command:r}}function nc(e){return tn(e,"npx",["--yes","install-expo-modules@latest"])}function ic(e){let t=Un(e,"expo");return Ve.existsSync(t)?tn(e,t,["install","expo-updates"]):{ok:!1,command:"npx expo install expo-updates",error:"Expo Modules are not installed. Install Expo Modules first."}}function rc(e){let t=[];return Ve.existsSync(Le.join(e,"ios"))&&t.push("ios"),Ve.existsSync(Le.join(e,"android"))&&t.push("android"),t}function Ln(e){let t=Un(e.cwd,"expo-updates");return Ve.existsSync(t)?e.platforms.map(n=>tn(e.cwd,t,["configuration:syncnative","--platform",n,"--workflow","generic"],{MACH_OTA_RUNTIME_VERSION:e.runtimeVersion,MACH_OTA_CHANNEL:e.channel,MACH_OTA_URL:e.url})):[{ok:!1,command:"expo-updates configuration:syncnative",error:"expo-updates is not installed in this project."}]}function oc(e){let t=Le.join(e,"android","app","src","main","AndroidManifest.xml"),n=Le.join(e,"android","app","src","main","res","values","strings.xml"),i,r=Le.join(e,"ios");if(Ve.existsSync(r)){let o=[r];for(;o.length>0&&!i;){let s=o.shift();for(let a of Ve.readdirSync(s,{withFileTypes:!0})){if(a.name==="Pods"||a.name==="build")continue;let c=Le.join(s,a.name);if(a.isDirectory())o.push(c);else if(a.isFile()&&a.name==="Expo.plist"){i=c;break}}}}return{...Ve.existsSync(t)?{androidManifest:t}:{},...Ve.existsSync(n)?{androidStrings:n}:{},...i?{iosExpoPlist:i}:{}}}var Gr=(e,t)=>!We.existsSync(e)||!We.existsSync(t)?!1:We.readFileSync(e,"utf-8")!==We.readFileSync(t,"utf-8"),nn={id:"react-native",displayName:"React Native",applyLocalProcessEnv:e=>{delete process.env.EXPO_NO_DEV_CLIENT,delete process.env.EXPO_AUTOLINKING_EXCLUDE,delete process.env.EXPO_NO_DOTENV},localAndroidEnv:(e,t)=>({MACH_FRAMEWORK:"react-native",MACH_BUILD_PROFILE:t}),remoteEnvSetupScript:()=>`
276
+ `;ke.appendFileSync(N,T)}let D="/opt/homebrew/bin/pod",F=ke.existsSync(D)?D:"pod",U=p(x);ke.existsSync(Ue.join(x,"Pods"))&&r.pods&&r.pods!==U&&(await e.reportLog(`[CACHE] Podfile/Podfile.lock changed \u2014 wiping ios/Pods
277
+ `),Ne.info(Re.dim("Podfile fingerprint changed \u2014 clearing Pods for clean install...")),ke.rmSync(Ue.join(x,"Pods"),{recursive:!0,force:!0})),Ne.info(Re.dim(`Using pod command: ${F} in ${x}`)),await c(F,["install"],x,I),r.pods=U,d(o,r)}catch(x){let N=x.message||"Unknown error";Ne.warn(Re.yellow(`Native "pod" command failed: ${N}`)),Ne.info(Re.dim("Falling back to npm exec pod-install..."));let I=s();l(Ue.join(i,"ios"),I),Ne.info(Re.magenta(`${A.nameUpper}_DEBUG: Executing pod-install override via npx --yes pod-install@latest`)),await c("npx",["--yes","pod-install@latest","ios"],i,I)}if(ke.existsSync(Ue.join(i,"ios/Pods"))){Ne.info(Re.dim("Disabling signing for Pod targets to prevent conflicts..."));try{Mr(`find ios/Pods -name "project.pbxproj" -exec sed -i '' 's/buildSettings = {/buildSettings = { CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; PROVISIONING_PROFILE_SPECIFIER = ""; EXPANDED_CODE_SIGN_IDENTITY = "";/g' {} +`,{cwd:i,stdio:"ignore"})}catch{}}return{appName:h,bundleId:u}}finally{v&&ke.writeFileSync(f,v)}}};import{log as Xe}from"@clack/prompts";import He from"chalk";import We from"fs";import Ct from"path";import{spawnSync as jr}from"child_process";import Ve from"fs";import Le from"path";var Un=(e,t)=>Le.join(e,"node_modules",".bin",process.platform==="win32"?`${t}.cmd`:t),Gr=e=>{try{return JSON.parse(Ve.readFileSync(Le.join(e,"package.json"),"utf-8"))}catch{return{}}};function nc(e,t){let n=Gr(e);return!!(n.dependencies?.[t]||n.devDependencies?.[t])}function tn(e,t,n,i={}){let r=`${t} ${n.join(" ")}`,o=jr(t,n,{cwd:e,stdio:"inherit",env:{...process.env,CI:process.env.CI||"1",EXPO_NO_TELEMETRY:"1",...i}});return o.error?{ok:!1,command:r,error:o.error.message}:o.status!==0?{ok:!1,command:r,error:`${t} exited with code ${o.status}`}:{ok:!0,command:r}}function ic(e){return tn(e,"npx",["--yes","install-expo-modules@latest"])}function rc(e){let t=Un(e,"expo");return Ve.existsSync(t)?tn(e,t,["install","expo-updates"]):{ok:!1,command:"npx expo install expo-updates",error:"Expo Modules are not installed. Install Expo Modules first."}}function oc(e){let t=[];return Ve.existsSync(Le.join(e,"ios"))&&t.push("ios"),Ve.existsSync(Le.join(e,"android"))&&t.push("android"),t}function Ln(e){let t=Un(e.cwd,"expo-updates");return Ve.existsSync(t)?e.platforms.map(n=>tn(e.cwd,t,["configuration:syncnative","--platform",n,"--workflow","generic"],{MACH_OTA_RUNTIME_VERSION:e.runtimeVersion,MACH_OTA_CHANNEL:e.channel,MACH_OTA_URL:e.url})):[{ok:!1,command:"expo-updates configuration:syncnative",error:"expo-updates is not installed in this project."}]}function sc(e){let t=Le.join(e,"android","app","src","main","AndroidManifest.xml"),n=Le.join(e,"android","app","src","main","res","values","strings.xml"),i,r=Le.join(e,"ios");if(Ve.existsSync(r)){let o=[r];for(;o.length>0&&!i;){let s=o.shift();for(let a of Ve.readdirSync(s,{withFileTypes:!0})){if(a.name==="Pods"||a.name==="build")continue;let c=Le.join(s,a.name);if(a.isDirectory())o.push(c);else if(a.isFile()&&a.name==="Expo.plist"){i=c;break}}}}return{...Ve.existsSync(t)?{androidManifest:t}:{},...Ve.existsSync(n)?{androidStrings:n}:{},...i?{iosExpoPlist:i}:{}}}var Ur=(e,t)=>!We.existsSync(e)||!We.existsSync(t)?!1:We.readFileSync(e,"utf-8")!==We.readFileSync(t,"utf-8"),nn={id:"react-native",displayName:"React Native",applyLocalProcessEnv:e=>{delete process.env.EXPO_NO_DEV_CLIENT,delete process.env.EXPO_AUTOLINKING_EXCLUDE,delete process.env.EXPO_NO_DOTENV},localAndroidEnv:(e,t)=>({MACH_FRAMEWORK:"react-native",MACH_BUILD_PROFILE:t}),remoteEnvSetupScript:()=>`
278
278
  export MACH_FRAMEWORK="react-native"
279
279
  echo "[ENV] MACH_FRAMEWORK=$MACH_FRAMEWORK"
280
280
  unset EXPO_NO_DOTENV
@@ -307,53 +307,53 @@ fi
307
307
  :
308
308
  `,androidRemoteReleaseGradlePropertiesScript:()=>`
309
309
  :
310
- `,prepareLocalProject:async e=>{let{platform:t,appRoot:n,cacheMeta:i,cacheMetaDir:r,currentBuildEnv:o,reportStep:s,reportLog:a,loggedRun:c,configureXcodeNodeBinary:l,podsFingerprint:p,writeCacheMeta:d}=e,u=o(),h=u.MACH_OTA_RUNTIME_VERSION,f=u.MACH_OTA_CHANNEL,v=u.MACH_OTA_URL;if(h&&f&&v){let x=Ln({cwd:n,platforms:[t],runtimeVersion:h,channel:f,url:v}).find(T=>!T.ok);if(x)throw new Error(`Could not synchronize ${t} Expo Updates configuration: ${x.error||x.command}. Run \`mach ota setup --platform ${t}\` and try again.`);Xe.info(He.green(`\u2713 OTA runtime ${h} synchronized for ${t}`))}if(t!=="ios")return{};let b=Ct.join(n,"ios"),R=Ct.join(b,"Podfile");if(!We.existsSync(R))throw new Error("React Native iOS build requires ios/Podfile. Commit the ios directory for vanilla React Native projects.");await s("pods"),Xe.info(He.blue("Running React Native pod install..."));let k=o();l(b,k);let y=Ct.join(b,"Pods"),N=Ct.join(b,"Podfile.lock"),$=Ct.join(y,"Manifest.lock"),G=We.existsSync(y),V=p(b);G&&i.reactNativePods&&i.reactNativePods!==V?(await a(`[CACHE] React Native Podfile/Podfile.lock changed - wiping ios/Pods
311
- `),Xe.info(He.dim("React Native Podfile fingerprint changed - clearing Pods for clean install...")),We.rmSync(y,{recursive:!0,force:!0})):G&&Gr(N,$)&&(await a(`[CACHE] React Native Pods Manifest.lock is out of sync - wiping ios/Pods
312
- `),Xe.info(He.dim("React Native Pods manifest is out of sync - clearing Pods for clean install...")),We.rmSync(y,{recursive:!0,force:!0}));let B="/opt/homebrew/bin/pod",F=We.existsSync(B)?B:"pod";try{Xe.info(He.dim(`Using pod command: ${F} in ${b}`)),await c(F,["install"],b,k)}catch(K){let x=K.message||"Unknown error";Xe.warn(He.yellow(`Native "pod" command failed: ${x}`)),Xe.info(He.dim("Falling back to npx pod-install..."));let T=o();l(b,T),Xe.info(He.magenta(`${A.nameUpper}_DEBUG: Executing pod-install fallback via npx --yes pod-install@latest`)),await c("npx",["--yes","pod-install@latest","ios"],n,T)}return i.reactNativePods=p(b),d(r,i),{}}};var Ur={expo:Gn,"react-native":nn};function bt(e){if(!e)return nn;if(e!=="flutter")return Ur[e];throw new Error('Flutter builds are not implemented yet. Set framework to "expo" or "react-native" for this build.')}var Xr="mach-env-v3-project-layout",Hr=new Set(["BUILD_ID","BUILD_NUMBER","ANDROID_VERSION_CODE","MACH_TOKEN","MACH_DEBUG","MACH_S3_DEBUG","MACH_ENV_FINGERPRINT","CODEARTIFACT_AUTH_TOKEN","EXPO_ZQRN_BB_REPO_TOKEN","SENTRY_AUTH_TOKEN","IOS_DIST_P12","IOS_PROVISIONING_PROFILE","IOS_P12_PASSWORD","MATCH_ENCRYPTION_PASSPHRASE","MATCH_PASSWORD","MATCH_KEYCHAIN_NAME","MATCH_KEYCHAIN_PASSWORD","APPLE_TEAM_ID","FASTLANE_TEAM_ID","ANDROID_KEYSTORE","ANDROID_KEYSTORE_BASE64","ANDROID_STORE_PASSWORD","ANDROID_KEY_PASSWORD","ANDROID_KEY_ALIAS","KEYSTORE_PASSWORD","KEYSTORE_ALIAS","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","AWS_SECURITY_TOKEN","GITHUB_TOKEN","NPM_TOKEN"]),Kr=["PRESIGNED_","KEYSTORE_PASSWORD_"],Jr=e=>!e||Hr.has(e)?!1:!Kr.some(t=>e.startsWith(t)),rn=(e,t,n)=>{let i=bt(n.framework);return{...e,...i.localAndroidEnv(n,t),MACH_APP_NAME:n.appName||n.name||"App",MACH_APP_DIRECTORY:n.appDirectory||"."}},Xn=e=>{let t=Object.entries(e).filter(([n])=>Jr(n)).sort(([n],[i])=>n.localeCompare(i));return Lr.createHash("sha256").update(JSON.stringify({version:Xr,entries:t})).digest("hex")};var Yr=/^\d+(?:\.\d+){0,2}$/,zr="auto";var Hn=e=>typeof e=="string"&&e.trim().toLowerCase()===zr,Cc=(e,t,n,i=!0)=>e!=null&&String(e).trim()!==""?{kind:"persisted",value:e}:t!=null&&!Hn(t)?{kind:"explicit",value:t}:i&&(n||Hn(t))?{kind:"auto"}:{kind:"none"},wt=e=>{let t=String(e??"").trim();return!t||t==="undefined"||t==="null"?null:Yr.test(t)?t:null},at=(e,t)=>{let n=wt(e);if(!n)throw new Error(`Invalid iOS buildNumber from ${t}: "${String(e??"")}". Use one to three period-separated integers, for example "68" or "1.2.3".`);return n},Qr=e=>{if(typeof e=="string"&&!/^\d+$/.test(e.trim()))return null;let t=Number(e);return!Number.isSafeInteger(t)||t<1||t>21e8?null:String(t)},Te=(e,t)=>{let n=Qr(e);if(!n)throw new Error(`Invalid Android versionCode from ${t}: "${String(e??"")}". Use an integer from 1 to 2100000000.`);return n},bc=(e,t,n,i)=>{let r=at(n,i);return e.resolvedBuildNumber=r,t.BUILD_NUMBER=r,t.CURRENT_PROJECT_VERSION=r,t.MACH_IOS_BUILD_NUMBER_LOCKED="1",r},wc=(e,t,n,i)=>{let r=Te(n,i);return e.resolvedVersionCode=r,t.ANDROID_VERSION_CODE=r,t.MACH_ANDROID_VERSION_CODE_LOCKED="1",r},Sc=(e,t)=>{let n=t.buildNumber!==void 0&&t.buildNumber!==null&&String(t.buildNumber).trim()!=="",i=t.versionCode!==void 0&&t.versionCode!==null&&String(t.versionCode).trim()!=="";!e.resolvedBuildNumber&&n&&(e.resolvedBuildNumber=at(t.buildNumber,"saved MACH build record")),!e.resolvedVersionCode&&i&&(e.resolvedVersionCode=Te(t.versionCode,"saved MACH build record"))};import{execFileSync as on}from"child_process";import Ze from"fs";import Qe from"path";var qr=new Set(["Pods","build","DerivedData",".git"]),Kn=(e,t=[])=>{if(!Ze.existsSync(e))return t;for(let n of Ze.readdirSync(e,{withFileTypes:!0})){if(n.isSymbolicLink())continue;let i=Qe.join(e,n.name);if(n.isDirectory()){if(qr.has(n.name)||n.name.endsWith(".xcworkspace")||n.name.endsWith(".xcarchive")||n.name.endsWith(".framework")||n.name.endsWith(".xcframework")||n.name.endsWith(".bundle")||n.name.endsWith(".app")||n.name.endsWith(".appex"))continue;Kn(i,t);continue}n.isFile()&&n.name==="Info.plist"&&t.push(i)}return t},eo=(e,t,n)=>{let i=String(e||"").trim().replace(/^"|"$/g,"");if(!i||(i=i.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g,(o,s,a)=>{let l=t[s||a];return l===void 0?"":String(l)}),!i||i.includes("$(")||i.includes("${")))return null;let r=String(t.SRCROOT||t.PROJECT_DIR||n);return Qe.resolve(Qe.isAbsolute(i)?i:Qe.join(r,i))},to=e=>{let t=e.indexOf("["),n=e.lastIndexOf("]");if(t<0||n<t)return[];let i=JSON.parse(e.slice(t,n+1));return Array.isArray(i)?i:[]},no=(e,t)=>{let n=new Set,i=[];(t.workspace||t.project)&&i.push([...t.workspace?["-workspace",t.workspace]:["-project",t.project],"-scheme",t.scheme]),t.project&&i.push(["-project",t.project,"-alltargets"]);for(let r of i){let o="";try{o=on("xcodebuild",[...r,"-configuration",t.configuration,"-showBuildSettings","-json"],{cwd:e,encoding:"utf8",maxBuffer:16*1024*1024})}catch{continue}for(let s of to(o)){let a=s?.buildSettings;if(!a)continue;let c=String(a.WRAPPER_EXTENSION||"").toLowerCase();if(c!=="app"&&c!=="appex")continue;let l=eo(String(a.INFOPLIST_FILE||""),a,e);if(!l||!Ze.existsSync(l))continue;let p=Qe.relative(e,l);p.startsWith("..")||Qe.isAbsolute(p)||n.add(l)}}return[...n].sort()},io=(e,t)=>{let n=Ze.readFileSync(e,"utf8");if(!/<plist(?:\s|>)/.test(n))return!1;let r=/<key>\s*CFBundleVersion\s*<\/key>/.exec(n),o;if(r){let s=r.index+r[0].length,a=n.slice(s),c=/^\s*<(string|integer)>[\s\S]*?<\/\1>/.exec(a);if(!c)throw new Error(`Could not update CFBundleVersion in ${e}: unsupported plist value type.`);o=n.slice(0,s)+`
310
+ `,prepareLocalProject:async e=>{let{platform:t,appRoot:n,cacheMeta:i,cacheMetaDir:r,currentBuildEnv:o,reportStep:s,reportLog:a,loggedRun:c,configureXcodeNodeBinary:l,podsFingerprint:p,writeCacheMeta:d}=e,u=o(),h=u.MACH_OTA_RUNTIME_VERSION,f=u.MACH_OTA_CHANNEL,v=u.MACH_OTA_URL;if(h&&f&&v){let k=Ln({cwd:n,platforms:[t],runtimeVersion:h,channel:f,url:v}).find(T=>!T.ok);if(k)throw new Error(`Could not synchronize ${t} Expo Updates configuration: ${k.error||k.command}. Run \`mach ota setup --platform ${t}\` and try again.`);Xe.info(He.green(`\u2713 OTA runtime ${h} synchronized for ${t}`))}if(t!=="ios")return{};let b=Ct.join(n,"ios"),x=Ct.join(b,"Podfile");if(!We.existsSync(x))throw new Error("React Native iOS build requires ios/Podfile. Commit the ios directory for vanilla React Native projects.");await s("pods"),Xe.info(He.blue("Running React Native pod install..."));let N=o();l(b,N);let I=Ct.join(b,"Pods"),R=Ct.join(b,"Podfile.lock"),$=Ct.join(I,"Manifest.lock"),G=We.existsSync(I),V=p(b);G&&i.reactNativePods&&i.reactNativePods!==V?(await a(`[CACHE] React Native Podfile/Podfile.lock changed - wiping ios/Pods
311
+ `),Xe.info(He.dim("React Native Podfile fingerprint changed - clearing Pods for clean install...")),We.rmSync(I,{recursive:!0,force:!0})):G&&Ur(R,$)&&(await a(`[CACHE] React Native Pods Manifest.lock is out of sync - wiping ios/Pods
312
+ `),Xe.info(He.dim("React Native Pods manifest is out of sync - clearing Pods for clean install...")),We.rmSync(I,{recursive:!0,force:!0}));let D="/opt/homebrew/bin/pod",F=We.existsSync(D)?D:"pod";try{Xe.info(He.dim(`Using pod command: ${F} in ${b}`)),await c(F,["install"],b,N)}catch(U){let k=U.message||"Unknown error";Xe.warn(He.yellow(`Native "pod" command failed: ${k}`)),Xe.info(He.dim("Falling back to npx pod-install..."));let T=o();l(b,T),Xe.info(He.magenta(`${A.nameUpper}_DEBUG: Executing pod-install fallback via npx --yes pod-install@latest`)),await c("npx",["--yes","pod-install@latest","ios"],n,T)}return i.reactNativePods=p(b),d(r,i),{}}};var Lr={expo:Gn,"react-native":nn};function bt(e){if(!e)return nn;if(e!=="flutter")return Lr[e];throw new Error('Flutter builds are not implemented yet. Set framework to "expo" or "react-native" for this build.')}var Hr="mach-env-v3-project-layout",Kr=new Set(["BUILD_ID","BUILD_NUMBER","ANDROID_VERSION_CODE","MACH_TOKEN","MACH_DEBUG","MACH_S3_DEBUG","MACH_ENV_FINGERPRINT","CODEARTIFACT_AUTH_TOKEN","EXPO_ZQRN_BB_REPO_TOKEN","SENTRY_AUTH_TOKEN","IOS_DIST_P12","IOS_PROVISIONING_PROFILE","IOS_P12_PASSWORD","MATCH_ENCRYPTION_PASSPHRASE","MATCH_PASSWORD","MATCH_KEYCHAIN_NAME","MATCH_KEYCHAIN_PASSWORD","APPLE_TEAM_ID","FASTLANE_TEAM_ID","ANDROID_KEYSTORE","ANDROID_KEYSTORE_BASE64","ANDROID_STORE_PASSWORD","ANDROID_KEY_PASSWORD","ANDROID_KEY_ALIAS","KEYSTORE_PASSWORD","KEYSTORE_ALIAS","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","AWS_SECURITY_TOKEN","GITHUB_TOKEN","NPM_TOKEN"]),Jr=["PRESIGNED_","KEYSTORE_PASSWORD_"],Yr=e=>!e||Kr.has(e)?!1:!Jr.some(t=>e.startsWith(t)),rn=(e,t,n)=>{let i=bt(n.framework);return{...e,...i.localAndroidEnv(n,t),MACH_APP_NAME:n.appName||n.name||"App",MACH_APP_DIRECTORY:n.appDirectory||"."}},Xn=e=>{let t=Object.entries(e).filter(([n])=>Yr(n)).sort(([n],[i])=>n.localeCompare(i));return Xr.createHash("sha256").update(JSON.stringify({version:Hr,entries:t})).digest("hex")};var zr=/^\d+(?:\.\d+){0,2}$/,Qr="auto";var Hn=e=>typeof e=="string"&&e.trim().toLowerCase()===Qr,bc=(e,t,n,i=!0)=>e!=null&&String(e).trim()!==""?{kind:"persisted",value:e}:t!=null&&!Hn(t)?{kind:"explicit",value:t}:i&&(n||Hn(t))?{kind:"auto"}:{kind:"none"},wt=e=>{let t=String(e??"").trim();return!t||t==="undefined"||t==="null"?null:zr.test(t)?t:null},at=(e,t)=>{let n=wt(e);if(!n)throw new Error(`Invalid iOS buildNumber from ${t}: "${String(e??"")}". Use one to three period-separated integers, for example "68" or "1.2.3".`);return n},qr=e=>{if(typeof e=="string"&&!/^\d+$/.test(e.trim()))return null;let t=Number(e);return!Number.isSafeInteger(t)||t<1||t>21e8?null:String(t)},Te=(e,t)=>{let n=qr(e);if(!n)throw new Error(`Invalid Android versionCode from ${t}: "${String(e??"")}". Use an integer from 1 to 2100000000.`);return n},wc=(e,t,n,i)=>{let r=at(n,i);return e.resolvedBuildNumber=r,t.BUILD_NUMBER=r,t.CURRENT_PROJECT_VERSION=r,t.MACH_IOS_BUILD_NUMBER_LOCKED="1",r},Sc=(e,t,n,i)=>{let r=Te(n,i);return e.resolvedVersionCode=r,t.ANDROID_VERSION_CODE=r,t.MACH_ANDROID_VERSION_CODE_LOCKED="1",r},vc=(e,t)=>{let n=t.buildNumber!==void 0&&t.buildNumber!==null&&String(t.buildNumber).trim()!=="",i=t.versionCode!==void 0&&t.versionCode!==null&&String(t.versionCode).trim()!=="";!e.resolvedBuildNumber&&n&&(e.resolvedBuildNumber=at(t.buildNumber,"saved MACH build record")),!e.resolvedVersionCode&&i&&(e.resolvedVersionCode=Te(t.versionCode,"saved MACH build record"))};import{execFileSync as on}from"child_process";import Ze from"fs";import Qe from"path";var eo=new Set(["Pods","build","DerivedData",".git"]),Kn=(e,t=[])=>{if(!Ze.existsSync(e))return t;for(let n of Ze.readdirSync(e,{withFileTypes:!0})){if(n.isSymbolicLink())continue;let i=Qe.join(e,n.name);if(n.isDirectory()){if(eo.has(n.name)||n.name.endsWith(".xcworkspace")||n.name.endsWith(".xcarchive")||n.name.endsWith(".framework")||n.name.endsWith(".xcframework")||n.name.endsWith(".bundle")||n.name.endsWith(".app")||n.name.endsWith(".appex"))continue;Kn(i,t);continue}n.isFile()&&n.name==="Info.plist"&&t.push(i)}return t},to=(e,t,n)=>{let i=String(e||"").trim().replace(/^"|"$/g,"");if(!i||(i=i.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g,(o,s,a)=>{let l=t[s||a];return l===void 0?"":String(l)}),!i||i.includes("$(")||i.includes("${")))return null;let r=String(t.SRCROOT||t.PROJECT_DIR||n);return Qe.resolve(Qe.isAbsolute(i)?i:Qe.join(r,i))},no=e=>{let t=e.indexOf("["),n=e.lastIndexOf("]");if(t<0||n<t)return[];let i=JSON.parse(e.slice(t,n+1));return Array.isArray(i)?i:[]},io=(e,t)=>{let n=new Set,i=[];(t.workspace||t.project)&&i.push([...t.workspace?["-workspace",t.workspace]:["-project",t.project],"-scheme",t.scheme]),t.project&&i.push(["-project",t.project,"-alltargets"]);for(let r of i){let o="";try{o=on("xcodebuild",[...r,"-configuration",t.configuration,"-showBuildSettings","-json"],{cwd:e,encoding:"utf8",maxBuffer:16*1024*1024})}catch{continue}for(let s of no(o)){let a=s?.buildSettings;if(!a)continue;let c=String(a.WRAPPER_EXTENSION||"").toLowerCase();if(c!=="app"&&c!=="appex")continue;let l=to(String(a.INFOPLIST_FILE||""),a,e);if(!l||!Ze.existsSync(l))continue;let p=Qe.relative(e,l);p.startsWith("..")||Qe.isAbsolute(p)||n.add(l)}}return[...n].sort()},ro=(e,t)=>{let n=Ze.readFileSync(e,"utf8");if(!/<plist(?:\s|>)/.test(n))return!1;let r=/<key>\s*CFBundleVersion\s*<\/key>/.exec(n),o;if(r){let s=r.index+r[0].length,a=n.slice(s),c=/^\s*<(string|integer)>[\s\S]*?<\/\1>/.exec(a);if(!c)throw new Error(`Could not update CFBundleVersion in ${e}: unsupported plist value type.`);o=n.slice(0,s)+`
313
313
  <string>${t}</string>`+a.slice(c[0].length)}else{let s=n.lastIndexOf("</dict>");if(s<0)throw new Error(`Could not update CFBundleVersion in ${e}: root dictionary not found.`);o=n.slice(0,s)+` <key>CFBundleVersion</key>
314
314
  <string>${t}</string>
315
- `+n.slice(s)}return Ze.writeFileSync(e,o),!0},ro=(e,t)=>{if(!io(e,t)){if(process.platform!=="darwin")throw new Error(`Could not update binary Info.plist outside macOS: ${e}`);try{on("/usr/bin/plutil",["-replace","CFBundleVersion","-string",t,e])}catch{on("/usr/bin/plutil",["-insert","CFBundleVersion","-string",t,e])}}},Jn=(e,t,n)=>{let i=at(t,"resolved MACH build"),r=Qe.resolve(e),o=new Set;if(n)try{for(let l of no(r,n))o.add(l)}catch{}for(let l of Kn(r))o.add(l);let s=[...o].sort(),a=new Map,c=!1;try{for(let l of s)a.set(l,Ze.readFileSync(l)),ro(l,i)}catch(l){for(let[p,d]of a)Ze.writeFileSync(p,d);throw l}return{buildNumber:i,plistPaths:s,restore:()=>{if(!c){c=!0;for(let[l,p]of a)Ze.existsSync(l)&&Ze.writeFileSync(l,p)}}}},sn=(e,t,n)=>{let i=at(e,n),r=at(t,"resolved MACH build");if(i!==r)throw new Error(`iOS build number mismatch in ${n}: expected MACH buildNumber ${r}, but the artifact contains CFBundleVersion ${i}.`);return i};import{execFileSync as Yn}from"child_process";import St from"fs";import Ie from"path";import oo from"adm-zip";var an=(e,t)=>{let n=0n,i=0n,r=t;for(;r<e.length&&i<=63n;){let o=e[r++];if(n|=BigInt(o&127)<<i,(o&128)===0)return{value:n,next:r};i+=7n}throw new Error("Malformed protobuf varint")},vt=e=>{let t=[],n=0;for(;n<e.length;){let i=an(e,n);n=i.next;let r=Number(i.value>>3n),o=Number(i.value&7n);if(r<1)throw new Error("Malformed protobuf field number");if(o===0){let s=an(e,n);n=s.next,t.push({number:r,wireType:o,varint:s.value});continue}if(o===1){if(n+8>e.length)throw new Error("Truncated protobuf fixed64");t.push({number:r,wireType:o,bytes:e.subarray(n,n+8)}),n+=8;continue}if(o===2){let s=an(e,n);n=s.next;let a=Number(s.value);if(!Number.isSafeInteger(a)||n+a>e.length)throw new Error("Truncated protobuf length-delimited field");t.push({number:r,wireType:o,bytes:e.subarray(n,n+a)}),n+=a;continue}if(o===5){if(n+4>e.length)throw new Error("Truncated protobuf fixed32");t.push({number:r,wireType:o,bytes:e.subarray(n,n+4)}),n+=4;continue}throw new Error(`Unsupported protobuf wire type ${o}`)}return t},zn=(e,t)=>e.find(i=>i.number===t&&i.wireType===2)?.bytes?.toString("utf8"),so=e=>{let n=vt(e).find(o=>o.number===7&&o.wireType===2)?.bytes;if(!n)return null;let r=vt(n).find(o=>(o.number===6||o.number===7)&&o.wireType===0)?.varint;return r===void 0||r>BigInt(Number.MAX_SAFE_INTEGER)?null:r.toString()},ao=e=>{let n=vt(e).find(l=>l.number===1&&l.wireType===2)?.bytes;if(!n)throw new Error("AAB base manifest has no root XML element");let o=vt(n).filter(l=>l.number===4&&l.wireType===2).map(l=>vt(l.bytes)).find(l=>zn(l,2)==="versionCode");if(!o)throw new Error("AAB base manifest has no android:versionCode");let s=zn(o,3)?.trim();if(s&&/^\d+$/.test(s))return Te(s,"packaged AAB manifest");let a=o.find(l=>l.number===6&&l.wireType===2)?.bytes,c=a?so(a):null;return Te(c,"packaged AAB manifest")},Qn=e=>{try{return St.accessSync(e,St.constants.X_OK),St.statSync(e).isFile()}catch{return!1}},cn=e=>String(process.env.PATH||"").split(Ie.delimiter).filter(Boolean).map(t=>Ie.join(t,e)),qn=()=>Array.from(new Set([process.env.ANDROID_HOME,process.env.ANDROID_SDK_ROOT,process.platform==="darwin"?Ie.join(process.env.HOME||"","Library/Android/sdk"):Ie.join(process.env.HOME||"","Android/Sdk"),"/opt/android-sdk"].filter(e=>!!e))),ei=e=>{try{return St.readdirSync(e).map(t=>Ie.join(e,t)).filter(t=>St.statSync(t).isDirectory()).sort((t,n)=>n.localeCompare(t,void 0,{numeric:!0}))}catch{return[]}},co=()=>{let e=cn("apkanalyzer");for(let t of qn()){let n=Ie.join(t,"cmdline-tools");e.push(Ie.join(n,"latest/bin/apkanalyzer"));for(let i of ei(n))e.push(Ie.join(i,"bin/apkanalyzer"))}return e},lo=()=>{let e=[...cn("aapt2"),...cn("aapt")];for(let t of qn())for(let n of ei(Ie.join(t,"build-tools")))e.push(Ie.join(n,"aapt2"),Ie.join(n,"aapt"));return e},po=e=>{let t=e.trim();return/^\d+$/.test(t)?t:null},uo=e=>e.match(/^package:.*\bversionCode='(\d+)'/m)?.[1]||null,fo=(e,t)=>{let n=t.apkanalyzer??co();for(let r of n)if(Qn(r))try{let o=Yn(r,["manifest","version-code",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=po(o);if(s)return Te(s,"packaged APK manifest")}catch{}let i=t.aapt??lo();for(let r of i)if(Qn(r))try{let o=Yn(r,["dump","badging",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=uo(o);if(s)return Te(s,"packaged APK manifest")}catch{}throw new Error("Could not inspect the packaged APK versionCode. Install Android SDK command-line tools (apkanalyzer or aapt2) and rebuild; MACH will not publish an unverified artifact.")},mo=(e,t={})=>{let n=Ie.extname(e).toLowerCase();if(n===".apk")return fo(e,t);if(n!==".aab")throw new Error(`Unsupported Android artifact for version validation: ${e}`);let i;try{i=new oo(e)}catch(o){throw new Error(`Could not open AAB ${Ie.basename(e)}: ${o.message}`)}let r=i.getEntry("base/manifest/AndroidManifest.xml")||i.getEntries().find(o=>o.entryName.replace(/\\/g,"/")==="base/manifest/AndroidManifest.xml");if(!r)throw new Error(`AAB ${Ie.basename(e)} has no base module manifest`);try{return ao(r.getData())}catch(o){throw new Error(`Could not read versionCode from ${Ie.basename(e)}: ${o.message}`)}},ln=(e,t,n={})=>{let i=Te(t,"resolved MACH build assignment"),r=mo(e,n);if(r!==i)throw new Error(`Android versionCode mismatch in ${Ie.basename(e)}: expected ${i}, packaged ${r}. MACH stopped the build before upload.`);return r};import fe from"fs";import Q from"path";var dn=e=>{let t=Q.join(e,"package.json");if(!fe.existsSync(t))return null;try{return JSON.parse(fe.readFileSync(t,"utf8"))}catch{return null}},ti=e=>{let t=dn(e);if(!t)return 0;let n={...t.dependencies||{},...t.devDependencies||{}},i=0;return n.expo&&(i+=8),n["react-native"]&&(i+=8),fe.existsSync(Q.join(e,"android"))&&(i+=3),fe.existsSync(Q.join(e,"ios"))&&(i+=3),/^(app|mobile)$/i.test(Q.basename(e))&&(i+=1),i},go=e=>{let t=e?.workspaces;return Array.isArray(t)?t.filter(n=>typeof n=="string"):Array.isArray(t?.packages)?t.packages.filter(n=>typeof n=="string"):[]},ho=(e,t)=>{let n=new Set;for(let i of t){let r=i.replace(/\\/g,"/").replace(/\/+$/,"");if(!r||r.startsWith("/")||r===".."||r.startsWith("../")||r.includes("/../"))continue;if(!r.includes("*")){n.add(Q.resolve(e,r));continue}let o=r.match(/^(.*)\/\*$/);if(!o)continue;let s=Q.resolve(e,o[1]);if(!(!fe.existsSync(s)||!fe.statSync(s).isDirectory()))for(let a of fe.readdirSync(s,{withFileTypes:!0}))a.isDirectory()&&n.add(Q.join(s,a.name))}for(let i of["apps","packages"]){let r=Q.join(e,i);if(!(!fe.existsSync(r)||!fe.statSync(r).isDirectory()))for(let o of fe.readdirSync(r,{withFileTypes:!0}))o.isDirectory()&&n.add(Q.join(r,o.name))}return Array.from(n)},Vc=e=>{let t=Q.resolve(e);if(ti(t)>0)return".";let n=dn(t),i=ho(t,go(n)).map(r=>({directory:r,score:ti(r)})).filter(r=>r.score>0).sort((r,o)=>o.score-r.score||r.directory.localeCompare(o.directory));return i.length===0||i[1]&&i[1].score===i[0].score?null:Q.relative(t,i[0].directory).split(Q.sep).join("/")},Wc=(e,t)=>{let n=ct(e,t,{requireAppDirectory:!0}),i=dn(n.appRoot);return{...i?.dependencies||{},...i?.devDependencies||{}}.expo?"expo":"react-native"},yo=e=>{if(e==null)return".";if(typeof e!="string")throw new Error("appDirectory must be a relative directory path.");let t=e.trim();if(!t||t===".")return".";if(t.includes("\0"))throw new Error("appDirectory contains an invalid null byte.");let n=t.replace(/\\/g,"/");if(Q.posix.isAbsolute(n)||/^[A-Za-z]:\//.test(n))throw new Error("appDirectory must be relative to the project root.");let i=Q.posix.normalize(n).replace(/^\.\//,"");if(i===".."||i.startsWith("../")||i.includes("/../"))throw new Error("appDirectory must stay inside the project root.");return!i||i==="."?".":i.replace(/\/+$/,"")},ct=(e,t,n={})=>{let i=Q.resolve(e),r=yo(t),o=Q.resolve(i,...r.split("/").filter(a=>a&&a!==".")),s=Q.relative(i,o);if(s===".."||s.startsWith(`..${Q.sep}`)||Q.isAbsolute(s))throw new Error("appDirectory must stay inside the project root.");if(n.requireAppDirectory){if(!fe.existsSync(o)||!fe.statSync(o).isDirectory())throw new Error(`Configured appDirectory "${r}" does not exist inside the project root.`);if(!fe.existsSync(Q.join(o,"package.json")))throw new Error(`Configured appDirectory "${r}" must contain a package.json.`);let a=fe.realpathSync(i),c=fe.realpathSync(o),l=Q.relative(a,c);if(l===".."||l.startsWith(`..${Q.sep}`)||Q.isAbsolute(l))throw new Error("Configured appDirectory resolves outside the project root.")}return{sourceRoot:i,appDirectory:r,appRoot:o}},Zc=(e,t,n)=>{if(t==="react-native"){if(n==="android"){let i=Q.join(e.appRoot,"android/gradlew"),r=Q.join(e.appRoot,"gradlew");if(!fe.existsSync(i)&&!fe.existsSync(r))throw new Error(`React Native Android build requires android/gradlew inside appDirectory "${e.appDirectory}".`);return}if(!fe.existsSync(Q.join(e.appRoot,"ios/Podfile")))throw new Error(`React Native iOS build requires ios/Podfile inside appDirectory "${e.appDirectory}".`)}};var ci=(e,t)=>t.filter(n=>C.existsSync(I.join(e,n))).reduce((n,i)=>n.update(C.readFileSync(I.join(e,i))),Ao.createHash("sha256")).digest("hex").slice(0,16),Co=e=>ci(e,["package.json","yarn.lock","package-lock.json","bun.lockb"]),bo=e=>ci(e,["Podfile","Podfile.lock"]),wo=e=>{let t=I.join(e,"fingerprint.json");try{return JSON.parse(C.readFileSync(t,"utf-8"))}catch{return{}}},ni=(e,t)=>{C.mkdirSync(e,{recursive:!0}),C.writeFileSync(I.join(e,"fingerprint.json"),JSON.stringify(t,null,2))},So=7200*1e3,vo=(e,t)=>{C.mkdirSync(e,{recursive:!0});let n=I.join(e,"build.lock");if(C.existsSync(n))try{let i=JSON.parse(C.readFileSync(n,"utf-8")),r=Date.now()-(i.timestamp||0);if(r<So)throw new Error(`Another build is already running for this project (build ${i.buildId}, started ${Math.round(r/6e4)}m ago). Cancel it from the dashboard first, or wait for it to complete.`)}catch(i){if(i.message.includes("Another build"))throw i}C.writeFileSync(n,JSON.stringify({buildId:t,pid:process.pid,timestamp:Date.now()}))},Eo=(e,t)=>{let n=I.join(e,"build.lock");try{C.existsSync(n)&&JSON.parse(C.readFileSync(n,"utf-8")).buildId===t&&C.unlinkSync(n)}catch{}},ii=15e5,ri=(e,t)=>{let n=e+t;return n.length>ii?n.slice(-ii):n},li=e=>e.replace(/\u001b\[[0-9;]*m/g,""),di=e=>/\berror:|fatal error:|xcodebuild: error|The following build commands failed|Command PhaseScriptExecution failed|PhaseScriptExecution|Command .* failed|CodeSign|Provisioning profile|No profiles|requires a provisioning profile|Undefined symbols|ld:|clang: error|SwiftCompile|CompileC|node: command not found|env: node|No such file or directory|Permission denied/i.test(e),Po=e=>{let t=new Set,n=[];e.forEach((r,o)=>{di(r)&&n.push(o)});for(let r of n){let o=/PhaseScriptExecution|Command PhaseScriptExecution failed|The following build commands failed/i.test(e[r])?18:8,s=/The following build commands failed/i.test(e[r])?18:10;for(let a=Math.max(0,r-o);a<=Math.min(e.length-1,r+s);a++)t.add(a)}if(t.size===0)return e.slice(-120);let i=Array.from(t).sort((r,o)=>r-o).map(r=>e[r]);return i.length>160?i.slice(-160):i},No=(e,t,n,i)=>{let r=li(i).replace(/\r/g,`
315
+ `+n.slice(s)}return Ze.writeFileSync(e,o),!0},oo=(e,t)=>{if(!ro(e,t)){if(process.platform!=="darwin")throw new Error(`Could not update binary Info.plist outside macOS: ${e}`);try{on("/usr/bin/plutil",["-replace","CFBundleVersion","-string",t,e])}catch{on("/usr/bin/plutil",["-insert","CFBundleVersion","-string",t,e])}}},Jn=(e,t,n)=>{let i=at(t,"resolved MACH build"),r=Qe.resolve(e),o=new Set;if(n)try{for(let l of io(r,n))o.add(l)}catch{}for(let l of Kn(r))o.add(l);let s=[...o].sort(),a=new Map,c=!1;try{for(let l of s)a.set(l,Ze.readFileSync(l)),oo(l,i)}catch(l){for(let[p,d]of a)Ze.writeFileSync(p,d);throw l}return{buildNumber:i,plistPaths:s,restore:()=>{if(!c){c=!0;for(let[l,p]of a)Ze.existsSync(l)&&Ze.writeFileSync(l,p)}}}},sn=(e,t,n)=>{let i=at(e,n),r=at(t,"resolved MACH build");if(i!==r)throw new Error(`iOS build number mismatch in ${n}: expected MACH buildNumber ${r}, but the artifact contains CFBundleVersion ${i}.`);return i};import{execFileSync as Yn}from"child_process";import St from"fs";import Ie from"path";import so from"adm-zip";var an=(e,t)=>{let n=0n,i=0n,r=t;for(;r<e.length&&i<=63n;){let o=e[r++];if(n|=BigInt(o&127)<<i,(o&128)===0)return{value:n,next:r};i+=7n}throw new Error("Malformed protobuf varint")},vt=e=>{let t=[],n=0;for(;n<e.length;){let i=an(e,n);n=i.next;let r=Number(i.value>>3n),o=Number(i.value&7n);if(r<1)throw new Error("Malformed protobuf field number");if(o===0){let s=an(e,n);n=s.next,t.push({number:r,wireType:o,varint:s.value});continue}if(o===1){if(n+8>e.length)throw new Error("Truncated protobuf fixed64");t.push({number:r,wireType:o,bytes:e.subarray(n,n+8)}),n+=8;continue}if(o===2){let s=an(e,n);n=s.next;let a=Number(s.value);if(!Number.isSafeInteger(a)||n+a>e.length)throw new Error("Truncated protobuf length-delimited field");t.push({number:r,wireType:o,bytes:e.subarray(n,n+a)}),n+=a;continue}if(o===5){if(n+4>e.length)throw new Error("Truncated protobuf fixed32");t.push({number:r,wireType:o,bytes:e.subarray(n,n+4)}),n+=4;continue}throw new Error(`Unsupported protobuf wire type ${o}`)}return t},zn=(e,t)=>e.find(i=>i.number===t&&i.wireType===2)?.bytes?.toString("utf8"),ao=e=>{let n=vt(e).find(o=>o.number===7&&o.wireType===2)?.bytes;if(!n)return null;let r=vt(n).find(o=>(o.number===6||o.number===7)&&o.wireType===0)?.varint;return r===void 0||r>BigInt(Number.MAX_SAFE_INTEGER)?null:r.toString()},co=e=>{let n=vt(e).find(l=>l.number===1&&l.wireType===2)?.bytes;if(!n)throw new Error("AAB base manifest has no root XML element");let o=vt(n).filter(l=>l.number===4&&l.wireType===2).map(l=>vt(l.bytes)).find(l=>zn(l,2)==="versionCode");if(!o)throw new Error("AAB base manifest has no android:versionCode");let s=zn(o,3)?.trim();if(s&&/^\d+$/.test(s))return Te(s,"packaged AAB manifest");let a=o.find(l=>l.number===6&&l.wireType===2)?.bytes,c=a?ao(a):null;return Te(c,"packaged AAB manifest")},Qn=e=>{try{return St.accessSync(e,St.constants.X_OK),St.statSync(e).isFile()}catch{return!1}},cn=e=>String(process.env.PATH||"").split(Ie.delimiter).filter(Boolean).map(t=>Ie.join(t,e)),qn=()=>Array.from(new Set([process.env.ANDROID_HOME,process.env.ANDROID_SDK_ROOT,process.platform==="darwin"?Ie.join(process.env.HOME||"","Library/Android/sdk"):Ie.join(process.env.HOME||"","Android/Sdk"),"/opt/android-sdk"].filter(e=>!!e))),ei=e=>{try{return St.readdirSync(e).map(t=>Ie.join(e,t)).filter(t=>St.statSync(t).isDirectory()).sort((t,n)=>n.localeCompare(t,void 0,{numeric:!0}))}catch{return[]}},lo=()=>{let e=cn("apkanalyzer");for(let t of qn()){let n=Ie.join(t,"cmdline-tools");e.push(Ie.join(n,"latest/bin/apkanalyzer"));for(let i of ei(n))e.push(Ie.join(i,"bin/apkanalyzer"))}return e},po=()=>{let e=[...cn("aapt2"),...cn("aapt")];for(let t of qn())for(let n of ei(Ie.join(t,"build-tools")))e.push(Ie.join(n,"aapt2"),Ie.join(n,"aapt"));return e},uo=e=>{let t=e.trim();return/^\d+$/.test(t)?t:null},fo=e=>e.match(/^package:.*\bversionCode='(\d+)'/m)?.[1]||null,mo=(e,t)=>{let n=t.apkanalyzer??lo();for(let r of n)if(Qn(r))try{let o=Yn(r,["manifest","version-code",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=uo(o);if(s)return Te(s,"packaged APK manifest")}catch{}let i=t.aapt??po();for(let r of i)if(Qn(r))try{let o=Yn(r,["dump","badging",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=fo(o);if(s)return Te(s,"packaged APK manifest")}catch{}throw new Error("Could not inspect the packaged APK versionCode. Install Android SDK command-line tools (apkanalyzer or aapt2) and rebuild; MACH will not publish an unverified artifact.")},go=(e,t={})=>{let n=Ie.extname(e).toLowerCase();if(n===".apk")return mo(e,t);if(n!==".aab")throw new Error(`Unsupported Android artifact for version validation: ${e}`);let i;try{i=new so(e)}catch(o){throw new Error(`Could not open AAB ${Ie.basename(e)}: ${o.message}`)}let r=i.getEntry("base/manifest/AndroidManifest.xml")||i.getEntries().find(o=>o.entryName.replace(/\\/g,"/")==="base/manifest/AndroidManifest.xml");if(!r)throw new Error(`AAB ${Ie.basename(e)} has no base module manifest`);try{return co(r.getData())}catch(o){throw new Error(`Could not read versionCode from ${Ie.basename(e)}: ${o.message}`)}},ln=(e,t,n={})=>{let i=Te(t,"resolved MACH build assignment"),r=go(e,n);if(r!==i)throw new Error(`Android versionCode mismatch in ${Ie.basename(e)}: expected ${i}, packaged ${r}. MACH stopped the build before upload.`);return r};import fe from"fs";import Q from"path";var dn=e=>{let t=Q.join(e,"package.json");if(!fe.existsSync(t))return null;try{return JSON.parse(fe.readFileSync(t,"utf8"))}catch{return null}},ti=e=>{let t=dn(e);if(!t)return 0;let n={...t.dependencies||{},...t.devDependencies||{}},i=0;return n.expo&&(i+=8),n["react-native"]&&(i+=8),fe.existsSync(Q.join(e,"android"))&&(i+=3),fe.existsSync(Q.join(e,"ios"))&&(i+=3),/^(app|mobile)$/i.test(Q.basename(e))&&(i+=1),i},ho=e=>{let t=e?.workspaces;return Array.isArray(t)?t.filter(n=>typeof n=="string"):Array.isArray(t?.packages)?t.packages.filter(n=>typeof n=="string"):[]},yo=(e,t)=>{let n=new Set;for(let i of t){let r=i.replace(/\\/g,"/").replace(/\/+$/,"");if(!r||r.startsWith("/")||r===".."||r.startsWith("../")||r.includes("/../"))continue;if(!r.includes("*")){n.add(Q.resolve(e,r));continue}let o=r.match(/^(.*)\/\*$/);if(!o)continue;let s=Q.resolve(e,o[1]);if(!(!fe.existsSync(s)||!fe.statSync(s).isDirectory()))for(let a of fe.readdirSync(s,{withFileTypes:!0}))a.isDirectory()&&n.add(Q.join(s,a.name))}for(let i of["apps","packages"]){let r=Q.join(e,i);if(!(!fe.existsSync(r)||!fe.statSync(r).isDirectory()))for(let o of fe.readdirSync(r,{withFileTypes:!0}))o.isDirectory()&&n.add(Q.join(r,o.name))}return Array.from(n)},Wc=e=>{let t=Q.resolve(e);if(ti(t)>0)return".";let n=dn(t),i=yo(t,ho(n)).map(r=>({directory:r,score:ti(r)})).filter(r=>r.score>0).sort((r,o)=>o.score-r.score||r.directory.localeCompare(o.directory));return i.length===0||i[1]&&i[1].score===i[0].score?null:Q.relative(t,i[0].directory).split(Q.sep).join("/")},Zc=(e,t)=>{let n=ct(e,t,{requireAppDirectory:!0}),i=dn(n.appRoot);return{...i?.dependencies||{},...i?.devDependencies||{}}.expo?"expo":"react-native"},Io=e=>{if(e==null)return".";if(typeof e!="string")throw new Error("appDirectory must be a relative directory path.");let t=e.trim();if(!t||t===".")return".";if(t.includes("\0"))throw new Error("appDirectory contains an invalid null byte.");let n=t.replace(/\\/g,"/");if(Q.posix.isAbsolute(n)||/^[A-Za-z]:\//.test(n))throw new Error("appDirectory must be relative to the project root.");let i=Q.posix.normalize(n).replace(/^\.\//,"");if(i===".."||i.startsWith("../")||i.includes("/../"))throw new Error("appDirectory must stay inside the project root.");return!i||i==="."?".":i.replace(/\/+$/,"")},ct=(e,t,n={})=>{let i=Q.resolve(e),r=Io(t),o=Q.resolve(i,...r.split("/").filter(a=>a&&a!==".")),s=Q.relative(i,o);if(s===".."||s.startsWith(`..${Q.sep}`)||Q.isAbsolute(s))throw new Error("appDirectory must stay inside the project root.");if(n.requireAppDirectory){if(!fe.existsSync(o)||!fe.statSync(o).isDirectory())throw new Error(`Configured appDirectory "${r}" does not exist inside the project root.`);if(!fe.existsSync(Q.join(o,"package.json")))throw new Error(`Configured appDirectory "${r}" must contain a package.json.`);let a=fe.realpathSync(i),c=fe.realpathSync(o),l=Q.relative(a,c);if(l===".."||l.startsWith(`..${Q.sep}`)||Q.isAbsolute(l))throw new Error("Configured appDirectory resolves outside the project root.")}return{sourceRoot:i,appDirectory:r,appRoot:o}},Mc=(e,t,n)=>{if(t==="react-native"){if(n==="android"){let i=Q.join(e.appRoot,"android/gradlew"),r=Q.join(e.appRoot,"gradlew");if(!fe.existsSync(i)&&!fe.existsSync(r))throw new Error(`React Native Android build requires android/gradlew inside appDirectory "${e.appDirectory}".`);return}if(!fe.existsSync(Q.join(e.appRoot,"ios/Podfile")))throw new Error(`React Native iOS build requires ios/Podfile inside appDirectory "${e.appDirectory}".`)}};var ci=(e,t)=>t.filter(n=>C.existsSync(y.join(e,n))).reduce((n,i)=>n.update(C.readFileSync(y.join(e,i))),Co.createHash("sha256")).digest("hex").slice(0,16),bo=e=>ci(e,["package.json","yarn.lock","package-lock.json","bun.lockb"]),wo=e=>ci(e,["Podfile","Podfile.lock"]),So=e=>{let t=y.join(e,"fingerprint.json");try{return JSON.parse(C.readFileSync(t,"utf-8"))}catch{return{}}},ni=(e,t)=>{C.mkdirSync(e,{recursive:!0}),C.writeFileSync(y.join(e,"fingerprint.json"),JSON.stringify(t,null,2))},vo=7200*1e3,Eo=(e,t)=>{C.mkdirSync(e,{recursive:!0});let n=y.join(e,"build.lock");if(C.existsSync(n))try{let i=JSON.parse(C.readFileSync(n,"utf-8")),r=Date.now()-(i.timestamp||0);if(r<vo)throw new Error(`Another build is already running for this project (build ${i.buildId}, started ${Math.round(r/6e4)}m ago). Cancel it from the dashboard first, or wait for it to complete.`)}catch(i){if(i.message.includes("Another build"))throw i}C.writeFileSync(n,JSON.stringify({buildId:t,pid:process.pid,timestamp:Date.now()}))},Po=(e,t)=>{let n=y.join(e,"build.lock");try{C.existsSync(n)&&JSON.parse(C.readFileSync(n,"utf-8")).buildId===t&&C.unlinkSync(n)}catch{}},ii=15e5,ri=(e,t)=>{let n=e+t;return n.length>ii?n.slice(-ii):n},li=e=>e.replace(/\u001b\[[0-9;]*m/g,""),di=e=>/\berror:|fatal error:|xcodebuild: error|The following build commands failed|Command PhaseScriptExecution failed|PhaseScriptExecution|Command .* failed|CodeSign|Provisioning profile|No profiles|requires a provisioning profile|Undefined symbols|ld:|clang: error|SwiftCompile|CompileC|node: command not found|env: node|No such file or directory|Permission denied/i.test(e),No=e=>{let t=new Set,n=[];e.forEach((r,o)=>{di(r)&&n.push(o)});for(let r of n){let o=/PhaseScriptExecution|Command PhaseScriptExecution failed|The following build commands failed/i.test(e[r])?18:8,s=/The following build commands failed/i.test(e[r])?18:10;for(let a=Math.max(0,r-o);a<=Math.min(e.length-1,r+s);a++)t.add(a)}if(t.size===0)return e.slice(-120);let i=Array.from(t).sort((r,o)=>r-o).map(r=>e[r]);return i.length>160?i.slice(-160):i},Ro=(e,t,n,i)=>{let r=li(i).replace(/\r/g,`
316
316
  `).split(`
317
- `).map(c=>c.trimEnd()).filter(Boolean),o=r.filter(di),s=o.length>0?Po(r):r.slice(-80),a=o.length>0?"Key failure output":"Last command output";return[`Command failed with code ${n}: ${e} ${t.join(" ")}`,s.length>0?`
317
+ `).map(c=>c.trimEnd()).filter(Boolean),o=r.filter(di),s=o.length>0?No(r):r.slice(-80),a=o.length>0?"Key failure output":"Last command output";return[`Command failed with code ${n}: ${e} ${t.join(" ")}`,s.length>0?`
318
318
  ${a}:
319
319
  ${s.join(`
320
- `)}`:""].join("")},Ro=e=>e==="xcodebuild"&&process.env.MACH_XCODE_FULL_LOGS!=="1",ko=e=>{let t=li(e).trim();return t?/\berror:|fatal error:|xcodebuild: error|The following build commands failed|Command PhaseScriptExecution failed|CodeSign|Provisioning profile|No profiles|requires a provisioning profile|Undefined symbols|ld:|clang: error|SwiftCompile|CompileC|CFBundleVersion|ARCHIVE SUCCEEDED|ARCHIVE FAILED|EXPORT SUCCEEDED|EXPORT FAILED|Exported .* to:|\[IPA VALID\]/i.test(t):!1},$e=e=>{try{C.existsSync(e)&&C.rmSync(e,{recursive:!0,force:!0})}catch{}},xo=(e,t)=>{try{if(!C.existsSync(e))return;for(let n of C.readdirSync(e))t(n)&&$e(I.join(e,n))}catch{}},lt=e=>{S.info(w.dim("Clearing Metro/Hermes JS transform caches..."));let t=he.tmpdir();xo(t,n=>n==="metro-cache"||n.startsWith("metro-")||n.startsWith("haste-map-")||n.startsWith("react-native-packager-cache-")),$e(I.join(e,".expo")),$e(I.join(e,"node_modules/.cache/metro")),$e(I.join(he.homedir(),".cache/metro")),$e(I.join(he.homedir(),".cache/react-native-packager")),$e(I.join(he.homedir(),"Library/Caches/metro")),$e(I.join(he.homedir(),"Library/Caches/react-native-packager"))},$o=e=>/Internal inconsistency error|never received target ended message/i.test(String(e?.message||e)),_o=e=>{S.warn(w.yellow("Xcode build system hit an internal inconsistency. Clearing simulator build state and retrying once...")),$e(I.join(e,"Build")),$e(I.join(e,"Index.noindex")),$e(I.join(e,"ModuleCache.noindex")),$e(I.join(e,"SourcePackages"))},Fo=e=>{let t=String(e?.message||e);return/Permission denied/i.test(t)&&/Pods\/.*\.sh/i.test(t)},pi=e=>{let t=I.join(e,"Pods"),i=[I.join(t,"Target Support Files"),t].filter(a=>C.existsSync(a)),r=new Set,o=0,s=a=>{let c=a;try{c=C.realpathSync(a)}catch{}if(r.has(c))return;r.add(c);let l;try{l=C.readdirSync(a,{withFileTypes:!0})}catch{return}for(let p of l){let d=I.join(a,p.name);if(p.isDirectory()){s(d);continue}if(!(!p.isFile()||!p.name.endsWith(".sh")))try{let u=C.statSync(d),h=u.mode|493;h!==u.mode&&(C.chmodSync(d,h),o+=1)}catch{}}};for(let a of i)s(a);return o>0&&S.info(w.dim(`Repaired executable permissions on ${o} CocoaPods script${o===1?"":"s"}.`)),o},To=(e,t,n,i,r)=>{let o=c=>{let l=c.filter(d=>d?.id&&String(d?.platform||"").includes("iOS Simulator")&&!d?.error),p=l.find(d=>/iphone/i.test(d.name||""))||l[0];return p?.id?`id=${p.id}`:void 0},s=c=>{let l=[],p=!1;for(let d of c.split(`
321
- `)){if(/Ineligible destinations/i.test(d)&&(p=!0),p||!d.includes("platform:iOS Simulator")||d.includes("error:"))continue;let u=d.match(/\bid:([^,}]+)/)?.[1]?.trim(),h=d.match(/\bname:([^,}]+)/)?.[1]?.trim();u&&l.push({id:u,name:h,platform:"iOS Simulator"})}return o(l)},a=[t?"-workspace":"-project",t||n,"-scheme",i,"-configuration",r,"-sdk","iphonesimulator","-showdestinations"];try{let c=Me("xcodebuild",[...a,"-json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),l=JSON.parse(c),p=Array.isArray(l.destinations)?l.destinations:Array.isArray(l.availableDestinations)?l.availableDestinations:[],d=o(p);if(d)return d}catch{}try{let c=Me("xcodebuild",a,{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return s(c)}catch{}},je=(e,t,n=process.cwd(),i={},r,o)=>new Promise((s,a)=>{let c="",l=Ro(e),p=Date.now(),d=[i.MACH_APP_ROOT?I.join(i.MACH_APP_ROOT,"node_modules/.bin"):"",i.MACH_SOURCE_ROOT?I.join(i.MACH_SOURCE_ROOT,"node_modules/.bin"):"","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin",I.join(he.homedir(),".npm-global/bin")],h=[...(process.env.PATH||"").split(":"),...d].filter((k,y,N)=>k&&N.indexOf(k)===y).join(":");process.env[`${A.envPrefix}DEBUG`]&&console.log(w.magenta(`[${A.nameUpper}_DEBUG] Execution PATH: ${h}`));let f={...process.env,...i,PATH:h,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"};r&&process.env[`${A.envPrefix}DEBUG`]&&(r(w.magenta(`[ENVIRONMENT] node: ${process.execPath}
320
+ `)}`:""].join("")},ko=e=>e==="xcodebuild"&&process.env.MACH_XCODE_FULL_LOGS!=="1",xo=e=>{let t=li(e).trim();return t?/\berror:|fatal error:|xcodebuild: error|The following build commands failed|Command PhaseScriptExecution failed|CodeSign|Provisioning profile|No profiles|requires a provisioning profile|Undefined symbols|ld:|clang: error|SwiftCompile|CompileC|CFBundleVersion|ARCHIVE SUCCEEDED|ARCHIVE FAILED|EXPORT SUCCEEDED|EXPORT FAILED|Exported .* to:|\[IPA VALID\]/i.test(t):!1},$e=e=>{try{C.existsSync(e)&&C.rmSync(e,{recursive:!0,force:!0})}catch{}},$o=(e,t)=>{try{if(!C.existsSync(e))return;for(let n of C.readdirSync(e))t(n)&&$e(y.join(e,n))}catch{}},lt=e=>{S.info(w.dim("Clearing Metro/Hermes JS transform caches..."));let t=he.tmpdir();$o(t,n=>n==="metro-cache"||n.startsWith("metro-")||n.startsWith("haste-map-")||n.startsWith("react-native-packager-cache-")),$e(y.join(e,".expo")),$e(y.join(e,"node_modules/.cache/metro")),$e(y.join(he.homedir(),".cache/metro")),$e(y.join(he.homedir(),".cache/react-native-packager")),$e(y.join(he.homedir(),"Library/Caches/metro")),$e(y.join(he.homedir(),"Library/Caches/react-native-packager"))},_o=e=>/Internal inconsistency error|never received target ended message/i.test(String(e?.message||e)),Fo=e=>{S.warn(w.yellow("Xcode build system hit an internal inconsistency. Clearing simulator build state and retrying once...")),$e(y.join(e,"Build")),$e(y.join(e,"Index.noindex")),$e(y.join(e,"ModuleCache.noindex")),$e(y.join(e,"SourcePackages"))},To=e=>{let t=String(e?.message||e);return/Permission denied/i.test(t)&&/Pods\/.*\.sh/i.test(t)},pi=e=>{let t=y.join(e,"Pods"),i=[y.join(t,"Target Support Files"),t].filter(a=>C.existsSync(a)),r=new Set,o=0,s=a=>{let c=a;try{c=C.realpathSync(a)}catch{}if(r.has(c))return;r.add(c);let l;try{l=C.readdirSync(a,{withFileTypes:!0})}catch{return}for(let p of l){let d=y.join(a,p.name);if(p.isDirectory()){s(d);continue}if(!(!p.isFile()||!p.name.endsWith(".sh")))try{let u=C.statSync(d),h=u.mode|493;h!==u.mode&&(C.chmodSync(d,h),o+=1)}catch{}}};for(let a of i)s(a);return o>0&&S.info(w.dim(`Repaired executable permissions on ${o} CocoaPods script${o===1?"":"s"}.`)),o},Oo=(e,t,n,i,r)=>{let o=c=>{let l=c.filter(d=>d?.id&&String(d?.platform||"").includes("iOS Simulator")&&!d?.error),p=l.find(d=>/iphone/i.test(d.name||""))||l[0];return p?.id?`id=${p.id}`:void 0},s=c=>{let l=[],p=!1;for(let d of c.split(`
321
+ `)){if(/Ineligible destinations/i.test(d)&&(p=!0),p||!d.includes("platform:iOS Simulator")||d.includes("error:"))continue;let u=d.match(/\bid:([^,}]+)/)?.[1]?.trim(),h=d.match(/\bname:([^,}]+)/)?.[1]?.trim();u&&l.push({id:u,name:h,platform:"iOS Simulator"})}return o(l)},a=[t?"-workspace":"-project",t||n,"-scheme",i,"-configuration",r,"-sdk","iphonesimulator","-showdestinations"];try{let c=Me("xcodebuild",[...a,"-json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),l=JSON.parse(c),p=Array.isArray(l.destinations)?l.destinations:Array.isArray(l.availableDestinations)?l.availableDestinations:[],d=o(p);if(d)return d}catch{}try{let c=Me("xcodebuild",a,{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return s(c)}catch{}},je=(e,t,n=process.cwd(),i={},r,o)=>new Promise((s,a)=>{let c="",l=ko(e),p=Date.now(),d=[i.MACH_APP_ROOT?y.join(i.MACH_APP_ROOT,"node_modules/.bin"):"",i.MACH_SOURCE_ROOT?y.join(i.MACH_SOURCE_ROOT,"node_modules/.bin"):"","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin","/usr/sbin","/sbin",y.join(he.homedir(),".npm-global/bin")],h=[...(process.env.PATH||"").split(":"),...d].filter((N,I,R)=>N&&R.indexOf(N)===I).join(":");process.env[`${A.envPrefix}DEBUG`]&&console.log(w.magenta(`[${A.nameUpper}_DEBUG] Execution PATH: ${h}`));let f={...process.env,...i,PATH:h,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"};r&&process.env[`${A.envPrefix}DEBUG`]&&(r(w.magenta(`[ENVIRONMENT] node: ${process.execPath}
322
322
  `)),r(w.magenta(`[ENVIRONMENT] PATH: ${h}
323
323
  `)),r(w.magenta(`[ENVIRONMENT] command: ${e} ${t.join(" ")}
324
- `)));let v=e;if(["node","npm","npx","pod"].includes(e)){let k=I.dirname(process.execPath),y=I.join(k,e);C.existsSync(y)&&(v=y,r&&r(w.dim(`[EXEC] Using absolute path: ${v}
325
- `)))}let b=ai(v,t,{stdio:"pipe",cwd:n,shell:!0,env:f,detached:process.platform!=="win32"});if(o){if(o.aborted){if(b.pid)try{process.kill(-b.pid,"SIGTERM")}catch{b.kill()}return a(new Error("Command aborted"))}o.addEventListener("abort",()=>{if(b.pid)try{process.kill(-b.pid,"SIGTERM")}catch{b.kill()}a(new Error("Command aborted"))})}let R=(k,y)=>{if(!l){y.write(k);return}let N=k.replace(/\r/g,`
324
+ `)));let v=e;if(["node","npm","npx","pod"].includes(e)){let N=y.dirname(process.execPath),I=y.join(N,e);C.existsSync(I)&&(v=I,r&&r(w.dim(`[EXEC] Using absolute path: ${v}
325
+ `)))}let b=ai(v,t,{stdio:"pipe",cwd:n,shell:!0,env:f,detached:process.platform!=="win32"});if(o){if(o.aborted){if(b.pid)try{process.kill(-b.pid,"SIGTERM")}catch{b.kill()}return a(new Error("Command aborted"))}o.addEventListener("abort",()=>{if(b.pid)try{process.kill(-b.pid,"SIGTERM")}catch{b.kill()}a(new Error("Command aborted"))})}let x=(N,I)=>{if(!l){I.write(N);return}let R=N.replace(/\r/g,`
326
326
  `).split(`
327
- `).filter(ko);if(N.length>0){y.write(`${N.join(`
327
+ `).filter(xo);if(R.length>0){I.write(`${R.join(`
328
328
  `)}
329
- `),p=Date.now();return}let $=Date.now();$-p>3e4&&(y.write(`[xcodebuild] still running; detailed output is streamed to Mach logs.
330
- `),p=$)};b.stdout.on("data",k=>{let y=k.toString();c=ri(c,y),R(y,process.stdout),r&&r(y)}),b.stderr.on("data",k=>{let y=k.toString();c=ri(c,y),R(y,process.stderr),r&&r(y)}),b.on("close",k=>{k===0?s(k):a(new Error(No(e,t,k,c)))}),b.on("error",k=>a(k))}),kt=async(e,t,n,i,r)=>{try{await je("xcodebuild",e,t,n,i,r)}catch(o){if(!Fo(o))throw o;S.warn(w.yellow("CocoaPods script permission denied. Repairing Pods script permissions and retrying xcodebuild once...")),pi(t),await je("xcodebuild",e,t,n,i,r)}},Oo=e=>{let t=Math.floor(e/1e3%60),n=Math.floor(e/(1e3*60)%60),i=Math.floor(e/(1e3*60*60)%24),r=[];return i>0&&r.push(`${i}h`),n>0&&r.push(`${n}m`),(t>0||r.length===0)&&r.push(`${t}s`),r.join(" ")},qe=(e,t)=>{let n=[];try{if(!C.existsSync(e))return n;let i=C.readdirSync(e);for(let r of i){let o=I.join(e,r);try{let s=C.statSync(o);if(t.some(c=>r.endsWith(c))){n.push(I.resolve(o));continue}s.isDirectory()&&(n=n.concat(qe(o,t)))}catch{}}}catch{}return n},ui=(e,t)=>{let n=wt(e);if(!n)throw new Error(`Invalid iOS CFBundleVersion from ${t}: "${e||""}". Apple requires one to three period-separated integers, for example "42" or "1.2.3". If you see "[Decryption Failed]", fix/remove the broken BUILD_NUMBER secret and rebuild.`);return n},un=(e,t)=>Me("/usr/libexec/PlistBuddy",["-c",`Print :${t}`,e],{encoding:"utf-8"}).trim(),dt=(e,t)=>{try{return un(e,t)}catch{return""}},oi=e=>String(e||"").replace(/\.app$/i,"").replace(/[^a-z0-9]/gi,"").toLowerCase(),Do=e=>{try{return C.statSync(e).isDirectory()}catch{return!1}},Bo=(e,t,n)=>{if(!C.existsSync(e))throw new Error(`iOS simulator build output directory was not found: ${e}`);let i=C.readdirSync(e).filter(l=>l.endsWith(".app")).map(l=>I.join(e,l)).filter(Do);if(i.length===0){let p=qe(e,[".app"]).map(d=>I.relative(e,d)).join(", ");throw new Error(`No top-level iOS simulator .app product was found in ${e}.`+(p?` Nested .app bundles found but ignored: ${p}`:""))}let r=new Set([t,n.iosScheme,n.scheme,n.appName].filter(Boolean).map(l=>oi(String(l))).filter(Boolean)),o=i.map(l=>{let p=I.join(l,"Info.plist"),d=C.existsSync(p)?dt(p,"CFBundleName"):"",u=C.existsSync(p)?dt(p,"CFBundleDisplayName"):"",h=C.existsSync(p)?dt(p,"CFBundleExecutable"):"",f=C.existsSync(p)?dt(p,"CFBundleIdentifier"):"",v=h?I.join(l,h):"";return{appPath:l,bundleIdentifier:f,executable:h,isValid:C.existsSync(p)&&!!h&&C.existsSync(v),names:[I.basename(l,".app"),d,u,h].map(oi).filter(Boolean)}}),s=o.filter(l=>l.isValid);if(s.length===0)throw new Error(`No valid iOS simulator .app product was found in ${e}. Candidates: `+o.map(l=>I.basename(l.appPath)).join(", "));let c=s.find(l=>l.names.some(p=>r.has(p)))||(s.length===1?s[0]:null);if(!c)throw new Error(`Multiple iOS simulator .app products were found in ${e}: `+s.map(l=>{let p=l.bundleIdentifier?` (${l.bundleIdentifier})`:"";return`${I.basename(l.appPath)}${p}`}).join(", ")+`. Set ios.scheme in ${A.configFileName} so ${A.name} can select the app target safely.`);return c.appPath},Vo=(e,t)=>{let n=I.join(e,"Info.plist");if(!C.existsSync(n))throw new Error(`Could not validate iOS build number: ${n} not found.`);let i=ui(un(n,"CFBundleVersion"),n);return t?sn(i,t,n):i},fi=(e,t=[])=>{if(!C.existsSync(e))return t;for(let n of C.readdirSync(e,{withFileTypes:!0})){if(!n.isDirectory()||n.isSymbolicLink())continue;let i=I.join(e,n.name);n.name!=="Frameworks"&&((n.name.endsWith(".app")||n.name.endsWith(".appex"))&&t.push(i),fi(i,t))}return t},si=(e,t)=>[e,...fi(e)].filter((i,r,o)=>o.indexOf(i)===r).map(i=>({bundlePath:i,buildNumber:Vo(i,t)})),mi=e=>{let t=I.join(e,"Info.plist");if(!C.existsSync(t))throw new Error(`Could not validate iOS app executable: ${t} not found.`);let n=dt(t,"CFBundleExecutable");if(!n)throw new Error(`Could not validate iOS app executable: CFBundleExecutable missing in ${t}.`);let i=I.join(e,n);if(!C.existsSync(i))throw new Error(`Could not validate iOS app executable: ${i} not found.`);return i},Wo=()=>process.arch==="arm64"?"arm64":"x86_64",gi=e=>{let t=mi(e),n="";try{n=Me("lipo",["-info",t],{encoding:"utf-8"}).trim()}catch(r){throw new Error(`Could not inspect iOS simulator executable architecture for ${I.basename(e)}: ${r.message}`)}let i=Wo();if(!new RegExp(`\\b${i}\\b`).test(n))throw new Error(`iOS simulator app ${I.basename(e)} cannot be installed on this runner because its executable does not include the required ${i} simulator architecture. lipo output: ${n}. Check the React Native iOS project ARCHS/EXCLUDED_ARCHS settings for iphonesimulator builds.`);return n},Zo=e=>{try{return Me("xcrun",["vtool","-show-build",e],{encoding:"utf-8"}).trim()}catch(t){throw new Error(`Could not inspect iOS executable build platform for ${I.basename(e)}: ${t.message}`)}},hi=e=>{let t=mi(e),n=Zo(t);if(!/\bplatform\s+IOSSIMULATOR\b/i.test(n))throw new Error(`iOS simulator app ${I.basename(e)} was built for the wrong Apple platform. A simulator artifact must contain PLATFORM IOSSIMULATOR, not an iPhone device binary. vtool output: ${n}`);return n},yi=(e,t)=>{let i=Me("unzip",["-Z1",e],{encoding:"utf-8"}).split(`
331
- `).map(o=>o.trim()).filter(o=>/^Payload\/.+\.(?:app|appex)\/Info\.plist$/.test(o)&&!o.includes("/Frameworks/"));if(i.length===0)throw new Error(`Could not validate iOS build number: ${I.basename(e)} has no Payload/*.app/Info.plist.`);let r=C.mkdtempSync(I.join(he.tmpdir(),`${A.nameLower}-ipa-plist-`));try{let o="";for(let[s,a]of i.entries()){let c=I.join(r,`Info-${s}.plist`),l=Me("unzip",["-p",e,a]);C.writeFileSync(c,l);let p=`${I.basename(e)}:${a}`,d=ui(un(c,"CFBundleVersion"),p);t&&sn(d,t,p),/^Payload\/[^/]+\.app\/Info\.plist$/.test(a)&&(o=d)}if(!o)throw new Error(`Could not validate iOS build number: ${I.basename(e)} has no main application Info.plist.`);return o}finally{C.rmSync(r,{recursive:!0,force:!0})}},Mo=e=>`'${e.replace(/'/g,"'\\''")}'`,jo=()=>process.execPath&&C.existsSync(process.execPath)?process.execPath:Me("which",["node"],{encoding:"utf-8"}).trim(),Ii=(e,t,n)=>{if(!C.existsSync(e))return;let i=jo();t.NODE_BINARY=i;let r=I.join(e,".xcode.env.local");C.writeFileSync(r,`export NODE_BINARY=${Mo(i)}
329
+ `),p=Date.now();return}let $=Date.now();$-p>3e4&&(I.write(`[xcodebuild] still running; detailed output is streamed to Mach logs.
330
+ `),p=$)};b.stdout.on("data",N=>{let I=N.toString();c=ri(c,I),x(I,process.stdout),r&&r(I)}),b.stderr.on("data",N=>{let I=N.toString();c=ri(c,I),x(I,process.stderr),r&&r(I)}),b.on("close",N=>{N===0?s(N):a(new Error(Ro(e,t,N,c)))}),b.on("error",N=>a(N))}),kt=async(e,t,n,i,r)=>{try{await je("xcodebuild",e,t,n,i,r)}catch(o){if(!To(o))throw o;S.warn(w.yellow("CocoaPods script permission denied. Repairing Pods script permissions and retrying xcodebuild once...")),pi(t),await je("xcodebuild",e,t,n,i,r)}},Do=e=>{let t=Math.floor(e/1e3%60),n=Math.floor(e/(1e3*60)%60),i=Math.floor(e/(1e3*60*60)%24),r=[];return i>0&&r.push(`${i}h`),n>0&&r.push(`${n}m`),(t>0||r.length===0)&&r.push(`${t}s`),r.join(" ")},qe=(e,t)=>{let n=[];try{if(!C.existsSync(e))return n;let i=C.readdirSync(e);for(let r of i){let o=y.join(e,r);try{let s=C.statSync(o);if(t.some(c=>r.endsWith(c))){n.push(y.resolve(o));continue}s.isDirectory()&&(n=n.concat(qe(o,t)))}catch{}}}catch{}return n},ui=(e,t)=>{let n=wt(e);if(!n)throw new Error(`Invalid iOS CFBundleVersion from ${t}: "${e||""}". Apple requires one to three period-separated integers, for example "42" or "1.2.3". If you see "[Decryption Failed]", fix/remove the broken BUILD_NUMBER secret and rebuild.`);return n},un=(e,t)=>Me("/usr/libexec/PlistBuddy",["-c",`Print :${t}`,e],{encoding:"utf-8"}).trim(),dt=(e,t)=>{try{return un(e,t)}catch{return""}},oi=e=>String(e||"").replace(/\.app$/i,"").replace(/[^a-z0-9]/gi,"").toLowerCase(),Bo=e=>{try{return C.statSync(e).isDirectory()}catch{return!1}},Vo=(e,t,n)=>{if(!C.existsSync(e))throw new Error(`iOS simulator build output directory was not found: ${e}`);let i=C.readdirSync(e).filter(l=>l.endsWith(".app")).map(l=>y.join(e,l)).filter(Bo);if(i.length===0){let p=qe(e,[".app"]).map(d=>y.relative(e,d)).join(", ");throw new Error(`No top-level iOS simulator .app product was found in ${e}.`+(p?` Nested .app bundles found but ignored: ${p}`:""))}let r=new Set([t,n.iosScheme,n.scheme,n.appName].filter(Boolean).map(l=>oi(String(l))).filter(Boolean)),o=i.map(l=>{let p=y.join(l,"Info.plist"),d=C.existsSync(p)?dt(p,"CFBundleName"):"",u=C.existsSync(p)?dt(p,"CFBundleDisplayName"):"",h=C.existsSync(p)?dt(p,"CFBundleExecutable"):"",f=C.existsSync(p)?dt(p,"CFBundleIdentifier"):"",v=h?y.join(l,h):"";return{appPath:l,bundleIdentifier:f,executable:h,isValid:C.existsSync(p)&&!!h&&C.existsSync(v),names:[y.basename(l,".app"),d,u,h].map(oi).filter(Boolean)}}),s=o.filter(l=>l.isValid);if(s.length===0)throw new Error(`No valid iOS simulator .app product was found in ${e}. Candidates: `+o.map(l=>y.basename(l.appPath)).join(", "));let c=s.find(l=>l.names.some(p=>r.has(p)))||(s.length===1?s[0]:null);if(!c)throw new Error(`Multiple iOS simulator .app products were found in ${e}: `+s.map(l=>{let p=l.bundleIdentifier?` (${l.bundleIdentifier})`:"";return`${y.basename(l.appPath)}${p}`}).join(", ")+`. Set ios.scheme in ${A.configFileName} so ${A.name} can select the app target safely.`);return c.appPath},Wo=(e,t)=>{let n=y.join(e,"Info.plist");if(!C.existsSync(n))throw new Error(`Could not validate iOS build number: ${n} not found.`);let i=ui(un(n,"CFBundleVersion"),n);return t?sn(i,t,n):i},fi=(e,t=[])=>{if(!C.existsSync(e))return t;for(let n of C.readdirSync(e,{withFileTypes:!0})){if(!n.isDirectory()||n.isSymbolicLink())continue;let i=y.join(e,n.name);n.name!=="Frameworks"&&((n.name.endsWith(".app")||n.name.endsWith(".appex"))&&t.push(i),fi(i,t))}return t},si=(e,t)=>[e,...fi(e)].filter((i,r,o)=>o.indexOf(i)===r).map(i=>({bundlePath:i,buildNumber:Wo(i,t)})),mi=e=>{let t=y.join(e,"Info.plist");if(!C.existsSync(t))throw new Error(`Could not validate iOS app executable: ${t} not found.`);let n=dt(t,"CFBundleExecutable");if(!n)throw new Error(`Could not validate iOS app executable: CFBundleExecutable missing in ${t}.`);let i=y.join(e,n);if(!C.existsSync(i))throw new Error(`Could not validate iOS app executable: ${i} not found.`);return i},Zo=()=>process.arch==="arm64"?"arm64":"x86_64",gi=e=>{let t=mi(e),n="";try{n=Me("lipo",["-info",t],{encoding:"utf-8"}).trim()}catch(r){throw new Error(`Could not inspect iOS simulator executable architecture for ${y.basename(e)}: ${r.message}`)}let i=Zo();if(!new RegExp(`\\b${i}\\b`).test(n))throw new Error(`iOS simulator app ${y.basename(e)} cannot be installed on this runner because its executable does not include the required ${i} simulator architecture. lipo output: ${n}. Check the React Native iOS project ARCHS/EXCLUDED_ARCHS settings for iphonesimulator builds.`);return n},Mo=e=>{try{return Me("xcrun",["vtool","-show-build",e],{encoding:"utf-8"}).trim()}catch(t){throw new Error(`Could not inspect iOS executable build platform for ${y.basename(e)}: ${t.message}`)}},hi=e=>{let t=mi(e),n=Mo(t);if(!/\bplatform\s+IOSSIMULATOR\b/i.test(n))throw new Error(`iOS simulator app ${y.basename(e)} was built for the wrong Apple platform. A simulator artifact must contain PLATFORM IOSSIMULATOR, not an iPhone device binary. vtool output: ${n}`);return n},yi=(e,t)=>{let i=Me("unzip",["-Z1",e],{encoding:"utf-8"}).split(`
331
+ `).map(o=>o.trim()).filter(o=>/^Payload\/.+\.(?:app|appex)\/Info\.plist$/.test(o)&&!o.includes("/Frameworks/"));if(i.length===0)throw new Error(`Could not validate iOS build number: ${y.basename(e)} has no Payload/*.app/Info.plist.`);let r=C.mkdtempSync(y.join(he.tmpdir(),`${A.nameLower}-ipa-plist-`));try{let o="";for(let[s,a]of i.entries()){let c=y.join(r,`Info-${s}.plist`),l=Me("unzip",["-p",e,a]);C.writeFileSync(c,l);let p=`${y.basename(e)}:${a}`,d=ui(un(c,"CFBundleVersion"),p);t&&sn(d,t,p),/^Payload\/[^/]+\.app\/Info\.plist$/.test(a)&&(o=d)}if(!o)throw new Error(`Could not validate iOS build number: ${y.basename(e)} has no main application Info.plist.`);return o}finally{C.rmSync(r,{recursive:!0,force:!0})}},jo=e=>`'${e.replace(/'/g,"'\\''")}'`,Go=()=>process.execPath&&C.existsSync(process.execPath)?process.execPath:Me("which",["node"],{encoding:"utf-8"}).trim(),Ii=(e,t,n)=>{if(!C.existsSync(e))return;let i=Go();t.NODE_BINARY=i;let r=y.join(e,".xcode.env.local");C.writeFileSync(r,`export NODE_BINARY=${jo(i)}
332
332
  `);let o=`[NODE] Xcode NODE_BINARY: ${i}
333
- `;n&&n(w.dim(o)),S.info(w.dim(o.trim()))},rl=async(e,t,n={},i,r={})=>{let o=xt(),s=Date.now(),a=e.platform,c=e.buildProfile||"production",l=bt(e.framework),p=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),d=p.sourceRoot,u=p.appRoot;e.appDirectory=p.appDirectory;let h=()=>({...rn(n,c,e),MACH_SOURCE_ROOT:d,MACH_APP_ROOT:u}),f=async(x,T={})=>{if(i)for(let X=1;X<=3;X++)try{await Z.patch(`/builds/${i}/${t}`,{status:x,...T});return}catch(oe){let me=oe?.response?.data?.message||oe?.message||String(oe);console.error(`[reportStatus] attempt ${X}/3 failed (status=${x}): ${me}`),X<3&&await new Promise(ae=>setTimeout(ae,2e3))}},v=new AbortController,{signal:b}=v,R=null;i&&(R=setInterval(async()=>{try{(await Z.get(`/builds/${i}/${t}`)).data.status==="cancelled"&&(S.warn(w.yellow(`
334
- \u{1F6D1} Build cancelled from dashboard. Terminating...`)),v.abort(),R&&clearInterval(R))}catch{}},5e3));let k=I.join(d,".mach-cache"),y="setup",N="",$=null,G=async()=>{if(!N||!i)return;let x=N;N="";try{let T=x;Object.values(n).forEach(X=>{if(X&&X.length>5){let oe=X.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");T=T.replace(new RegExp(oe,"g"),"[SECRET]")}}),await Z.post(`/builds/${i}/${t}/logs`,{log:T,step:y})}catch{}},V=async()=>{$&&(clearTimeout($),$=null),await G(),Eo(k,t),R&&(clearInterval(R),R=null);try{let x=I.join(he.tmpdir(),`${A.buildPrefix}-${t}.keychain-db`);C.existsSync(x)&&(J(`security delete-keychain "${x}"`,{stdio:"ignore"}),S.info(w.dim("\u{1F511} Build keychain deleted.")))}catch{}try{let x=I.join(he.homedir(),"Library/MobileDevice/Provisioning Profiles");if(C.existsSync(x)){let T=C.readdirSync(x).filter(X=>X.includes(t)||X.startsWith(`${A.nameLower}-temp-${t}`));for(let X of T)C.unlinkSync(I.join(x,X))}}catch{}},B=async x=>{i&&(N+=x,N.length>=8192?($&&(clearTimeout($),$=null),await G()):$||($=setTimeout(()=>{$=null,G()},2e3)))},F=async x=>{y=x,await B(`[STEP_START:${x}] ${Math.floor(Date.now()/1e3)}
335
- `)},K=async(x,T,X,oe)=>await je(x,T,X,oe,me=>{B(me)},b);S.info(w.blue(`\u{1F680} Starting local build for ${a} (${c})...`));try{vo(k,t)}catch(x){throw await f("failed",{error:x.message,endTime:Date.now()}),x}await f("building"),await F("setup"),a==="ios"&&!e.simulator&&n.MACH_IOS_BUILD_NUMBER_LOCKED==="1"&&n.BUILD_NUMBER&&(S.info(w.dim(`Auto build number: ${n.BUILD_NUMBER}`)),await B(`[BUILD_NUMBER] ${n.BUILD_NUMBER}
336
- `)),await F("lock"),l.applyLocalProcessEnv(e);try{await F("clone"),S.info(w.dim("Preparing source...")),await F("read_config");let x=I.join(d,A.configFileName);if(C.existsSync(x)){let P=JSON.parse(C.readFileSync(x,"utf-8"))?.build?.[c]||{};await B(`[CONFIG] Profile: ${c}, distribution: ${P.distribution||"not set"}, simulator: ${P.simulator||!1}
337
- `)}if(await F("read_package"),e.nodeVersion){let E=process.env.NVM_DIR||I.join(he.homedir(),".nvm"),P=I.join(E,"versions","node"),D;if(C.existsSync(P)){let W=C.readdirSync(P).sort().reverse(),z=e.nodeVersion.startsWith("v")?e.nodeVersion:`v${e.nodeVersion}`,ye=W.find(ue=>ue===z||ue.startsWith(z+".")||ue.startsWith(`v${e.nodeVersion}.`));ye&&(D=I.join(P,ye,"bin"))}if(D&&C.existsSync(D)){let W=process.env.PATH||"";process.env.PATH=`${D}:${W}`,await B(`[NODE] Switched to Node ${e.nodeVersion} \u2014 using ${D}
338
- `),S.info(w.green(`\u2713 Node switched to ${e.nodeVersion} (${D})`))}else await B(`[NODE] Warning: Node ${e.nodeVersion} not found in nvm. Run: nvm install ${e.nodeVersion} on the build machine.
339
- `),S.warn(w.yellow(`Node ${e.nodeVersion} not found in nvm \u2014 using system default`))}await F("deps"),o.start("Checking dependencies...");let T=wo(k),X=Co(d),oe=C.existsSync(I.join(d,"node_modules")),me=C.existsSync(I.join(d,"yarn.lock")),ae=C.existsSync(I.join(d,"bun.lockb"));oe&&T.node&&T.node!==X&&(o.stop("Dependency fingerprint changed \u2014 clearing node_modules for clean install..."),await B(`[CACHE] package.json/lockfile changed \u2014 wiping node_modules
340
- `),C.rmSync(I.join(d,"node_modules"),{recursive:!0,force:!0}),oe=!1);let ee="npm",ce=["install","--prefer-offline"];me?(ee="yarn",ce=["install","--prefer-offline"]):ae&&(ee="bun",ce=["install"]),oe?o.stop("Cached node_modules found. Syncing dependencies..."):o.stop("No cached dependencies. Running fresh install..."),e.preBuild&&(S.info(w.blue("Running pre-install hook...")),S.info(w.dim(`> ${e.preBuild}`)),await F("prebuild"),await K("bash",[e.preBuild],d,h())),S.info(w.dim(`Running ${ee} ${ce.join(" ")}...`)),await K(ee,ce,d,h()),T.node=X,ni(k,T);let se=await l.prepareLocalProject({platform:a,options:e,sourceRoot:d,appRoot:u,cacheMeta:T,cacheMetaDir:k,currentBuildEnv:h,reportStep:F,reportLog:B,loggedRun:K,configureXcodeNodeBinary:Ii,podsFingerprint:bo,writeCacheMeta:ni}),Ce=se.bundleId||e.iosBundleIdentifier||"",De=se.appName||e.name||"",_=[];if(a==="android")await F("build"),_=await Go(e,c,n,E=>B(E),b);else if(a==="ios"){await F("signing"),S.info(w.dim("Preparing credentials..."));let E=r?.distributionType;_=await Uo(e,t,c,n,i,P=>B(P),b,E,P=>F(P))}if(e.postBuild&&(S.info(w.blue("Running post-build hook...")),S.info(w.dim(`> ${e.postBuild}`)),await K(e.postBuild,[],d,h())),a==="ios"){let E=wt(e.resolvedBuildNumber||n.BUILD_NUMBER);if(E)for(let P of _.filter(D=>D.endsWith(".ipa"))){let D=yi(P,E);await B(`[IPA FINAL] CFBundleVersion ${D} matches MACH buildNumber ${E}
341
- `)}}if(a==="android"){let E=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(E){let P=Te(E,"resolved MACH build assignment");if(_.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${P}.`);for(let D of _){let W=ln(D,P);await B(`[ANDROID FINAL] ${I.basename(D)} versionCode ${W} matches MACH assignment
342
- `)}}}let U=Oo(Date.now()-s);if(S.success(w.green(`
343
- \u2713 Local build completed successfully in ${U}`)),await f("building",{...Ce&&{bundleId:Ce},...De&&{appName:De}}),_.length>0&&(S.info(w.cyan(`
344
- \u{1F4E6} Generated Artifacts:`)),_.forEach(E=>{let P=I.resolve(E);S.info(w.dim(` - ${E}`)),S.info(w.gray(` Path: ${P}`))}),e.interactive)){let E=await Io({message:"Install on connected device?"});if(!$t(E)&&E){if(a==="android"){let P=_.find(D=>D.endsWith(".apk"))||_[0];await Xo(P,D=>B(D))}else if(a==="ios"){let P=_.find(W=>W.endsWith(".ipa"))||_.find(W=>W.endsWith(".app"))||_[0],D=pt("ios");e.simulator?await Ho(P,D||"",W=>B(W)):await Ko(P,D||"",W=>B(W))}}}await F("upload");let M=[];for(let E of _)try{let P=I.join(he.tmpdir(),`${t}-${I.basename(E)}`);C.copyFileSync(E,P),M.push(P),S.info(w.dim(` \u{1F4CB} Preserved artifact: ${I.basename(E)}`))}catch{S.warn(w.yellow(` Failed to preserve artifact: ${I.basename(E)}`))}_=M,S.info(w.dim("\u{1F9F9} Cleaning workspace (preserving dependency cache)..."));try{let E=process.cwd(),P=new Set(["node_modules"]),D=C.readdirSync(E),W=0;for(let z of D)if(!P.has(z)){if(z==="ios"){let ye=I.join(E,"ios"),ue=C.readdirSync(ye);for(let be of ue)if(be!=="Pods")try{C.rmSync(I.join(ye,be),{recursive:!0,force:!0}),W++}catch{}continue}try{C.rmSync(I.join(E,z),{recursive:!0,force:!0}),W++}catch{}}S.info(w.dim(` Cleaned ${W} items. Cached: node_modules${C.existsSync(I.join(E,"ios","Pods"))?", ios/Pods":""}`)),S.info(w.green("\u{1F512} Security: No source code retained on build server. Only public dependencies cached."))}catch{S.warn(w.yellow("Post-build cleanup encountered errors (non-fatal)."))}try{let P=I.join(he.homedir(),A.workspacesDir),D=J(`df -k "${P}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim(),W=parseInt(D,10)*1024;if(W<53687091200&&C.existsSync(P)){S.info(w.dim(` \u26A0\uFE0F Low disk space (${(W/1024/1024/1024).toFixed(0)} GB free). Running cache eviction...`));let z=I.basename(process.cwd()),ye=C.readdirSync(P).filter(ue=>ue!==z).map(ue=>{let be=I.join(P,ue);try{let tt=C.statSync(be);return tt.isDirectory()?{name:ue,dir:be,mtime:tt.mtimeMs}:null}catch{return null}}).filter(Boolean);ye.sort((ue,be)=>ue.mtime-be.mtime);for(let ue of ye){if(W>=53687091200)break;try{C.rmSync(ue.dir,{recursive:!0,force:!0}),S.info(w.dim(` \u{1F5D1}\uFE0F Evicted stale workspace: ${ue.name}`));let be=J(`df -k "${P}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim();if(parseInt(be,10)*1024>=53687091200)break}catch{}}}}catch{}return await V(),_}catch(x){throw await V(),x.message==="Command aborted"?(S.warn(w.yellow(`
345
- \u274C Build aborted.`)),await f("failed",{error:"Aborted by user",endTime:Date.now()}),x):(S.error(w.red(`
346
- \u2717 Local build failed: ${x.message}`)),await f("failed",{error:x.message,endTime:Date.now()}),x)}},Go=async(e,t,n={},i,r)=>{let o=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),s=I.join(o.appRoot,"android"),a=I.join(o.appRoot,"gradlew"),c=I.join(s,"gradlew"),l=C.existsSync(c)?c:C.existsSync(a)?a:null;if(!l)throw new Error(`Could not find gradlew inside appDirectory "${o.appDirectory}".`);let p=e.developmentClient?"assembleDebug":"assembleRelease";!e.developmentClient&&e.distribution==="store"?p="bundleRelease":!e.developmentClient&&e.distribution==="internal"&&(p="assembleRelease");let d=e.buildCommand||p;S.info(w.blue(`Running Android build: ${d}...`));let u=l===c?s:o.appRoot,h="./gradlew",f=[d],v=bt(e.framework),b={...n,...v.localAndroidEnv(e,t),MACH_APP_NAME:e.appName||e.name||"App",MACH_APP_DIRECTORY:o.appDirectory,MACH_SOURCE_ROOT:o.sourceRoot,MACH_APP_ROOT:o.appRoot},R=e.resolvedVersionCode||n.ANDROID_VERSION_CODE,k=R?Te(R,"resolved MACH build assignment"):null;k&&(f.push(`-Pandroid.injected.version.code=${k}`),b.ANDROID_VERSION_CODE=k,S.info(w.green(`\u2713 Applying Android versionCode ${k}`)));for(let $ of["app/build","build",".cxx"]){let G=I.join(u,$);C.existsSync(G)&&C.rmSync(G,{recursive:!0,force:!0})}lt(o.appRoot),o.appRoot!==o.sourceRoot&&lt(o.sourceRoot),await je(h,f,u,b,i,r);let y=I.join(u,"app/build/outputs"),N=qe(y,[".apk",".aab"]);if(k&&N.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${k}.`);if(k)for(let $ of N){let G=ln($,k);S.info(w.dim(`Validated Android versionCode ${G} in ${I.basename($)}`)),i?.(`[ANDROID VALID] ${I.basename($)} versionCode ${G} matches MACH assignment
347
- `)}return N},Uo=async(e,t,n,i={},r,o,s,a,c)=>{if(process.platform!=="darwin")throw new Error("iOS builds can only be run on macOS.");let l=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),p=I.join(l.appRoot,"ios");if(!C.existsSync(p))throw new Error(`Could not find ios/ inside appDirectory "${l.appDirectory}".`);pi(p);let d=C.readdirSync(p),u=d.find(G=>G.endsWith(".xcworkspace")),h=d.find(G=>G.endsWith(".xcodeproj")),f={...rn(i,n,e),MACH_SOURCE_ROOT:l.sourceRoot,MACH_APP_ROOT:l.appRoot};Ii(p,f,o);let v=e.resolvedBuildNumber||f.BUILD_NUMBER||f.CURRENT_PROJECT_VERSION,b=wt(v);if(v&&!b)throw new Error(`Invalid iOS build number: "${v}". Apple requires one to three period-separated integers. Fix the Dashboard secret or remove it so Mach can use its auto build number.`);let R=b?[`BUILD_NUMBER=${b}`,`CURRENT_PROJECT_VERSION=${b}`,`INFOPLIST_KEY_CFBundleVersion=${b}`]:[];if(b&&(f.BUILD_NUMBER=b,f.CURRENT_PROJECT_VERSION=b,S.info(w.dim(`Using iOS build number: ${b}`))),!u&&!h)throw new Error("Could not find Xcode workspace or project in ios/ directory.");try{let G=J("xcode-select -p").toString().trim();S.info(w.dim(`Using Xcode at: ${G}`))}catch{S.warn(w.dim("Could not detect Xcode path."))}S.info(w.blue("Running iOS build via xcodebuild..."));let k=u?u.replace(".xcworkspace",""):h?.replace(".xcodeproj",""),y=e.iosScheme||k||e.scheme,N=e.developmentClient?"Debug":e.iosConfiguration||"Release",$;try{if(b){$=Jn(p,b,{workspace:u,project:h,scheme:y,configuration:N});let T=$.plistPaths.length>0?`${$.plistPaths.length} Xcode target Info.plist file(s)`:"generated Info.plist build settings";S.info(w.green(`\u2713 Applied iOS buildNumber ${b} to ${T}`)),o&&o(`[VERSIONING] Applied iOS buildNumber ${b} to ${T}
348
- `)}let G=(r||"default").replace(/[^a-zA-Z0-9-_]/g,"_"),V=I.join(he.homedir(),`Library/Developer/Xcode/DerivedData/${A.nameLower}`,G);C.mkdirSync(V,{recursive:!0});let B=Xn(f),F=I.join(V,".mach-env-hash"),K=I.join(V,"Build"),x=C.existsSync(F)?C.readFileSync(F,"utf-8").trim():"";if(C.existsSync(K)){let T=x&&x!==B?"Build environment changed \u2014 clearing iOS DerivedData build products.":x?"Clearing iOS DerivedData build products to force a fresh JS bundle.":"DerivedData has no environment stamp \u2014 clearing iOS build products.";S.info(w.dim(T)),C.rmSync(K,{recursive:!0,force:!0})}if(C.writeFileSync(F,B),lt(l.appRoot),l.appRoot!==l.sourceRoot&&lt(l.sourceRoot),e.simulator){let T=To(p,u,h,y,N),X=T||"generic/platform=iOS Simulator",oe=["-destination",X];S.info(w.dim(T?`Building for simulator (Scheme: ${y}, Config: ${N}, Destination: ${X})...`:`Building for simulator (Scheme: ${y}, Config: ${N}, Destination: ${X})...`));let me=[u?"-workspace":"-project",u||h,"-scheme",y,"-configuration",N,"-sdk","iphonesimulator",...oe,"-derivedDataPath",V,...R,"COMPILER_INDEX_STORE_ENABLE=NO","CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","ONLY_ACTIVE_ARCH=NO","EXCLUDED_ARCHS=","SUPPORTED_PLATFORMS=iphonesimulator"];try{await kt(me,p,f,o,s)}catch(E){if(!$o(E))throw E;_o(V),lt(l.appRoot),l.appRoot!==l.sourceRoot&&lt(l.sourceRoot),await kt(me,p,f,o,s)}let ae=I.join(V,"Build/Products",`${N}-iphonesimulator`),ee=Bo(ae,y,e),ce=I.basename(ee,".app"),se=dt(I.join(ee,"Info.plist"),"CFBundleIdentifier")||"unknown bundle",De=si(ee,b||void 0)[0].buildNumber,_=gi(ee),U=hi(ee),M=I.join(ae,`${ce}_simulator.zip`);return S.info(w.dim(`Selected simulator app: ${I.relative(ae,ee)} (${se}, build ${De})`)),S.info(w.dim(`Simulator executable architecture: ${_}`)),S.info(w.dim(`Simulator executable platform: ${U.split(`
349
- `).find(E=>/\bplatform\b/i.test(E))?.trim()||"IOSSIMULATOR"}`)),S.info(w.dim(`Creating simulator artifact: ${M}...`)),$e(M),Me("zip",["-r",M,I.basename(ee)],{cwd:I.dirname(ee),stdio:"pipe"}),[M]}else{S.info(w.dim(`Archiving (Scheme: ${y}, Config: ${N})...`));let T=I.join(p,"build.xcarchive"),X=I.join(p,"export");C.rmSync(T,{recursive:!0,force:!0}),C.rmSync(X,{recursive:!0,force:!0});let oe=i.IOS_DIST_P12,me=i.IOS_PROVISIONING_PROFILE,ae=i.IOS_P12_PASSWORD||"",ee=[],ce,se,Ce={isAppStore:!1,isDevelopment:!1};if(oe&&me){S.info(w.blue("\u{1F510} CI/CD Signing: Importing certificates..."));try{let W=`${A.buildPrefix}-${t}.keychain-db`,z=I.join(he.tmpdir(),W),ye=A.keychainPassword;J(`security create-keychain -p "${ye}" "${z}" 2>/dev/null || true`),J(`security set-keychain-settings -t 3600 -l "${z}"`),J(`security unlock-keychain -p "${ye}" "${z}"`);let ue=I.join(he.tmpdir(),`cert-${t}.p12`),be=Buffer.from(oe,"base64");C.writeFileSync(ue,be),S.info(w.dim(`P12 data size: ${be.length} bytes, first bytes: ${be.slice(0,4).toString("hex")}`)),(be.length<100||be[0]!==48)&&(S.warn(w.yellow("\u26A0\uFE0F P12 data looks corrupted or was not decrypted correctly.")),S.warn(w.yellow(" This usually means MACH_ENCRYPTION_KEY on the Remote API differs from when credentials were uploaded.")));let tt=[ae,"",A.keychainPassword],Sn=!1;for(let we of tt)try{J(`security import "${ue}" -k "${z}" -P "${we}" -A -T /usr/bin/codesign -T /usr/bin/security`,{stdio:"pipe"}),Sn=!0,S.info(w.dim(`\u2713 P12 imported successfully with password: ${we?"[set]":"[empty]"}`));break}catch(Fe){S.info(w.dim(` P12 import attempt with password ${we?`"${we.substring(0,3)}..."`:"[empty]"} failed: ${Fe.message?.split(`
350
- `)[0]||"unknown"}`))}if(!Sn)throw new Error("Failed to import P12.");C.unlinkSync(ue),J(`security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${ye}" "${z}"`);let er=J("security list-keychains -d user",{encoding:"utf-8"}).split(`
351
- `).map(we=>we.trim().replace(/^"|"$/g,"")).filter(we=>we.length>0),tr=[z,...er].map(we=>`"${we}"`).join(" ");J(`security list-keychains -d user -s ${tr}`),J(`security default-keychain -s "${z}"`);let Zt=I.join(he.homedir(),"Library/MobileDevice/Provisioning Profiles");C.mkdirSync(Zt,{recursive:!0});let vn=Buffer.from(me,"base64"),Mt=I.join(Zt,`${A.nameLower}-temp-${t}.mobileprovision`);C.writeFileSync(Mt,vn);let jt=vn.toString("utf-8"),En=/<key>get-task-allow<\/key>\s*<true\/>/.test(jt);Ce={isAppStore:!jt.includes("<key>ProvisionedDevices</key>")&&!En,isDevelopment:En};try{let Fe=J(`security cms -D -i "${Mt}"`,{encoding:"utf-8"}).match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);se=Fe?Fe[1]:void 0}catch{let Fe=jt.match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);se=Fe?Fe[1]:void 0}se||(S.warn("Could not extract UUID from provisioning profile. Using fallback."),se=`${A.nameLower}-${t}`);let Gt=I.join(Zt,`${se}.mobileprovision`);C.existsSync(Gt)&&C.unlinkSync(Gt),C.renameSync(Mt,Gt);try{let we=J(`security find-identity -v -p codesigning "${z}"`,{encoding:"utf-8"}),Fe=Array.from(we.matchAll(/"((?:Apple|iPhone) (?:Distribution|Developer|Development)[^"]*)"/g),gt=>gt[1]),Pn=Ce.isDevelopment?Fe.find(gt=>/\b(Development|Developer)\b/.test(gt)):Fe.find(gt=>/\bDistribution\b/.test(gt)),Nn=Fe[0];(Pn||Nn)&&(ce=Pn||Nn,S.info(w.blue(`Identity auto-detected from keychain: "${ce}"`)))}catch{}ce||(ce=Ce.isDevelopment?"Apple Development":"Apple Distribution",S.info(w.blue(`Identity fallback (profile heuristic): "${ce}"`))),S.info(w.dim(`Profile type: ${Ce.isDevelopment?"Development":Ce.isAppStore?"App Store":"Ad-Hoc"}`)),S.info(w.dim(`Identity Detection: get-task-allow=${Ce.isDevelopment}, Selected Identity="${ce}"`)),ee.push("CODE_SIGN_STYLE=Manual"),ee.push(`CODE_SIGN_IDENTITY="${ce}"`),ee.push(`PROVISIONING_PROFILE_SPECIFIER=${se}`),e.iosTeamId&&ee.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`)}catch(W){throw S.error(`Signing setup failed: ${W.message}`),W}}else ee.push("-allowProvisioningUpdates"),e.iosTeamId&&ee.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`);c&&await c("archive"),S.info(w.blue(`Archive detected Identity: "${ce}"`)),S.info(w.blue(`Archive detected UUID: "${se}"`)),await kt(["archive",u?"-workspace":"-project",u||h,"-scheme",y,"-configuration",N,"-archivePath",T,"-derivedDataPath",V,...R,...ee],p,f,o,s);let De=qe(I.join(T,"Products","Applications"),[".app"]);for(let W of De)for(let z of si(W,b||void 0))S.info(w.dim(`Validated iOS CFBundleVersion ${z.buildNumber} in ${I.basename(z.bundlePath)}`));let _;se?(Ce.isAppStore?_="app-store":Ce.isDevelopment?_="development":_="ad-hoc",S.info(w.blue(`Export method from profile: "${_}"`))):(_=e.distribution==="store"?"app-store":e.distribution==="internal"?"ad-hoc":"development",S.warn(w.yellow(`No profile UUID detected. Export method from distribution flag: "${_}"`)));let U=e.iosExportMethod||_,M=e.iosBundleIdentifier||pt("ios"),E=I.join(p,"ExportOptions.plist"),P=`<?xml version="1.0" encoding="UTF-8"?>
333
+ `;n&&n(w.dim(o)),S.info(w.dim(o.trim()))},ol=async(e,t,n={},i,r={})=>{let o=xt(),s=Date.now(),a=e.platform,c=e.buildProfile||"production",l=bt(e.framework),p=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),d=p.sourceRoot,u=p.appRoot;e.appDirectory=p.appDirectory;let h=()=>({...rn(n,c,e),MACH_SOURCE_ROOT:d,MACH_APP_ROOT:u}),f=async(k,T={})=>{if(i)for(let H=1;H<=3;H++)try{await Z.patch(`/builds/${i}/${t}`,{status:k,...T});return}catch(oe){let me=oe?.response?.data?.message||oe?.message||String(oe);console.error(`[reportStatus] attempt ${H}/3 failed (status=${k}): ${me}`),H<3&&await new Promise(ae=>setTimeout(ae,2e3))}},v=new AbortController,{signal:b}=v,x=null;i&&(x=setInterval(async()=>{try{(await Z.get(`/builds/${i}/${t}`)).data.status==="cancelled"&&(S.warn(w.yellow(`
334
+ \u{1F6D1} Build cancelled from dashboard. Terminating...`)),v.abort(),x&&clearInterval(x))}catch{}},5e3));let N=y.join(d,".mach-cache"),I="setup",R="",$=null,G=async()=>{if(!R||!i)return;let k=R;R="";try{let T=k;Object.values(n).forEach(H=>{if(H&&H.length>5){let oe=H.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");T=T.replace(new RegExp(oe,"g"),"[SECRET]")}}),await Z.post(`/builds/${i}/${t}/logs`,{log:T,step:I})}catch{}},V=async()=>{$&&(clearTimeout($),$=null),await G(),Po(N,t),x&&(clearInterval(x),x=null);try{let k=y.join(he.tmpdir(),`${A.buildPrefix}-${t}.keychain-db`);C.existsSync(k)&&(J(`security delete-keychain "${k}"`,{stdio:"ignore"}),S.info(w.dim("\u{1F511} Build keychain deleted.")))}catch{}try{let k=y.join(he.homedir(),"Library/MobileDevice/Provisioning Profiles");if(C.existsSync(k)){let T=C.readdirSync(k).filter(H=>H.includes(t)||H.startsWith(`${A.nameLower}-temp-${t}`));for(let H of T)C.unlinkSync(y.join(k,H))}}catch{}},D=async k=>{i&&(R+=k,R.length>=8192?($&&(clearTimeout($),$=null),await G()):$||($=setTimeout(()=>{$=null,G()},2e3)))},F=async k=>{I=k,await D(`[STEP_START:${k}] ${Math.floor(Date.now()/1e3)}
335
+ `)},U=async(k,T,H,oe)=>await je(k,T,H,oe,me=>{D(me)},b);S.info(w.blue(`\u{1F680} Starting local build for ${a} (${c})...`));try{Eo(N,t)}catch(k){throw await f("failed",{error:k.message,endTime:Date.now()}),k}await f("building"),await F("setup"),a==="ios"&&!e.simulator&&n.MACH_IOS_BUILD_NUMBER_LOCKED==="1"&&n.BUILD_NUMBER&&(S.info(w.dim(`Auto build number: ${n.BUILD_NUMBER}`)),await D(`[BUILD_NUMBER] ${n.BUILD_NUMBER}
336
+ `)),await F("lock"),l.applyLocalProcessEnv(e);try{await F("clone"),S.info(w.dim("Preparing source...")),await F("read_config");let k=y.join(d,A.configFileName);if(C.existsSync(k)){let P=JSON.parse(C.readFileSync(k,"utf-8"))?.build?.[c]||{};await D(`[CONFIG] Profile: ${c}, distribution: ${P.distribution||"not set"}, simulator: ${P.simulator||!1}
337
+ `)}if(await F("read_package"),e.nodeVersion){let E=process.env.NVM_DIR||y.join(he.homedir(),".nvm"),P=y.join(E,"versions","node"),B;if(C.existsSync(P)){let W=C.readdirSync(P).sort().reverse(),z=e.nodeVersion.startsWith("v")?e.nodeVersion:`v${e.nodeVersion}`,ye=W.find(ue=>ue===z||ue.startsWith(z+".")||ue.startsWith(`v${e.nodeVersion}.`));ye&&(B=y.join(P,ye,"bin"))}if(B&&C.existsSync(B)){let W=process.env.PATH||"";process.env.PATH=`${B}:${W}`,await D(`[NODE] Switched to Node ${e.nodeVersion} \u2014 using ${B}
338
+ `),S.info(w.green(`\u2713 Node switched to ${e.nodeVersion} (${B})`))}else await D(`[NODE] Warning: Node ${e.nodeVersion} not found in nvm. Run: nvm install ${e.nodeVersion} on the build machine.
339
+ `),S.warn(w.yellow(`Node ${e.nodeVersion} not found in nvm \u2014 using system default`))}await F("deps"),o.start("Checking dependencies...");let T=So(N),H=bo(d),oe=C.existsSync(y.join(d,"node_modules")),me=C.existsSync(y.join(d,"yarn.lock")),ae=C.existsSync(y.join(d,"bun.lockb"));oe&&T.node&&T.node!==H&&(o.stop("Dependency fingerprint changed \u2014 clearing node_modules for clean install..."),await D(`[CACHE] package.json/lockfile changed \u2014 wiping node_modules
340
+ `),C.rmSync(y.join(d,"node_modules"),{recursive:!0,force:!0}),oe=!1);let ee="npm",ce=["install","--prefer-offline"];me?(ee="yarn",ce=["install","--prefer-offline"]):ae&&(ee="bun",ce=["install"]),oe?o.stop("Cached node_modules found. Syncing dependencies..."):o.stop("No cached dependencies. Running fresh install..."),e.preBuild&&(S.info(w.blue("Running pre-install hook...")),S.info(w.dim(`> ${e.preBuild}`)),await F("prebuild"),await U("bash",[e.preBuild],d,h())),S.info(w.dim(`Running ${ee} ${ce.join(" ")}...`)),await U(ee,ce,d,h()),T.node=H,ni(N,T);let se=await l.prepareLocalProject({platform:a,options:e,sourceRoot:d,appRoot:u,cacheMeta:T,cacheMetaDir:N,currentBuildEnv:h,reportStep:F,reportLog:D,loggedRun:U,configureXcodeNodeBinary:Ii,podsFingerprint:wo,writeCacheMeta:ni}),Ce=se.bundleId||e.iosBundleIdentifier||"",De=se.appName||e.name||"",_=[];if(a==="android")await F("build"),_=await Uo(e,c,n,E=>D(E),b);else if(a==="ios"){await F("signing"),S.info(w.dim("Preparing credentials..."));let E=r?.distributionType;_=await Lo(e,t,c,n,i,P=>D(P),b,E,P=>F(P))}if(e.postBuild&&(S.info(w.blue("Running post-build hook...")),S.info(w.dim(`> ${e.postBuild}`)),await U(e.postBuild,[],d,h())),a==="ios"){let E=wt(e.resolvedBuildNumber||n.BUILD_NUMBER);if(E)for(let P of _.filter(B=>B.endsWith(".ipa"))){let B=yi(P,E);await D(`[IPA FINAL] CFBundleVersion ${B} matches MACH buildNumber ${E}
341
+ `)}}if(a==="android"){let E=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(E){let P=Te(E,"resolved MACH build assignment");if(_.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${P}.`);for(let B of _){let W=ln(B,P);await D(`[ANDROID FINAL] ${y.basename(B)} versionCode ${W} matches MACH assignment
342
+ `)}}}let L=Do(Date.now()-s);if(S.success(w.green(`
343
+ \u2713 Local build completed successfully in ${L}`)),await f("building",{...Ce&&{bundleId:Ce},...De&&{appName:De}}),_.length>0&&(S.info(w.cyan(`
344
+ \u{1F4E6} Generated Artifacts:`)),_.forEach(E=>{let P=y.resolve(E);S.info(w.dim(` - ${E}`)),S.info(w.gray(` Path: ${P}`))}),e.interactive)){let E=await Ao({message:"Install on connected device?"});if(!$t(E)&&E){if(a==="android"){let P=_.find(B=>B.endsWith(".apk"))||_[0];await Ho(P,B=>D(B))}else if(a==="ios"){let P=_.find(W=>W.endsWith(".ipa"))||_.find(W=>W.endsWith(".app"))||_[0],B=pt("ios");e.simulator?await Ko(P,B||"",W=>D(W)):await Jo(P,B||"",W=>D(W))}}}await F("upload");let M=[];for(let E of _)try{let P=y.join(he.tmpdir(),`${t}-${y.basename(E)}`);C.copyFileSync(E,P),M.push(P),S.info(w.dim(` \u{1F4CB} Preserved artifact: ${y.basename(E)}`))}catch{S.warn(w.yellow(` Failed to preserve artifact: ${y.basename(E)}`))}_=M,S.info(w.dim("\u{1F9F9} Cleaning workspace (preserving dependency cache)..."));try{let E=process.cwd(),P=new Set(["node_modules"]),B=C.readdirSync(E),W=0;for(let z of B)if(!P.has(z)){if(z==="ios"){let ye=y.join(E,"ios"),ue=C.readdirSync(ye);for(let be of ue)if(be!=="Pods")try{C.rmSync(y.join(ye,be),{recursive:!0,force:!0}),W++}catch{}continue}try{C.rmSync(y.join(E,z),{recursive:!0,force:!0}),W++}catch{}}S.info(w.dim(` Cleaned ${W} items. Cached: node_modules${C.existsSync(y.join(E,"ios","Pods"))?", ios/Pods":""}`)),S.info(w.green("\u{1F512} Security: No source code retained on build server. Only public dependencies cached."))}catch{S.warn(w.yellow("Post-build cleanup encountered errors (non-fatal)."))}try{let P=y.join(he.homedir(),A.workspacesDir),B=J(`df -k "${P}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim(),W=parseInt(B,10)*1024;if(W<53687091200&&C.existsSync(P)){S.info(w.dim(` \u26A0\uFE0F Low disk space (${(W/1024/1024/1024).toFixed(0)} GB free). Running cache eviction...`));let z=y.basename(process.cwd()),ye=C.readdirSync(P).filter(ue=>ue!==z).map(ue=>{let be=y.join(P,ue);try{let tt=C.statSync(be);return tt.isDirectory()?{name:ue,dir:be,mtime:tt.mtimeMs}:null}catch{return null}}).filter(Boolean);ye.sort((ue,be)=>ue.mtime-be.mtime);for(let ue of ye){if(W>=53687091200)break;try{C.rmSync(ue.dir,{recursive:!0,force:!0}),S.info(w.dim(` \u{1F5D1}\uFE0F Evicted stale workspace: ${ue.name}`));let be=J(`df -k "${P}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim();if(parseInt(be,10)*1024>=53687091200)break}catch{}}}}catch{}return await V(),_}catch(k){throw await V(),k.message==="Command aborted"?(S.warn(w.yellow(`
345
+ \u274C Build aborted.`)),await f("failed",{error:"Aborted by user",endTime:Date.now()}),k):(S.error(w.red(`
346
+ \u2717 Local build failed: ${k.message}`)),await f("failed",{error:k.message,endTime:Date.now()}),k)}},Uo=async(e,t,n={},i,r)=>{let o=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),s=y.join(o.appRoot,"android"),a=y.join(o.appRoot,"gradlew"),c=y.join(s,"gradlew"),l=C.existsSync(c)?c:C.existsSync(a)?a:null;if(!l)throw new Error(`Could not find gradlew inside appDirectory "${o.appDirectory}".`);let p=e.developmentClient?"assembleDebug":"assembleRelease";!e.developmentClient&&e.distribution==="store"?p="bundleRelease":!e.developmentClient&&e.distribution==="internal"&&(p="assembleRelease");let d=e.buildCommand||p;S.info(w.blue(`Running Android build: ${d}...`));let u=l===c?s:o.appRoot,h="./gradlew",f=[d],v=bt(e.framework),b={...n,...v.localAndroidEnv(e,t),MACH_APP_NAME:e.appName||e.name||"App",MACH_APP_DIRECTORY:o.appDirectory,MACH_SOURCE_ROOT:o.sourceRoot,MACH_APP_ROOT:o.appRoot},x=e.resolvedVersionCode||n.ANDROID_VERSION_CODE,N=x?Te(x,"resolved MACH build assignment"):null;N&&(f.push(`-Pandroid.injected.version.code=${N}`),b.ANDROID_VERSION_CODE=N,S.info(w.green(`\u2713 Applying Android versionCode ${N}`)));for(let $ of["app/build","build",".cxx"]){let G=y.join(u,$);C.existsSync(G)&&C.rmSync(G,{recursive:!0,force:!0})}lt(o.appRoot),o.appRoot!==o.sourceRoot&&lt(o.sourceRoot),await je(h,f,u,b,i,r);let I=y.join(u,"app/build/outputs"),R=qe(I,[".apk",".aab"]);if(N&&R.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${N}.`);if(N)for(let $ of R){let G=ln($,N);S.info(w.dim(`Validated Android versionCode ${G} in ${y.basename($)}`)),i?.(`[ANDROID VALID] ${y.basename($)} versionCode ${G} matches MACH assignment
347
+ `)}return R},Lo=async(e,t,n,i={},r,o,s,a,c)=>{if(process.platform!=="darwin")throw new Error("iOS builds can only be run on macOS.");let l=ct(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),p=y.join(l.appRoot,"ios");if(!C.existsSync(p))throw new Error(`Could not find ios/ inside appDirectory "${l.appDirectory}".`);pi(p);let d=C.readdirSync(p),u=d.find(G=>G.endsWith(".xcworkspace")),h=d.find(G=>G.endsWith(".xcodeproj")),f={...rn(i,n,e),MACH_SOURCE_ROOT:l.sourceRoot,MACH_APP_ROOT:l.appRoot};Ii(p,f,o);let v=e.resolvedBuildNumber||f.BUILD_NUMBER||f.CURRENT_PROJECT_VERSION,b=wt(v);if(v&&!b)throw new Error(`Invalid iOS build number: "${v}". Apple requires one to three period-separated integers. Fix the Dashboard secret or remove it so Mach can use its auto build number.`);let x=b?[`BUILD_NUMBER=${b}`,`CURRENT_PROJECT_VERSION=${b}`,`INFOPLIST_KEY_CFBundleVersion=${b}`]:[];if(b&&(f.BUILD_NUMBER=b,f.CURRENT_PROJECT_VERSION=b,S.info(w.dim(`Using iOS build number: ${b}`))),!u&&!h)throw new Error("Could not find Xcode workspace or project in ios/ directory.");try{let G=J("xcode-select -p").toString().trim();S.info(w.dim(`Using Xcode at: ${G}`))}catch{S.warn(w.dim("Could not detect Xcode path."))}S.info(w.blue("Running iOS build via xcodebuild..."));let N=u?u.replace(".xcworkspace",""):h?.replace(".xcodeproj",""),I=e.iosScheme||N||e.scheme,R=e.developmentClient?"Debug":e.iosConfiguration||"Release",$;try{if(b){$=Jn(p,b,{workspace:u,project:h,scheme:I,configuration:R});let T=$.plistPaths.length>0?`${$.plistPaths.length} Xcode target Info.plist file(s)`:"generated Info.plist build settings";S.info(w.green(`\u2713 Applied iOS buildNumber ${b} to ${T}`)),o&&o(`[VERSIONING] Applied iOS buildNumber ${b} to ${T}
348
+ `)}let G=(r||"default").replace(/[^a-zA-Z0-9-_]/g,"_"),V=y.join(he.homedir(),`Library/Developer/Xcode/DerivedData/${A.nameLower}`,G);C.mkdirSync(V,{recursive:!0});let D=Xn(f),F=y.join(V,".mach-env-hash"),U=y.join(V,"Build"),k=C.existsSync(F)?C.readFileSync(F,"utf-8").trim():"";if(C.existsSync(U)){let T=k&&k!==D?"Build environment changed \u2014 clearing iOS DerivedData build products.":k?"Clearing iOS DerivedData build products to force a fresh JS bundle.":"DerivedData has no environment stamp \u2014 clearing iOS build products.";S.info(w.dim(T)),C.rmSync(U,{recursive:!0,force:!0})}if(C.writeFileSync(F,D),lt(l.appRoot),l.appRoot!==l.sourceRoot&&lt(l.sourceRoot),e.simulator){let T=Oo(p,u,h,I,R),H=T||"generic/platform=iOS Simulator",oe=["-destination",H];S.info(w.dim(T?`Building for simulator (Scheme: ${I}, Config: ${R}, Destination: ${H})...`:`Building for simulator (Scheme: ${I}, Config: ${R}, Destination: ${H})...`));let me=[u?"-workspace":"-project",u||h,"-scheme",I,"-configuration",R,"-sdk","iphonesimulator",...oe,"-derivedDataPath",V,...x,"COMPILER_INDEX_STORE_ENABLE=NO","CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","ONLY_ACTIVE_ARCH=NO","EXCLUDED_ARCHS=","SUPPORTED_PLATFORMS=iphonesimulator"];try{await kt(me,p,f,o,s)}catch(E){if(!_o(E))throw E;Fo(V),lt(l.appRoot),l.appRoot!==l.sourceRoot&&lt(l.sourceRoot),await kt(me,p,f,o,s)}let ae=y.join(V,"Build/Products",`${R}-iphonesimulator`),ee=Vo(ae,I,e),ce=y.basename(ee,".app"),se=dt(y.join(ee,"Info.plist"),"CFBundleIdentifier")||"unknown bundle",De=si(ee,b||void 0)[0].buildNumber,_=gi(ee),L=hi(ee),M=y.join(ae,`${ce}_simulator.zip`);return S.info(w.dim(`Selected simulator app: ${y.relative(ae,ee)} (${se}, build ${De})`)),S.info(w.dim(`Simulator executable architecture: ${_}`)),S.info(w.dim(`Simulator executable platform: ${L.split(`
349
+ `).find(E=>/\bplatform\b/i.test(E))?.trim()||"IOSSIMULATOR"}`)),S.info(w.dim(`Creating simulator artifact: ${M}...`)),$e(M),Me("zip",["-r",M,y.basename(ee)],{cwd:y.dirname(ee),stdio:"pipe"}),[M]}else{S.info(w.dim(`Archiving (Scheme: ${I}, Config: ${R})...`));let T=y.join(p,"build.xcarchive"),H=y.join(p,"export");C.rmSync(T,{recursive:!0,force:!0}),C.rmSync(H,{recursive:!0,force:!0});let oe=i.IOS_DIST_P12,me=i.IOS_PROVISIONING_PROFILE,ae=i.IOS_P12_PASSWORD||"",ee=[],ce,se,Ce={isAppStore:!1,isDevelopment:!1};if(oe&&me){S.info(w.blue("\u{1F510} CI/CD Signing: Importing certificates..."));try{let W=`${A.buildPrefix}-${t}.keychain-db`,z=y.join(he.tmpdir(),W),ye=A.keychainPassword;J(`security create-keychain -p "${ye}" "${z}" 2>/dev/null || true`),J(`security set-keychain-settings -t 3600 -l "${z}"`),J(`security unlock-keychain -p "${ye}" "${z}"`);let ue=y.join(he.tmpdir(),`cert-${t}.p12`),be=Buffer.from(oe,"base64");C.writeFileSync(ue,be),S.info(w.dim(`P12 data size: ${be.length} bytes, first bytes: ${be.slice(0,4).toString("hex")}`)),(be.length<100||be[0]!==48)&&(S.warn(w.yellow("\u26A0\uFE0F P12 data looks corrupted or was not decrypted correctly.")),S.warn(w.yellow(" This usually means MACH_ENCRYPTION_KEY on the Remote API differs from when credentials were uploaded.")));let tt=[ae,"",A.keychainPassword],Sn=!1;for(let we of tt)try{J(`security import "${ue}" -k "${z}" -P "${we}" -A -T /usr/bin/codesign -T /usr/bin/security`,{stdio:"pipe"}),Sn=!0,S.info(w.dim(`\u2713 P12 imported successfully with password: ${we?"[set]":"[empty]"}`));break}catch(Fe){S.info(w.dim(` P12 import attempt with password ${we?`"${we.substring(0,3)}..."`:"[empty]"} failed: ${Fe.message?.split(`
350
+ `)[0]||"unknown"}`))}if(!Sn)throw new Error("Failed to import P12.");C.unlinkSync(ue),J(`security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${ye}" "${z}"`);let tr=J("security list-keychains -d user",{encoding:"utf-8"}).split(`
351
+ `).map(we=>we.trim().replace(/^"|"$/g,"")).filter(we=>we.length>0),nr=[z,...tr].map(we=>`"${we}"`).join(" ");J(`security list-keychains -d user -s ${nr}`),J(`security default-keychain -s "${z}"`);let Zt=y.join(he.homedir(),"Library/MobileDevice/Provisioning Profiles");C.mkdirSync(Zt,{recursive:!0});let vn=Buffer.from(me,"base64"),Mt=y.join(Zt,`${A.nameLower}-temp-${t}.mobileprovision`);C.writeFileSync(Mt,vn);let jt=vn.toString("utf-8"),En=/<key>get-task-allow<\/key>\s*<true\/>/.test(jt);Ce={isAppStore:!jt.includes("<key>ProvisionedDevices</key>")&&!En,isDevelopment:En};try{let Fe=J(`security cms -D -i "${Mt}"`,{encoding:"utf-8"}).match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);se=Fe?Fe[1]:void 0}catch{let Fe=jt.match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);se=Fe?Fe[1]:void 0}se||(S.warn("Could not extract UUID from provisioning profile. Using fallback."),se=`${A.nameLower}-${t}`);let Gt=y.join(Zt,`${se}.mobileprovision`);C.existsSync(Gt)&&C.unlinkSync(Gt),C.renameSync(Mt,Gt);try{let we=J(`security find-identity -v -p codesigning "${z}"`,{encoding:"utf-8"}),Fe=Array.from(we.matchAll(/"((?:Apple|iPhone) (?:Distribution|Developer|Development)[^"]*)"/g),gt=>gt[1]),Pn=Ce.isDevelopment?Fe.find(gt=>/\b(Development|Developer)\b/.test(gt)):Fe.find(gt=>/\bDistribution\b/.test(gt)),Nn=Fe[0];(Pn||Nn)&&(ce=Pn||Nn,S.info(w.blue(`Identity auto-detected from keychain: "${ce}"`)))}catch{}ce||(ce=Ce.isDevelopment?"Apple Development":"Apple Distribution",S.info(w.blue(`Identity fallback (profile heuristic): "${ce}"`))),S.info(w.dim(`Profile type: ${Ce.isDevelopment?"Development":Ce.isAppStore?"App Store":"Ad-Hoc"}`)),S.info(w.dim(`Identity Detection: get-task-allow=${Ce.isDevelopment}, Selected Identity="${ce}"`)),ee.push("CODE_SIGN_STYLE=Manual"),ee.push(`CODE_SIGN_IDENTITY="${ce}"`),ee.push(`PROVISIONING_PROFILE_SPECIFIER=${se}`),e.iosTeamId&&ee.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`)}catch(W){throw S.error(`Signing setup failed: ${W.message}`),W}}else ee.push("-allowProvisioningUpdates"),e.iosTeamId&&ee.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`);c&&await c("archive"),S.info(w.blue(`Archive detected Identity: "${ce}"`)),S.info(w.blue(`Archive detected UUID: "${se}"`)),await kt(["archive",u?"-workspace":"-project",u||h,"-scheme",I,"-configuration",R,"-archivePath",T,"-derivedDataPath",V,...x,...ee],p,f,o,s);let De=qe(y.join(T,"Products","Applications"),[".app"]);for(let W of De)for(let z of si(W,b||void 0))S.info(w.dim(`Validated iOS CFBundleVersion ${z.buildNumber} in ${y.basename(z.bundlePath)}`));let _;se?(Ce.isAppStore?_="app-store":Ce.isDevelopment?_="development":_="ad-hoc",S.info(w.blue(`Export method from profile: "${_}"`))):(_=e.distribution==="store"?"app-store":e.distribution==="internal"?"ad-hoc":"development",S.warn(w.yellow(`No profile UUID detected. Export method from distribution flag: "${_}"`)));let L=e.iosExportMethod||_,M=e.iosBundleIdentifier||pt("ios"),E=y.join(p,"ExportOptions.plist"),P=`<?xml version="1.0" encoding="UTF-8"?>
352
352
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
353
353
  <plist version="1.0">
354
354
  <dict>
355
355
  <key>method</key>
356
- <string>${U}</string>
356
+ <string>${L}</string>
357
357
  <key>destination</key>
358
358
  <string>export</string>
359
359
  <key>signingStyle</key>
@@ -369,45 +369,45 @@ ${s.join(`
369
369
  </dict>`:""}
370
370
  </dict>
371
371
  </plist>`;if(C.writeFileSync(E,P),process.env[`${A.envPrefix}DEBUG`]&&S.info(w.magenta(`[${A.nameUpper}_DEBUG] ExportOptions.plist:
372
- ${P}`)),c&&await c("export"),S.info(w.blue(`Exporting with Bundle ID: "${M}"`)),S.info(w.blue(`Exporting with Method: "${U}"`)),o){o(w.magenta(`
372
+ ${P}`)),c&&await c("export"),S.info(w.blue(`Exporting with Bundle ID: "${M}"`)),S.info(w.blue(`Exporting with Method: "${L}"`)),o){o(w.magenta(`
373
373
  [DIAGNOSTIC] Checking available signing identities...
374
374
  `));try{let W=J("security find-identity -v -p codesigning",{encoding:"utf-8"});o(w.magenta(`${W}
375
375
  `))}catch(W){o(w.red(`[DIAGNOSTIC] Failed to list identities: ${W.message}
376
- `))}}await kt(["-exportArchive","-archivePath",T,"-exportPath",X,"-exportOptionsPlist",E],p,f,o,s),c&&await c("validate");let D=qe(X,[".ipa"]);for(let W of D)try{J(`unzip -t "${W}"`,{stdio:"pipe"});let z=yi(W,b||void 0);o&&o(`[IPA VALID] ${I.basename(W)} \u2014 archive integrity OK
376
+ `))}}await kt(["-exportArchive","-archivePath",T,"-exportPath",H,"-exportOptionsPlist",E],p,f,o,s),c&&await c("validate");let B=qe(H,[".ipa"]);for(let W of B)try{J(`unzip -t "${W}"`,{stdio:"pipe"});let z=yi(W,b||void 0);o&&o(`[IPA VALID] ${y.basename(W)} \u2014 archive integrity OK
377
377
  `),o&&o(`[IPA VALID] CFBundleVersion ${z}
378
- `)}catch(z){let ye=`IPA validation failed for ${I.basename(W)}: ${z.message||"archive may be corrupt"}`;throw o&&o(`[IPA CORRUPT] ${ye}
379
- `),new Error(ye)}return D}}finally{$?.restore()}},pt=(e,t)=>{try{let n=I.join(process.cwd(),A.configFileName),i={};if(C.existsSync(n)){if(i=JSON.parse(C.readFileSync(n,"utf-8")),e==="android"&&i.android?.package)return i.android.package;if(e==="ios"&&i.ios?.bundleIdentifier)return i.ios.bundleIdentifier}let o=ct(process.cwd(),t??i.appDirectory).appRoot;if(e==="android"){let s=["android/app/build.gradle","app/build.gradle","build.gradle"];for(let a of s){let c=I.join(o,a);if(C.existsSync(c)){let p=C.readFileSync(c,"utf-8").match(/applicationId\s+['"]([^'"]+)['"]/);if(p)return p[1]}}}else{let s=I.join(o,"ios"),a=C.existsSync(s)?s:o,c=qe(a,["Info.plist"]).filter(d=>!d.includes("/Pods/")&&!d.includes("/build/")&&!d.includes("/DerivedData/"));c.sort((d,u)=>u.split("/").length-d.split("/").length);for(let d of c){let h=C.readFileSync(d,"utf-8").match(/<key>CFBundleIdentifier<\/key>\s*<string>([^<]+)<\/string>/);if(h&&!h[1].includes("$"))return h[1]}let l=qe(a,[".xcodeproj"]);if(l.length>0){let d=I.join(l[0],"project.pbxproj");if(C.existsSync(d)){let h=C.readFileSync(d,"utf-8").match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/);if(h)return h[1]}}let p=["app.json","app.config.json","app.config.js","app.config.ts"];for(let d of p){let u=I.join(o,d);if(C.existsSync(u)){let f=C.readFileSync(u,"utf-8").match(/"bundleIdentifier":\s*"([^"]+)"/);if(f)return f[1]}}}}catch{return null}return null},Lo=()=>{try{return J("emulator -version",{stdio:"ignore"}),"emulator"}catch{let t=he.homedir(),n=[I.join(t,"Library/Android/sdk/emulator/emulator"),I.join(t,"Android/Sdk/emulator/emulator"),"/usr/local/lib/android/sdk/emulator/emulator"];for(let i of n)if(C.existsSync(i))return i}return"emulator"},Xo=async(e,t)=>{let n=xt();try{if(J("adb devices").toString().split(`
380
- `).slice(1).map(s=>s.trim()).filter(s=>s.length>0&&!s.startsWith("*")).map(s=>s.split(" ")[0]).length===0){S.warn(w.yellow("No Android devices or emulators found."));let s=Lo(),a=[];try{a=J(`${s} -list-avds`).toString().split(`
378
+ `)}catch(z){let ye=`IPA validation failed for ${y.basename(W)}: ${z.message||"archive may be corrupt"}`;throw o&&o(`[IPA CORRUPT] ${ye}
379
+ `),new Error(ye)}return B}}finally{$?.restore()}},pt=(e,t)=>{try{let n=y.join(process.cwd(),A.configFileName),i={};if(C.existsSync(n)){if(i=JSON.parse(C.readFileSync(n,"utf-8")),e==="android"&&i.android?.package)return i.android.package;if(e==="ios"&&i.ios?.bundleIdentifier)return i.ios.bundleIdentifier}let o=ct(process.cwd(),t??i.appDirectory).appRoot;if(e==="android"){let s=["android/app/build.gradle","app/build.gradle","build.gradle"];for(let a of s){let c=y.join(o,a);if(C.existsSync(c)){let p=C.readFileSync(c,"utf-8").match(/applicationId\s+['"]([^'"]+)['"]/);if(p)return p[1]}}}else{let s=y.join(o,"ios"),a=C.existsSync(s)?s:o,c=qe(a,["Info.plist"]).filter(d=>!d.includes("/Pods/")&&!d.includes("/build/")&&!d.includes("/DerivedData/"));c.sort((d,u)=>u.split("/").length-d.split("/").length);for(let d of c){let h=C.readFileSync(d,"utf-8").match(/<key>CFBundleIdentifier<\/key>\s*<string>([^<]+)<\/string>/);if(h&&!h[1].includes("$"))return h[1]}let l=qe(a,[".xcodeproj"]);if(l.length>0){let d=y.join(l[0],"project.pbxproj");if(C.existsSync(d)){let h=C.readFileSync(d,"utf-8").match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/);if(h)return h[1]}}let p=["app.json","app.config.json","app.config.js","app.config.ts"];for(let d of p){let u=y.join(o,d);if(C.existsSync(u)){let f=C.readFileSync(u,"utf-8").match(/"bundleIdentifier":\s*"([^"]+)"/);if(f)return f[1]}}}}catch{return null}return null},Xo=()=>{try{return J("emulator -version",{stdio:"ignore"}),"emulator"}catch{let t=he.homedir(),n=[y.join(t,"Library/Android/sdk/emulator/emulator"),y.join(t,"Android/Sdk/emulator/emulator"),"/usr/local/lib/android/sdk/emulator/emulator"];for(let i of n)if(C.existsSync(i))return i}return"emulator"},Ho=async(e,t)=>{let n=xt();try{if(J("adb devices").toString().split(`
380
+ `).slice(1).map(s=>s.trim()).filter(s=>s.length>0&&!s.startsWith("*")).map(s=>s.split(" ")[0]).length===0){S.warn(w.yellow("No Android devices or emulators found."));let s=Xo(),a=[];try{a=J(`${s} -list-avds`).toString().split(`
381
381
  `).filter(c=>c.trim().length>0)}catch{}if(a.length>0){let c=await pn({message:"Select an emulator to launch:",options:a.map(d=>({value:d,label:d}))});if($t(c))return;n.start(`Launching emulator ${c}...`),ai(s,["-avd",c],{detached:!0,stdio:"ignore"}).unref();let l=0,p=!1;for(;l<60;){try{if(J("adb shell getprop sys.boot_completed",{stdio:"pipe"}).toString().trim()==="1"){p=!0;break}}catch{}await new Promise(d=>setTimeout(d,2e3)),l++}if(!p)throw n.stop("Emulator launch timed out."),new Error("Emulator launch timed out. Please try launching it manually.");n.stop("Emulator launched.")}else throw new Error("No devices found and no emulators available to launch. (Make sure Android SDK is installed)")}n.start("Installing APK on device..."),await je("adb",["install","-r",e],process.cwd(),{},t),n.stop("Installation complete.");let o=pt("android");if(o){S.info(w.blue(`\u{1F680} Launching ${o}...`));try{J(`adb shell dumpsys package ${o}`).toString().split(`
382
- `).find(c=>c.includes("android.intent.action.MAIN")&&c.includes("android.intent.category.LAUNCHER"))?J(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"}):J(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"})}catch{S.warn("Could not auto-launch app. You may need to open it manually.")}}}catch(i){n.stop("Installation failed."),S.error(w.red(`Failed to install APK: ${i.message}`))}},Ho=async(e,t,n)=>{let i=xt();try{if(!J("xcrun simctl list devices booted").toString().includes("(Booted)")){S.warn(w.yellow("No iOS Simulator is currently booted."));let o=J("xcrun simctl list devices --json").toString(),s=JSON.parse(o).devices,a=[];Object.keys(s).forEach(d=>{s[d].forEach(u=>{u.isAvailable&&a.push({...u,runtime:d})})});let c=await pn({message:"Select a simulator to launch:",options:a.map(d=>({value:d.udid,label:`${d.name} (${d.runtime.split(".").pop()})`}))});if($t(c))return;i.start(`Booting ${c}...`),J(`xcrun simctl boot ${c}`),J(`open -a Simulator --args -CurrentDeviceUDID ${c}`);let l=0,p=!1;for(;l<30;){try{if(J("xcrun simctl list devices booted").toString().includes(c)){p=!0;break}}catch{}await new Promise(d=>setTimeout(d,2e3)),l++}if(!p)throw i.stop("Simulator boot timed out."),new Error("Simulator boot timed out.");i.stop("Simulator booted.")}i.start("Installing on iOS Simulator..."),gi(e),hi(e),await je("xcrun",["simctl","install","booted",e],process.cwd(),{},n),i.stop("Installation complete."),S.info(w.blue(`\u{1F680} Launching ${t}...`)),await je("xcrun",["simctl","launch","booted",t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),S.error(w.red(`Failed to install on Simulator: ${r.message}`))}},Ko=async(e,t,n)=>{let i=xt();i.start("Scanning for connected iOS devices...");try{let r=J("xcrun devicectl list devices --json-output -").toString(),s=(JSON.parse(r).result?.devices||[]).filter(c=>c.connectionProperties?.transportType==="wired"||c.connectionProperties?.transportType==="localNetwork");if(s.length===0)throw i.stop("No connected iOS devices found."),new Error("Please connect your iPhone via USB or ensure it is on the same Wi-Fi for wireless debugging.");let a=s[0].identifier;if(s.length>1){i.stop();let c=await pn({message:"Select a device to install on:",options:s.map(l=>({value:l.identifier,label:`${l.deviceProperties?.name||l.name||l.model?.name} (${l.model?.name||"iPhone"}) - ${l.identifier}`}))});if($t(c))return;a=c,i.start(`Installing on ${a}...`)}else i.message(`Installing on ${s[0].model.name}...`);await je("xcrun",["devicectl","device","install","app","--device",a,e],process.cwd(),{},n),i.stop("Installation complete."),S.info(w.blue(`\u{1F680} Launching ${t}...`)),await je("xcrun",["devicectl","device","launch","app","--device",a,t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),S.error(w.red(`Failed to install on device: ${r.message}`)),S.info(w.dim('Make sure your device is unlocked and "Developer Mode" is enabled in Settings -> Privacy & Security.'))}};import{createRequire as Jo}from"module";var Yo=Jo(import.meta.url),zo=Yo("../package.json"),fn=String(zo.version||"0.0.0");var Si="https://mach-api.securejs.in",qo=["google-services.json","android/app/google-services.json"],Ai="0.1.4";function es(){return Ae.join(process.cwd(),A.configFileName)}function Ft(){let e=$n();if(!e?.projectId)throw new Error(`No linked MACH project. Run \`${A.nameLower} link\` first.`);return e}function vi(e){le.writeFileSync(es(),`${JSON.stringify(e,null,2)}
383
- `)}function ts(){return mn(Ae.join(process.cwd(),"package.json"))}function mn(e){if(!le.existsSync(e))return null;try{return JSON.parse(le.readFileSync(e,"utf8"))}catch{return null}}function ns(e){let t=ts();return!!(t?.dependencies?.[e]||t?.devDependencies?.[e])}function gn(e){let t=process.cwd(),n=mn(Ae.join(t,"node_modules",...e.split("/"),"package.json"));if(typeof n?.version=="string")return n.version;let r=mn(Ae.join(t,"package-lock.json"))?.packages?.[`node_modules/${e}`]?.version;return typeof r=="string"?r:void 0}function is(e,t){let n=o=>o.replace(/^v/,"").split(/[.-]/).slice(0,3).map(s=>Number.parseInt(s,10)||0),i=n(e),r=n(t);for(let o=0;o<3;o+=1)if(i[o]!==r[o])return i[o]>r[o]?1:-1;return 0}function Ci(e,t){let n=gn(e);return!ns(e)||!n||is(n,t)<0}function rs(e,t=!1){let n=process.cwd();return le.existsSync(Ae.join(n,"pnpm-lock.yaml"))?{command:"pnpm",args:["add",...t?["-D"]:[],e],label:`pnpm add ${t?"-D ":""}${e}`}:le.existsSync(Ae.join(n,"yarn.lock"))?{command:"yarn",args:["add",...t?["-D"]:[],e],label:`yarn add ${t?"-D ":""}${e}`}:le.existsSync(Ae.join(n,"bun.lock"))||le.existsSync(Ae.join(n,"bun.lockb"))?{command:"bun",args:["add",...t?["-d"]:[],e],label:`bun add ${t?"-d ":""}${e}`}:{command:"npm",args:["install",...t?["--save-dev"]:["--save"],"--no-audit","--no-fund",e],label:`npm install ${t?"--save-dev ":"--save "}${e} --no-audit --no-fund`}}function bi(e,t=!1){let n=rs(e,t);console.log(q.dim(`Installing dependency: ${n.label}`));let i=Qo(n.command,n.args,{cwd:process.cwd(),stdio:"inherit",timeout:12e4,env:{...process.env,NPM_CONFIG_AUDIT:"false",NPM_CONFIG_FUND:"false"}});return i.signal==="SIGTERM"?{ok:!1,note:`${n.label} timed out after 120s. Run it manually, or re-run \`${A.nameLower} push setup --skip-install\` to only generate files.`}:i.error||i.status!==0?{ok:!1,note:`${n.label} failed${i.error?`: ${i.error.message}`:` with code ${i.status}`}.`}:{ok:!0,note:`Installed with ${n.label}.`}}function os(e,t){let n=[];if(t)return n.push("Dependency installation skipped."),n;if(Ci("@radhya/mach-push-react-native",Ai)){let i=bi(`@radhya/mach-push-react-native@${Ai}`);if(!i.ok)throw new Error(`${i.note} No application files were wired.`);n.push(i.note)}else n.push(`@radhya/mach-push-react-native is already current (${gn("@radhya/mach-push-react-native")}).`);if(e==="expo")if(Ci("@radhya/mach",fn)){let i=bi(`@radhya/mach@${fn}`,!0);if(!i.ok)throw new Error(`${i.note} No Expo configuration was changed.`);n.push(i.note)}else n.push(`@radhya/mach is already current for the Expo config (${gn("@radhya/mach")}).`);return n}function ss(e,t){return e||t||["google-services.json","android/app/google-services.json"].find(n=>le.existsSync(Ae.join(process.cwd(),n)))}function Ei(e){let t={enabled:!0};return e.appId&&e.publishableKey&&(t.appId=e.appId,t.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!==Si&&(t.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(t.environment=e.environment),e.googleServicesFile&&!qo.includes(e.googleServicesFile)&&(t.googleServicesFile=e.googleServicesFile),t}function as(e){return e==="development"?"development":"production"}function Pi(e){let t=process.cwd(),n=e==="ios"?"bundleIdentifier":"package";for(let i of["app.json","app.config.json"]){let r=Ae.join(t,i);if(le.existsSync(r))try{let o=JSON.parse(le.readFileSync(r,"utf8")),a=(o.expo&&typeof o.expo=="object"?o.expo:o)?.[e]?.[n];if(typeof a=="string"&&a.trim())return a.trim()}catch{}}for(let i of["app.config.ts","app.config.js"]){let r=Ae.join(t,i);if(!le.existsSync(r))continue;let s=le.readFileSync(r,"utf8").match(new RegExp(`${n}\\s*:\\s*['"]([^'"]+)['"]`));if(s?.[1])return s[1]}}function Ni(e,t){return t||Ge(e)||Pi("ios")||pt("ios")||void 0}function Ri(e,t){return t||it(e)||Pi("android")||pt("android")||void 0}function cs(e,t){let n=le.readFileSync(e,"utf8");if(n.includes(t))return"already";let i=/(^[ \t]*)plugins\s*:\s*\[([\s\S]*?)\]/m.exec(n);if(!i||i.index===void 0)return"manual";let r=n.includes(`\r
382
+ `).find(c=>c.includes("android.intent.action.MAIN")&&c.includes("android.intent.category.LAUNCHER"))?J(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"}):J(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"})}catch{S.warn("Could not auto-launch app. You may need to open it manually.")}}}catch(i){n.stop("Installation failed."),S.error(w.red(`Failed to install APK: ${i.message}`))}},Ko=async(e,t,n)=>{let i=xt();try{if(!J("xcrun simctl list devices booted").toString().includes("(Booted)")){S.warn(w.yellow("No iOS Simulator is currently booted."));let o=J("xcrun simctl list devices --json").toString(),s=JSON.parse(o).devices,a=[];Object.keys(s).forEach(d=>{s[d].forEach(u=>{u.isAvailable&&a.push({...u,runtime:d})})});let c=await pn({message:"Select a simulator to launch:",options:a.map(d=>({value:d.udid,label:`${d.name} (${d.runtime.split(".").pop()})`}))});if($t(c))return;i.start(`Booting ${c}...`),J(`xcrun simctl boot ${c}`),J(`open -a Simulator --args -CurrentDeviceUDID ${c}`);let l=0,p=!1;for(;l<30;){try{if(J("xcrun simctl list devices booted").toString().includes(c)){p=!0;break}}catch{}await new Promise(d=>setTimeout(d,2e3)),l++}if(!p)throw i.stop("Simulator boot timed out."),new Error("Simulator boot timed out.");i.stop("Simulator booted.")}i.start("Installing on iOS Simulator..."),gi(e),hi(e),await je("xcrun",["simctl","install","booted",e],process.cwd(),{},n),i.stop("Installation complete."),S.info(w.blue(`\u{1F680} Launching ${t}...`)),await je("xcrun",["simctl","launch","booted",t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),S.error(w.red(`Failed to install on Simulator: ${r.message}`))}},Jo=async(e,t,n)=>{let i=xt();i.start("Scanning for connected iOS devices...");try{let r=J("xcrun devicectl list devices --json-output -").toString(),s=(JSON.parse(r).result?.devices||[]).filter(c=>c.connectionProperties?.transportType==="wired"||c.connectionProperties?.transportType==="localNetwork");if(s.length===0)throw i.stop("No connected iOS devices found."),new Error("Please connect your iPhone via USB or ensure it is on the same Wi-Fi for wireless debugging.");let a=s[0].identifier;if(s.length>1){i.stop();let c=await pn({message:"Select a device to install on:",options:s.map(l=>({value:l.identifier,label:`${l.deviceProperties?.name||l.name||l.model?.name} (${l.model?.name||"iPhone"}) - ${l.identifier}`}))});if($t(c))return;a=c,i.start(`Installing on ${a}...`)}else i.message(`Installing on ${s[0].model.name}...`);await je("xcrun",["devicectl","device","install","app","--device",a,e],process.cwd(),{},n),i.stop("Installation complete."),S.info(w.blue(`\u{1F680} Launching ${t}...`)),await je("xcrun",["devicectl","device","launch","app","--device",a,t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),S.error(w.red(`Failed to install on device: ${r.message}`)),S.info(w.dim('Make sure your device is unlocked and "Developer Mode" is enabled in Settings -> Privacy & Security.'))}};import{createRequire as Yo}from"module";var zo=Yo(import.meta.url),Qo=zo("../package.json"),fn=String(Qo.version||"0.0.0");var Si="https://mach-api.securejs.in",es=["google-services.json","android/app/google-services.json"],Ai="0.1.4";function ts(){return Ae.join(process.cwd(),A.configFileName)}function Ft(){let e=$n();if(!e?.projectId)throw new Error(`No linked MACH project. Run \`${A.nameLower} link\` first.`);return e}function vi(e){le.writeFileSync(ts(),`${JSON.stringify(e,null,2)}
383
+ `)}function ns(){return mn(Ae.join(process.cwd(),"package.json"))}function mn(e){if(!le.existsSync(e))return null;try{return JSON.parse(le.readFileSync(e,"utf8"))}catch{return null}}function is(e){let t=ns();return!!(t?.dependencies?.[e]||t?.devDependencies?.[e])}function gn(e){let t=process.cwd(),n=mn(Ae.join(t,"node_modules",...e.split("/"),"package.json"));if(typeof n?.version=="string")return n.version;let r=mn(Ae.join(t,"package-lock.json"))?.packages?.[`node_modules/${e}`]?.version;return typeof r=="string"?r:void 0}function rs(e,t){let n=o=>o.replace(/^v/,"").split(/[.-]/).slice(0,3).map(s=>Number.parseInt(s,10)||0),i=n(e),r=n(t);for(let o=0;o<3;o+=1)if(i[o]!==r[o])return i[o]>r[o]?1:-1;return 0}function Ci(e,t){let n=gn(e);return!is(e)||!n||rs(n,t)<0}function os(e,t=!1){let n=process.cwd();return le.existsSync(Ae.join(n,"pnpm-lock.yaml"))?{command:"pnpm",args:["add",...t?["-D"]:[],e],label:`pnpm add ${t?"-D ":""}${e}`}:le.existsSync(Ae.join(n,"yarn.lock"))?{command:"yarn",args:["add",...t?["-D"]:[],e],label:`yarn add ${t?"-D ":""}${e}`}:le.existsSync(Ae.join(n,"bun.lock"))||le.existsSync(Ae.join(n,"bun.lockb"))?{command:"bun",args:["add",...t?["-d"]:[],e],label:`bun add ${t?"-d ":""}${e}`}:{command:"npm",args:["install",...t?["--save-dev"]:["--save"],"--no-audit","--no-fund",e],label:`npm install ${t?"--save-dev ":"--save "}${e} --no-audit --no-fund`}}function bi(e,t=!1){let n=os(e,t);console.log(q.dim(`Installing dependency: ${n.label}`));let i=qo(n.command,n.args,{cwd:process.cwd(),stdio:"inherit",timeout:12e4,env:{...process.env,NPM_CONFIG_AUDIT:"false",NPM_CONFIG_FUND:"false"}});return i.signal==="SIGTERM"?{ok:!1,note:`${n.label} timed out after 120s. Run it manually, or re-run \`${A.nameLower} push setup --skip-install\` to only generate files.`}:i.error||i.status!==0?{ok:!1,note:`${n.label} failed${i.error?`: ${i.error.message}`:` with code ${i.status}`}.`}:{ok:!0,note:`Installed with ${n.label}.`}}function ss(e,t){let n=[];if(t)return n.push("Dependency installation skipped."),n;if(Ci("@radhya/mach-push-react-native",Ai)){let i=bi(`@radhya/mach-push-react-native@${Ai}`);if(!i.ok)throw new Error(`${i.note} No application files were wired.`);n.push(i.note)}else n.push(`@radhya/mach-push-react-native is already current (${gn("@radhya/mach-push-react-native")}).`);if(e==="expo")if(Ci("@radhya/mach",fn)){let i=bi(`@radhya/mach@${fn}`,!0);if(!i.ok)throw new Error(`${i.note} No Expo configuration was changed.`);n.push(i.note)}else n.push(`@radhya/mach is already current for the Expo config (${gn("@radhya/mach")}).`);return n}function as(e,t){return e||t||["google-services.json","android/app/google-services.json"].find(n=>le.existsSync(Ae.join(process.cwd(),n)))}function Ei(e){let t={enabled:!0};return e.appId&&e.publishableKey&&(t.appId=e.appId,t.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!==Si&&(t.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(t.environment=e.environment),e.googleServicesFile&&!es.includes(e.googleServicesFile)&&(t.googleServicesFile=e.googleServicesFile),t}function cs(e){return e==="development"?"development":"production"}function Pi(e){let t=process.cwd(),n=e==="ios"?"bundleIdentifier":"package";for(let i of["app.json","app.config.json"]){let r=Ae.join(t,i);if(le.existsSync(r))try{let o=JSON.parse(le.readFileSync(r,"utf8")),a=(o.expo&&typeof o.expo=="object"?o.expo:o)?.[e]?.[n];if(typeof a=="string"&&a.trim())return a.trim()}catch{}}for(let i of["app.config.ts","app.config.js"]){let r=Ae.join(t,i);if(!le.existsSync(r))continue;let s=le.readFileSync(r,"utf8").match(new RegExp(`${n}\\s*:\\s*['"]([^'"]+)['"]`));if(s?.[1])return s[1]}}function Ni(e,t){return t||Ge(e)||Pi("ios")||pt("ios")||void 0}function Ri(e,t){return t||it(e)||Pi("android")||pt("android")||void 0}function ls(e,t){let n=le.readFileSync(e,"utf8");if(n.includes(t))return"already";let i=/(^[ \t]*)plugins\s*:\s*\[([\s\S]*?)\]/m.exec(n);if(!i||i.index===void 0)return"manual";let r=n.includes(`\r
384
384
  `)?`\r
385
385
  `:`
386
- `,o=i[1]||"",s=i[2]||"",a=s.match(/\r?\n([ \t]+)\S/)?.[1]||`${o} `,c=s.trim().length===0?`${r}${a}'${t}',${r}${o}`:`${r}${a}'${t}',${s}`,l=i[0].indexOf("["),p=`${i[0].slice(0,l+1)}${c}]`;return le.writeFileSync(e,`${n.slice(0,i.index)}${p}${n.slice(i.index+i[0].length)}`),"inserted"}function ki(){let e="@radhya/mach/expo-plugin",t=["app.config.ts","app.config.js"].find(c=>le.existsSync(Ae.join(process.cwd(),c)));if(t){let c=cs(Ae.join(process.cwd(),t),e);return c==="inserted"?`${t} now includes ${e}.`:c==="already"?`${t} already includes ${e}.`:`Add "${e}" to the plugins array in ${t}; MACH could not safely edit its computed configuration.`}let n=["app.config.json","app.json"].find(c=>le.existsSync(Ae.join(process.cwd(),c)));if(!n)return`Add "${e}" to the Expo plugins array.`;let i=Ae.join(process.cwd(),n),r=JSON.parse(le.readFileSync(i,"utf8")),o=r.expo&&typeof r.expo=="object"?r.expo:r,s=Array.isArray(o.plugins)?o.plugins:[];return s.some(c=>(Array.isArray(c)?c[0]:c)===e)?`${n} already includes ${e}.`:(o.plugins=[...s,e],le.writeFileSync(i,`${JSON.stringify(r,null,2)}
387
- `),`${n} now includes ${e}.`)}async function xi(e){let t=Ft(),n=e.app||t.push?.appId,i=e.environment||t.push?.environment||"production";if(n)return{config:t,appId:n,environment:i};let{data:r}=await Z.get(`/projects/${t.projectId}/push/overview?days=1`),s=(r?.apps||[]).filter(a=>a.status!=="disabled").sort((a,c)=>(c.updatedAt||0)-(a.updatedAt||0))[0]?.appId;if(!s)throw new Error(`Push is not configured. Run \`${A.nameLower} push setup\` first.`);return{config:t,appId:s,environment:i}}function wi(e){let t=Ae.resolve(e);if(!le.existsSync(t))throw new Error(`File not found: ${t}`);return t}function Et(e){let t=e?.response?.data?.message||e?.message||"Unknown error";console.error(q.red(t)),process.exitCode=1}async function Al(e){let t=_t();try{let n=Ft();if(Lt(n)==="flutter")throw new Error("MACH Push currently supports Expo and bare React Native. Flutter push support is planned for a later release.");let r=Ni(n,e.iosBundle),o=Ri(n,e.androidPackage);if(!r&&!o)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);t.start("Creating MACH Push app..."),await Z.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});let s=e.environment||"production";n.push=Ei({environment:s,googleServicesFile:e.googleServicesFile}),vi(n);let a=n.framework==="expo"?ki():void 0;t.stop(q.green("MACH Push app created.")),console.log(["",`${q.bold("Client config:")} ${A.configFileName} \u2192 push`,"","Install the mobile SDK:"," npm install @radhya/mach-push-react-native",...n.framework==="expo"?[" npm install --save-dev @radhya/mach",` ${a}`," Run npx expo prebuild."]:[],"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications.`].join(`
388
- `))}catch(n){t.stop(q.red("MACH Push setup failed.")),Et(n)}}async function Cl(e){let t=_t();try{let n=Ft(),i=Lt(n);if(i==="flutter")throw new Error("MACH Push currently supports Expo and bare React Native. Flutter push support is planned for a later release.");let r=Ni(n,e.iosBundle),o=Ri(n,e.androidPackage);if(!r&&!o)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);let s;t.start("Checking the MACH Push app...");let l=((await Z.get(`/projects/${n.projectId}/push/overview?days=1`)).data?.apps||[]).filter(y=>y.status!=="disabled").sort((y,N)=>(N.updatedAt||0)-(y.updatedAt||0)).find(y=>(!r||y.iosBundleId===r)&&(!o||y.androidPackageName===o));if(l)s=l.appId,t.stop(q.green("Existing MACH Push app linked."));else{let{data:y}=await Z.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});s=y.app.appId,t.stop(q.green("MACH Push app created."))}if(!s)throw new Error("MACH Push did not return a usable application.");let p=n.push,d=e.environment||p?.environment||"production",u=p?.apiUrl||Si,h=ss(e.googleServicesFile,p?.googleServicesFile);n.push=Ei({apiUrl:u,environment:d,googleServicesFile:h}),vi(n);let f=os(i,!!e.skipInstall),v=i==="expo"?ki():void 0;if(v?.startsWith('Add "'))throw new Error(v);let b={projectId:n.projectId,apiUrl:u,environment:d},R=Zn(process.cwd(),i,b);if(!R.entryFile)throw new Error(R.notes[0]||"MACH could not locate the application entry point.");let k=i==="expo"?{written:[],notes:[]}:jn(process.cwd(),{iosBundleId:r,iosEnvironment:as(d),googleServicesFile:h});console.log(["",q.green.bold("MACH Push basic setup is ready."),`${q.bold("Framework:")} ${i}`,`${q.bold("Client config:")} ${A.configFileName} \u2192 push`,`${q.bold("Automatic startup:")} ${R.entryFile||"manual entry import required"}`,`${q.bold("Customize callbacks:")} ${R.editableFile||"see the setup notes below"}`,"",...f.map(y=>`\u2022 ${y}`),...v?[`\u2022 ${v}`]:[],...R.notes.map(y=>`\u2022 ${y}`),...k.notes.map(y=>`\u2022 ${y}`),...[...R.written,...k.written].map(y=>`\u2022 Updated ${y}.`),"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications, then create one new native build.`].join(`
389
- `))}catch(n){t.stop(q.red("MACH Push setup failed.")),Et(n)}}async function Tt(e,t){let n=_t();try{let{config:i,appId:r,environment:o}=await xi(t),s;if(e==="apns"){if(!t.teamId||!t.keyId)throw new Error("APNs requires --team-id and --key-id.");let a=t.privateKey||(t.file?le.readFileSync(wi(t.file),"utf8"):"");if(!a)throw new Error("APNs requires --file or a generated private key.");let c=t.bundleId||Ge(i);if(!c)throw new Error("APNs requires --bundle-id.");s={environment:o,teamId:t.teamId,keyId:t.keyId,bundleId:c,privateKey:a}}else{let a=t.serviceAccount||(t.file?JSON.parse(le.readFileSync(wi(t.file),"utf8")):void 0);if(!a)throw new Error("FCM requires --file or a generated service account.");s={serviceAccount:a}}n.start(`Configuring ${e.toUpperCase()}...`),await Z.put(`/projects/${i.projectId}/push/apps/${r}/credentials/${e}`,s),n.stop(q.green(`${e.toUpperCase()} is ready.`))}catch(i){n.stop(q.red(`${e.toUpperCase()} setup failed.`)),Et(i)}}async function bl(e){let t=_t(),n=!1;try{let{config:i,appId:r,environment:o}=await xi(e),s=e.all?{all:!0,platform:e.platform}:e.token?.length?{machPushTokens:e.token}:e.user?.length?{externalUserIds:e.user}:null;if(!s)throw new Error('Choose --token, --user, or --all. Example: mach push send --all --title "Hello" --body "World"');let a;if(e.data){let d=JSON.parse(e.data);if(!d||typeof d!="object"||Array.isArray(d))throw new Error("--data must be a JSON object.");a=Object.fromEntries(Object.entries(d).map(([u,h])=>[u,String(h)]))}let c=e.badge===void 0?void 0:Number(e.badge),l=e.ttl===void 0?void 0:Number(e.ttl);t.start("Queueing notification..."),n=!0;let{data:p}=await Z.post(`/projects/${i.projectId}/push/send`,{appId:r,environment:o,target:s,notification:{title:e.title,body:e.body,data:a},options:{sound:e.sound,badge:c,ttlSeconds:l,collapseKey:e.collapseKey,androidChannelId:e.androidChannelId}});t.stop(q.green(`Notification queued: ${p.requestId}`))}catch(i){n?t.stop(q.red("Notification was not queued.")):console.error(q.red("Notification was not queued.")),Et(i)}}async function wl(e){try{let t=Ft(),n=Math.min(Math.max(Number(e.days||30),1),90),{data:i}=await Z.get(`/projects/${t.projectId}/push/overview?days=${n}`),r=i.totals,o=r.requested>0?`${(r.accepted/r.requested*100).toFixed(1)}%`:"\u2014";console.log([`${q.bold("Active devices:")} ${i.activeDevices}`,`${q.bold("Queued requests:")} ${r.queuedRequests}`,`${q.bold("Requested:")} ${r.requested}`,`${q.bold("Provider accepted:")} ${r.accepted}`,`${q.bold("Failed:")} ${r.failed}`,`${q.bold("Retried:")} ${r.retried}`,`${q.bold("Invalid devices:")} ${r.invalidDevices}`,`${q.bold("Acceptance:")} ${o}`].join(`
390
- `))}catch(t){Et(t)}}import Mi from"axios";import g from"chalk";import{execSync as _e,spawnSync as pe}from"child_process";import{createRequire as fs}from"module";import Ot from"crypto";import O from"fs";import L from"path";import et from"os";import ms from"adm-zip";var Oe=e=>typeof e!="string"?void 0:e.trim()||void 0,ls=e=>(Oe(e?.teamId)||Oe(e?.developerTeamId)||Oe(e?.issuerId)||Oe(e?.meta?.teamId)||Oe(e?.meta?.developerTeamId)||Oe(e?.meta?.issuerId))?.toUpperCase(),$i=e=>Oe(e?.keyId)||Oe(e?.meta?.keyId),_i=(e,t)=>{if(e?.type!=="ios_cert"||e?.platform&&e.platform!=="ios"||!Oe(e?.s3Key))return!1;let n=Oe(e?.distributionType)?.toLowerCase();return n&&["development","dev"].includes(n)?!1:ls(e)===t.trim().toUpperCase()},Fi=(e,t,n,i,r,o)=>{let s=["sigh","renew"];return e==="adhoc"&&s.push("--adhoc"),s.push("--app_identifier",t,"--provisioning_name",n,"--cert_id",i,"--force","--output_path",r,"--filename",o),s};var gs=fs(import.meta.url);Mi.defaults.proxy=!1;function Dt(e,t){if(!O.existsSync(e))return;let n=O.readdirSync(e);for(let i of n){let r=L.join(e,i);if(O.statSync(r).isDirectory()){let s=Dt(r,t);if(s)return s}else if(t.test(i))return r}}var ft=e=>String(e||"").trim().toLowerCase().replace(/_/g,"-"),Ti=e=>String(e||"unknown").trim().replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown",hs=(e,t)=>`ios-certificates/${Ti(e)}/${Ti(t)}/`;function ys(e){return"'"+e.replace(/'/g,"'\\''")+"'"}function mt(...e){let t=e.join(`
386
+ `,o=i[1]||"",s=i[2]||"",a=s.match(/\r?\n([ \t]+)\S/)?.[1]||`${o} `,c=s.trim().length===0?`${r}${a}'${t}',${r}${o}`:`${r}${a}'${t}',${s}`,l=i[0].indexOf("["),p=`${i[0].slice(0,l+1)}${c}]`;return le.writeFileSync(e,`${n.slice(0,i.index)}${p}${n.slice(i.index+i[0].length)}`),"inserted"}function ki(){let e="@radhya/mach/expo-plugin",t=["app.config.ts","app.config.js"].find(c=>le.existsSync(Ae.join(process.cwd(),c)));if(t){let c=ls(Ae.join(process.cwd(),t),e);return c==="inserted"?`${t} now includes ${e}.`:c==="already"?`${t} already includes ${e}.`:`Add "${e}" to the plugins array in ${t}; MACH could not safely edit its computed configuration.`}let n=["app.config.json","app.json"].find(c=>le.existsSync(Ae.join(process.cwd(),c)));if(!n)return`Add "${e}" to the Expo plugins array.`;let i=Ae.join(process.cwd(),n),r=JSON.parse(le.readFileSync(i,"utf8")),o=r.expo&&typeof r.expo=="object"?r.expo:r,s=Array.isArray(o.plugins)?o.plugins:[];return s.some(c=>(Array.isArray(c)?c[0]:c)===e)?`${n} already includes ${e}.`:(o.plugins=[...s,e],le.writeFileSync(i,`${JSON.stringify(r,null,2)}
387
+ `),`${n} now includes ${e}.`)}async function xi(e){let t=Ft(),n=e.app||t.push?.appId,i=e.environment||t.push?.environment||"production";if(n)return{config:t,appId:n,environment:i};let{data:r}=await Z.get(`/projects/${t.projectId}/push/overview?days=1`),s=(r?.apps||[]).filter(a=>a.status!=="disabled").sort((a,c)=>(c.updatedAt||0)-(a.updatedAt||0))[0]?.appId;if(!s)throw new Error(`Push is not configured. Run \`${A.nameLower} push setup\` first.`);return{config:t,appId:s,environment:i}}function wi(e){let t=Ae.resolve(e);if(!le.existsSync(t))throw new Error(`File not found: ${t}`);return t}function Et(e){let t=e?.response?.data?.message||e?.message||"Unknown error";console.error(q.red(t)),process.exitCode=1}async function Cl(e){let t=_t();try{let n=Ft();if(Lt(n)==="flutter")throw new Error("MACH Push currently supports Expo and bare React Native. Flutter push support is planned for a later release.");let r=Ni(n,e.iosBundle),o=Ri(n,e.androidPackage);if(!r&&!o)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);t.start("Creating MACH Push app..."),await Z.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});let s=e.environment||"production";n.push=Ei({environment:s,googleServicesFile:e.googleServicesFile}),vi(n);let a=n.framework==="expo"?ki():void 0;t.stop(q.green("MACH Push app created.")),console.log(["",`${q.bold("Client config:")} ${A.configFileName} \u2192 push`,"","Install the mobile SDK:"," npm install @radhya/mach-push-react-native",...n.framework==="expo"?[" npm install --save-dev @radhya/mach",` ${a}`," Run npx expo prebuild."]:[],"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications.`].join(`
388
+ `))}catch(n){t.stop(q.red("MACH Push setup failed.")),Et(n)}}async function bl(e){let t=_t();try{let n=Ft(),i=Lt(n);if(i==="flutter")throw new Error("MACH Push currently supports Expo and bare React Native. Flutter push support is planned for a later release.");let r=Ni(n,e.iosBundle),o=Ri(n,e.androidPackage);if(!r&&!o)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);let s;t.start("Checking the MACH Push app...");let l=((await Z.get(`/projects/${n.projectId}/push/overview?days=1`)).data?.apps||[]).filter(I=>I.status!=="disabled").sort((I,R)=>(R.updatedAt||0)-(I.updatedAt||0)).find(I=>(!r||I.iosBundleId===r)&&(!o||I.androidPackageName===o));if(l)s=l.appId,t.stop(q.green("Existing MACH Push app linked."));else{let{data:I}=await Z.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});s=I.app.appId,t.stop(q.green("MACH Push app created."))}if(!s)throw new Error("MACH Push did not return a usable application.");let p=n.push,d=e.environment||p?.environment||"production",u=p?.apiUrl||Si,h=as(e.googleServicesFile,p?.googleServicesFile);n.push=Ei({apiUrl:u,environment:d,googleServicesFile:h}),vi(n);let f=ss(i,!!e.skipInstall),v=i==="expo"?ki():void 0;if(v?.startsWith('Add "'))throw new Error(v);let b={projectId:n.projectId,apiUrl:u,environment:d},x=Zn(process.cwd(),i,b);if(!x.entryFile)throw new Error(x.notes[0]||"MACH could not locate the application entry point.");let N=i==="expo"?{written:[],notes:[]}:jn(process.cwd(),{iosBundleId:r,iosEnvironment:cs(d),googleServicesFile:h});console.log(["",q.green.bold("MACH Push basic setup is ready."),`${q.bold("Framework:")} ${i}`,`${q.bold("Client config:")} ${A.configFileName} \u2192 push`,`${q.bold("Automatic startup:")} ${x.entryFile||"manual entry import required"}`,`${q.bold("Customize callbacks:")} ${x.editableFile||"see the setup notes below"}`,"",...f.map(I=>`\u2022 ${I}`),...v?[`\u2022 ${v}`]:[],...x.notes.map(I=>`\u2022 ${I}`),...N.notes.map(I=>`\u2022 ${I}`),...[...x.written,...N.written].map(I=>`\u2022 Updated ${I}.`),"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications, then create one new native build.`].join(`
389
+ `))}catch(n){t.stop(q.red("MACH Push setup failed.")),Et(n)}}async function Tt(e,t){let n=_t();try{let{config:i,appId:r,environment:o}=await xi(t),s;if(e==="apns"){if(!t.teamId||!t.keyId)throw new Error("APNs requires --team-id and --key-id.");let a=t.privateKey||(t.file?le.readFileSync(wi(t.file),"utf8"):"");if(!a)throw new Error("APNs requires --file or a generated private key.");let c=t.bundleId||Ge(i);if(!c)throw new Error("APNs requires --bundle-id.");s={environment:o,teamId:t.teamId,keyId:t.keyId,bundleId:c,privateKey:a}}else{let a=t.serviceAccount||(t.file?JSON.parse(le.readFileSync(wi(t.file),"utf8")):void 0);if(!a)throw new Error("FCM requires --file or a generated service account.");s={serviceAccount:a}}n.start(`Configuring ${e.toUpperCase()}...`),await Z.put(`/projects/${i.projectId}/push/apps/${r}/credentials/${e}`,s),n.stop(q.green(`${e.toUpperCase()} is ready.`))}catch(i){n.stop(q.red(`${e.toUpperCase()} setup failed.`)),Et(i)}}async function wl(e){let t=_t(),n=!1;try{let{config:i,appId:r,environment:o}=await xi(e),s=e.all?{all:!0,platform:e.platform}:e.token?.length?{machPushTokens:e.token}:e.user?.length?{externalUserIds:e.user}:null;if(!s)throw new Error('Choose --token, --user, or --all. Example: mach push send --all --title "Hello" --body "World"');let a;if(e.data){let d=JSON.parse(e.data);if(!d||typeof d!="object"||Array.isArray(d))throw new Error("--data must be a JSON object.");a=Object.fromEntries(Object.entries(d).map(([u,h])=>[u,String(h)]))}let c=e.badge===void 0?void 0:Number(e.badge),l=e.ttl===void 0?void 0:Number(e.ttl);t.start("Queueing notification..."),n=!0;let{data:p}=await Z.post(`/projects/${i.projectId}/push/send`,{appId:r,environment:o,target:s,notification:{title:e.title,body:e.body,data:a},options:{sound:e.sound,badge:c,ttlSeconds:l,collapseKey:e.collapseKey,androidChannelId:e.androidChannelId}});t.stop(q.green(`Notification queued: ${p.requestId}`))}catch(i){n?t.stop(q.red("Notification was not queued.")):console.error(q.red("Notification was not queued.")),Et(i)}}async function Sl(e){try{let t=Ft(),n=Math.min(Math.max(Number(e.days||30),1),90),{data:i}=await Z.get(`/projects/${t.projectId}/push/overview?days=${n}`),r=i.totals,o=r.requested>0?`${(r.accepted/r.requested*100).toFixed(1)}%`:"\u2014";console.log([`${q.bold("Active devices:")} ${i.activeDevices}`,`${q.bold("Queued requests:")} ${r.queuedRequests}`,`${q.bold("Requested:")} ${r.requested}`,`${q.bold("Provider accepted:")} ${r.accepted}`,`${q.bold("Failed:")} ${r.failed}`,`${q.bold("Retried:")} ${r.retried}`,`${q.bold("Invalid devices:")} ${r.invalidDevices}`,`${q.bold("Acceptance:")} ${o}`].join(`
390
+ `))}catch(t){Et(t)}}import ji from"axios";import g from"chalk";import{execSync as _e,spawnSync as pe}from"child_process";import{createRequire as ms}from"module";import Ot from"crypto";import O from"fs";import X from"path";import et from"os";import gs from"adm-zip";var Oe=e=>typeof e!="string"?void 0:e.trim()||void 0,ds=e=>(Oe(e?.teamId)||Oe(e?.developerTeamId)||Oe(e?.issuerId)||Oe(e?.meta?.teamId)||Oe(e?.meta?.developerTeamId)||Oe(e?.meta?.issuerId))?.toUpperCase(),$i=e=>Oe(e?.keyId)||Oe(e?.meta?.keyId),_i=async({storedPassword:e,tryPassword:t,requestPassword:n})=>{if(e&&await t(e))return{status:"unlocked",password:e,source:"stored"};if(await t(""))return{status:"unlocked",password:"",source:"legacy-empty"};let i=await n();return i===void 0?{status:"cancelled"}:await t(i)?{status:"unlocked",password:i,source:"prompt"}:{status:"failed"}},Fi=(e,t)=>{if(e?.type!=="ios_cert"||e?.platform&&e.platform!=="ios"||!Oe(e?.s3Key))return!1;let n=Oe(e?.distributionType)?.toLowerCase();return n&&["development","dev"].includes(n)?!1:ds(e)===t.trim().toUpperCase()},Ti=(e,t,n,i,r,o)=>{let s=["sigh","renew"];return e==="adhoc"&&s.push("--adhoc"),s.push("--app_identifier",t,"--provisioning_name",n,"--cert_id",i,"--force","--output_path",r,"--filename",o),s};var hs=ms(import.meta.url);ji.defaults.proxy=!1;function Dt(e,t){if(!O.existsSync(e))return;let n=O.readdirSync(e);for(let i of n){let r=X.join(e,i);if(O.statSync(r).isDirectory()){let s=Dt(r,t);if(s)return s}else if(t.test(i))return r}}var ft=e=>String(e||"").trim().toLowerCase().replace(/_/g,"-"),Oi=e=>String(e||"unknown").trim().replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown",ys=(e,t)=>`ios-certificates/${Oi(e)}/${Oi(t)}/`;function Is(e){return"'"+e.replace(/'/g,"'\\''")+"'"}function mt(...e){let t=e.join(`
391
391
  `).split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return t.length>0?t.slice(-8).join(`
392
- `):void 0}function Is(e,t,n){let i=pe(e,t,{env:n,encoding:"utf-8"});if(!(i.error||i.status!==0))return(i.stdout||i.stderr||"").trim()||void 0}function As(e,t,n,i,r=!1){let o=[`${e} match ${t}`];return n&&o.push(`--app_identifier "${n}"`),i&&o.push(`--profile_name "${i}"`),r&&(t==="adhoc"||t==="development")&&o.push("--force_for_new_devices"),o.join(" ")}function Cs(e){let t=e?.match(/ruby\s+(\d+)\.(\d+)/);return t?{major:Number(t[1]),minor:Number(t[2])}:null}function bs(e,t,n){let i=Cs(e);return i?i.major!==t?i.major<t:i.minor<n:!1}function hn(e){let t=process.env.HOME||et.homedir(),n=process.env.FASTLANE_GEM_HOME||L.join(t,".local/share/fastlane/3.4.0"),i=[process.env.FASTLANE_BINARY,"/usr/local/bin/fastlane","/opt/homebrew/bin/fastlane","/usr/local/Cellar/fastlane/2.227.0/libexec/bin/fastlane","/opt/homebrew/Cellar/fastlane/2.227.0/libexec/bin/fastlane",L.join(n,"bin/fastlane"),"fastlane"].filter(Boolean);for(let r of i){if(r.includes("/")&&!O.existsSync(r))continue;let o=pe(r,["--version"],{env:e,stdio:"ignore"});if(!o.error&&o.status===0)return{command:r,shellCommand:ys(r),env:e}}return null}function ws(e){if(process.env.MACH_SKIP_FASTLANE_INSTALL==="1")return{ok:!1,detail:"Automatic install skipped because MACH_SKIP_FASTLANE_INSTALL=1."};let t=pe("gem",["--version"],{env:e,encoding:"utf-8"});if(t.error||t.status!==0)return{ok:!1,detail:mt(t.stdout,t.stderr)||"RubyGems is not available."};let n=Is("ruby",["-v"],e);if(bs(n,3,2))return{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,"The latest fastlane dependency tree now requires Ruby >= 3.2.","Mach skipped automatic gem install because macOS system Ruby is too old for it."].filter(Boolean).join(`
393
- `)};let i=process.env.HOME||et.homedir(),r=process.env.FASTLANE_GEM_HOME||L.join(i,".local/share/fastlane/3.4.0"),o=L.join(r,"bin");O.mkdirSync(o,{recursive:!0}),m.info(g.dim("fastlane not found. Installing fastlane into the local Mach cache..."));let s=pe("gem",["install","fastlane","--no-document","--install-dir",r,"--bindir",o],{env:{...e,GEM_HOME:r,GEM_PATH:[r,e.GEM_PATH].filter(Boolean).join(":")},encoding:"utf-8"});if(s.error||s.status!==0){let a=mt(s.stdout,s.stderr);return m.warn(g.yellow("Automatic fastlane install failed.")),a&&m.warn(g.dim(a)),{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,a].filter(Boolean).join(`
394
- `)||void 0}}return m.success(g.green("\u2713 fastlane installed into the local Mach cache.")),{ok:!0}}function Ss(){return!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY}function vs(e){let t=pe("brew",["--version"],{env:e,encoding:"utf-8"});if(t.error||t.status!==0)return{ok:!1,detail:"Homebrew is not available on PATH."};m.info(g.dim("Installing fastlane with Homebrew..."));let n=pe("brew",["install","fastlane"],{env:e,stdio:"inherit"});return n.error||n.status!==0?{ok:!1,detail:"brew install fastlane failed."}:(m.success(g.green("\u2713 fastlane installed with Homebrew.")),{ok:!0})}async function Es(e){if(!Ss())return!1;m.warn(g.yellow("fastlane is required for iOS certificate/profile sync, but it was not found.")),e&&m.info(g.dim(e));let t=await bn({message:"Install fastlane now with Homebrew?",initialValue:!0});return j(t)?(Y("Operation cancelled"),!1):!!t}async function Ps(){let e=rt(),t=hn(e);if(t)return t;let n=ws(e);e=rt();let i=hn(e);if(i)return i;if(await Es(n.detail)){let r=vs(e);e=rt();let o=hn(e);if(o)return o;throw new Error(["fastlane is required for iOS certificate/profile sync, but it was still not found after Homebrew install.",r.detail?`Homebrew install failed:
392
+ `):void 0}function As(e,t,n){let i=pe(e,t,{env:n,encoding:"utf-8"});if(!(i.error||i.status!==0))return(i.stdout||i.stderr||"").trim()||void 0}function Cs(e,t,n,i,r=!1){let o=[`${e} match ${t}`];return n&&o.push(`--app_identifier "${n}"`),i&&o.push(`--profile_name "${i}"`),r&&(t==="adhoc"||t==="development")&&o.push("--force_for_new_devices"),o.join(" ")}function bs(e){let t=e?.match(/ruby\s+(\d+)\.(\d+)/);return t?{major:Number(t[1]),minor:Number(t[2])}:null}function ws(e,t,n){let i=bs(e);return i?i.major!==t?i.major<t:i.minor<n:!1}function hn(e){let t=process.env.HOME||et.homedir(),n=process.env.FASTLANE_GEM_HOME||X.join(t,".local/share/fastlane/3.4.0"),i=[process.env.FASTLANE_BINARY,"/usr/local/bin/fastlane","/opt/homebrew/bin/fastlane","/usr/local/Cellar/fastlane/2.227.0/libexec/bin/fastlane","/opt/homebrew/Cellar/fastlane/2.227.0/libexec/bin/fastlane",X.join(n,"bin/fastlane"),"fastlane"].filter(Boolean);for(let r of i){if(r.includes("/")&&!O.existsSync(r))continue;let o=pe(r,["--version"],{env:e,stdio:"ignore"});if(!o.error&&o.status===0)return{command:r,shellCommand:Is(r),env:e}}return null}function Ss(e){if(process.env.MACH_SKIP_FASTLANE_INSTALL==="1")return{ok:!1,detail:"Automatic install skipped because MACH_SKIP_FASTLANE_INSTALL=1."};let t=pe("gem",["--version"],{env:e,encoding:"utf-8"});if(t.error||t.status!==0)return{ok:!1,detail:mt(t.stdout,t.stderr)||"RubyGems is not available."};let n=As("ruby",["-v"],e);if(ws(n,3,2))return{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,"The latest fastlane dependency tree now requires Ruby >= 3.2.","Mach skipped automatic gem install because macOS system Ruby is too old for it."].filter(Boolean).join(`
393
+ `)};let i=process.env.HOME||et.homedir(),r=process.env.FASTLANE_GEM_HOME||X.join(i,".local/share/fastlane/3.4.0"),o=X.join(r,"bin");O.mkdirSync(o,{recursive:!0}),m.info(g.dim("fastlane not found. Installing fastlane into the local Mach cache..."));let s=pe("gem",["install","fastlane","--no-document","--install-dir",r,"--bindir",o],{env:{...e,GEM_HOME:r,GEM_PATH:[r,e.GEM_PATH].filter(Boolean).join(":")},encoding:"utf-8"});if(s.error||s.status!==0){let a=mt(s.stdout,s.stderr);return m.warn(g.yellow("Automatic fastlane install failed.")),a&&m.warn(g.dim(a)),{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,a].filter(Boolean).join(`
394
+ `)||void 0}}return m.success(g.green("\u2713 fastlane installed into the local Mach cache.")),{ok:!0}}function vs(){return!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY}function Es(e){let t=pe("brew",["--version"],{env:e,encoding:"utf-8"});if(t.error||t.status!==0)return{ok:!1,detail:"Homebrew is not available on PATH."};m.info(g.dim("Installing fastlane with Homebrew..."));let n=pe("brew",["install","fastlane"],{env:e,stdio:"inherit"});return n.error||n.status!==0?{ok:!1,detail:"brew install fastlane failed."}:(m.success(g.green("\u2713 fastlane installed with Homebrew.")),{ok:!0})}async function Ps(e){if(!vs())return!1;m.warn(g.yellow("fastlane is required for iOS certificate/profile sync, but it was not found.")),e&&m.info(g.dim(e));let t=await bn({message:"Install fastlane now with Homebrew?",initialValue:!0});return j(t)?(Y("Operation cancelled"),!1):!!t}async function Ns(){let e=rt(),t=hn(e);if(t)return t;let n=Ss(e);e=rt();let i=hn(e);if(i)return i;if(await Ps(n.detail)){let r=Es(e);e=rt();let o=hn(e);if(o)return o;throw new Error(["fastlane is required for iOS certificate/profile sync, but it was still not found after Homebrew install.",r.detail?`Homebrew install failed:
395
395
  ${r.detail}`:void 0,"Try running manually: brew install fastlane","Then run mach credentials again."].filter(Boolean).join(`
396
396
  `))}throw new Error(["fastlane is required for iOS certificate/profile sync, but it was not found on PATH.",n.detail?`Automatic install failed:
397
397
  ${n.detail}`:void 0,"Recommended fix: brew install fastlane","Alternative: install Ruby 3.x, then run: gem install fastlane --no-document","Then run mach credentials again."].filter(Boolean).join(`
398
- `))}var re=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},wn=e=>re(e.password)||re(e.p12Password)||re(e.certificatePassword)||re(e.meta?.password)||re(e.meta?.p12Password)||re(e.meta?.certificatePassword),ji=e=>re(e.keystorePassword)||re(e.storePassword)||re(e.meta?.keystorePassword)||re(e.meta?.storePassword),Gi=e=>re(e.keyPassword)||re(e.meta?.keyPassword),Ns=e=>re(e.alias)||re(e.meta?.alias),Bt=e=>e.credentialId||e.id,An=e=>e.bundleId||e.bundleIdentifier||e.meta?.bundleId||e.meta?.bundleIdentifier,Cn=e=>e.distributionType||e.meta?.distributionType,Oi=e=>!!wn(e)||!!ji(e)||!!Gi(e),Ui=async(e,t,n)=>{if(!["ios_cert","android_keystore"].includes(n.type)||Oi(n))return n;let i=An(n),r=Cn(n);if(!i||!r)return n;try{let s=(await Z.get("/credentials/resolve",{params:{projectId:e,platform:t,bundleId:i,distributionType:r}})).data.credentials||[],a=Bt(n),c=s.find(l=>{if(l.type!==n.type)return!1;let p=Bt(l);return a&&p===a?!0:An(l)===i&&ft(Cn(l))===ft(r)&&Oi(l)});return c?{...n,...c,meta:{...n.meta,...c.meta}}:n}catch{return n}},Rs=e=>{let t=ft(e);return t==="store"||t==="app-store"?"PRODUCTION":["adhoc","ad-hoc","internal","staging","stage"].includes(t)?"STAGING":"DEVELOPMENT"},Li=(e,t)=>{let n=wn(e);if(n)return n;let i=Rs(e.distributionType);return["IOS_P12_PASSWORD",`${A.envPrefix}P12_PASSWORD`,`IOS_P12_PASSWORD_${i}`,`P12_PASSWORD_${i}`,"MACH_P12_PASSWORD","P12_PASSWORD","CERT_PASSWORD"].map(o=>re(t[o])).find(Boolean)||""},ks=(e,t)=>{let n=ft(e.distributionType),i=n==="store"?"PRODUCTION":["internal","adhoc","ad-hoc","staging","stage"].includes(n)?"STAGING":"DEVELOPMENT",r=["PRODUCTION","STORE","INTERNAL","STAGING","DEVELOPMENT","RELEASE","DEBUG"],o=[`KEYSTORE_PASSWORD_${i}`,`KEYSTORE_PASSWORD_${String(e.distributionType||"").toUpperCase()}`,...r.map(d=>`KEYSTORE_PASSWORD_${d}`),"ANDROID_STORE_PASSWORD","ANDROID_KEYSTORE_PASSWORD","ANDROID_KEYSTONE_PASSWORD","KEYSTORE_PASSWORD"],s=[`KEY_PASSWORD_${i}`,`KEY_PASSWORD_${String(e.distributionType||"").toUpperCase()}`,"ANDROID_KEY_PASSWORD","KEY_PASSWORD"],a=[`KEYSTORE_ALIAS_${i}`,`KEYSTORE_ALIAS_${String(e.distributionType||"").toUpperCase()}`,...r.map(d=>`KEYSTORE_ALIAS_${d}`),"ANDROID_KEY_ALIAS","KEYSTORE_ALIAS"],c=ji(e)||wn(e)||o.map(d=>re(t[d])).find(Boolean)||"",l=Gi(e)||s.map(d=>re(t[d])).find(Boolean)||c;return{alias:Ns(e)||a.map(d=>re(t[d])).find(Boolean)||"",keystorePassword:c,keyPassword:l}},Di=(e,t,n)=>{let i=e.includes(".")?e.replace(/\.[^.]+$/i,".zip"):`${e}.zip`,r=L.basename(e),o=new ms;return o.addLocalFile(e,void 0,r),o.addFile(t,Buffer.from(n.endsWith(`
398
+ `))}var re=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},wn=e=>re(e.password)||re(e.p12Password)||re(e.certificatePassword)||re(e.meta?.password)||re(e.meta?.p12Password)||re(e.meta?.certificatePassword),Gi=e=>re(e.keystorePassword)||re(e.storePassword)||re(e.meta?.keystorePassword)||re(e.meta?.storePassword),Ui=e=>re(e.keyPassword)||re(e.meta?.keyPassword),Rs=e=>re(e.alias)||re(e.meta?.alias),Bt=e=>e.credentialId||e.id,An=e=>e.bundleId||e.bundleIdentifier||e.meta?.bundleId||e.meta?.bundleIdentifier,Cn=e=>e.distributionType||e.meta?.distributionType,Di=e=>!!wn(e)||!!Gi(e)||!!Ui(e),Li=async(e,t,n)=>{if(!["ios_cert","android_keystore"].includes(n.type)||Di(n))return n;let i=An(n),r=Cn(n);if(!i||!r)return n;try{let s=(await Z.get("/credentials/resolve",{params:{projectId:e,platform:t,bundleId:i,distributionType:r}})).data.credentials||[],a=Bt(n),c=s.find(l=>{if(l.type!==n.type)return!1;let p=Bt(l);return a&&p===a?!0:An(l)===i&&ft(Cn(l))===ft(r)&&Di(l)});return c?{...n,...c,meta:{...n.meta,...c.meta}}:n}catch{return n}},ks=e=>{let t=ft(e);return t==="store"||t==="app-store"?"PRODUCTION":["adhoc","ad-hoc","internal","staging","stage"].includes(t)?"STAGING":"DEVELOPMENT"},Xi=(e,t)=>{let n=wn(e);if(n)return n;let i=ks(e.distributionType);return["IOS_P12_PASSWORD",`${A.envPrefix}P12_PASSWORD`,`IOS_P12_PASSWORD_${i}`,`P12_PASSWORD_${i}`,"MACH_P12_PASSWORD","P12_PASSWORD","CERT_PASSWORD"].map(o=>re(t[o])).find(Boolean)||""},xs=(e,t)=>{let n=ft(e.distributionType),i=n==="store"?"PRODUCTION":["internal","adhoc","ad-hoc","staging","stage"].includes(n)?"STAGING":"DEVELOPMENT",r=["PRODUCTION","STORE","INTERNAL","STAGING","DEVELOPMENT","RELEASE","DEBUG"],o=[`KEYSTORE_PASSWORD_${i}`,`KEYSTORE_PASSWORD_${String(e.distributionType||"").toUpperCase()}`,...r.map(d=>`KEYSTORE_PASSWORD_${d}`),"ANDROID_STORE_PASSWORD","ANDROID_KEYSTORE_PASSWORD","ANDROID_KEYSTONE_PASSWORD","KEYSTORE_PASSWORD"],s=[`KEY_PASSWORD_${i}`,`KEY_PASSWORD_${String(e.distributionType||"").toUpperCase()}`,"ANDROID_KEY_PASSWORD","KEY_PASSWORD"],a=[`KEYSTORE_ALIAS_${i}`,`KEYSTORE_ALIAS_${String(e.distributionType||"").toUpperCase()}`,...r.map(d=>`KEYSTORE_ALIAS_${d}`),"ANDROID_KEY_ALIAS","KEYSTORE_ALIAS"],c=Gi(e)||wn(e)||o.map(d=>re(t[d])).find(Boolean)||"",l=Ui(e)||s.map(d=>re(t[d])).find(Boolean)||c;return{alias:Rs(e)||a.map(d=>re(t[d])).find(Boolean)||"",keystorePassword:c,keyPassword:l}},Bi=(e,t,n)=>{let i=e.includes(".")?e.replace(/\.[^.]+$/i,".zip"):`${e}.zip`,r=X.basename(e),o=new gs;return o.addLocalFile(e,void 0,r),o.addFile(t,Buffer.from(n.endsWith(`
399
399
  `)?n:`${n}
400
- `,"utf8")),o.writeZip(i),i},xs=e=>{let t=e.toLowerCase();return t==="production"||t==="prod"||t.includes("store")||t.endsWith("-production")||t.endsWith("-prod")},$s=(e,t)=>{let n=nt(e,t)||{},i=ft(n.distribution),r=ft(n.environment);return i==="store"||r==="production"||r==="store"||xs(t)?"store":"internal"},_s=["development","preview","production"],Fs="U27F4V844T",yn=null;function Wt(){return yn||(yn=gs("@expo/apple-utils")),yn}function Bi(e){let t=n=>n.replace(/^.*The password is only used to authenticate with Apple and never stored on Expo servers.*(?:\r?\n)?/gm,"").replace(/^.*Learn more\..*(?:\r?\n)?/gm,"");if(typeof e=="string")return t(e);if(Buffer.isBuffer(e)){let n=e.toString("utf-8"),i=t(n);return i===n?e:Buffer.from(i,"utf-8")}return e}async function Ts(e){let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr);process.stdout.write=(i,...r)=>t(Bi(i),...r),process.stderr.write=(i,...r)=>n(Bi(i),...r);try{return await e()}finally{process.stdout.write=t,process.stderr.write=n}}function Xi(e){return O.existsSync(L.resolve(e))?void 0:"File not found"}function Os(){try{let e=`./${A.configFileName}`;return O.existsSync(e)?JSON.parse(O.readFileSync(e,"utf-8")):{}}catch{return{}}}function Ds(e,t){let n=String(e.name||t||"Mobile app").trim().replace(/\s+/g," ")||"Mobile app",i=new Date,r=[i.getFullYear(),String(i.getMonth()+1).padStart(2,"0"),String(i.getDate()).padStart(2,"0")].join(""),o=Ot.randomBytes(2).toString("hex").toUpperCase(),s=` ${r}-${o}`;return`${`MACH Push ${n}`.slice(0,Math.max(1,50-s.length))}${s}`}async function Bs(e){let t=e.submit?.production?.ios?.appleId||e.submit?.preview?.ios?.appleId||e.submit?.development?.ios?.appleId,n=await ve({message:"Apple ID (for Apple Developer Portal):",initialValue:t,validate:i=>i.includes("@")?void 0:"Enter a valid Apple ID email"});return j(n)&&(Y("Operation cancelled"),process.exit(0)),n}async function Vs(e){let t=await ut({message:`Apple password for ${e} (used only for Apple login, not stored):`,validate:n=>n.trim()?void 0:"Password is required"});return j(t)&&(Y("Operation cancelled"),process.exit(0)),t}function Ws(e){return(Array.isArray(e?.services)?e.services:[]).some(n=>n?.id===Fs||/apple push notification|apns/i.test(String(n?.name||"")))}async function Zs(e){let{Keys:t}=Wt(),n=Je();try{n.start("Fetching existing APNs keys from Apple...");let i=await t.getKeysAsync(e),o=(await Promise.all(i.map(async s=>{try{return await t.getKeyInfoAsync(e,{id:s.id})}catch{return s}}))).filter(Ws);return n.stop(g.green(`Found ${o.length} APNs key${o.length===1?"":"s"}.`)),o}catch(i){throw n.stop(g.red("Could not fetch APNs keys from Apple.")),i}}async function Ms(e){let{Keys:t}=Wt(),i=(await Zs(e)).filter(c=>c.canRevoke!==!1);if(i.length===0)return m.warn(g.yellow("No revokable APNs keys were found for this Apple team.")),!1;let r=await Ee({message:"Select an APNs key to revoke:",options:i.map(c=>({value:c.id,label:`${c.name||"Untitled APNs key"} (${c.id})`,hint:c.canDownload?"APNs key, private key may still be downloadable":"APNs key"}))});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=i.find(c=>c.id===r);m.warn(g.yellow("Revoking this key can break push notifications for any service currently using it."));let s=await bn({message:`Revoke "${o?.name||"Untitled APNs key"}" (${r})? This cannot be undone.`,initialValue:!1});if(j(s)&&(Y("Operation cancelled"),process.exit(0)),!s)return m.info(g.dim("APNs key was not revoked.")),!1;let a=Je();try{return a.start(`Revoking APNs key ${r}...`),await t.revokeKeyAsync(e,{id:r}),a.stop(g.green(`Revoked APNs key ${r}.`)),!0}catch(c){throw a.stop(g.red(`Could not revoke APNs key ${r}.`)),c}}async function js(e,t){let{Keys:n}=Wt(),i=0;for(;;){let r=t(),o=Je();try{o.start(`Creating APNs auth key (${r})...`);let s=await n.createKeyAsync(e,{name:r,isApns:!0});o.message("Downloading APNs private key...");let a=await n.downloadKeyAsync(e,{id:s.id});if(!a)throw new Error("Apple did not return the APNs private key.");return o.stop(g.green(`APNs key generated: ${s.id}`)),{keyId:s.id,keyName:r,privateKey:a}}catch(s){if(o.stop(g.red("APNs key generation failed.")),Us(s)&&i<3){i+=1,m.warn(g.yellow("Apple says that APNs key name already exists. Retrying with a new generated name..."));continue}if(!Hi(s))throw s;Ki(s);let a=await Ee({message:"Apple APNs key limit reached. What do you want to do?",options:[{value:"revoke",label:"List and revoke an existing APNs key",hint:"Then Mach will create a new key"},{value:"retry",label:"Try creating again"},{value:"exit",label:"Exit"}]});if((j(a)||a==="exit")&&(Y("Operation cancelled"),process.exit(0)),a==="revoke"&&await Ms(e))continue}}}async function Gs(e,t){let n=await Bs(e);try{let i=await Vs(n),{Auth:r}=Wt();m.info(g.dim("Signing in to Apple Developer Portal..."));let o=await Ts(()=>r.loginAsync({username:n,password:i},{autoResolveProvider:!0})),s=String(o?.context?.teamId||"").trim().toUpperCase(),a=await js(o.context,()=>Ds(e,t));return{keyId:a.keyId,teamId:s,privateKey:a.privateKey}}catch(i){throw m.error(g.red("APNs key generation failed.")),i}}function Hi(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
401
- `);return/maximum allowed number.*keys/i.test(t)||/already reached the maximum/i.test(t)}function Us(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
402
- `);return/another key with same name exists/i.test(t)||/same name already exists/i.test(t)}function Ki(e){if(m.warn(g.yellow(e?.message||"Could not generate APNs key automatically.")),Hi(e)){m.info(g.dim("Apple rejected the request because this team is already at its APNs auth-key limit.")),m.info(g.dim("If you saved an existing .p8 file, upload it here. If not, delete an unused APNs key in Apple Developer, then generate again.")),m.info(g.dim("Apple only lets you download an APNs .p8 private key when the key is first created."));return}m.info(g.dim("You can upload an existing .p8 key, retry generation, or exit and try again later."))}async function In(){let e=await Ee({message:"Where should Mach save this APNs key?",options:[{value:"all",label:"All environments",hint:"Recommended \u2014 one APNs key works for sandbox and production"},{value:"development",label:"Development only"},{value:"preview",label:"Preview only"},{value:"production",label:"Production only"}]});return j(e)&&(Y("Operation cancelled"),process.exit(0)),e==="all"?_s:[e]}async function Ls(e,t,n,i){let r=i.teamId||e.teamId;if(!r){let o=await ve({message:"Apple Team ID:",validate:s=>/^[A-Z0-9]{10}$/i.test(s.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});j(o)&&(Y("Operation cancelled"),process.exit(0)),r=o.trim().toUpperCase()}for(let o of t)await Tt("apns",{...e,environment:o,privateKey:i.privateKey,teamId:r,keyId:i.keyId,bundleId:n})}async function Vi(e,t,n){let i=await ve({message:"Path to APNs auth key (.p8):",validate:Xi});j(i)&&(Y("Operation cancelled"),process.exit(0));let r=await ve({message:"Apple Team ID:",initialValue:e.teamId,validate:s=>s.trim()?void 0:"Team ID is required"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=await ve({message:"APNs Key ID:",initialValue:e.keyId,validate:s=>s.trim()?void 0:"Key ID is required"});j(o)&&(Y("Operation cancelled"),process.exit(0));for(let s of t)await Tt("apns",{...e,environment:s,file:i,teamId:r,keyId:o,bundleId:n})}async function Xs(e){let t=Os(),n=e.bundleId||Ge(t)||t.push?.iosBundleId;for(;;){let i=await Ee({message:"How do you want to configure APNs?",options:[{value:"generate",label:"Generate new APNs key with Apple",hint:"Mach creates, downloads once, and uploads it securely"},{value:"upload",label:"Upload existing .p8 key",hint:"Use a key you already downloaded from Apple"}]});if(j(i)&&(Y("Operation cancelled"),process.exit(0)),i==="upload"){let r=await In();await Vi(e,r,n);return}try{let r=await Gs(t,n),o=await In();await Ls(e,o,n,r);return}catch(r){Ki(r);let o=await Ee({message:"APNs key was not created. What do you want to do?",options:[{value:"upload",label:"Upload existing .p8 key"},{value:"retry",label:"Try generating again"},{value:"exit",label:"Exit"}]});if((j(o)||o==="exit")&&(Y("Operation cancelled"),process.exit(0)),o==="upload"){let s=await In();await Vi(e,s,n);return}}}}async function Hs(e){let t=await ve({message:"Path to Firebase service account JSON:",validate:Xi});j(t)&&(Y("Operation cancelled"),process.exit(0));let n;try{n=JSON.parse(O.readFileSync(t,"utf8"))}catch(i){Y(`Invalid Firebase service account JSON: ${i.message}`),process.exit(1)}await Tt("fcm",{...e,serviceAccount:n})}async function Ks(e,t){if(t==="ios"){await Xs(e);return}await Hs(e)}function Js(e,t,n){let i=O.readFileSync(n,"utf8"),r=Math.floor(Date.now()/1e3),o=Buffer.from(JSON.stringify({alg:"ES256",kid:e,typ:"JWT"})).toString("base64url"),s=Buffer.from(JSON.stringify({iss:t,iat:r,exp:r+1200,aud:"appstoreconnect-v1"})).toString("base64url"),a=`${o}.${s}`,c=Ot.createSign("SHA256");c.update(a);let l=c.sign({key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${l}`}async function Ys(e,t,n,i){let r=Js(t,n,i),o=(await import("axios")).default;for(let s of e)try{await o.post("https://api.appstoreconnect.apple.com/v1/devices",{data:{type:"devices",attributes:{name:s.name,udid:s.udid,platform:"IOS"}}},{headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"}}),m.info(g.dim(` \u2713 Registered: ${s.name}`))}catch(a){let c=a.response?.data?.errors;c?.some(p=>p.code==="ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE"||p.detail?.toLowerCase().includes("already registered")||p.detail?.toLowerCase().includes("already exists"))?m.info(g.dim(` Already on Portal: ${s.name}`)):m.warn(g.yellow(` Could not register ${s.name}: ${c?.[0]?.detail||a.message}`))}}var zs=async e=>{ds(g.bgCyan.black(A.cliTag("Credentials")));let t=await Ee({message:"Select platform:",options:[{value:"ios",label:"iOS"},{value:"android",label:"Android"}]});j(t)&&(Y("Operation cancelled"),process.exit(0));let n=await Ee({message:"What do you want to do?",options:[{value:"setup",label:"Build Credentials (Certs/Profiles)",hint:"Manage everything needed to build your project"},{value:"download",label:"Download credentials (credentials.json)",hint:"Sync credentials from Dashboard to local project"},{value:"service",label:"App Store Connect API Key (Magic)",hint:"Manage your API Key for automated submission"},{value:"push",label:"Push Notifications",hint:t==="ios"?"Upload APNs key":"Upload Firebase service account"},{value:"back",label:"Go back"},{value:"exit",label:"Exit"}].filter(i=>(t==="android"&&i.value==="service"&&(i.label="Google Service Account (JSON)"),!0))});if((j(n)||n==="exit")&&(Y("Operation cancelled"),process.exit(0)),n==="back")return zs(e);n==="setup"?await Qs({...e,platform:t}):n==="download"?await la({...e,platform:t}):n==="service"?await Vn({...e,platform:t}):n==="push"&&await Ks(e,t),ps(g.green("Done!"))},Qs=async e=>{let t=Je(),n=e.platform,i=e.profile,r=e.credentialType;if(r&&!Ut(r)){m.error("Credential type must be development, adhoc, or store.");return}if(!i&&r){let c=Ut(r);i=c==="store"?"production":c==="adhoc"?"staging":"development"}if(!i){let c=await Ee({message:"Select credential type:",options:[{value:"development",label:"Development",hint:"Local testing & simulators"},{value:"staging",label:"Ad Hoc / Staging",hint:"Internal distribution & device testing"},{value:"production",label:"Production / App Store",hint:"App Store & Play Store submission"}]});j(c)&&(Y("Operation cancelled"),process.exit(0)),i=c,r=c==="production"?"store":c==="staging"?"adhoc":"development"}let o=`./${A.configFileName}`;if(!O.existsSync(o)){m.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let s=JSON.parse(O.readFileSync(o,"utf-8")),{projectId:a}=s;if(!a){m.error(`${A.configFileName} is missing projectId.`);return}if(e.awsProfile&&m.warn(g.yellow(`Ignoring --aws-profile. Authenticating with ${A.name} Cloud...`)),m.info(g.dim(`Setting up credentials for: ${i}`)),n==="ios")await qs(a,i,e,s,r);else{let c=$s(s,i);await ca(a,i,c,e,s)}};async function qs(e,t,n,i,r){let o=n.bundleId;if(!o){let l=i.submit?.[t]?.ios?.bundleIdentifier||i.submit?.[t]?.ios?.bundleId||Ge(i,t),p=[];try{let u=(await Z.get(`/credentials/${e}`)).data.credentials||[];p=[...new Set(u.filter(h=>h.platform==="ios"&&h.bundleId&&h.bundleId!=="*").map(h=>h.bundleId))]}catch{}if(l&&!p.includes(l)&&p.unshift(l),p.length>0){let d=[...p.map(h=>({value:h,label:h,hint:h===l?"from config":void 0})),{value:"__new__",label:"+ Enter a new Bundle ID"}],u=await Ee({message:"Which Bundle ID are you setting up credentials for?",options:d});if(j(u)&&(Y("Operation cancelled"),process.exit(0)),u==="__new__"){let h=await ve({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:f=>f.includes(".")?void 0:"Please enter a valid Bundle ID"});j(h)&&(Y("Operation cancelled"),process.exit(0)),o=h}else o=u}else{let d=await ve({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:u=>u.includes(".")?void 0:"Please enter a valid Bundle ID"});j(d)&&(Y("Operation cancelled"),process.exit(0)),o=d}}m.info(g.dim(`Bundle ID: ${o}`));let s=Rn({buildProfile:t,profile:nt(i,t)||{},requestedCredentialType:r});m.info(g.dim(`Credential storage type: ${s}`));let a=i.submit?.production?.ios?.appleId;a&&m.info(g.dim(`Using Apple ID from config: ${a}`)),await aa(e,o,t,s,s==="store"?"appstore":s==="adhoc"?"adhoc":"development",n,i,a)}var Ji=e=>re(e.expiresAt)||re(e.expires)||re(e.expirationDate)||re(e.meta?.expiresAt)||re(e.meta?.expires),ea=e=>{let t=e.credential,n=An(t)||"all apps",i=Cn(t)||"distribution",r=Ji(t);return[e.projectName,i,n,r?`expires ${r}`:void 0].filter(Boolean).join(" \xB7 ")};async function ta(e){let n=(await Z.get("/projects")).data.projects||[],i=(await Promise.all(n.map(async o=>{if(!o.projectId)return[];try{return((await Z.get(`/credentials/${o.projectId}`)).data.credentials||[]).filter(c=>_i(c,e)).map(c=>({projectId:o.projectId,projectName:o.name||o.slug||o.projectId,credential:c,certificateId:$i(c),teamId:e}))}catch{return[]}}))).flat(),r=new Map;for(let o of i){let s=`${o.projectId}:${o.certificateId||Bt(o.credential)}`,a=r.get(s);(!a||String(o.credential.createdAt||"")>String(a.credential.createdAt||""))&&r.set(s,o)}return[...r.values()]}var Yi=e=>String(e||"").replace(/[^a-zA-Z0-9]/g,"").toUpperCase(),na=(e,t)=>{let n=s=>pe("openssl",["pkcs12","-in",e,"-clcerts","-nokeys","-passin",`pass:${t}`,...s?["-legacy"]:[]],{encoding:"utf-8"}),i=n(!0);if((i.error||i.status!==0)&&(i=n(!1)),i.error||i.status!==0||!i.stdout)return;let o=(pe("openssl",["x509","-noout","-serial"],{input:i.stdout,encoding:"utf-8"}).stdout||"").match(/serial=([A-Fa-f0-9:]+)/);return o?Yi(o[1]):void 0};async function ia(e,t,n,i,r,o){if(e.certificateId)return e.certificateId;let s=await Vt(r,i,o);if(s.length===0)throw new Error("No active Apple Distribution certificates were returned by the Apple Developer Portal.");let a=na(t,n),c=a?s.filter(p=>Yi(p.serial)===a):[];if(c.length===1)return m.info(g.dim(`Matched the selected saved P12 to Apple certificate ${c[0].name||c[0].id}.`)),c[0].id;m.warn(g.yellow("This saved certificate was created by an older Mach version without its Apple Portal ID. Select its matching active certificate below."));let l=await Ee({message:"Which Apple Distribution certificate matches the selected saved P12?",options:[...s.map(p=>({value:p.id,label:[p.name||"Apple Distribution certificate",p.expires].filter(Boolean).join(" \xB7 "),hint:p.serial?`serial ${p.serial}`:void 0})),{value:"cancel",label:"Cancel"}]});if(!(j(l)||l==="cancel"))return l}async function ra(e,t,n){let i="";for(let o=1;o<=5;o++)try{let s=await Z.get(`/credentials/${t}/download`,{params:{projectId:e,format:"proxy"},responseType:"arraybuffer"});O.writeFileSync(n,Buffer.from(s.data));return}catch(s){if(i=s?.response?.data?.message||s?.message||String(s),!Qi(i)||o>=5)break;let c=Math.min(15e3,1e3*Math.pow(2,o-1));m.warn(g.yellow(`Certificate download was interrupted (${i}). Retrying with a fresh secure link in ${Math.round(c/1e3)}s\u2026 (${o}/5)`)),await zi(c)}throw new Error(`Could not download the saved Mach certificate after 5 attempts: ${i||"Unknown network error"}`)}async function oa({targetProjectId:e,targetBundleId:t,targetDistributionType:n,matchType:i,candidate:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:c,teamMeta:l}){let p=await Ui(r.projectId,"ios",r.credential),d=Li(p,{});if(!d){let b=await ut({message:`P12 password for ${r.projectName}'s saved certificate:`,validate:R=>R.length>0?void 0:"The certificate password is required"});if(j(b))return!1;d=b}let u=O.mkdtempSync(L.join(et.tmpdir(),`${A.nameLower}-reuse-cert-`)),h=L.join(u,"selected-distribution-certificate.p12"),f=`${A.nameLower} ${i} ${t}`,v=`${A.nameLower}-${i}-${Date.now()}.mobileprovision`;try{m.info(g.dim(`Downloading the selected certificate from ${r.projectName}\u2026`));let b=Bt(p);if(!b)throw new Error("The selected Mach certificate no longer has a credential ID.");await ra(r.projectId,b,h),m.info(g.dim("Importing the selected certificate into Mach\u2019s team keychain\u2026"));let R=F=>pe("security",["import",h,"-k",a,"-P",F,"-T","/usr/bin/codesign"],{encoding:"utf-8"}),k=d,y=R(k);if((y.error||y.status!==0)&&d){m.warn(g.dim("Saved P12 did not unlock with its stored password; trying the legacy empty-password format\u2026"));let F=R("");!F.error&&F.status===0&&(y=F,k="")}if(y.error||y.status!==0)throw new Error(mt(y.stdout,y.stderr)||"Could not import the selected .p12 certificate. Check its password.");let N=pe("security",["set-key-partition-list","-S","apple-tool:,apple:,codesign:","-s","-k",c,a],{encoding:"utf-8"});if(N.error||N.status!==0)throw new Error(mt(N.stdout,N.stderr)||"Could not grant codesign access to the imported certificate.");let $=await ia(r,h,k,i,s,o.shellCommand);if(!$)return!1;m.info(g.blue(`Creating a new ${i==="adhoc"?"Ad Hoc":"App Store"} profile for ${t}\u2026`));let G=pe(o.command,Fi(i,t,f,$,u,v),{cwd:process.cwd(),env:s,stdio:"inherit"});if(G.error||G.status!==0)throw new Error("Apple could not create the provisioning profile with the selected certificate.");let V=Dt(u,/\.mobileprovision$/);if(!V)throw new Error("The new provisioning profile was not produced by fastlane.");let B=Ji(p);return await Ke(e,h,"ios_cert",t,n,void 0,B,l.teamId,$,k,void 0,void 0,l.teamId,l.teamName,l.developerTeamId||l.teamId,l.appStoreConnectTeamId,l.providerId,l.providerName),await Ke(e,V,"ios_profile",t,n,void 0,void 0,l.teamId,void 0,void 0,void 0,void 0,l.teamId,l.teamName,l.developerTeamId||l.teamId,l.appStoreConnectTeamId,l.providerId,l.providerName),m.success(g.green(`\u2713 Reused the saved certificate and created credentials for ${t}.`)),!0}finally{try{O.rmSync(u,{recursive:!0,force:!0})}catch{}}}async function sa(e){let t="MATCH_ENCRYPTION_PASSPHRASE";try{let s=((await Z.get(`/projects/${e}/secrets/export?env=development`)).data.secrets||{})[t];if(s&&!s.includes("[Decryption Failed]"))return m.info(g.dim("Using existing encryption passphrase from Dashboard")),s;if(s&&s.includes("[Decryption Failed]")){m.warn(g.yellow("\u26A0\uFE0F Existing MATCH_PASSWORD could not be decrypted (encryption key changed).")),m.info(g.dim("Generating a fresh passphrase and cleaning old certificates..."));let a=Ot.randomBytes(32).toString("base64");try{await Z.post(`/projects/${e}/secrets`,{key:t,value:a,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 New encryption passphrase generated and saved"))}catch{}try{await Z.post("/credentials/clean-match-storage",{projectId:e}),m.success(g.green("\u2713 Cleaned old certificates from storage"))}catch{}return a}}catch(r){m.info(g.dim(`Could not fetch existing passphrase from Dashboard: ${r.message}`))}let n=await Ee({message:"No active encryption passphrase found on Dashboard. What would you like to do?",options:[{value:"generate",label:"Generate a new secure passphrase",hint:"Safe for first-time setup"},{value:"enter",label:"Enter existing passphrase manually",hint:"Required if you already have certs in S3"},{value:"cancel",label:"Cancel",hint:"Quit"}]});if((j(n)||n==="cancel")&&(Y("Operation cancelled"),process.exit(0)),n==="enter"){let r=await ut({message:"Enter your MATCH_PASSWORD (encryption passphrase):",validate:s=>s.length>0?void 0:"Passphrase is required"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=r;try{await Z.post(`/projects/${e}/secrets`,{key:t,value:o,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)"}),m.success(g.green("\u2713 Saved passphrase to Dashboard"))}catch{}return o}let i=Ot.randomBytes(32).toString("base64");try{await Z.post(`/projects/${e}/secrets`,{key:t,value:i,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 Generated and saved encryption passphrase to Dashboard"))}catch(r){m.warn(g.yellow(`Could not save passphrase to Dashboard: ${r.message}`))}return i}async function aa(e,t,n,i,r,o,s,a){let c=Je(),l=!1,p=b=>{c.start(b),l=!0},d=b=>{l&&(c.stop(b),l=!1)};m.info(g.blue("Configuring iOS certificate management..."));let u,h,f=ht(s,n),v=f;if(!a){let b=await ve({message:"Apple ID (for Apple Developer Portal):",placeholder:"your-email@example.com",validate:R=>R.includes("@")?void 0:"Please enter a valid email"});j(b)&&(Y("Operation cancelled"),process.exit(0)),a=b}try{let b=await sa(e),R="",k="";try{let x=await Z.post("/credentials/build-server-token",{projectId:e});x.data.status==="success"&&x.data.credentials&&(process.env.AWS_ACCESS_KEY_ID=x.data.credentials.accessKeyId,process.env.AWS_SECRET_ACCESS_KEY=x.data.credentials.secretAccessKey,x.data.credentials.sessionToken&&(process.env.AWS_SESSION_TOKEN=x.data.credentials.sessionToken),k=x.data.credentials.region||"ap-south-1",R=x.data.credentials.bucket||A.bucketPrefix,process.env.AWS_REGION=k,delete process.env.AWS_PROFILE)}catch(x){throw m.error(`Failed to authenticate with ${A.name} Cloud.`),x}if(!R||!k){m.error(`Failed to resolve S3 configuration from ${A.name} Cloud.`);return}let y=o.teamId||f.teamId||s.submit?.production?.ios?.appleTeamId;if(!y)try{let T=(await Z.get(`/projects/${e}/secrets`)).data.secrets?.find(X=>X.key==="APPLE_TEAM_ID");T&&(y=T.value,m.info(g.dim(`Using Team ID from Dashboard: ${y}`)))}catch{}y&&y===s.submit?.production?.ios?.appleTeamId&&m.info(g.dim(`Using Apple Team ID from config: ${y}`));let N=await yt({appleId:a,config:s,profile:n,initialTeam:{...f,teamId:y,developerTeamId:f.developerTeamId||y},promptToPersistConfig:!y,saveTeamId:y?void 0:x=>Wi(e,x)});if(!N?.teamId)return;y=N.teamId;let $={...f,...N,teamId:y,developerTeamId:N.developerTeamId||f.developerTeamId||y};v=$;let G=hs(e,y);m.info(g.dim(`Using match storage prefix: ${G}`));let V=await Ps(),B={...V.env};process.env.CI||delete B.CI,p(`Preparing ${r} certificate sync...`),d("Starting certificate sync...");let F=`${A.buildPrefix}-${y}-${r}.keychain-db`,K=A.keychainPassword;try{let T=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${F}`;m.info(g.dim(`Ensuring keychain exists: ${F}`));try{_e(`security create-keychain -p ${K} ${F} 2>/dev/null || true`),_e(`security unlock-keychain -p ${K} ${F}`),_e(`security set-keychain-settings ${F}`);let _=_e("security list-keychains -d user").toString();if(!_.includes(F)){m.info(g.dim(`Adding ${F} to search list`));let M=[..._.replace(/"/g,"").split(`
403
- `).map(E=>E.trim()).filter(E=>E.length>0),T].join(" ");_e(`security list-keychains -d user -s ${M}`)}}catch(_){m.warn(g.dim("Keychain setup warning (non-critical): "+_.message))}let X,oe;try{let U=((await Z.get(`/credentials/${e}`)).data.credentials||[]).find(M=>M.type==="asc_api_key"&&M.issuerId);if(U){let M=await Z.get(`/credentials/${U.credentialId}/download`,{params:{projectId:e,format:"raw"}});if(M.data.downloadUrl){let P=await(await import("axios")).default.get(M.data.downloadUrl,{responseType:"arraybuffer"}),D=L.join(et.tmpdir(),`mach-asc-${Date.now()}`);O.mkdirSync(D,{recursive:!0}),u=L.join(D,`AuthKey_${U.keyId}.p8`),O.writeFileSync(u,Buffer.from(P.data)),X=U.keyId,oe=U.issuerId,m.success(g.green("\u2713 ASC API key loaded \u2014 no 2FA required for Portal operations"))}}}catch(_){m.warn(g.dim(`Could not load ASC API key: ${_.message}. Will fall back to Apple ID auth.`))}m.info(g.dim("Generating secure P12 export password..."));let me=qi();m.success(g.green("\u2713 Secure P12 password generated.")),h=O.mkdtempSync(L.join(et.tmpdir(),`${A.nameLower}-match-${r}-`));let ae={...B,AWS_REGION:process.env.AWS_REGION||"ap-south-1",AWS_ACCESS_KEY_ID:process.env.AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY:process.env.AWS_SECRET_ACCESS_KEY,SSL_CERT_FILE:"/etc/ssl/cert.pem",AWS_CA_BUNDLE:"/etc/ssl/cert.pem",FASTLANE_SSL_CA_CERT:"/etc/ssl/cert.pem",MATCH_PASSWORD:b,FASTLANE_USER:a,FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_TEAM_ID:y,MATCH_KEYCHAIN_NAME:T,MATCH_KEYCHAIN_PASSWORD:K,TERM:process.env.TERM||"xterm-256color",SHELL:process.env.SHELL||"/bin/zsh",MATCH_OUTPUT_PATH:h,MATCH_STORAGE_MODE:"s3",MATCH_S3_REGION:k,MATCH_S3_BUCKET:R,MATCH_S3_OBJECT_PREFIX:G,MATCH_USERNAME:a,MATCH_APP_IDENTIFIER:t,MATCH_TYPE:r,[`${A.envPrefix}P12_PASSWORD`]:me,...u&&X&&oe?{APP_STORE_CONNECT_API_KEY_KEY_ID:X,APP_STORE_CONNECT_API_KEY_ISSUER_ID:oe,APP_STORE_CONNECT_API_KEY_KEY_FILEPATH:u,FASTLANE_SKIP_2FA:"1"}:{}};if(o.force){m.warn(g.yellow(`
404
- \u26A0\uFE0F Force flag detected: Hard resetting ${r} certificates...`)),m.info(g.dim("Detected decryption failure loop. Clearing remote storage directly to allow fresh generation.")),m.info(g.dim(`Cleaning match storage for Team ID: ${y}...`));try{(await Z.post("/credentials/clean-match-storage",{projectId:e,teamId:y,storagePrefix:G})).data.status==="success"&&m.success(g.green(`\u2713 Cleared S3 storage for Team ID: ${y}`))}catch(_){m.warn(g.yellow(`S3 cleanup via API failed: ${_.message}`)),m.info(g.dim("Continuing to attempt standard nuke..."))}try{_e(`${V.shellCommand} match nuke ${r} --skip_confirmation`,{stdio:"inherit",cwd:process.cwd(),env:ae}),m.success(g.green(`\u2713 Nuked existing ${r} credentials`))}catch{m.warn(g.yellow("Standard nuke failed (likely due to password mismatch).")),m.info(g.dim("Since S3 was cleared manually, proceeding to generation..."))}}let ee=r==="adhoc"||r==="development";if(r==="adhoc"||r==="development")try{m.info(g.blue("Fetching registered devices..."));let U=(await Z.get("/devices",y?{params:{teamId:y}}:void 0)).data.devices||[];if(y)try{let M=await Z.get("/devices",{params:{teamId:"LEGACY"}}),E=new Map;for(let P of[...U,...M.data.devices||[]])E.set(P.udid,P);U=Array.from(E.values())}catch{}if(U.length===0)m.warn(g.yellow("No registered devices found. Profile will only include devices already on the Apple Developer Portal.")),m.info(g.dim(`Register devices with: ${A.nameLower} device register`));else{let{multiselect:M}=await import("@clack/prompts"),E=await M({message:`Select devices to include in the ${r} profile:`,options:U.map(P=>({value:P.udid,label:`${P.name} (${P.udid.substring(0,12)}...)`,hint:P.model||P.platform})),initialValues:U.map(P=>P.udid)});if(!j(E)&&E.length>0){let P=U.filter(D=>E.includes(D.udid));if(m.info(g.blue(`Registering ${P.length} device(s) on Apple Developer Portal...`)),y&&await Promise.all(P.filter(D=>!D.teamId).map(D=>Z.post("/devices",{udid:D.udid,name:D.name,platform:"ios",addedVia:D.addedVia||"cli",teamId:y,teamName:$.teamName}).catch(()=>{}))),u&&X&&oe)await Ys(P,X,oe,u);else{m.info(g.dim("You will be prompted for a 2FA code once \u2014 type it and press Enter."));for(let D of P){let W=D.name.replace(/"/g,'\\"');pe(`${V.shellCommand} run register_device name:"${W}" udid:"${D.udid}"`,{shell:!0,env:ae,stdio:"inherit",cwd:process.cwd()})}}m.info(g.green("\u2713 Device registration complete.")),ee=!0}}}catch(_){m.warn(g.yellow(`Could not fetch registered devices: ${_.message}`)),m.info(g.dim("Continuing without explicit device registration."))}try{let _=`${A.nameLower} ${r} ${t}`,U=As(V.shellCommand,r,t,_,ee);ee&&m.info(g.dim(`Refreshing ${r} provisioning profile when device list changes (--force_for_new_devices).`));let M=pe(U,{shell:!0,cwd:process.cwd(),env:ae,stdio:"inherit",encoding:"utf-8"});if(M.status!==0){m.warn(g.yellow(`
405
- Certificate sync failed. Attempting to create App ID and retry...`));try{_e(`${V.shellCommand} produce --app_identifier "${t}" --app_name "${t}" --skip_itc`,{stdio:"inherit",env:ae}),m.success(g.green("\u2713 App ID created successfully")),m.info(g.blue("Retrying certificate sync...")),M=pe(U,{shell:!0,cwd:process.cwd(),env:ae,stdio:"inherit",encoding:"utf-8"})}catch{}if(M.status!==0)throw new Error("fastlane match failed")}}catch(_){m.warn(g.yellow(`
406
- Certificate sync failed. This can be caused by an incorrect encryption passphrase, an expired Apple session, or Apple\u2019s Distribution certificate limit.`));let U=[];if(r==="adhoc"||r==="appstore")try{U=await ta(y)}catch{}let M=await Ee({message:"What would you like to do?",options:[...U.length>0?[{value:"reuse_saved",label:"Reuse a saved Mach certificate",hint:`${U.length} compatible certificate${U.length===1?"":"s"} found \u2014 no certificate is revoked`}]:[],{value:"retry_password",label:"Retry with a different MATCH_PASSWORD",hint:"Manually enter the decryption passphrase"},{value:"check_portal",label:"Check Apple Portal",hint:"Inspect certificate limits or explicitly revoke an old certificate"},{value:"manual",label:"Fallback to manual upload",hint:"Provide .p12 and .mobileprovision files"},{value:"cancel",label:"Cancel",hint:"Go back"}]});if(j(M)||M==="cancel")throw _;if(M==="reuse_saved"){let E=await Ee({message:"Select a saved Apple Distribution certificate to reuse:",options:[...U.map((W,z)=>({value:String(z),label:ea(W),hint:W.certificateId?`Apple Team ${W.teamId}`:`Apple Team ${W.teamId} \xB7 legacy record; Apple certificate matching may be requested`})),{value:"cancel",label:"Cancel"}]});if(j(E)||E==="cancel")throw _;let P=U[Number(E)];if(!P)throw new Error("The selected saved certificate is no longer available.");if(await oa({targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:r,candidate:P,fastlane:V,matchEnv:ae,keychainPath:T,keychainPassword:K,teamMeta:$}))return;throw _}else if(M==="retry_password"){m.info(g.dim(`
407
- You are overriding the dashboard passphrase for this session.`));let E=await ut({message:"Enter the correct MATCH_PASSWORD for this project:"});if(E&&!j(E)){b=E,m.info(g.blue("Retrying with provided passphrase..."));let P={...ae,MATCH_PASSWORD:b};if(pe(`${V.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:P}).status===0)await Z.post(`/projects/${e}/secrets`,{key:"MATCH_ENCRYPTION_PASSPHRASE",value:b,description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 Dashboard passphrase updated."));else throw new Error("Sync failed again with provided passphrase.")}else throw _}else if(M==="check_portal")try{let E=await Vt(ae,r,V.shellCommand);if(E.length>0){if(m.info(g.dim(`Found ${E.length} existing ${r} certificates on the portal.`)),await pa(r,ae,e,V.shellCommand,E)&&(m.info(g.blue("Retrying certificate sync...")),pe(`${V.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:ae}).status!==0))throw new Error("Retry failed")}else throw m.error(g.red("No existing certificates found on portal to resolve.")),_}catch(E){throw m.warn(g.dim(`Portal check warning: ${E.message}`)),_}else throw _}m.success(g.green("\u2713 Certificates fetched and synced"));let ce=h,se=L.join(ce,`${A.fastlanePrefix}_export.p12`),Ce=Dt(ce,/\.mobileprovision$/);try{let U=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${F}`;O.existsSync(ce)||O.mkdirSync(ce,{recursive:!0}),m.info(g.dim("Exporting certificate from keychain for dashboard upload..."));let M=_e(`security find-identity -v -p codesigning "${U}"`,{encoding:"utf-8"});m.info(g.dim(`Identities in keychain:
408
- ${M.trim()}`));let E=pe("security",["export","-k",U,"-t","identities","-f","pkcs12","-o",se,"-P",me],{encoding:"utf-8"});if(E.error||E.status!==0)throw new Error(mt(E.stdout,E.stderr)||"security could not export the signing certificate.");try{let P=pe("openssl",["pkcs12","-in",se,"-nokeys","-passin",`pass:${me}`,"-legacy"],{encoding:"utf-8"});if((P.error||P.status!==0)&&(P=pe("openssl",["pkcs12","-in",se,"-nokeys","-passin",`pass:${me}`],{encoding:"utf-8"})),P.error||P.status!==0)throw new Error(mt(P.stdout,P.stderr)||"openssl could not read the exported P12.");let D=P.stdout||"";if(!D.includes(y))throw new Error(`Exported P12 does not contain identity for team ${y}. Found: ${D.substring(0,200)}`);m.success(g.green(`\u2713 P12 verified \u2014 contains correct team identity (${y})`))}catch(P){throw new Error(`P12 verification failed: ${P.message}`)}}catch{m.warn(g.dim("Could not export certificate from keychain."))}o.teamId&&!y&&await Wi(e,o.teamId);let De=O.existsSync(se)?se:Dt(ce,/\.p12$/);if(De&&Ce){let _,U;try{let M=await Vt(ae,r,V.shellCommand);M.length>0&&(_=M[0].expires,U=M[0].id)}catch{m.warn(g.dim("Could not fetch expiration date or ID for dashboard record."))}await Ke(e,De,"ios_cert",t,i,void 0,_,o.teamId||y,U,me,void 0,void 0,$.teamId,$.teamName,$.developerTeamId,$.appStoreConnectTeamId,$.providerId,$.providerName),await Ke(e,Ce,"ios_profile",t,i,void 0,_,o.teamId||y,void 0,void 0,void 0,void 0,$.teamId,$.teamName,$.developerTeamId,$.appStoreConnectTeamId,$.providerId,$.providerName),m.success(g.green("\u2713 Both iOS certificate and provisioning profile uploaded successfully"))}else m.warn(g.yellow("Certificates generated but not found in expected location.")),m.info(g.dim("Falling back to manual upload...")),await Zi(e,t,i,v)}catch(x){d("Certificate fetch failed"),m.error(g.red(`Error: ${x.message}`)),m.info(g.dim("Falling back to manual upload...")),await Zi(e,t,i,v)}}catch(b){d("iOS setup failed"),m.error(g.red(`Error: ${b.message}`))}finally{if(u)try{O.rmSync(L.dirname(u),{recursive:!0,force:!0})}catch{}if(h)try{O.rmSync(h,{recursive:!0,force:!0})}catch{}}}async function Wi(e,t){try{await Z.post(`/projects/${e}/secrets`,{key:"APPLE_TEAM_ID",value:t,description:"Apple Developer Team ID (used for iOS signing)"}),m.success(g.green(`\u2713 Saved Team ID ${t} to Dashboard`))}catch(n){m.warn(g.yellow(`Could not save Team ID to Dashboard: ${n.message}`))}}async function Zi(e,t,n,i={}){m.info(g.yellow(`
409
- Manual Upload Mode`)),m.info("Please provide your certificate and provisioning profile:");let r=await ve({message:"Path to .p12 certificate file:",validate:a=>O.existsSync(a)?void 0:"File not found"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=await ve({message:"Path to .mobileprovision file:",validate:a=>O.existsSync(a)?void 0:"File not found"});j(o)&&(Y("Operation cancelled"),process.exit(0));let s=Je();s.start(`Uploading to ${A.name} Dashboard...`);try{await Ke(e,r,"ios_cert",t,n,void 0,void 0,i.teamId,void 0,void 0,void 0,void 0,i.teamId,i.teamName,i.developerTeamId||i.teamId,i.appStoreConnectTeamId,i.providerId,i.providerName),await Ke(e,o,"ios_profile",t,n,void 0,void 0,i.teamId,void 0,void 0,void 0,void 0,i.teamId,i.teamName,i.developerTeamId||i.teamId,i.appStoreConnectTeamId,i.providerId,i.providerName),s.stop("Upload complete"),m.success(g.green("\u2713 iOS credentials uploaded successfully"))}catch(a){throw s.stop("Upload failed"),a}}async function ca(e,t,n,i,r){let o=Je();m.step(g.blue("Android Credential Setup"));let s=i.bundleId;if(!s){let d=it(r,t),u=[];try{let f=(await Z.get(`/credentials/${e}`)).data.credentials||[];u=[...new Set(f.filter(v=>v.platform==="android"&&v.bundleId&&v.bundleId!=="*").map(v=>v.bundleId))]}catch{}if(d&&!u.includes(d)&&u.unshift(d),u.length>0){let h=[...u.map(v=>({value:v,label:v,hint:v===d?"from config":void 0})),{value:"__new__",label:"+ Enter a new Package Name"}],f=await Ee({message:"Which Package Name are you setting up credentials for?",options:h});if(j(f)&&(Y("Operation cancelled"),process.exit(0)),f==="__new__"){let v=await ve({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:b=>b.includes(".")?void 0:"Please enter a valid package name"});j(v)&&(Y("Operation cancelled"),process.exit(0)),s=v}else s=f}else{let h=await ve({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:f=>f.includes(".")?void 0:"Please enter a valid package name"});j(h)&&(Y("Operation cancelled"),process.exit(0)),s=h}}try{let h=((await Z.get(`/credentials/${e}`)).data.credentials||[]).find(f=>f.platform==="android"&&f.distributionType===n&&f.bundleId===s);if(h){m.warn(g.yellow(`\u26A0\uFE0F Existing Android credentials found for ${n}`));let f=await ve({message:"What would you like to do? (use/new/cancel)",validate:v=>{let b=v.toLowerCase();if(!(b==="use"||b==="new"||b==="cancel"))return"Please type: use, new, or cancel"}});if(j(f)||f.toLowerCase()==="cancel")return;if(f.toLowerCase()==="use"){m.success(g.green("\u2713 Using existing credentials."));return}await Z.delete(`/credentials/${h.credentialId}?projectId=${e}`)}}catch{}let a="./android/app/my-release-key.jks";if(O.existsSync(a)){let d=await bn({message:"Upload existing keystore?"});if(d&&!j(d)){let u=await ve({message:"Key alias:",initialValue:"my-key-alias"});if(j(u))return;let h=await ut({message:"Keystore password:"});if(j(h))return;let f=await ut({message:"Key password (leave blank if same as keystore password):"});if(j(f))return;let v=f.trim()||h;await Ke(e,a,"android_keystore",s,n,u,void 0,void 0,void 0,void 0,h,v),m.success(g.green("\u2713 Keystore uploaded"));return}}m.info(g.blue("Generating new Android keystore..."));let c=i.keyAlias||`${A.nameLower}-${da()}`,l=qi(),p=`./${A.nameLower}-${t}.jks`;O.existsSync(p)&&O.unlinkSync(p),o.start("Generating keystore...");try{let d=l.replace(/'/g,"'\\''");_e(`keytool -genkeypair -v -keystore "${p}" -alias "${c}" -keyalg RSA -keysize 2048 -validity 10000 -storepass '${d}' -keypass '${d}' -dname "CN=${A.name} Build, OU=Mobile, O=Company, L=City, S=State, C=US"`,{stdio:"inherit"}),o.stop("Keystore generated"),await Ke(e,p,"android_keystore",s,n,c,void 0,void 0,void 0,void 0,l,l),m.success(g.green("\u2713 Android credentials uploaded successfully")),m.info(g.cyan(`Key Alias: ${c}`))}catch(d){throw o.stop("Generation failed"),new Error(`Keystore generation failed: ${d.message}`)}}var zi=e=>new Promise(t=>setTimeout(t,e));function Qi(e){return/ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNABORTED|socket hang up|network|timeout|temporar/i.test(e)||/API_ERROR:\s*(408|409|425|429|5\d\d)/i.test(e)}async function Ke(e,t,n,i,r,o,s,a,c,l,p,d,u,h,f,v,b,R){let k=L.basename(t);m.info(g.dim(`Uploading ${k} (Isolated process)...`));let y=new URL(import.meta.url),N=L.dirname(y.pathname),G=[L.join(N,"commands","isolated-upload.js"),e,t,n,i,r,o||"undefined",s||"undefined",a||"undefined",c||"undefined",l||"undefined",p||"undefined",d||"undefined",u||"undefined",h||"undefined",f||"undefined",v||"undefined",b||"undefined",R||"undefined"],V="",B=5;for(let F=1;F<=B;F++){let K=pe("node",G,{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(K.status===0&&K.stdout.includes("SUCCESS")){m.info(g.dim(`\u2713 ${k} uploaded and registered.`));return}if(K.status===0){m.warn(g.yellow(`Isolated upload finished but success not confirmed: ${K.stdout}`));return}if(V=(K.stderr||K.stdout||K.error?.message||"Unknown isolated upload failure").trim(),!Qi(V)||F>=B)throw m.error(g.red(`Isolated Upload Failed: ${V}`)),new Error(V);let T=Math.min(3e4,1500*Math.pow(2,F-1));m.warn(g.yellow(`Upload failed with a transient error. Retrying ${k} in ${Math.round(T/1e3)}s... (${F}/${B})`)),await zi(T)}throw new Error(V||"Unknown isolated upload failure")}async function la(e){let t=Je(),n=e.platform,i=`./${A.configFileName}`;if(!O.existsSync(i)){m.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(O.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){m.error(`${A.configFileName} is missing projectId.`);return}try{t.start("Fetching project secrets...");let a=(await Z.get(`/projects/${o}/secrets/export?env=all`)).data.secrets||{};t.stop("Secrets fetched and merged."),t.start("Fetching credentials...");let l=(await Z.get(`/credentials/${o}`)).data.credentials||[];t.stop(`Found ${l.length} metadata records.`);let p=l.filter(f=>f.platform===n);if(p.length===0){m.info(`No ${n} credentials found on Dashboard.`);return}let d="./credentials.json",u={};if(O.existsSync(d))try{u=JSON.parse(O.readFileSync(d,"utf-8"))}catch{m.warn("Could not parse existing credentials.json, creating a new one.")}u[n]||(u[n]={});let h=L.join(process.cwd(),"credentials",n);O.existsSync(h)||O.mkdirSync(h,{recursive:!0});for(let f of p){t.start(`Downloading ${f.type} (${f.distributionType})...`);try{let v=await Z.get(`/credentials/${f.credentialId}/download`,{params:{projectId:o,format:"raw"}});if(v.data.status==="success"&&v.data.downloadUrl){let b=L.join(process.cwd(),"credentials",n,f.distributionType);O.existsSync(b)||O.mkdirSync(b,{recursive:!0});let R=f.s3Key?.split(".").pop()||(f.type.includes("keystore")?"jks":f.type.includes("cert")?"p12":"mobileprovision"),k=`${f.type}.${R}`,y=L.join(b,k),N=await Mi.get(v.data.downloadUrl,{responseType:"arraybuffer"});O.writeFileSync(y,Buffer.from(N.data));let $=L.join("credentials",n,f.distributionType,k),G="",V="",B={alias:"",keystorePassword:"",keyPassword:""};if(n==="ios"&&f.type==="ios_cert"||n==="android"&&f.type==="android_keystore"){let F=await Ui(o,n,f);if(n==="ios"&&f.type==="ios_cert"&&R.toLowerCase()==="p12"){if(G=Li(F,a),G){let K=Di(y,`${L.basename(y,L.extname(y))}-password.txt`,G);V=L.join("credentials",n,f.distributionType,L.basename(K))}}else if(n==="android"&&f.type==="android_keystore"&&(B=ks(F,a),B.keystorePassword||B.keyPassword)){let K=[B.alias?`keyAlias=${B.alias}`:void 0,B.keystorePassword?`keystorePassword=${B.keystorePassword}`:void 0,B.keyPassword?`keyPassword=${B.keyPassword}`:void 0].filter(Boolean).join(`
410
- `),x=Di(y,`${L.basename(y,L.extname(y))}-passwords.txt`,K);V=L.join("credentials",n,f.distributionType,L.basename(x))}}if(n==="android")f.type==="android_keystore"&&(u.android.keystore={keystorePath:$,keystorePassword:B.keystorePassword,keyAlias:B.alias,keyPassword:B.keyPassword},V&&(u.android.keystore.keystoreArchivePath=V));else if(n==="ios"){let F=f.distributionType==="store"?"production":f.distributionType==="adhoc"?"staging":"development";u.ios[F]||(u.ios[F]={}),f.type==="ios_cert"?(u.ios[F].certificatePath=$,u.ios[F].certificatePassword=G,V&&(u.ios[F].certificateArchivePath=V)):f.type==="ios_profile"&&(u.ios[F].provisioningProfilePath=$)}t.stop(`\u2713 ${f.type} (${f.distributionType}) saved${V?" with password archive":""}.`)}}catch(v){let b=v.response?.data?.message||v.message;t.stop(g.dim(`- Skipped ${f.type} (${f.distributionType}): ${b}`))}}O.writeFileSync(d,JSON.stringify(u,null,2)),m.success(g.green("\u2713 Local credentials.json updated.")),us("Credentials have been synced to your local machine. Ensure credentials.json and credentials/ is added to your .gitignore.","Sync Complete")}catch(s){t.stop(g.red("Sync failed.")),m.error(`Error: ${s.message}`)}}function qi(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_+=",t="";for(let n=0;n<24;n++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}function da(e=8){let t="abcdefghijklmnopqrstuvwxyz0123456789",n="";for(let i=0;i<e;i++)n+=t.charAt(Math.floor(Math.random()*t.length));return n}async function pa(e,t,n,i,r){let o=r||await Vt(t,e,i);if(!o||o.length===0)return!1;let s=await Ee({message:"Select a certificate to revoke:",options:[...o.map(a=>({value:`revoke:${a.id}`,label:`Revoke: ${a.name} (${a.expires})`})),{value:"nuke",label:"Revoke All"},{value:"cancel",label:"Cancel"}]});return j(s)||s==="cancel"?!1:s==="nuke"?(_e(`${i} match nuke ${e}`,{stdio:"inherit",cwd:process.cwd(),env:t}),!0):typeof s=="string"&&s.startsWith("revoke:")?(await ua(t,s.split(":")[1],i),!0):!1}async function Vt(e,t,n){let i=t==="development"?"development":"distribution",r=`
400
+ `,"utf8")),o.writeZip(i),i},$s=e=>{let t=e.toLowerCase();return t==="production"||t==="prod"||t.includes("store")||t.endsWith("-production")||t.endsWith("-prod")},_s=(e,t)=>{let n=nt(e,t)||{},i=ft(n.distribution),r=ft(n.environment);return i==="store"||r==="production"||r==="store"||$s(t)?"store":"internal"},Fs=["development","preview","production"],Ts="U27F4V844T",yn=null;function Wt(){return yn||(yn=hs("@expo/apple-utils")),yn}function Vi(e){let t=n=>n.replace(/^.*The password is only used to authenticate with Apple and never stored on Expo servers.*(?:\r?\n)?/gm,"").replace(/^.*Learn more\..*(?:\r?\n)?/gm,"");if(typeof e=="string")return t(e);if(Buffer.isBuffer(e)){let n=e.toString("utf-8"),i=t(n);return i===n?e:Buffer.from(i,"utf-8")}return e}async function Os(e){let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr);process.stdout.write=(i,...r)=>t(Vi(i),...r),process.stderr.write=(i,...r)=>n(Vi(i),...r);try{return await e()}finally{process.stdout.write=t,process.stderr.write=n}}function Hi(e){return O.existsSync(X.resolve(e))?void 0:"File not found"}function Ds(){try{let e=`./${A.configFileName}`;return O.existsSync(e)?JSON.parse(O.readFileSync(e,"utf-8")):{}}catch{return{}}}function Bs(e,t){let n=String(e.name||t||"Mobile app").trim().replace(/\s+/g," ")||"Mobile app",i=new Date,r=[i.getFullYear(),String(i.getMonth()+1).padStart(2,"0"),String(i.getDate()).padStart(2,"0")].join(""),o=Ot.randomBytes(2).toString("hex").toUpperCase(),s=` ${r}-${o}`;return`${`MACH Push ${n}`.slice(0,Math.max(1,50-s.length))}${s}`}async function Vs(e){let t=e.submit?.production?.ios?.appleId||e.submit?.preview?.ios?.appleId||e.submit?.development?.ios?.appleId,n=await ve({message:"Apple ID (for Apple Developer Portal):",initialValue:t,validate:i=>i.includes("@")?void 0:"Enter a valid Apple ID email"});return j(n)&&(Y("Operation cancelled"),process.exit(0)),n}async function Ws(e){let t=await ut({message:`Apple password for ${e} (used only for Apple login, not stored):`,validate:n=>n.trim()?void 0:"Password is required"});return j(t)&&(Y("Operation cancelled"),process.exit(0)),t}function Zs(e){return(Array.isArray(e?.services)?e.services:[]).some(n=>n?.id===Ts||/apple push notification|apns/i.test(String(n?.name||"")))}async function Ms(e){let{Keys:t}=Wt(),n=Je();try{n.start("Fetching existing APNs keys from Apple...");let i=await t.getKeysAsync(e),o=(await Promise.all(i.map(async s=>{try{return await t.getKeyInfoAsync(e,{id:s.id})}catch{return s}}))).filter(Zs);return n.stop(g.green(`Found ${o.length} APNs key${o.length===1?"":"s"}.`)),o}catch(i){throw n.stop(g.red("Could not fetch APNs keys from Apple.")),i}}async function js(e){let{Keys:t}=Wt(),i=(await Ms(e)).filter(c=>c.canRevoke!==!1);if(i.length===0)return m.warn(g.yellow("No revokable APNs keys were found for this Apple team.")),!1;let r=await Ee({message:"Select an APNs key to revoke:",options:i.map(c=>({value:c.id,label:`${c.name||"Untitled APNs key"} (${c.id})`,hint:c.canDownload?"APNs key, private key may still be downloadable":"APNs key"}))});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=i.find(c=>c.id===r);m.warn(g.yellow("Revoking this key can break push notifications for any service currently using it."));let s=await bn({message:`Revoke "${o?.name||"Untitled APNs key"}" (${r})? This cannot be undone.`,initialValue:!1});if(j(s)&&(Y("Operation cancelled"),process.exit(0)),!s)return m.info(g.dim("APNs key was not revoked.")),!1;let a=Je();try{return a.start(`Revoking APNs key ${r}...`),await t.revokeKeyAsync(e,{id:r}),a.stop(g.green(`Revoked APNs key ${r}.`)),!0}catch(c){throw a.stop(g.red(`Could not revoke APNs key ${r}.`)),c}}async function Gs(e,t){let{Keys:n}=Wt(),i=0;for(;;){let r=t(),o=Je();try{o.start(`Creating APNs auth key (${r})...`);let s=await n.createKeyAsync(e,{name:r,isApns:!0});o.message("Downloading APNs private key...");let a=await n.downloadKeyAsync(e,{id:s.id});if(!a)throw new Error("Apple did not return the APNs private key.");return o.stop(g.green(`APNs key generated: ${s.id}`)),{keyId:s.id,keyName:r,privateKey:a}}catch(s){if(o.stop(g.red("APNs key generation failed.")),Ls(s)&&i<3){i+=1,m.warn(g.yellow("Apple says that APNs key name already exists. Retrying with a new generated name..."));continue}if(!Ki(s))throw s;Ji(s);let a=await Ee({message:"Apple APNs key limit reached. What do you want to do?",options:[{value:"revoke",label:"List and revoke an existing APNs key",hint:"Then Mach will create a new key"},{value:"retry",label:"Try creating again"},{value:"exit",label:"Exit"}]});if((j(a)||a==="exit")&&(Y("Operation cancelled"),process.exit(0)),a==="revoke"&&await js(e))continue}}}async function Us(e,t){let n=await Vs(e);try{let i=await Ws(n),{Auth:r}=Wt();m.info(g.dim("Signing in to Apple Developer Portal..."));let o=await Os(()=>r.loginAsync({username:n,password:i},{autoResolveProvider:!0})),s=String(o?.context?.teamId||"").trim().toUpperCase(),a=await Gs(o.context,()=>Bs(e,t));return{keyId:a.keyId,teamId:s,privateKey:a.privateKey}}catch(i){throw m.error(g.red("APNs key generation failed.")),i}}function Ki(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
401
+ `);return/maximum allowed number.*keys/i.test(t)||/already reached the maximum/i.test(t)}function Ls(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
402
+ `);return/another key with same name exists/i.test(t)||/same name already exists/i.test(t)}function Ji(e){if(m.warn(g.yellow(e?.message||"Could not generate APNs key automatically.")),Ki(e)){m.info(g.dim("Apple rejected the request because this team is already at its APNs auth-key limit.")),m.info(g.dim("If you saved an existing .p8 file, upload it here. If not, delete an unused APNs key in Apple Developer, then generate again.")),m.info(g.dim("Apple only lets you download an APNs .p8 private key when the key is first created."));return}m.info(g.dim("You can upload an existing .p8 key, retry generation, or exit and try again later."))}async function In(){let e=await Ee({message:"Where should Mach save this APNs key?",options:[{value:"all",label:"All environments",hint:"Recommended \u2014 one APNs key works for sandbox and production"},{value:"development",label:"Development only"},{value:"preview",label:"Preview only"},{value:"production",label:"Production only"}]});return j(e)&&(Y("Operation cancelled"),process.exit(0)),e==="all"?Fs:[e]}async function Xs(e,t,n,i){let r=i.teamId||e.teamId;if(!r){let o=await ve({message:"Apple Team ID:",validate:s=>/^[A-Z0-9]{10}$/i.test(s.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});j(o)&&(Y("Operation cancelled"),process.exit(0)),r=o.trim().toUpperCase()}for(let o of t)await Tt("apns",{...e,environment:o,privateKey:i.privateKey,teamId:r,keyId:i.keyId,bundleId:n})}async function Wi(e,t,n){let i=await ve({message:"Path to APNs auth key (.p8):",validate:Hi});j(i)&&(Y("Operation cancelled"),process.exit(0));let r=await ve({message:"Apple Team ID:",initialValue:e.teamId,validate:s=>s.trim()?void 0:"Team ID is required"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=await ve({message:"APNs Key ID:",initialValue:e.keyId,validate:s=>s.trim()?void 0:"Key ID is required"});j(o)&&(Y("Operation cancelled"),process.exit(0));for(let s of t)await Tt("apns",{...e,environment:s,file:i,teamId:r,keyId:o,bundleId:n})}async function Hs(e){let t=Ds(),n=e.bundleId||Ge(t)||t.push?.iosBundleId;for(;;){let i=await Ee({message:"How do you want to configure APNs?",options:[{value:"generate",label:"Generate new APNs key with Apple",hint:"Mach creates, downloads once, and uploads it securely"},{value:"upload",label:"Upload existing .p8 key",hint:"Use a key you already downloaded from Apple"}]});if(j(i)&&(Y("Operation cancelled"),process.exit(0)),i==="upload"){let r=await In();await Wi(e,r,n);return}try{let r=await Us(t,n),o=await In();await Xs(e,o,n,r);return}catch(r){Ji(r);let o=await Ee({message:"APNs key was not created. What do you want to do?",options:[{value:"upload",label:"Upload existing .p8 key"},{value:"retry",label:"Try generating again"},{value:"exit",label:"Exit"}]});if((j(o)||o==="exit")&&(Y("Operation cancelled"),process.exit(0)),o==="upload"){let s=await In();await Wi(e,s,n);return}}}}async function Ks(e){let t=await ve({message:"Path to Firebase service account JSON:",validate:Hi});j(t)&&(Y("Operation cancelled"),process.exit(0));let n;try{n=JSON.parse(O.readFileSync(t,"utf8"))}catch(i){Y(`Invalid Firebase service account JSON: ${i.message}`),process.exit(1)}await Tt("fcm",{...e,serviceAccount:n})}async function Js(e,t){if(t==="ios"){await Hs(e);return}await Ks(e)}function Ys(e,t,n){let i=O.readFileSync(n,"utf8"),r=Math.floor(Date.now()/1e3),o=Buffer.from(JSON.stringify({alg:"ES256",kid:e,typ:"JWT"})).toString("base64url"),s=Buffer.from(JSON.stringify({iss:t,iat:r,exp:r+1200,aud:"appstoreconnect-v1"})).toString("base64url"),a=`${o}.${s}`,c=Ot.createSign("SHA256");c.update(a);let l=c.sign({key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${l}`}async function zs(e,t,n,i){let r=Ys(t,n,i),o=(await import("axios")).default;for(let s of e)try{await o.post("https://api.appstoreconnect.apple.com/v1/devices",{data:{type:"devices",attributes:{name:s.name,udid:s.udid,platform:"IOS"}}},{headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"}}),m.info(g.dim(` \u2713 Registered: ${s.name}`))}catch(a){let c=a.response?.data?.errors;c?.some(p=>p.code==="ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE"||p.detail?.toLowerCase().includes("already registered")||p.detail?.toLowerCase().includes("already exists"))?m.info(g.dim(` Already on Portal: ${s.name}`)):m.warn(g.yellow(` Could not register ${s.name}: ${c?.[0]?.detail||a.message}`))}}var Qs=async e=>{ps(g.bgCyan.black(A.cliTag("Credentials")));let t=await Ee({message:"Select platform:",options:[{value:"ios",label:"iOS"},{value:"android",label:"Android"}]});j(t)&&(Y("Operation cancelled"),process.exit(0));let n=await Ee({message:"What do you want to do?",options:[{value:"setup",label:"Build Credentials (Certs/Profiles)",hint:"Manage everything needed to build your project"},{value:"download",label:"Download credentials (credentials.json)",hint:"Sync credentials from Dashboard to local project"},{value:"service",label:"App Store Connect API Key (Magic)",hint:"Manage your API Key for automated submission"},{value:"push",label:"Push Notifications",hint:t==="ios"?"Upload APNs key":"Upload Firebase service account"},{value:"back",label:"Go back"},{value:"exit",label:"Exit"}].filter(i=>(t==="android"&&i.value==="service"&&(i.label="Google Service Account (JSON)"),!0))});if((j(n)||n==="exit")&&(Y("Operation cancelled"),process.exit(0)),n==="back")return Qs(e);n==="setup"?await qs({...e,platform:t}):n==="download"?await da({...e,platform:t}):n==="service"?await Vn({...e,platform:t}):n==="push"&&await Js(e,t),us(g.green("Done!"))},qs=async e=>{let t=Je(),n=e.platform,i=e.profile,r=e.credentialType;if(r&&!Ut(r)){m.error("Credential type must be development, adhoc, or store.");return}if(!i&&r){let c=Ut(r);i=c==="store"?"production":c==="adhoc"?"staging":"development"}if(!i){let c=await Ee({message:"Select credential type:",options:[{value:"development",label:"Development",hint:"Local testing & simulators"},{value:"staging",label:"Ad Hoc / Staging",hint:"Internal distribution & device testing"},{value:"production",label:"Production / App Store",hint:"App Store & Play Store submission"}]});j(c)&&(Y("Operation cancelled"),process.exit(0)),i=c,r=c==="production"?"store":c==="staging"?"adhoc":"development"}let o=`./${A.configFileName}`;if(!O.existsSync(o)){m.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let s=JSON.parse(O.readFileSync(o,"utf-8")),{projectId:a}=s;if(!a){m.error(`${A.configFileName} is missing projectId.`);return}if(e.awsProfile&&m.warn(g.yellow(`Ignoring --aws-profile. Authenticating with ${A.name} Cloud...`)),m.info(g.dim(`Setting up credentials for: ${i}`)),n==="ios")await ea(a,i,e,s,r);else{let c=_s(s,i);await la(a,i,c,e,s)}};async function ea(e,t,n,i,r){let o=n.bundleId;if(!o){let l=i.submit?.[t]?.ios?.bundleIdentifier||i.submit?.[t]?.ios?.bundleId||Ge(i,t),p=[];try{let u=(await Z.get(`/credentials/${e}`)).data.credentials||[];p=[...new Set(u.filter(h=>h.platform==="ios"&&h.bundleId&&h.bundleId!=="*").map(h=>h.bundleId))]}catch{}if(l&&!p.includes(l)&&p.unshift(l),p.length>0){let d=[...p.map(h=>({value:h,label:h,hint:h===l?"from config":void 0})),{value:"__new__",label:"+ Enter a new Bundle ID"}],u=await Ee({message:"Which Bundle ID are you setting up credentials for?",options:d});if(j(u)&&(Y("Operation cancelled"),process.exit(0)),u==="__new__"){let h=await ve({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:f=>f.includes(".")?void 0:"Please enter a valid Bundle ID"});j(h)&&(Y("Operation cancelled"),process.exit(0)),o=h}else o=u}else{let d=await ve({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:u=>u.includes(".")?void 0:"Please enter a valid Bundle ID"});j(d)&&(Y("Operation cancelled"),process.exit(0)),o=d}}m.info(g.dim(`Bundle ID: ${o}`));let s=Rn({buildProfile:t,profile:nt(i,t)||{},requestedCredentialType:r});m.info(g.dim(`Credential storage type: ${s}`));let a=i.submit?.production?.ios?.appleId;a&&m.info(g.dim(`Using Apple ID from config: ${a}`)),await ca(e,o,t,s,s==="store"?"appstore":s==="adhoc"?"adhoc":"development",n,i,a)}var Yi=e=>re(e.expiresAt)||re(e.expires)||re(e.expirationDate)||re(e.meta?.expiresAt)||re(e.meta?.expires),ta=e=>{let t=e.credential,n=An(t)||"all apps",i=Cn(t)||"distribution",r=Yi(t);return[e.projectName,i,n,r?`expires ${r}`:void 0].filter(Boolean).join(" \xB7 ")};async function na(e){let n=(await Z.get("/projects")).data.projects||[],i=(await Promise.all(n.map(async o=>{if(!o.projectId)return[];try{return((await Z.get(`/credentials/${o.projectId}`)).data.credentials||[]).filter(c=>Fi(c,e)).map(c=>({projectId:o.projectId,projectName:o.name||o.slug||o.projectId,credential:c,certificateId:$i(c),teamId:e}))}catch{return[]}}))).flat(),r=new Map;for(let o of i){let s=`${o.projectId}:${o.certificateId||Bt(o.credential)}`,a=r.get(s);(!a||String(o.credential.createdAt||"")>String(a.credential.createdAt||""))&&r.set(s,o)}return[...r.values()]}var zi=e=>String(e||"").replace(/[^a-zA-Z0-9]/g,"").toUpperCase(),ia=(e,t)=>{let n=s=>pe("openssl",["pkcs12","-in",e,"-clcerts","-nokeys","-passin",`pass:${t}`,...s?["-legacy"]:[]],{encoding:"utf-8"}),i=n(!0);if((i.error||i.status!==0)&&(i=n(!1)),i.error||i.status!==0||!i.stdout)return;let o=(pe("openssl",["x509","-noout","-serial"],{input:i.stdout,encoding:"utf-8"}).stdout||"").match(/serial=([A-Fa-f0-9:]+)/);return o?zi(o[1]):void 0};async function ra(e,t,n,i,r,o){if(e.certificateId)return e.certificateId;let s=await Vt(r,i,o);if(s.length===0)throw new Error("No active Apple Distribution certificates were returned by the Apple Developer Portal.");let a=ia(t,n),c=a?s.filter(p=>zi(p.serial)===a):[];if(c.length===1)return m.info(g.dim(`Matched the selected saved P12 to Apple certificate ${c[0].name||c[0].id}.`)),c[0].id;m.warn(g.yellow("This saved certificate was created by an older Mach version without its Apple Portal ID. Select its matching active certificate below."));let l=await Ee({message:"Which Apple Distribution certificate matches the selected saved P12?",options:[...s.map(p=>({value:p.id,label:[p.name||"Apple Distribution certificate",p.expires].filter(Boolean).join(" \xB7 "),hint:p.serial?`serial ${p.serial}`:void 0})),{value:"cancel",label:"Cancel"}]});if(!(j(l)||l==="cancel"))return l}async function oa(e,t,n){let i="";for(let o=1;o<=5;o++)try{let s=await Z.get(`/credentials/${t}/download`,{params:{projectId:e,format:"proxy"},responseType:"arraybuffer"});O.writeFileSync(n,Buffer.from(s.data));return}catch(s){if(i=s?.response?.data?.message||s?.message||String(s),!qi(i)||o>=5)break;let c=Math.min(15e3,1e3*Math.pow(2,o-1));m.warn(g.yellow(`Certificate download was interrupted (${i}). Retrying with a fresh secure link in ${Math.round(c/1e3)}s\u2026 (${o}/5)`)),await Qi(c)}throw new Error(`Could not download the saved Mach certificate after 5 attempts: ${i||"Unknown network error"}`)}async function sa({targetProjectId:e,targetBundleId:t,targetDistributionType:n,matchType:i,candidate:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:c,teamMeta:l}){let p=await Li(r.projectId,"ios",r.credential),d=Xi(p,{})||void 0,u=O.mkdtempSync(X.join(et.tmpdir(),`${A.nameLower}-reuse-cert-`)),h=X.join(u,"selected-distribution-certificate.p12"),f=`${A.nameLower} ${i} ${t}`,v=`${A.nameLower}-${i}-${Date.now()}.mobileprovision`;try{m.info(g.dim(`Downloading the selected certificate from ${r.projectName}\u2026`));let b=Bt(p);if(!b)throw new Error("The selected Mach certificate no longer has a credential ID.");await oa(r.projectId,b,h),m.info(g.dim("Importing the selected certificate into Mach\u2019s team keychain\u2026"));let x=U=>pe("security",["import",h,"-k",a,"-P",U,"-T","/usr/bin/codesign"],{encoding:"utf-8"}),N,I=await _i({storedPassword:d,tryPassword:U=>(U===""&&d&&m.warn(g.dim("Saved P12 did not unlock with its stored password; trying the legacy empty-password format\u2026")),N=x(U),!N.error&&N.status===0),requestPassword:async()=>{m.warn(g.yellow("This saved P12 is password protected, but Mach does not have its password."));let U=await ut({message:`P12 password for ${r.projectName}'s saved certificate:`,validate:k=>k.length>0?void 0:"The certificate password is required"});return j(U)?void 0:U}});if(I.status==="cancelled")return!1;if(I.status==="failed")throw new Error(mt(N?.stdout,N?.stderr)||"Could not import the selected .p12 certificate. Check its password.");let R=I.password,$=pe("security",["set-key-partition-list","-S","apple-tool:,apple:,codesign:","-s","-k",c,a],{encoding:"utf-8"});if($.error||$.status!==0)throw new Error(mt($.stdout,$.stderr)||"Could not grant codesign access to the imported certificate.");let G=await ra(r,h,R,i,s,o.shellCommand);if(!G)return!1;m.info(g.blue(`Creating a new ${i==="adhoc"?"Ad Hoc":"App Store"} profile for ${t}\u2026`));let V=pe(o.command,Ti(i,t,f,G,u,v),{cwd:process.cwd(),env:s,stdio:"inherit"});if(V.error||V.status!==0)throw new Error("Apple could not create the provisioning profile with the selected certificate.");let D=Dt(u,/\.mobileprovision$/);if(!D)throw new Error("The new provisioning profile was not produced by fastlane.");let F=Yi(p);return await Ke(e,h,"ios_cert",t,n,void 0,F,l.teamId,G,R,void 0,void 0,l.teamId,l.teamName,l.developerTeamId||l.teamId,l.appStoreConnectTeamId,l.providerId,l.providerName),await Ke(e,D,"ios_profile",t,n,void 0,void 0,l.teamId,void 0,void 0,void 0,void 0,l.teamId,l.teamName,l.developerTeamId||l.teamId,l.appStoreConnectTeamId,l.providerId,l.providerName),m.success(g.green(`\u2713 Reused the saved certificate and created credentials for ${t}.`)),!0}finally{try{O.rmSync(u,{recursive:!0,force:!0})}catch{}}}async function aa(e){let t="MATCH_ENCRYPTION_PASSPHRASE";try{let s=((await Z.get(`/projects/${e}/secrets/export?env=development`)).data.secrets||{})[t];if(s&&!s.includes("[Decryption Failed]"))return m.info(g.dim("Using existing encryption passphrase from Dashboard")),s;if(s&&s.includes("[Decryption Failed]")){m.warn(g.yellow("\u26A0\uFE0F Existing MATCH_PASSWORD could not be decrypted (encryption key changed).")),m.info(g.dim("Generating a fresh passphrase and cleaning old certificates..."));let a=Ot.randomBytes(32).toString("base64");try{await Z.post(`/projects/${e}/secrets`,{key:t,value:a,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 New encryption passphrase generated and saved"))}catch{}try{await Z.post("/credentials/clean-match-storage",{projectId:e}),m.success(g.green("\u2713 Cleaned old certificates from storage"))}catch{}return a}}catch(r){m.info(g.dim(`Could not fetch existing passphrase from Dashboard: ${r.message}`))}let n=await Ee({message:"No active encryption passphrase found on Dashboard. What would you like to do?",options:[{value:"generate",label:"Generate a new secure passphrase",hint:"Safe for first-time setup"},{value:"enter",label:"Enter existing passphrase manually",hint:"Required if you already have certs in S3"},{value:"cancel",label:"Cancel",hint:"Quit"}]});if((j(n)||n==="cancel")&&(Y("Operation cancelled"),process.exit(0)),n==="enter"){let r=await ut({message:"Enter your MATCH_PASSWORD (encryption passphrase):",validate:s=>s.length>0?void 0:"Passphrase is required"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=r;try{await Z.post(`/projects/${e}/secrets`,{key:t,value:o,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)"}),m.success(g.green("\u2713 Saved passphrase to Dashboard"))}catch{}return o}let i=Ot.randomBytes(32).toString("base64");try{await Z.post(`/projects/${e}/secrets`,{key:t,value:i,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 Generated and saved encryption passphrase to Dashboard"))}catch(r){m.warn(g.yellow(`Could not save passphrase to Dashboard: ${r.message}`))}return i}async function ca(e,t,n,i,r,o,s,a){let c=Je(),l=!1,p=b=>{c.start(b),l=!0},d=b=>{l&&(c.stop(b),l=!1)};m.info(g.blue("Configuring iOS certificate management..."));let u,h,f=ht(s,n),v=f;if(!a){let b=await ve({message:"Apple ID (for Apple Developer Portal):",placeholder:"your-email@example.com",validate:x=>x.includes("@")?void 0:"Please enter a valid email"});j(b)&&(Y("Operation cancelled"),process.exit(0)),a=b}try{let b=await aa(e),x="",N="";try{let k=await Z.post("/credentials/build-server-token",{projectId:e});k.data.status==="success"&&k.data.credentials&&(process.env.AWS_ACCESS_KEY_ID=k.data.credentials.accessKeyId,process.env.AWS_SECRET_ACCESS_KEY=k.data.credentials.secretAccessKey,k.data.credentials.sessionToken&&(process.env.AWS_SESSION_TOKEN=k.data.credentials.sessionToken),N=k.data.credentials.region||"ap-south-1",x=k.data.credentials.bucket||A.bucketPrefix,process.env.AWS_REGION=N,delete process.env.AWS_PROFILE)}catch(k){throw m.error(`Failed to authenticate with ${A.name} Cloud.`),k}if(!x||!N){m.error(`Failed to resolve S3 configuration from ${A.name} Cloud.`);return}let I=o.teamId||f.teamId||s.submit?.production?.ios?.appleTeamId;if(!I)try{let T=(await Z.get(`/projects/${e}/secrets`)).data.secrets?.find(H=>H.key==="APPLE_TEAM_ID");T&&(I=T.value,m.info(g.dim(`Using Team ID from Dashboard: ${I}`)))}catch{}I&&I===s.submit?.production?.ios?.appleTeamId&&m.info(g.dim(`Using Apple Team ID from config: ${I}`));let R=await yt({appleId:a,config:s,profile:n,initialTeam:{...f,teamId:I,developerTeamId:f.developerTeamId||I},promptToPersistConfig:!I,saveTeamId:I?void 0:k=>Zi(e,k)});if(!R?.teamId)return;I=R.teamId;let $={...f,...R,teamId:I,developerTeamId:R.developerTeamId||f.developerTeamId||I};v=$;let G=ys(e,I);m.info(g.dim(`Using match storage prefix: ${G}`));let V=await Ns(),D={...V.env};process.env.CI||delete D.CI,p(`Preparing ${r} certificate sync...`),d("Starting certificate sync...");let F=`${A.buildPrefix}-${I}-${r}.keychain-db`,U=A.keychainPassword;try{let T=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${F}`;m.info(g.dim(`Ensuring keychain exists: ${F}`));try{_e(`security create-keychain -p ${U} ${F} 2>/dev/null || true`),_e(`security unlock-keychain -p ${U} ${F}`),_e(`security set-keychain-settings ${F}`);let _=_e("security list-keychains -d user").toString();if(!_.includes(F)){m.info(g.dim(`Adding ${F} to search list`));let M=[..._.replace(/"/g,"").split(`
403
+ `).map(E=>E.trim()).filter(E=>E.length>0),T].join(" ");_e(`security list-keychains -d user -s ${M}`)}}catch(_){m.warn(g.dim("Keychain setup warning (non-critical): "+_.message))}let H,oe;try{let L=((await Z.get(`/credentials/${e}`)).data.credentials||[]).find(M=>M.type==="asc_api_key"&&M.issuerId);if(L){let M=await Z.get(`/credentials/${L.credentialId}/download`,{params:{projectId:e,format:"raw"}});if(M.data.downloadUrl){let P=await(await import("axios")).default.get(M.data.downloadUrl,{responseType:"arraybuffer"}),B=X.join(et.tmpdir(),`mach-asc-${Date.now()}`);O.mkdirSync(B,{recursive:!0}),u=X.join(B,`AuthKey_${L.keyId}.p8`),O.writeFileSync(u,Buffer.from(P.data)),H=L.keyId,oe=L.issuerId,m.success(g.green("\u2713 ASC API key loaded \u2014 no 2FA required for Portal operations"))}}}catch(_){m.warn(g.dim(`Could not load ASC API key: ${_.message}. Will fall back to Apple ID auth.`))}m.info(g.dim("Generating secure P12 export password..."));let me=er();m.success(g.green("\u2713 Secure P12 password generated.")),h=O.mkdtempSync(X.join(et.tmpdir(),`${A.nameLower}-match-${r}-`));let ae={...D,AWS_REGION:process.env.AWS_REGION||"ap-south-1",AWS_ACCESS_KEY_ID:process.env.AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY:process.env.AWS_SECRET_ACCESS_KEY,SSL_CERT_FILE:"/etc/ssl/cert.pem",AWS_CA_BUNDLE:"/etc/ssl/cert.pem",FASTLANE_SSL_CA_CERT:"/etc/ssl/cert.pem",MATCH_PASSWORD:b,FASTLANE_USER:a,FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_TEAM_ID:I,MATCH_KEYCHAIN_NAME:T,MATCH_KEYCHAIN_PASSWORD:U,TERM:process.env.TERM||"xterm-256color",SHELL:process.env.SHELL||"/bin/zsh",MATCH_OUTPUT_PATH:h,MATCH_STORAGE_MODE:"s3",MATCH_S3_REGION:N,MATCH_S3_BUCKET:x,MATCH_S3_OBJECT_PREFIX:G,MATCH_USERNAME:a,MATCH_APP_IDENTIFIER:t,MATCH_TYPE:r,[`${A.envPrefix}P12_PASSWORD`]:me,...u&&H&&oe?{APP_STORE_CONNECT_API_KEY_KEY_ID:H,APP_STORE_CONNECT_API_KEY_ISSUER_ID:oe,APP_STORE_CONNECT_API_KEY_KEY_FILEPATH:u,FASTLANE_SKIP_2FA:"1"}:{}};if(o.force){m.warn(g.yellow(`
404
+ \u26A0\uFE0F Force flag detected: Hard resetting ${r} certificates...`)),m.info(g.dim("Detected decryption failure loop. Clearing remote storage directly to allow fresh generation.")),m.info(g.dim(`Cleaning match storage for Team ID: ${I}...`));try{(await Z.post("/credentials/clean-match-storage",{projectId:e,teamId:I,storagePrefix:G})).data.status==="success"&&m.success(g.green(`\u2713 Cleared S3 storage for Team ID: ${I}`))}catch(_){m.warn(g.yellow(`S3 cleanup via API failed: ${_.message}`)),m.info(g.dim("Continuing to attempt standard nuke..."))}try{_e(`${V.shellCommand} match nuke ${r} --skip_confirmation`,{stdio:"inherit",cwd:process.cwd(),env:ae}),m.success(g.green(`\u2713 Nuked existing ${r} credentials`))}catch{m.warn(g.yellow("Standard nuke failed (likely due to password mismatch).")),m.info(g.dim("Since S3 was cleared manually, proceeding to generation..."))}}let ee=r==="adhoc"||r==="development";if(r==="adhoc"||r==="development")try{m.info(g.blue("Fetching registered devices..."));let L=(await Z.get("/devices",I?{params:{teamId:I}}:void 0)).data.devices||[];if(I)try{let M=await Z.get("/devices",{params:{teamId:"LEGACY"}}),E=new Map;for(let P of[...L,...M.data.devices||[]])E.set(P.udid,P);L=Array.from(E.values())}catch{}if(L.length===0)m.warn(g.yellow("No registered devices found. Profile will only include devices already on the Apple Developer Portal.")),m.info(g.dim(`Register devices with: ${A.nameLower} device register`));else{let{multiselect:M}=await import("@clack/prompts"),E=await M({message:`Select devices to include in the ${r} profile:`,options:L.map(P=>({value:P.udid,label:`${P.name} (${P.udid.substring(0,12)}...)`,hint:P.model||P.platform})),initialValues:L.map(P=>P.udid)});if(!j(E)&&E.length>0){let P=L.filter(B=>E.includes(B.udid));if(m.info(g.blue(`Registering ${P.length} device(s) on Apple Developer Portal...`)),I&&await Promise.all(P.filter(B=>!B.teamId).map(B=>Z.post("/devices",{udid:B.udid,name:B.name,platform:"ios",addedVia:B.addedVia||"cli",teamId:I,teamName:$.teamName}).catch(()=>{}))),u&&H&&oe)await zs(P,H,oe,u);else{m.info(g.dim("You will be prompted for a 2FA code once \u2014 type it and press Enter."));for(let B of P){let W=B.name.replace(/"/g,'\\"');pe(`${V.shellCommand} run register_device name:"${W}" udid:"${B.udid}"`,{shell:!0,env:ae,stdio:"inherit",cwd:process.cwd()})}}m.info(g.green("\u2713 Device registration complete.")),ee=!0}}}catch(_){m.warn(g.yellow(`Could not fetch registered devices: ${_.message}`)),m.info(g.dim("Continuing without explicit device registration."))}try{let _=`${A.nameLower} ${r} ${t}`,L=Cs(V.shellCommand,r,t,_,ee);ee&&m.info(g.dim(`Refreshing ${r} provisioning profile when device list changes (--force_for_new_devices).`));let M=pe(L,{shell:!0,cwd:process.cwd(),env:ae,stdio:"inherit",encoding:"utf-8"});if(M.status!==0){m.warn(g.yellow(`
405
+ Certificate sync failed. Attempting to create App ID and retry...`));try{_e(`${V.shellCommand} produce --app_identifier "${t}" --app_name "${t}" --skip_itc`,{stdio:"inherit",env:ae}),m.success(g.green("\u2713 App ID created successfully")),m.info(g.blue("Retrying certificate sync...")),M=pe(L,{shell:!0,cwd:process.cwd(),env:ae,stdio:"inherit",encoding:"utf-8"})}catch{}if(M.status!==0)throw new Error("fastlane match failed")}}catch(_){m.warn(g.yellow(`
406
+ Certificate sync failed. This can be caused by an incorrect encryption passphrase, an expired Apple session, or Apple\u2019s Distribution certificate limit.`));let L=[];if(r==="adhoc"||r==="appstore")try{L=await na(I)}catch{}let M=await Ee({message:"What would you like to do?",options:[...L.length>0?[{value:"reuse_saved",label:"Reuse a saved Mach certificate",hint:`${L.length} compatible certificate${L.length===1?"":"s"} found \u2014 no certificate is revoked`}]:[],{value:"retry_password",label:"Retry with a different MATCH_PASSWORD",hint:"Manually enter the decryption passphrase"},{value:"check_portal",label:"Check Apple Portal",hint:"Inspect certificate limits or explicitly revoke an old certificate"},{value:"manual",label:"Fallback to manual upload",hint:"Provide .p12 and .mobileprovision files"},{value:"cancel",label:"Cancel",hint:"Go back"}]});if(j(M)||M==="cancel")throw _;if(M==="reuse_saved"){let E=await Ee({message:"Select a saved Apple Distribution certificate to reuse:",options:[...L.map((W,z)=>({value:String(z),label:ta(W),hint:W.certificateId?`Apple Team ${W.teamId}`:`Apple Team ${W.teamId} \xB7 legacy record; Apple certificate matching may be requested`})),{value:"cancel",label:"Cancel"}]});if(j(E)||E==="cancel")throw _;let P=L[Number(E)];if(!P)throw new Error("The selected saved certificate is no longer available.");if(await sa({targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:r,candidate:P,fastlane:V,matchEnv:ae,keychainPath:T,keychainPassword:U,teamMeta:$}))return;throw _}else if(M==="retry_password"){m.info(g.dim(`
407
+ You are overriding the dashboard passphrase for this session.`));let E=await ut({message:"Enter the correct MATCH_PASSWORD for this project:"});if(E&&!j(E)){b=E,m.info(g.blue("Retrying with provided passphrase..."));let P={...ae,MATCH_PASSWORD:b};if(pe(`${V.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:P}).status===0)await Z.post(`/projects/${e}/secrets`,{key:"MATCH_ENCRYPTION_PASSPHRASE",value:b,description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),m.success(g.green("\u2713 Dashboard passphrase updated."));else throw new Error("Sync failed again with provided passphrase.")}else throw _}else if(M==="check_portal")try{let E=await Vt(ae,r,V.shellCommand);if(E.length>0){if(m.info(g.dim(`Found ${E.length} existing ${r} certificates on the portal.`)),await ua(r,ae,e,V.shellCommand,E)&&(m.info(g.blue("Retrying certificate sync...")),pe(`${V.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:ae}).status!==0))throw new Error("Retry failed")}else throw m.error(g.red("No existing certificates found on portal to resolve.")),_}catch(E){throw m.warn(g.dim(`Portal check warning: ${E.message}`)),_}else throw _}m.success(g.green("\u2713 Certificates fetched and synced"));let ce=h,se=X.join(ce,`${A.fastlanePrefix}_export.p12`),Ce=Dt(ce,/\.mobileprovision$/);try{let L=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${F}`;O.existsSync(ce)||O.mkdirSync(ce,{recursive:!0}),m.info(g.dim("Exporting certificate from keychain for dashboard upload..."));let M=_e(`security find-identity -v -p codesigning "${L}"`,{encoding:"utf-8"});m.info(g.dim(`Identities in keychain:
408
+ ${M.trim()}`));let E=pe("security",["export","-k",L,"-t","identities","-f","pkcs12","-o",se,"-P",me],{encoding:"utf-8"});if(E.error||E.status!==0)throw new Error(mt(E.stdout,E.stderr)||"security could not export the signing certificate.");try{let P=pe("openssl",["pkcs12","-in",se,"-nokeys","-passin",`pass:${me}`,"-legacy"],{encoding:"utf-8"});if((P.error||P.status!==0)&&(P=pe("openssl",["pkcs12","-in",se,"-nokeys","-passin",`pass:${me}`],{encoding:"utf-8"})),P.error||P.status!==0)throw new Error(mt(P.stdout,P.stderr)||"openssl could not read the exported P12.");let B=P.stdout||"";if(!B.includes(I))throw new Error(`Exported P12 does not contain identity for team ${I}. Found: ${B.substring(0,200)}`);m.success(g.green(`\u2713 P12 verified \u2014 contains correct team identity (${I})`))}catch(P){throw new Error(`P12 verification failed: ${P.message}`)}}catch{m.warn(g.dim("Could not export certificate from keychain."))}o.teamId&&!I&&await Zi(e,o.teamId);let De=O.existsSync(se)?se:Dt(ce,/\.p12$/);if(De&&Ce){let _,L;try{let M=await Vt(ae,r,V.shellCommand);M.length>0&&(_=M[0].expires,L=M[0].id)}catch{m.warn(g.dim("Could not fetch expiration date or ID for dashboard record."))}await Ke(e,De,"ios_cert",t,i,void 0,_,o.teamId||I,L,me,void 0,void 0,$.teamId,$.teamName,$.developerTeamId,$.appStoreConnectTeamId,$.providerId,$.providerName),await Ke(e,Ce,"ios_profile",t,i,void 0,_,o.teamId||I,void 0,void 0,void 0,void 0,$.teamId,$.teamName,$.developerTeamId,$.appStoreConnectTeamId,$.providerId,$.providerName),m.success(g.green("\u2713 Both iOS certificate and provisioning profile uploaded successfully"))}else m.warn(g.yellow("Certificates generated but not found in expected location.")),m.info(g.dim("Falling back to manual upload...")),await Mi(e,t,i,v)}catch(k){d("Certificate fetch failed"),m.error(g.red(`Error: ${k.message}`)),m.info(g.dim("Falling back to manual upload...")),await Mi(e,t,i,v)}}catch(b){d("iOS setup failed"),m.error(g.red(`Error: ${b.message}`))}finally{if(u)try{O.rmSync(X.dirname(u),{recursive:!0,force:!0})}catch{}if(h)try{O.rmSync(h,{recursive:!0,force:!0})}catch{}}}async function Zi(e,t){try{await Z.post(`/projects/${e}/secrets`,{key:"APPLE_TEAM_ID",value:t,description:"Apple Developer Team ID (used for iOS signing)"}),m.success(g.green(`\u2713 Saved Team ID ${t} to Dashboard`))}catch(n){m.warn(g.yellow(`Could not save Team ID to Dashboard: ${n.message}`))}}async function Mi(e,t,n,i={}){m.info(g.yellow(`
409
+ Manual Upload Mode`)),m.info("Please provide your certificate and provisioning profile:");let r=await ve({message:"Path to .p12 certificate file:",validate:a=>O.existsSync(a)?void 0:"File not found"});j(r)&&(Y("Operation cancelled"),process.exit(0));let o=await ve({message:"Path to .mobileprovision file:",validate:a=>O.existsSync(a)?void 0:"File not found"});j(o)&&(Y("Operation cancelled"),process.exit(0));let s=Je();s.start(`Uploading to ${A.name} Dashboard...`);try{await Ke(e,r,"ios_cert",t,n,void 0,void 0,i.teamId,void 0,void 0,void 0,void 0,i.teamId,i.teamName,i.developerTeamId||i.teamId,i.appStoreConnectTeamId,i.providerId,i.providerName),await Ke(e,o,"ios_profile",t,n,void 0,void 0,i.teamId,void 0,void 0,void 0,void 0,i.teamId,i.teamName,i.developerTeamId||i.teamId,i.appStoreConnectTeamId,i.providerId,i.providerName),s.stop("Upload complete"),m.success(g.green("\u2713 iOS credentials uploaded successfully"))}catch(a){throw s.stop("Upload failed"),a}}async function la(e,t,n,i,r){let o=Je();m.step(g.blue("Android Credential Setup"));let s=i.bundleId;if(!s){let d=it(r,t),u=[];try{let f=(await Z.get(`/credentials/${e}`)).data.credentials||[];u=[...new Set(f.filter(v=>v.platform==="android"&&v.bundleId&&v.bundleId!=="*").map(v=>v.bundleId))]}catch{}if(d&&!u.includes(d)&&u.unshift(d),u.length>0){let h=[...u.map(v=>({value:v,label:v,hint:v===d?"from config":void 0})),{value:"__new__",label:"+ Enter a new Package Name"}],f=await Ee({message:"Which Package Name are you setting up credentials for?",options:h});if(j(f)&&(Y("Operation cancelled"),process.exit(0)),f==="__new__"){let v=await ve({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:b=>b.includes(".")?void 0:"Please enter a valid package name"});j(v)&&(Y("Operation cancelled"),process.exit(0)),s=v}else s=f}else{let h=await ve({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:f=>f.includes(".")?void 0:"Please enter a valid package name"});j(h)&&(Y("Operation cancelled"),process.exit(0)),s=h}}try{let h=((await Z.get(`/credentials/${e}`)).data.credentials||[]).find(f=>f.platform==="android"&&f.distributionType===n&&f.bundleId===s);if(h){m.warn(g.yellow(`\u26A0\uFE0F Existing Android credentials found for ${n}`));let f=await ve({message:"What would you like to do? (use/new/cancel)",validate:v=>{let b=v.toLowerCase();if(!(b==="use"||b==="new"||b==="cancel"))return"Please type: use, new, or cancel"}});if(j(f)||f.toLowerCase()==="cancel")return;if(f.toLowerCase()==="use"){m.success(g.green("\u2713 Using existing credentials."));return}await Z.delete(`/credentials/${h.credentialId}?projectId=${e}`)}}catch{}let a="./android/app/my-release-key.jks";if(O.existsSync(a)){let d=await bn({message:"Upload existing keystore?"});if(d&&!j(d)){let u=await ve({message:"Key alias:",initialValue:"my-key-alias"});if(j(u))return;let h=await ut({message:"Keystore password:"});if(j(h))return;let f=await ut({message:"Key password (leave blank if same as keystore password):"});if(j(f))return;let v=f.trim()||h;await Ke(e,a,"android_keystore",s,n,u,void 0,void 0,void 0,void 0,h,v),m.success(g.green("\u2713 Keystore uploaded"));return}}m.info(g.blue("Generating new Android keystore..."));let c=i.keyAlias||`${A.nameLower}-${pa()}`,l=er(),p=`./${A.nameLower}-${t}.jks`;O.existsSync(p)&&O.unlinkSync(p),o.start("Generating keystore...");try{let d=l.replace(/'/g,"'\\''");_e(`keytool -genkeypair -v -keystore "${p}" -alias "${c}" -keyalg RSA -keysize 2048 -validity 10000 -storepass '${d}' -keypass '${d}' -dname "CN=${A.name} Build, OU=Mobile, O=Company, L=City, S=State, C=US"`,{stdio:"inherit"}),o.stop("Keystore generated"),await Ke(e,p,"android_keystore",s,n,c,void 0,void 0,void 0,void 0,l,l),m.success(g.green("\u2713 Android credentials uploaded successfully")),m.info(g.cyan(`Key Alias: ${c}`))}catch(d){throw o.stop("Generation failed"),new Error(`Keystore generation failed: ${d.message}`)}}var Qi=e=>new Promise(t=>setTimeout(t,e));function qi(e){return/ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNABORTED|socket hang up|network|timeout|temporar/i.test(e)||/API_ERROR:\s*(408|409|425|429|5\d\d)/i.test(e)}async function Ke(e,t,n,i,r,o,s,a,c,l,p,d,u,h,f,v,b,x){let N=X.basename(t);m.info(g.dim(`Uploading ${N} (Isolated process)...`));let I=new URL(import.meta.url),R=X.dirname(I.pathname),G=[X.join(R,"commands","isolated-upload.js"),e,t,n,i,r,o||"undefined",s||"undefined",a||"undefined",c||"undefined",l||"undefined",p||"undefined",d||"undefined",u||"undefined",h||"undefined",f||"undefined",v||"undefined",b||"undefined",x||"undefined"],V="",D=5;for(let F=1;F<=D;F++){let U=pe("node",G,{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(U.status===0&&U.stdout.includes("SUCCESS")){m.info(g.dim(`\u2713 ${N} uploaded and registered.`));return}if(U.status===0){m.warn(g.yellow(`Isolated upload finished but success not confirmed: ${U.stdout}`));return}if(V=(U.stderr||U.stdout||U.error?.message||"Unknown isolated upload failure").trim(),!qi(V)||F>=D)throw m.error(g.red(`Isolated Upload Failed: ${V}`)),new Error(V);let T=Math.min(3e4,1500*Math.pow(2,F-1));m.warn(g.yellow(`Upload failed with a transient error. Retrying ${N} in ${Math.round(T/1e3)}s... (${F}/${D})`)),await Qi(T)}throw new Error(V||"Unknown isolated upload failure")}async function da(e){let t=Je(),n=e.platform,i=`./${A.configFileName}`;if(!O.existsSync(i)){m.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(O.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){m.error(`${A.configFileName} is missing projectId.`);return}try{t.start("Fetching project secrets...");let a=(await Z.get(`/projects/${o}/secrets/export?env=all`)).data.secrets||{};t.stop("Secrets fetched and merged."),t.start("Fetching credentials...");let l=(await Z.get(`/credentials/${o}`)).data.credentials||[];t.stop(`Found ${l.length} metadata records.`);let p=l.filter(f=>f.platform===n);if(p.length===0){m.info(`No ${n} credentials found on Dashboard.`);return}let d="./credentials.json",u={};if(O.existsSync(d))try{u=JSON.parse(O.readFileSync(d,"utf-8"))}catch{m.warn("Could not parse existing credentials.json, creating a new one.")}u[n]||(u[n]={});let h=X.join(process.cwd(),"credentials",n);O.existsSync(h)||O.mkdirSync(h,{recursive:!0});for(let f of p){t.start(`Downloading ${f.type} (${f.distributionType})...`);try{let v=await Z.get(`/credentials/${f.credentialId}/download`,{params:{projectId:o,format:"raw"}});if(v.data.status==="success"&&v.data.downloadUrl){let b=X.join(process.cwd(),"credentials",n,f.distributionType);O.existsSync(b)||O.mkdirSync(b,{recursive:!0});let x=f.s3Key?.split(".").pop()||(f.type.includes("keystore")?"jks":f.type.includes("cert")?"p12":"mobileprovision"),N=`${f.type}.${x}`,I=X.join(b,N),R=await ji.get(v.data.downloadUrl,{responseType:"arraybuffer"});O.writeFileSync(I,Buffer.from(R.data));let $=X.join("credentials",n,f.distributionType,N),G="",V="",D={alias:"",keystorePassword:"",keyPassword:""};if(n==="ios"&&f.type==="ios_cert"||n==="android"&&f.type==="android_keystore"){let F=await Li(o,n,f);if(n==="ios"&&f.type==="ios_cert"&&x.toLowerCase()==="p12"){if(G=Xi(F,a),G){let U=Bi(I,`${X.basename(I,X.extname(I))}-password.txt`,G);V=X.join("credentials",n,f.distributionType,X.basename(U))}}else if(n==="android"&&f.type==="android_keystore"&&(D=xs(F,a),D.keystorePassword||D.keyPassword)){let U=[D.alias?`keyAlias=${D.alias}`:void 0,D.keystorePassword?`keystorePassword=${D.keystorePassword}`:void 0,D.keyPassword?`keyPassword=${D.keyPassword}`:void 0].filter(Boolean).join(`
410
+ `),k=Bi(I,`${X.basename(I,X.extname(I))}-passwords.txt`,U);V=X.join("credentials",n,f.distributionType,X.basename(k))}}if(n==="android")f.type==="android_keystore"&&(u.android.keystore={keystorePath:$,keystorePassword:D.keystorePassword,keyAlias:D.alias,keyPassword:D.keyPassword},V&&(u.android.keystore.keystoreArchivePath=V));else if(n==="ios"){let F=f.distributionType==="store"?"production":f.distributionType==="adhoc"?"staging":"development";u.ios[F]||(u.ios[F]={}),f.type==="ios_cert"?(u.ios[F].certificatePath=$,u.ios[F].certificatePassword=G,V&&(u.ios[F].certificateArchivePath=V)):f.type==="ios_profile"&&(u.ios[F].provisioningProfilePath=$)}t.stop(`\u2713 ${f.type} (${f.distributionType}) saved${V?" with password archive":""}.`)}}catch(v){let b=v.response?.data?.message||v.message;t.stop(g.dim(`- Skipped ${f.type} (${f.distributionType}): ${b}`))}}O.writeFileSync(d,JSON.stringify(u,null,2)),m.success(g.green("\u2713 Local credentials.json updated.")),fs("Credentials have been synced to your local machine. Ensure credentials.json and credentials/ is added to your .gitignore.","Sync Complete")}catch(s){t.stop(g.red("Sync failed.")),m.error(`Error: ${s.message}`)}}function er(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_+=",t="";for(let n=0;n<24;n++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}function pa(e=8){let t="abcdefghijklmnopqrstuvwxyz0123456789",n="";for(let i=0;i<e;i++)n+=t.charAt(Math.floor(Math.random()*t.length));return n}async function ua(e,t,n,i,r){let o=r||await Vt(t,e,i);if(!o||o.length===0)return!1;let s=await Ee({message:"Select a certificate to revoke:",options:[...o.map(a=>({value:`revoke:${a.id}`,label:`Revoke: ${a.name} (${a.expires})`})),{value:"nuke",label:"Revoke All"},{value:"cancel",label:"Cancel"}]});return j(s)||s==="cancel"?!1:s==="nuke"?(_e(`${i} match nuke ${e}`,{stdio:"inherit",cwd:process.cwd(),env:t}),!0):typeof s=="string"&&s.startsWith("revoke:")?(await fa(t,s.split(":")[1],i),!0):!1}async function Vt(e,t,n){let i=t==="development"?"development":"distribution",r=`
411
411
  lane :${A.fastlanePrefix}_list_certs do
412
412
  require 'spaceship'
413
413
  require 'json'
@@ -442,7 +442,7 @@ lane :${A.fastlanePrefix}_list_certs do
442
442
  $stderr.puts "ERROR: #{e.message}"
443
443
  exit 1
444
444
  end
445
- end`,o=L.join(et.tmpdir(),`/tmp/${A.nameLower}-list-certs-${Date.now()}`),s=L.join(o,"fastlane"),a=L.join(s,"Fastfile");try{O.existsSync(s)||O.mkdirSync(s,{recursive:!0}),O.writeFileSync(a,r);let l=_e(`${n} ${A.fastlanePrefix}_list_certs`,{env:{...e,CI:"1",FASTLANE_FASTFILE:a},cwd:o,stdio:["inherit","pipe","inherit"]}).toString().match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));return l?JSON.parse(l[1]):[]}finally{O.existsSync(o)&&O.rmSync(o,{recursive:!0,force:!0})}}async function ua(e,t,n){let i=`
445
+ end`,o=X.join(et.tmpdir(),`/tmp/${A.nameLower}-list-certs-${Date.now()}`),s=X.join(o,"fastlane"),a=X.join(s,"Fastfile");try{O.existsSync(s)||O.mkdirSync(s,{recursive:!0}),O.writeFileSync(a,r);let l=_e(`${n} ${A.fastlanePrefix}_list_certs`,{env:{...e,CI:"1",FASTLANE_FASTFILE:a},cwd:o,stdio:["inherit","pipe","inherit"]}).toString().match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));return l?JSON.parse(l[1]):[]}finally{O.existsSync(o)&&O.rmSync(o,{recursive:!0,force:!0})}}async function fa(e,t,n){let i=`
446
446
  lane :${A.fastlanePrefix}_revoke_cert do
447
447
  require 'spaceship'
448
448
  begin
@@ -454,4 +454,4 @@ lane :${A.fastlanePrefix}_revoke_cert do
454
454
  $stderr.puts "ERROR: #{e.message}"
455
455
  exit 1
456
456
  end
457
- end`,r=L.join(et.tmpdir(),`/tmp/${A.nameLower}-revoke-cert-${Date.now()}`),o=L.join(r,"fastlane"),s=L.join(o,"Fastfile");try{O.existsSync(o)||O.mkdirSync(o,{recursive:!0}),O.writeFileSync(s,i),_e(`${n} ${A.fastlanePrefix}_revoke_cert`,{env:{...e,CI:"1",FASTLANE_FASTFILE:s},cwd:r,stdio:["inherit","pipe","inherit"]})}finally{O.existsSync(r)&&O.rmSync(r,{recursive:!0,force:!0})}}export{tc as a,nc as b,ic as c,rc as d,Ln as e,oc as f,bt as g,rn as h,Xn as i,Hn as j,Cc as k,bc as l,wc as m,Sc as n,Vc as o,Wc as p,yo as q,ct as r,Zc as s,rl as t,pt as u,ya as v,rr as w,Lt as x,ht as y,$n as z,nt as A,it as B,Ge as C,Ia as D,Vn as E,fn as F,Al as G,Cl as H,Tt as I,bl as J,wl as K,zs as L,Qs as M,la as N};
457
+ end`,r=X.join(et.tmpdir(),`/tmp/${A.nameLower}-revoke-cert-${Date.now()}`),o=X.join(r,"fastlane"),s=X.join(o,"Fastfile");try{O.existsSync(o)||O.mkdirSync(o,{recursive:!0}),O.writeFileSync(s,i),_e(`${n} ${A.fastlanePrefix}_revoke_cert`,{env:{...e,CI:"1",FASTLANE_FASTFILE:s},cwd:r,stdio:["inherit","pipe","inherit"]})}finally{O.existsSync(r)&&O.rmSync(r,{recursive:!0,force:!0})}}export{nc as a,ic as b,rc as c,oc as d,Ln as e,sc as f,bt as g,rn as h,Xn as i,Hn as j,bc as k,wc as l,Sc as m,vc as n,Wc as o,Zc as p,Io as q,ct as r,Mc as s,ol as t,pt as u,Ia as v,or as w,Lt as x,ht as y,$n as z,nt as A,it as B,Ge as C,Aa as D,Vn as E,fn as F,Cl as G,bl as H,Tt as I,wl as J,Sl as K,Qs as L,qs as M,da as N};