@radhya/mach 2.6.1 → 2.6.2

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 U,i as Mt,k as kn}from"./chunk-QFXPWC5D.js";import{log as g,spinner as ct,text as Te,password as ht,select as be,confirm as Pi,isCancel as L,cancel as ee,intro as Sc,outro as wc,note as Cc}from"@clack/prompts";import{log as ie,spinner as wt,text as He,select as ft,isCancel as we,cancel as Oe,note as rn,confirm as Di}from"@clack/prompts";import fe from"chalk";import{spawnSync as jt}from"child_process";import Ie from"fs";import _e from"path";import Ln from"os";import qt from"fs";import{log as Mo}from"@clack/prompts";var Bo=["react-native","expo","flutter"],Nl="react-native",$i=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},_i=e=>$i(e)?.toUpperCase()||void 0,en=(...e)=>{for(let t of e){let n=$i(t);if(n)return n}};function Vo(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="react-native"||t==="react_native"||t==="reactnative")return"react-native";if(t==="expo")return"expo";if(t==="flutter")return"flutter"}function _n(e){let t=Vo(e?.framework);if(t)return t;let n=Bo.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 Bt(e,t=Ge(e,"store","production")){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=_i(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=en(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:en(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:_i(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:en(n.providerId,i.providerId,r.providerId,s),providerName:en(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function Ti(e){if(e){if(!qt.existsSync(e))return null;try{return JSON.parse(qt.readFileSync(e,"utf-8"))}catch{return null}}if(!qt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(qt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function Fe(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=Fe(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android},flutter:{...o.flutter,...i.flutter}})}if(r.envGroups&&Array.isArray(r.envGroups)){let o={};for(let s of r.envGroups){let a=e.envGroups?.[s];a?Object.assign(o,a):Mo.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function Ge(e,t="first",n="production"){let i=Object.keys(e?.build||{});return i.length===0?n:t==="first"?i[0]:i.find(o=>{let s=Fe(e,o)||{},a=String(s.distribution||"").trim().toLowerCase().replace(/_/g,"-"),l=String(s.environment||"").trim().toLowerCase().replace(/_/g,"-"),c=String(s.iosExportMethod||s.ios?.exportMethod||"").trim().toLowerCase().replace(/_/g,"-");return t==="development"?s.developmentClient===!0||s.simulator===!0||s.ios?.simulator===!0||s.flutter?.mode==="debug"||a==="development"||l==="development":a==="store"||c==="app-store"||l==="production"||l==="store"})||i[0]}function bt(e,t){let n=t?Fe(e,t)||{}:{};if(n.android?.package)return n.android.package;if(n.androidPackage)return n.androidPackage;if(e.android?.package)return e.android.package;if(e.expo?.android?.package)return e.expo.android.package}function nt(e,t){let n=t?Fe(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 kl=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],l=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${l}_`):n[l]=String(a)}};return i(e,t),n};import{cancel as Tn,confirm as jo,isCancel as Fn,log as dt,select as Lo,text as Uo}from"@clack/prompts";import ut from"chalk";import On from"fs";import{createRequire as Wo}from"module";import Go from"os";import tn from"path";var Zo=Wo(import.meta.url),$n=null;function Ho(){return $n||($n=Zo("@expo/apple-utils")),$n}function nn(e){if(!e)return!1;try{return On.readdirSync(tn.join(e,"gems"),{withFileTypes:!0}).some(t=>t.isDirectory()&&t.name.startsWith("fastlane-"))}catch{return!1}}function Xo(){let e=["/opt/homebrew/opt/fastlane/libexec","/usr/local/opt/fastlane/libexec"];for(let n of e)if(nn(n))return n;let t=["/opt/homebrew/Cellar/fastlane","/usr/local/Cellar/fastlane"];for(let n of t)try{let i=On.readdirSync(n,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,o)=>o.localeCompare(r,void 0,{numeric:!0}));for(let r of i){let o=tn.join(n,r,"libexec");if(nn(o))return o}}catch{}}function St(){let e=process.env.HOME||Go.homedir(),t=tn.join(e,".local/share/fastlane/3.4.0"),n=process.env.FASTLANE_GEM_HOME?.trim(),i=nn(n)?n:Xo()||(nn(t)?t:n||t);return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,tn.join(i,"bin"),"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin",process.env.PATH].filter(Boolean).join(":"),GEM_HOME:i,GEM_PATH:[i,process.env.GEM_PATH].filter(Boolean).join(":"),FASTLANE_INSTALLED_VIA_HOMEBREW:"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1",LANG:process.env.LANG||"en_US.UTF-8",LC_ALL:process.env.LC_ALL||"en_US.UTF-8",CI:"1"}}function Ko(e,t=Ge(e,"store","production")){return e.submit||(e.submit={}),e.submit[t]||(e.submit[t]={}),e.submit[t].ios||(e.submit[t].ios={}),e.submit[t].ios}function Jo(e,t,n=Ge(e,"store","production")){if(!e||!t.id)return;let i=Ko(e,n);i.appleTeamId=t.id;try{On.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function Yo(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 zo(e){try{let{Auth:t,Teams:n}=Ho(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let c of o||[]){let d=Yo(c);d&&s.set(d.id,d)}let a=Array.from(s.values()),l=r?a.find(c=>c.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:l}}catch(t){let n=t instanceof Error?t.message:String(t||"");return dt.warn(ut.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Fi(){dt.warn(ut.yellow(`
2
- Apple Team ID is required to fetch certificates.`)),dt.info(ut.dim("You can find this at: https://developer.apple.com/account -> Membership Details"));let e=await Uo({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 Fn(e)?(Tn("Operation cancelled"),null):{id:e.trim().toUpperCase()}}function Qo(e){let t=[e.id,e.type].filter(Boolean);return t.length>0?t.join(" \xB7 "):void 0}async function qo(e,t){if(!e.config)return!1;if(e.persistConfig)return!0;if(!e.promptToPersistConfig)return!1;let n=e.profile||Ge(e.config,"store","production"),i=await jo({message:`Save Apple Team ID ${t} to ${A.configFileName} for "${n}" profile?`,initialValue:!0});return Fn(i)?(Tn("Operation cancelled"),null):i}async function Vt(e){let t=e.initialTeam?.teamId?.trim().toUpperCase();if(t){let c=e.initialTeam?.developerTeamId?.trim().toUpperCase();return{...e.initialTeam,teamId:t,developerTeamId:c||t}}dt.info(ut.blue("Fetching Apple Developer teams..."));let{teams:n,selectedTeam:i}=await zo(e.appleId),r;if(i)r=i,dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length===1)r=n[0],dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length>1){let c=await Lo({message:"Select Apple Developer team:",options:[...n.map(d=>({value:d.id,label:d.name||d.id,hint:Qo(d)})),{value:"__manual__",label:"Enter Team ID manually",hint:"Use if your team is not listed"}]});if(Fn(c))return Tn("Operation cancelled"),null;r=c==="__manual__"?await Fi():n.find(d=>d.id===c)||{id:c}}else dt.warn(ut.yellow("Could not list Apple Developer teams automatically.")),r=await Fi();if(!r)return null;let o=r.id.trim().toUpperCase(),s=r.name?.trim(),a={...e.initialTeam,teamId:o,teamName:s||e.initialTeam?.teamName,developerTeamId:o},l=await qo(e,o);return l===null?null:(l&&Jo(e.config,{...r,id:o,name:s},e.profile),e.saveTeamId&&await e.saveTeamId(o,s),a)}var es="cmVxdWlyZSAnc3BhY2VzaGlwJwpyZXF1aXJlICdqc29uJwoKZGVmIHJlYWRfdGVhbV9maWVsZCh0ZWFtLCAqa2V5cykKICBrZXlzLmVhY2ggZG8gfGtleXwKICAgIGJlZ2luCiAgICAgIHZhbHVlID0gdGVhbVtrZXldIGlmIHRlYW0ucmVzcG9uZF90bz8oOltdKQogICAgICByZXR1cm4gdmFsdWUgaWYgdmFsdWUgJiYgdmFsdWUudG9fcy5sZW5ndGggPiAwCiAgICByZXNjdWUKICAgIGVuZAoKICAgIG1ldGhvZF9uYW1lID0ga2V5LnRvX3MKICAgIGlmIHRlYW0ucmVzcG9uZF90bz8obWV0aG9kX25hbWUpCiAgICAgIHZhbHVlID0gdGVhbS5wdWJsaWNfc2VuZChtZXRob2RfbmFtZSkKICAgICAgcmV0dXJuIHZhbHVlIGlmIHZhbHVlICYmIHZhbHVlLnRvX3MubGVuZ3RoID4gMAogICAgZW5kCiAgZW5kCgogIG5pbAplbmQKCmRlZiBub3JtYWxpemVfdGVhbV9uYW1lKG5hbWUpCiAgbmFtZS50b19zLmRvd25jYXNlLmdzdWIoL1teYS16MC05XSsvLCAnICcpLnN0cmlwCmVuZAoKZGVmIHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtX2lkID0gRU5WWydGQVNUTEFORV9URUFNX0lEJ10udG9fcwogIHRlYW1zID0gU3BhY2VzaGlwOjpQb3J0YWwuY2xpZW50LnRlYW1zCiAgdGVhbXMgPSB0ZWFtcy52YWx1ZXMgaWYgdGVhbXMuaXNfYT8oSGFzaCkKCiAgdGVhbSA9IEFycmF5KHRlYW1zKS5maW5kIGRvIHx0fAogICAgWwogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1JZCcsIDp0ZWFtSWQpLAogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1faWQnLCA6dGVhbV9pZCksCiAgICAgIHJlYWRfdGVhbV9maWVsZCh0LCAnaWQnLCA6aWQpCiAgICBdLmNvbXBhY3QubWFwKCY6dG9fcykuaW5jbHVkZT8odGVhbV9pZCkKICBlbmQKCiAgcmVhZF90ZWFtX2ZpZWxkKHRlYW0sICduYW1lJywgOm5hbWUsICd0ZWFtTmFtZScsIDp0ZWFtTmFtZSwgJ2Rpc3BsYXlOYW1lJywgOmRpc3BsYXlOYW1lKQpyZXNjdWUgPT4gZQogICRzdGRlcnIucHV0cyAiREVCVUc6IENvdWxkIG5vdCByZXNvbHZlIERldmVsb3BlciBQb3J0YWwgdGVhbSBuYW1lOiAje2UubWVzc2FnZX0iCiAgbmlsCmVuZAoKZGVmIHR1bmVzX3RlYW1faWQodGVhbSkKICByZWFkX3RlYW1fZmllbGQoCiAgICB0ZWFtLAogICAgJ3Byb3ZpZGVySWQnLCA6cHJvdmlkZXJJZCwKICAgICdwcm92aWRlcl9pZCcsIDpwcm92aWRlcl9pZCwKICAgICdjb250ZW50UHJvdmlkZXJJZCcsIDpjb250ZW50UHJvdmlkZXJJZCwKICAgICdjb250ZW50X3Byb3ZpZGVyX2lkJywgOmNvbnRlbnRfcHJvdmlkZXJfaWQsCiAgICAndGVhbUlkJywgOnRlYW1JZCwKICAgICd0ZWFtX2lkJywgOnRlYW1faWQsCiAgICAnaWQnLCA6aWQKICApLnRvX3MKZW5kCgpkZWYgdHVuZXNfdGVhbV9uYW1lKHRlYW0pCiAgcmVhZF90ZWFtX2ZpZWxkKAogICAgdGVhbSwKICAgICduYW1lJywgOm5hbWUsCiAgICAnY29udGVudFByb3ZpZGVyTmFtZScsIDpjb250ZW50UHJvdmlkZXJOYW1lLAogICAgJ2NvbnRlbnRfcHJvdmlkZXJfbmFtZScsIDpjb250ZW50X3Byb3ZpZGVyX25hbWUsCiAgICAndGVhbU5hbWUnLCA6dGVhbU5hbWUsCiAgICAnZGlzcGxheU5hbWUnLCA6ZGlzcGxheU5hbWUKICApLnRvX3MKZW5kCgpkZWYgYXZhaWxhYmxlX3R1bmVzX3RlYW1zCiAgdGVhbXMgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudC50ZWFtcwogIHRlYW1zID0gdGVhbXMudmFsdWVzIGlmIHRlYW1zLmlzX2E/KEhhc2gpCiAgQXJyYXkodGVhbXMpCnJlc2N1ZSA9PiBlCiAgJHN0ZGVyci5wdXRzICJERUJVRzogQ291bGQgbm90IGluc3BlY3QgQXBwIFN0b3JlIENvbm5lY3QgdGVhbXM6ICN7ZS5tZXNzYWdlfSIKICBbXQplbmQKCmRlZiBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogIGV4cGxpY2l0X3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX0lUQ19URUFNX0lEJ10gfHwgRU5WWydGQVNUTEFORV9BU0NfVEVBTV9JRCddCiAgaWYgZXhwbGljaXRfdGVhbV9pZCAmJiBleHBsaWNpdF90ZWFtX2lkLnRvX3MubGVuZ3RoID4gMAogICAgU3BhY2VzaGlwOjpUdW5lcy5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBleHBsaWNpdF90ZWFtX2lkKQogICAgcmV0dXJuIGV4cGxpY2l0X3RlYW1faWQKICBlbmQKCiAgZGV2ZWxvcGVyX3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXS50b19zCiAgZGV2ZWxvcGVyX3RlYW1fbmFtZSA9IHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtcyA9IGF2YWlsYWJsZV90dW5lc190ZWFtcwoKICBpZiBkZXZlbG9wZXJfdGVhbV9uYW1lICYmIGRldmVsb3Blcl90ZWFtX25hbWUubGVuZ3RoID4gMAogICAgbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZSA9IG5vcm1hbGl6ZV90ZWFtX25hbWUoZGV2ZWxvcGVyX3RlYW1fbmFtZSkKICAgIG1hdGNoZWRfdGVhbSA9IHRlYW1zLmZpbmQgeyB8dGVhbXwgbm9ybWFsaXplX3RlYW1fbmFtZSh0dW5lc190ZWFtX25hbWUodGVhbSkpID09IG5vcm1hbGl6ZWRfZGV2ZWxvcGVyX25hbWUgfQoKICAgIGlmIG1hdGNoZWRfdGVhbQogICAgICBtYXRjaGVkX2lkID0gdHVuZXNfdGVhbV9pZChtYXRjaGVkX3RlYW0pCiAgICAgIG1hdGNoZWRfbmFtZSA9IHR1bmVzX3RlYW1fbmFtZShtYXRjaGVkX3RlYW0pCiAgICAgIFNwYWNlc2hpcDo6VHVuZXMuc2VsZWN0X3RlYW0odGVhbV9pZDogbWF0Y2hlZF9pZCkKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogQXV0by1zZWxlY3RlZCBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7bWF0Y2hlZF9pZH0gKCN7bWF0Y2hlZF9uYW1lfSkgZm9yIERldmVsb3BlciBUZWFtICN7ZGV2ZWxvcGVyX3RlYW1faWR9IgogICAgICByZXR1cm4gbWF0Y2hlZF9pZAogICAgZW5kCiAgZW5kCgogIGlmIHRlYW1zLmxlbmd0aCA9PSAxCiAgICBvbmx5X3RlYW0gPSB0ZWFtcy5maXJzdAogICAgb25seV90ZWFtX2lkID0gdHVuZXNfdGVhbV9pZChvbmx5X3RlYW0pCiAgICBTcGFjZXNoaXA6OlR1bmVzLnNlbGVjdF90ZWFtKHRlYW1faWQ6IG9ubHlfdGVhbV9pZCkKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEF1dG8tc2VsZWN0ZWQgb25seSBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7b25seV90ZWFtX2lkfSAoI3t0dW5lc190ZWFtX25hbWUob25seV90ZWFtKX0pIgogICAgcmV0dXJuIG9ubHlfdGVhbV9pZAogIGVuZAoKICAkc3RkZXJyLnB1dHMgIkVSUk9SOiBDb3VsZCBub3QgbWFwIEFwcGxlIERldmVsb3BlciBUZWFtIElEICcje2RldmVsb3Blcl90ZWFtX2lkfScje2RldmVsb3Blcl90ZWFtX25hbWUgPyAiICgje2RldmVsb3Blcl90ZWFtX25hbWV9KSIgOiAnJ30gdG8gQXBwIFN0b3JlIENvbm5lY3QuIgogICRzdGRlcnIucHV0cyAiQXZhaWxhYmxlIEFwcCBTdG9yZSBDb25uZWN0IHRlYW1zOiIKICB0ZWFtcy5lYWNoIGRvIHx0ZWFtfAogICAgJHN0ZGVyci5wdXRzICItICN7dHVuZXNfdGVhbV9pZCh0ZWFtKX0gKCN7dHVuZXNfdGVhbV9uYW1lKHRlYW0pfSkiCiAgZW5kCiAgZXhpdCAxCmVuZAoKZGVmIGxpc3RfdGVhbXMKICBiZWdpbgogICAgU3BhY2VzaGlwOjpQb3J0YWwubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBTcGFjZXNoaXA6OlBvcnRhbC5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXSkKCiAgICBkZXZlbG9wZXJfdGVhbV9uYW1lID0gcG9ydGFsX3RlYW1fbmFtZQoKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lID0gbm9ybWFsaXplX3RlYW1fbmFtZShkZXZlbG9wZXJfdGVhbV9uYW1lKQogICAgdGVhbXMgPSBhdmFpbGFibGVfdHVuZXNfdGVhbXMubWFwIGRvIHx0ZWFtfAogICAgICB0ZWFtX25hbWUgPSB0dW5lc190ZWFtX25hbWUodGVhbSkKICAgICAgewogICAgICAgIGlkOiB0dW5lc190ZWFtX2lkKHRlYW0pLAogICAgICAgIG5hbWU6IHRlYW1fbmFtZSwKICAgICAgICByZWNvbW1lbmRlZDogbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZS5sZW5ndGggPiAwICYmIG5vcm1hbGl6ZV90ZWFtX25hbWUodGVhbV9uYW1lKSA9PSBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lCiAgICAgIH0KICAgIGVuZAoKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyB7CiAgICAgIGRldmVsb3BlclRlYW1JZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10sCiAgICAgIGRldmVsb3BlclRlYW1OYW1lOiBkZXZlbG9wZXJfdGVhbV9uYW1lLAogICAgICB0ZWFtczogdGVhbXMKICAgIH0udG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBleGl0IDEKICBlbmQKZW5kCgpkZWYgbGlzdF9rZXlzCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICAjIFVzZSBUdW5lcyBjbGllbnQgd2hpY2ggcG9pbnRzIHRvIGFwcHN0b3JlY29ubmVjdC5hcHBsZS5jb20KICAgIGNsaWVudCA9IFNwYWNlc2hpcDo6VHVuZXMuY2xpZW50CiAgICAjIFVzZSByb290LXJlbGF0aXZlIFVSTCB0byByZXBsYWNlIHRoZSBkZWZhdWx0IFR1bmVzIHBhdGggKC9XZWJPYmplY3RzLy4uLikKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOmdldCwgJy9pcmlzL3YxL2FwaUtleXMnKQogICAgCiAgICBpZiByZXNwb25zZS5ib2R5Lm5pbD8gfHwgIXJlc3BvbnNlLmJvZHkuaXNfYT8oSGFzaCkKICAgICAgcmFpc2UgIkFQSSByZXR1cm5lZCBlbXB0eSBvciBpbnZhbGlkIHJlc3BvbnNlIGJvZHkgZm9yIGxpc3Rpbmcga2V5cyIKICAgIGVuZAogICAgCiAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGdWxsIExpc3QgUmVzcG9uc2U6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAga2V5cyA9IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXSB8fCBbXQogICAgCiAgICBvdXRwdXQgPSBrZXlzLm1hcCBkbyB8a3wKICAgICAgYXR0ciA9IGtbJ2F0dHJpYnV0ZXMnXSB8fCB7fQogICAgICB7CiAgICAgICAgaWQ6IGtbJ2lkJ10sCiAgICAgICAgbmFtZTogYXR0clsnbmFtZSddLAogICAgICAgIGlzc3VlcklkOiBhdHRyWydpc3N1ZXJJZCddLAogICAgICAgIHJvbGU6IGF0dHJbJ3JvbGVzJ10mLmZpcnN0LAogICAgICAgIHJldm9jYWJsZTogYXR0clsncmV2b2NhYmxlJ10KICAgICAgfQogICAgZW5kCiAgICAKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyBvdXRwdXQudG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBpZiBkZWZpbmVkPyhyZXNwb25zZSkgJiYgcmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keQogICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGNyZWF0ZV9rZXkobmFtZSwgcm9sZSA9ICdBRE1JTicpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgCiAgICAjIFRydW5jYXRlIG5pY2tuYW1lIHRvIDMwIGNoYXJzIGFzIHBlciBBcHBsZSdzIGxpbWl0CiAgICAjIFdlIGtlZXAgdGhlIG9yaWdpbmFsICduYW1lJyBmb3IgbG9nZ2luZyBidXQgc2VuZCB0cnVuY2F0ZWQgJ25pY2tuYW1lJyB0byBBUEkKICAgIHNhZmVfbmlja25hbWUgPSBuYW1lWzAsIDMwXQogICAgCiAgICBwYXlsb2FkID0gewogICAgICBkYXRhOiB7CiAgICAgICAgdHlwZTogImFwaUtleXMiLAogICAgICAgIGF0dHJpYnV0ZXM6IHsKICAgICAgICAgIG5pY2tuYW1lOiBzYWZlX25pY2tuYW1lLAogICAgICAgICAga2V5VHlwZTogIlBVQkxJQ19BUEkiLAogICAgICAgICAgcm9sZXM6IFtyb2xlXSwKICAgICAgICAgIGFsbEFwcHNWaXNpYmxlOiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOnBvc3QpIGRvIHxyZXF8CiAgICAgIHJlcS51cmwgIi9pcmlzL3YxL2FwaUtleXMiCiAgICAgIHJlcS5ib2R5ID0gcGF5bG9hZC50b19qc29uCiAgICAgIHJlcS5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJwogICAgICByZXEuaGVhZGVyc1snQWNjZXB0J10gPSAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uLCBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJwogICAgICByZXEuaGVhZGVyc1snWC1SZXF1ZXN0ZWQtV2l0aCddID0gJ1hNTEh0dHBSZXF1ZXN0JwogICAgICByZXEuaGVhZGVyc1snUmVmZXJlciddID0gJ2h0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9hY2Nlc3MvYXBpJwogICAgICByZXEuaGVhZGVyc1snWC1BcHBsZS1XaWRnZXQtS2V5J10gPSBjbGllbnQud2lkZ2V0X2tleSBpZiBjbGllbnQucmVzcG9uZF90bz8oOndpZGdldF9rZXkpCiAgICBlbmQKICAgIAogICAgIyBERUJVRzogSW5zcGVjdCB0aGUgcmF3IHJlc3BvbnNlIG9iamVjdAogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgQ2xhc3M6ICN7cmVzcG9uc2UuY2xhc3N9IgogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgSGVhZGVyczogI3tyZXNwb25zZS5oZWFkZXJzfSIKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAgaWYgcmVzcG9uc2UuYm9keS5uaWw/IHx8ICFyZXNwb25zZS5ib2R5LmlzX2E/KEhhc2gpIHx8IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXS5uaWw/CiAgICAgIGVycm9yX21zZyA9ICJBUEkgZmFpbGVkIHRvIGNyZWF0ZSBrZXkuIgogICAgICBpZiByZXNwb25zZS5ib2R5ICYmIHJlc3BvbnNlLmJvZHlbJ2Vycm9ycyddCiAgICAgICAgZXJyb3JfbXNnICs9ICIgRXJyb3JzOiAiICsgcmVzcG9uc2UuYm9keVsnZXJyb3JzJ10ubWFwe3xlfCBlWydkZXRhaWwnXX0uam9pbignLCAnKQogICAgICBlbmQKICAgICAgcmFpc2UgZXJyb3JfbXNnCiAgICBlbmQKICAgIAogICAga2V5X2RhdGEgPSByZXNwb25zZS5ib2R5WydkYXRhJ10KICAgIGF0dHIgPSBrZXlfZGF0YVsnYXR0cmlidXRlcyddIHx8IHt9CgogICAgIyBUaGUgLnA4IGNvbnRlbnQgaXMgdXN1YWxseSBpbiAncHJpdmF0ZUtleScgb3IgJ2tleUNvbnRlbnQnIG9uIHRoZSBJTklUSUFMIENSRUFURSByZXNwb25zZQogICAgcDhfY29udGVudCA9IGF0dHJbJ3ByaXZhdGVLZXknXSB8fCBhdHRyWydrZXlDb250ZW50J10KICAgIAogICAgaWYgcDhfY29udGVudC5uaWw/CiAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEtleSBjb250ZW50IG1pc3NpbmcgaW4gcmVzcG9uc2UuIEF0dGVtcHRpbmcgcmV0cmlldmFsIHZpYSBkb3dubG9hZC9leHBvcnQgZW5kcG9pbnRzLi4uIiAKICAgICAgCiAgICAgIHBhdGhzX3RvX3RyeSA9IFsKICAgICAgICAiaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2lyaXMvdjEvYXBpS2V5cy8je2tleV9kYXRhWydpZCddfS9kb3dubG9hZCIsCiAgICAgICAgImh0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9pcmlzL3YxL2FwaUtleXMvI3trZXlfZGF0YVsnaWQnXX0vZXhwb3J0IgogICAgICBdCiAgICAgIAogICAgICBwYXRoc190b190cnkuZWFjaCBkbyB8cGF0aHwKICAgICAgICBiZWdpbgogICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogVHJ5aW5nICN7cGF0aH0uLi4iCiAgICAgICAgICBkb3dubG9hZF9yZXNwID0gY2xpZW50LnJlcXVlc3QoOmdldCkgZG8gfHJlcXwKICAgICAgICAgICAgcmVxLnVybCBwYXRoCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydBY2NlcHQnXSA9ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24sIGFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCwgKi8qOyBxPTAuMDEnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydSZWZlcmVyJ10gPSAnaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2FjY2Vzcy9hcGknCiAgICAgICAgICBlbmQKICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIENsYXNzOiAje2Rvd25sb2FkX3Jlc3AuYm9keS5jbGFzc30iCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBTdGF0dXM6ICN7ZG93bmxvYWRfcmVzcC5zdGF0dXN9IiBpZiBkb3dubG9hZF9yZXNwLnJlc3BvbmRfdG8/KDpzdGF0dXMpCiAgICAgICAgICAKICAgICAgICAgIGlmIGRvd25sb2FkX3Jlc3AuYm9keSAmJiAhZG93bmxvYWRfcmVzcC5ib2R5LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKQogICAgICAgICAgICAgaWYgZG93bmxvYWRfcmVzcC5ib2R5LmlzX2E/KEhhc2gpCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHlbJ2tleUNvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHlbJ2NvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHkuZGlnKCdkYXRhJywgJ2F0dHJpYnV0ZXMnLCAncHJpdmF0ZUtleScpCiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHkKICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgCiAgICAgICAgICAgICBpZiBwOF9jb250ZW50ICYmIHA4X2NvbnRlbnQudG9fcy5zdGFydF93aXRoPygnLS0tLS1CRUdJTicpCiAgICAgICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJldHJpZXZhbCB2aWEgI3twYXRofSBzdWNjZXNzZnVsISBDb250ZW50IGxlbmd0aDogI3twOF9jb250ZW50LnRvX3MubGVuZ3RofSIKICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgZnJvbSAje3BhdGh9IGRpZCBub3QgY29udGFpbiBhIHZhbGlkIHByaXZhdGUga2V5LiIKICAgICAgICAgICAgICAgcDhfY29udGVudCA9IG5pbAogICAgICAgICAgICAgZW5kCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBmcm9tICN7cGF0aH0gZW1wdHkgb3IgY29udGFpbnMgZXJyb3JzLiIKICAgICAgICAgIGVuZAogICAgICAgIHJlc2N1ZSA9PiBlCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBBdHRlbXB0IGZvciAje3BhdGh9IGZhaWxlZDogI3tlLm1lc3NhZ2V9IgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAoKICAgICMgRklOQUwgVkFMSURBVElPTjogRW5zdXJlIGl0J3Mgbm90IGEgUnVieSBoYXNoIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBlcnJvcgogICAgaWYgcDhfY29udGVudC5pc19hPyhIYXNoKSB8fCBwOF9jb250ZW50LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKSB8fCAhcDhfY29udGVudC50b19zLnN0YXJ0X3dpdGg/KCctLS0tLUJFR0lOJykKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogSW52YWxpZCBrZXkgY29udGVudCBkZXRlY3RlZC4iCiAgICAgIHA4X2NvbnRlbnQgPSBuaWwKICAgIGVuZAoKICAgIGlmIHA4X2NvbnRlbnQubmlsPwogICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGYWlsZWQgdG8gcmV0cmlldmUga2V5IGNvbnRlbnQuIgogICAgZW5kCiAgICAKICAgIHJlc3VsdCA9IHsKICAgICAgaWQ6IGtleV9kYXRhWydpZCddLAogICAgICBuYW1lOiBhdHRyWyduaWNrbmFtZSddIHx8IGF0dHJbJ25hbWUnXSwKICAgICAgaXNzdWVySWQ6IGF0dHJbJ2lzc3VlcklkJ10sCiAgICAgIGtleUNvbnRlbnQ6IHA4X2NvbnRlbnQsCiAgICAgIHJhd19yZXNwb25zZTogcmVzcG9uc2UuYm9keSAjIEluY2x1ZGUgdGhpcyBmb3IgZGVidWdnaW5nIHdoZW4ga2V5Q29udGVudCBpcyBuaWwKICAgIH0KICAgIAogICAgcHV0cyAiX19fTUFDSF9KU09OX1NUQVJUX19fIiArIHJlc3VsdC50b19qc29uICsgIl9fX01BQ0hfSlNPTl9FTkRfX18iCiAgcmVzY3VlID0+IGUKICAgICRzdGRlcnIucHV0cyAiRVJST1I6ICN7ZS5tZXNzYWdlfSIKICAgIGlmIGRlZmluZWQ/KHJlc3BvbnNlKSAmJiByZXNwb25zZSAmJiByZXNwb25zZS5ib2R5CiAgICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGRlbGV0ZV9rZXkoaWQpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgY2xpZW50LnJlcXVlc3QoOmRlbGV0ZSwgIi9pcmlzL3YxL2FwaUtleXMvI3tpZH0iKQogICAgcHV0cyAiU1VDQ0VTUyIKICByZXNjdWUgPT4gZQogICAgJHN0ZGVyci5wdXRzICJFUlJPUjogI3tlLm1lc3NhZ2V9IgogICAgZXhpdCAxCiAgZW5kCmVuZAoKY29tbWFuZCA9IEFSR1ZbMF0KaWYgY29tbWFuZCA9PSAnbGlzdCcKICBsaXN0X2tleXMKZWxzaWYgY29tbWFuZCA9PSAndGVhbXMnCiAgbGlzdF90ZWFtcwplbHNpZiBjb21tYW5kID09ICdjcmVhdGUnCiAgY3JlYXRlX2tleShBUkdWWzFdIHx8ICJNYWNoIEFQSSBLZXkgI3tUaW1lLm5vdy50b19pfSIpCmVsc2lmIGNvbW1hbmQgPT0gJ2RlbGV0ZScKICBkZWxldGVfa2V5KEFSR1ZbMV0pCmVuZAo=";function Mn(){let e=_e.join(Ln.tmpdir(),A.nameLower);Ie.existsSync(e)||Ie.mkdirSync(e,{recursive:!0});let t=_e.join(e,"manage_asc_keys.rb");return Ie.writeFileSync(t,Buffer.from(es,"base64").toString("utf-8"),{mode:493}),t}function Bn(){return St()}function Un(e){let t=new Map,n=/-\s+(\d+)\s+\(([^)]+)\)/g,i=/\d+\)\s+"([^"]+)"\s+\((\d+)\)/g,r;for(;(r=n.exec(e))!==null;)t.set(r[1],{id:r[1],name:r[2]});for(;(r=i.exec(e))!==null;)t.set(r[2],{id:r[2],name:r[1]});return Array.from(t.values())}function Mi(e,t=Ge(e,"store","production")){return Bt(e,t).appStoreConnectTeamId}function Bi(e,t,n){return{...Bn(),FASTLANE_USER:e,FASTLANE_TEAM_ID:t,...n?{FASTLANE_ITC_TEAM_ID:n,FASTLANE_ASC_TEAM_ID:n}:{}}}function pt(e,t=Ge(e,"store","production"),n={}){let i=Bt(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 ts(e,t,n=Ge(e,"store","production")){if(!t.id)return;e.submit||(e.submit={}),e.submit[n]||(e.submit[n]={}),e.submit[n].ios||(e.submit[n].ios={});let i=e.submit[n].ios;i.appStoreConnectTeamId=t.id,delete i.providerId,delete i.appStoreConnectTeamName,delete i.providerName,delete i.appleTeamName}function Wn(e,t,n){ts(e,t,n);try{Ie.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}async function ns(e,t,n,i,r){let o=wt();o.start("Fetching App Store Connect providers...");let s=jt("ruby",[e,"teams"],{env:Bi(n,i),stdio:["inherit","pipe","pipe"],encoding:"utf-8"});if(s.status!==0){o.stop("Could not fetch providers");let p=Un(`${s.stdout||""}
3
- ${s.stderr||""}`);if(p.length>0)return Vn(t,p,"Select the App Store Connect provider for this API key:",void 0,r);ie.warn(fe.yellow(`Could not list App Store Connect providers: ${s.stderr||"Unknown error"}`));return}let a=(s.stdout||"").match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!a){o.stop("Could not parse providers");return}let l=JSON.parse(a[1]),c=(l.teams||[]).filter(p=>p.id&&p.name);if(o.stop(c.length===1?"Found 1 provider":`Found ${c.length} providers`),c.length===0)return;if(c.length===1){ie.success(fe.green(`\u2713 Using App Store Connect provider ${c[0].name} (${c[0].id})`));let p={...c[0],developerTeamName:l.developerTeamName};return Wn(t,p,r),p}let d=c.filter(p=>p.recommended),u=c.filter(p=>!p.recommended);return Vn(t,[...d,...u],`Select the App Store Connect provider for Developer Team ${l.developerTeamName||i}:`,l.developerTeamName,r)}async function Vn(e,t,n,i,r){let o=await ft({message:n,options:t.map(c=>({value:c.id,label:c.name,hint:`${c.id}${c.recommended?" \xB7 recommended":""}`}))});if(we(o))return Oe("Operation cancelled"),null;let s=o,l={...t.find(c=>c.id===s)||{id:s,name:s},developerTeamName:i};return Wn(e,l,r),ie.success(fe.green(`\u2713 Using App Store Connect provider ${l.name} (${l.id})`)),l}var Lt=e=>typeof e=="string"&&e.trim()?e.trim():void 0,Oi=e=>Lt(e)?.toUpperCase();function is(e,t){let n=Oi(t.developerTeamId||t.teamId),i=Lt(t.appStoreConnectTeamId||t.providerId);return e.filter(r=>{let o=Oi(r.teamId),s=Lt(r.appStoreConnectTeamId||r.providerId);return!(n&&o!==n||i&&s!==i)})}function Dn(e){let t=Lt(e.name)||"App Store Connect API key",n=Lt(e.sourceProjectName)||e.sourceProjectId;return`${t} \xB7 ${n}`}function rs(e){return[e.teamId?`Apple Team ${e.teamId}`:void 0,e.appStoreConnectTeamId||e.providerId?`ASC provider ${e.appStoreConnectTeamId||e.providerId}`:void 0,e.keyId?`Key ${e.keyId}`:void 0].filter(Boolean).join(" \xB7 ")}async function os(e,t,n){let i=pt(t,n),r=i.developerTeamId||i.teamId,o=i.appStoreConnectTeamId||i.providerId;if(!r){ie.error(`Set ios.appleTeamId or submit.${n}.ios.appleTeamId in ${A.configFileName} before reusing an App Store Connect API key.`);return}let s=wt(),a=[];try{s.start("Looking for compatible saved App Store Connect API keys...");let d=await U.get("/credentials/reusable",{params:{projectId:e,type:"asc_api_key"}});a=is(Array.isArray(d.data?.credentials)?d.data.credentials:[],i),s.stop(a.length===1?"Found 1 compatible saved API key":`Found ${a.length} compatible saved API keys`)}catch(d){s.stop("Could not load saved API keys"),ie.error(`Could not load reusable App Store Connect API keys: ${d.response?.data?.message||d.message}. You need administrator access to this project and the source project.`);return}if(a.length===0){let d=o?`Apple Team ${r} and App Store Connect provider ${o}`:`Apple Team ${r}`;ie.info(`No compatible saved API keys were found for ${d}.`);return}let l=await ft({message:"Select a saved App Store Connect API key to reuse:",options:[...a.map((d,u)=>({value:String(u),label:Dn(d),hint:rs(d)})),{value:"cancel",label:"Cancel"}]});if(we(l)||l==="cancel"){Oe("Operation cancelled");return}let c=a[Number(l)];if(!c){ie.error("The selected App Store Connect API key is no longer available.");return}try{s.start(`Copying ${Dn(c)} into this project...`),await U.post("/credentials/reuse",{projectId:e,sourceProjectId:c.sourceProjectId,credentialId:c.credentialId,type:"asc_api_key"}),s.stop("Saved API key copied to this project");let d=c.appStoreConnectTeamId||c.providerId;d&&Wn(t,{id:d,name:c.providerName||d},n),ie.success(fe.green(`\u2713 Reused ${Dn(c)} for this project.`))}catch(d){s.stop("Could not reuse saved API key"),ie.error(`Could not reuse the selected App Store Connect API key: ${d.response?.data?.message||d.message}.`)}}var Vi=async e=>{let t=wt(),n=e.platform,i=`./${A.configFileName}`;if(!Ie.existsSync(i)){ie.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(Ie.readFileSync(i,"utf-8")),{projectId:o}=r,s=e.profile||Ge(r,"store","production");if(!o){ie.error(`${A.configFileName} is missing projectId.`);return}let a=e.file,l=n==="android"?e.packageName||e.bundleId:e.bundleId||nt(r,s)||"*";if(n==="android"&&!l&&(l=await ss(o,r,s),l===null))return;if(n==="ios"&&!a){let p=await ft({message:"Manage App Store Connect API Key:",options:[{value:"magic",label:"\u2728 Create new automatically",hint:"Requires Apple ID + 2FA"},{value:"reuse",label:"\u267B\uFE0F Use a saved API Key",hint:"Copy a compatible key from another Mach project"},{value:"manual",label:"\u{1F50D} Configure manually",hint:"Provide existing .p8 file"},{value:"delete",label:"\u{1F5D1}\uFE0F Delete an existing Key"}]});if(we(p)){Oe("Operation cancelled");return}if(p==="magic"){await ls(o,r,s);return}if(p==="reuse"){await os(o,r,s);return}if(p==="delete"){await ds(o,r,s);return}}if(!a){let p=n==="ios"?"https://appstoreconnect.apple.com/access/api":"https://console.cloud.google.com/apis/credentials";rn(`To submit to the ${n==="ios"?"App Store":"Google Play Store"}, you need a Service Key:
1
+ import{a as A,h as U,i as Mt,k as kn}from"./chunk-QFXPWC5D.js";import{log as g,spinner as ct,text as Oe,password as ht,select as be,confirm as Pi,isCancel as L,cancel as q,intro as wc,outro as vc,note as Ec}from"@clack/prompts";import{log as ie,spinner as Ct,text as He,select as ft,isCancel as Ce,cancel as Fe,note as rn,confirm as Di}from"@clack/prompts";import fe from"chalk";import{spawnSync as jt}from"child_process";import Ae from"fs";import $e from"path";import Ln from"os";import qt from"fs";import{log as Bo}from"@clack/prompts";var jo=["react-native","expo","flutter"],$l="react-native",$i=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},_i=e=>$i(e)?.toUpperCase()||void 0,en=(...e)=>{for(let t of e){let n=$i(t);if(n)return n}};function Lo(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="react-native"||t==="react_native"||t==="reactnative")return"react-native";if(t==="expo")return"expo";if(t==="flutter")return"flutter"}function _n(e){let t=Lo(e?.framework);if(t)return t;let n=jo.map(i=>`"${i}"`).join(", ");throw e?.framework?new Error(`${A.configFileName} has invalid framework "${e.framework}". Use one of: ${n}.`):new Error(`${A.configFileName} is missing required field "framework". Add one of: ${n}.`)}function Vt(e,t=Ge(e,"store","production")){let n=e?.ios||{},i=e?.submit?.[t]?.ios||{},r=e?.submit?.production?.ios||{},o=_i(n.appleTeamId||n.developerTeamId||i.appleTeamId||i.developerTeamId||r.appleTeamId||r.developerTeamId),s=en(n.appStoreConnectTeamId,n.itcTeamId,n.appleConnectTeamId,i.appStoreConnectTeamId,i.itcTeamId,i.appleConnectTeamId,r.appStoreConnectTeamId,r.itcTeamId,r.appleConnectTeamId);return{teamId:o,teamName:en(n.appleTeamName,n.teamName,n.developerTeamName,i.appleTeamName,i.teamName,i.developerTeamName,r.appleTeamName,r.teamName,r.developerTeamName),developerTeamId:_i(n.developerTeamId||i.developerTeamId||r.developerTeamId||o),appStoreConnectTeamId:s,providerId:en(n.providerId,i.providerId,r.providerId,s),providerName:en(n.providerName,n.appStoreConnectTeamName,i.providerName,i.appStoreConnectTeamName,r.providerName,r.appStoreConnectTeamName)}}function Oi(e){if(e){if(!qt.existsSync(e))return null;try{return JSON.parse(qt.readFileSync(e,"utf-8"))}catch{return null}}if(!qt.existsSync(`./${A.configFileName}`))return null;try{return JSON.parse(qt.readFileSync(`./${A.configFileName}`,"utf-8"))}catch{return null}}function Te(e,t,n=new Set){if(n.has(t))throw new Error(`Circular inheritance detected in profile: ${t}`);n.add(t);let i=e.build?.[t];if(!i)return null;let r={...i};if(i.extends){let o=Te(e,i.extends,n);o&&(r={...o,...i,env:{...o.env,...i.env},ios:{...o.ios,...i.ios},android:{...o.android,...i.android},flutter:{...o.flutter,...i.flutter}})}if(r.envGroups&&Array.isArray(r.envGroups)){let o={};for(let s of r.envGroups){let a=e.envGroups?.[s];a?Object.assign(o,a):Bo.warn(`Environment group not found: ${s}`)}r.env={...o,...r.env}}return r}function Ge(e,t="first",n="production"){let i=Object.keys(e?.build||{});return i.length===0?n:t==="first"?i[0]:i.find(o=>{let s=Te(e,o)||{},a=String(s.distribution||"").trim().toLowerCase().replace(/_/g,"-"),l=String(s.environment||"").trim().toLowerCase().replace(/_/g,"-"),c=String(s.iosExportMethod||s.ios?.exportMethod||"").trim().toLowerCase().replace(/_/g,"-");return t==="development"?s.developmentClient===!0||s.simulator===!0||s.ios?.simulator===!0||s.flutter?.mode==="debug"||a==="development"||l==="development":a==="store"||c==="app-store"||l==="production"||l==="store"})||i[0]}function bt(e,t){let n=t?Te(e,t)||{}:{};if(n.android?.package)return n.android.package;if(n.androidPackage)return n.androidPackage;if(e.android?.package)return e.android.package;if(e.expo?.android?.package)return e.expo.android.package}function nt(e,t){let n=t?Te(e,t)||{}:{};if(n.ios?.bundleIdentifier)return n.ios.bundleIdentifier;if(n.iosBundleIdentifier)return n.iosBundleIdentifier;if(e.ios?.bundleIdentifier)return e.ios.bundleIdentifier;if(e.ios?.bundleId)return e.ios.bundleId;if(e.expo?.ios?.bundleIdentifier)return e.expo.ios.bundleIdentifier}var Ol=(e,t=`${A.envPrefix}`)=>{let n={},i=(r,o)=>{if(r)for(let s in r){let a=r[s],l=`${o}${s.toUpperCase().replace(/[^A-Z0-9]/g,"_")}`;a!==null&&typeof a=="object"&&!Array.isArray(a)?i(a,`${l}_`):n[l]=String(a)}};return i(e,t),n};import{cancel as On,confirm as Uo,isCancel as Tn,log as dt,select as Wo,text as Go}from"@clack/prompts";import ut from"chalk";import Fn from"fs";import{createRequire as Zo}from"module";import Ho from"os";import tn from"path";var Xo=Zo(import.meta.url),$n=null;function Ko(){return $n||($n=Xo("@expo/apple-utils")),$n}function nn(e){if(!e)return!1;try{return Fn.readdirSync(tn.join(e,"gems"),{withFileTypes:!0}).some(t=>t.isDirectory()&&t.name.startsWith("fastlane-"))}catch{return!1}}function Jo(){let e=["/opt/homebrew/opt/fastlane/libexec","/usr/local/opt/fastlane/libexec"];for(let n of e)if(nn(n))return n;let t=["/opt/homebrew/Cellar/fastlane","/usr/local/Cellar/fastlane"];for(let n of t)try{let i=Fn.readdirSync(n,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name).sort((r,o)=>o.localeCompare(r,void 0,{numeric:!0}));for(let r of i){let o=tn.join(n,r,"libexec");if(nn(o))return o}}catch{}}function St(){let e=process.env.HOME||Ho.homedir(),t=tn.join(e,".local/share/fastlane/3.4.0"),n=process.env.FASTLANE_GEM_HOME?.trim(),i=nn(n)?n:Jo()||(nn(t)?t:n||t);return{...process.env,PATH:[process.env.FASTLANE_BIN_DIR,tn.join(i,"bin"),"/usr/local/opt/ruby/bin","/opt/homebrew/opt/ruby/bin","/usr/local/bin","/opt/homebrew/bin",process.env.PATH].filter(Boolean).join(":"),GEM_HOME:i,GEM_PATH:[i,process.env.GEM_PATH].filter(Boolean).join(":"),FASTLANE_INSTALLED_VIA_HOMEBREW:"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1",LANG:process.env.LANG||"en_US.UTF-8",LC_ALL:process.env.LC_ALL||"en_US.UTF-8",CI:"1"}}function Yo(e,t=Ge(e,"store","production")){return e.submit||(e.submit={}),e.submit[t]||(e.submit[t]={}),e.submit[t].ios||(e.submit[t].ios={}),e.submit[t].ios}function zo(e,t,n=Ge(e,"store","production")){if(!e||!t.id)return;let i=Yo(e,n);i.appleTeamId=t.id;try{Fn.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}function Qo(e){let t=String(e?.teamId||e?.id||"").trim().toUpperCase();return t?{id:t,name:String(e?.name||"").trim()||void 0,type:String(e?.type||"").trim()||void 0}:null}async function qo(e){try{let{Auth:t,Teams:n}=Ko(),i=await t.loginAsync({username:e},{autoResolveProvider:!0}),r=String(i?.context?.teamId||"").trim().toUpperCase(),o=await n.getTeamsAsync(),s=new Map;for(let c of o||[]){let d=Qo(c);d&&s.set(d.id,d)}let a=Array.from(s.values()),l=r?a.find(c=>c.id===r)||{id:r}:void 0;return{teams:a,selectedTeam:l}}catch(t){let n=t instanceof Error?t.message:String(t||"");return dt.warn(ut.yellow(`Apple Developer team lookup failed${n?`: ${n}`:""}`)),{teams:[]}}}async function Ti(){dt.warn(ut.yellow(`
2
+ Apple Team ID is required to fetch certificates.`)),dt.info(ut.dim("You can find this at: https://developer.apple.com/account -> Membership Details"));let e=await Go({message:"Enter your 10-character Apple Team ID:",placeholder:"e.g. SA56KTS33U",validate:t=>/^[A-Z0-9]{10}$/i.test(t.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});return Tn(e)?(On("Operation cancelled"),null):{id:e.trim().toUpperCase()}}function es(e){let t=[e.id,e.type].filter(Boolean);return t.length>0?t.join(" \xB7 "):void 0}async function ts(e,t){if(!e.config)return!1;if(e.persistConfig)return!0;if(!e.promptToPersistConfig)return!1;let n=e.profile||Ge(e.config,"store","production"),i=await Uo({message:`Save Apple Team ID ${t} to ${A.configFileName} for "${n}" profile?`,initialValue:!0});return Tn(i)?(On("Operation cancelled"),null):i}async function Bt(e){let t=e.initialTeam?.teamId?.trim().toUpperCase();if(t){let c=e.initialTeam?.developerTeamId?.trim().toUpperCase();return{...e.initialTeam,teamId:t,developerTeamId:c||t}}dt.info(ut.blue("Fetching Apple Developer teams..."));let{teams:n,selectedTeam:i}=await qo(e.appleId),r;if(i)r=i,dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length===1)r=n[0],dt.success(ut.green(`\u2713 Using Apple Developer team ${r.name||r.id} (${r.id})`));else if(n.length>1){let c=await Wo({message:"Select Apple Developer team:",options:[...n.map(d=>({value:d.id,label:d.name||d.id,hint:es(d)})),{value:"__manual__",label:"Enter Team ID manually",hint:"Use if your team is not listed"}]});if(Tn(c))return On("Operation cancelled"),null;r=c==="__manual__"?await Ti():n.find(d=>d.id===c)||{id:c}}else dt.warn(ut.yellow("Could not list Apple Developer teams automatically.")),r=await Ti();if(!r)return null;let o=r.id.trim().toUpperCase(),s=r.name?.trim(),a={...e.initialTeam,teamId:o,teamName:s||e.initialTeam?.teamName,developerTeamId:o},l=await ts(e,o);return l===null?null:(l&&zo(e.config,{...r,id:o,name:s},e.profile),e.saveTeamId&&await e.saveTeamId(o,s),a)}var ns="cmVxdWlyZSAnc3BhY2VzaGlwJwpyZXF1aXJlICdqc29uJwoKZGVmIHJlYWRfdGVhbV9maWVsZCh0ZWFtLCAqa2V5cykKICBrZXlzLmVhY2ggZG8gfGtleXwKICAgIGJlZ2luCiAgICAgIHZhbHVlID0gdGVhbVtrZXldIGlmIHRlYW0ucmVzcG9uZF90bz8oOltdKQogICAgICByZXR1cm4gdmFsdWUgaWYgdmFsdWUgJiYgdmFsdWUudG9fcy5sZW5ndGggPiAwCiAgICByZXNjdWUKICAgIGVuZAoKICAgIG1ldGhvZF9uYW1lID0ga2V5LnRvX3MKICAgIGlmIHRlYW0ucmVzcG9uZF90bz8obWV0aG9kX25hbWUpCiAgICAgIHZhbHVlID0gdGVhbS5wdWJsaWNfc2VuZChtZXRob2RfbmFtZSkKICAgICAgcmV0dXJuIHZhbHVlIGlmIHZhbHVlICYmIHZhbHVlLnRvX3MubGVuZ3RoID4gMAogICAgZW5kCiAgZW5kCgogIG5pbAplbmQKCmRlZiBub3JtYWxpemVfdGVhbV9uYW1lKG5hbWUpCiAgbmFtZS50b19zLmRvd25jYXNlLmdzdWIoL1teYS16MC05XSsvLCAnICcpLnN0cmlwCmVuZAoKZGVmIHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtX2lkID0gRU5WWydGQVNUTEFORV9URUFNX0lEJ10udG9fcwogIHRlYW1zID0gU3BhY2VzaGlwOjpQb3J0YWwuY2xpZW50LnRlYW1zCiAgdGVhbXMgPSB0ZWFtcy52YWx1ZXMgaWYgdGVhbXMuaXNfYT8oSGFzaCkKCiAgdGVhbSA9IEFycmF5KHRlYW1zKS5maW5kIGRvIHx0fAogICAgWwogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1JZCcsIDp0ZWFtSWQpLAogICAgICByZWFkX3RlYW1fZmllbGQodCwgJ3RlYW1faWQnLCA6dGVhbV9pZCksCiAgICAgIHJlYWRfdGVhbV9maWVsZCh0LCAnaWQnLCA6aWQpCiAgICBdLmNvbXBhY3QubWFwKCY6dG9fcykuaW5jbHVkZT8odGVhbV9pZCkKICBlbmQKCiAgcmVhZF90ZWFtX2ZpZWxkKHRlYW0sICduYW1lJywgOm5hbWUsICd0ZWFtTmFtZScsIDp0ZWFtTmFtZSwgJ2Rpc3BsYXlOYW1lJywgOmRpc3BsYXlOYW1lKQpyZXNjdWUgPT4gZQogICRzdGRlcnIucHV0cyAiREVCVUc6IENvdWxkIG5vdCByZXNvbHZlIERldmVsb3BlciBQb3J0YWwgdGVhbSBuYW1lOiAje2UubWVzc2FnZX0iCiAgbmlsCmVuZAoKZGVmIHR1bmVzX3RlYW1faWQodGVhbSkKICByZWFkX3RlYW1fZmllbGQoCiAgICB0ZWFtLAogICAgJ3Byb3ZpZGVySWQnLCA6cHJvdmlkZXJJZCwKICAgICdwcm92aWRlcl9pZCcsIDpwcm92aWRlcl9pZCwKICAgICdjb250ZW50UHJvdmlkZXJJZCcsIDpjb250ZW50UHJvdmlkZXJJZCwKICAgICdjb250ZW50X3Byb3ZpZGVyX2lkJywgOmNvbnRlbnRfcHJvdmlkZXJfaWQsCiAgICAndGVhbUlkJywgOnRlYW1JZCwKICAgICd0ZWFtX2lkJywgOnRlYW1faWQsCiAgICAnaWQnLCA6aWQKICApLnRvX3MKZW5kCgpkZWYgdHVuZXNfdGVhbV9uYW1lKHRlYW0pCiAgcmVhZF90ZWFtX2ZpZWxkKAogICAgdGVhbSwKICAgICduYW1lJywgOm5hbWUsCiAgICAnY29udGVudFByb3ZpZGVyTmFtZScsIDpjb250ZW50UHJvdmlkZXJOYW1lLAogICAgJ2NvbnRlbnRfcHJvdmlkZXJfbmFtZScsIDpjb250ZW50X3Byb3ZpZGVyX25hbWUsCiAgICAndGVhbU5hbWUnLCA6dGVhbU5hbWUsCiAgICAnZGlzcGxheU5hbWUnLCA6ZGlzcGxheU5hbWUKICApLnRvX3MKZW5kCgpkZWYgYXZhaWxhYmxlX3R1bmVzX3RlYW1zCiAgdGVhbXMgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudC50ZWFtcwogIHRlYW1zID0gdGVhbXMudmFsdWVzIGlmIHRlYW1zLmlzX2E/KEhhc2gpCiAgQXJyYXkodGVhbXMpCnJlc2N1ZSA9PiBlCiAgJHN0ZGVyci5wdXRzICJERUJVRzogQ291bGQgbm90IGluc3BlY3QgQXBwIFN0b3JlIENvbm5lY3QgdGVhbXM6ICN7ZS5tZXNzYWdlfSIKICBbXQplbmQKCmRlZiBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogIGV4cGxpY2l0X3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX0lUQ19URUFNX0lEJ10gfHwgRU5WWydGQVNUTEFORV9BU0NfVEVBTV9JRCddCiAgaWYgZXhwbGljaXRfdGVhbV9pZCAmJiBleHBsaWNpdF90ZWFtX2lkLnRvX3MubGVuZ3RoID4gMAogICAgU3BhY2VzaGlwOjpUdW5lcy5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBleHBsaWNpdF90ZWFtX2lkKQogICAgcmV0dXJuIGV4cGxpY2l0X3RlYW1faWQKICBlbmQKCiAgZGV2ZWxvcGVyX3RlYW1faWQgPSBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXS50b19zCiAgZGV2ZWxvcGVyX3RlYW1fbmFtZSA9IHBvcnRhbF90ZWFtX25hbWUKICB0ZWFtcyA9IGF2YWlsYWJsZV90dW5lc190ZWFtcwoKICBpZiBkZXZlbG9wZXJfdGVhbV9uYW1lICYmIGRldmVsb3Blcl90ZWFtX25hbWUubGVuZ3RoID4gMAogICAgbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZSA9IG5vcm1hbGl6ZV90ZWFtX25hbWUoZGV2ZWxvcGVyX3RlYW1fbmFtZSkKICAgIG1hdGNoZWRfdGVhbSA9IHRlYW1zLmZpbmQgeyB8dGVhbXwgbm9ybWFsaXplX3RlYW1fbmFtZSh0dW5lc190ZWFtX25hbWUodGVhbSkpID09IG5vcm1hbGl6ZWRfZGV2ZWxvcGVyX25hbWUgfQoKICAgIGlmIG1hdGNoZWRfdGVhbQogICAgICBtYXRjaGVkX2lkID0gdHVuZXNfdGVhbV9pZChtYXRjaGVkX3RlYW0pCiAgICAgIG1hdGNoZWRfbmFtZSA9IHR1bmVzX3RlYW1fbmFtZShtYXRjaGVkX3RlYW0pCiAgICAgIFNwYWNlc2hpcDo6VHVuZXMuc2VsZWN0X3RlYW0odGVhbV9pZDogbWF0Y2hlZF9pZCkKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogQXV0by1zZWxlY3RlZCBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7bWF0Y2hlZF9pZH0gKCN7bWF0Y2hlZF9uYW1lfSkgZm9yIERldmVsb3BlciBUZWFtICN7ZGV2ZWxvcGVyX3RlYW1faWR9IgogICAgICByZXR1cm4gbWF0Y2hlZF9pZAogICAgZW5kCiAgZW5kCgogIGlmIHRlYW1zLmxlbmd0aCA9PSAxCiAgICBvbmx5X3RlYW0gPSB0ZWFtcy5maXJzdAogICAgb25seV90ZWFtX2lkID0gdHVuZXNfdGVhbV9pZChvbmx5X3RlYW0pCiAgICBTcGFjZXNoaXA6OlR1bmVzLnNlbGVjdF90ZWFtKHRlYW1faWQ6IG9ubHlfdGVhbV9pZCkKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEF1dG8tc2VsZWN0ZWQgb25seSBBcHAgU3RvcmUgQ29ubmVjdCB0ZWFtICN7b25seV90ZWFtX2lkfSAoI3t0dW5lc190ZWFtX25hbWUob25seV90ZWFtKX0pIgogICAgcmV0dXJuIG9ubHlfdGVhbV9pZAogIGVuZAoKICAkc3RkZXJyLnB1dHMgIkVSUk9SOiBDb3VsZCBub3QgbWFwIEFwcGxlIERldmVsb3BlciBUZWFtIElEICcje2RldmVsb3Blcl90ZWFtX2lkfScje2RldmVsb3Blcl90ZWFtX25hbWUgPyAiICgje2RldmVsb3Blcl90ZWFtX25hbWV9KSIgOiAnJ30gdG8gQXBwIFN0b3JlIENvbm5lY3QuIgogICRzdGRlcnIucHV0cyAiQXZhaWxhYmxlIEFwcCBTdG9yZSBDb25uZWN0IHRlYW1zOiIKICB0ZWFtcy5lYWNoIGRvIHx0ZWFtfAogICAgJHN0ZGVyci5wdXRzICItICN7dHVuZXNfdGVhbV9pZCh0ZWFtKX0gKCN7dHVuZXNfdGVhbV9uYW1lKHRlYW0pfSkiCiAgZW5kCiAgZXhpdCAxCmVuZAoKZGVmIGxpc3RfdGVhbXMKICBiZWdpbgogICAgU3BhY2VzaGlwOjpQb3J0YWwubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBTcGFjZXNoaXA6OlBvcnRhbC5zZWxlY3RfdGVhbSh0ZWFtX2lkOiBFTlZbJ0ZBU1RMQU5FX1RFQU1fSUQnXSkKCiAgICBkZXZlbG9wZXJfdGVhbV9uYW1lID0gcG9ydGFsX3RlYW1fbmFtZQoKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lID0gbm9ybWFsaXplX3RlYW1fbmFtZShkZXZlbG9wZXJfdGVhbV9uYW1lKQogICAgdGVhbXMgPSBhdmFpbGFibGVfdHVuZXNfdGVhbXMubWFwIGRvIHx0ZWFtfAogICAgICB0ZWFtX25hbWUgPSB0dW5lc190ZWFtX25hbWUodGVhbSkKICAgICAgewogICAgICAgIGlkOiB0dW5lc190ZWFtX2lkKHRlYW0pLAogICAgICAgIG5hbWU6IHRlYW1fbmFtZSwKICAgICAgICByZWNvbW1lbmRlZDogbm9ybWFsaXplZF9kZXZlbG9wZXJfbmFtZS5sZW5ndGggPiAwICYmIG5vcm1hbGl6ZV90ZWFtX25hbWUodGVhbV9uYW1lKSA9PSBub3JtYWxpemVkX2RldmVsb3Blcl9uYW1lCiAgICAgIH0KICAgIGVuZAoKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyB7CiAgICAgIGRldmVsb3BlclRlYW1JZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10sCiAgICAgIGRldmVsb3BlclRlYW1OYW1lOiBkZXZlbG9wZXJfdGVhbV9uYW1lLAogICAgICB0ZWFtczogdGVhbXMKICAgIH0udG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBleGl0IDEKICBlbmQKZW5kCgpkZWYgbGlzdF9rZXlzCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICAjIFVzZSBUdW5lcyBjbGllbnQgd2hpY2ggcG9pbnRzIHRvIGFwcHN0b3JlY29ubmVjdC5hcHBsZS5jb20KICAgIGNsaWVudCA9IFNwYWNlc2hpcDo6VHVuZXMuY2xpZW50CiAgICAjIFVzZSByb290LXJlbGF0aXZlIFVSTCB0byByZXBsYWNlIHRoZSBkZWZhdWx0IFR1bmVzIHBhdGggKC9XZWJPYmplY3RzLy4uLikKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOmdldCwgJy9pcmlzL3YxL2FwaUtleXMnKQogICAgCiAgICBpZiByZXNwb25zZS5ib2R5Lm5pbD8gfHwgIXJlc3BvbnNlLmJvZHkuaXNfYT8oSGFzaCkKICAgICAgcmFpc2UgIkFQSSByZXR1cm5lZCBlbXB0eSBvciBpbnZhbGlkIHJlc3BvbnNlIGJvZHkgZm9yIGxpc3Rpbmcga2V5cyIKICAgIGVuZAogICAgCiAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGdWxsIExpc3QgUmVzcG9uc2U6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAga2V5cyA9IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXSB8fCBbXQogICAgCiAgICBvdXRwdXQgPSBrZXlzLm1hcCBkbyB8a3wKICAgICAgYXR0ciA9IGtbJ2F0dHJpYnV0ZXMnXSB8fCB7fQogICAgICB7CiAgICAgICAgaWQ6IGtbJ2lkJ10sCiAgICAgICAgbmFtZTogYXR0clsnbmFtZSddLAogICAgICAgIGlzc3VlcklkOiBhdHRyWydpc3N1ZXJJZCddLAogICAgICAgIHJvbGU6IGF0dHJbJ3JvbGVzJ10mLmZpcnN0LAogICAgICAgIHJldm9jYWJsZTogYXR0clsncmV2b2NhYmxlJ10KICAgICAgfQogICAgZW5kCiAgICAKICAgIHB1dHMgIl9fX01BQ0hfSlNPTl9TVEFSVF9fXyIgKyBvdXRwdXQudG9fanNvbiArICJfX19NQUNIX0pTT05fRU5EX19fIgogIHJlc2N1ZSA9PiBlCiAgICAkc3RkZXJyLnB1dHMgIkVSUk9SOiAje2UubWVzc2FnZX0iCiAgICBpZiBkZWZpbmVkPyhyZXNwb25zZSkgJiYgcmVzcG9uc2UgJiYgcmVzcG9uc2UuYm9keQogICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGNyZWF0ZV9rZXkobmFtZSwgcm9sZSA9ICdBRE1JTicpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgCiAgICAjIFRydW5jYXRlIG5pY2tuYW1lIHRvIDMwIGNoYXJzIGFzIHBlciBBcHBsZSdzIGxpbWl0CiAgICAjIFdlIGtlZXAgdGhlIG9yaWdpbmFsICduYW1lJyBmb3IgbG9nZ2luZyBidXQgc2VuZCB0cnVuY2F0ZWQgJ25pY2tuYW1lJyB0byBBUEkKICAgIHNhZmVfbmlja25hbWUgPSBuYW1lWzAsIDMwXQogICAgCiAgICBwYXlsb2FkID0gewogICAgICBkYXRhOiB7CiAgICAgICAgdHlwZTogImFwaUtleXMiLAogICAgICAgIGF0dHJpYnV0ZXM6IHsKICAgICAgICAgIG5pY2tuYW1lOiBzYWZlX25pY2tuYW1lLAogICAgICAgICAga2V5VHlwZTogIlBVQkxJQ19BUEkiLAogICAgICAgICAgcm9sZXM6IFtyb2xlXSwKICAgICAgICAgIGFsbEFwcHNWaXNpYmxlOiB0cnVlCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAKICAgIHJlc3BvbnNlID0gY2xpZW50LnJlcXVlc3QoOnBvc3QpIGRvIHxyZXF8CiAgICAgIHJlcS51cmwgIi9pcmlzL3YxL2FwaUtleXMiCiAgICAgIHJlcS5ib2R5ID0gcGF5bG9hZC50b19qc29uCiAgICAgIHJlcS5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJwogICAgICByZXEuaGVhZGVyc1snQWNjZXB0J10gPSAnYXBwbGljYXRpb24vdm5kLmFwaStqc29uLCBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJwogICAgICByZXEuaGVhZGVyc1snWC1SZXF1ZXN0ZWQtV2l0aCddID0gJ1hNTEh0dHBSZXF1ZXN0JwogICAgICByZXEuaGVhZGVyc1snUmVmZXJlciddID0gJ2h0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9hY2Nlc3MvYXBpJwogICAgICByZXEuaGVhZGVyc1snWC1BcHBsZS1XaWRnZXQtS2V5J10gPSBjbGllbnQud2lkZ2V0X2tleSBpZiBjbGllbnQucmVzcG9uZF90bz8oOndpZGdldF9rZXkpCiAgICBlbmQKICAgIAogICAgIyBERUJVRzogSW5zcGVjdCB0aGUgcmF3IHJlc3BvbnNlIG9iamVjdAogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgQ2xhc3M6ICN7cmVzcG9uc2UuY2xhc3N9IgogICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgSGVhZGVyczogI3tyZXNwb25zZS5oZWFkZXJzfSIKICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIAogICAgaWYgcmVzcG9uc2UuYm9keS5uaWw/IHx8ICFyZXNwb25zZS5ib2R5LmlzX2E/KEhhc2gpIHx8IHJlc3BvbnNlLmJvZHlbJ2RhdGEnXS5uaWw/CiAgICAgIGVycm9yX21zZyA9ICJBUEkgZmFpbGVkIHRvIGNyZWF0ZSBrZXkuIgogICAgICBpZiByZXNwb25zZS5ib2R5ICYmIHJlc3BvbnNlLmJvZHlbJ2Vycm9ycyddCiAgICAgICAgZXJyb3JfbXNnICs9ICIgRXJyb3JzOiAiICsgcmVzcG9uc2UuYm9keVsnZXJyb3JzJ10ubWFwe3xlfCBlWydkZXRhaWwnXX0uam9pbignLCAnKQogICAgICBlbmQKICAgICAgcmFpc2UgZXJyb3JfbXNnCiAgICBlbmQKICAgIAogICAga2V5X2RhdGEgPSByZXNwb25zZS5ib2R5WydkYXRhJ10KICAgIGF0dHIgPSBrZXlfZGF0YVsnYXR0cmlidXRlcyddIHx8IHt9CgogICAgIyBUaGUgLnA4IGNvbnRlbnQgaXMgdXN1YWxseSBpbiAncHJpdmF0ZUtleScgb3IgJ2tleUNvbnRlbnQnIG9uIHRoZSBJTklUSUFMIENSRUFURSByZXNwb25zZQogICAgcDhfY29udGVudCA9IGF0dHJbJ3ByaXZhdGVLZXknXSB8fCBhdHRyWydrZXlDb250ZW50J10KICAgIAogICAgaWYgcDhfY29udGVudC5uaWw/CiAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IEtleSBjb250ZW50IG1pc3NpbmcgaW4gcmVzcG9uc2UuIEF0dGVtcHRpbmcgcmV0cmlldmFsIHZpYSBkb3dubG9hZC9leHBvcnQgZW5kcG9pbnRzLi4uIiAKICAgICAgCiAgICAgIHBhdGhzX3RvX3RyeSA9IFsKICAgICAgICAiaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2lyaXMvdjEvYXBpS2V5cy8je2tleV9kYXRhWydpZCddfS9kb3dubG9hZCIsCiAgICAgICAgImh0dHBzOi8vYXBwc3RvcmVjb25uZWN0LmFwcGxlLmNvbS9pcmlzL3YxL2FwaUtleXMvI3trZXlfZGF0YVsnaWQnXX0vZXhwb3J0IgogICAgICBdCiAgICAgIAogICAgICBwYXRoc190b190cnkuZWFjaCBkbyB8cGF0aHwKICAgICAgICBiZWdpbgogICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogVHJ5aW5nICN7cGF0aH0uLi4iCiAgICAgICAgICBkb3dubG9hZF9yZXNwID0gY2xpZW50LnJlcXVlc3QoOmdldCkgZG8gfHJlcXwKICAgICAgICAgICAgcmVxLnVybCBwYXRoCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydBY2NlcHQnXSA9ICdhcHBsaWNhdGlvbi92bmQuYXBpK2pzb24sIGFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCwgKi8qOyBxPTAuMDEnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgICAgIHJlcS5oZWFkZXJzWydSZWZlcmVyJ10gPSAnaHR0cHM6Ly9hcHBzdG9yZWNvbm5lY3QuYXBwbGUuY29tL2FjY2Vzcy9hcGknCiAgICAgICAgICBlbmQKICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJlc3BvbnNlIENsYXNzOiAje2Rvd25sb2FkX3Jlc3AuYm9keS5jbGFzc30iCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBTdGF0dXM6ICN7ZG93bmxvYWRfcmVzcC5zdGF0dXN9IiBpZiBkb3dubG9hZF9yZXNwLnJlc3BvbmRfdG8/KDpzdGF0dXMpCiAgICAgICAgICAKICAgICAgICAgIGlmIGRvd25sb2FkX3Jlc3AuYm9keSAmJiAhZG93bmxvYWRfcmVzcC5ib2R5LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKQogICAgICAgICAgICAgaWYgZG93bmxvYWRfcmVzcC5ib2R5LmlzX2E/KEhhc2gpCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHlbJ2tleUNvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHlbJ2NvbnRlbnQnXSB8fCBkb3dubG9hZF9yZXNwLmJvZHkuZGlnKCdkYXRhJywgJ2F0dHJpYnV0ZXMnLCAncHJpdmF0ZUtleScpCiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgIHA4X2NvbnRlbnQgPSBkb3dubG9hZF9yZXNwLmJvZHkKICAgICAgICAgICAgIGVuZAogICAgICAgICAgICAgCiAgICAgICAgICAgICBpZiBwOF9jb250ZW50ICYmIHA4X2NvbnRlbnQudG9fcy5zdGFydF93aXRoPygnLS0tLS1CRUdJTicpCiAgICAgICAgICAgICAgICRzdGRlcnIucHV0cyAiREVCVUc6IFJldHJpZXZhbCB2aWEgI3twYXRofSBzdWNjZXNzZnVsISBDb250ZW50IGxlbmd0aDogI3twOF9jb250ZW50LnRvX3MubGVuZ3RofSIKICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogUmVzcG9uc2UgZnJvbSAje3BhdGh9IGRpZCBub3QgY29udGFpbiBhIHZhbGlkIHByaXZhdGUga2V5LiIKICAgICAgICAgICAgICAgcDhfY29udGVudCA9IG5pbAogICAgICAgICAgICAgZW5kCiAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBSZXNwb25zZSBmcm9tICN7cGF0aH0gZW1wdHkgb3IgY29udGFpbnMgZXJyb3JzLiIKICAgICAgICAgIGVuZAogICAgICAgIHJlc2N1ZSA9PiBlCiAgICAgICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBBdHRlbXB0IGZvciAje3BhdGh9IGZhaWxlZDogI3tlLm1lc3NhZ2V9IgogICAgICAgIGVuZAogICAgICBlbmQKICAgIGVuZAoKICAgICMgRklOQUwgVkFMSURBVElPTjogRW5zdXJlIGl0J3Mgbm90IGEgUnVieSBoYXNoIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBlcnJvcgogICAgaWYgcDhfY29udGVudC5pc19hPyhIYXNoKSB8fCBwOF9jb250ZW50LnRvX3MuaW5jbHVkZT8oJyJlcnJvcnMiPT4nKSB8fCAhcDhfY29udGVudC50b19zLnN0YXJ0X3dpdGg/KCctLS0tLUJFR0lOJykKICAgICAgJHN0ZGVyci5wdXRzICJERUJVRzogSW52YWxpZCBrZXkgY29udGVudCBkZXRlY3RlZC4iCiAgICAgIHA4X2NvbnRlbnQgPSBuaWwKICAgIGVuZAoKICAgIGlmIHA4X2NvbnRlbnQubmlsPwogICAgICAkc3RkZXJyLnB1dHMgIkRFQlVHOiBGYWlsZWQgdG8gcmV0cmlldmUga2V5IGNvbnRlbnQuIgogICAgZW5kCiAgICAKICAgIHJlc3VsdCA9IHsKICAgICAgaWQ6IGtleV9kYXRhWydpZCddLAogICAgICBuYW1lOiBhdHRyWyduaWNrbmFtZSddIHx8IGF0dHJbJ25hbWUnXSwKICAgICAgaXNzdWVySWQ6IGF0dHJbJ2lzc3VlcklkJ10sCiAgICAgIGtleUNvbnRlbnQ6IHA4X2NvbnRlbnQsCiAgICAgIHJhd19yZXNwb25zZTogcmVzcG9uc2UuYm9keSAjIEluY2x1ZGUgdGhpcyBmb3IgZGVidWdnaW5nIHdoZW4ga2V5Q29udGVudCBpcyBuaWwKICAgIH0KICAgIAogICAgcHV0cyAiX19fTUFDSF9KU09OX1NUQVJUX19fIiArIHJlc3VsdC50b19qc29uICsgIl9fX01BQ0hfSlNPTl9FTkRfX18iCiAgcmVzY3VlID0+IGUKICAgICRzdGRlcnIucHV0cyAiRVJST1I6ICN7ZS5tZXNzYWdlfSIKICAgIGlmIGRlZmluZWQ/KHJlc3BvbnNlKSAmJiByZXNwb25zZSAmJiByZXNwb25zZS5ib2R5CiAgICAgICAkc3RkZXJyLnB1dHMgIlJlc3BvbnNlIEJvZHk6ICN7cmVzcG9uc2UuYm9keS50b19qc29ufSIKICAgIGVuZAogICAgZXhpdCAxCiAgZW5kCmVuZAoKZGVmIGRlbGV0ZV9rZXkoaWQpCiAgYmVnaW4KICAgIFNwYWNlc2hpcDo6UG9ydGFsLmxvZ2luKEVOVlsnRkFTVExBTkVfVVNFUiddKQogICAgU3BhY2VzaGlwOjpQb3J0YWwuc2VsZWN0X3RlYW0odGVhbV9pZDogRU5WWydGQVNUTEFORV9URUFNX0lEJ10pCiAgICAKICAgIFNwYWNlc2hpcDo6VHVuZXMubG9naW4oRU5WWydGQVNUTEFORV9VU0VSJ10pCiAgICBzZWxlY3RfYXBwX3N0b3JlX2Nvbm5lY3RfdGVhbQogICAgCiAgICBjbGllbnQgPSBTcGFjZXNoaXA6OlR1bmVzLmNsaWVudAogICAgY2xpZW50LnJlcXVlc3QoOmRlbGV0ZSwgIi9pcmlzL3YxL2FwaUtleXMvI3tpZH0iKQogICAgcHV0cyAiU1VDQ0VTUyIKICByZXNjdWUgPT4gZQogICAgJHN0ZGVyci5wdXRzICJFUlJPUjogI3tlLm1lc3NhZ2V9IgogICAgZXhpdCAxCiAgZW5kCmVuZAoKY29tbWFuZCA9IEFSR1ZbMF0KaWYgY29tbWFuZCA9PSAnbGlzdCcKICBsaXN0X2tleXMKZWxzaWYgY29tbWFuZCA9PSAndGVhbXMnCiAgbGlzdF90ZWFtcwplbHNpZiBjb21tYW5kID09ICdjcmVhdGUnCiAgY3JlYXRlX2tleShBUkdWWzFdIHx8ICJNYWNoIEFQSSBLZXkgI3tUaW1lLm5vdy50b19pfSIpCmVsc2lmIGNvbW1hbmQgPT0gJ2RlbGV0ZScKICBkZWxldGVfa2V5KEFSR1ZbMV0pCmVuZAo=";function Mn(){let e=$e.join(Ln.tmpdir(),A.nameLower);Ae.existsSync(e)||Ae.mkdirSync(e,{recursive:!0});let t=$e.join(e,"manage_asc_keys.rb");return Ae.writeFileSync(t,Buffer.from(ns,"base64").toString("utf-8"),{mode:493}),t}function Vn(){return St()}function Un(e){let t=new Map,n=/-\s+(\d+)\s+\(([^)]+)\)/g,i=/\d+\)\s+"([^"]+)"\s+\((\d+)\)/g,r;for(;(r=n.exec(e))!==null;)t.set(r[1],{id:r[1],name:r[2]});for(;(r=i.exec(e))!==null;)t.set(r[2],{id:r[2],name:r[1]});return Array.from(t.values())}function Mi(e,t=Ge(e,"store","production")){return Vt(e,t).appStoreConnectTeamId}function Vi(e,t,n){return{...Vn(),FASTLANE_USER:e,FASTLANE_TEAM_ID:t,...n?{FASTLANE_ITC_TEAM_ID:n,FASTLANE_ASC_TEAM_ID:n}:{}}}function pt(e,t=Ge(e,"store","production"),n={}){let i=Vt(e,t),r=n.teamId||i.teamId,o=n.appStoreConnectTeamId||i.appStoreConnectTeamId;return{teamId:r,teamName:n.teamName||i.teamName,developerTeamId:n.developerTeamId||i.developerTeamId||r,appStoreConnectTeamId:o,providerId:n.providerId||i.providerId||o,providerName:n.providerName||i.providerName}}function is(e,t,n=Ge(e,"store","production")){if(!t.id)return;e.submit||(e.submit={}),e.submit[n]||(e.submit[n]={}),e.submit[n].ios||(e.submit[n].ios={});let i=e.submit[n].ios;i.appStoreConnectTeamId=t.id,delete i.providerId,delete i.appStoreConnectTeamName,delete i.providerName,delete i.appleTeamName}function Wn(e,t,n){is(e,t,n);try{Ae.writeFileSync(`./${A.configFileName}`,JSON.stringify(e,null,2))}catch{}}async function rs(e,t,n,i,r){let o=Ct();o.start("Fetching App Store Connect providers...");let s=jt("ruby",[e,"teams"],{env:Vi(n,i),stdio:["inherit","pipe","pipe"],encoding:"utf-8"});if(s.status!==0){o.stop("Could not fetch providers");let p=Un(`${s.stdout||""}
3
+ ${s.stderr||""}`);if(p.length>0)return Bn(t,p,"Select the App Store Connect provider for this API key:",void 0,r);ie.warn(fe.yellow(`Could not list App Store Connect providers: ${s.stderr||"Unknown error"}`));return}let a=(s.stdout||"").match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!a){o.stop("Could not parse providers");return}let l=JSON.parse(a[1]),c=(l.teams||[]).filter(p=>p.id&&p.name);if(o.stop(c.length===1?"Found 1 provider":`Found ${c.length} providers`),c.length===0)return;if(c.length===1){ie.success(fe.green(`\u2713 Using App Store Connect provider ${c[0].name} (${c[0].id})`));let p={...c[0],developerTeamName:l.developerTeamName};return Wn(t,p,r),p}let d=c.filter(p=>p.recommended),u=c.filter(p=>!p.recommended);return Bn(t,[...d,...u],`Select the App Store Connect provider for Developer Team ${l.developerTeamName||i}:`,l.developerTeamName,r)}async function Bn(e,t,n,i,r){let o=await ft({message:n,options:t.map(c=>({value:c.id,label:c.name,hint:`${c.id}${c.recommended?" \xB7 recommended":""}`}))});if(Ce(o))return Fe("Operation cancelled"),null;let s=o,l={...t.find(c=>c.id===s)||{id:s,name:s},developerTeamName:i};return Wn(e,l,r),ie.success(fe.green(`\u2713 Using App Store Connect provider ${l.name} (${l.id})`)),l}var Lt=e=>typeof e=="string"&&e.trim()?e.trim():void 0,Fi=e=>Lt(e)?.toUpperCase();function os(e,t){let n=Fi(t.developerTeamId||t.teamId),i=Lt(t.appStoreConnectTeamId||t.providerId);return e.filter(r=>{let o=Fi(r.teamId),s=Lt(r.appStoreConnectTeamId||r.providerId);return!(n&&o!==n||i&&s!==i)})}function Dn(e){let t=Lt(e.name)||"App Store Connect API key",n=Lt(e.sourceProjectName)||e.sourceProjectId;return`${t} \xB7 ${n}`}function ss(e){return[e.teamId?`Apple Team ${e.teamId}`:void 0,e.appStoreConnectTeamId||e.providerId?`ASC provider ${e.appStoreConnectTeamId||e.providerId}`:void 0,e.keyId?`Key ${e.keyId}`:void 0].filter(Boolean).join(" \xB7 ")}async function as(e,t,n){let i=pt(t,n),r=i.developerTeamId||i.teamId,o=i.appStoreConnectTeamId||i.providerId;if(!r){ie.error(`Set ios.appleTeamId or submit.${n}.ios.appleTeamId in ${A.configFileName} before reusing an App Store Connect API key.`);return}let s=Ct(),a=[];try{s.start("Looking for compatible saved App Store Connect API keys...");let d=await U.get("/credentials/reusable",{params:{projectId:e,type:"asc_api_key"}});a=os(Array.isArray(d.data?.credentials)?d.data.credentials:[],i),s.stop(a.length===1?"Found 1 compatible saved API key":`Found ${a.length} compatible saved API keys`)}catch(d){s.stop("Could not load saved API keys"),ie.error(`Could not load reusable App Store Connect API keys: ${d.response?.data?.message||d.message}. You need administrator access to this project and the source project.`);return}if(a.length===0){let d=o?`Apple Team ${r} and App Store Connect provider ${o}`:`Apple Team ${r}`;ie.info(`No compatible saved API keys were found for ${d}.`);return}let l=await ft({message:"Select a saved App Store Connect API key to reuse:",options:[...a.map((d,u)=>({value:String(u),label:Dn(d),hint:ss(d)})),{value:"cancel",label:"Cancel"}]});if(Ce(l)||l==="cancel"){Fe("Operation cancelled");return}let c=a[Number(l)];if(!c){ie.error("The selected App Store Connect API key is no longer available.");return}try{s.start(`Copying ${Dn(c)} into this project...`),await U.post("/credentials/reuse",{projectId:e,sourceProjectId:c.sourceProjectId,credentialId:c.credentialId,type:"asc_api_key"}),s.stop("Saved API key copied to this project");let d=c.appStoreConnectTeamId||c.providerId;d&&Wn(t,{id:d,name:c.providerName||d},n),ie.success(fe.green(`\u2713 Reused ${Dn(c)} for this project.`))}catch(d){s.stop("Could not reuse saved API key"),ie.error(`Could not reuse the selected App Store Connect API key: ${d.response?.data?.message||d.message}.`)}}var Bi=async e=>{let t=Ct(),n=e.platform,i=`./${A.configFileName}`;if(!Ae.existsSync(i)){ie.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(Ae.readFileSync(i,"utf-8")),{projectId:o}=r,s=e.profile||Ge(r,"store","production");if(!o){ie.error(`${A.configFileName} is missing projectId.`);return}let a=e.file,l=n==="android"?e.packageName||e.bundleId:e.bundleId||nt(r,s)||"*";if(n==="android"&&!l&&(l=await cs(o,r,s),l===null))return;if(n==="ios"&&!a){let p=await ft({message:"Manage App Store Connect API Key:",options:[{value:"magic",label:"\u2728 Create new automatically",hint:"Requires Apple ID + 2FA"},{value:"reuse",label:"\u267B\uFE0F Use a saved API Key",hint:"Copy a compatible key from another Mach project"},{value:"manual",label:"\u{1F50D} Configure manually",hint:"Provide existing .p8 file"},{value:"delete",label:"\u{1F5D1}\uFE0F Delete an existing Key"}]});if(Ce(p)){Fe("Operation cancelled");return}if(p==="magic"){await us(o,r,s);return}if(p==="reuse"){await as(o,r,s);return}if(p==="delete"){await ps(o,r,s);return}}if(!a){let p=n==="ios"?"https://appstoreconnect.apple.com/access/api":"https://console.cloud.google.com/apis/credentials";rn(`To submit to the ${n==="ios"?"App Store":"Google Play Store"}, you need a Service Key:
4
4
 
5
5
  1. Open: ${fe.cyan(p)}
6
6
  `+(n==="ios"?`2. Generate an "App Store Connect API Key" with ${fe.bold("Admin")} role.
7
7
  3. Download the ${fe.bold(".p8")} file.`:`2. Create a "Service Account", generate a ${fe.bold("JSON")} key.
8
- 3. Download the ${fe.bold(".json")} file.`),"Guided Setup"),t.start("Scanning for downloaded keys...");let f=us(n);if(t.stop(f.length>0?`Detected ${f.length} potential key(s)`:"No keys detected automatically"),f.length>0){let m=await ft({message:"Found these potential keys. Use one of them?",options:[...f.map(E=>({value:E.path,label:`${_e.basename(E.path)} (${E.location})`})),{value:"manual",label:"Enter path manually..."}]});if(we(m)){Oe("Operation cancelled");return}m!=="manual"&&(a=m)}if(!a){let m=await He({message:`Paste the path to your ${n==="ios"?".p8":".json"} file:`,validate:E=>Ie.existsSync(E)?void 0:"File not found"});if(we(m)){Oe("Operation cancelled");return}a=m}}let c=e.issuerId,d=e.keyId;if(n==="ios"){if(!d&&a){let p=_e.basename(a).match(/AuthKey_(.*)\.p8/);p&&(d=p[1],ie.info(`Auto-detected Key ID from filename: ${fe.green(d)}`))}if(!c){let p=await He({message:"Enter App Store Connect Issuer ID (Found on the Keys page):",validate:f=>f.length>0?void 0:"Issuer ID is required"});if(we(p)){Oe("Operation cancelled");return}c=p}if(!d){let p=await He({message:"Enter App Store Connect Key ID:",validate:f=>f.length>0?void 0:"Key ID is required"});if(we(p)){Oe("Operation cancelled");return}d=p}}if(n==="android"&&(!l||l==="*")){let p=await ji();if(p===null)return;l=p}let u=n==="ios"?pt(r,s):{};await jn(o,a,n,c,d,l,{...u})};async function ss(e,t,n){let i=await as(e),r=cs(t,n);if(r&&!i.includes(r)&&i.unshift(r),i.length>0){let o=await ft({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(we(o))return Oe("Operation cancelled"),null;if(o==="manual")return ji();if(o!=="manual")return o}if(r){let o=await Di({message:`Use Android package from local config (${r})?`,initialValue:!0});if(we(o))return Oe("Operation cancelled"),null;if(o)return r}}async function ji(){let e=await He({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 we(e)?(Oe("Operation cancelled"),null):e}async function as(e){try{let n=(await U.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 ie.warn(fe.yellow(`Could not fetch saved Android package identifiers: ${t.message}`)),[]}}function cs(e,t){let n=bt(e,t);if(n)return n;let i=_e.join(process.cwd(),"app.json");if(Ie.existsSync(i))try{return JSON.parse(Ie.readFileSync(i,"utf-8")).expo?.android?.package}catch{}let r=_e.join(process.cwd(),"app.config.json");if(Ie.existsSync(r))try{let o=JSON.parse(Ie.readFileSync(r,"utf-8"));return o.expo?.android?.package||o.android?.package}catch{}}async function ls(e,t,n){let i=wt(),r=t.submit?.[n]?.ios?.appleId||t.submit?.production?.ios?.appleId,o=pt(t,n).teamId,s=Mi(t,n);if(!r){let c=await He({message:"Apple ID:",placeholder:"your-email@example.com"});if(we(c))return;r=c}if(!o){let c=await Vt({appleId:r,config:t,profile:n,initialTeam:pt(t,n),promptToPersistConfig:!0});if(!c?.teamId)return;o=c.teamId}let a=await He({message:"Enter a name for the new API Key:",initialValue:`[${A.name}] Project ${e}`});if(we(a))return;let l=Mn();if(!Ie.existsSync(l)){ie.error(`Magic Error: Helper script not found at ${l}`);return}try{let c=await ns(l,t,r,o,n);if(c===null)return;let d;if(c)d=c,s=c.id;else if(!s)return;i.start("Creating App Store Connect API Key...");let u=b=>jt("ruby",[l,"create",a],{env:Bi(r,o,b),stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),p=u(s),f=p.stdout||"",m=p.stderr||"";if(p.status!==0){let b=Un(`${f}
9
- ${m}`);if(b.length>0){i.stop("Select App Store Connect team"),rn(`Apple Developer Team IDs look like ${fe.bold(o)}.
10
- App Store Connect API keys use a numeric provider/team ID instead.`,"Team ID mismatch");let k=await Vn(t,b,"Select the App Store Connect provider for this API key:");if(!k)return;d=k,s=k.id,i.start("Creating API Key with selected App Store Connect team..."),p=u(s),f=p.stdout||"",m=p.stderr||""}}if(m&&(m.includes("DEBUG:")||m.includes("ERROR:"))&&m.split(`
11
- `).forEach(b=>{b.trim()&&ie.info(fe.dim(`[Ruby] ${b.trim()}`))}),p.status!==0){i.stop("Failed"),ie.error(`Magic creation failed: ${m}`);return}let E=f.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!E){i.stop("Parse Error"),ie.error("Could not parse response from Apple Portal.");return}let v=JSON.parse(E[1]),{id:P,issuerId:F,keyContent:C}=v,N=pt(t,n,{teamId:o,teamName:d?.developerTeamName,developerTeamId:o,appStoreConnectTeamId:s,providerId:s,providerName:d?.name});if(i.stop("Key Created Successfully"),ie.success(`\u2713 Created Key ID: ${fe.green(P)}`),!F){rn(`Your Issuer ID is shown at the top of:
8
+ 3. Download the ${fe.bold(".json")} file.`),"Guided Setup"),t.start("Scanning for downloaded keys...");let f=fs(n);if(t.stop(f.length>0?`Detected ${f.length} potential key(s)`:"No keys detected automatically"),f.length>0){let m=await ft({message:"Found these potential keys. Use one of them?",options:[...f.map(P=>({value:P.path,label:`${$e.basename(P.path)} (${P.location})`})),{value:"manual",label:"Enter path manually..."}]});if(Ce(m)){Fe("Operation cancelled");return}m!=="manual"&&(a=m)}if(!a){let m=await He({message:`Paste the path to your ${n==="ios"?".p8":".json"} file:`,validate:P=>Ae.existsSync(P)?void 0:"File not found"});if(Ce(m)){Fe("Operation cancelled");return}a=m}}let c=e.issuerId,d=e.keyId;if(n==="ios"){if(!d&&a){let p=$e.basename(a).match(/AuthKey_(.*)\.p8/);p&&(d=p[1],ie.info(`Auto-detected Key ID from filename: ${fe.green(d)}`))}if(!c){let p=await He({message:"Enter App Store Connect Issuer ID (Found on the Keys page):",validate:f=>f.length>0?void 0:"Issuer ID is required"});if(Ce(p)){Fe("Operation cancelled");return}c=p}if(!d){let p=await He({message:"Enter App Store Connect Key ID:",validate:f=>f.length>0?void 0:"Key ID is required"});if(Ce(p)){Fe("Operation cancelled");return}d=p}}if(n==="android"&&(!l||l==="*")){let p=await ji();if(p===null)return;l=p}let u=n==="ios"?pt(r,s):{};await jn(o,a,n,c,d,l,{...u})};async function cs(e,t,n){let i=await ls(e),r=ds(t,n);if(r&&!i.includes(r)&&i.unshift(r),i.length>0){let o=await ft({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(Ce(o))return Fe("Operation cancelled"),null;if(o==="manual")return ji();if(o!=="manual")return o}if(r){let o=await Di({message:`Use Android package from local config (${r})?`,initialValue:!0});if(Ce(o))return Fe("Operation cancelled"),null;if(o)return r}}async function ji(){let e=await He({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 Ce(e)?(Fe("Operation cancelled"),null):e}async function ls(e){try{let n=(await U.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 ie.warn(fe.yellow(`Could not fetch saved Android package identifiers: ${t.message}`)),[]}}function ds(e,t){let n=bt(e,t);if(n)return n;let i=$e.join(process.cwd(),"app.json");if(Ae.existsSync(i))try{return JSON.parse(Ae.readFileSync(i,"utf-8")).expo?.android?.package}catch{}let r=$e.join(process.cwd(),"app.config.json");if(Ae.existsSync(r))try{let o=JSON.parse(Ae.readFileSync(r,"utf-8"));return o.expo?.android?.package||o.android?.package}catch{}}async function us(e,t,n){let i=Ct(),r=t.submit?.[n]?.ios?.appleId||t.submit?.production?.ios?.appleId,o=pt(t,n).teamId,s=Mi(t,n);if(!r){let c=await He({message:"Apple ID:",placeholder:"your-email@example.com"});if(Ce(c))return;r=c}if(!o){let c=await Bt({appleId:r,config:t,profile:n,initialTeam:pt(t,n),promptToPersistConfig:!0});if(!c?.teamId)return;o=c.teamId}let a=await He({message:"Enter a name for the new API Key:",initialValue:`[${A.name}] Project ${e}`});if(Ce(a))return;let l=Mn();if(!Ae.existsSync(l)){ie.error(`Magic Error: Helper script not found at ${l}`);return}try{let c=await rs(l,t,r,o,n);if(c===null)return;let d;if(c)d=c,s=c.id;else if(!s)return;i.start("Creating App Store Connect API Key...");let u=S=>jt("ruby",[l,"create",a],{env:Vi(r,o,S),stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),p=u(s),f=p.stdout||"",m=p.stderr||"";if(p.status!==0){let S=Un(`${f}
9
+ ${m}`);if(S.length>0){i.stop("Select App Store Connect team"),rn(`Apple Developer Team IDs look like ${fe.bold(o)}.
10
+ App Store Connect API keys use a numeric provider/team ID instead.`,"Team ID mismatch");let _=await Bn(t,S,"Select the App Store Connect provider for this API key:");if(!_)return;d=_,s=_.id,i.start("Creating API Key with selected App Store Connect team..."),p=u(s),f=p.stdout||"",m=p.stderr||""}}if(m&&(m.includes("DEBUG:")||m.includes("ERROR:"))&&m.split(`
11
+ `).forEach(S=>{S.trim()&&ie.info(fe.dim(`[Ruby] ${S.trim()}`))}),p.status!==0){i.stop("Failed"),ie.error(`Magic creation failed: ${m}`);return}let P=f.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!P){i.stop("Parse Error"),ie.error("Could not parse response from Apple Portal.");return}let v=JSON.parse(P[1]),{id:R,issuerId:O,keyContent:C}=v,x=pt(t,n,{teamId:o,teamName:d?.developerTeamName,developerTeamId:o,appStoreConnectTeamId:s,providerId:s,providerName:d?.name});if(i.stop("Key Created Successfully"),ie.success(`\u2713 Created Key ID: ${fe.green(R)}`),!O){rn(`Your Issuer ID is shown at the top of:
12
12
  ${fe.cyan("https://appstoreconnect.apple.com/access/integrations/api")}
13
13
 
14
- It looks like: ${fe.dim("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")}`,"One More Thing");let b=await He({message:"Enter your App Store Connect Issuer ID:",validate:k=>k.trim().length>0?void 0:"Issuer ID is required"});if(we(b)){Oe("Operation cancelled.");return}F=b.trim()}if(C){let b=_e.join(Ln.tmpdir(),`AuthKey_${P}.p8`);Ie.writeFileSync(b,C),await jn(e,b,"ios",F,P,t.ios?.bundleIdentifier||"*",{...N}),Ie.unlinkSync(b)}else{ie.warn(fe.yellow("\u26A0\uFE0F Apple did not return the private key in the response.")),rn(`Download the .p8 file manually:
14
+ It looks like: ${fe.dim("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")}`,"One More Thing");let S=await He({message:"Enter your App Store Connect Issuer ID:",validate:_=>_.trim().length>0?void 0:"Issuer ID is required"});if(Ce(S)){Fe("Operation cancelled.");return}O=S.trim()}if(C){let S=$e.join(Ln.tmpdir(),`AuthKey_${R}.p8`);Ae.writeFileSync(S,C),await jn(e,S,"ios",O,R,t.ios?.bundleIdentifier||"*",{...x}),Ae.unlinkSync(S)}else{ie.warn(fe.yellow("\u26A0\uFE0F Apple did not return the private key in the response.")),rn(`Download the .p8 file manually:
15
15
 
16
16
  1. Open: ${fe.cyan("https://appstoreconnect.apple.com/access/integrations/api")}
17
- 2. Find Key ID: ${fe.green(P)}
17
+ 2. Find Key ID: ${fe.green(R)}
18
18
  3. Click ${fe.bold("Download API Key")} (only available once)
19
- 4. Drag & drop the downloaded .p8 file below`,"Manual Step Required");let b=await He({message:"Path to the downloaded .p8 file (drag & drop here):",validate:k=>Ie.existsSync(k)?void 0:"File not found"});if(we(b)){Oe("Operation cancelled. Credential ID was registered but key content is missing.");return}await jn(e,b,"ios",F,P,t.ios?.bundleIdentifier||"*",{...N})}}catch(c){i.stop("Error"),ie.error(`Error: ${c.message}`)}}async function ds(e,t,n){let i=wt(),r=t.submit?.[n]?.ios?.appleId||t.submit?.production?.ios?.appleId,o=pt(t,n).teamId,s=Mi(t,n);if(!r){let l=await He({message:"Apple ID:"});if(we(l))return;r=l}if(!o){let l=await Vt({appleId:r,config:t,profile:n,initialTeam:pt(t,n),promptToPersistConfig:!0});if(!l?.teamId)return;o=l.teamId}i.start("Fetching existing API Keys...");let a=Mn();if(!Ie.existsSync(a)){ie.error(`Magic Error: Helper script not found at ${a}`);return}try{let l=E=>jt("ruby",[a,"list"],{env:{...Bn(),FASTLANE_USER:r,FASTLANE_TEAM_ID:o,...E?{FASTLANE_ITC_TEAM_ID:E,FASTLANE_ASC_TEAM_ID:E}:{}},stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),c=l(s);if(c.status!==0){let E=Un(`${c.stdout||""}
20
- ${c.stderr||""}`);if(E.length>0){i.stop("Select App Store Connect team");let v=await ft({message:"Select the App Store Connect team to list API keys:",options:E.map(P=>({value:P.id,label:P.name,hint:P.id}))});if(we(v)){Oe("Operation cancelled");return}s=v,i.start("Fetching existing API Keys..."),c=l(s)}}if(c.status!==0){i.stop("Failed"),ie.error(`Listing failed: ${c.stderr}`);return}let d=c.stdout.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!d){i.stop("Parse Error");return}let u=JSON.parse(d[1]);if(i.stop(`Found ${u.length} keys`),u.length===0){ie.info("No API Keys found on this team.");return}let p=await ft({message:"Select a key to delete from Apple Developer Portal:",options:[...u.map(E=>({value:E.id,label:`ID: ${E.id} - ${E.name} (${E.role})`})),{value:"cancel",label:"Cancel"}]});if(we(p)||p==="cancel")return;let f=await Di({message:`Are you sure you want to delete Key ${p}? This cannot be undone.`});if(!f||we(f))return;i.start(`Deleting Key ${p}...`);let m=jt("ruby",[Mn(),"delete",p],{env:{...Bn(),FASTLANE_USER:r,FASTLANE_TEAM_ID:o,...s?{FASTLANE_ITC_TEAM_ID:s,FASTLANE_ASC_TEAM_ID:s}:{}},stdio:"pipe",encoding:"utf-8"});m.status===0?(i.stop("Deleted"),ie.success(`\u2713 Key ${p} has been removed from Apple Portal.`)):(i.stop("Deletion Failed"),ie.error(`Error: ${m.stderr}`))}catch(l){i.stop("Error"),ie.error(`Error: ${l.message}`)}}async function jn(e,t,n,i,r,o="*",s={}){let a=wt();a.start(`Uploading Service Credentials for ${n}...`);try{let l=n==="ios"?"asc_api_key":"google_service_account",c=new URL(import.meta.url),d=_e.dirname(c.pathname),u=[_e.join(d,"isolated-upload.js"),_e.join(d,"commands","isolated-upload.js"),_e.resolve(d,"../commands/isolated-upload.js"),_e.resolve(process.cwd(),`node_modules/.bin/${A.nameLower}-upload`)],p="";for(let m of u)if(Ie.existsSync(m)){p=m;break}if(!p)throw new Error("Could not locate isolated-upload.js. Ensure the CLI is properly installed.");let f=jt("node",[p,e,t,l,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(f.status!==0){let m=f.stderr||f.stdout||"Unknown upload failure";a.stop("Upload Failed"),ie.error(fe.red(`Upload Failed: ${m}`));return}f.stdout.includes("SUCCESS")?(a.stop("Upload Success"),ie.success(fe.green(`\u2713 Service Credentials for ${n} uploaded successfully.`))):(a.stop("Upload Summary"),ie.warn(fe.yellow(`Upload finished but success not confirmed: ${f.stdout}`)))}catch(l){a.stop("Upload Error"),ie.error(fe.red(`Error: ${l.message}`))}}function us(e){let t=e==="ios"?".p8":".json",n=[],i=[{path:"./",label:"Project Root"},{path:_e.join(Ln.homedir(),"Downloads"),label:"Downloads"}];for(let r of i)if(Ie.existsSync(r.path))try{let o=Ie.readdirSync(r.path);for(let s of o)if(s.endsWith(t)){if(e==="android"&&!Ie.readFileSync(_e.join(r.path,s),"utf8").includes("service_account")||e==="ios"&&!s.startsWith("AuthKey"))continue;n.push({path:_e.join(r.path,s),location:r.label})}}catch{}return n}import{spinner as An}from"@clack/prompts";import ae from"chalk";import{spawnSync as eo}from"child_process";import me from"fs";import Ee from"path";import H from"fs";import te from"path";var ps={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"]},fs=["lib/main.dart","lib/main_development.dart","lib/main_staging.dart","lib/main_production.dart"];function he(e,t){return te.relative(e,t).split(te.sep).join("/")}function Li(e,t){return t.find(n=>H.existsSync(te.join(e,n)))}function ms(e,t){return t.split(te.sep).join("/").startsWith("src/")?te.join(e,"src"):e}function gs(e){return e.endsWith(".ts")||e.endsWith(".tsx")}function hs(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 ys(e,t){let n=H.readFileSync(e,"utf8");if(n.includes("MACH Push setup")||/(?:from\s+)?['"][^'"]*mach-push['"]/.test(n))return!1;let i=hs(e,t);return H.writeFileSync(e,`import '${i}'; // MACH Push setup
21
- ${n}`),!0}function Is(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 S=await He({message:"Path to the downloaded .p8 file (drag & drop here):",validate:_=>Ae.existsSync(_)?void 0:"File not found"});if(Ce(S)){Fe("Operation cancelled. Credential ID was registered but key content is missing.");return}await jn(e,S,"ios",O,R,t.ios?.bundleIdentifier||"*",{...x})}}catch(c){i.stop("Error"),ie.error(`Error: ${c.message}`)}}async function ps(e,t,n){let i=Ct(),r=t.submit?.[n]?.ios?.appleId||t.submit?.production?.ios?.appleId,o=pt(t,n).teamId,s=Mi(t,n);if(!r){let l=await He({message:"Apple ID:"});if(Ce(l))return;r=l}if(!o){let l=await Bt({appleId:r,config:t,profile:n,initialTeam:pt(t,n),promptToPersistConfig:!0});if(!l?.teamId)return;o=l.teamId}i.start("Fetching existing API Keys...");let a=Mn();if(!Ae.existsSync(a)){ie.error(`Magic Error: Helper script not found at ${a}`);return}try{let l=P=>jt("ruby",[a,"list"],{env:{...Vn(),FASTLANE_USER:r,FASTLANE_TEAM_ID:o,...P?{FASTLANE_ITC_TEAM_ID:P,FASTLANE_ASC_TEAM_ID:P}:{}},stdio:["inherit","pipe","pipe"],encoding:"utf-8"}),c=l(s);if(c.status!==0){let P=Un(`${c.stdout||""}
20
+ ${c.stderr||""}`);if(P.length>0){i.stop("Select App Store Connect team");let v=await ft({message:"Select the App Store Connect team to list API keys:",options:P.map(R=>({value:R.id,label:R.name,hint:R.id}))});if(Ce(v)){Fe("Operation cancelled");return}s=v,i.start("Fetching existing API Keys..."),c=l(s)}}if(c.status!==0){i.stop("Failed"),ie.error(`Listing failed: ${c.stderr}`);return}let d=c.stdout.match(new RegExp(`${A.jsonStartMarker}(.*)${A.jsonEndMarker}`));if(!d){i.stop("Parse Error");return}let u=JSON.parse(d[1]);if(i.stop(`Found ${u.length} keys`),u.length===0){ie.info("No API Keys found on this team.");return}let p=await ft({message:"Select a key to delete from Apple Developer Portal:",options:[...u.map(P=>({value:P.id,label:`ID: ${P.id} - ${P.name} (${P.role})`})),{value:"cancel",label:"Cancel"}]});if(Ce(p)||p==="cancel")return;let f=await Di({message:`Are you sure you want to delete Key ${p}? This cannot be undone.`});if(!f||Ce(f))return;i.start(`Deleting Key ${p}...`);let m=jt("ruby",[Mn(),"delete",p],{env:{...Vn(),FASTLANE_USER:r,FASTLANE_TEAM_ID:o,...s?{FASTLANE_ITC_TEAM_ID:s,FASTLANE_ASC_TEAM_ID:s}:{}},stdio:"pipe",encoding:"utf-8"});m.status===0?(i.stop("Deleted"),ie.success(`\u2713 Key ${p} has been removed from Apple Portal.`)):(i.stop("Deletion Failed"),ie.error(`Error: ${m.stderr}`))}catch(l){i.stop("Error"),ie.error(`Error: ${l.message}`)}}async function jn(e,t,n,i,r,o="*",s={}){let a=Ct();a.start(`Uploading Service Credentials for ${n}...`);try{let l=n==="ios"?"asc_api_key":"google_service_account",c=new URL(import.meta.url),d=$e.dirname(c.pathname),u=[$e.join(d,"isolated-upload.js"),$e.join(d,"commands","isolated-upload.js"),$e.resolve(d,"../commands/isolated-upload.js"),$e.resolve(process.cwd(),`node_modules/.bin/${A.nameLower}-upload`)],p="";for(let m of u)if(Ae.existsSync(m)){p=m;break}if(!p)throw new Error("Could not locate isolated-upload.js. Ensure the CLI is properly installed.");let f=jt("node",[p,e,t,l,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(f.status!==0){let m=f.stderr||f.stdout||"Unknown upload failure";a.stop("Upload Failed"),ie.error(fe.red(`Upload Failed: ${m}`));return}f.stdout.includes("SUCCESS")?(a.stop("Upload Success"),ie.success(fe.green(`\u2713 Service Credentials for ${n} uploaded successfully.`))):(a.stop("Upload Summary"),ie.warn(fe.yellow(`Upload finished but success not confirmed: ${f.stdout}`)))}catch(l){a.stop("Upload Error"),ie.error(fe.red(`Error: ${l.message}`))}}function fs(e){let t=e==="ios"?".p8":".json",n=[],i=[{path:"./",label:"Project Root"},{path:$e.join(Ln.homedir(),"Downloads"),label:"Downloads"}];for(let r of i)if(Ae.existsSync(r.path))try{let o=Ae.readdirSync(r.path);for(let s of o)if(s.endsWith(t)){if(e==="android"&&!Ae.readFileSync($e.join(r.path,s),"utf8").includes("service_account")||e==="ios"&&!s.startsWith("AuthKey"))continue;n.push({path:$e.join(r.path,s),location:r.label})}}catch{}return n}import{spinner as An}from"@clack/prompts";import ae from"chalk";import{spawnSync as no}from"child_process";import me from"fs";import Ee from"path";import H from"fs";import te from"path";var ms={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"]},gs=["lib/main.dart","lib/main_development.dart","lib/main_staging.dart","lib/main_production.dart"];function he(e,t){return te.relative(e,t).split(te.sep).join("/")}function Li(e,t){return t.find(n=>H.existsSync(te.join(e,n)))}function hs(e,t){return t.split(te.sep).join("/").startsWith("src/")?te.join(e,"src"):e}function ys(e){return e.endsWith(".ts")||e.endsWith(".tsx")}function Is(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 As(e,t){let n=H.readFileSync(e,"utf8");if(n.includes("MACH Push setup")||/(?:from\s+)?['"][^'"]*mach-push['"]/.test(n))return!1;let i=Is(e,t);return H.writeFileSync(e,`import '${i}'; // MACH Push setup
21
+ ${n}`),!0}function bs(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 As(e,t){return t?`/**
27
+ `}function Ss(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 Ui(e,t,n){let i=[],r=[],o=Li(e,ps[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=ms(e,o),l=gs(o)?"ts":"js",c=l==="ts",d=te.join(a,`mach-push.generated.${l}`),u=te.join(a,`mach-push.${l}`);return H.mkdirSync(a,{recursive:!0}),H.writeFileSync(d,Is(n,c)),i.push(he(e,d)),H.existsSync(u)?r.push(`${he(e,u)} already exists; developer callbacks were preserved.`):(H.writeFileSync(u,As("./mach-push.generated",c)),i.push(he(e,u))),ys(s,u)?i.push(he(e,s)):r.push(`${he(e,s)} already starts MACH Push.`),{written:i,notes:r,editableFile:he(e,u),generatedFile:he(e,d),entryFile:he(e,s)}}function bs(e){let t=e.environment||"production",n=[e.appId?` appId: '${e.appId}',`:void 0,e.publishableKey?` publishableKey: '${e.publishableKey}',`:void 0,e.apiUrl&&e.apiUrl!=="https://mach-api.securejs.in"?` apiUrl: '${e.apiUrl}',`:void 0,t!=="production"?` environment: MachPushEnvironment.${t},`:void 0].filter(Boolean).join(`
140
+ `}function Ui(e,t,n){let i=[],r=[],o=Li(e,ms[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=hs(e,o),l=ys(o)?"ts":"js",c=l==="ts",d=te.join(a,`mach-push.generated.${l}`),u=te.join(a,`mach-push.${l}`);return H.mkdirSync(a,{recursive:!0}),H.writeFileSync(d,bs(n,c)),i.push(he(e,d)),H.existsSync(u)?r.push(`${he(e,u)} already exists; developer callbacks were preserved.`):(H.writeFileSync(u,Ss("./mach-push.generated",c)),i.push(he(e,u))),As(s,u)?i.push(he(e,s)):r.push(`${he(e,s)} already starts MACH Push.`),{written:i,notes:r,editableFile:he(e,u),generatedFile:he(e,d),entryFile:he(e,s)}}function Cs(e){let t=e.environment||"production",n=[e.appId?` appId: '${e.appId}',`:void 0,e.publishableKey?` publishableKey: '${e.publishableKey}',`:void 0,e.apiUrl&&e.apiUrl!=="https://mach-api.securejs.in"?` apiUrl: '${e.apiUrl}',`:void 0,t!=="production"?` environment: MachPushEnvironment.${t},`:void 0].filter(Boolean).join(`
141
141
  `);return`// Generated by \`mach push setup\`. Re-run the command to refresh.
142
142
  // Public client configuration only. Provider credentials are never written here.
143
143
  import 'package:mach_push_flutter/mach_push_flutter.dart';
@@ -146,7 +146,7 @@ const machPushConfig = MachPushConfig(
146
146
  projectId: '${e.projectId}',
147
147
  ${n?`${n}
148
148
  `:""});
149
- `}function Ss(){return`/**
149
+ `}function ws(){return`/**
150
150
  * MACH Push application hooks.
151
151
  *
152
152
  * This file belongs to your app and is never overwritten by
@@ -201,12 +201,12 @@ void onMachPushError(Object error) {
201
201
  print('[MACH Push] $error');
202
202
  }
203
203
 
204
- `}function ws(e,t){let n=H.readFileSync(e,"utf8"),i=!1,r=te.relative(te.dirname(e),t).split(te.sep).join("/"),o=r.startsWith(".")?r:`./${r}`;if(!n.includes(`import '${o}'`)&&!n.includes(`import "${o}"`)&&(n=`import '${o}'; // MACH Push setup
204
+ `}function vs(e,t){let n=H.readFileSync(e,"utf8"),i=!1,r=te.relative(te.dirname(e),t).split(te.sep).join("/"),o=r.startsWith(".")?r:`./${r}`;if(!n.includes(`import '${o}'`)&&!n.includes(`import "${o}"`)&&(n=`import '${o}'; // MACH Push setup
205
205
  ${n}`,i=!0),!n.includes("MACH Push startup")){let s=/((?:Future\s*<\s*void\s*>|void)\s+main\s*\([^)]*\)\s*(?:async\s*)?\{)/m;if(s.test(n))n=n.replace(s,`$1
206
206
  startMachPushInBackground(); // MACH Push startup`),i=!0;else{let a=/(void\s+main\s*\([^)]*\))\s*=>\s*([^;]+);/m;a.test(n)&&(n=n.replace(a,`$1 {
207
207
  startMachPushInBackground(); // MACH Push startup
208
208
  $2;
209
- }`),i=!0)}}return i&&H.writeFileSync(e,n),{changed:i,startupInjected:n.includes("MACH Push startup")}}function Wi(e,t,n){let i=[],r=[],o=n?.replace(/^\.\//,"").replace(/\\/g,"/");if(o&&!H.existsSync(te.join(e,o)))return{written:i,notes:[`Configured Flutter entrypoint ${o} does not exist.`]};let s=o||Li(e,fs);if(!s)return{written:i,notes:["Could not locate a Flutter lib/main*.dart entrypoint. Import lib/mach_push.dart once from your application entrypoint."]};let a=te.join(e,"lib"),l=te.join(a,"mach_push.generated.dart"),c=te.join(a,"mach_push.dart"),d=te.join(e,s);H.mkdirSync(a,{recursive:!0}),H.writeFileSync(l,bs(t)),i.push(he(e,l)),H.existsSync(c)?r.push(`${he(e,c)} already exists; developer callbacks were preserved.`):(H.writeFileSync(c,Ss()),i.push(he(e,c)));let u=ws(d,c);return u.changed?i.push(he(e,d)):u.startupInjected&&r.push(`${he(e,d)} already starts MACH Push.`),u.startupInjected||r.push(`Mach imported ${he(e,c)}, but could not safely patch main(). Call startMachPushInBackground() once during app startup.`),{written:i,notes:r,editableFile:he(e,c),generatedFile:he(e,l),entryFile:he(e,d)}}function Gi(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(...Gi(r,t)):t(r)&&n.push(r)}return n}function Cs(e,t){if(H.mkdirSync(te.dirname(e),{recursive:!0}),!H.existsSync(e)){H.writeFileSync(e,`<?xml version="1.0" encoding="UTF-8"?>
209
+ }`),i=!0)}}return i&&H.writeFileSync(e,n),{changed:i,startupInjected:n.includes("MACH Push startup")}}function Wi(e,t,n){let i=[],r=[],o=n?.replace(/^\.\//,"").replace(/\\/g,"/");if(o&&!H.existsSync(te.join(e,o)))return{written:i,notes:[`Configured Flutter entrypoint ${o} does not exist.`]};let s=o||Li(e,gs);if(!s)return{written:i,notes:["Could not locate a Flutter lib/main*.dart entrypoint. Import lib/mach_push.dart once from your application entrypoint."]};let a=te.join(e,"lib"),l=te.join(a,"mach_push.generated.dart"),c=te.join(a,"mach_push.dart"),d=te.join(e,s);H.mkdirSync(a,{recursive:!0}),H.writeFileSync(l,Cs(t)),i.push(he(e,l)),H.existsSync(c)?r.push(`${he(e,c)} already exists; developer callbacks were preserved.`):(H.writeFileSync(c,ws()),i.push(he(e,c)));let u=vs(d,c);return u.changed?i.push(he(e,d)):u.startupInjected&&r.push(`${he(e,d)} already starts MACH Push.`),u.startupInjected||r.push(`Mach imported ${he(e,c)}, but could not safely patch main(). Call startMachPushInBackground() once during app startup.`),{written:i,notes:r,editableFile:he(e,c),generatedFile:he(e,l),entryFile:he(e,d)}}function Gi(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(...Gi(r,t)):t(r)&&n.push(r)}return n}function Es(e,t){if(H.mkdirSync(te.dirname(e),{recursive:!0}),!H.existsSync(e)){H.writeFileSync(e,`<?xml version="1.0" encoding="UTF-8"?>
210
210
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
211
211
  <plist version="1.0">
212
212
  <dict>
@@ -216,20 +216,20 @@ ${n}`,i=!0),!n.includes("MACH Push startup")){let s=/((?:Future\s*<\s*void\s*>|v
216
216
  </plist>
217
217
  `);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>
218
218
  <string>${t}</string>
219
- </dict>`))}function vs(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=Gi(o,d=>d.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 l=H.readFileSync(a,"utf8"),c=Array.from(l.matchAll(/CODE_SIGN_ENTITLEMENTS\s*=\s*"?([^";$]+\.entitlements)"?;/g),d=>d[1].trim());if(c.length===0&&t){let d=te.basename(te.dirname(a),".xcodeproj"),p=[H.existsSync(te.join(o,d))?d:"",`${d}.entitlements`].filter(Boolean).join("/"),f=!1;l=l.replace(/buildSettings = \{([\s\S]*?)\n(\s*)\};/g,(m,E,v)=>!new RegExp(`PRODUCT_BUNDLE_IDENTIFIER\\s*=\\s*"?${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"?;`).test(E)||E.includes("CODE_SIGN_ENTITLEMENTS")?m:(f=!0,m.replace(/(\n\s*PRODUCT_BUNDLE_IDENTIFIER\s*=)/,`
220
- ${v} CODE_SIGN_ENTITLEMENTS = ${p};$1`))),f&&(H.writeFileSync(a,l),i.push(he(e,a)),c.push(p))}if(c.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 d of new Set(c)){let u=te.join(o,d);Cs(u,n),i.push(he(e,u))}return r.push(`iOS APNs entitlement is configured for ${n}.`),{written:[...new Set(i)],notes:r}}function Es(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")
219
+ </dict>`))}function Ps(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=Gi(o,d=>d.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 l=H.readFileSync(a,"utf8"),c=Array.from(l.matchAll(/CODE_SIGN_ENTITLEMENTS\s*=\s*"?([^";$]+\.entitlements)"?;/g),d=>d[1].trim());if(c.length===0&&t){let d=te.basename(te.dirname(a),".xcodeproj"),p=[H.existsSync(te.join(o,d))?d:"",`${d}.entitlements`].filter(Boolean).join("/"),f=!1;l=l.replace(/buildSettings = \{([\s\S]*?)\n(\s*)\};/g,(m,P,v)=>!new RegExp(`PRODUCT_BUNDLE_IDENTIFIER\\s*=\\s*"?${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"?;`).test(P)||P.includes("CODE_SIGN_ENTITLEMENTS")?m:(f=!0,m.replace(/(\n\s*PRODUCT_BUNDLE_IDENTIFIER\s*=)/,`
220
+ ${v} CODE_SIGN_ENTITLEMENTS = ${p};$1`))),f&&(H.writeFileSync(a,l),i.push(he(e,a)),c.push(p))}if(c.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 d of new Set(c)){let u=te.join(o,d);Es(u,n),i.push(he(e,u))}return r.push(`iOS APNs entitlement is configured for ${n}.`),{written:[...new Set(i)],notes:r}}function Rs(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")
221
221
  `:` id 'com.google.gms.google-services'
222
222
  `,o=i.index+i[0].length;H.writeFileSync(e,`${n.slice(0,o)}
223
223
  ${r}${n.slice(o)}`)}else{let r=t?`
224
224
  apply(plugin = "com.google.gms.google-services")
225
225
  `:`
226
226
  apply plugin: "com.google.gms.google-services"
227
- `;H.writeFileSync(e,`${n.trimEnd()}${r}`)}return!0}function Ps(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 l=/plugins\s*\{/.exec(a);if(l?.index!==void 0){let d=t.endsWith(".kts")?` id("com.google.gms.google-services") version "4.4.4" apply false
227
+ `;H.writeFileSync(e,`${n.trimEnd()}${r}`)}return!0}function Ns(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 l=/plugins\s*\{/.exec(a);if(l?.index!==void 0){let d=t.endsWith(".kts")?` id("com.google.gms.google-services") version "4.4.4" apply false
228
228
  `:` id "com.google.gms.google-services" version "4.4.4" apply false
229
229
  `,u=l.index+l[0].length;return H.writeFileSync(t,`${a.slice(0,u)}
230
230
  ${d}${a.slice(u)}`),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")
231
231
  `,s=r.index+r[0].length;return H.writeFileSync(n,`${i.slice(0,s)}
232
- ${o}${i.slice(s)}`),n}function Rs(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(he(e,s)));let a=["build.gradle.kts","build.gradle"].map(c=>te.join(r,"app",c)).find(c=>H.existsSync(c));if(!a)return i.push("Could not locate android/app/build.gradle to enable Firebase."),{written:n,notes:i};Es(a,a.endsWith(".kts"))&&n.push(he(e,a));let l=Ps(r);return l&&n.push(he(e,l)),i.push("Android Firebase configuration and notification permission are wired."),{written:[...new Set(n)],notes:i}}function Zi(e,t){let n=vs(e,t.iosBundleId,t.iosEnvironment),i=Rs(e,t.googleServicesFile);return{written:[...new Set([...n.written,...i.written])],notes:[...n.notes,...i.notes]}}import{spinner as yn,log as R,isCancel as In,confirm as _a,select as pi}from"@clack/prompts";import w from"chalk";import I from"fs";import y from"path";import{execFileSync as Qe,execSync as re,spawn as Br}from"child_process";import Ae from"os";import Vr from"crypto";import jr from"adm-zip";import Ms from"crypto";import{log as De}from"@clack/prompts";import Me from"chalk";import{execSync as xs}from"child_process";import Be from"fs";import it from"path";var Hi={id:"expo",displayName:"Expo",applyLocalProcessEnv:e=>{e.developmentClient?(De.info(Me.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):(De.info(Me.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:()=>`
232
+ ${o}${i.slice(s)}`),n}function xs(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(he(e,s)));let a=["build.gradle.kts","build.gradle"].map(c=>te.join(r,"app",c)).find(c=>H.existsSync(c));if(!a)return i.push("Could not locate android/app/build.gradle to enable Firebase."),{written:n,notes:i};Rs(a,a.endsWith(".kts"))&&n.push(he(e,a));let l=Ns(r);return l&&n.push(he(e,l)),i.push("Android Firebase configuration and notification permission are wired."),{written:[...new Set(n)],notes:i}}function Zi(e,t){let n=Ps(e,t.iosBundleId,t.iosEnvironment),i=xs(e,t.googleServicesFile);return{written:[...new Set([...n.written,...i.written])],notes:[...n.notes,...i.notes]}}import{spinner as yn,log as E,isCancel as In,confirm as Oa,select as pi}from"@clack/prompts";import w from"chalk";import I from"fs";import y from"path";import{execFileSync as Qe,execSync as re,spawn as jr}from"child_process";import ye from"os";import Lr from"crypto";import Ur from"adm-zip";import Bs from"crypto";import{log as De}from"@clack/prompts";import Me from"chalk";import{execSync as ks}from"child_process";import Ve from"fs";import it from"path";var Hi={id:"expo",displayName:"Expo",applyLocalProcessEnv:e=>{e.developmentClient?(De.info(Me.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):(De.info(Me.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:()=>`
233
233
  export MACH_FRAMEWORK="expo"
234
234
  echo "[ENV] MACH_FRAMEWORK=$MACH_FRAMEWORK"
235
235
  export EXPO_NO_DOTENV="\${EXPO_NO_DOTENV:-1}"
@@ -280,7 +280,7 @@ for (const file of files) {
280
280
  }
281
281
 
282
282
  if (!patched) {
283
- console.log('[VERSIONING] Generated Android Gradle versionCode was not found; relying on Gradle property injection.');
283
+ console.log('[VERSIONING] Generated Android Gradle versionCode was not found; the Android Variant API lock remains authoritative.');
284
284
  }
285
285
  NODE
286
286
  }
@@ -324,26 +324,26 @@ fi
324
324
  echo "expo.enableHermes=true" >> gradle.properties
325
325
  `,androidRemoteReleaseGradlePropertiesScript:()=>`
326
326
  echo "expo.enableProguardInReleaseBuilds=true" >> gradle.properties
327
- `,prepareLocalProject:async e=>{let{platform:t,options:n,appRoot:i,cacheMeta:r,cacheMetaDir:o,currentBuildEnv:s,reportStep:a,loggedRun:l,configureXcodeNodeBinary:c,podsFingerprint:d,writeCacheMeta:u}=e,p=n.iosBundleIdentifier||"",f=n.name||"",m=it.join(i,"app.json"),E=null;De.info(Me.blue(`Running Expo prebuild for ${t}...`));try{if(Be.existsSync(m)){E=Be.readFileSync(m,"utf-8");let P=JSON.parse(E);P.expo=P.expo||{},f||(f=P.expo.name||""),t==="ios"&&!p&&(p=P.expo?.ios?.bundleIdentifier||""),n.name&&(P.expo.name=n.name),n.scheme&&(P.expo.scheme=n.scheme),t==="ios"&&n.iosBundleIdentifier?(P.expo.ios=P.expo.ios||{},P.expo.ios.bundleIdentifier=n.iosBundleIdentifier):t==="android"&&n.androidPackage&&(P.expo.android=P.expo.android||{},P.expo.android.package=n.androidPackage),Be.writeFileSync(m,JSON.stringify(P,null,2))}let v=["exec","--","expo","prebuild","--platform",t,"--no-install"];if(await a("prebuild"),await l("npm",v,i,s()),t!=="ios"||!Be.existsSync(it.join(i,"ios")))return{appName:f,bundleId:p};await a("pods"),De.info(Me.blue("Running pod install..."));try{let P=it.join(i,"ios"),F=it.join(P,"Podfile");if(!Be.existsSync(F))throw new Error("ios/Podfile not found. Skipping pod install.");let C=s();c(P,C);let N=Be.readFileSync(F,"utf-8"),b=n.iosDeploymentTarget||"13.4";if(!n.developmentClient&&(De.info(Me.blue("\u2139\uFE0F Patching Podfile to EXCLUDE expo-dev-client...")),N.includes("use_expo_modules!")&&!N.includes("exclude:"))){let M=/use_expo_modules!(\s*)$/m;M.test(N)?N=N.replace(M,'use_expo_modules!(exclude: ["expo-dev-client"])$1'):N=N.replace("use_expo_modules!",'use_expo_modules!(exclude: ["expo-dev-client"])')}let k=`
327
+ `,prepareLocalProject:async e=>{let{platform:t,options:n,appRoot:i,cacheMeta:r,cacheMetaDir:o,currentBuildEnv:s,reportStep:a,loggedRun:l,configureXcodeNodeBinary:c,podsFingerprint:d,writeCacheMeta:u}=e,p=n.iosBundleIdentifier||"",f=n.name||"",m=it.join(i,"app.json"),P=null;De.info(Me.blue(`Running Expo prebuild for ${t}...`));try{if(Ve.existsSync(m)){P=Ve.readFileSync(m,"utf-8");let R=JSON.parse(P);R.expo=R.expo||{},f||(f=R.expo.name||""),t==="ios"&&!p&&(p=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),Ve.writeFileSync(m,JSON.stringify(R,null,2))}let v=["exec","--","expo","prebuild","--platform",t,"--no-install"];if(await a("prebuild"),await l("npm",v,i,s()),t!=="ios"||!Ve.existsSync(it.join(i,"ios")))return{appName:f,bundleId:p};await a("pods"),De.info(Me.blue("Running pod install..."));try{let R=it.join(i,"ios"),O=it.join(R,"Podfile");if(!Ve.existsSync(O))throw new Error("ios/Podfile not found. Skipping pod install.");let C=s();c(R,C);let x=Ve.readFileSync(O,"utf-8"),S=n.iosDeploymentTarget||"13.4";if(!n.developmentClient&&(De.info(Me.blue("\u2139\uFE0F Patching Podfile to EXCLUDE expo-dev-client...")),x.includes("use_expo_modules!")&&!x.includes("exclude:"))){let M=/use_expo_modules!(\s*)$/m;M.test(x)?x=x.replace(M,'use_expo_modules!(exclude: ["expo-dev-client"])$1'):x=x.replace("use_expo_modules!",'use_expo_modules!(exclude: ["expo-dev-client"])')}let _=`
328
328
  installer.generated_projects.each do |project|
329
329
  project.targets.each do |target|
330
330
  target.build_configurations.each do |config|
331
- config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${b}'
331
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${S}'
332
332
  end
333
333
  end
334
334
  end
335
335
  installer.pods_project.targets.each do |target|
336
336
  target.build_configurations.each do |config|
337
- config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${b}'
337
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${S}'
338
338
  end
339
339
  end
340
- `,_=/post_install\s+do\s+\|installer\|/;if(_.test(N))De.info(Me.dim(`Injecting deployment target (${b}) into existing post_install hook...`)),N=N.replace(_,`post_install do |installer|
341
- ${k}`),Be.writeFileSync(F,N);else{De.info(Me.dim(`Appending new post_install hook for deployment target (${b})...`));let M=`
340
+ `,k=/post_install\s+do\s+\|installer\|/;if(k.test(x))De.info(Me.dim(`Injecting deployment target (${S}) into existing post_install hook...`)),x=x.replace(k,`post_install do |installer|
341
+ ${_}`),Ve.writeFileSync(O,x);else{De.info(Me.dim(`Appending new post_install hook for deployment target (${S})...`));let M=`
342
342
  post_install do |installer|
343
- ${k}
343
+ ${_}
344
344
  end
345
- `;Be.appendFileSync(F,M)}let S="/opt/homebrew/bin/pod",$=Be.existsSync(S)?S:"pod",j=d(P);Be.existsSync(it.join(P,"Pods"))&&r.pods&&r.pods!==j&&(await e.reportLog(`[CACHE] Podfile/Podfile.lock changed \u2014 wiping ios/Pods
346
- `),De.info(Me.dim("Podfile fingerprint changed \u2014 clearing Pods for clean install...")),Be.rmSync(it.join(P,"Pods"),{recursive:!0,force:!0})),De.info(Me.dim(`Using pod command: ${$} in ${P}`)),await l($,["install"],P,C),r.pods=j,u(o,r)}catch(P){let F=P.message||"Unknown error";De.warn(Me.yellow(`Native "pod" command failed: ${F}`)),De.info(Me.dim("Falling back to npm exec pod-install..."));let C=s();c(it.join(i,"ios"),C),De.info(Me.magenta(`${A.nameUpper}_DEBUG: Executing pod-install override via npx --yes pod-install@latest`)),await l("npx",["--yes","pod-install@latest","ios"],i,C)}if(Be.existsSync(it.join(i,"ios/Pods"))){De.info(Me.dim("Disabling signing for Pod targets to prevent conflicts..."));try{xs(`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:f,bundleId:p}}finally{E&&Be.writeFileSync(m,E)}}};import{log as ot}from"@clack/prompts";import st from"chalk";import Ke from"fs";import Ut from"path";import{spawnSync as Ns}from"child_process";import Xe from"fs";import rt from"path";var Xi=(e,t)=>rt.join(e,"node_modules",".bin",process.platform==="win32"?`${t}.cmd`:t),ks=e=>{try{return JSON.parse(Xe.readFileSync(rt.join(e,"package.json"),"utf-8"))}catch{return{}}};function md(e,t){let n=ks(e);return!!(n.dependencies?.[t]||n.devDependencies?.[t])}function Gn(e,t,n,i={}){let r=`${t} ${n.join(" ")}`,o=Ns(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 gd(e){return Gn(e,"npx",["--yes","install-expo-modules@latest"])}function hd(e){let t=Xi(e,"expo");return Xe.existsSync(t)?Gn(e,t,["install","expo-updates"]):{ok:!1,command:"npx expo install expo-updates",error:"Expo Modules are not installed. Install Expo Modules first."}}function yd(e){let t=[];return Xe.existsSync(rt.join(e,"ios"))&&t.push("ios"),Xe.existsSync(rt.join(e,"android"))&&t.push("android"),t}function Ki(e){let t=Xi(e.cwd,"expo-updates");return Xe.existsSync(t)?e.platforms.map(n=>Gn(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 Id(e){let t=rt.join(e,"android","app","src","main","AndroidManifest.xml"),n=rt.join(e,"android","app","src","main","res","values","strings.xml"),i,r=rt.join(e,"ios");if(Xe.existsSync(r)){let o=[r];for(;o.length>0&&!i;){let s=o.shift();for(let a of Xe.readdirSync(s,{withFileTypes:!0})){if(a.name==="Pods"||a.name==="build")continue;let l=rt.join(s,a.name);if(a.isDirectory())o.push(l);else if(a.isFile()&&a.name==="Expo.plist"){i=l;break}}}}return{...Xe.existsSync(t)?{androidManifest:t}:{},...Xe.existsSync(n)?{androidStrings:n}:{},...i?{iosExpoPlist:i}:{}}}var _s=(e,t)=>!Ke.existsSync(e)||!Ke.existsSync(t)?!1:Ke.readFileSync(e,"utf-8")!==Ke.readFileSync(t,"utf-8"),Zn={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:()=>`
345
+ `;Ve.appendFileSync(O,M)}let b="/opt/homebrew/bin/pod",$=Ve.existsSync(b)?b:"pod",j=d(R);Ve.existsSync(it.join(R,"Pods"))&&r.pods&&r.pods!==j&&(await e.reportLog(`[CACHE] Podfile/Podfile.lock changed \u2014 wiping ios/Pods
346
+ `),De.info(Me.dim("Podfile fingerprint changed \u2014 clearing Pods for clean install...")),Ve.rmSync(it.join(R,"Pods"),{recursive:!0,force:!0})),De.info(Me.dim(`Using pod command: ${$} in ${R}`)),await l($,["install"],R,C),r.pods=j,u(o,r)}catch(R){let O=R.message||"Unknown error";De.warn(Me.yellow(`Native "pod" command failed: ${O}`)),De.info(Me.dim("Falling back to npm exec pod-install..."));let C=s();c(it.join(i,"ios"),C),De.info(Me.magenta(`${A.nameUpper}_DEBUG: Executing pod-install override via npx --yes pod-install@latest`)),await l("npx",["--yes","pod-install@latest","ios"],i,C)}if(Ve.existsSync(it.join(i,"ios/Pods"))){De.info(Me.dim("Disabling signing for Pod targets to prevent conflicts..."));try{ks(`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:f,bundleId:p}}finally{P&&Ve.writeFileSync(m,P)}}};import{log as ot}from"@clack/prompts";import st from"chalk";import Ke from"fs";import Ut from"path";import{spawnSync as _s}from"child_process";import Xe from"fs";import rt from"path";var Xi=(e,t)=>rt.join(e,"node_modules",".bin",process.platform==="win32"?`${t}.cmd`:t),$s=e=>{try{return JSON.parse(Xe.readFileSync(rt.join(e,"package.json"),"utf-8"))}catch{return{}}};function yd(e,t){let n=$s(e);return!!(n.dependencies?.[t]||n.devDependencies?.[t])}function Gn(e,t,n,i={}){let r=`${t} ${n.join(" ")}`,o=_s(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 Id(e){return Gn(e,"npx",["--yes","install-expo-modules@latest"])}function Ad(e){let t=Xi(e,"expo");return Xe.existsSync(t)?Gn(e,t,["install","expo-updates"]):{ok:!1,command:"npx expo install expo-updates",error:"Expo Modules are not installed. Install Expo Modules first."}}function bd(e){let t=[];return Xe.existsSync(rt.join(e,"ios"))&&t.push("ios"),Xe.existsSync(rt.join(e,"android"))&&t.push("android"),t}function Ki(e){let t=Xi(e.cwd,"expo-updates");return Xe.existsSync(t)?e.platforms.map(n=>Gn(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 Sd(e){let t=rt.join(e,"android","app","src","main","AndroidManifest.xml"),n=rt.join(e,"android","app","src","main","res","values","strings.xml"),i,r=rt.join(e,"ios");if(Xe.existsSync(r)){let o=[r];for(;o.length>0&&!i;){let s=o.shift();for(let a of Xe.readdirSync(s,{withFileTypes:!0})){if(a.name==="Pods"||a.name==="build")continue;let l=rt.join(s,a.name);if(a.isDirectory())o.push(l);else if(a.isFile()&&a.name==="Expo.plist"){i=l;break}}}}return{...Xe.existsSync(t)?{androidManifest:t}:{},...Xe.existsSync(n)?{androidStrings:n}:{},...i?{iosExpoPlist:i}:{}}}var Os=(e,t)=>!Ke.existsSync(e)||!Ke.existsSync(t)?!1:Ke.readFileSync(e,"utf-8")!==Ke.readFileSync(t,"utf-8"),Zn={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:()=>`
347
347
  export MACH_FRAMEWORK="react-native"
348
348
  echo "[ENV] MACH_FRAMEWORK=$MACH_FRAMEWORK"
349
349
  unset EXPO_NO_DOTENV
@@ -360,7 +360,7 @@ if [ -n "\${MACH_OTA_RUNTIME_VERSION:-}" ]; then
360
360
  "$EXPO_UPDATES_BIN" configuration:syncnative --platform ios --workflow generic
361
361
  fi
362
362
  `,androidRemoteVersionCodeScript:()=>`
363
- echo "[VERSIONING] React Native framework configured. Version code will be injected through Gradle."
363
+ echo "[VERSIONING] React Native configured. Mach will lock versionCode through the Android Variant API."
364
364
  `,androidRemotePrebuildScript:()=>`
365
365
  echo "[PREBUILD] React Native framework configured. Skipping Expo prebuild."
366
366
  if [ -n "\${MACH_OTA_RUNTIME_VERSION:-}" ]; then
@@ -376,9 +376,9 @@ fi
376
376
  :
377
377
  `,androidRemoteReleaseGradlePropertiesScript:()=>`
378
378
  :
379
- `,prepareLocalProject:async e=>{let{platform:t,appRoot:n,cacheMeta:i,cacheMetaDir:r,currentBuildEnv:o,reportStep:s,reportLog:a,loggedRun:l,configureXcodeNodeBinary:c,podsFingerprint:d,writeCacheMeta:u}=e,p=o(),f=p.MACH_OTA_RUNTIME_VERSION,m=p.MACH_OTA_CHANNEL,E=p.MACH_OTA_URL;if(f&&m&&E){let x=Ki({cwd:n,platforms:[t],runtimeVersion:f,channel:m,url:E}).find(M=>!M.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.`);ot.info(st.green(`\u2713 OTA runtime ${f} synchronized for ${t}`))}if(t!=="ios")return{};let v=Ut.join(n,"ios"),P=Ut.join(v,"Podfile");if(!Ke.existsSync(P))throw new Error("React Native iOS build requires ios/Podfile. Commit the ios directory for vanilla React Native projects.");await s("pods"),ot.info(st.blue("Running React Native pod install..."));let F=o();c(v,F);let C=Ut.join(v,"Pods"),N=Ut.join(v,"Podfile.lock"),b=Ut.join(C,"Manifest.lock"),k=Ke.existsSync(C),_=d(v);k&&i.reactNativePods&&i.reactNativePods!==_?(await a(`[CACHE] React Native Podfile/Podfile.lock changed - wiping ios/Pods
380
- `),ot.info(st.dim("React Native Podfile fingerprint changed - clearing Pods for clean install...")),Ke.rmSync(C,{recursive:!0,force:!0})):k&&_s(N,b)&&(await a(`[CACHE] React Native Pods Manifest.lock is out of sync - wiping ios/Pods
381
- `),ot.info(st.dim("React Native Pods manifest is out of sync - clearing Pods for clean install...")),Ke.rmSync(C,{recursive:!0,force:!0}));let S="/opt/homebrew/bin/pod",$=Ke.existsSync(S)?S:"pod";try{ot.info(st.dim(`Using pod command: ${$} in ${v}`)),await l($,["install"],v,F)}catch(j){let x=j.message||"Unknown error";ot.warn(st.yellow(`Native "pod" command failed: ${x}`)),ot.info(st.dim("Falling back to npx pod-install..."));let M=o();c(v,M),ot.info(st.magenta(`${A.nameUpper}_DEBUG: Executing pod-install fallback via npx --yes pod-install@latest`)),await l("npx",["--yes","pod-install@latest","ios"],n,M)}return i.reactNativePods=d(v),u(r,i),{}}};import qi from"os";import Kn from"path";import{execFileSync as Yi}from"child_process";import Je from"fs";import mt from"path";var Hn=(e,t)=>{let n=e.match(new RegExp(`^${t.replace(/[.*+?^${}()|[\\]\\]/g,"\\$&")}:\\s*([^#\\r\\n]+)`,"m"));return n?.[1]&&n[1].trim().replace(/^['"]|['"]$/g,"")||void 0},Ji=(e,t,n)=>{let i=e.split(/\r?\n/),r=null;for(let o of i){if(!o.trim()||o.trimStart().startsWith("#"))continue;let s=o.length-o.trimStart().length;if(r===null){s===0&&new RegExp(`^${t}:\\s*(?:#.*)?$`).test(o.trim())&&(r=s);continue}if(s<=r)break;let a=o.trim().match(new RegExp(`^${n}:\\s*([^#]+)`));if(a?.[1])return a[1].trim().replace(/^['"]|['"]$/g,"")||void 0}},on=e=>{let t=mt.join(e,"pubspec.yaml");if(!Je.existsSync(t))return!1;try{let n=Je.readFileSync(t,"utf8");return/^\s*flutter:\s*$/m.test(n)&&/^\s+sdk:\s*flutter\s*(?:#.*)?$/m.test(n)}catch{return!1}},zi=e=>{let t=mt.join(e,"pubspec.yaml");if(!Je.existsSync(t))return{};let n=Je.readFileSync(t,"utf8"),i=Hn(n,"version"),[r,o]=i?.split("+")||[],s=mt.join(e,".metadata"),a;if(Je.existsSync(s))try{a=Hn(Je.readFileSync(s,"utf8"),"project_type")}catch{}return{name:Hn(n,"name"),version:r,buildNumber:o,sdkConstraint:Ji(n,"environment","sdk"),defaultFlavor:Ji(n,"flutter","default-flavor"),projectType:a}},Qi=e=>{if(!on(e))throw new Error("Flutter app root must contain a pubspec.yaml with a flutter SDK dependency.");let t=zi(e).projectType;if(t&&t!=="app")throw new Error(`Flutter project type "${t}" is not a standalone application. Mach currently supports standalone Flutter apps; add-to-app modules require a host-application workflow.`)},sn=e=>{let t=typeof e=="string"&&e.trim()?e.trim().replace(/\\/g,"/"):"lib/main.dart";if(mt.posix.isAbsolute(t)||t===".."||t.startsWith("../")||t.includes("/../"))throw new Error("flutter.target must be a relative Dart file inside appDirectory.");if(!t.endsWith(".dart"))throw new Error("flutter.target must point to a .dart file.");return t.replace(/^\.\//,"")},kd=e=>{if(e==null||e==="")return;let t=String(e).trim();if(!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(t))throw new Error("flutter.sdkVersion must be an exact Flutter version such as 3.47.1 or 3.48.0-0.2.pre.");return t},$s=(e,t,n)=>({...t?.flutter||{},...n?t?.[n]?.flutter||{}:{}}),Ts=e=>{let t=[mt.join(e,"android","app","build.gradle"),mt.join(e,"android","app","build.gradle.kts")],n=new Set;for(let i of t){if(!Je.existsSync(i))continue;let r=Je.readFileSync(i,"utf8");r=r.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"");let o=/\bproductFlavors\s*(?:=\s*)?\{/g,s;for(;s=o.exec(r);){let a=r.indexOf("{",s.index),l=1,c="",d=!1,u=a+1;for(;u<r.length&&l>0;u+=1){let f=r[u];if(d){d=!1;continue}if(c){f==="\\"?d=!0:f===c&&(c="");continue}if(f==='"'||f==="'"){c=f;continue}f==="{"?l+=1:f==="}"&&(l-=1)}let p=r.slice(a+1,Math.max(a+1,u-1));for(let f of p.matchAll(/\b(?:create|maybeCreate|register)\s*\(\s*["']([A-Za-z_][A-Za-z0-9_-]*)["']/g))n.add(f[1]);for(let f of p.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_-]*)\s*\{/gm))["create","maybeCreate","register","configureEach","all"].includes(f[1])||n.add(f[1]);o.lastIndex=u}}return[...n].sort()},_d=(e,t)=>e?.mode?e.mode:t.simulator||t.developmentClient||t.distribution==="development"?"debug":"release",$d=(e,t,n,i)=>{if(n?.developmentClient)throw new Error(`Build profile "${t}" uses developmentClient, which is Expo-specific. For Flutter, set flutter.mode to "debug" when a debug build is required.`);let r=$s({},n,i);if(r.mode&&!["debug","profile","release"].includes(r.mode))throw new Error(`build.${t}.flutter.mode must be debug, profile, or release.`);let o=sn(r.target);if(!Je.existsSync(mt.join(e,o)))throw new Error(`build.${t}.flutter.target points to missing file ${o}.`);if(r.dartDefinesFromEnv!==void 0&&(!Array.isArray(r.dartDefinesFromEnv)||r.dartDefinesFromEnv.some(s=>typeof s!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(s))))throw new Error(`build.${t}.flutter.dartDefinesFromEnv must contain valid environment variable names.`);if(r.obfuscate!==void 0&&typeof r.obfuscate!="boolean")throw new Error(`build.${t}.flutter.obfuscate must be a boolean.`);if(r.splitDebugInfo!==void 0&&typeof r.splitDebugInfo!="boolean")throw new Error(`build.${t}.flutter.splitDebugInfo must be a boolean.`);if(i==="android"&&!r.flavor&&!zi(e).defaultFlavor){let s=Ts(e);if(s.length>0)throw new Error(`build.${t} does not select a Flutter flavor, but the Android project defines: ${s.join(", ")}. Set build.${t}.flutter.flavor, or build.${t}.android.flutter.flavor for an Android-only override.`)}return r},Fs=(e,t)=>e?.length?e.map(n=>{let i=t[n];if(i===void 0)throw new Error(`Flutter compile-time value ${n} is required by dartDefinesFromEnv but is not defined.`);return`--dart-define=${n}=${i}`}):[],Wt=(e,t)=>{let n=[],i=e.flutterMode||"release";n.push(`--${i}`),e.flutterFlavor&&n.push("--flavor",e.flutterFlavor),n.push("--target",sn(e.flutterTarget));let r=e.platform==="android"?e.resolvedVersionCode:e.resolvedBuildNumber;if(r&&n.push("--build-number",r),e.appVersion&&n.push("--build-name",e.appVersion),n.push(...Fs(e.flutterDartDefinesFromEnv,t)),e.flutterSplitDebugInfoPath){if(e.platform==="web")throw new Error("Flutter web does not support --split-debug-info/--obfuscate. Disable these fields for web profiles.");if(i!=="release")throw new Error('Flutter split debug info and obfuscation require flutter.mode "release".');e.flutterObfuscate&&n.push("--obfuscate"),n.push("--split-debug-info",e.flutterSplitDebugInfoPath)}return n},Xn=()=>{try{let e=Yi("flutter",["--version","--machine"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=JSON.parse(e);return{flutter:t.frameworkVersion,dart:t.dartSdkVersion}}catch{return{}}},Td=()=>{try{let e=Yi("flutter",["devices","--machine"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>n&&typeof n.id=="string"&&n.id.trim().length>0):[]}catch{return[]}},Fd=(e,t)=>e.filter(n=>{let i=String(n.targetPlatform||"").toLowerCase();return t==="ios"?i.startsWith("ios"):i.startsWith("android")});var Os=(e,t)=>{let n=["build","ios","--config-only","--no-codesign"];return e.simulator&&n.push("--simulator"),n.push(...Wt(e,t)),n},Jn={id:"flutter",displayName:"Flutter",applyLocalProcessEnv:()=>{},localAndroidEnv:e=>({MACH_FRAMEWORK:"flutter",MACH_FLUTTER_FLAVOR:e.flutterFlavor||"",MACH_FLUTTER_TARGET:sn(e.flutterTarget),MACH_FLUTTER_MODE:e.flutterMode||"release"}),remoteEnvSetupScript:()=>`
379
+ `,prepareLocalProject:async e=>{let{platform:t,appRoot:n,cacheMeta:i,cacheMetaDir:r,currentBuildEnv:o,reportStep:s,reportLog:a,loggedRun:l,configureXcodeNodeBinary:c,podsFingerprint:d,writeCacheMeta:u}=e,p=o(),f=p.MACH_OTA_RUNTIME_VERSION,m=p.MACH_OTA_CHANNEL,P=p.MACH_OTA_URL;if(f&&m&&P){let N=Ki({cwd:n,platforms:[t],runtimeVersion:f,channel:m,url:P}).find(M=>!M.ok);if(N)throw new Error(`Could not synchronize ${t} Expo Updates configuration: ${N.error||N.command}. Run \`mach ota setup --platform ${t}\` and try again.`);ot.info(st.green(`\u2713 OTA runtime ${f} synchronized for ${t}`))}if(t!=="ios")return{};let v=Ut.join(n,"ios"),R=Ut.join(v,"Podfile");if(!Ke.existsSync(R))throw new Error("React Native iOS build requires ios/Podfile. Commit the ios directory for vanilla React Native projects.");await s("pods"),ot.info(st.blue("Running React Native pod install..."));let O=o();c(v,O);let C=Ut.join(v,"Pods"),x=Ut.join(v,"Podfile.lock"),S=Ut.join(C,"Manifest.lock"),_=Ke.existsSync(C),k=d(v);_&&i.reactNativePods&&i.reactNativePods!==k?(await a(`[CACHE] React Native Podfile/Podfile.lock changed - wiping ios/Pods
380
+ `),ot.info(st.dim("React Native Podfile fingerprint changed - clearing Pods for clean install...")),Ke.rmSync(C,{recursive:!0,force:!0})):_&&Os(x,S)&&(await a(`[CACHE] React Native Pods Manifest.lock is out of sync - wiping ios/Pods
381
+ `),ot.info(st.dim("React Native Pods manifest is out of sync - clearing Pods for clean install...")),Ke.rmSync(C,{recursive:!0,force:!0}));let b="/opt/homebrew/bin/pod",$=Ke.existsSync(b)?b:"pod";try{ot.info(st.dim(`Using pod command: ${$} in ${v}`)),await l($,["install"],v,O)}catch(j){let N=j.message||"Unknown error";ot.warn(st.yellow(`Native "pod" command failed: ${N}`)),ot.info(st.dim("Falling back to npx pod-install..."));let M=o();c(v,M),ot.info(st.magenta(`${A.nameUpper}_DEBUG: Executing pod-install fallback via npx --yes pod-install@latest`)),await l("npx",["--yes","pod-install@latest","ios"],n,M)}return i.reactNativePods=d(v),u(r,i),{}}};import qi from"os";import Kn from"path";import{execFileSync as Yi}from"child_process";import Je from"fs";import mt from"path";var Hn=(e,t)=>{let n=e.match(new RegExp(`^${t.replace(/[.*+?^${}()|[\\]\\]/g,"\\$&")}:\\s*([^#\\r\\n]+)`,"m"));return n?.[1]&&n[1].trim().replace(/^['"]|['"]$/g,"")||void 0},Ji=(e,t,n)=>{let i=e.split(/\r?\n/),r=null;for(let o of i){if(!o.trim()||o.trimStart().startsWith("#"))continue;let s=o.length-o.trimStart().length;if(r===null){s===0&&new RegExp(`^${t}:\\s*(?:#.*)?$`).test(o.trim())&&(r=s);continue}if(s<=r)break;let a=o.trim().match(new RegExp(`^${n}:\\s*([^#]+)`));if(a?.[1])return a[1].trim().replace(/^['"]|['"]$/g,"")||void 0}},on=e=>{let t=mt.join(e,"pubspec.yaml");if(!Je.existsSync(t))return!1;try{let n=Je.readFileSync(t,"utf8");return/^\s*flutter:\s*$/m.test(n)&&/^\s+sdk:\s*flutter\s*(?:#.*)?$/m.test(n)}catch{return!1}},zi=e=>{let t=mt.join(e,"pubspec.yaml");if(!Je.existsSync(t))return{};let n=Je.readFileSync(t,"utf8"),i=Hn(n,"version"),[r,o]=i?.split("+")||[],s=mt.join(e,".metadata"),a;if(Je.existsSync(s))try{a=Hn(Je.readFileSync(s,"utf8"),"project_type")}catch{}return{name:Hn(n,"name"),version:r,buildNumber:o,sdkConstraint:Ji(n,"environment","sdk"),defaultFlavor:Ji(n,"flutter","default-flavor"),projectType:a}},Qi=e=>{if(!on(e))throw new Error("Flutter app root must contain a pubspec.yaml with a flutter SDK dependency.");let t=zi(e).projectType;if(t&&t!=="app")throw new Error(`Flutter project type "${t}" is not a standalone application. Mach currently supports standalone Flutter apps; add-to-app modules require a host-application workflow.`)},sn=e=>{let t=typeof e=="string"&&e.trim()?e.trim().replace(/\\/g,"/"):"lib/main.dart";if(mt.posix.isAbsolute(t)||t===".."||t.startsWith("../")||t.includes("/../"))throw new Error("flutter.target must be a relative Dart file inside appDirectory.");if(!t.endsWith(".dart"))throw new Error("flutter.target must point to a .dart file.");return t.replace(/^\.\//,"")},Od=e=>{if(e==null||e==="")return;let t=String(e).trim();if(!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(t))throw new Error("flutter.sdkVersion must be an exact Flutter version such as 3.47.1 or 3.48.0-0.2.pre.");return t},Ts=(e,t,n)=>({...t?.flutter||{},...n?t?.[n]?.flutter||{}:{}}),Fs=e=>{let t=[mt.join(e,"android","app","build.gradle"),mt.join(e,"android","app","build.gradle.kts")],n=new Set;for(let i of t){if(!Je.existsSync(i))continue;let r=Je.readFileSync(i,"utf8");r=r.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"");let o=/\bproductFlavors\s*(?:=\s*)?\{/g,s;for(;s=o.exec(r);){let a=r.indexOf("{",s.index),l=1,c="",d=!1,u=a+1;for(;u<r.length&&l>0;u+=1){let f=r[u];if(d){d=!1;continue}if(c){f==="\\"?d=!0:f===c&&(c="");continue}if(f==='"'||f==="'"){c=f;continue}f==="{"?l+=1:f==="}"&&(l-=1)}let p=r.slice(a+1,Math.max(a+1,u-1));for(let f of p.matchAll(/\b(?:create|maybeCreate|register)\s*\(\s*["']([A-Za-z_][A-Za-z0-9_-]*)["']/g))n.add(f[1]);for(let f of p.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_-]*)\s*\{/gm))["create","maybeCreate","register","configureEach","all"].includes(f[1])||n.add(f[1]);o.lastIndex=u}}return[...n].sort()},Td=(e,t)=>e?.mode?e.mode:t.simulator||t.developmentClient||t.distribution==="development"?"debug":"release",Fd=(e,t,n,i)=>{if(n?.developmentClient)throw new Error(`Build profile "${t}" uses developmentClient, which is Expo-specific. For Flutter, set flutter.mode to "debug" when a debug build is required.`);let r=Ts({},n,i);if(r.mode&&!["debug","profile","release"].includes(r.mode))throw new Error(`build.${t}.flutter.mode must be debug, profile, or release.`);let o=sn(r.target);if(!Je.existsSync(mt.join(e,o)))throw new Error(`build.${t}.flutter.target points to missing file ${o}.`);if(r.dartDefinesFromEnv!==void 0&&(!Array.isArray(r.dartDefinesFromEnv)||r.dartDefinesFromEnv.some(s=>typeof s!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(s))))throw new Error(`build.${t}.flutter.dartDefinesFromEnv must contain valid environment variable names.`);if(r.obfuscate!==void 0&&typeof r.obfuscate!="boolean")throw new Error(`build.${t}.flutter.obfuscate must be a boolean.`);if(r.splitDebugInfo!==void 0&&typeof r.splitDebugInfo!="boolean")throw new Error(`build.${t}.flutter.splitDebugInfo must be a boolean.`);if(i==="android"&&!r.flavor&&!zi(e).defaultFlavor){let s=Fs(e);if(s.length>0)throw new Error(`build.${t} does not select a Flutter flavor, but the Android project defines: ${s.join(", ")}. Set build.${t}.flutter.flavor, or build.${t}.android.flutter.flavor for an Android-only override.`)}return r},Ds=(e,t)=>e?.length?e.map(n=>{let i=t[n];if(i===void 0)throw new Error(`Flutter compile-time value ${n} is required by dartDefinesFromEnv but is not defined.`);return`--dart-define=${n}=${i}`}):[],Wt=(e,t)=>{let n=[],i=e.flutterMode||"release";n.push(`--${i}`),e.flutterFlavor&&n.push("--flavor",e.flutterFlavor),n.push("--target",sn(e.flutterTarget));let r=e.platform==="android"?e.resolvedVersionCode:e.resolvedBuildNumber;if(r&&n.push("--build-number",r),e.appVersion&&n.push("--build-name",e.appVersion),n.push(...Ds(e.flutterDartDefinesFromEnv,t)),e.flutterSplitDebugInfoPath){if(e.platform==="web")throw new Error("Flutter web does not support --split-debug-info/--obfuscate. Disable these fields for web profiles.");if(i!=="release")throw new Error('Flutter split debug info and obfuscation require flutter.mode "release".');e.flutterObfuscate&&n.push("--obfuscate"),n.push("--split-debug-info",e.flutterSplitDebugInfoPath)}return n},Xn=()=>{try{let e=Yi("flutter",["--version","--machine"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=JSON.parse(e);return{flutter:t.frameworkVersion,dart:t.dartSdkVersion}}catch{return{}}},Dd=()=>{try{let e=Yi("flutter",["devices","--machine"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>n&&typeof n.id=="string"&&n.id.trim().length>0):[]}catch{return[]}},Md=(e,t)=>e.filter(n=>{let i=String(n.targetPlatform||"").toLowerCase();return t==="ios"?i.startsWith("ios"):i.startsWith("android")});var Ms=(e,t)=>{let n=["build","ios","--config-only","--no-codesign"];return e.simulator&&n.push("--simulator"),n.push(...Wt(e,t)),n},Jn={id:"flutter",displayName:"Flutter",applyLocalProcessEnv:()=>{},localAndroidEnv:e=>({MACH_FRAMEWORK:"flutter",MACH_FLUTTER_FLAVOR:e.flutterFlavor||"",MACH_FLUTTER_TARGET:sn(e.flutterTarget),MACH_FLUTTER_MODE:e.flutterMode||"release"}),remoteEnvSetupScript:()=>`
382
382
  export MACH_FRAMEWORK="flutter"
383
383
  export PUB_CACHE="\${PUB_CACHE:-$HOME/.pub-cache}"
384
384
  INSTALLED_FLUTTER_VERSION=""
@@ -488,13 +488,98 @@ flutter --version
488
488
  flutter precache --android
489
489
  `,androidRemoteGradlePropertiesScript:()=>": # Flutter manages its Gradle integration",androidRemoteReleaseGradlePropertiesScript:()=>": # Flutter manages release architectures",prepareLocalProject:async e=>{let{platform:t,options:n,appRoot:i,currentBuildEnv:r,loggedRun:o,reportLog:s}=e,a=r(),l=Xn().flutter;if(!!(n.local&&n.buildId)&&n.flutterSdkVersion&&l!==n.flutterSdkVersion){await s(`[FLUTTER] Activating pinned SDK ${n.flutterSdkVersion} on managed runner
490
490
  `),await o("bash",["-lc",Jn.remoteEnvSetupScript()],e.sourceRoot,{...a,MACH_FLUTTER_SDK_VERSION:n.flutterSdkVersion});let d=process.platform==="linux"?Kn.join("/opt","mach",`flutter-${n.flutterSdkVersion}`,"bin"):Kn.join(qi.homedir(),".mach",`flutter-${n.flutterSdkVersion}`,"bin");process.env.PATH=`${d}:${process.env.PATH||""}`,process.env.PUB_CACHE||=Kn.join(qi.homedir(),".pub-cache"),a=r(),l=Xn().flutter}if(!l)throw new Error("Flutter CLI is unavailable. Install Flutter or use a Mach managed cloud build.");if(n.flutterSdkVersion&&l!==n.flutterSdkVersion)throw new Error(`Local Flutter SDK mismatch: ${n.flutterSdkVersion} is configured, but ${l} is active. Activate the pinned SDK (for example with FVM) or update flutter.sdkVersion intentionally.`);return await o("flutter",["--version"],i,a),await o("flutter",["precache",`--${t}`],i,a),await o("flutter",["pub","get"],i,a),await s(`[FLUTTER] Dependencies resolved with flutter pub get
491
- `),t==="ios"&&(await o("flutter",Os(n,a),i,a),await s(`[FLUTTER] Generated iOS build configuration
492
- `)),{}}};var Ds={expo:Hi,"react-native":Zn,flutter:Jn};function Gt(e){return e?Ds[e]:Zn}var Bs="mach-env-v3-project-layout",Vs=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_PROVISIONING_PROFILES","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"]),js=["PRESIGNED_","KEYSTORE_PASSWORD_"],Ls=e=>!e||Vs.has(e)?!1:!js.some(t=>e.startsWith(t)),an=(e,t,n)=>{let i=Gt(n.framework);return{...e,...i.localAndroidEnv(n,t),MACH_APP_NAME:n.appName||n.name||"App",MACH_APP_DIRECTORY:n.appDirectory||"."}},er=e=>{let t=Object.entries(e).filter(([n])=>Ls(n)).sort(([n],[i])=>n.localeCompare(i));return Ms.createHash("sha256").update(JSON.stringify({version:Bs,entries:t})).digest("hex")};var Us=/^\d+(?:\.\d+){0,2}$/,Ws="auto";var tr=e=>typeof e=="string"&&e.trim().toLowerCase()===Ws,Xd=(e,t,n,i=!0)=>e!=null&&String(e).trim()!==""?{kind:"persisted",value:e}:t!=null&&!tr(t)?{kind:"explicit",value:t}:i&&(n||tr(t))?{kind:"auto"}:{kind:"none"},Zt=e=>{let t=String(e??"").trim();return!t||t==="undefined"||t==="null"?null:Us.test(t)?t:null},Ct=(e,t)=>{let n=Zt(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},Gs=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)},Ue=(e,t)=>{let n=Gs(e);if(!n)throw new Error(`Invalid Android versionCode from ${t}: "${String(e??"")}". Use an integer from 1 to 2100000000.`);return n},Kd=(e,t,n,i)=>{let r=Ct(n,i);return e.resolvedBuildNumber=r,t.BUILD_NUMBER=r,t.CURRENT_PROJECT_VERSION=r,t.MACH_IOS_BUILD_NUMBER_LOCKED="1",r},Jd=(e,t,n,i)=>{let r=Ue(n,i);return e.resolvedVersionCode=r,t.ANDROID_VERSION_CODE=r,t.MACH_ANDROID_VERSION_CODE_LOCKED="1",r},Yd=(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=Ct(t.buildNumber,"saved MACH build record")),!e.resolvedVersionCode&&i&&(e.resolvedVersionCode=Ue(t.versionCode,"saved MACH build record"))};import{execFileSync as Yn}from"child_process";import Ye from"fs";import gt from"path";var Zs=new Set(["Pods","build","DerivedData",".git"]),nr=(e,t=[])=>{if(!Ye.existsSync(e))return t;for(let n of Ye.readdirSync(e,{withFileTypes:!0})){if(n.isSymbolicLink())continue;let i=gt.join(e,n.name);if(n.isDirectory()){if(Zs.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;nr(i,t);continue}n.isFile()&&n.name==="Info.plist"&&t.push(i)}return t},Hs=(e,t,n)=>{let i=String(e||"").trim().replace(/^"|"$/g,"");if(!i||(i=i.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g,(o,s,a)=>{let c=t[s||a];return c===void 0?"":String(c)}),!i||i.includes("$(")||i.includes("${")))return null;let r=String(t.SRCROOT||t.PROJECT_DIR||n);return gt.resolve(gt.isAbsolute(i)?i:gt.join(r,i))},Xs=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:[]},Ks=(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=Yn("xcodebuild",[...r,"-configuration",t.configuration,"-showBuildSettings","-json"],{cwd:e,encoding:"utf8",maxBuffer:16*1024*1024})}catch{continue}for(let s of Xs(o)){let a=s?.buildSettings;if(!a)continue;let l=String(a.WRAPPER_EXTENSION||"").toLowerCase();if(l!=="app"&&l!=="appex")continue;let c=Hs(String(a.INFOPLIST_FILE||""),a,e);if(!c||!Ye.existsSync(c))continue;let d=gt.relative(e,c);d.startsWith("..")||gt.isAbsolute(d)||n.add(c)}}return[...n].sort()},Js=(e,t)=>{let n=Ye.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),l=/^\s*<(string|integer)>[\s\S]*?<\/\1>/.exec(a);if(!l)throw new Error(`Could not update CFBundleVersion in ${e}: unsupported plist value type.`);o=n.slice(0,s)+`
491
+ `),t==="ios"&&(await o("flutter",Ms(n,a),i,a),await s(`[FLUTTER] Generated iOS build configuration
492
+ `)),{}}};var Vs={expo:Hi,"react-native":Zn,flutter:Jn};function Gt(e){return e?Vs[e]:Zn}var js="mach-env-v3-project-layout",Ls=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_PROVISIONING_PROFILES","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"]),Us=["PRESIGNED_","KEYSTORE_PASSWORD_"],Ws=e=>!e||Ls.has(e)?!1:!Us.some(t=>e.startsWith(t)),an=(e,t,n)=>{let i=Gt(n.framework);return{...e,...i.localAndroidEnv(n,t),MACH_APP_NAME:n.appName||n.name||"App",MACH_APP_DIRECTORY:n.appDirectory||"."}},er=e=>{let t=Object.entries(e).filter(([n])=>Ws(n)).sort(([n],[i])=>n.localeCompare(i));return Bs.createHash("sha256").update(JSON.stringify({version:js,entries:t})).digest("hex")};var Gs=/^\d+(?:\.\d+){0,2}$/,Zs="auto";var tr=e=>typeof e=="string"&&e.trim().toLowerCase()===Zs,Yd=(e,t,n,i=!0)=>e!=null&&String(e).trim()!==""?{kind:"persisted",value:e}:t!=null&&!tr(t)?{kind:"explicit",value:t}:i&&(n||tr(t))?{kind:"auto"}:{kind:"none"},Zt=e=>{let t=String(e??"").trim();return!t||t==="undefined"||t==="null"?null:Gs.test(t)?t:null},wt=(e,t)=>{let n=Zt(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},Hs=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)},We=(e,t)=>{let n=Hs(e);if(!n)throw new Error(`Invalid Android versionCode from ${t}: "${String(e??"")}". Use an integer from 1 to 2100000000.`);return n},zd=(e,t,n,i)=>{let r=wt(n,i);return e.resolvedBuildNumber=r,t.BUILD_NUMBER=r,t.CURRENT_PROJECT_VERSION=r,t.MACH_IOS_BUILD_NUMBER_LOCKED="1",r},Qd=(e,t,n,i)=>{let r=We(n,i);return e.resolvedVersionCode=r,t.ANDROID_VERSION_CODE=r,t.MACH_ANDROID_VERSION_CODE_LOCKED="1",r},qd=(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=wt(t.buildNumber,"saved MACH build record")),!e.resolvedVersionCode&&i&&(e.resolvedVersionCode=We(t.versionCode,"saved MACH build record"))};import{execFileSync as Yn}from"child_process";import Ye from"fs";import gt from"path";var Xs=new Set(["Pods","build","DerivedData",".git"]),nr=(e,t=[])=>{if(!Ye.existsSync(e))return t;for(let n of Ye.readdirSync(e,{withFileTypes:!0})){if(n.isSymbolicLink())continue;let i=gt.join(e,n.name);if(n.isDirectory()){if(Xs.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;nr(i,t);continue}n.isFile()&&n.name==="Info.plist"&&t.push(i)}return t},Ks=(e,t,n)=>{let i=String(e||"").trim().replace(/^"|"$/g,"");if(!i||(i=i.replace(/\$\(([^)]+)\)|\$\{([^}]+)\}/g,(o,s,a)=>{let c=t[s||a];return c===void 0?"":String(c)}),!i||i.includes("$(")||i.includes("${")))return null;let r=String(t.SRCROOT||t.PROJECT_DIR||n);return gt.resolve(gt.isAbsolute(i)?i:gt.join(r,i))},Js=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:[]},Ys=(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=Yn("xcodebuild",[...r,"-configuration",t.configuration,"-showBuildSettings","-json"],{cwd:e,encoding:"utf8",maxBuffer:16*1024*1024})}catch{continue}for(let s of Js(o)){let a=s?.buildSettings;if(!a)continue;let l=String(a.WRAPPER_EXTENSION||"").toLowerCase();if(l!=="app"&&l!=="appex")continue;let c=Ks(String(a.INFOPLIST_FILE||""),a,e);if(!c||!Ye.existsSync(c))continue;let d=gt.relative(e,c);d.startsWith("..")||gt.isAbsolute(d)||n.add(c)}}return[...n].sort()},zs=(e,t)=>{let n=Ye.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),l=/^\s*<(string|integer)>[\s\S]*?<\/\1>/.exec(a);if(!l)throw new Error(`Could not update CFBundleVersion in ${e}: unsupported plist value type.`);o=n.slice(0,s)+`
493
493
  <string>${t}</string>`+a.slice(l[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>
494
494
  <string>${t}</string>
495
- `+n.slice(s)}return Ye.writeFileSync(e,o),!0},Ys=(e,t)=>{if(!Js(e,t)){if(process.platform!=="darwin")throw new Error(`Could not update binary Info.plist outside macOS: ${e}`);try{Yn("/usr/bin/plutil",["-replace","CFBundleVersion","-string",t,e])}catch{Yn("/usr/bin/plutil",["-insert","CFBundleVersion","-string",t,e])}}},ir=(e,t,n)=>{let i=Ct(t,"resolved MACH build"),r=gt.resolve(e),o=new Set;if(n)try{for(let c of Ks(r,n))o.add(c)}catch{}for(let c of nr(r))o.add(c);let s=[...o].sort(),a=new Map,l=!1;try{for(let c of s)a.set(c,Ye.readFileSync(c)),Ys(c,i)}catch(c){for(let[d,u]of a)Ye.writeFileSync(d,u);throw c}return{buildNumber:i,plistPaths:s,restore:()=>{if(!l){l=!0;for(let[c,d]of a)Ye.existsSync(c)&&Ye.writeFileSync(c,d)}}}},zn=(e,t,n)=>{let i=Ct(e,n),r=Ct(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 rr}from"child_process";import Ht from"fs";import Ne from"path";import zs from"adm-zip";var Qn=(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")},Xt=e=>{let t=[],n=0;for(;n<e.length;){let i=Qn(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=Qn(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=Qn(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},or=(e,t)=>e.find(i=>i.number===t&&i.wireType===2)?.bytes?.toString("utf8"),Qs=e=>{let n=Xt(e).find(o=>o.number===7&&o.wireType===2)?.bytes;if(!n)return null;let r=Xt(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()},qs=e=>{let n=Xt(e).find(c=>c.number===1&&c.wireType===2)?.bytes;if(!n)throw new Error("AAB base manifest has no root XML element");let o=Xt(n).filter(c=>c.number===4&&c.wireType===2).map(c=>Xt(c.bytes)).find(c=>or(c,2)==="versionCode");if(!o)throw new Error("AAB base manifest has no android:versionCode");let s=or(o,3)?.trim();if(s&&/^\d+$/.test(s))return Ue(s,"packaged AAB manifest");let a=o.find(c=>c.number===6&&c.wireType===2)?.bytes,l=a?Qs(a):null;return Ue(l,"packaged AAB manifest")},sr=e=>{try{return Ht.accessSync(e,Ht.constants.X_OK),Ht.statSync(e).isFile()}catch{return!1}},qn=e=>String(process.env.PATH||"").split(Ne.delimiter).filter(Boolean).map(t=>Ne.join(t,e)),ar=()=>Array.from(new Set([process.env.ANDROID_HOME,process.env.ANDROID_SDK_ROOT,process.platform==="darwin"?Ne.join(process.env.HOME||"","Library/Android/sdk"):Ne.join(process.env.HOME||"","Android/Sdk"),"/opt/android-sdk"].filter(e=>!!e))),cr=e=>{try{return Ht.readdirSync(e).map(t=>Ne.join(e,t)).filter(t=>Ht.statSync(t).isDirectory()).sort((t,n)=>n.localeCompare(t,void 0,{numeric:!0}))}catch{return[]}},ea=()=>{let e=qn("apkanalyzer");for(let t of ar()){let n=Ne.join(t,"cmdline-tools");e.push(Ne.join(n,"latest/bin/apkanalyzer"));for(let i of cr(n))e.push(Ne.join(i,"bin/apkanalyzer"))}return e},ta=()=>{let e=[...qn("aapt2"),...qn("aapt")];for(let t of ar())for(let n of cr(Ne.join(t,"build-tools")))e.push(Ne.join(n,"aapt2"),Ne.join(n,"aapt"));return e},na=e=>{let t=e.trim();return/^\d+$/.test(t)?t:null},ia=e=>e.match(/^package:.*\bversionCode='(\d+)'/m)?.[1]||null,ra=(e,t)=>{let n=t.apkanalyzer??ea();for(let r of n)if(sr(r))try{let o=rr(r,["manifest","version-code",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=na(o);if(s)return Ue(s,"packaged APK manifest")}catch{}let i=t.aapt??ta();for(let r of i)if(sr(r))try{let o=rr(r,["dump","badging",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=ia(o);if(s)return Ue(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.")},oa=(e,t={})=>{let n=Ne.extname(e).toLowerCase();if(n===".apk")return ra(e,t);if(n!==".aab")throw new Error(`Unsupported Android artifact for version validation: ${e}`);let i;try{i=new zs(e)}catch(o){throw new Error(`Could not open AAB ${Ne.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 ${Ne.basename(e)} has no base module manifest`);try{return qs(r.getData())}catch(o){throw new Error(`Could not read versionCode from ${Ne.basename(e)}: ${o.message}`)}},cn=(e,t,n={})=>{let i=Ue(t,"resolved MACH build assignment"),r=oa(e,n);if(r!==i)throw new Error(`Android versionCode mismatch in ${Ne.basename(e)}: expected ${i}, packaged ${r}. MACH stopped the build before upload.`);return r};import oe from"fs";import q from"path";var ei=e=>{let t=q.join(e,"package.json");if(!oe.existsSync(t))return null;try{return JSON.parse(oe.readFileSync(t,"utf8"))}catch{return null}},lr=e=>{if(on(e)){let r=12;return oe.existsSync(q.join(e,"android"))&&(r+=3),oe.existsSync(q.join(e,"ios"))&&(r+=3),oe.existsSync(q.join(e,"lib/main.dart"))&&(r+=2),/^(app|mobile)$/i.test(q.basename(e))&&(r+=1),r}let t=ei(e);if(!t)return 0;let n={...t.dependencies||{},...t.devDependencies||{}},i=0;return n.expo&&(i+=8),n["react-native"]&&(i+=8),oe.existsSync(q.join(e,"android"))&&(i+=3),oe.existsSync(q.join(e,"ios"))&&(i+=3),/^(app|mobile)$/i.test(q.basename(e))&&(i+=1),i},sa=e=>{let t=q.join(e,"pubspec.yaml");if(!oe.existsSync(t))return[];try{let n=oe.readFileSync(t,"utf8").split(/\r?\n/),i=[],r=null;for(let o of n){if(!o.trim()||o.trimStart().startsWith("#"))continue;let s=o.length-o.trimStart().length;if(r===null){/^workspace:\s*(?:#.*)?$/.test(o.trim())&&(r=s);continue}if(s<=r)break;let a=o.trim().match(/^-\s*['"]?([^'"#]+?)['"]?\s*(?:#.*)?$/)?.[1]?.trim();a&&i.push(a)}return i}catch{return[]}},aa=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"):[]},ca=(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(!(!oe.existsSync(s)||!oe.statSync(s).isDirectory()))for(let a of oe.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(!(!oe.existsSync(r)||!oe.statSync(r).isDirectory()))for(let o of oe.readdirSync(r,{withFileTypes:!0}))o.isDirectory()&&n.add(q.join(r,o.name))}return Array.from(n)},pu=e=>{let t=q.resolve(e);if(lr(t)>0)return".";let n=ei(t),i=[...aa(n),...sa(t)],r=ca(t,i).map(o=>({directory:o,score:lr(o)})).filter(o=>o.score>0).sort((o,s)=>s.score-o.score||o.directory.localeCompare(s.directory));return r.length===0||r[1]&&r[1].score===r[0].score?null:q.relative(t,r[0].directory).split(q.sep).join("/")},fu=(e,t)=>{let n=ze(e,t,{requireAppDirectory:!0});if(on(n.appRoot))return"flutter";let i=ei(n.appRoot);return{...i?.dependencies||{},...i?.devDependencies||{}}.expo?"expo":"react-native"},la=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(/\/+$/,"")},ze=(e,t,n={})=>{let i=q.resolve(e),r=la(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(!oe.existsSync(o)||!oe.statSync(o).isDirectory())throw new Error(`Configured appDirectory "${r}" does not exist inside the project root.`);if(!oe.existsSync(q.join(o,"package.json"))&&!oe.existsSync(q.join(o,"pubspec.yaml")))throw new Error(`Configured appDirectory "${r}" must contain a package.json or pubspec.yaml.`);let a=oe.realpathSync(i),l=oe.realpathSync(o),c=q.relative(a,l);if(c===".."||c.startsWith(`..${q.sep}`)||q.isAbsolute(c))throw new Error("Configured appDirectory resolves outside the project root.")}return{sourceRoot:i,appDirectory:r,appRoot:o}},mu=(e,t,n)=>{if(t==="flutter"){if(Qi(e.appRoot),n==="web"){let r=q.join(e.appRoot,"web");if(!oe.existsSync(r)||!oe.statSync(r).isDirectory())throw new Error(`Flutter web build requires web/ inside appDirectory "${e.appDirectory}". Run \`flutter create . --platforms web\` to add it.`);return}let i=q.join(e.appRoot,n);if(!oe.existsSync(i)||!oe.statSync(i).isDirectory())throw new Error(`Flutter ${n==="ios"?"iOS":"Android"} build requires ${n}/ inside appDirectory "${e.appDirectory}".`);return}if(n==="web")throw new Error("Web builds are currently supported only for Flutter projects.");if(t==="react-native"){if(n==="android"){let i=q.join(e.appRoot,"android/gradlew"),r=q.join(e.appRoot,"gradlew");if(!oe.existsSync(i)&&!oe.existsSync(r))throw new Error(`React Native Android build requires android/gradlew inside appDirectory "${e.appDirectory}".`);return}if(!oe.existsSync(q.join(e.appRoot,"ios/Podfile")))throw new Error(`React Native iOS build requires ios/Podfile inside appDirectory "${e.appDirectory}".`)}};import ti from"fs";import dn from"path";import{spawnSync as da}from"child_process";var Ce=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},dr=e=>e==null?void 0:Ce(String(e)),pr=e=>{if(!ti.existsSync(e))return null;try{return JSON.parse(ti.readFileSync(e,"utf-8"))}catch{return null}},ua=e=>{let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{let n=t.indexOf("{"),i=t.lastIndexOf("}");if(n<0||i<=n)return null;try{return JSON.parse(t.slice(n,i+1))}catch{return null}}};function ur(e=process.cwd()){let t=pr(dn.join(e,"package.json"))||{};return Ce(t.version)}function pa(e=process.cwd()){let t=pr(dn.join(e,"package.json"))||{},n={...t.dependencies||{},...t.devDependencies||{}};if(n.expo)return"expo";if(n["react-native"])return"react-native"}function fr(e=process.cwd(),t={}){let n=process.platform==="win32"?dn.join(e,"node_modules",".bin","expo.cmd"):dn.join(e,"node_modules",".bin","expo"),i=ti.existsSync(n),s=da(i?n:"npx",i?["config","--type","public","--json"]:["--no-install","expo","config","--type","public","--json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","pipe"],env:{...process.env,EXPO_NO_TELEMETRY:"1",...t}});return s.error||s.status!==0?null:ua(s.stdout||"")}var mr=e=>{let t=Ce(e);if(!(!t||t==="manual"))return t},ln=(e,t,n,i={})=>{let r=Ce(e);if(r)return r;if(!e||typeof e!="object")return;let o=Ce(e.policy);if(o==="appVersion")return Ce(t.version);if(o==="sdkVersion")return Ce(t.sdkVersion);if(o==="nativeVersion"){let s=Ce(t.version);if(!s||!n)return;let a=n==="ios"?dr(i.iosBuildNumber)||dr(t.ios?.buildNumber):i.androidVersionCode!==void 0?String(i.androidVersionCode).trim():t.android?.versionCode!==void 0?String(t.android.versionCode).trim():void 0;return!a||a.toLowerCase()==="auto"?s:a?`${s}(${a})`:s}};function fa(e,t,n={},i){let r=t?ln(e[t]?.runtimeVersion,e,t,n):void 0;if(r)return r;let o=ln(e.runtimeVersion,e,t,n);return o||(i?ln({policy:i},e,t,n):void 0)}function ma(e,t){if(!(!e||typeof e!="object"))return Ce(t?e[t]?.runtimeVersion:void 0)||Ce(e.runtimeVersion)}function Au(e,t={}){return Ce(t.MACH_OTA_CHANNEL)||Ce(e.ota?.channel)||"production"}function gr(e,t){return[e?.runtimeVersion!==t.runtimeVersion?`runtime ${e?.runtimeVersion||"missing"} (expected ${t.runtimeVersion})`:void 0,e?.channel!==t.channel?`channel ${e?.channel||"missing"} (expected ${t.channel})`:void 0,e?.url!==t.url?`URL ${e?.url||"missing"} (expected ${t.url})`:void 0].filter(n=>!!n)}function hr(e,t){let n=fr(e,{MACH_OTA_RUNTIME_VERSION:t.runtimeVersion,MACH_OTA_CHANNEL:t.channel,MACH_OTA_URL:t.url});return n?{runtimeVersion:ma(n,t.platform),channel:Ce(n.updates?.requestHeaders?.["expo-channel-name"]),url:Ce(n.updates?.url),expoConfig:n}:null}function ga(e,t,n={}){let i=Ce(n.runtimeVersion)||Ce(e.ota?.runtimeVersion);if(i)return i;let r={iosBuildNumber:n.iosBuildNumber,androidVersionCode:n.androidVersionCode},o=mr(e.ota?.runtimeVersionPolicy);if(o){let s=ln({policy:o},t,n.platform,r);if(s)return s}return fa(t,n.platform,r)}function bu(e,t={}){let n=t.cwd||process.cwd(),i=Ce(t.runtimeVersion)||Ce(e.ota?.runtimeVersion);if(i)return i;let r=mr(e.ota?.runtimeVersionPolicy),o={iosBuildNumber:t.iosBuildNumber,androidVersionCode:t.androidVersionCode};if((t.framework||e.framework||pa(n))==="expo"){let a=fr(n),l=a?ga(e,a,{platform:t.platform,iosBuildNumber:o.iosBuildNumber,androidVersionCode:o.androidVersionCode}):void 0;if(l)return l}return ur(n)||"1.0.0"}import Kt from"fs";import ni from"path";import{spawnSync as ha}from"child_process";var un=/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/;function Ir(e){if(!e||typeof e!="object")return;let t=e,n=typeof t.targetName=="string"?t.targetName.trim():"",i=typeof t.bundleIdentifier=="string"?t.bundleIdentifier.trim():"";if(!(!n||n.length>128||/[\r\n\0]/.test(n)||!un.test(i)))return{targetName:n,bundleIdentifier:i}}function ii(e){if(!e||typeof e!="object")return[];let t=e,i=(t.expo&&typeof t.expo=="object"?t.expo:t)?.extra?.eas?.build?.experimental?.ios?.appExtensions;return Array.isArray(i)?i.map(Ir).filter(Boolean):[]}function ya(e){for(let t of["app.json","app.config.json"]){let n=ni.join(e,t);if(Kt.existsSync(n))try{return ii(JSON.parse(Kt.readFileSync(n,"utf8")))}catch{return[]}}return[]}function Ia(e){let t=ha(process.platform==="win32"?"npx.cmd":"npx",["--no-install","expo","config","--type","public","--json"],{cwd:e,encoding:"utf8",timeout:15e3,maxBuffer:5242880,stdio:["ignore","pipe","ignore"]});if(t.status!==0||!t.stdout)return[];try{return ii(JSON.parse(t.stdout))}catch{return[]}}function yr(e,t,n){let i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`${i}(?:\\s+\\/\\*[^\\n]*\\*\\/)?\\s*=\\s*\\{\\s*isa\\s*=\\s*${n};([\\s\\S]*?)\\n\\s*\\};`))?.[1]}function Aa(e){let t=ni.join(e,"ios");if(!Kt.existsSync(t))return[];let n=[],i=o=>{for(let s of Kt.readdirSync(o,{withFileTypes:!0})){if(s.name==="Pods"||s.name==="build")continue;let a=ni.join(o,s.name);s.isDirectory()?i(a):s.name==="project.pbxproj"&&n.push(a)}};i(t);let r=[];for(let o of n){let s=Kt.readFileSync(o,"utf8"),a=/([A-Fa-f0-9]{24})(?: \/\* ([^*\n]+) \*\/)? = \{\s*isa = PBXNativeTarget;([\s\S]*?)\n\s*\};/g;for(let l of s.matchAll(a)){let c=l[3]||"";if(!/productType\s*=\s*"?com\.apple\.product-type\.app-extension"?;/.test(c))continue;let d=(c.match(/\bname\s*=\s*"?([^";\n]+)"?;/)?.[1]||l[2]||"").trim(),u=c.match(/buildConfigurationList\s*=\s*([A-Fa-f0-9]{24})/)?.[1];if(!d||!u)continue;let f=[...(yr(s,u,"XCConfigurationList")||"").matchAll(/([A-Fa-f0-9]{24})(?: \/\*[^*\n]+\*\/)?/g)].map(E=>E[1]),m;for(let E of f){let P=yr(s,E,"XCBuildConfiguration")?.match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/)?.[1]?.trim();if(P&&!P.includes("$")&&un.test(P)){m=P;break}}m&&r.push({targetName:d,bundleIdentifier:m})}}return r}function ba(e,t,n){if(!un.test(e))throw new Error(`Invalid main iOS bundle identifier "${e}".`);let i=[{targetName:t,bundleIdentifier:e,isMainApplication:!0}],r=new Set([e]),o=new Set(t?[t]:[]);for(let s of n){let a=Ir(s);if(!a)throw new Error("Each ios.appExtensions entry requires a valid targetName and bundleIdentifier.");if(r.has(a.bundleIdentifier))throw new Error(`Duplicate iOS signing bundle identifier "${a.bundleIdentifier}".`);if(o.has(a.targetName))throw new Error(`Duplicate iOS signing target name "${a.targetName}".`);r.add(a.bundleIdentifier),o.add(a.targetName),i.push({...a,isMainApplication:!1})}return i}function Eu(e){let{config:t,resolvedProfile:n,framework:i,appRoot:r}=e,o=n?.ios?.appExtensions??t?.ios?.appExtensions,s=Array.isArray(o)?o:[];return s.length===0&&(s=ii(t?.expo)),s.length===0&&i==="expo"&&(s=ya(r)),s.length===0&&i==="expo"&&(s=Ia(r)),s.length===0&&(s=Aa(r)),ba(e.mainBundleIdentifier,e.mainTargetName,s)}function Pu(e){return JSON.stringify({version:1,profiles:e})}function Ar(e){if(!e)return[];let t;try{t=JSON.parse(e)}catch{throw new Error("IOS_PROVISIONING_PROFILES contains invalid JSON.")}let n=t;if(n.version!==1||!Array.isArray(n.profiles))throw new Error("IOS_PROVISIONING_PROFILES has an unsupported format.");return n.profiles.map(i=>{let r=i.isMainApplication===!0,o=typeof i.bundleIdentifier=="string"?i.bundleIdentifier.trim():"",s=typeof i.targetName=="string"?i.targetName.trim():"";if(!un.test(o)||!r&&(!s||s.length>128||/[\r\n\0]/.test(s))||typeof i.profileBase64!="string"||i.profileBase64.length<64)throw new Error("IOS_PROVISIONING_PROFILES contains an invalid profile.");return{targetName:s||void 0,bundleIdentifier:o,isMainApplication:r,profileBase64:i.profileBase64}})}import xe from"fs";import gn from"os";import ve from"path";import{execFileSync as Rr,spawnSync as xr}from"child_process";import{spawnSync as ri}from"child_process";import br from"crypto";import Sa from"fs";var pn=e=>String(e||"").replace(/[^a-fA-F0-9]/g,"").toUpperCase(),oi=(e,t)=>{let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`<key>${n}<\\/key>\\s*<string>([^<]+)<\\/string>`))?.[1]?.trim()},wa=(e,t)=>{let n=oi(e,"application-identifier");if(!n)return;if(t&&n.startsWith(`${t}.`))return n.slice(t.length+1);let i=n.indexOf(".");return i>=0?n.slice(i+1):n},Sr=e=>{let t=new br.X509Certificate(e);return{sha1:pn(t.fingerprint),sha256:pn(t.fingerprint256),serial:pn(t.serialNumber),subject:t.subject}},Ca=e=>(e.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g)||[]).map(n=>new br.X509Certificate(n).raw);function ai(e){let t=e.match(/<key>TeamIdentifier<\/key>\s*<array>\s*<string>([^<]+)<\/string>/)?.[1]?.trim(),n=e.match(/<key>DeveloperCertificates<\/key>\s*<array>([\s\S]*?)<\/array>/)?.[1]||"",r=Array.from(n.matchAll(/<data>\s*([\s\S]*?)\s*<\/data>/g),a=>a[1].replace(/\s+/g,"")).filter(Boolean).map(a=>Sr(Buffer.from(a,"base64"))),o=/<key>get-task-allow<\/key>\s*<true\/>/.test(e),s=e.includes("<key>ProvisionedDevices</key>");return{uuid:oi(e,"UUID"),name:oi(e,"Name"),teamId:t,bundleIdentifier:wa(e,t),isDevelopment:o,isAppStore:!o&&!s,certificateSha1s:r.map(a=>a.sha1),certificateSha256s:r.map(a=>a.sha256)}}var va=e=>{let t=Sa.readFileSync(e,"utf8");if(t.includes("<plist")&&t.includes("DeveloperCertificates"))return t;let n=ri("security",["cms","-D","-i",e],{encoding:"utf8",maxBuffer:5*1024*1024});if(!n.error&&n.status===0&&n.stdout?.includes("<plist"))return n.stdout;let i=ri("openssl",["smime","-verify","-inform","DER","-in",e,"-noverify"],{encoding:"utf8",maxBuffer:5*1024*1024});if(!i.error&&i.status===0&&i.stdout?.includes("<plist"))return i.stdout;let r=[n.stderr,i.stderr,n.error?.message,i.error?.message].filter(Boolean).join(`
496
- `).trim();throw new Error(`Could not decode provisioning profile${r?`: ${r}`:"."}`)};function Et(e){return ai(va(e))}function Jt(e,t){let n=[!0,!1],i;for(let o of n){let s=ri("openssl",["pkcs12","-in",e,"-clcerts","-nokeys","-passin",`pass:${t}`,...o?["-legacy"]:[]],{encoding:"utf8",maxBuffer:5242880});if(i=s,s.error||s.status!==0||!s.stdout)continue;let a=Ca(s.stdout).map(Sr);if(a.length>0)return a}let r=[i?.stderr,i?.error?.message].filter(Boolean).join(`
497
- `).trim();throw new Error(`Could not read signing certificate from .p12${r?`: ${r}`:"."}`)}function wr(e){let t=Array.from(e.matchAll(/\)\s*([A-Fa-f0-9]{40})\s+"([^"]+)"/g),i=>({sha1:pn(i[1]),name:i[2]})),n=new Set;return t.filter(i=>n.has(i.sha1)?!1:(n.add(i.sha1),!0))}var vt=e=>e.name||e.uuid||"selected provisioning profile",si=e=>e.length>12?`${e.slice(0,12)}\u2026`:e;function fn(e,t){if(t.certificateSha1s.length===0)throw new Error(`${vt(t)} has no embedded signing certificates.`);let n=e.find(o=>t.certificateSha1s.includes(o.sha1)||t.certificateSha256s.includes(o.sha256));if(n)return n;let i=e.map(o=>si(o.sha1)).join(", "),r=t.certificateSha1s.map(si).join(", ");throw new Error(`${vt(t)} was created for a different signing certificate. P12 fingerprint(s): ${i||"none"}; profile fingerprint(s): ${r||"none"}. Run \`mach credentials\` to regenerate the profile with the selected certificate.`)}var Ea=(e,t)=>e?e===t||e==="*"?!0:e.endsWith(".*")?t.startsWith(`${e.slice(0,-2)}.`):!1:!1;function mn(e,t){if(!Ea(e.bundleIdentifier,t.bundleIdentifier))throw new Error(`${vt(e)} is for ${e.bundleIdentifier||"an unknown bundle ID"}, not ${t.bundleIdentifier}.`);if(t.teamId&&e.teamId&&e.teamId.toUpperCase()!==t.teamId.toUpperCase())throw new Error(`${vt(e)} belongs to Apple Team ${e.teamId}, not ${t.teamId}.`);let n=e.isDevelopment?"development":e.isAppStore?"store":"adhoc";if(n!==t.distributionType)throw new Error(`${vt(e)} is a ${n} profile, not the requested ${t.distributionType} profile.`)}function Cr(e,t){let n=e.filter(r=>t.certificateSha1s.includes(r.sha1));if(n.length===0){let r=t.certificateSha1s.map(si).join(", ");throw new Error(`${vt(t)} does not include any certificate imported from the selected P12. Expected fingerprint(s): ${r||"none"}. Run \`mach credentials\` to repair this signing pair.`)}let i=t.isDevelopment?/\b(Development|Developer)\b/i:/\bDistribution\b/i;return n.find(r=>i.test(r.name))||n[0]}var vr=e=>e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;"),li=(e,t)=>{let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`<key>${n}<\\/key>\\s*<string>([^<]+)<\\/string>`))?.[1]?.trim()},Pa=e=>{let t=li(e,"application-identifier");if(!t)return;let n=e.match(/<key>TeamIdentifier<\/key>\s*<array>\s*<string>([^<]+)<\/string>/)?.[1]?.trim();if(n&&t.startsWith(`${n}.`))return t.slice(n.length+1);let i=t.indexOf(".");return i>=0?t.slice(i+1):t},Ra=(e,t)=>e===t||e==="*"?!0:e.endsWith(".*")?t.startsWith(`${e.slice(0,-2)}.`):!1;function Nr(e){let t=e.profileDirectory||ve.join(gn.homedir(),"Library","MobileDevice","Provisioning Profiles");return xe.mkdirSync(t,{recursive:!0}),e.profiles.map((n,i)=>{let r=ve.join(gn.tmpdir(),`mach-profile-${e.buildId}-${i}.mobileprovision`);xe.writeFileSync(r,Buffer.from(n.profileBase64,"base64"),{mode:384});try{let o=Rr("security",["cms","-D","-i",r],{encoding:"utf8",maxBuffer:5242880}),s=li(o,"UUID");if(!s)throw new Error(`Provisioning profile for ${n.bundleIdentifier} has no UUID.`);let a=Pa(o);if(!a||!Ra(a,n.bundleIdentifier))throw new Error(`Provisioning profile mismatch for ${n.bundleIdentifier}; profile contains ${a||"an unknown App ID"}.`);let l=/<key>get-task-allow<\/key>\s*<true\/>/.test(o),c=o.includes("<key>ProvisionedDevices</key>"),d=ai(o);if(d.certificateSha1s.length===0)throw new Error(`Provisioning profile for ${n.bundleIdentifier} has no embedded signing certificates.`);let u=ve.join(t,`${s}.mobileprovision`);return xe.copyFileSync(r,u),xe.chmodSync(u,384),{targetName:n.targetName,bundleIdentifier:n.bundleIdentifier,isMainApplication:n.isMainApplication,uuid:s,name:li(o,"Name"),isAppStore:!c&&!l,isDevelopment:l,signingProfile:d}}finally{try{xe.unlinkSync(r)}catch{}}})}var kr=(e,t=[])=>{if(!xe.existsSync(e))return t;for(let n of xe.readdirSync(e,{withFileTypes:!0})){if(n.name==="Pods"||n.name==="build"||n.name==="DerivedData")continue;let i=ve.join(e,n.name);if(n.isDirectory()&&n.name.endsWith(".xcodeproj")){let r=ve.join(i,"project.pbxproj");xe.existsSync(r)&&t.push(r);continue}n.isDirectory()&&kr(i,t)}return t},Er=e=>e.filter(t=>!!(t&&xe.existsSync(t))),ci=e=>{if(!xe.existsSync(e))return[];try{return xe.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>ve.join(e,t.name))}catch{return[]}},Pr=(e,t,n)=>{let i=xr(e,t,{env:n,encoding:"utf8",stdio:["ignore","pipe","ignore"]});if(!(i.error||i.status!==0))return i.stdout.trim()||void 0};function xa(e={}){let t=e.baseEnv||process.env,n=e.homeDirectory||gn.homedir(),i=String(t.GEM_PATH||"").split(ve.delimiter).filter(Boolean),r=String(t.PATH||"").split(ve.delimiter).filter(Boolean),o=[...e.fastlaneGemRoots||[],t.FASTLANE_GEM_HOME,...ci(ve.join(n,".local/share/fastlane")),...ci("/opt/homebrew/Cellar/fastlane").map(a=>ve.join(a,"libexec")),...ci("/usr/local/Cellar/fastlane").map(a=>ve.join(a,"libexec")),...i],s=[...e.rubyBinDirectories||[],t.FASTLANE_BIN_DIR,"/opt/homebrew/opt/ruby/bin","/usr/local/opt/ruby/bin",...r];return{...t,PATH:[...new Set(Er(s))].join(ve.delimiter),GEM_PATH:[...new Set(Er(o))].join(ve.delimiter),FASTLANE_INSTALLED_VIA_HOMEBREW:t.FASTLANE_INSTALLED_VIA_HOMEBREW||"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1"}}var Na=e=>{let t={...process.env},n=Pr("brew",["--prefix","fastlane"],t),i=Pr("brew",["--prefix","ruby"],t),r=xa({baseEnv:t,fastlaneGemRoots:n?[ve.join(n,"libexec")]:[],rubyBinDirectories:i?[ve.join(i,"bin")]:[]}),o=[...process.env.MACH_XCODEPROJ_RUBY?[{command:process.env.MACH_XCODEPROJ_RUBY,prefixArguments:[],env:r}]:[],{command:"ruby",prefixArguments:[],env:r},{command:"bundle",prefixArguments:["exec","ruby"],env:r}];for(let s of o){let a=xr(s.command,[...s.prefixArguments,"-e","require 'xcodeproj'; print Xcodeproj::VERSION"],{cwd:e,env:s.env,encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(!a.error&&a.status===0)return s}throw new Error(["Mach could not load the Ruby xcodeproj library required for multi-target iOS signing.","Install Fastlane with Homebrew (`brew install fastlane`) or install the xcodeproj gem in the runner Ruby environment.","Mach checks Homebrew Fastlane, FASTLANE_GEM_HOME, and `bundle exec ruby` automatically."].join(" "))},ka=String.raw`
495
+ `+n.slice(s)}return Ye.writeFileSync(e,o),!0},Qs=(e,t)=>{if(!zs(e,t)){if(process.platform!=="darwin")throw new Error(`Could not update binary Info.plist outside macOS: ${e}`);try{Yn("/usr/bin/plutil",["-replace","CFBundleVersion","-string",t,e])}catch{Yn("/usr/bin/plutil",["-insert","CFBundleVersion","-string",t,e])}}},ir=(e,t,n)=>{let i=wt(t,"resolved MACH build"),r=gt.resolve(e),o=new Set;if(n)try{for(let c of Ys(r,n))o.add(c)}catch{}for(let c of nr(r))o.add(c);let s=[...o].sort(),a=new Map,l=!1;try{for(let c of s)a.set(c,Ye.readFileSync(c)),Qs(c,i)}catch(c){for(let[d,u]of a)Ye.writeFileSync(d,u);throw c}return{buildNumber:i,plistPaths:s,restore:()=>{if(!l){l=!0;for(let[c,d]of a)Ye.existsSync(c)&&Ye.writeFileSync(c,d)}}}},zn=(e,t,n)=>{let i=wt(e,n),r=wt(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 rr}from"child_process";import Ht from"fs";import xe from"path";import qs from"adm-zip";var Qn=(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")},Xt=e=>{let t=[],n=0;for(;n<e.length;){let i=Qn(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=Qn(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=Qn(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},or=(e,t)=>e.find(i=>i.number===t&&i.wireType===2)?.bytes?.toString("utf8"),ea=e=>{let n=Xt(e).find(o=>o.number===7&&o.wireType===2)?.bytes;if(!n)return null;let r=Xt(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()},ta=e=>{let n=Xt(e).find(c=>c.number===1&&c.wireType===2)?.bytes;if(!n)throw new Error("AAB base manifest has no root XML element");let o=Xt(n).filter(c=>c.number===4&&c.wireType===2).map(c=>Xt(c.bytes)).find(c=>or(c,2)==="versionCode");if(!o)throw new Error("AAB base manifest has no android:versionCode");let s=or(o,3)?.trim();if(s&&/^\d+$/.test(s))return We(s,"packaged AAB manifest");let a=o.find(c=>c.number===6&&c.wireType===2)?.bytes,l=a?ea(a):null;return We(l,"packaged AAB manifest")},sr=e=>{try{return Ht.accessSync(e,Ht.constants.X_OK),Ht.statSync(e).isFile()}catch{return!1}},qn=e=>String(process.env.PATH||"").split(xe.delimiter).filter(Boolean).map(t=>xe.join(t,e)),ar=()=>Array.from(new Set([process.env.ANDROID_HOME,process.env.ANDROID_SDK_ROOT,process.platform==="darwin"?xe.join(process.env.HOME||"","Library/Android/sdk"):xe.join(process.env.HOME||"","Android/Sdk"),"/opt/android-sdk"].filter(e=>!!e))),cr=e=>{try{return Ht.readdirSync(e).map(t=>xe.join(e,t)).filter(t=>Ht.statSync(t).isDirectory()).sort((t,n)=>n.localeCompare(t,void 0,{numeric:!0}))}catch{return[]}},na=()=>{let e=qn("apkanalyzer");for(let t of ar()){let n=xe.join(t,"cmdline-tools");e.push(xe.join(n,"latest/bin/apkanalyzer"));for(let i of cr(n))e.push(xe.join(i,"bin/apkanalyzer"))}return e},ia=()=>{let e=[...qn("aapt2"),...qn("aapt")];for(let t of ar())for(let n of cr(xe.join(t,"build-tools")))e.push(xe.join(n,"aapt2"),xe.join(n,"aapt"));return e},ra=e=>{let t=e.trim();return/^\d+$/.test(t)?t:null},oa=e=>e.match(/^package:.*\bversionCode='(\d+)'/m)?.[1]||null,sa=(e,t)=>{let n=t.apkanalyzer??na();for(let r of n)if(sr(r))try{let o=rr(r,["manifest","version-code",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=ra(o);if(s)return We(s,"packaged APK manifest")}catch{}let i=t.aapt??ia();for(let r of i)if(sr(r))try{let o=rr(r,["dump","badging",e],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}),s=oa(o);if(s)return We(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.")},aa=(e,t={})=>{let n=xe.extname(e).toLowerCase();if(n===".apk")return sa(e,t);if(n!==".aab")throw new Error(`Unsupported Android artifact for version validation: ${e}`);let i;try{i=new qs(e)}catch(o){throw new Error(`Could not open AAB ${xe.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 ${xe.basename(e)} has no base module manifest`);try{return ta(r.getData())}catch(o){throw new Error(`Could not read versionCode from ${xe.basename(e)}: ${o.message}`)}},cn=(e,t,n={})=>{let i=We(t,"resolved MACH build assignment"),r=aa(e,n);if(r!==i)throw new Error(`Android versionCode mismatch in ${xe.basename(e)}: expected ${i}, packaged ${r}. MACH stopped the build before upload.`);return r};var lr=`import org.gradle.api.GradleException
496
+
497
+ def rawMachVersionCode = System.getenv('ANDROID_VERSION_CODE')
498
+ if (rawMachVersionCode == null || !(rawMachVersionCode ==~ /[0-9]+/)) {
499
+ throw new GradleException('[MACH VERSIONING] ANDROID_VERSION_CODE must be a positive integer.')
500
+ }
501
+
502
+ def machVersionCode = rawMachVersionCode.toLong()
503
+ if (machVersionCode < 1L || machVersionCode > 2100000000L) {
504
+ throw new GradleException('[MACH VERSIONING] ANDROID_VERSION_CODE must be between 1 and 2100000000.')
505
+ }
506
+
507
+ def machVersionState = [
508
+ applicationPluginSeen: false,
509
+ configuredOutputs: []
510
+ ]
511
+
512
+ gradle.beforeProject { project ->
513
+ project.pluginManager.withPlugin('com.android.application') {
514
+ machVersionState.applicationPluginSeen = true
515
+ def androidComponents = project.extensions.findByName('androidComponents')
516
+ if (androidComponents == null) {
517
+ throw new GradleException(
518
+ '[MACH VERSIONING] The Android application plugin does not expose the public ' +
519
+ 'Android Components API. Upgrade the Android Gradle Plugin before building with Mach.'
520
+ )
521
+ }
522
+
523
+ androidComponents.onVariants(androidComponents.selector().all()) { variant ->
524
+ variant.outputs.each { output ->
525
+ def configuredVersionCode = output.versionCode.orNull
526
+ output.versionCode.set(Math.toIntExact(machVersionCode))
527
+ output.versionCode.disallowChanges()
528
+ machVersionState.configuredOutputs.add([
529
+ projectPath: project.path,
530
+ variantName: variant.name,
531
+ configuredVersionCode: configuredVersionCode,
532
+ versionCode: output.versionCode
533
+ ])
534
+ }
535
+ }
536
+ }
537
+ }
538
+
539
+ gradle.projectsLoaded { loadedGradle ->
540
+ loadedGradle.rootProject.tasks.register('machVerifyInjectedVersionCode') {
541
+ group = 'verification'
542
+ description = 'Verifies Mach locked the assigned Android versionCode before compilation.'
543
+
544
+ doLast {
545
+ if (!machVersionState.applicationPluginSeen) {
546
+ throw new GradleException(
547
+ '[MACH VERSIONING] No module applies com.android.application. ' +
548
+ 'Mach cannot safely inject the assigned Android versionCode.'
549
+ )
550
+ }
551
+ if (machVersionState.configuredOutputs.isEmpty()) {
552
+ throw new GradleException(
553
+ '[MACH VERSIONING] No Android application variant outputs were found. ' +
554
+ 'Mach stopped before compilation to prevent a wrongly versioned artifact.'
555
+ )
556
+ }
557
+
558
+ machVersionState.configuredOutputs.each { configured ->
559
+ def actual = configured.versionCode.get()
560
+ if (actual != Math.toIntExact(machVersionCode)) {
561
+ throw new GradleException(
562
+ '[MACH VERSIONING] Could not lock versionCode for ' +
563
+ configured.projectPath + ':' + configured.variantName +
564
+ '. Expected ' + machVersionCode + ', resolved ' + actual + '.'
565
+ )
566
+ }
567
+ if (configured.configuredVersionCode != null &&
568
+ configured.configuredVersionCode != Math.toIntExact(machVersionCode)) {
569
+ println('[MACH VERSIONING] Corrected ' + configured.projectPath + ':' +
570
+ configured.variantName + ' versionCode ' +
571
+ configured.configuredVersionCode + ' -> ' + machVersionCode + '.')
572
+ }
573
+ }
574
+
575
+ println('[MACH VERSIONING] Preflight passed: locked versionCode ' + machVersionCode +
576
+ ' for ' + machVersionState.configuredOutputs.size() + ' Android variant output(s).')
577
+ }
578
+ }
579
+ }
580
+ `,dr="machVerifyInjectedVersionCode";import oe from"fs";import ee from"path";var ei=e=>{let t=ee.join(e,"package.json");if(!oe.existsSync(t))return null;try{return JSON.parse(oe.readFileSync(t,"utf8"))}catch{return null}},ur=e=>{if(on(e)){let r=12;return oe.existsSync(ee.join(e,"android"))&&(r+=3),oe.existsSync(ee.join(e,"ios"))&&(r+=3),oe.existsSync(ee.join(e,"lib/main.dart"))&&(r+=2),/^(app|mobile)$/i.test(ee.basename(e))&&(r+=1),r}let t=ei(e);if(!t)return 0;let n={...t.dependencies||{},...t.devDependencies||{}},i=0;return n.expo&&(i+=8),n["react-native"]&&(i+=8),oe.existsSync(ee.join(e,"android"))&&(i+=3),oe.existsSync(ee.join(e,"ios"))&&(i+=3),/^(app|mobile)$/i.test(ee.basename(e))&&(i+=1),i},ca=e=>{let t=ee.join(e,"pubspec.yaml");if(!oe.existsSync(t))return[];try{let n=oe.readFileSync(t,"utf8").split(/\r?\n/),i=[],r=null;for(let o of n){if(!o.trim()||o.trimStart().startsWith("#"))continue;let s=o.length-o.trimStart().length;if(r===null){/^workspace:\s*(?:#.*)?$/.test(o.trim())&&(r=s);continue}if(s<=r)break;let a=o.trim().match(/^-\s*['"]?([^'"#]+?)['"]?\s*(?:#.*)?$/)?.[1]?.trim();a&&i.push(a)}return i}catch{return[]}},la=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"):[]},da=(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(ee.resolve(e,r));continue}let o=r.match(/^(.*)\/\*$/);if(!o)continue;let s=ee.resolve(e,o[1]);if(!(!oe.existsSync(s)||!oe.statSync(s).isDirectory()))for(let a of oe.readdirSync(s,{withFileTypes:!0}))a.isDirectory()&&n.add(ee.join(s,a.name))}for(let i of["apps","packages"]){let r=ee.join(e,i);if(!(!oe.existsSync(r)||!oe.statSync(r).isDirectory()))for(let o of oe.readdirSync(r,{withFileTypes:!0}))o.isDirectory()&&n.add(ee.join(r,o.name))}return Array.from(n)},hu=e=>{let t=ee.resolve(e);if(ur(t)>0)return".";let n=ei(t),i=[...la(n),...ca(t)],r=da(t,i).map(o=>({directory:o,score:ur(o)})).filter(o=>o.score>0).sort((o,s)=>s.score-o.score||o.directory.localeCompare(s.directory));return r.length===0||r[1]&&r[1].score===r[0].score?null:ee.relative(t,r[0].directory).split(ee.sep).join("/")},yu=(e,t)=>{let n=ze(e,t,{requireAppDirectory:!0});if(on(n.appRoot))return"flutter";let i=ei(n.appRoot);return{...i?.dependencies||{},...i?.devDependencies||{}}.expo?"expo":"react-native"},ua=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(ee.posix.isAbsolute(n)||/^[A-Za-z]:\//.test(n))throw new Error("appDirectory must be relative to the project root.");let i=ee.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(/\/+$/,"")},ze=(e,t,n={})=>{let i=ee.resolve(e),r=ua(t),o=ee.resolve(i,...r.split("/").filter(a=>a&&a!==".")),s=ee.relative(i,o);if(s===".."||s.startsWith(`..${ee.sep}`)||ee.isAbsolute(s))throw new Error("appDirectory must stay inside the project root.");if(n.requireAppDirectory){if(!oe.existsSync(o)||!oe.statSync(o).isDirectory())throw new Error(`Configured appDirectory "${r}" does not exist inside the project root.`);if(!oe.existsSync(ee.join(o,"package.json"))&&!oe.existsSync(ee.join(o,"pubspec.yaml")))throw new Error(`Configured appDirectory "${r}" must contain a package.json or pubspec.yaml.`);let a=oe.realpathSync(i),l=oe.realpathSync(o),c=ee.relative(a,l);if(c===".."||c.startsWith(`..${ee.sep}`)||ee.isAbsolute(c))throw new Error("Configured appDirectory resolves outside the project root.")}return{sourceRoot:i,appDirectory:r,appRoot:o}},Iu=(e,t,n)=>{if(t==="flutter"){if(Qi(e.appRoot),n==="web"){let r=ee.join(e.appRoot,"web");if(!oe.existsSync(r)||!oe.statSync(r).isDirectory())throw new Error(`Flutter web build requires web/ inside appDirectory "${e.appDirectory}". Run \`flutter create . --platforms web\` to add it.`);return}let i=ee.join(e.appRoot,n);if(!oe.existsSync(i)||!oe.statSync(i).isDirectory())throw new Error(`Flutter ${n==="ios"?"iOS":"Android"} build requires ${n}/ inside appDirectory "${e.appDirectory}".`);return}if(n==="web")throw new Error("Web builds are currently supported only for Flutter projects.");if(t==="react-native"){if(n==="android"){let i=ee.join(e.appRoot,"android/gradlew"),r=ee.join(e.appRoot,"gradlew");if(!oe.existsSync(i)&&!oe.existsSync(r))throw new Error(`React Native Android build requires android/gradlew inside appDirectory "${e.appDirectory}".`);return}if(!oe.existsSync(ee.join(e.appRoot,"ios/Podfile")))throw new Error(`React Native iOS build requires ios/Podfile inside appDirectory "${e.appDirectory}".`)}};import ti from"fs";import dn from"path";import{spawnSync as pa}from"child_process";var we=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},pr=e=>e==null?void 0:we(String(e)),mr=e=>{if(!ti.existsSync(e))return null;try{return JSON.parse(ti.readFileSync(e,"utf-8"))}catch{return null}},fa=e=>{let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{let n=t.indexOf("{"),i=t.lastIndexOf("}");if(n<0||i<=n)return null;try{return JSON.parse(t.slice(n,i+1))}catch{return null}}};function fr(e=process.cwd()){let t=mr(dn.join(e,"package.json"))||{};return we(t.version)}function ma(e=process.cwd()){let t=mr(dn.join(e,"package.json"))||{},n={...t.dependencies||{},...t.devDependencies||{}};if(n.expo)return"expo";if(n["react-native"])return"react-native"}function gr(e=process.cwd(),t={}){let n=process.platform==="win32"?dn.join(e,"node_modules",".bin","expo.cmd"):dn.join(e,"node_modules",".bin","expo"),i=ti.existsSync(n),s=pa(i?n:"npx",i?["config","--type","public","--json"]:["--no-install","expo","config","--type","public","--json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","pipe"],env:{...process.env,EXPO_NO_TELEMETRY:"1",...t}});return s.error||s.status!==0?null:fa(s.stdout||"")}var hr=e=>{let t=we(e);if(!(!t||t==="manual"))return t},ln=(e,t,n,i={})=>{let r=we(e);if(r)return r;if(!e||typeof e!="object")return;let o=we(e.policy);if(o==="appVersion")return we(t.version);if(o==="sdkVersion")return we(t.sdkVersion);if(o==="nativeVersion"){let s=we(t.version);if(!s||!n)return;let a=n==="ios"?pr(i.iosBuildNumber)||pr(t.ios?.buildNumber):i.androidVersionCode!==void 0?String(i.androidVersionCode).trim():t.android?.versionCode!==void 0?String(t.android.versionCode).trim():void 0;return!a||a.toLowerCase()==="auto"?s:a?`${s}(${a})`:s}};function ga(e,t,n={},i){let r=t?ln(e[t]?.runtimeVersion,e,t,n):void 0;if(r)return r;let o=ln(e.runtimeVersion,e,t,n);return o||(i?ln({policy:i},e,t,n):void 0)}function ha(e,t){if(!(!e||typeof e!="object"))return we(t?e[t]?.runtimeVersion:void 0)||we(e.runtimeVersion)}function wu(e,t={}){return we(t.MACH_OTA_CHANNEL)||we(e.ota?.channel)||"production"}function yr(e,t){return[e?.runtimeVersion!==t.runtimeVersion?`runtime ${e?.runtimeVersion||"missing"} (expected ${t.runtimeVersion})`:void 0,e?.channel!==t.channel?`channel ${e?.channel||"missing"} (expected ${t.channel})`:void 0,e?.url!==t.url?`URL ${e?.url||"missing"} (expected ${t.url})`:void 0].filter(n=>!!n)}function Ir(e,t){let n=gr(e,{MACH_OTA_RUNTIME_VERSION:t.runtimeVersion,MACH_OTA_CHANNEL:t.channel,MACH_OTA_URL:t.url});return n?{runtimeVersion:ha(n,t.platform),channel:we(n.updates?.requestHeaders?.["expo-channel-name"]),url:we(n.updates?.url),expoConfig:n}:null}function ya(e,t,n={}){let i=we(n.runtimeVersion)||we(e.ota?.runtimeVersion);if(i)return i;let r={iosBuildNumber:n.iosBuildNumber,androidVersionCode:n.androidVersionCode},o=hr(e.ota?.runtimeVersionPolicy);if(o){let s=ln({policy:o},t,n.platform,r);if(s)return s}return ga(t,n.platform,r)}function vu(e,t={}){let n=t.cwd||process.cwd(),i=we(t.runtimeVersion)||we(e.ota?.runtimeVersion);if(i)return i;let r=hr(e.ota?.runtimeVersionPolicy),o={iosBuildNumber:t.iosBuildNumber,androidVersionCode:t.androidVersionCode};if((t.framework||e.framework||ma(n))==="expo"){let a=gr(n),l=a?ya(e,a,{platform:t.platform,iosBuildNumber:o.iosBuildNumber,androidVersionCode:o.androidVersionCode}):void 0;if(l)return l}return fr(n)||"1.0.0"}import Kt from"fs";import ni from"path";import{spawnSync as Ia}from"child_process";var un=/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/;function br(e){if(!e||typeof e!="object")return;let t=e,n=typeof t.targetName=="string"?t.targetName.trim():"",i=typeof t.bundleIdentifier=="string"?t.bundleIdentifier.trim():"";if(!(!n||n.length>128||/[\r\n\0]/.test(n)||!un.test(i)))return{targetName:n,bundleIdentifier:i}}function ii(e){if(!e||typeof e!="object")return[];let t=e,i=(t.expo&&typeof t.expo=="object"?t.expo:t)?.extra?.eas?.build?.experimental?.ios?.appExtensions;return Array.isArray(i)?i.map(br).filter(Boolean):[]}function Aa(e){for(let t of["app.json","app.config.json"]){let n=ni.join(e,t);if(Kt.existsSync(n))try{return ii(JSON.parse(Kt.readFileSync(n,"utf8")))}catch{return[]}}return[]}function ba(e){let t=Ia(process.platform==="win32"?"npx.cmd":"npx",["--no-install","expo","config","--type","public","--json"],{cwd:e,encoding:"utf8",timeout:15e3,maxBuffer:5242880,stdio:["ignore","pipe","ignore"]});if(t.status!==0||!t.stdout)return[];try{return ii(JSON.parse(t.stdout))}catch{return[]}}function Ar(e,t,n){let i=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`${i}(?:\\s+\\/\\*[^\\n]*\\*\\/)?\\s*=\\s*\\{\\s*isa\\s*=\\s*${n};([\\s\\S]*?)\\n\\s*\\};`))?.[1]}function Sa(e){let t=ni.join(e,"ios");if(!Kt.existsSync(t))return[];let n=[],i=o=>{for(let s of Kt.readdirSync(o,{withFileTypes:!0})){if(s.name==="Pods"||s.name==="build")continue;let a=ni.join(o,s.name);s.isDirectory()?i(a):s.name==="project.pbxproj"&&n.push(a)}};i(t);let r=[];for(let o of n){let s=Kt.readFileSync(o,"utf8"),a=/([A-Fa-f0-9]{24})(?: \/\* ([^*\n]+) \*\/)? = \{\s*isa = PBXNativeTarget;([\s\S]*?)\n\s*\};/g;for(let l of s.matchAll(a)){let c=l[3]||"";if(!/productType\s*=\s*"?com\.apple\.product-type\.app-extension"?;/.test(c))continue;let d=(c.match(/\bname\s*=\s*"?([^";\n]+)"?;/)?.[1]||l[2]||"").trim(),u=c.match(/buildConfigurationList\s*=\s*([A-Fa-f0-9]{24})/)?.[1];if(!d||!u)continue;let f=[...(Ar(s,u,"XCConfigurationList")||"").matchAll(/([A-Fa-f0-9]{24})(?: \/\*[^*\n]+\*\/)?/g)].map(P=>P[1]),m;for(let P of f){let R=Ar(s,P,"XCBuildConfiguration")?.match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/)?.[1]?.trim();if(R&&!R.includes("$")&&un.test(R)){m=R;break}}m&&r.push({targetName:d,bundleIdentifier:m})}}return r}function Ca(e,t,n){if(!un.test(e))throw new Error(`Invalid main iOS bundle identifier "${e}".`);let i=[{targetName:t,bundleIdentifier:e,isMainApplication:!0}],r=new Set([e]),o=new Set(t?[t]:[]);for(let s of n){let a=br(s);if(!a)throw new Error("Each ios.appExtensions entry requires a valid targetName and bundleIdentifier.");if(r.has(a.bundleIdentifier))throw new Error(`Duplicate iOS signing bundle identifier "${a.bundleIdentifier}".`);if(o.has(a.targetName))throw new Error(`Duplicate iOS signing target name "${a.targetName}".`);r.add(a.bundleIdentifier),o.add(a.targetName),i.push({...a,isMainApplication:!1})}return i}function xu(e){let{config:t,resolvedProfile:n,framework:i,appRoot:r}=e,o=n?.ios?.appExtensions??t?.ios?.appExtensions,s=Array.isArray(o)?o:[];return s.length===0&&(s=ii(t?.expo)),s.length===0&&i==="expo"&&(s=Aa(r)),s.length===0&&i==="expo"&&(s=ba(r)),s.length===0&&(s=Sa(r)),Ca(e.mainBundleIdentifier,e.mainTargetName,s)}function ku(e){return JSON.stringify({version:1,profiles:e})}function Sr(e){if(!e)return[];let t;try{t=JSON.parse(e)}catch{throw new Error("IOS_PROVISIONING_PROFILES contains invalid JSON.")}let n=t;if(n.version!==1||!Array.isArray(n.profiles))throw new Error("IOS_PROVISIONING_PROFILES has an unsupported format.");return n.profiles.map(i=>{let r=i.isMainApplication===!0,o=typeof i.bundleIdentifier=="string"?i.bundleIdentifier.trim():"",s=typeof i.targetName=="string"?i.targetName.trim():"";if(!un.test(o)||!r&&(!s||s.length>128||/[\r\n\0]/.test(s))||typeof i.profileBase64!="string"||i.profileBase64.length<64)throw new Error("IOS_PROVISIONING_PROFILES contains an invalid profile.");return{targetName:s||void 0,bundleIdentifier:o,isMainApplication:r,profileBase64:i.profileBase64}})}import Ne from"fs";import gn from"os";import ve from"path";import{execFileSync as xr,spawnSync as kr}from"child_process";import{spawnSync as ri}from"child_process";import Cr from"crypto";import wa from"fs";var pn=e=>String(e||"").replace(/[^a-fA-F0-9]/g,"").toUpperCase(),oi=(e,t)=>{let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`<key>${n}<\\/key>\\s*<string>([^<]+)<\\/string>`))?.[1]?.trim()},va=(e,t)=>{let n=oi(e,"application-identifier");if(!n)return;if(t&&n.startsWith(`${t}.`))return n.slice(t.length+1);let i=n.indexOf(".");return i>=0?n.slice(i+1):n},wr=e=>{let t=new Cr.X509Certificate(e);return{sha1:pn(t.fingerprint),sha256:pn(t.fingerprint256),serial:pn(t.serialNumber),subject:t.subject}},Ea=e=>(e.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g)||[]).map(n=>new Cr.X509Certificate(n).raw);function ai(e){let t=e.match(/<key>TeamIdentifier<\/key>\s*<array>\s*<string>([^<]+)<\/string>/)?.[1]?.trim(),n=e.match(/<key>DeveloperCertificates<\/key>\s*<array>([\s\S]*?)<\/array>/)?.[1]||"",r=Array.from(n.matchAll(/<data>\s*([\s\S]*?)\s*<\/data>/g),a=>a[1].replace(/\s+/g,"")).filter(Boolean).map(a=>wr(Buffer.from(a,"base64"))),o=/<key>get-task-allow<\/key>\s*<true\/>/.test(e),s=e.includes("<key>ProvisionedDevices</key>");return{uuid:oi(e,"UUID"),name:oi(e,"Name"),teamId:t,bundleIdentifier:va(e,t),isDevelopment:o,isAppStore:!o&&!s,certificateSha1s:r.map(a=>a.sha1),certificateSha256s:r.map(a=>a.sha256)}}var Pa=e=>{let t=wa.readFileSync(e,"utf8");if(t.includes("<plist")&&t.includes("DeveloperCertificates"))return t;let n=ri("security",["cms","-D","-i",e],{encoding:"utf8",maxBuffer:5*1024*1024});if(!n.error&&n.status===0&&n.stdout?.includes("<plist"))return n.stdout;let i=ri("openssl",["smime","-verify","-inform","DER","-in",e,"-noverify"],{encoding:"utf8",maxBuffer:5*1024*1024});if(!i.error&&i.status===0&&i.stdout?.includes("<plist"))return i.stdout;let r=[n.stderr,i.stderr,n.error?.message,i.error?.message].filter(Boolean).join(`
581
+ `).trim();throw new Error(`Could not decode provisioning profile${r?`: ${r}`:"."}`)};function Et(e){return ai(Pa(e))}function Jt(e,t){let n=[!0,!1],i;for(let o of n){let s=ri("openssl",["pkcs12","-in",e,"-clcerts","-nokeys","-passin",`pass:${t}`,...o?["-legacy"]:[]],{encoding:"utf8",maxBuffer:5242880});if(i=s,s.error||s.status!==0||!s.stdout)continue;let a=Ea(s.stdout).map(wr);if(a.length>0)return a}let r=[i?.stderr,i?.error?.message].filter(Boolean).join(`
582
+ `).trim();throw new Error(`Could not read signing certificate from .p12${r?`: ${r}`:"."}`)}function vr(e){let t=Array.from(e.matchAll(/\)\s*([A-Fa-f0-9]{40})\s+"([^"]+)"/g),i=>({sha1:pn(i[1]),name:i[2]})),n=new Set;return t.filter(i=>n.has(i.sha1)?!1:(n.add(i.sha1),!0))}var vt=e=>e.name||e.uuid||"selected provisioning profile",si=e=>e.length>12?`${e.slice(0,12)}\u2026`:e;function fn(e,t){if(t.certificateSha1s.length===0)throw new Error(`${vt(t)} has no embedded signing certificates.`);let n=e.find(o=>t.certificateSha1s.includes(o.sha1)||t.certificateSha256s.includes(o.sha256));if(n)return n;let i=e.map(o=>si(o.sha1)).join(", "),r=t.certificateSha1s.map(si).join(", ");throw new Error(`${vt(t)} was created for a different signing certificate. P12 fingerprint(s): ${i||"none"}; profile fingerprint(s): ${r||"none"}. Run \`mach credentials\` to regenerate the profile with the selected certificate.`)}var Ra=(e,t)=>e?e===t||e==="*"?!0:e.endsWith(".*")?t.startsWith(`${e.slice(0,-2)}.`):!1:!1;function mn(e,t){if(!Ra(e.bundleIdentifier,t.bundleIdentifier))throw new Error(`${vt(e)} is for ${e.bundleIdentifier||"an unknown bundle ID"}, not ${t.bundleIdentifier}.`);if(t.teamId&&e.teamId&&e.teamId.toUpperCase()!==t.teamId.toUpperCase())throw new Error(`${vt(e)} belongs to Apple Team ${e.teamId}, not ${t.teamId}.`);let n=e.isDevelopment?"development":e.isAppStore?"store":"adhoc";if(n!==t.distributionType)throw new Error(`${vt(e)} is a ${n} profile, not the requested ${t.distributionType} profile.`)}function Er(e,t){let n=e.filter(r=>t.certificateSha1s.includes(r.sha1));if(n.length===0){let r=t.certificateSha1s.map(si).join(", ");throw new Error(`${vt(t)} does not include any certificate imported from the selected P12. Expected fingerprint(s): ${r||"none"}. Run \`mach credentials\` to repair this signing pair.`)}let i=t.isDevelopment?/\b(Development|Developer)\b/i:/\bDistribution\b/i;return n.find(r=>i.test(r.name))||n[0]}var Pr=e=>e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;"),li=(e,t)=>{let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`<key>${n}<\\/key>\\s*<string>([^<]+)<\\/string>`))?.[1]?.trim()},Na=e=>{let t=li(e,"application-identifier");if(!t)return;let n=e.match(/<key>TeamIdentifier<\/key>\s*<array>\s*<string>([^<]+)<\/string>/)?.[1]?.trim();if(n&&t.startsWith(`${n}.`))return t.slice(n.length+1);let i=t.indexOf(".");return i>=0?t.slice(i+1):t},xa=(e,t)=>e===t||e==="*"?!0:e.endsWith(".*")?t.startsWith(`${e.slice(0,-2)}.`):!1;function _r(e){let t=e.profileDirectory||ve.join(gn.homedir(),"Library","MobileDevice","Provisioning Profiles");return Ne.mkdirSync(t,{recursive:!0}),e.profiles.map((n,i)=>{let r=ve.join(gn.tmpdir(),`mach-profile-${e.buildId}-${i}.mobileprovision`);Ne.writeFileSync(r,Buffer.from(n.profileBase64,"base64"),{mode:384});try{let o=xr("security",["cms","-D","-i",r],{encoding:"utf8",maxBuffer:5242880}),s=li(o,"UUID");if(!s)throw new Error(`Provisioning profile for ${n.bundleIdentifier} has no UUID.`);let a=Na(o);if(!a||!xa(a,n.bundleIdentifier))throw new Error(`Provisioning profile mismatch for ${n.bundleIdentifier}; profile contains ${a||"an unknown App ID"}.`);let l=/<key>get-task-allow<\/key>\s*<true\/>/.test(o),c=o.includes("<key>ProvisionedDevices</key>"),d=ai(o);if(d.certificateSha1s.length===0)throw new Error(`Provisioning profile for ${n.bundleIdentifier} has no embedded signing certificates.`);let u=ve.join(t,`${s}.mobileprovision`);return Ne.copyFileSync(r,u),Ne.chmodSync(u,384),{targetName:n.targetName,bundleIdentifier:n.bundleIdentifier,isMainApplication:n.isMainApplication,uuid:s,name:li(o,"Name"),isAppStore:!c&&!l,isDevelopment:l,signingProfile:d}}finally{try{Ne.unlinkSync(r)}catch{}}})}var $r=(e,t=[])=>{if(!Ne.existsSync(e))return t;for(let n of Ne.readdirSync(e,{withFileTypes:!0})){if(n.name==="Pods"||n.name==="build"||n.name==="DerivedData")continue;let i=ve.join(e,n.name);if(n.isDirectory()&&n.name.endsWith(".xcodeproj")){let r=ve.join(i,"project.pbxproj");Ne.existsSync(r)&&t.push(r);continue}n.isDirectory()&&$r(i,t)}return t},Rr=e=>e.filter(t=>!!(t&&Ne.existsSync(t))),ci=e=>{if(!Ne.existsSync(e))return[];try{return Ne.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>ve.join(e,t.name))}catch{return[]}},Nr=(e,t,n)=>{let i=kr(e,t,{env:n,encoding:"utf8",stdio:["ignore","pipe","ignore"]});if(!(i.error||i.status!==0))return i.stdout.trim()||void 0};function ka(e={}){let t=e.baseEnv||process.env,n=e.homeDirectory||gn.homedir(),i=String(t.GEM_PATH||"").split(ve.delimiter).filter(Boolean),r=String(t.PATH||"").split(ve.delimiter).filter(Boolean),o=[...e.fastlaneGemRoots||[],t.FASTLANE_GEM_HOME,...ci(ve.join(n,".local/share/fastlane")),...ci("/opt/homebrew/Cellar/fastlane").map(a=>ve.join(a,"libexec")),...ci("/usr/local/Cellar/fastlane").map(a=>ve.join(a,"libexec")),...i],s=[...e.rubyBinDirectories||[],t.FASTLANE_BIN_DIR,"/opt/homebrew/opt/ruby/bin","/usr/local/opt/ruby/bin",...r];return{...t,PATH:[...new Set(Rr(s))].join(ve.delimiter),GEM_PATH:[...new Set(Rr(o))].join(ve.delimiter),FASTLANE_INSTALLED_VIA_HOMEBREW:t.FASTLANE_INSTALLED_VIA_HOMEBREW||"true",FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_HIDE_CHANGELOG:"1"}}var _a=e=>{let t={...process.env},n=Nr("brew",["--prefix","fastlane"],t),i=Nr("brew",["--prefix","ruby"],t),r=ka({baseEnv:t,fastlaneGemRoots:n?[ve.join(n,"libexec")]:[],rubyBinDirectories:i?[ve.join(i,"bin")]:[]}),o=[...process.env.MACH_XCODEPROJ_RUBY?[{command:process.env.MACH_XCODEPROJ_RUBY,prefixArguments:[],env:r}]:[],{command:"ruby",prefixArguments:[],env:r},{command:"bundle",prefixArguments:["exec","ruby"],env:r}];for(let s of o){let a=kr(s.command,[...s.prefixArguments,"-e","require 'xcodeproj'; print Xcodeproj::VERSION"],{cwd:e,env:s.env,encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(!a.error&&a.status===0)return s}throw new Error(["Mach could not load the Ruby xcodeproj library required for multi-target iOS signing.","Install Fastlane with Homebrew (`brew install fastlane`) or install the xcodeproj gem in the runner Ruby environment.","Mach checks Homebrew Fastlane, FASTLANE_GEM_HOME, and `bundle exec ruby` automatically."].join(" "))},$a=String.raw`
498
583
  require 'json'
499
584
  require 'xcodeproj'
500
585
 
@@ -539,50 +624,50 @@ unless missing.empty?
539
624
  end
540
625
 
541
626
  puts JSON.generate(matched)
542
- `;function _r(e){if(e.profiles.length<2)return{matchedTargets:[],restore:()=>{}};let t=kr(e.iosDirectory);if(t.length===0)throw new Error(`Multi-target iOS signing requires a committed .xcodeproj in ${e.iosDirectory}.`);let n=new Map(t.map(a=>[a,xe.readFileSync(a)])),i=xe.mkdtempSync(ve.join(gn.tmpdir(),`mach-signing-${e.temporaryLabel}-`)),r=ve.join(i,"profiles.json"),o=ve.join(i,"apply.rb");xe.writeFileSync(r,JSON.stringify({projects:t,profiles:e.profiles,teamId:e.teamId}),{mode:384}),xe.writeFileSync(o,ka,{mode:448});let s=()=>{for(let[a,l]of n)xe.writeFileSync(a,l)};try{let a=Na(e.iosDirectory),l=Rr(a.command,[...a.prefixArguments,o,r],{cwd:e.iosDirectory,env:a.env,encoding:"utf8",maxBuffer:5*1024*1024}),c=JSON.parse(l.trim()||"{}");return{matchedTargets:Object.entries(c).map(([d,u])=>`${u} (${d})`),restore:s}}catch(a){throw s(),a}finally{xe.rmSync(i,{recursive:!0,force:!0})}}function $r(e){return e.length===0?"":[" <key>provisioningProfiles</key>"," <dict>",...e.flatMap(t=>[` <key>${vr(t.bundleIdentifier)}</key>`,` <string>${vr(t.uuid)}</string>`])," </dict>"].join(`
543
- `)}var Lr=(e,t)=>t.filter(n=>I.existsSync(y.join(e,n))).reduce((n,i)=>n.update(I.readFileSync(y.join(e,i))),Vr.createHash("sha256")).digest("hex").slice(0,16),$a=e=>Lr(e,["package.json","yarn.lock","package-lock.json","bun.lockb"]),Tr=e=>Lr(e,["Podfile","Podfile.lock"]),Ta=e=>{let t=y.join(e,"fingerprint.json");try{return JSON.parse(I.readFileSync(t,"utf-8"))}catch{return{}}},di=(e,t)=>{I.mkdirSync(e,{recursive:!0}),I.writeFileSync(y.join(e,"fingerprint.json"),JSON.stringify(t,null,2))},Fa=7200*1e3,Oa=(e,t)=>{I.mkdirSync(e,{recursive:!0});let n=y.join(e,"build.lock");if(I.existsSync(n))try{let i=JSON.parse(I.readFileSync(n,"utf-8")),r=Date.now()-(i.timestamp||0);if(r<Fa)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}I.writeFileSync(n,JSON.stringify({buildId:t,pid:process.pid,timestamp:Date.now()}))},Da=(e,t)=>{let n=y.join(e,"build.lock");try{I.existsSync(n)&&JSON.parse(I.readFileSync(n,"utf-8")).buildId===t&&I.unlinkSync(n)}catch{}},Fr=15e5,Or=(e,t)=>{let n=e+t;return n.length>Fr?n.slice(-Fr):n},fi=e=>e.replace(/\u001b\[[0-9;]*m/g,""),Ur=e=>/^\s*\d+\s*\|/.test(e),mi=e=>{let t=fi(e).trim();return!t||Ur(t)?!1:/(?:^|\s)(?:fatal\s+)?error:|xcodebuild:\s*error|The following build commands failed|Command PhaseScriptExecution failed|PhaseScriptExecution|Command .* failed|CodeSign\b.*(?:failed|error:)|Provisioning profile.*(?:doesn't|does not|missing|not include|invalid|required)|No profiles|requires a provisioning profile|Undefined symbols|(?:^|\s)ld:|clang:\s*error|node: command not found|env: node|No such file or directory|Permission denied/i.test(t)},Ma=e=>{let t=new Set,n=[];e.forEach((r,o)=>{mi(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},Ba=(e,t,n,i)=>{let r=fi(i).replace(/\r/g,`
627
+ `;function Or(e){if(e.profiles.length<2)return{matchedTargets:[],restore:()=>{}};let t=$r(e.iosDirectory);if(t.length===0)throw new Error(`Multi-target iOS signing requires a committed .xcodeproj in ${e.iosDirectory}.`);let n=new Map(t.map(a=>[a,Ne.readFileSync(a)])),i=Ne.mkdtempSync(ve.join(gn.tmpdir(),`mach-signing-${e.temporaryLabel}-`)),r=ve.join(i,"profiles.json"),o=ve.join(i,"apply.rb");Ne.writeFileSync(r,JSON.stringify({projects:t,profiles:e.profiles,teamId:e.teamId}),{mode:384}),Ne.writeFileSync(o,$a,{mode:448});let s=()=>{for(let[a,l]of n)Ne.writeFileSync(a,l)};try{let a=_a(e.iosDirectory),l=xr(a.command,[...a.prefixArguments,o,r],{cwd:e.iosDirectory,env:a.env,encoding:"utf8",maxBuffer:5*1024*1024}),c=JSON.parse(l.trim()||"{}");return{matchedTargets:Object.entries(c).map(([d,u])=>`${u} (${d})`),restore:s}}catch(a){throw s(),a}finally{Ne.rmSync(i,{recursive:!0,force:!0})}}function Tr(e){return e.length===0?"":[" <key>provisioningProfiles</key>"," <dict>",...e.flatMap(t=>[` <key>${Pr(t.bundleIdentifier)}</key>`,` <string>${Pr(t.uuid)}</string>`])," </dict>"].join(`
628
+ `)}var Wr=(e,t)=>t.filter(n=>I.existsSync(y.join(e,n))).reduce((n,i)=>n.update(I.readFileSync(y.join(e,i))),Lr.createHash("sha256")).digest("hex").slice(0,16),Ta=e=>Wr(e,["package.json","yarn.lock","package-lock.json","bun.lockb"]),Fr=e=>Wr(e,["Podfile","Podfile.lock"]),Fa=e=>{let t=y.join(e,"fingerprint.json");try{return JSON.parse(I.readFileSync(t,"utf-8"))}catch{return{}}},di=(e,t)=>{I.mkdirSync(e,{recursive:!0}),I.writeFileSync(y.join(e,"fingerprint.json"),JSON.stringify(t,null,2))},Da=7200*1e3,Ma=(e,t)=>{I.mkdirSync(e,{recursive:!0});let n=y.join(e,"build.lock");if(I.existsSync(n))try{let i=JSON.parse(I.readFileSync(n,"utf-8")),r=Date.now()-(i.timestamp||0);if(r<Da)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}I.writeFileSync(n,JSON.stringify({buildId:t,pid:process.pid,timestamp:Date.now()}))},Va=(e,t)=>{let n=y.join(e,"build.lock");try{I.existsSync(n)&&JSON.parse(I.readFileSync(n,"utf-8")).buildId===t&&I.unlinkSync(n)}catch{}},Dr=15e5,Mr=(e,t)=>{let n=e+t;return n.length>Dr?n.slice(-Dr):n},fi=e=>e.replace(/\u001b\[[0-9;]*m/g,""),Gr=e=>/^\s*\d+\s*\|/.test(e),mi=e=>{let t=fi(e).trim();return!t||Gr(t)?!1:/(?:^|\s)(?:fatal\s+)?error:|xcodebuild:\s*error|The following build commands failed|Command PhaseScriptExecution failed|PhaseScriptExecution|Command .* failed|CodeSign\b.*(?:failed|error:)|Provisioning profile.*(?:doesn't|does not|missing|not include|invalid|required)|No profiles|requires a provisioning profile|Undefined symbols|(?:^|\s)ld:|clang:\s*error|node: command not found|env: node|No such file or directory|Permission denied/i.test(t)},Ba=e=>{let t=new Set,n=[];e.forEach((r,o)=>{mi(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},ja=(e,t,n,i)=>{let r=fi(i).replace(/\r/g,`
544
629
  `).split(`
545
- `).map(l=>l.trimEnd()).filter(Boolean),o=r.filter(mi),s=o.length>0?Ma(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?`
630
+ `).map(l=>l.trimEnd()).filter(Boolean),o=r.filter(mi),s=o.length>0?Ba(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?`
546
631
  ${a}:
547
632
  ${s.join(`
548
- `)}`:""].join("")},Va=e=>e==="xcodebuild"&&process.env.MACH_XCODE_FULL_LOGS!=="1",ja=e=>{let t=fi(e).trim();return!t||Ur(t)?!1:mi(t)||/ARCHIVE SUCCEEDED|ARCHIVE FAILED|EXPORT SUCCEEDED|EXPORT FAILED|Exported .* to:|\[IPA VALID\]/i.test(t)},$e=e=>{try{I.existsSync(e)&&I.rmSync(e,{recursive:!0,force:!0})}catch{}},La=(e,t)=>{try{if(!I.existsSync(e))return;for(let n of I.readdirSync(e))t(n)&&$e(y.join(e,n))}catch{}},Pt=e=>{R.info(w.dim("Clearing Metro/Hermes JS transform caches..."));let t=Ae.tmpdir();La(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(Ae.homedir(),".cache/metro")),$e(y.join(Ae.homedir(),".cache/react-native-packager")),$e(y.join(Ae.homedir(),"Library/Caches/metro")),$e(y.join(Ae.homedir(),"Library/Caches/react-native-packager"))},Ua=e=>/Internal inconsistency error|never received target ended message/i.test(String(e?.message||e)),Wa=e=>{R.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"))},Ga=e=>{let t=String(e?.message||e);return/Permission denied/i.test(t)&&/Pods\/.*\.sh/i.test(t)},Wr=e=>{let t=y.join(e,"Pods"),i=[y.join(t,"Target Support Files"),t].filter(a=>I.existsSync(a)),r=new Set,o=0,s=a=>{let l=a;try{l=I.realpathSync(a)}catch{}if(r.has(l))return;r.add(l);let c;try{c=I.readdirSync(a,{withFileTypes:!0})}catch{return}for(let d of c){let u=y.join(a,d.name);if(d.isDirectory()){s(u);continue}if(!(!d.isFile()||!d.name.endsWith(".sh")))try{let p=I.statSync(u),f=p.mode|493;f!==p.mode&&(I.chmodSync(u,f),o+=1)}catch{}}};for(let a of i)s(a);return o>0&&R.info(w.dim(`Repaired executable permissions on ${o} CocoaPods script${o===1?"":"s"}.`)),o},Za=(e,t,n,i,r)=>{let o=l=>{let c=l.filter(u=>u?.id&&String(u?.platform||"").includes("iOS Simulator")&&!u?.error),d=c.find(u=>/iphone/i.test(u.name||""))||c[0];return d?.id?`id=${d.id}`:void 0},s=l=>{let c=[],d=!1;for(let u of l.split(`
549
- `)){if(/Ineligible destinations/i.test(u)&&(d=!0),d||!u.includes("platform:iOS Simulator")||u.includes("error:"))continue;let p=u.match(/\bid:([^,}]+)/)?.[1]?.trim(),f=u.match(/\bname:([^,}]+)/)?.[1]?.trim();p&&c.push({id:p,name:f,platform:"iOS Simulator"})}return o(c)},a=[t?"-workspace":"-project",t||n,"-scheme",i,"-configuration",r,"-sdk","iphonesimulator","-showdestinations"];try{let l=Qe("xcodebuild",[...a,"-json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),c=JSON.parse(l),d=Array.isArray(c.destinations)?c.destinations:Array.isArray(c.availableDestinations)?c.availableDestinations:[],u=o(d);if(u)return u}catch{}try{let l=Qe("xcodebuild",a,{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return s(l)}catch{}},We=(e,t,n=process.cwd(),i={},r,o)=>new Promise((s,a)=>{let l="",c=Va(e),d=Date.now(),u=new Map,p=[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(Ae.homedir(),".npm-global/bin")],m=[...(process.env.PATH||"").split(":"),...p].filter((N,b,k)=>N&&k.indexOf(N)===b).join(":");process.env[`${A.envPrefix}DEBUG`]&&console.log(w.magenta(`[${A.nameUpper}_DEBUG] Execution PATH: ${m}`));let E={...process.env,...i,PATH:m,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"};r&&process.env[`${A.envPrefix}DEBUG`]&&(r(w.magenta(`[ENVIRONMENT] node: ${process.execPath}
633
+ `)}`:""].join("")},La=e=>e==="xcodebuild"&&process.env.MACH_XCODE_FULL_LOGS!=="1",Ua=e=>{let t=fi(e).trim();return!t||Gr(t)?!1:mi(t)||/ARCHIVE SUCCEEDED|ARCHIVE FAILED|EXPORT SUCCEEDED|EXPORT FAILED|Exported .* to:|\[IPA VALID\]/i.test(t)},ke=e=>{try{I.existsSync(e)&&I.rmSync(e,{recursive:!0,force:!0})}catch{}},Wa=(e,t)=>{try{if(!I.existsSync(e))return;for(let n of I.readdirSync(e))t(n)&&ke(y.join(e,n))}catch{}},Pt=e=>{E.info(w.dim("Clearing Metro/Hermes JS transform caches..."));let t=ye.tmpdir();Wa(t,n=>n==="metro-cache"||n.startsWith("metro-")||n.startsWith("haste-map-")||n.startsWith("react-native-packager-cache-")),ke(y.join(e,".expo")),ke(y.join(e,"node_modules/.cache/metro")),ke(y.join(ye.homedir(),".cache/metro")),ke(y.join(ye.homedir(),".cache/react-native-packager")),ke(y.join(ye.homedir(),"Library/Caches/metro")),ke(y.join(ye.homedir(),"Library/Caches/react-native-packager"))},Ga=e=>/Internal inconsistency error|never received target ended message/i.test(String(e?.message||e)),Za=e=>{E.warn(w.yellow("Xcode build system hit an internal inconsistency. Clearing simulator build state and retrying once...")),ke(y.join(e,"Build")),ke(y.join(e,"Index.noindex")),ke(y.join(e,"ModuleCache.noindex")),ke(y.join(e,"SourcePackages"))},Ha=e=>{let t=String(e?.message||e);return/Permission denied/i.test(t)&&/Pods\/.*\.sh/i.test(t)},Zr=e=>{let t=y.join(e,"Pods"),i=[y.join(t,"Target Support Files"),t].filter(a=>I.existsSync(a)),r=new Set,o=0,s=a=>{let l=a;try{l=I.realpathSync(a)}catch{}if(r.has(l))return;r.add(l);let c;try{c=I.readdirSync(a,{withFileTypes:!0})}catch{return}for(let d of c){let u=y.join(a,d.name);if(d.isDirectory()){s(u);continue}if(!(!d.isFile()||!d.name.endsWith(".sh")))try{let p=I.statSync(u),f=p.mode|493;f!==p.mode&&(I.chmodSync(u,f),o+=1)}catch{}}};for(let a of i)s(a);return o>0&&E.info(w.dim(`Repaired executable permissions on ${o} CocoaPods script${o===1?"":"s"}.`)),o},Xa=(e,t,n,i,r)=>{let o=l=>{let c=l.filter(u=>u?.id&&String(u?.platform||"").includes("iOS Simulator")&&!u?.error),d=c.find(u=>/iphone/i.test(u.name||""))||c[0];return d?.id?`id=${d.id}`:void 0},s=l=>{let c=[],d=!1;for(let u of l.split(`
634
+ `)){if(/Ineligible destinations/i.test(u)&&(d=!0),d||!u.includes("platform:iOS Simulator")||u.includes("error:"))continue;let p=u.match(/\bid:([^,}]+)/)?.[1]?.trim(),f=u.match(/\bname:([^,}]+)/)?.[1]?.trim();p&&c.push({id:p,name:f,platform:"iOS Simulator"})}return o(c)},a=[t?"-workspace":"-project",t||n,"-scheme",i,"-configuration",r,"-sdk","iphonesimulator","-showdestinations"];try{let l=Qe("xcodebuild",[...a,"-json"],{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),c=JSON.parse(l),d=Array.isArray(c.destinations)?c.destinations:Array.isArray(c.availableDestinations)?c.availableDestinations:[],u=o(d);if(u)return u}catch{}try{let l=Qe("xcodebuild",a,{cwd:e,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return s(l)}catch{}},je=(e,t,n=process.cwd(),i={},r,o)=>new Promise((s,a)=>{let l="",c=La(e),d=Date.now(),u=new Map,p=[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(ye.homedir(),".npm-global/bin")],m=[...(process.env.PATH||"").split(":"),...p].filter((x,S,_)=>x&&_.indexOf(x)===S).join(":");process.env[`${A.envPrefix}DEBUG`]&&console.log(w.magenta(`[${A.nameUpper}_DEBUG] Execution PATH: ${m}`));let P={...process.env,...i,PATH:m,LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"};r&&process.env[`${A.envPrefix}DEBUG`]&&(r(w.magenta(`[ENVIRONMENT] node: ${process.execPath}
550
635
  `)),r(w.magenta(`[ENVIRONMENT] PATH: ${m}
551
636
  `)),r(w.magenta(`[ENVIRONMENT] command: ${e} ${t.join(" ")}
552
- `)));let v=e;if(["node","npm","npx","pod"].includes(e)){let N=y.dirname(process.execPath),b=y.join(N,e);I.existsSync(b)&&(v=b,r&&r(w.dim(`[EXEC] Using absolute path: ${v}
553
- `)))}let P=Br(v,t,{stdio:"pipe",cwd:n,shell:!0,env:E,detached:process.platform!=="win32"});if(o){if(o.aborted){if(P.pid)try{process.kill(-P.pid,"SIGTERM")}catch{P.kill()}return a(new Error("Command aborted"))}o.addEventListener("abort",()=>{if(P.pid)try{process.kill(-P.pid,"SIGTERM")}catch{P.kill()}a(new Error("Command aborted"))})}let F=(N,b,k=!1)=>{if(!c)return N;let S=`${u.get(b)||""}${N.replace(/\r/g,`
637
+ `)));let v=e;if(["node","npm","npx","pod"].includes(e)){let x=y.dirname(process.execPath),S=y.join(x,e);I.existsSync(S)&&(v=S,r&&r(w.dim(`[EXEC] Using absolute path: ${v}
638
+ `)))}let R=jr(v,t,{stdio:"pipe",cwd:n,shell:!0,env:P,detached:process.platform!=="win32"});if(o){if(o.aborted){if(R.pid)try{process.kill(-R.pid,"SIGTERM")}catch{R.kill()}return a(new Error("Command aborted"))}o.addEventListener("abort",()=>{if(R.pid)try{process.kill(-R.pid,"SIGTERM")}catch{R.kill()}a(new Error("Command aborted"))})}let O=(x,S,_=!1)=>{if(!c)return x;let b=`${u.get(S)||""}${x.replace(/\r/g,`
554
639
  `)}`.split(`
555
- `),$=k?"":S.pop()||"";u.set(b,$);let j=S.filter(ja);if(j.length>0)return d=Date.now(),`${j.join(`
640
+ `),$=_?"":b.pop()||"";u.set(S,$);let j=b.filter(Ua);if(j.length>0)return d=Date.now(),`${j.join(`
556
641
  `)}
557
- `;let x=Date.now();return x-d>3e4?(d=x,`[xcodebuild] still running; errors and milestones will appear here.
558
- `):""},C=(N,b,k=!1)=>{let _=F(N,b,k);_&&(b.write(_),r&&r(_))};P.stdout.on("data",N=>{let b=N.toString();l=Or(l,b),C(b,process.stdout)}),P.stderr.on("data",N=>{let b=N.toString();l=Or(l,b),C(b,process.stderr)}),P.on("close",N=>{C("",process.stdout,!0),C("",process.stderr,!0),N===0?s(N):a(new Error(Ba(e,t,N,l)))}),P.on("error",N=>a(N))}),hn=async(e,t,n,i,r)=>{try{await We("xcodebuild",e,t,n,i,r)}catch(o){if(!Ga(o))throw o;R.warn(w.yellow("CocoaPods script permission denied. Repairing Pods script permissions and retrying xcodebuild once...")),Wr(t),await We("xcodebuild",e,t,n,i,r)}},Ha=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(!I.existsSync(e))return n;let i=I.readdirSync(e);for(let r of i){let o=y.join(e,r);try{let s=I.statSync(o);if(t.some(l=>r.endsWith(l))){n.push(y.resolve(o));continue}s.isDirectory()&&(n=n.concat(qe(o,t)))}catch{}}}catch{}return n},Gr=(e,t)=>{let n=Zt(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},gi=(e,t)=>Qe("/usr/libexec/PlistBuddy",["-c",`Print :${t}`,e],{encoding:"utf-8"}).trim(),Rt=(e,t)=>{try{return gi(e,t)}catch{return""}},Dr=e=>String(e||"").replace(/\.app$/i,"").replace(/[^a-z0-9]/gi,"").toLowerCase(),Xa=e=>{try{return I.statSync(e).isDirectory()}catch{return!1}},Ka=(e,t,n)=>{if(!I.existsSync(e))throw new Error(`iOS simulator build output directory was not found: ${e}`);let i=I.readdirSync(e).filter(c=>c.endsWith(".app")).map(c=>y.join(e,c)).filter(Xa);if(i.length===0){let d=qe(e,[".app"]).map(u=>y.relative(e,u)).join(", ");throw new Error(`No top-level iOS simulator .app product was found in ${e}.`+(d?` Nested .app bundles found but ignored: ${d}`:""))}let r=new Set([t,n.iosScheme,n.scheme,n.appName].filter(Boolean).map(c=>Dr(String(c))).filter(Boolean)),o=i.map(c=>{let d=y.join(c,"Info.plist"),u=I.existsSync(d)?Rt(d,"CFBundleName"):"",p=I.existsSync(d)?Rt(d,"CFBundleDisplayName"):"",f=I.existsSync(d)?Rt(d,"CFBundleExecutable"):"",m=I.existsSync(d)?Rt(d,"CFBundleIdentifier"):"",E=f?y.join(c,f):"";return{appPath:c,bundleIdentifier:m,executable:f,isValid:I.existsSync(d)&&!!f&&I.existsSync(E),names:[y.basename(c,".app"),u,p,f].map(Dr).filter(Boolean)}}),s=o.filter(c=>c.isValid);if(s.length===0)throw new Error(`No valid iOS simulator .app product was found in ${e}. Candidates: `+o.map(c=>y.basename(c.appPath)).join(", "));let l=s.find(c=>c.names.some(d=>r.has(d)))||(s.length===1?s[0]:null);if(!l)throw new Error(`Multiple iOS simulator .app products were found in ${e}: `+s.map(c=>{let d=c.bundleIdentifier?` (${c.bundleIdentifier})`:"";return`${y.basename(c.appPath)}${d}`}).join(", ")+`. Set ios.scheme in ${A.configFileName} so ${A.name} can select the app target safely.`);return l.appPath},Ja=(e,t)=>{let n=y.join(e,"Info.plist");if(!I.existsSync(n))throw new Error(`Could not validate iOS build number: ${n} not found.`);let i=Gr(gi(n,"CFBundleVersion"),n);return t?zn(i,t,n):i},Zr=(e,t=[])=>{if(!I.existsSync(e))return t;for(let n of I.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),Zr(i,t))}return t},Mr=(e,t)=>[e,...Zr(e)].filter((i,r,o)=>o.indexOf(i)===r).map(i=>({bundlePath:i,buildNumber:Ja(i,t)})),Hr=e=>{let t=y.join(e,"Info.plist");if(!I.existsSync(t))throw new Error(`Could not validate iOS app executable: ${t} not found.`);let n=Rt(t,"CFBundleExecutable");if(!n)throw new Error(`Could not validate iOS app executable: CFBundleExecutable missing in ${t}.`);let i=y.join(e,n);if(!I.existsSync(i))throw new Error(`Could not validate iOS app executable: ${i} not found.`);return i},Ya=()=>process.arch==="arm64"?"arm64":"x86_64",Xr=e=>{let t=Hr(e),n="";try{n=Qe("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=Ya();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},za=e=>{try{return Qe("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}`)}},Kr=e=>{let t=Hr(e),n=za(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},Jr=(e,t)=>{let i=Qe("unzip",["-Z1",e],{encoding:"utf-8"}).split(`
559
- `).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=I.mkdtempSync(y.join(Ae.tmpdir(),`${A.nameLower}-ipa-plist-`));try{let o="";for(let[s,a]of i.entries()){let l=y.join(r,`Info-${s}.plist`),c=Qe("unzip",["-p",e,a]);I.writeFileSync(l,c);let d=`${y.basename(e)}:${a}`,u=Gr(gi(l,"CFBundleVersion"),d);t&&zn(u,t,d),/^Payload\/[^/]+\.app\/Info\.plist$/.test(a)&&(o=u)}if(!o)throw new Error(`Could not validate iOS build number: ${y.basename(e)} has no main application Info.plist.`);return o}finally{I.rmSync(r,{recursive:!0,force:!0})}},Qa=e=>`'${e.replace(/'/g,"'\\''")}'`,qa=()=>process.execPath&&I.existsSync(process.execPath)?process.execPath:Qe("which",["node"],{encoding:"utf-8"}).trim(),ui=(e,t,n)=>{if(!I.existsSync(e))return;let i=qa();t.NODE_BINARY=i;let r=y.join(e,".xcode.env.local");I.writeFileSync(r,`export NODE_BINARY=${Qa(i)}
642
+ `;let N=Date.now();return N-d>3e4?(d=N,`[xcodebuild] still running; errors and milestones will appear here.
643
+ `):""},C=(x,S,_=!1)=>{let k=O(x,S,_);k&&(S.write(k),r&&r(k))};R.stdout.on("data",x=>{let S=x.toString();l=Mr(l,S),C(S,process.stdout)}),R.stderr.on("data",x=>{let S=x.toString();l=Mr(l,S),C(S,process.stderr)}),R.on("close",x=>{C("",process.stdout,!0),C("",process.stderr,!0),x===0?s(x):a(new Error(ja(e,t,x,l)))}),R.on("error",x=>a(x))}),hn=async(e,t,n,i,r)=>{try{await je("xcodebuild",e,t,n,i,r)}catch(o){if(!Ha(o))throw o;E.warn(w.yellow("CocoaPods script permission denied. Repairing Pods script permissions and retrying xcodebuild once...")),Zr(t),await je("xcodebuild",e,t,n,i,r)}},Ka=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(!I.existsSync(e))return n;let i=I.readdirSync(e);for(let r of i){let o=y.join(e,r);try{let s=I.statSync(o);if(t.some(l=>r.endsWith(l))){n.push(y.resolve(o));continue}s.isDirectory()&&(n=n.concat(qe(o,t)))}catch{}}}catch{}return n},Hr=(e,t)=>{let n=Zt(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},gi=(e,t)=>Qe("/usr/libexec/PlistBuddy",["-c",`Print :${t}`,e],{encoding:"utf-8"}).trim(),Rt=(e,t)=>{try{return gi(e,t)}catch{return""}},Vr=e=>String(e||"").replace(/\.app$/i,"").replace(/[^a-z0-9]/gi,"").toLowerCase(),Ja=e=>{try{return I.statSync(e).isDirectory()}catch{return!1}},Ya=(e,t,n)=>{if(!I.existsSync(e))throw new Error(`iOS simulator build output directory was not found: ${e}`);let i=I.readdirSync(e).filter(c=>c.endsWith(".app")).map(c=>y.join(e,c)).filter(Ja);if(i.length===0){let d=qe(e,[".app"]).map(u=>y.relative(e,u)).join(", ");throw new Error(`No top-level iOS simulator .app product was found in ${e}.`+(d?` Nested .app bundles found but ignored: ${d}`:""))}let r=new Set([t,n.iosScheme,n.scheme,n.appName].filter(Boolean).map(c=>Vr(String(c))).filter(Boolean)),o=i.map(c=>{let d=y.join(c,"Info.plist"),u=I.existsSync(d)?Rt(d,"CFBundleName"):"",p=I.existsSync(d)?Rt(d,"CFBundleDisplayName"):"",f=I.existsSync(d)?Rt(d,"CFBundleExecutable"):"",m=I.existsSync(d)?Rt(d,"CFBundleIdentifier"):"",P=f?y.join(c,f):"";return{appPath:c,bundleIdentifier:m,executable:f,isValid:I.existsSync(d)&&!!f&&I.existsSync(P),names:[y.basename(c,".app"),u,p,f].map(Vr).filter(Boolean)}}),s=o.filter(c=>c.isValid);if(s.length===0)throw new Error(`No valid iOS simulator .app product was found in ${e}. Candidates: `+o.map(c=>y.basename(c.appPath)).join(", "));let l=s.find(c=>c.names.some(d=>r.has(d)))||(s.length===1?s[0]:null);if(!l)throw new Error(`Multiple iOS simulator .app products were found in ${e}: `+s.map(c=>{let d=c.bundleIdentifier?` (${c.bundleIdentifier})`:"";return`${y.basename(c.appPath)}${d}`}).join(", ")+`. Set ios.scheme in ${A.configFileName} so ${A.name} can select the app target safely.`);return l.appPath},za=(e,t)=>{let n=y.join(e,"Info.plist");if(!I.existsSync(n))throw new Error(`Could not validate iOS build number: ${n} not found.`);let i=Hr(gi(n,"CFBundleVersion"),n);return t?zn(i,t,n):i},Xr=(e,t=[])=>{if(!I.existsSync(e))return t;for(let n of I.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),Xr(i,t))}return t},Br=(e,t)=>[e,...Xr(e)].filter((i,r,o)=>o.indexOf(i)===r).map(i=>({bundlePath:i,buildNumber:za(i,t)})),Kr=e=>{let t=y.join(e,"Info.plist");if(!I.existsSync(t))throw new Error(`Could not validate iOS app executable: ${t} not found.`);let n=Rt(t,"CFBundleExecutable");if(!n)throw new Error(`Could not validate iOS app executable: CFBundleExecutable missing in ${t}.`);let i=y.join(e,n);if(!I.existsSync(i))throw new Error(`Could not validate iOS app executable: ${i} not found.`);return i},Qa=()=>process.arch==="arm64"?"arm64":"x86_64",Jr=e=>{let t=Kr(e),n="";try{n=Qe("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=Qa();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},qa=e=>{try{return Qe("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}`)}},Yr=e=>{let t=Kr(e),n=qa(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},zr=(e,t)=>{let i=Qe("unzip",["-Z1",e],{encoding:"utf-8"}).split(`
644
+ `).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=I.mkdtempSync(y.join(ye.tmpdir(),`${A.nameLower}-ipa-plist-`));try{let o="";for(let[s,a]of i.entries()){let l=y.join(r,`Info-${s}.plist`),c=Qe("unzip",["-p",e,a]);I.writeFileSync(l,c);let d=`${y.basename(e)}:${a}`,u=Hr(gi(l,"CFBundleVersion"),d);t&&zn(u,t,d),/^Payload\/[^/]+\.app\/Info\.plist$/.test(a)&&(o=u)}if(!o)throw new Error(`Could not validate iOS build number: ${y.basename(e)} has no main application Info.plist.`);return o}finally{I.rmSync(r,{recursive:!0,force:!0})}},ec=e=>`'${e.replace(/'/g,"'\\''")}'`,tc=()=>process.execPath&&I.existsSync(process.execPath)?process.execPath:Qe("which",["node"],{encoding:"utf-8"}).trim(),ui=(e,t,n)=>{if(!I.existsSync(e))return;let i=tc();t.NODE_BINARY=i;let r=y.join(e,".xcode.env.local");I.writeFileSync(r,`export NODE_BINARY=${ec(i)}
560
645
  `);let o=`[NODE] Xcode NODE_BINARY: ${i}
561
- `;n&&n(w.dim(o)),R.info(w.dim(o.trim()))},sp=async(e,t,n={},i,r={})=>{let o=yn(),s=Date.now(),a=e.platform,l=e.buildProfile||"production",c=Gt(e.framework),d=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),u=d.sourceRoot,p=d.appRoot;e.appDirectory=d.appDirectory;let f=()=>({...an(n,l,e),MACH_SOURCE_ROOT:u,MACH_APP_ROOT:p}),m=async(x,M={})=>{if(i)for(let D=1;D<=3;D++)try{await U.patch(`/builds/${i}/${t}`,{status:x,...M});return}catch(ce){let Se=ce?.response?.data?.message||ce?.message||String(ce);console.error(`[reportStatus] attempt ${D}/3 failed (status=${x}): ${Se}`),D<3&&await new Promise(Z=>setTimeout(Z,2e3))}},E=new AbortController,{signal:v}=E,P=null;i&&(P=setInterval(async()=>{try{(await U.get(`/builds/${i}/${t}`)).data.status==="cancelled"&&(R.warn(w.yellow(`
562
- \u{1F6D1} Build cancelled from dashboard. Terminating...`)),E.abort(),P&&clearInterval(P))}catch{}},5e3));let F=y.join(u,".mach-cache"),C="setup",N="",b=null,k=async()=>{if(!N||!i)return;let x=N;N="";try{let M=x;Object.values(n).forEach(D=>{if(D&&D.length>5){let ce=D.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");M=M.replace(new RegExp(ce,"g"),"[SECRET]")}}),await U.post(`/builds/${i}/${t}/logs`,{log:M,step:C})}catch{}},_=async()=>{b&&(clearTimeout(b),b=null),await k(),Da(F,t),P&&(clearInterval(P),P=null);try{let x=y.join(Ae.tmpdir(),`${A.buildPrefix}-${t}.keychain-db`);I.existsSync(x)&&(re(`security delete-keychain "${x}"`,{stdio:"ignore"}),R.info(w.dim("\u{1F511} Build keychain deleted.")))}catch{}try{let x=y.join(Ae.homedir(),"Library/MobileDevice/Provisioning Profiles");if(I.existsSync(x)){let M=I.readdirSync(x).filter(D=>D.includes(t)||D.startsWith(`${A.nameLower}-temp-${t}`));for(let D of M)I.unlinkSync(y.join(x,D))}}catch{}},S=async x=>{i&&(N+=x,N.length>=8192?(b&&(clearTimeout(b),b=null),await k()):b||(b=setTimeout(()=>{b=null,k()},2e3)))},$=async x=>{C=x,await S(`[STEP_START:${x}] ${Math.floor(Date.now()/1e3)}
563
- `)},j=async(x,M,D,ce)=>await We(x,M,D,ce,Se=>{S(Se)},v);R.info(w.blue(`\u{1F680} Starting local build for ${a} (${l})...`));try{Oa(F,t)}catch(x){throw await m("failed",{error:x.message,endTime:Date.now()}),x}await m("building"),await $("setup"),a==="ios"&&!e.simulator&&n.MACH_IOS_BUILD_NUMBER_LOCKED==="1"&&n.BUILD_NUMBER&&(R.info(w.dim(`Auto build number: ${n.BUILD_NUMBER}`)),await S(`[BUILD_NUMBER] ${n.BUILD_NUMBER}
564
- `)),await $("lock"),c.applyLocalProcessEnv(e);try{await $("clone"),R.info(w.dim("Preparing source...")),await $("read_config");let x=y.join(u,A.configFileName);if(I.existsSync(x)){let T=JSON.parse(I.readFileSync(x,"utf-8"))?.build?.[l]||{};await S(`[CONFIG] Profile: ${l}, distribution: ${T.distribution||"not set"}, simulator: ${T.simulator||!1}
565
- `)}if(await $("read_package"),e.framework!=="flutter"&&e.nodeVersion){let O=process.env.NVM_DIR||y.join(Ae.homedir(),".nvm"),T=y.join(O,"versions","node"),G;if(I.existsSync(T)){let W=I.readdirSync(T).sort().reverse(),z=e.nodeVersion.startsWith("v")?e.nodeVersion:`v${e.nodeVersion}`,se=W.find(X=>X===z||X.startsWith(z+".")||X.startsWith(`v${e.nodeVersion}.`));se&&(G=y.join(T,se,"bin"))}if(G&&I.existsSync(G)){let W=process.env.PATH||"";process.env.PATH=`${G}:${W}`,await S(`[NODE] Switched to Node ${e.nodeVersion} \u2014 using ${G}
566
- `),R.info(w.green(`\u2713 Node switched to ${e.nodeVersion} (${G})`))}else await S(`[NODE] Warning: Node ${e.nodeVersion} not found in nvm. Run: nvm install ${e.nodeVersion} on the build machine.
567
- `),R.warn(w.yellow(`Node ${e.nodeVersion} not found in nvm \u2014 using system default`))}await $("deps"),o.start("Checking dependencies...");let M=Ta(F),D={};if(e.framework==="flutter")o.stop("Preparing Flutter dependencies..."),e.preBuild&&(R.info(w.blue("Running pre-install hook...")),R.info(w.dim(`> ${e.preBuild}`)),await $("prebuild"),await j("bash",[e.preBuild],u,f())),D=await c.prepareLocalProject({platform:a,options:e,sourceRoot:u,appRoot:p,cacheMeta:M,cacheMetaDir:F,currentBuildEnv:f,reportStep:$,reportLog:S,loggedRun:j,configureXcodeNodeBinary:ui,podsFingerprint:Tr,writeCacheMeta:di});else{let O=$a(u),T=I.existsSync(y.join(u,"node_modules")),G=I.existsSync(y.join(u,"yarn.lock")),W=I.existsSync(y.join(u,"bun.lockb"));T&&M.node&&M.node!==O&&(o.stop("Dependency fingerprint changed \u2014 clearing node_modules for clean install..."),await S(`[CACHE] package.json/lockfile changed \u2014 wiping node_modules
568
- `),I.rmSync(y.join(u,"node_modules"),{recursive:!0,force:!0}),T=!1);let z="npm",se=["install","--prefer-offline"];if(G?(z="yarn",se=["install","--prefer-offline"]):W&&(z="bun",se=["install"]),T?o.stop("Cached node_modules found. Syncing dependencies..."):o.stop("No cached dependencies. Running fresh install..."),e.preBuild&&(R.info(w.blue("Running pre-install hook...")),R.info(w.dim(`> ${e.preBuild}`)),await $("prebuild"),await j("bash",[e.preBuild],u,f())),R.info(w.dim(`Running ${z} ${se.join(" ")}...`)),await j(z,se,u,f()),M.node=O,di(F,M),e.framework==="expo"){let X=n.MACH_OTA_RUNTIME_VERSION,ue=n.MACH_OTA_CHANNEL,ye=n.MACH_OTA_URL;if(X&&ue&&ye){let V=hr(u,{platform:a,runtimeVersion:X,channel:ue,url:ye}),J=gr(V,{runtimeVersion:X,channel:ue,url:ye});if(J.length>0)throw new Error(`Expo OTA configuration mismatch after installing dependencies: ${J.join("; ")}. Run \`${A.nameLower} ota setup\` to update the local Expo plugin before building.`);R.info(w.green(`\u2713 Expo OTA configuration verified (${ue})`))}}D=await c.prepareLocalProject({platform:a,options:e,sourceRoot:u,appRoot:p,cacheMeta:M,cacheMetaDir:F,currentBuildEnv:f,reportStep:$,reportLog:S,loggedRun:j,configureXcodeNodeBinary:ui,podsFingerprint:Tr,writeCacheMeta:di})}let ce=D.bundleId||e.iosBundleIdentifier||"",Se=D.appName||e.name||"",Z=[];if(a==="android")await $("build"),Z=await ec(e,l,n,O=>S(O),v);else if(a==="ios"){await $("signing"),R.info(w.dim("Preparing credentials..."));let O=r?.distributionType;Z=await nc(e,t,l,n,i,T=>S(T),v,O,T=>$(T))}else a==="web"&&e.framework==="flutter"&&(await $("build"),Z=await tc(e,n,O=>S(O),v));if(e.framework==="flutter"&&e.flutterSplitDebugInfoPath&&I.existsSync(e.flutterSplitDebugInfoPath)){let O=qe(e.flutterSplitDebugInfoPath,[".symbols",".json"]);if(O.length>0){let T=y.join(Ae.tmpdir(),`${t}-flutter-symbols.zip`),G=new jr;G.addLocalFolder(e.flutterSplitDebugInfoPath),G.writeZip(T),Z.push(T),await S(`[FLUTTER] Preserved ${O.length} split debug symbol file(s)
569
- `)}}if(e.postBuild&&(R.info(w.blue("Running post-build hook...")),R.info(w.dim(`> ${e.postBuild}`)),await j(e.postBuild,[],u,f())),a==="ios"){let O=Zt(e.resolvedBuildNumber||n.BUILD_NUMBER);if(O)for(let T of Z.filter(G=>G.endsWith(".ipa"))){let G=Jr(T,O);await S(`[IPA FINAL] CFBundleVersion ${G} matches MACH buildNumber ${O}
570
- `)}}if(a==="android"){let O=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(O){let T=Ue(O,"resolved MACH build assignment");if(Z.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${T}.`);for(let G of Z){let W=cn(G,T);await S(`[ANDROID FINAL] ${y.basename(G)} versionCode ${W} matches MACH assignment
571
- `)}}}let Le=Ha(Date.now()-s);if(R.success(w.green(`
572
- \u2713 Local build completed successfully in ${Le}`)),await m("building",{...ce&&{bundleId:ce},...Se&&{appName:Se}}),Z.length>0&&(R.info(w.cyan(`
573
- \u{1F4E6} Generated Artifacts:`)),Z.forEach(O=>{let T=y.resolve(O);R.info(w.dim(` - ${O}`)),R.info(w.gray(` Path: ${T}`))}),e.interactive)){let O=await _a({message:"Install on connected device?"});if(!In(O)&&O){if(a==="android"){let T=Z.find(G=>G.endsWith(".apk"))||Z[0];await rc(T,G=>S(G))}else if(a==="ios"){let T=Z.find(W=>W.endsWith(".ipa"))||Z.find(W=>W.endsWith(".app"))||Z[0],G=xt("ios");e.simulator?await oc(T,G||"",W=>S(W)):await sc(T,G||"",W=>S(W))}}}await $("upload");let de=[];for(let O of Z)try{let T=y.join(Ae.tmpdir(),`${t}-${y.basename(O)}`);I.copyFileSync(O,T),de.push(T),R.info(w.dim(` \u{1F4CB} Preserved artifact: ${y.basename(O)}`))}catch{R.warn(w.yellow(` Failed to preserve artifact: ${y.basename(O)}`))}if(Z=de,r?.isolatedRunner===!0){R.info(w.dim("\u{1F9F9} Cleaning isolated workspace (preserving dependency cache)..."));try{let O=process.cwd(),T=new Set(["node_modules"]),G=I.readdirSync(O),W=0;for(let z of G)if(!T.has(z)){if(z==="ios"){let se=y.join(O,"ios"),X=I.readdirSync(se);for(let ue of X)if(ue!=="Pods")try{I.rmSync(y.join(se,ue),{recursive:!0,force:!0}),W++}catch{}continue}try{I.rmSync(y.join(O,z),{recursive:!0,force:!0}),W++}catch{}}R.info(w.dim(` Cleaned ${W} items. Cached: node_modules${I.existsSync(y.join(O,"ios","Pods"))?", ios/Pods":""}`)),R.info(w.green("\u{1F512} Security: No source code retained on build server. Only public dependencies cached."))}catch{R.warn(w.yellow("Post-build cleanup encountered errors (non-fatal)."))}try{let T=y.join(Ae.homedir(),A.workspacesDir),G=re(`df -k "${T}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim(),W=parseInt(G,10)*1024;if(W<53687091200&&I.existsSync(T)){R.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()),se=I.readdirSync(T).filter(X=>X!==z).map(X=>{let ue=y.join(T,X);try{let ye=I.statSync(ue);return ye.isDirectory()?{name:X,dir:ue,mtime:ye.mtimeMs}:null}catch{return null}}).filter(Boolean);se.sort((X,ue)=>X.mtime-ue.mtime);for(let X of se){if(W>=53687091200)break;try{I.rmSync(X.dir,{recursive:!0,force:!0}),R.info(w.dim(` \u{1F5D1}\uFE0F Evicted stale workspace: ${X.name}`));let ue=re(`df -k "${T}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim();if(parseInt(ue,10)*1024>=53687091200)break}catch{}}}}catch{}}return await _(),Z}catch(x){throw await _(),x.message==="Command aborted"?(R.warn(w.yellow(`
574
- \u274C Build aborted.`)),await m("failed",{error:"Aborted by user",endTime:Date.now()}),x):(R.error(w.red(`
575
- \u2717 Local build failed: ${x.message}`)),await m("failed",{error:x.message,endTime:Date.now()}),x)}},ec=async(e,t,n={},i,r)=>{let o=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),s=y.join(o.appRoot,"android");if(e.framework==="flutter"){let b=e.apk===!0?"apk":e.apk===!1||e.distribution==="store"?"appbundle":"apk",k={...n,...an(n,t,e),MACH_SOURCE_ROOT:o.sourceRoot,MACH_APP_ROOT:o.appRoot},_;if(n.ANDROID_KEYSTORE_BASE64&&n.ANDROID_KEY_ALIAS&&n.ANDROID_KEY_PASSWORD){let M=I.mkdtempSync(y.join(Ae.tmpdir(),"mach-flutter-signing-"));_=y.join(M,"release.keystore"),I.writeFileSync(_,Buffer.from(n.ANDROID_KEYSTORE_BASE64,"base64"),{mode:384}),k["ORG_GRADLE_PROJECT_android.injected.signing.store.file"]=_,k["ORG_GRADLE_PROJECT_android.injected.signing.store.password"]=n.ANDROID_STORE_PASSWORD||n.ANDROID_KEY_PASSWORD,k["ORG_GRADLE_PROJECT_android.injected.signing.key.alias"]=n.ANDROID_KEY_ALIAS,k["ORG_GRADLE_PROJECT_android.injected.signing.key.password"]=n.ANDROID_KEY_PASSWORD}let S=["build",b,...Wt(e,k)];R.info(w.blue(`Running Flutter Android ${b} build...`));try{$e(y.join(o.appRoot,"build","app","outputs")),await We("flutter",S,o.appRoot,k,i,r)}finally{_&&$e(y.dirname(_))}let $=y.join(o.appRoot,"build/app/outputs"),j=qe($,b==="appbundle"?[".aab"]:[".apk"]);if(j.length===0)throw new Error(`Flutter build completed but produced no ${b==="appbundle"?"AAB":"APK"} artifact.`);let x=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(x)for(let M of j)cn(M,x);return j}let a=y.join(o.appRoot,"gradlew"),l=y.join(s,"gradlew"),c=I.existsSync(l)?l:I.existsSync(a)?a:null;if(!c)throw new Error(`Could not find gradlew inside appDirectory "${o.appDirectory}".`);let d=e.developmentClient?"assembleDebug":"assembleRelease";!e.developmentClient&&e.distribution==="store"?d="bundleRelease":!e.developmentClient&&e.distribution==="internal"&&(d="assembleRelease");let u=e.buildCommand||d;R.info(w.blue(`Running Android build: ${u}...`));let p=c===l?s:o.appRoot,f="./gradlew",m=[u],E=Gt(e.framework),v={...n,...E.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},P=e.resolvedVersionCode||n.ANDROID_VERSION_CODE,F=P?Ue(P,"resolved MACH build assignment"):null;F&&(m.push(`-Pandroid.injected.version.code=${F}`),v.ANDROID_VERSION_CODE=F,R.info(w.green(`\u2713 Applying Android versionCode ${F}`)));for(let b of["app/build","build",".cxx"]){let k=y.join(p,b);I.existsSync(k)&&I.rmSync(k,{recursive:!0,force:!0})}Pt(o.appRoot),o.appRoot!==o.sourceRoot&&Pt(o.sourceRoot),await We(f,m,p,v,i,r);let C=y.join(p,"app/build/outputs"),N=qe(C,[".apk",".aab"]);if(F&&N.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${F}.`);if(F)for(let b of N){let k=cn(b,F);R.info(w.dim(`Validated Android versionCode ${k} in ${y.basename(b)}`)),i?.(`[ANDROID VALID] ${y.basename(b)} versionCode ${k} matches MACH assignment
576
- `)}return N},tc=async(e,t={},n,i)=>{let r=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),o={...t,MACH_SOURCE_ROOT:r.sourceRoot,MACH_APP_ROOT:r.appRoot},s=y.join(r.appRoot,"build","web");if($e(s),R.info(w.blue("Running Flutter web build...")),await We("flutter",["build","web",...Wt(e,o)],r.appRoot,o,n,i),!I.existsSync(y.join(s,"index.html")))throw new Error("Flutter web build completed but build/web/index.html is missing.");let a=y.join(Ae.tmpdir(),`${e.buildId||Vr.randomUUID()}-flutter-web.zip`),l=new jr;return l.addLocalFolder(s),l.writeZip(a),[a]},nc=async(e,t,n,i={},r,o,s,a,l)=>{if(process.platform!=="darwin")throw new Error("iOS builds can only be run on macOS.");let c=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),d=y.join(c.appRoot,"ios");if(!I.existsSync(d))throw new Error(`Could not find ios/ inside appDirectory "${c.appDirectory}".`);Wr(d);let u=I.readdirSync(d),p=u.find(_=>_.endsWith(".xcworkspace")),f=u.find(_=>_.endsWith(".xcodeproj")),m={...an(i,n,e),MACH_SOURCE_ROOT:c.sourceRoot,MACH_APP_ROOT:c.appRoot};e.framework!=="flutter"&&ui(d,m,o);let E=e.resolvedBuildNumber||m.BUILD_NUMBER||m.CURRENT_PROJECT_VERSION,v=Zt(E);if(E&&!v)throw new Error(`Invalid iOS build number: "${E}". Apple requires one to three period-separated integers. Fix the Dashboard secret or remove it so Mach can use its auto build number.`);let P=v?[`BUILD_NUMBER=${v}`,`CURRENT_PROJECT_VERSION=${v}`,`INFOPLIST_KEY_CFBundleVersion=${v}`]:[];if(v&&(m.BUILD_NUMBER=v,m.CURRENT_PROJECT_VERSION=v,R.info(w.dim(`Using iOS build number: ${v}`))),!p&&!f)throw new Error("Could not find Xcode workspace or project in ios/ directory.");try{let _=re("xcode-select -p").toString().trim();R.info(w.dim(`Using Xcode at: ${_}`))}catch{R.warn(w.dim("Could not detect Xcode path."))}R.info(w.blue("Running iOS build via xcodebuild..."));let F=p?p.replace(".xcworkspace",""):f?.replace(".xcodeproj",""),C=e.iosScheme||F||e.scheme,N=e.developmentClient?"Debug":e.iosConfiguration||"Release",b,k;try{if(v){b=ir(d,v,{workspace:p,project:f,scheme:C,configuration:N});let D=b.plistPaths.length>0?`${b.plistPaths.length} Xcode target Info.plist file(s)`:"generated Info.plist build settings";R.info(w.green(`\u2713 Applied iOS buildNumber ${v} to ${D}`)),o&&o(`[VERSIONING] Applied iOS buildNumber ${v} to ${D}
577
- `)}let _=(r||"default").replace(/[^a-zA-Z0-9-_]/g,"_"),S=y.join(Ae.homedir(),`Library/Developer/Xcode/DerivedData/${A.nameLower}`,_);I.mkdirSync(S,{recursive:!0});let $=er(m),j=y.join(S,".mach-env-hash"),x=y.join(S,"Build"),M=I.existsSync(j)?I.readFileSync(j,"utf-8").trim():"";if(I.existsSync(x)){let D=M&&M!==$?"Build environment changed \u2014 clearing iOS DerivedData build products.":M?"Clearing iOS DerivedData build products to force a fresh JS bundle.":"DerivedData has no environment stamp \u2014 clearing iOS build products.";R.info(w.dim(D)),I.rmSync(x,{recursive:!0,force:!0})}if(I.writeFileSync(j,$),e.framework!=="flutter"&&(Pt(c.appRoot),c.appRoot!==c.sourceRoot&&Pt(c.sourceRoot)),e.simulator){let D=Za(d,p,f,C,N),ce=D||"generic/platform=iOS Simulator",Se=["-destination",ce];R.info(w.dim(D?`Building for simulator (Scheme: ${C}, Config: ${N}, Destination: ${ce})...`:`Building for simulator (Scheme: ${C}, Config: ${N}, Destination: ${ce})...`));let Z=[p?"-workspace":"-project",p||f,"-scheme",C,"-configuration",N,"-sdk","iphonesimulator",...Se,"-derivedDataPath",S,...P,"COMPILER_INDEX_STORE_ENABLE=NO","CODE_SIGNING_ALLOWED=NO","CODE_SIGNING_REQUIRED=NO","ONLY_ACTIVE_ARCH=NO","EXCLUDED_ARCHS=","SUPPORTED_PLATFORMS=iphonesimulator"];try{await hn(Z,d,m,o,s)}catch(ue){if(!Ua(ue))throw ue;Wa(S),e.framework!=="flutter"&&(Pt(c.appRoot),c.appRoot!==c.sourceRoot&&Pt(c.sourceRoot)),await hn(Z,d,m,o,s)}let Le=y.join(S,"Build/Products",`${N}-iphonesimulator`),de=Ka(Le,C,e),O=y.basename(de,".app"),T=Rt(y.join(de,"Info.plist"),"CFBundleIdentifier")||"unknown bundle",W=Mr(de,v||void 0)[0].buildNumber,z=Xr(de),se=Kr(de),X=y.join(Le,`${O}_simulator.zip`);return R.info(w.dim(`Selected simulator app: ${y.relative(Le,de)} (${T}, build ${W})`)),R.info(w.dim(`Simulator executable architecture: ${z}`)),R.info(w.dim(`Simulator executable platform: ${se.split(`
578
- `).find(ue=>/\bplatform\b/i.test(ue))?.trim()||"IOSSIMULATOR"}`)),R.info(w.dim(`Creating simulator artifact: ${X}...`)),$e(X),Qe("zip",["-r",X,y.basename(de)],{cwd:y.dirname(de),stdio:"pipe"}),[X]}else{R.info(w.dim(`Archiving (Scheme: ${C}, Config: ${N})...`));let D=y.join(d,"build.xcarchive"),ce=y.join(d,"export");I.rmSync(D,{recursive:!0,force:!0}),I.rmSync(ce,{recursive:!0,force:!0});let Se=i.IOS_DIST_P12,Z=i.IOS_PROVISIONING_PROFILE,Le=i.IOS_P12_PASSWORD||"",de=Ar(i.IOS_PROVISIONING_PROFILES),O=de.length>1,T=[],G,W,z=[],se=[],X={isAppStore:!1,isDevelopment:!1};if(Se&&Z){R.info(w.blue("\u{1F510} CI/CD Signing: Importing certificates..."));try{let Re=`${A.buildPrefix}-${t}.keychain-db`,ke=y.join(Ae.tmpdir(),Re),It=A.keychainPassword;re(`security create-keychain -p "${It}" "${ke}" 2>/dev/null || true`),re(`security set-keychain-settings -t 3600 -l "${ke}"`),re(`security unlock-keychain -p "${It}" "${ke}"`);let Nn=y.join(Ae.tmpdir(),`cert-${t}.p12`),_t=Buffer.from(Se,"base64");I.writeFileSync(Nn,_t),R.info(w.dim(`P12 data size: ${_t.length} bytes, first bytes: ${_t.slice(0,4).toString("hex")}`)),(_t.length<100||_t[0]!==48)&&(R.warn(w.yellow("\u26A0\uFE0F P12 data looks corrupted or was not decrypted correctly.")),R.warn(w.yellow(" This usually means MACH_ENCRYPTION_KEY on the Remote API differs from when credentials were uploaded.")));let Fo=[Le,"",A.keychainPassword],ki=!1;for(let ge of Fo)try{re(`security import "${Nn}" -k "${ke}" -P "${ge}" -A -T /usr/bin/codesign -T /usr/bin/security`,{stdio:"pipe"}),ki=!0,R.info(w.dim(`\u2713 P12 imported successfully with password: ${ge?"[set]":"[empty]"}`));break}catch(Ve){R.info(w.dim(` P12 import attempt with password ${ge?`"${ge.substring(0,3)}..."`:"[empty]"} failed: ${Ve.message?.split(`
579
- `)[0]||"unknown"}`))}if(!ki)throw new Error("Failed to import P12.");I.unlinkSync(Nn),re(`security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${It}" "${ke}"`);let Oo=re("security list-keychains -d user",{encoding:"utf-8"}).split(`
580
- `).map(ge=>ge.trim().replace(/^"|"$/g,"")).filter(ge=>ge.length>0),Do=[ke,...Oo].map(ge=>`"${ge}"`).join(" ");if(re(`security list-keychains -d user -s ${Do}`),re(`security default-keychain -s "${ke}"`),O){z=Nr({profiles:de,buildId:t});let ge=z.find(Ve=>Ve.isMainApplication)||z[0];W=ge.uuid,X={isAppStore:ge.isAppStore,isDevelopment:ge.isDevelopment},se=z.map(Ve=>Ve.signingProfile),k=_r({iosDirectory:d,profiles:z,teamId:e.iosTeamId,temporaryLabel:t}),R.info(w.green(`\u2713 Applied target-specific signing to ${k.matchedTargets.length} Xcode targets`));for(let Ve of k.matchedTargets)R.info(w.dim(` - ${Ve}`))}else{let ge=y.join(Ae.homedir(),"Library/MobileDevice/Provisioning Profiles");I.mkdirSync(ge,{recursive:!0});let Ve=Buffer.from(Z,"base64"),At=y.join(ge,`${A.nameLower}-temp-${t}.mobileprovision`);I.writeFileSync(At,Ve);let tt=Ve.toString("utf-8"),$t=/<key>get-task-allow<\/key>\s*<true\/>/.test(tt);X={isAppStore:!tt.includes("<key>ProvisionedDevices</key>")&&!$t,isDevelopment:$t};try{let Dt=re(`security cms -D -i "${At}"`,{encoding:"utf-8"}).match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);W=Dt?Dt[1]:void 0}catch{let Dt=tt.match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);W=Dt?Dt[1]:void 0}W||(R.warn("Could not extract UUID from provisioning profile. Using fallback."),W=`${A.nameLower}-${t}`);let Ft=y.join(ge,`${W}.mobileprovision`);I.existsSync(Ft)&&I.unlinkSync(Ft),I.renameSync(At,Ft);let lt=Et(Ft);if(lt.uuid&&lt.uuid!==W){let Ot=y.join(ge,`${lt.uuid}.mobileprovision`);I.existsSync(Ot)&&I.unlinkSync(Ot),I.renameSync(Ft,Ot),W=lt.uuid}X={isAppStore:lt.isAppStore,isDevelopment:lt.isDevelopment},se=[lt]}try{let ge=re(`security find-identity -v -p codesigning "${ke}"`,{encoding:"utf-8"}),Ve=wr(ge),At=se[0];if(!At)throw new Error("No decoded provisioning profile is available for signing validation.");let tt=Cr(Ve,At),$t=se.filter(Tt=>!Tt.certificateSha1s.includes(tt.sha1));if($t.length>0)throw new Error(`The selected P12 does not contain one certificate accepted by every provisioning profile. Mismatched profile(s): ${$t.map(Tt=>Tt.name||Tt.uuid||"unknown").join(", ")}. Run \`mach credentials\` to regenerate those profiles with the selected certificate.`);G=tt.sha1,R.info(w.green(`\u2713 Signing identity verified against provisioning profile (${tt.name}, ${tt.sha1.slice(0,12)}\u2026).`))}catch(ge){throw new Error(`iOS signing credential mismatch: ${ge.message}`)}R.info(w.dim(`Profile type: ${X.isDevelopment?"Development":X.isAppStore?"App Store":"Ad-Hoc"}`)),R.info(w.dim(`Identity Detection: get-task-allow=${X.isDevelopment}, Selected Identity fingerprint=${G}`)),T.push("CODE_SIGN_STYLE=Manual"),T.push(`CODE_SIGN_IDENTITY="${G}"`),O||T.push(`PROVISIONING_PROFILE_SPECIFIER=${W}`),e.iosTeamId&&T.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`)}catch(Re){throw R.error(`Signing setup failed: ${Re.message}`),Re}}else T.push("-allowProvisioningUpdates"),e.iosTeamId&&T.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`);l&&await l("archive"),R.info(w.blue(`Archive detected Identity: "${G}"`)),R.info(w.blue(`Archive detected UUID: "${W}"`)),await hn(["archive",p?"-workspace":"-project",p||f,"-scheme",C,"-configuration",N,"-archivePath",D,"-derivedDataPath",S,...P,...T],d,m,o,s);let ue=qe(y.join(D,"Products","Applications"),[".app"]);for(let Re of ue)for(let ke of Mr(Re,v||void 0))R.info(w.dim(`Validated iOS CFBundleVersion ${ke.buildNumber} in ${y.basename(ke.bundlePath)}`));let ye;W?(X.isAppStore?ye="app-store":X.isDevelopment?ye="development":ye="ad-hoc",R.info(w.blue(`Export method from profile: "${ye}"`))):(ye=e.distribution==="store"?"app-store":e.distribution==="internal"?"ad-hoc":"development",R.warn(w.yellow(`No profile UUID detected. Export method from distribution flag: "${ye}"`)));let V=e.iosExportMethod||ye,J=e.iosBundleIdentifier||xt("ios"),ne=O?z:J&&W?[{bundleIdentifier:J,uuid:W}]:[],Y=W&&G?`<key>signingCertificate</key><string>${G}</string>`:"",K=y.join(d,"ExportOptions.plist"),pe=`<?xml version="1.0" encoding="UTF-8"?>
646
+ `;n&&n(w.dim(o)),E.info(w.dim(o.trim()))},up=async(e,t,n={},i,r={})=>{let o=yn(),s=Date.now(),a=e.platform,l=e.buildProfile||"production",c=Gt(e.framework),d=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),u=d.sourceRoot,p=d.appRoot;e.appDirectory=d.appDirectory;let f=()=>({...an(n,l,e),MACH_SOURCE_ROOT:u,MACH_APP_ROOT:p}),m=async(N,M={})=>{if(i)for(let D=1;D<=3;D++)try{await U.patch(`/builds/${i}/${t}`,{status:N,...M});return}catch(ce){let Se=ce?.response?.data?.message||ce?.message||String(ce);console.error(`[reportStatus] attempt ${D}/3 failed (status=${N}): ${Se}`),D<3&&await new Promise(Z=>setTimeout(Z,2e3))}},P=new AbortController,{signal:v}=P,R=null;i&&(R=setInterval(async()=>{try{(await U.get(`/builds/${i}/${t}`)).data.status==="cancelled"&&(E.warn(w.yellow(`
647
+ \u{1F6D1} Build cancelled from dashboard. Terminating...`)),P.abort(),R&&clearInterval(R))}catch{}},5e3));let O=y.join(u,".mach-cache"),C="setup",x="",S=null,_=async()=>{if(!x||!i)return;let N=x;x="";try{let M=N;Object.values(n).forEach(D=>{if(D&&D.length>5){let ce=D.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");M=M.replace(new RegExp(ce,"g"),"[SECRET]")}}),await U.post(`/builds/${i}/${t}/logs`,{log:M,step:C})}catch{}},k=async()=>{S&&(clearTimeout(S),S=null),await _(),Va(O,t),R&&(clearInterval(R),R=null);try{let N=y.join(ye.tmpdir(),`${A.buildPrefix}-${t}.keychain-db`);I.existsSync(N)&&(re(`security delete-keychain "${N}"`,{stdio:"ignore"}),E.info(w.dim("\u{1F511} Build keychain deleted.")))}catch{}try{let N=y.join(ye.homedir(),"Library/MobileDevice/Provisioning Profiles");if(I.existsSync(N)){let M=I.readdirSync(N).filter(D=>D.includes(t)||D.startsWith(`${A.nameLower}-temp-${t}`));for(let D of M)I.unlinkSync(y.join(N,D))}}catch{}},b=async N=>{i&&(x+=N,x.length>=8192?(S&&(clearTimeout(S),S=null),await _()):S||(S=setTimeout(()=>{S=null,_()},2e3)))},$=async N=>{C=N,await b(`[STEP_START:${N}] ${Math.floor(Date.now()/1e3)}
648
+ `)},j=async(N,M,D,ce)=>await je(N,M,D,ce,Se=>{b(Se)},v);E.info(w.blue(`\u{1F680} Starting local build for ${a} (${l})...`));try{Ma(O,t)}catch(N){throw await m("failed",{error:N.message,endTime:Date.now()}),N}await m("building"),await $("setup"),a==="ios"&&!e.simulator&&n.MACH_IOS_BUILD_NUMBER_LOCKED==="1"&&n.BUILD_NUMBER&&(E.info(w.dim(`Auto build number: ${n.BUILD_NUMBER}`)),await b(`[BUILD_NUMBER] ${n.BUILD_NUMBER}
649
+ `)),await $("lock"),c.applyLocalProcessEnv(e);try{await $("clone"),E.info(w.dim("Preparing source...")),await $("read_config");let N=y.join(u,A.configFileName);if(I.existsSync(N)){let T=JSON.parse(I.readFileSync(N,"utf-8"))?.build?.[l]||{};await b(`[CONFIG] Profile: ${l}, distribution: ${T.distribution||"not set"}, simulator: ${T.simulator||!1}
650
+ `)}if(await $("read_package"),e.framework!=="flutter"&&e.nodeVersion){let F=process.env.NVM_DIR||y.join(ye.homedir(),".nvm"),T=y.join(F,"versions","node"),G;if(I.existsSync(T)){let W=I.readdirSync(T).sort().reverse(),z=e.nodeVersion.startsWith("v")?e.nodeVersion:`v${e.nodeVersion}`,se=W.find(X=>X===z||X.startsWith(z+".")||X.startsWith(`v${e.nodeVersion}.`));se&&(G=y.join(T,se,"bin"))}if(G&&I.existsSync(G)){let W=process.env.PATH||"";process.env.PATH=`${G}:${W}`,await b(`[NODE] Switched to Node ${e.nodeVersion} \u2014 using ${G}
651
+ `),E.info(w.green(`\u2713 Node switched to ${e.nodeVersion} (${G})`))}else await b(`[NODE] Warning: Node ${e.nodeVersion} not found in nvm. Run: nvm install ${e.nodeVersion} on the build machine.
652
+ `),E.warn(w.yellow(`Node ${e.nodeVersion} not found in nvm \u2014 using system default`))}await $("deps"),o.start("Checking dependencies...");let M=Fa(O),D={};if(e.framework==="flutter")o.stop("Preparing Flutter dependencies..."),e.preBuild&&(E.info(w.blue("Running pre-install hook...")),E.info(w.dim(`> ${e.preBuild}`)),await $("prebuild"),await j("bash",[e.preBuild],u,f())),D=await c.prepareLocalProject({platform:a,options:e,sourceRoot:u,appRoot:p,cacheMeta:M,cacheMetaDir:O,currentBuildEnv:f,reportStep:$,reportLog:b,loggedRun:j,configureXcodeNodeBinary:ui,podsFingerprint:Fr,writeCacheMeta:di});else{let F=Ta(u),T=I.existsSync(y.join(u,"node_modules")),G=I.existsSync(y.join(u,"yarn.lock")),W=I.existsSync(y.join(u,"bun.lockb"));T&&M.node&&M.node!==F&&(o.stop("Dependency fingerprint changed \u2014 clearing node_modules for clean install..."),await b(`[CACHE] package.json/lockfile changed \u2014 wiping node_modules
653
+ `),I.rmSync(y.join(u,"node_modules"),{recursive:!0,force:!0}),T=!1);let z="npm",se=["install","--prefer-offline"];if(G?(z="yarn",se=["install","--prefer-offline"]):W&&(z="bun",se=["install"]),T?o.stop("Cached node_modules found. Syncing dependencies..."):o.stop("No cached dependencies. Running fresh install..."),e.preBuild&&(E.info(w.blue("Running pre-install hook...")),E.info(w.dim(`> ${e.preBuild}`)),await $("prebuild"),await j("bash",[e.preBuild],u,f())),E.info(w.dim(`Running ${z} ${se.join(" ")}...`)),await j(z,se,u,f()),M.node=F,di(O,M),e.framework==="expo"){let X=n.MACH_OTA_RUNTIME_VERSION,ue=n.MACH_OTA_CHANNEL,Ie=n.MACH_OTA_URL;if(X&&ue&&Ie){let B=Ir(u,{platform:a,runtimeVersion:X,channel:ue,url:Ie}),J=yr(B,{runtimeVersion:X,channel:ue,url:Ie});if(J.length>0)throw new Error(`Expo OTA configuration mismatch after installing dependencies: ${J.join("; ")}. Run \`${A.nameLower} ota setup\` to update the local Expo plugin before building.`);E.info(w.green(`\u2713 Expo OTA configuration verified (${ue})`))}}D=await c.prepareLocalProject({platform:a,options:e,sourceRoot:u,appRoot:p,cacheMeta:M,cacheMetaDir:O,currentBuildEnv:f,reportStep:$,reportLog:b,loggedRun:j,configureXcodeNodeBinary:ui,podsFingerprint:Fr,writeCacheMeta:di})}let ce=D.bundleId||e.iosBundleIdentifier||"",Se=D.appName||e.name||"",Z=[];if(a==="android")await $("build"),Z=await nc(e,l,n,F=>b(F),v);else if(a==="ios"){await $("signing"),E.info(w.dim("Preparing credentials..."));let F=r?.distributionType;Z=await rc(e,t,l,n,i,T=>b(T),v,F,T=>$(T))}else a==="web"&&e.framework==="flutter"&&(await $("build"),Z=await ic(e,n,F=>b(F),v));if(e.framework==="flutter"&&e.flutterSplitDebugInfoPath&&I.existsSync(e.flutterSplitDebugInfoPath)){let F=qe(e.flutterSplitDebugInfoPath,[".symbols",".json"]);if(F.length>0){let T=y.join(ye.tmpdir(),`${t}-flutter-symbols.zip`),G=new Ur;G.addLocalFolder(e.flutterSplitDebugInfoPath),G.writeZip(T),Z.push(T),await b(`[FLUTTER] Preserved ${F.length} split debug symbol file(s)
654
+ `)}}if(e.postBuild&&(E.info(w.blue("Running post-build hook...")),E.info(w.dim(`> ${e.postBuild}`)),await j(e.postBuild,[],u,f())),a==="ios"){let F=Zt(e.resolvedBuildNumber||n.BUILD_NUMBER);if(F)for(let T of Z.filter(G=>G.endsWith(".ipa"))){let G=zr(T,F);await b(`[IPA FINAL] CFBundleVersion ${G} matches MACH buildNumber ${F}
655
+ `)}}if(a==="android"){let F=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(F){let T=We(F,"resolved MACH build assignment");if(Z.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${T}.`);for(let G of Z){let W=cn(G,T);await b(`[ANDROID FINAL] ${y.basename(G)} versionCode ${W} matches MACH assignment
656
+ `)}}}let Ue=Ka(Date.now()-s);if(E.success(w.green(`
657
+ \u2713 Local build completed successfully in ${Ue}`)),await m("building",{...ce&&{bundleId:ce},...Se&&{appName:Se}}),Z.length>0&&(E.info(w.cyan(`
658
+ \u{1F4E6} Generated Artifacts:`)),Z.forEach(F=>{let T=y.resolve(F);E.info(w.dim(` - ${F}`)),E.info(w.gray(` Path: ${T}`))}),e.interactive)){let F=await Oa({message:"Install on connected device?"});if(!In(F)&&F){if(a==="android"){let T=Z.find(G=>G.endsWith(".apk"))||Z[0];await sc(T,G=>b(G))}else if(a==="ios"){let T=Z.find(W=>W.endsWith(".ipa"))||Z.find(W=>W.endsWith(".app"))||Z[0],G=Nt("ios");e.simulator?await ac(T,G||"",W=>b(W)):await cc(T,G||"",W=>b(W))}}}await $("upload");let de=[];for(let F of Z)try{let T=y.join(ye.tmpdir(),`${t}-${y.basename(F)}`);I.copyFileSync(F,T),de.push(T),E.info(w.dim(` \u{1F4CB} Preserved artifact: ${y.basename(F)}`))}catch{E.warn(w.yellow(` Failed to preserve artifact: ${y.basename(F)}`))}if(Z=de,r?.isolatedRunner===!0){E.info(w.dim("\u{1F9F9} Cleaning isolated workspace (preserving dependency cache)..."));try{let F=process.cwd(),T=new Set(["node_modules"]),G=I.readdirSync(F),W=0;for(let z of G)if(!T.has(z)){if(z==="ios"){let se=y.join(F,"ios"),X=I.readdirSync(se);for(let ue of X)if(ue!=="Pods")try{I.rmSync(y.join(se,ue),{recursive:!0,force:!0}),W++}catch{}continue}try{I.rmSync(y.join(F,z),{recursive:!0,force:!0}),W++}catch{}}E.info(w.dim(` Cleaned ${W} items. Cached: node_modules${I.existsSync(y.join(F,"ios","Pods"))?", ios/Pods":""}`)),E.info(w.green("\u{1F512} Security: No source code retained on build server. Only public dependencies cached."))}catch{E.warn(w.yellow("Post-build cleanup encountered errors (non-fatal)."))}try{let T=y.join(ye.homedir(),A.workspacesDir),G=re(`df -k "${T}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim(),W=parseInt(G,10)*1024;if(W<53687091200&&I.existsSync(T)){E.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()),se=I.readdirSync(T).filter(X=>X!==z).map(X=>{let ue=y.join(T,X);try{let Ie=I.statSync(ue);return Ie.isDirectory()?{name:X,dir:ue,mtime:Ie.mtimeMs}:null}catch{return null}}).filter(Boolean);se.sort((X,ue)=>X.mtime-ue.mtime);for(let X of se){if(W>=53687091200)break;try{I.rmSync(X.dir,{recursive:!0,force:!0}),E.info(w.dim(` \u{1F5D1}\uFE0F Evicted stale workspace: ${X.name}`));let ue=re(`df -k "${T}" | tail -1 | awk '{print $4}'`,{encoding:"utf8"}).trim();if(parseInt(ue,10)*1024>=53687091200)break}catch{}}}}catch{}}return await k(),Z}catch(N){throw await k(),N.message==="Command aborted"?(E.warn(w.yellow(`
659
+ \u274C Build aborted.`)),await m("failed",{error:"Aborted by user",endTime:Date.now()}),N):(E.error(w.red(`
660
+ \u2717 Local build failed: ${N.message}`)),await m("failed",{error:N.message,endTime:Date.now()}),N)}},nc=async(e,t,n={},i,r)=>{let o=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),s=y.join(o.appRoot,"android");if(e.framework==="flutter"){let S=e.apk===!0?"apk":e.apk===!1||e.distribution==="store"?"appbundle":"apk",_={...n,...an(n,t,e),MACH_SOURCE_ROOT:o.sourceRoot,MACH_APP_ROOT:o.appRoot},k;if(n.ANDROID_KEYSTORE_BASE64&&n.ANDROID_KEY_ALIAS&&n.ANDROID_KEY_PASSWORD){let M=I.mkdtempSync(y.join(ye.tmpdir(),"mach-flutter-signing-"));k=y.join(M,"release.keystore"),I.writeFileSync(k,Buffer.from(n.ANDROID_KEYSTORE_BASE64,"base64"),{mode:384}),_["ORG_GRADLE_PROJECT_android.injected.signing.store.file"]=k,_["ORG_GRADLE_PROJECT_android.injected.signing.store.password"]=n.ANDROID_STORE_PASSWORD||n.ANDROID_KEY_PASSWORD,_["ORG_GRADLE_PROJECT_android.injected.signing.key.alias"]=n.ANDROID_KEY_ALIAS,_["ORG_GRADLE_PROJECT_android.injected.signing.key.password"]=n.ANDROID_KEY_PASSWORD}let b=["build",S,...Wt(e,_)];E.info(w.blue(`Running Flutter Android ${S} build...`));try{ke(y.join(o.appRoot,"build","app","outputs")),await je("flutter",b,o.appRoot,_,i,r)}finally{k&&ke(y.dirname(k))}let $=y.join(o.appRoot,"build/app/outputs"),j=qe($,S==="appbundle"?[".aab"]:[".apk"]);if(j.length===0)throw new Error(`Flutter build completed but produced no ${S==="appbundle"?"AAB":"APK"} artifact.`);let N=e.resolvedVersionCode||n.ANDROID_VERSION_CODE;if(N)for(let M of j)cn(M,N);return j}let a=y.join(o.appRoot,"gradlew"),l=y.join(s,"gradlew"),c=I.existsSync(l)?l:I.existsSync(a)?a:null;if(!c)throw new Error(`Could not find gradlew inside appDirectory "${o.appDirectory}".`);let d=e.developmentClient?"assembleDebug":"assembleRelease";!e.developmentClient&&e.distribution==="store"?d="bundleRelease":!e.developmentClient&&e.distribution==="internal"&&(d="assembleRelease");let u=e.buildCommand||d;E.info(w.blue(`Running Android build: ${u}...`));let p=c===l?s:o.appRoot,f="./gradlew",m=[u],P=Gt(e.framework),v={...n,...P.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,O=R?We(R,"resolved MACH build assignment"):null,C=null,x=null;O&&(C=I.mkdtempSync(y.join(ye.tmpdir(),"mach-android-version-")),x=y.join(C,"mach-android-version.init.gradle"),I.writeFileSync(x,lr,{mode:384}),m.push("--init-script",x,"--no-configuration-cache"),v.ANDROID_VERSION_CODE=O,E.info(w.green(`\u2713 Locking Android versionCode ${O} with the public Variant API`)));try{for(let k of["app/build","build",".cxx"]){let b=y.join(p,k);I.existsSync(b)&&I.rmSync(b,{recursive:!0,force:!0})}Pt(o.appRoot),o.appRoot!==o.sourceRoot&&Pt(o.sourceRoot),O&&x&&(E.info(w.blue(`Verifying Android versionCode ${O} before compilation...`)),await je(f,[dr,"--init-script",x,"--no-configure-on-demand","--no-configuration-cache","--console=plain","--no-daemon"],p,v,i,r)),await je(f,m,p,v,i,r);let S=y.join(p,"app/build/outputs"),_=qe(S,[".apk",".aab"]);if(O&&_.length===0)throw new Error(`Android build produced no APK or AAB to verify against MACH versionCode ${O}.`);if(O)for(let k of _){let b=cn(k,O);E.info(w.dim(`Validated Android versionCode ${b} in ${y.basename(k)}`)),i?.(`[ANDROID VALID] ${y.basename(k)} versionCode ${b} matches MACH assignment
661
+ `)}return _}finally{C&&ke(C)}},ic=async(e,t={},n,i)=>{let r=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),o={...t,MACH_SOURCE_ROOT:r.sourceRoot,MACH_APP_ROOT:r.appRoot},s=y.join(r.appRoot,"build","web");if(ke(s),E.info(w.blue("Running Flutter web build...")),await je("flutter",["build","web",...Wt(e,o)],r.appRoot,o,n,i),!I.existsSync(y.join(s,"index.html")))throw new Error("Flutter web build completed but build/web/index.html is missing.");let a=y.join(ye.tmpdir(),`${e.buildId||Lr.randomUUID()}-flutter-web.zip`),l=new Ur;return l.addLocalFolder(s),l.writeZip(a),[a]},rc=async(e,t,n,i={},r,o,s,a,l)=>{if(process.platform!=="darwin")throw new Error("iOS builds can only be run on macOS.");let c=ze(process.cwd(),e.appDirectory,{requireAppDirectory:!0}),d=y.join(c.appRoot,"ios");if(!I.existsSync(d))throw new Error(`Could not find ios/ inside appDirectory "${c.appDirectory}".`);Zr(d);let u=I.readdirSync(d),p=u.find(k=>k.endsWith(".xcworkspace")),f=u.find(k=>k.endsWith(".xcodeproj")),m={...an(i,n,e),MACH_SOURCE_ROOT:c.sourceRoot,MACH_APP_ROOT:c.appRoot};e.framework!=="flutter"&&ui(d,m,o);let P=e.resolvedBuildNumber||m.BUILD_NUMBER||m.CURRENT_PROJECT_VERSION,v=Zt(P);if(P&&!v)throw new Error(`Invalid iOS build number: "${P}". 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=v?[`BUILD_NUMBER=${v}`,`CURRENT_PROJECT_VERSION=${v}`,`INFOPLIST_KEY_CFBundleVersion=${v}`]:[];if(v&&(m.BUILD_NUMBER=v,m.CURRENT_PROJECT_VERSION=v,E.info(w.dim(`Using iOS build number: ${v}`))),!p&&!f)throw new Error("Could not find Xcode workspace or project in ios/ directory.");try{let k=re("xcode-select -p").toString().trim();E.info(w.dim(`Using Xcode at: ${k}`))}catch{E.warn(w.dim("Could not detect Xcode path."))}E.info(w.blue("Running iOS build via xcodebuild..."));let O=p?p.replace(".xcworkspace",""):f?.replace(".xcodeproj",""),C=e.iosScheme||O||e.scheme,x=e.developmentClient?"Debug":e.iosConfiguration||"Release",S,_;try{if(v){S=ir(d,v,{workspace:p,project:f,scheme:C,configuration:x});let D=S.plistPaths.length>0?`${S.plistPaths.length} Xcode target Info.plist file(s)`:"generated Info.plist build settings";E.info(w.green(`\u2713 Applied iOS buildNumber ${v} to ${D}`)),o&&o(`[VERSIONING] Applied iOS buildNumber ${v} to ${D}
662
+ `)}let k=(r||"default").replace(/[^a-zA-Z0-9-_]/g,"_"),b=y.join(ye.homedir(),`Library/Developer/Xcode/DerivedData/${A.nameLower}`,k);I.mkdirSync(b,{recursive:!0});let $=er(m),j=y.join(b,".mach-env-hash"),N=y.join(b,"Build"),M=I.existsSync(j)?I.readFileSync(j,"utf-8").trim():"";if(I.existsSync(N)){let D=M&&M!==$?"Build environment changed \u2014 clearing iOS DerivedData build products.":M?"Clearing iOS DerivedData build products to force a fresh JS bundle.":"DerivedData has no environment stamp \u2014 clearing iOS build products.";E.info(w.dim(D)),I.rmSync(N,{recursive:!0,force:!0})}if(I.writeFileSync(j,$),e.framework!=="flutter"&&(Pt(c.appRoot),c.appRoot!==c.sourceRoot&&Pt(c.sourceRoot)),e.simulator){let D=Xa(d,p,f,C,x),ce=D||"generic/platform=iOS Simulator",Se=["-destination",ce];E.info(w.dim(D?`Building for simulator (Scheme: ${C}, Config: ${x}, Destination: ${ce})...`:`Building for simulator (Scheme: ${C}, Config: ${x}, Destination: ${ce})...`));let Z=[p?"-workspace":"-project",p||f,"-scheme",C,"-configuration",x,"-sdk","iphonesimulator",...Se,"-derivedDataPath",b,...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 hn(Z,d,m,o,s)}catch(ue){if(!Ga(ue))throw ue;Za(b),e.framework!=="flutter"&&(Pt(c.appRoot),c.appRoot!==c.sourceRoot&&Pt(c.sourceRoot)),await hn(Z,d,m,o,s)}let Ue=y.join(b,"Build/Products",`${x}-iphonesimulator`),de=Ya(Ue,C,e),F=y.basename(de,".app"),T=Rt(y.join(de,"Info.plist"),"CFBundleIdentifier")||"unknown bundle",W=Br(de,v||void 0)[0].buildNumber,z=Jr(de),se=Yr(de),X=y.join(Ue,`${F}_simulator.zip`);return E.info(w.dim(`Selected simulator app: ${y.relative(Ue,de)} (${T}, build ${W})`)),E.info(w.dim(`Simulator executable architecture: ${z}`)),E.info(w.dim(`Simulator executable platform: ${se.split(`
663
+ `).find(ue=>/\bplatform\b/i.test(ue))?.trim()||"IOSSIMULATOR"}`)),E.info(w.dim(`Creating simulator artifact: ${X}...`)),ke(X),Qe("zip",["-r",X,y.basename(de)],{cwd:y.dirname(de),stdio:"pipe"}),[X]}else{E.info(w.dim(`Archiving (Scheme: ${C}, Config: ${x})...`));let D=y.join(d,"build.xcarchive"),ce=y.join(d,"export");I.rmSync(D,{recursive:!0,force:!0}),I.rmSync(ce,{recursive:!0,force:!0});let Se=i.IOS_DIST_P12,Z=i.IOS_PROVISIONING_PROFILE,Ue=i.IOS_P12_PASSWORD||"",de=Sr(i.IOS_PROVISIONING_PROFILES),F=de.length>1,T=[],G,W,z=[],se=[],X={isAppStore:!1,isDevelopment:!1};if(Se&&Z){E.info(w.blue("\u{1F510} CI/CD Signing: Importing certificates..."));try{let Re=`${A.buildPrefix}-${t}.keychain-db`,_e=y.join(ye.tmpdir(),Re),It=A.keychainPassword;re(`security create-keychain -p "${It}" "${_e}" 2>/dev/null || true`),re(`security set-keychain-settings -t 3600 -l "${_e}"`),re(`security unlock-keychain -p "${It}" "${_e}"`);let xn=y.join(ye.tmpdir(),`cert-${t}.p12`),_t=Buffer.from(Se,"base64");I.writeFileSync(xn,_t),E.info(w.dim(`P12 data size: ${_t.length} bytes, first bytes: ${_t.slice(0,4).toString("hex")}`)),(_t.length<100||_t[0]!==48)&&(E.warn(w.yellow("\u26A0\uFE0F P12 data looks corrupted or was not decrypted correctly.")),E.warn(w.yellow(" This usually means MACH_ENCRYPTION_KEY on the Remote API differs from when credentials were uploaded.")));let Do=[Ue,"",A.keychainPassword],ki=!1;for(let ge of Do)try{re(`security import "${xn}" -k "${_e}" -P "${ge}" -A -T /usr/bin/codesign -T /usr/bin/security`,{stdio:"pipe"}),ki=!0,E.info(w.dim(`\u2713 P12 imported successfully with password: ${ge?"[set]":"[empty]"}`));break}catch(Be){E.info(w.dim(` P12 import attempt with password ${ge?`"${ge.substring(0,3)}..."`:"[empty]"} failed: ${Be.message?.split(`
664
+ `)[0]||"unknown"}`))}if(!ki)throw new Error("Failed to import P12.");I.unlinkSync(xn),re(`security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${It}" "${_e}"`);let Mo=re("security list-keychains -d user",{encoding:"utf-8"}).split(`
665
+ `).map(ge=>ge.trim().replace(/^"|"$/g,"")).filter(ge=>ge.length>0),Vo=[_e,...Mo].map(ge=>`"${ge}"`).join(" ");if(re(`security list-keychains -d user -s ${Vo}`),re(`security default-keychain -s "${_e}"`),F){z=_r({profiles:de,buildId:t});let ge=z.find(Be=>Be.isMainApplication)||z[0];W=ge.uuid,X={isAppStore:ge.isAppStore,isDevelopment:ge.isDevelopment},se=z.map(Be=>Be.signingProfile),_=Or({iosDirectory:d,profiles:z,teamId:e.iosTeamId,temporaryLabel:t}),E.info(w.green(`\u2713 Applied target-specific signing to ${_.matchedTargets.length} Xcode targets`));for(let Be of _.matchedTargets)E.info(w.dim(` - ${Be}`))}else{let ge=y.join(ye.homedir(),"Library/MobileDevice/Provisioning Profiles");I.mkdirSync(ge,{recursive:!0});let Be=Buffer.from(Z,"base64"),At=y.join(ge,`${A.nameLower}-temp-${t}.mobileprovision`);I.writeFileSync(At,Be);let tt=Be.toString("utf-8"),$t=/<key>get-task-allow<\/key>\s*<true\/>/.test(tt);X={isAppStore:!tt.includes("<key>ProvisionedDevices</key>")&&!$t,isDevelopment:$t};try{let Dt=re(`security cms -D -i "${At}"`,{encoding:"utf-8"}).match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);W=Dt?Dt[1]:void 0}catch{let Dt=tt.match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);W=Dt?Dt[1]:void 0}W||(E.warn("Could not extract UUID from provisioning profile. Using fallback."),W=`${A.nameLower}-${t}`);let Tt=y.join(ge,`${W}.mobileprovision`);I.existsSync(Tt)&&I.unlinkSync(Tt),I.renameSync(At,Tt);let lt=Et(Tt);if(lt.uuid&&lt.uuid!==W){let Ft=y.join(ge,`${lt.uuid}.mobileprovision`);I.existsSync(Ft)&&I.unlinkSync(Ft),I.renameSync(Tt,Ft),W=lt.uuid}X={isAppStore:lt.isAppStore,isDevelopment:lt.isDevelopment},se=[lt]}try{let ge=re(`security find-identity -v -p codesigning "${_e}"`,{encoding:"utf-8"}),Be=vr(ge),At=se[0];if(!At)throw new Error("No decoded provisioning profile is available for signing validation.");let tt=Er(Be,At),$t=se.filter(Ot=>!Ot.certificateSha1s.includes(tt.sha1));if($t.length>0)throw new Error(`The selected P12 does not contain one certificate accepted by every provisioning profile. Mismatched profile(s): ${$t.map(Ot=>Ot.name||Ot.uuid||"unknown").join(", ")}. Run \`mach credentials\` to regenerate those profiles with the selected certificate.`);G=tt.sha1,E.info(w.green(`\u2713 Signing identity verified against provisioning profile (${tt.name}, ${tt.sha1.slice(0,12)}\u2026).`))}catch(ge){throw new Error(`iOS signing credential mismatch: ${ge.message}`)}E.info(w.dim(`Profile type: ${X.isDevelopment?"Development":X.isAppStore?"App Store":"Ad-Hoc"}`)),E.info(w.dim(`Identity Detection: get-task-allow=${X.isDevelopment}, Selected Identity fingerprint=${G}`)),T.push("CODE_SIGN_STYLE=Manual"),T.push(`CODE_SIGN_IDENTITY="${G}"`),F||T.push(`PROVISIONING_PROFILE_SPECIFIER=${W}`),e.iosTeamId&&T.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`)}catch(Re){throw E.error(`Signing setup failed: ${Re.message}`),Re}}else T.push("-allowProvisioningUpdates"),e.iosTeamId&&T.push(`DEVELOPMENT_TEAM=${e.iosTeamId}`);l&&await l("archive"),E.info(w.blue(`Archive detected Identity: "${G}"`)),E.info(w.blue(`Archive detected UUID: "${W}"`)),await hn(["archive",p?"-workspace":"-project",p||f,"-scheme",C,"-configuration",x,"-archivePath",D,"-derivedDataPath",b,...R,...T],d,m,o,s);let ue=qe(y.join(D,"Products","Applications"),[".app"]);for(let Re of ue)for(let _e of Br(Re,v||void 0))E.info(w.dim(`Validated iOS CFBundleVersion ${_e.buildNumber} in ${y.basename(_e.bundlePath)}`));let Ie;W?(X.isAppStore?Ie="app-store":X.isDevelopment?Ie="development":Ie="ad-hoc",E.info(w.blue(`Export method from profile: "${Ie}"`))):(Ie=e.distribution==="store"?"app-store":e.distribution==="internal"?"ad-hoc":"development",E.warn(w.yellow(`No profile UUID detected. Export method from distribution flag: "${Ie}"`)));let B=e.iosExportMethod||Ie,J=e.iosBundleIdentifier||Nt("ios"),ne=F?z:J&&W?[{bundleIdentifier:J,uuid:W}]:[],Y=W&&G?`<key>signingCertificate</key><string>${G}</string>`:"",K=y.join(d,"ExportOptions.plist"),pe=`<?xml version="1.0" encoding="UTF-8"?>
581
666
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
582
667
  <plist version="1.0">
583
668
  <dict>
584
669
  <key>method</key>
585
- <string>${V}</string>
670
+ <string>${B}</string>
586
671
  <key>destination</key>
587
672
  <string>export</string>
588
673
  <key>signingStyle</key>
@@ -591,48 +676,48 @@ ${s.join(`
591
676
  <key>thinning</key>
592
677
  <string>&lt;none&gt;</string>
593
678
  ${e.iosTeamId?`<key>teamID</key><string>${e.iosTeamId}</string>`:""}
594
- ${$r(ne)}
679
+ ${Tr(ne)}
595
680
  </dict>
596
- </plist>`;if(I.writeFileSync(K,pe),process.env[`${A.envPrefix}DEBUG`]&&R.info(w.magenta(`[${A.nameUpper}_DEBUG] ExportOptions.plist:
597
- ${pe}`)),l&&await l("export"),R.info(w.blue(`Exporting with Bundle ID: "${J}"`)),R.info(w.blue(`Exporting with Method: "${V}"`)),o){o(w.magenta(`
681
+ </plist>`;if(I.writeFileSync(K,pe),process.env[`${A.envPrefix}DEBUG`]&&E.info(w.magenta(`[${A.nameUpper}_DEBUG] ExportOptions.plist:
682
+ ${pe}`)),l&&await l("export"),E.info(w.blue(`Exporting with Bundle ID: "${J}"`)),E.info(w.blue(`Exporting with Method: "${B}"`)),o){o(w.magenta(`
598
683
  [DIAGNOSTIC] Checking available signing identities...
599
684
  `));try{let Re=re("security find-identity -v -p codesigning",{encoding:"utf-8"});o(w.magenta(`${Re}
600
685
  `))}catch(Re){o(w.red(`[DIAGNOSTIC] Failed to list identities: ${Re.message}
601
- `))}}await hn(["-exportArchive","-archivePath",D,"-exportPath",ce,"-exportOptionsPlist",K],d,m,o,s),l&&await l("validate");let et=qe(ce,[".ipa"]);for(let Re of et)try{re(`unzip -t "${Re}"`,{stdio:"pipe"});let ke=Jr(Re,v||void 0);o&&o(`[IPA VALID] ${y.basename(Re)} \u2014 archive integrity OK
602
- `),o&&o(`[IPA VALID] CFBundleVersion ${ke}
603
- `)}catch(ke){let It=`IPA validation failed for ${y.basename(Re)}: ${ke.message||"archive may be corrupt"}`;throw o&&o(`[IPA CORRUPT] ${It}
604
- `),new Error(It)}return et}}finally{k?.restore(),b?.restore()}},xt=(e,t)=>{try{let n=y.join(process.cwd(),A.configFileName),i={};if(I.existsSync(n)){if(i=JSON.parse(I.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=ze(process.cwd(),t??i.appDirectory).appRoot;if(e==="android"){let s=["android/app/build.gradle","android/app/build.gradle.kts","app/build.gradle","app/build.gradle.kts","build.gradle","build.gradle.kts"];for(let l of s){let c=y.join(o,l);if(I.existsSync(c)){let u=I.readFileSync(c,"utf-8").match(/applicationId\s*(?:=\s*)?['"]([^'"]+)['"]/);if(u)return u[1]}}let a=["app.json","app.config.json","app.config.js","app.config.ts"];for(let l of a){let c=y.join(o,l);if(!I.existsSync(c))continue;let u=I.readFileSync(c,"utf-8").match(/(?:["']package["']|\bpackage)\s*[:=]\s*["']([^"']+)["']/);if(u?.[1])return u[1]}}else{let s=y.join(o,"ios"),a=I.existsSync(s)?s:o,l=qe(a,["Info.plist"]).filter(u=>!u.includes("/Pods/")&&!u.includes("/build/")&&!u.includes("/DerivedData/"));l.sort((u,p)=>p.split("/").length-u.split("/").length);for(let u of l){let f=I.readFileSync(u,"utf-8").match(/<key>CFBundleIdentifier<\/key>\s*<string>([^<]+)<\/string>/);if(f&&!f[1].includes("$"))return f[1]}let c=qe(a,[".xcodeproj"]);if(c.length>0){let u=y.join(c[0],"project.pbxproj");if(I.existsSync(u)){let f=I.readFileSync(u,"utf-8").match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/);if(f)return f[1]}}let d=["app.json","app.config.json","app.config.js","app.config.ts"];for(let u of d){let p=y.join(o,u);if(I.existsSync(p)){let m=I.readFileSync(p,"utf-8").match(/"bundleIdentifier":\s*"([^"]+)"/);if(m)return m[1]}}}}catch{return null}return null},ic=()=>{try{return re("emulator -version",{stdio:"ignore"}),"emulator"}catch{let t=Ae.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(I.existsSync(i))return i}return"emulator"},rc=async(e,t)=>{let n=yn();try{if(re("adb devices").toString().split(`
605
- `).slice(1).map(s=>s.trim()).filter(s=>s.length>0&&!s.startsWith("*")).map(s=>s.split(" ")[0]).length===0){R.warn(w.yellow("No Android devices or emulators found."));let s=ic(),a=[];try{a=re(`${s} -list-avds`).toString().split(`
606
- `).filter(l=>l.trim().length>0)}catch{}if(a.length>0){let l=await pi({message:"Select an emulator to launch:",options:a.map(u=>({value:u,label:u}))});if(In(l))return;n.start(`Launching emulator ${l}...`),Br(s,["-avd",l],{detached:!0,stdio:"ignore"}).unref();let c=0,d=!1;for(;c<60;){try{if(re("adb shell getprop sys.boot_completed",{stdio:"pipe"}).toString().trim()==="1"){d=!0;break}}catch{}await new Promise(u=>setTimeout(u,2e3)),c++}if(!d)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 We("adb",["install","-r",e],process.cwd(),{},t),n.stop("Installation complete.");let o=xt("android");if(o){R.info(w.blue(`\u{1F680} Launching ${o}...`));try{re(`adb shell dumpsys package ${o}`).toString().split(`
607
- `).find(l=>l.includes("android.intent.action.MAIN")&&l.includes("android.intent.category.LAUNCHER"))?re(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"}):re(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"})}catch{R.warn("Could not auto-launch app. You may need to open it manually.")}}}catch(i){n.stop("Installation failed."),R.error(w.red(`Failed to install APK: ${i.message}`))}},oc=async(e,t,n)=>{let i=yn();try{if(!re("xcrun simctl list devices booted").toString().includes("(Booted)")){R.warn(w.yellow("No iOS Simulator is currently booted."));let o=re("xcrun simctl list devices --json").toString(),s=JSON.parse(o).devices,a=[];Object.keys(s).forEach(u=>{s[u].forEach(p=>{p.isAvailable&&a.push({...p,runtime:u})})});let l=await pi({message:"Select a simulator to launch:",options:a.map(u=>({value:u.udid,label:`${u.name} (${u.runtime.split(".").pop()})`}))});if(In(l))return;i.start(`Booting ${l}...`),re(`xcrun simctl boot ${l}`),re(`open -a Simulator --args -CurrentDeviceUDID ${l}`);let c=0,d=!1;for(;c<30;){try{if(re("xcrun simctl list devices booted").toString().includes(l)){d=!0;break}}catch{}await new Promise(u=>setTimeout(u,2e3)),c++}if(!d)throw i.stop("Simulator boot timed out."),new Error("Simulator boot timed out.");i.stop("Simulator booted.")}i.start("Installing on iOS Simulator..."),Xr(e),Kr(e),await We("xcrun",["simctl","install","booted",e],process.cwd(),{},n),i.stop("Installation complete."),R.info(w.blue(`\u{1F680} Launching ${t}...`)),await We("xcrun",["simctl","launch","booted",t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),R.error(w.red(`Failed to install on Simulator: ${r.message}`))}},sc=async(e,t,n)=>{let i=yn();i.start("Scanning for connected iOS devices...");try{let r=re("xcrun devicectl list devices --json-output -").toString(),s=(JSON.parse(r).result?.devices||[]).filter(l=>l.connectionProperties?.transportType==="wired"||l.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 l=await pi({message:"Select a device to install on:",options:s.map(c=>({value:c.identifier,label:`${c.deviceProperties?.name||c.name||c.model?.name} (${c.model?.name||"iPhone"}) - ${c.identifier}`}))});if(In(l))return;a=l,i.start(`Installing on ${a}...`)}else i.message(`Installing on ${s[0].model.name}...`);await We("xcrun",["devicectl","device","install","app","--device",a,e],process.cwd(),{},n),i.stop("Installation complete."),R.info(w.blue(`\u{1F680} Launching ${t}...`)),await We("xcrun",["devicectl","device","launch","app","--device",a,t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),R.error(w.red(`Failed to install on device: ${r.message}`)),R.info(w.dim('Make sure your device is unlocked and "Developer Mode" is enabled in Settings -> Privacy & Security.'))}};import{createRequire as ac}from"module";var cc=ac(import.meta.url),lc=cc("../package.json"),hi=String(lc.version||"0.0.0");var to="https://mach-api.securejs.in",dc=["google-services.json","android/app/google-services.json"],Yr="0.1.4",no="0.1.0";function uc(){return Ee.join(process.cwd(),A.configFileName)}function bn(){let e=Ti();if(!e?.projectId)throw new Error(`No linked MACH project. Run \`${A.nameLower} link\` first.`);return e}function io(e){me.writeFileSync(uc(),`${JSON.stringify(e,null,2)}
608
- `)}function pc(){return yi(Ee.join(process.cwd(),"package.json"))}function yi(e){if(!me.existsSync(e))return null;try{return JSON.parse(me.readFileSync(e,"utf8"))}catch{return null}}function fc(e){let t=pc();return!!(t?.dependencies?.[e]||t?.devDependencies?.[e])}function Ii(e){let t=process.cwd(),n=yi(Ee.join(t,"node_modules",...e.split("/"),"package.json"));if(typeof n?.version=="string")return n.version;let r=yi(Ee.join(t,"package-lock.json"))?.packages?.[`node_modules/${e}`]?.version;return typeof r=="string"?r:void 0}function mc(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 zr(e,t){let n=Ii(e);return!fc(e)||!n||mc(n,t)<0}function gc(e,t=!1){let n=process.cwd();return me.existsSync(Ee.join(n,"pnpm-lock.yaml"))?{command:"pnpm",args:["add",...t?["-D"]:[],e],label:`pnpm add ${t?"-D ":""}${e}`}:me.existsSync(Ee.join(n,"yarn.lock"))?{command:"yarn",args:["add",...t?["-D"]:[],e],label:`yarn add ${t?"-D ":""}${e}`}:me.existsSync(Ee.join(n,"bun.lock"))||me.existsSync(Ee.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 Qr(e,t=!1){let n=gc(e,t);console.log(ae.dim(`Installing dependency: ${n.label}`));let i=eo(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 hc(e,t,n=process.cwd()){let i=[];if(t)return i.push("Dependency installation skipped."),i;if(e==="flutter"){let r=Ee.join(n,"pubspec.yaml");if(me.existsSync(r)&&/^\s{2}mach_push_flutter\s*:/m.test(me.readFileSync(r,"utf8")))return i.push("mach_push_flutter is already present in pubspec.yaml."),i;let s=`mach_push_flutter:^${no}`;console.log(ae.dim(`Installing dependency: flutter pub add ${s}`));let a=eo("flutter",["pub","add",s],{cwd:n,stdio:"inherit",timeout:12e4,env:{...process.env}});if(a.error||a.status!==0)throw new Error(`flutter pub add ${s} failed${a.error?`: ${a.error.message}`:` with code ${a.status}`}. No application files were wired. Use --skip-install only when the dependency is already managed by your workspace.`);return i.push(`Installed with flutter pub add ${s}.`),i}if(zr("@radhya/mach-push-react-native",Yr)){let r=Qr(`@radhya/mach-push-react-native@${Yr}`);if(!r.ok)throw new Error(`${r.note} No application files were wired.`);i.push(r.note)}else i.push(`@radhya/mach-push-react-native is already current (${Ii("@radhya/mach-push-react-native")}).`);if(e==="expo")if(zr("@radhya/mach",hi)){let r=Qr(`@radhya/mach@${hi}`,!0);if(!r.ok)throw new Error(`${r.note} No Expo configuration was changed.`);i.push(r.note)}else i.push(`@radhya/mach is already current for the Expo config (${Ii("@radhya/mach")}).`);return i}function yc(e,t,n=process.cwd()){return e||t||["google-services.json","android/app/google-services.json"].find(i=>me.existsSync(Ee.join(n,i)))}function ro(e){let t={enabled:!0};return e.appId&&e.publishableKey&&(t.appId=e.appId,t.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!==to&&(t.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(t.environment=e.environment),e.googleServicesFile&&!dc.includes(e.googleServicesFile)&&(t.googleServicesFile=e.googleServicesFile),t}function Ic(e){return e==="development"?"development":"production"}function oo(e){let t=process.cwd(),n=e==="ios"?"bundleIdentifier":"package";for(let i of["app.json","app.config.json"]){let r=Ee.join(t,i);if(me.existsSync(r))try{let o=JSON.parse(me.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=Ee.join(t,i);if(!me.existsSync(r))continue;let s=me.readFileSync(r,"utf8").match(new RegExp(`${n}\\s*:\\s*['"]([^'"]+)['"]`));if(s?.[1])return s[1]}}function so(e,t,n){return t||nt(e,n)||oo("ios")||xt("ios")||void 0}function ao(e,t,n){return t||bt(e,n)||oo("android")||xt("android")||void 0}function Ac(e,t){let n=me.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
686
+ `))}}await hn(["-exportArchive","-archivePath",D,"-exportPath",ce,"-exportOptionsPlist",K],d,m,o,s),l&&await l("validate");let et=qe(ce,[".ipa"]);for(let Re of et)try{re(`unzip -t "${Re}"`,{stdio:"pipe"});let _e=zr(Re,v||void 0);o&&o(`[IPA VALID] ${y.basename(Re)} \u2014 archive integrity OK
687
+ `),o&&o(`[IPA VALID] CFBundleVersion ${_e}
688
+ `)}catch(_e){let It=`IPA validation failed for ${y.basename(Re)}: ${_e.message||"archive may be corrupt"}`;throw o&&o(`[IPA CORRUPT] ${It}
689
+ `),new Error(It)}return et}}finally{_?.restore(),S?.restore()}},Nt=(e,t)=>{try{let n=y.join(process.cwd(),A.configFileName),i={};if(I.existsSync(n)){if(i=JSON.parse(I.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=ze(process.cwd(),t??i.appDirectory).appRoot;if(e==="android"){let s=["android/app/build.gradle","android/app/build.gradle.kts","app/build.gradle","app/build.gradle.kts","build.gradle","build.gradle.kts"];for(let l of s){let c=y.join(o,l);if(I.existsSync(c)){let u=I.readFileSync(c,"utf-8").match(/applicationId\s*(?:=\s*)?['"]([^'"]+)['"]/);if(u)return u[1]}}let a=["app.json","app.config.json","app.config.js","app.config.ts"];for(let l of a){let c=y.join(o,l);if(!I.existsSync(c))continue;let u=I.readFileSync(c,"utf-8").match(/(?:["']package["']|\bpackage)\s*[:=]\s*["']([^"']+)["']/);if(u?.[1])return u[1]}}else{let s=y.join(o,"ios"),a=I.existsSync(s)?s:o,l=qe(a,["Info.plist"]).filter(u=>!u.includes("/Pods/")&&!u.includes("/build/")&&!u.includes("/DerivedData/"));l.sort((u,p)=>p.split("/").length-u.split("/").length);for(let u of l){let f=I.readFileSync(u,"utf-8").match(/<key>CFBundleIdentifier<\/key>\s*<string>([^<]+)<\/string>/);if(f&&!f[1].includes("$"))return f[1]}let c=qe(a,[".xcodeproj"]);if(c.length>0){let u=y.join(c[0],"project.pbxproj");if(I.existsSync(u)){let f=I.readFileSync(u,"utf-8").match(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";\s]+)"?;/);if(f)return f[1]}}let d=["app.json","app.config.json","app.config.js","app.config.ts"];for(let u of d){let p=y.join(o,u);if(I.existsSync(p)){let m=I.readFileSync(p,"utf-8").match(/"bundleIdentifier":\s*"([^"]+)"/);if(m)return m[1]}}}}catch{return null}return null},oc=()=>{try{return re("emulator -version",{stdio:"ignore"}),"emulator"}catch{let t=ye.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(I.existsSync(i))return i}return"emulator"},sc=async(e,t)=>{let n=yn();try{if(re("adb devices").toString().split(`
690
+ `).slice(1).map(s=>s.trim()).filter(s=>s.length>0&&!s.startsWith("*")).map(s=>s.split(" ")[0]).length===0){E.warn(w.yellow("No Android devices or emulators found."));let s=oc(),a=[];try{a=re(`${s} -list-avds`).toString().split(`
691
+ `).filter(l=>l.trim().length>0)}catch{}if(a.length>0){let l=await pi({message:"Select an emulator to launch:",options:a.map(u=>({value:u,label:u}))});if(In(l))return;n.start(`Launching emulator ${l}...`),jr(s,["-avd",l],{detached:!0,stdio:"ignore"}).unref();let c=0,d=!1;for(;c<60;){try{if(re("adb shell getprop sys.boot_completed",{stdio:"pipe"}).toString().trim()==="1"){d=!0;break}}catch{}await new Promise(u=>setTimeout(u,2e3)),c++}if(!d)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=Nt("android");if(o){E.info(w.blue(`\u{1F680} Launching ${o}...`));try{re(`adb shell dumpsys package ${o}`).toString().split(`
692
+ `).find(l=>l.includes("android.intent.action.MAIN")&&l.includes("android.intent.category.LAUNCHER"))?re(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"}):re(`adb shell monkey -p ${o} -c android.intent.category.LAUNCHER 1`,{stdio:"ignore"})}catch{E.warn("Could not auto-launch app. You may need to open it manually.")}}}catch(i){n.stop("Installation failed."),E.error(w.red(`Failed to install APK: ${i.message}`))}},ac=async(e,t,n)=>{let i=yn();try{if(!re("xcrun simctl list devices booted").toString().includes("(Booted)")){E.warn(w.yellow("No iOS Simulator is currently booted."));let o=re("xcrun simctl list devices --json").toString(),s=JSON.parse(o).devices,a=[];Object.keys(s).forEach(u=>{s[u].forEach(p=>{p.isAvailable&&a.push({...p,runtime:u})})});let l=await pi({message:"Select a simulator to launch:",options:a.map(u=>({value:u.udid,label:`${u.name} (${u.runtime.split(".").pop()})`}))});if(In(l))return;i.start(`Booting ${l}...`),re(`xcrun simctl boot ${l}`),re(`open -a Simulator --args -CurrentDeviceUDID ${l}`);let c=0,d=!1;for(;c<30;){try{if(re("xcrun simctl list devices booted").toString().includes(l)){d=!0;break}}catch{}await new Promise(u=>setTimeout(u,2e3)),c++}if(!d)throw i.stop("Simulator boot timed out."),new Error("Simulator boot timed out.");i.stop("Simulator booted.")}i.start("Installing on iOS Simulator..."),Jr(e),Yr(e),await je("xcrun",["simctl","install","booted",e],process.cwd(),{},n),i.stop("Installation complete."),E.info(w.blue(`\u{1F680} Launching ${t}...`)),await je("xcrun",["simctl","launch","booted",t],process.cwd(),{},n)}catch(r){i.stop("Installation failed."),E.error(w.red(`Failed to install on Simulator: ${r.message}`))}},cc=async(e,t,n)=>{let i=yn();i.start("Scanning for connected iOS devices...");try{let r=re("xcrun devicectl list devices --json-output -").toString(),s=(JSON.parse(r).result?.devices||[]).filter(l=>l.connectionProperties?.transportType==="wired"||l.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 l=await pi({message:"Select a device to install on:",options:s.map(c=>({value:c.identifier,label:`${c.deviceProperties?.name||c.name||c.model?.name} (${c.model?.name||"iPhone"}) - ${c.identifier}`}))});if(In(l))return;a=l,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."),E.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."),E.error(w.red(`Failed to install on device: ${r.message}`)),E.info(w.dim('Make sure your device is unlocked and "Developer Mode" is enabled in Settings -> Privacy & Security.'))}};import{createRequire as lc}from"module";var dc=lc(import.meta.url),uc=dc("../package.json"),hi=String(uc.version||"0.0.0");var io="https://mach-api.securejs.in",pc=["google-services.json","android/app/google-services.json"],Qr="0.1.4",ro="0.1.0";function fc(){return Ee.join(process.cwd(),A.configFileName)}function bn(){let e=Oi();if(!e?.projectId)throw new Error(`No linked MACH project. Run \`${A.nameLower} link\` first.`);return e}function oo(e){me.writeFileSync(fc(),`${JSON.stringify(e,null,2)}
693
+ `)}function mc(){return yi(Ee.join(process.cwd(),"package.json"))}function yi(e){if(!me.existsSync(e))return null;try{return JSON.parse(me.readFileSync(e,"utf8"))}catch{return null}}function gc(e){let t=mc();return!!(t?.dependencies?.[e]||t?.devDependencies?.[e])}function Ii(e){let t=process.cwd(),n=yi(Ee.join(t,"node_modules",...e.split("/"),"package.json"));if(typeof n?.version=="string")return n.version;let r=yi(Ee.join(t,"package-lock.json"))?.packages?.[`node_modules/${e}`]?.version;return typeof r=="string"?r:void 0}function hc(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 qr(e,t){let n=Ii(e);return!gc(e)||!n||hc(n,t)<0}function yc(e,t=!1){let n=process.cwd();return me.existsSync(Ee.join(n,"pnpm-lock.yaml"))?{command:"pnpm",args:["add",...t?["-D"]:[],e],label:`pnpm add ${t?"-D ":""}${e}`}:me.existsSync(Ee.join(n,"yarn.lock"))?{command:"yarn",args:["add",...t?["-D"]:[],e],label:`yarn add ${t?"-D ":""}${e}`}:me.existsSync(Ee.join(n,"bun.lock"))||me.existsSync(Ee.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 eo(e,t=!1){let n=yc(e,t);console.log(ae.dim(`Installing dependency: ${n.label}`));let i=no(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 Ic(e,t,n=process.cwd()){let i=[];if(t)return i.push("Dependency installation skipped."),i;if(e==="flutter"){let r=Ee.join(n,"pubspec.yaml");if(me.existsSync(r)&&/^\s{2}mach_push_flutter\s*:/m.test(me.readFileSync(r,"utf8")))return i.push("mach_push_flutter is already present in pubspec.yaml."),i;let s=`mach_push_flutter:^${ro}`;console.log(ae.dim(`Installing dependency: flutter pub add ${s}`));let a=no("flutter",["pub","add",s],{cwd:n,stdio:"inherit",timeout:12e4,env:{...process.env}});if(a.error||a.status!==0)throw new Error(`flutter pub add ${s} failed${a.error?`: ${a.error.message}`:` with code ${a.status}`}. No application files were wired. Use --skip-install only when the dependency is already managed by your workspace.`);return i.push(`Installed with flutter pub add ${s}.`),i}if(qr("@radhya/mach-push-react-native",Qr)){let r=eo(`@radhya/mach-push-react-native@${Qr}`);if(!r.ok)throw new Error(`${r.note} No application files were wired.`);i.push(r.note)}else i.push(`@radhya/mach-push-react-native is already current (${Ii("@radhya/mach-push-react-native")}).`);if(e==="expo")if(qr("@radhya/mach",hi)){let r=eo(`@radhya/mach@${hi}`,!0);if(!r.ok)throw new Error(`${r.note} No Expo configuration was changed.`);i.push(r.note)}else i.push(`@radhya/mach is already current for the Expo config (${Ii("@radhya/mach")}).`);return i}function Ac(e,t,n=process.cwd()){return e||t||["google-services.json","android/app/google-services.json"].find(i=>me.existsSync(Ee.join(n,i)))}function so(e){let t={enabled:!0};return e.appId&&e.publishableKey&&(t.appId=e.appId,t.publishableKey=e.publishableKey),e.apiUrl&&e.apiUrl!==io&&(t.apiUrl=e.apiUrl),e.environment&&e.environment!=="production"&&(t.environment=e.environment),e.googleServicesFile&&!pc.includes(e.googleServicesFile)&&(t.googleServicesFile=e.googleServicesFile),t}function bc(e){return e==="development"?"development":"production"}function ao(e){let t=process.cwd(),n=e==="ios"?"bundleIdentifier":"package";for(let i of["app.json","app.config.json"]){let r=Ee.join(t,i);if(me.existsSync(r))try{let o=JSON.parse(me.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=Ee.join(t,i);if(!me.existsSync(r))continue;let s=me.readFileSync(r,"utf8").match(new RegExp(`${n}\\s*:\\s*['"]([^'"]+)['"]`));if(s?.[1])return s[1]}}function co(e,t,n){return t||nt(e,n)||ao("ios")||Nt("ios")||void 0}function lo(e,t,n){return t||bt(e,n)||ao("android")||Nt("android")||void 0}function Sc(e,t){let n=me.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
609
694
  `)?`\r
610
695
  `:`
611
- `,o=i[1]||"",s=i[2]||"",a=s.match(/\r?\n([ \t]+)\S/)?.[1]||`${o} `,l=s.trim().length===0?`${r}${a}'${t}',${r}${o}`:`${r}${a}'${t}',${s}`,c=i[0].indexOf("["),d=`${i[0].slice(0,c+1)}${l}]`;return me.writeFileSync(e,`${n.slice(0,i.index)}${d}${n.slice(i.index+i[0].length)}`),"inserted"}function co(){let e="@radhya/mach/expo-plugin",t=["app.config.ts","app.config.js"].find(l=>me.existsSync(Ee.join(process.cwd(),l)));if(t){let l=Ac(Ee.join(process.cwd(),t),e);return l==="inserted"?`${t} now includes ${e}.`:l==="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(l=>me.existsSync(Ee.join(process.cwd(),l)));if(!n)return`Add "${e}" to the Expo plugins array.`;let i=Ee.join(process.cwd(),n),r=JSON.parse(me.readFileSync(i,"utf8")),o=r.expo&&typeof r.expo=="object"?r.expo:r,s=Array.isArray(o.plugins)?o.plugins:[];return s.some(l=>(Array.isArray(l)?l[0]:l)===e)?`${n} already includes ${e}.`:(o.plugins=[...s,e],me.writeFileSync(i,`${JSON.stringify(r,null,2)}
612
- `),`${n} now includes ${e}.`)}async function lo(e){let t=bn(),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 U.get(`/projects/${t.projectId}/push/overview?days=1`),s=(r?.apps||[]).filter(a=>a.status!=="disabled").sort((a,l)=>(l.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 qr(e){let t=Ee.resolve(e);if(!me.existsSync(t))throw new Error(`File not found: ${t}`);return t}function Yt(e){let t=e?.response?.data?.message||e?.message||"Unknown error";console.error(ae.red(t)),process.exitCode=1}async function wp(e){let t=An();try{let n=bn(),i=_n(n);if(e.profile&&!Fe(n,e.profile))throw new Error(`Build profile "${e.profile}" was not found in ${A.configFileName}.`);let r=so(n,e.iosBundle,e.profile),o=ao(n,e.androidPackage,e.profile);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 U.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});let s=e.environment||"production";n.push=ro({environment:s,googleServicesFile:e.googleServicesFile}),io(n);let a=n.framework==="expo"?co():void 0;t.stop(ae.green("MACH Push app created.")),console.log(["",`${ae.bold("Client config:")} ${A.configFileName} \u2192 push`,"","Install the mobile SDK:",i==="flutter"?` flutter pub add mach_push_flutter:^${no}`:" 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(`
613
- `))}catch(n){t.stop(ae.red("MACH Push setup failed.")),Yt(n)}}async function Cp(e){let t=An();try{let n=bn(),i=_n(n),r=i==="flutter"?ze(process.cwd(),n.appDirectory,{requireAppDirectory:!0}).appRoot:process.cwd(),o=e.profile?Fe(n,e.profile):void 0;if(e.profile&&!o)throw new Error(`Build profile "${e.profile}" was not found in ${A.configFileName}.`);let s=so(n,e.iosBundle,e.profile),a=ao(n,e.androidPackage,e.profile);if(!s&&!a)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);let l;t.start("Checking the MACH Push app...");let u=((await U.get(`/projects/${n.projectId}/push/overview?days=1`)).data?.apps||[]).filter(S=>S.status!=="disabled").sort((S,$)=>($.updatedAt||0)-(S.updatedAt||0)).find(S=>(!s||S.iosBundleId===s)&&(!a||S.androidPackageName===a));if(u)l=u.appId,t.stop(ae.green("Existing MACH Push app linked."));else{let{data:S}=await U.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:s,androidPackageName:a});l=S.app.appId,t.stop(ae.green("MACH Push app created."))}if(!l)throw new Error("MACH Push did not return a usable application.");let p=n.push,f=e.environment||p?.environment||"production",m=p?.apiUrl||to,E=yc(e.googleServicesFile,p?.googleServicesFile,r);n.push=ro({apiUrl:m,environment:f,googleServicesFile:E}),io(n);let v=hc(i,!!e.skipInstall,r),P=i==="expo"?co():void 0;if(P?.startsWith('Add "'))throw new Error(P);let F={projectId:n.projectId,apiUrl:m,environment:f},C=i==="flutter"?Array.from(new Set((o?[o.flutter?.target,o.ios?.flutter?.target,o.android?.flutter?.target]:Object.values(n.build||{}).flatMap(S=>[S?.flutter?.target,S?.ios?.flutter?.target,S?.android?.flutter?.target])).filter(S=>!!S))):[],N=C.find(S=>!me.existsSync(Ee.resolve(r,S)));if(N)throw new Error(`Configured Flutter entrypoint ${N} does not exist.`);let b=i==="flutter"?(C.length?C:[void 0]).map(S=>Wi(r,F,S)):[],k=i==="flutter"?{written:Array.from(new Set(b.flatMap(S=>S.written))),notes:Array.from(new Set(b.flatMap(S=>S.notes))),editableFile:b.find(S=>S.editableFile)?.editableFile,generatedFile:b.find(S=>S.generatedFile)?.generatedFile,entryFile:b.find(S=>S.entryFile)?.entryFile}:Ui(process.cwd(),i,F);if(!k.entryFile)throw new Error(k.notes[0]||"MACH could not locate the application entry point.");let _=i==="expo"?{written:[],notes:[]}:Zi(r,{iosBundleId:s,iosEnvironment:Ic(f),googleServicesFile:E});console.log(["",ae.green.bold("MACH Push basic setup is ready."),`${ae.bold("Framework:")} ${i}`,`${ae.bold("Client config:")} ${A.configFileName} \u2192 push`,`${ae.bold("Automatic startup:")} ${k.entryFile||"manual entry import required"}`,`${ae.bold("Customize callbacks:")} ${k.editableFile||"see the setup notes below"}`,"",...v.map(S=>`\u2022 ${S}`),...P?[`\u2022 ${P}`]:[],...k.notes.map(S=>`\u2022 ${S}`),..._.notes.map(S=>`\u2022 ${S}`),...[...k.written,..._.written].map(S=>`\u2022 Updated ${S}.`),"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications, then create one new native build.`].join(`
614
- `))}catch(n){t.stop(ae.red("MACH Push setup failed.")),Yt(n)}}async function Sn(e,t){let n=An();try{let{config:i,appId:r,environment:o}=await lo(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?me.readFileSync(qr(t.file),"utf8"):"");if(!a)throw new Error("APNs requires --file or a generated private key.");let l=t.bundleId||nt(i);if(!l)throw new Error("APNs requires --bundle-id.");s={environment:o,teamId:t.teamId,keyId:t.keyId,bundleId:l,privateKey:a}}else{let a=t.serviceAccount||(t.file?JSON.parse(me.readFileSync(qr(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 U.put(`/projects/${i.projectId}/push/apps/${r}/credentials/${e}`,s),n.stop(ae.green(`${e.toUpperCase()} is ready.`))}catch(i){n.stop(ae.red(`${e.toUpperCase()} setup failed.`)),Yt(i)}}async function vp(e){let t=An(),n=!1;try{let{config:i,appId:r,environment:o}=await lo(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 u=JSON.parse(e.data);if(!u||typeof u!="object"||Array.isArray(u))throw new Error("--data must be a JSON object.");a=Object.fromEntries(Object.entries(u).map(([p,f])=>[p,String(f)]))}let l=e.badge===void 0?void 0:Number(e.badge),c=e.ttl===void 0?void 0:Number(e.ttl);t.start("Queueing notification..."),n=!0;let{data:d}=await U.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:l,ttlSeconds:c,collapseKey:e.collapseKey,androidChannelId:e.androidChannelId}});t.stop(ae.green(`Notification queued: ${d.requestId}`))}catch(i){n?t.stop(ae.red("Notification was not queued.")):console.error(ae.red("Notification was not queued.")),Yt(i)}}async function Ep(e){try{let t=bn(),n=Math.min(Math.max(Number(e.days||30),1),90),{data:i}=await U.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([`${ae.bold("Active devices:")} ${i.activeDevices}`,`${ae.bold("Queued requests:")} ${r.queuedRequests}`,`${ae.bold("Requested:")} ${r.requested}`,`${ae.bold("Provider accepted:")} ${r.accepted}`,`${ae.bold("Failed:")} ${r.failed}`,`${ae.bold("Retried:")} ${r.retried}`,`${ae.bold("Invalid devices:")} ${r.invalidDevices}`,`${ae.bold("Acceptance:")} ${o}`].join(`
615
- `))}catch(t){Yt(t)}}import wo from"axios";import h from"chalk";import{execSync as je,spawnSync as Pe}from"child_process";import{createRequire as vc}from"module";import Cn from"crypto";import B from"fs";import Q from"path";import yt from"os";import Ec from"adm-zip";var Ze=e=>typeof e!="string"?void 0:e.trim()||void 0,Ai=e=>(Ze(e?.teamId)||Ze(e?.developerTeamId)||Ze(e?.issuerId)||Ze(e?.meta?.teamId)||Ze(e?.meta?.developerTeamId)||Ze(e?.meta?.issuerId))?.toUpperCase(),bi=e=>Ze(e?.keyId)||Ze(e?.meta?.keyId),bc=(e,t)=>{let n=Ze(e)?.toLowerCase().replace(/_/g,"-");return t==="development"?n==="development"||n==="dev":t==="adhoc"?["adhoc","ad-hoc","internal","staging","stage","preview"].includes(n||""):["store","app-store","appstore","production","prod"].includes(n||"")},uo=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"}},Si=(e,t,n)=>e?.type!=="ios_cert"||e?.platform&&e.platform!=="ios"||!Ze(e?.s3Key)||!bc(e?.distributionType,n)?!1:Ai(e)===t.trim().toUpperCase();var po=(e,t,n,i,r,o)=>{let s=["sigh","renew"];return e==="development"&&s.push("--development"),e==="adhoc"&&s.push("--adhoc"),s.push("--app_identifier",t,"--provisioning_name",n,"--cert_id",i,"--force","--output_path",r,"--filename",o),s};var Pc=vc(import.meta.url);wo.defaults.proxy=!1;function vn(e,t){if(!B.existsSync(e))return;let n=B.readdirSync(e);for(let i of n){let r=Q.join(e,i);if(B.statSync(r).isDirectory()){let s=vn(r,t);if(s)return s}else if(t.test(i))return r}}var Nt=e=>String(e||"").trim().toLowerCase().replace(/_/g,"-"),fo=e=>String(e||"unknown").trim().replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown",Rc=(e,t)=>`ios-certificates/${fo(e)}/${fo(t)}/`;function xc(e){return"'"+e.replace(/'/g,"'\\''")+"'"}function kt(...e){let t=e.join(`
696
+ `,o=i[1]||"",s=i[2]||"",a=s.match(/\r?\n([ \t]+)\S/)?.[1]||`${o} `,l=s.trim().length===0?`${r}${a}'${t}',${r}${o}`:`${r}${a}'${t}',${s}`,c=i[0].indexOf("["),d=`${i[0].slice(0,c+1)}${l}]`;return me.writeFileSync(e,`${n.slice(0,i.index)}${d}${n.slice(i.index+i[0].length)}`),"inserted"}function uo(){let e="@radhya/mach/expo-plugin",t=["app.config.ts","app.config.js"].find(l=>me.existsSync(Ee.join(process.cwd(),l)));if(t){let l=Sc(Ee.join(process.cwd(),t),e);return l==="inserted"?`${t} now includes ${e}.`:l==="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(l=>me.existsSync(Ee.join(process.cwd(),l)));if(!n)return`Add "${e}" to the Expo plugins array.`;let i=Ee.join(process.cwd(),n),r=JSON.parse(me.readFileSync(i,"utf8")),o=r.expo&&typeof r.expo=="object"?r.expo:r,s=Array.isArray(o.plugins)?o.plugins:[];return s.some(l=>(Array.isArray(l)?l[0]:l)===e)?`${n} already includes ${e}.`:(o.plugins=[...s,e],me.writeFileSync(i,`${JSON.stringify(r,null,2)}
697
+ `),`${n} now includes ${e}.`)}async function po(e){let t=bn(),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 U.get(`/projects/${t.projectId}/push/overview?days=1`),s=(r?.apps||[]).filter(a=>a.status!=="disabled").sort((a,l)=>(l.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 to(e){let t=Ee.resolve(e);if(!me.existsSync(t))throw new Error(`File not found: ${t}`);return t}function Yt(e){let t=e?.response?.data?.message||e?.message||"Unknown error";console.error(ae.red(t)),process.exitCode=1}async function Rp(e){let t=An();try{let n=bn(),i=_n(n);if(e.profile&&!Te(n,e.profile))throw new Error(`Build profile "${e.profile}" was not found in ${A.configFileName}.`);let r=co(n,e.iosBundle,e.profile),o=lo(n,e.androidPackage,e.profile);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 U.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:r,androidPackageName:o});let s=e.environment||"production";n.push=so({environment:s,googleServicesFile:e.googleServicesFile}),oo(n);let a=n.framework==="expo"?uo():void 0;t.stop(ae.green("MACH Push app created.")),console.log(["",`${ae.bold("Client config:")} ${A.configFileName} \u2192 push`,"","Install the mobile SDK:",i==="flutter"?` flutter pub add mach_push_flutter:^${ro}`:" 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(`
698
+ `))}catch(n){t.stop(ae.red("MACH Push setup failed.")),Yt(n)}}async function Np(e){let t=An();try{let n=bn(),i=_n(n),r=i==="flutter"?ze(process.cwd(),n.appDirectory,{requireAppDirectory:!0}).appRoot:process.cwd(),o=e.profile?Te(n,e.profile):void 0;if(e.profile&&!o)throw new Error(`Build profile "${e.profile}" was not found in ${A.configFileName}.`);let s=co(n,e.iosBundle,e.profile),a=lo(n,e.androidPackage,e.profile);if(!s&&!a)throw new Error(`Add ios.bundleIdentifier or android.package to ${A.configFileName}, or pass --ios-bundle/--android-package.`);let l;t.start("Checking the MACH Push app...");let u=((await U.get(`/projects/${n.projectId}/push/overview?days=1`)).data?.apps||[]).filter(b=>b.status!=="disabled").sort((b,$)=>($.updatedAt||0)-(b.updatedAt||0)).find(b=>(!s||b.iosBundleId===s)&&(!a||b.androidPackageName===a));if(u)l=u.appId,t.stop(ae.green("Existing MACH Push app linked."));else{let{data:b}=await U.post(`/projects/${n.projectId}/push/apps`,{name:e.name||n.name||"Mobile app",iosBundleId:s,androidPackageName:a});l=b.app.appId,t.stop(ae.green("MACH Push app created."))}if(!l)throw new Error("MACH Push did not return a usable application.");let p=n.push,f=e.environment||p?.environment||"production",m=p?.apiUrl||io,P=Ac(e.googleServicesFile,p?.googleServicesFile,r);n.push=so({apiUrl:m,environment:f,googleServicesFile:P}),oo(n);let v=Ic(i,!!e.skipInstall,r),R=i==="expo"?uo():void 0;if(R?.startsWith('Add "'))throw new Error(R);let O={projectId:n.projectId,apiUrl:m,environment:f},C=i==="flutter"?Array.from(new Set((o?[o.flutter?.target,o.ios?.flutter?.target,o.android?.flutter?.target]:Object.values(n.build||{}).flatMap(b=>[b?.flutter?.target,b?.ios?.flutter?.target,b?.android?.flutter?.target])).filter(b=>!!b))):[],x=C.find(b=>!me.existsSync(Ee.resolve(r,b)));if(x)throw new Error(`Configured Flutter entrypoint ${x} does not exist.`);let S=i==="flutter"?(C.length?C:[void 0]).map(b=>Wi(r,O,b)):[],_=i==="flutter"?{written:Array.from(new Set(S.flatMap(b=>b.written))),notes:Array.from(new Set(S.flatMap(b=>b.notes))),editableFile:S.find(b=>b.editableFile)?.editableFile,generatedFile:S.find(b=>b.generatedFile)?.generatedFile,entryFile:S.find(b=>b.entryFile)?.entryFile}:Ui(process.cwd(),i,O);if(!_.entryFile)throw new Error(_.notes[0]||"MACH could not locate the application entry point.");let k=i==="expo"?{written:[],notes:[]}:Zi(r,{iosBundleId:s,iosEnvironment:bc(f),googleServicesFile:P});console.log(["",ae.green.bold("MACH Push basic setup is ready."),`${ae.bold("Framework:")} ${i}`,`${ae.bold("Client config:")} ${A.configFileName} \u2192 push`,`${ae.bold("Automatic startup:")} ${_.entryFile||"manual entry import required"}`,`${ae.bold("Customize callbacks:")} ${_.editableFile||"see the setup notes below"}`,"",...v.map(b=>`\u2022 ${b}`),...R?[`\u2022 ${R}`]:[],..._.notes.map(b=>`\u2022 ${b}`),...k.notes.map(b=>`\u2022 ${b}`),...[..._.written,...k.written].map(b=>`\u2022 Updated ${b}.`),"",`Next: run \`${A.nameLower} credentials\` and choose Push Notifications, then create one new native build.`].join(`
699
+ `))}catch(n){t.stop(ae.red("MACH Push setup failed.")),Yt(n)}}async function Sn(e,t){let n=An();try{let{config:i,appId:r,environment:o}=await po(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?me.readFileSync(to(t.file),"utf8"):"");if(!a)throw new Error("APNs requires --file or a generated private key.");let l=t.bundleId||nt(i);if(!l)throw new Error("APNs requires --bundle-id.");s={environment:o,teamId:t.teamId,keyId:t.keyId,bundleId:l,privateKey:a}}else{let a=t.serviceAccount||(t.file?JSON.parse(me.readFileSync(to(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 U.put(`/projects/${i.projectId}/push/apps/${r}/credentials/${e}`,s),n.stop(ae.green(`${e.toUpperCase()} is ready.`))}catch(i){n.stop(ae.red(`${e.toUpperCase()} setup failed.`)),Yt(i)}}async function xp(e){let t=An(),n=!1;try{let{config:i,appId:r,environment:o}=await po(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 u=JSON.parse(e.data);if(!u||typeof u!="object"||Array.isArray(u))throw new Error("--data must be a JSON object.");a=Object.fromEntries(Object.entries(u).map(([p,f])=>[p,String(f)]))}let l=e.badge===void 0?void 0:Number(e.badge),c=e.ttl===void 0?void 0:Number(e.ttl);t.start("Queueing notification..."),n=!0;let{data:d}=await U.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:l,ttlSeconds:c,collapseKey:e.collapseKey,androidChannelId:e.androidChannelId}});t.stop(ae.green(`Notification queued: ${d.requestId}`))}catch(i){n?t.stop(ae.red("Notification was not queued.")):console.error(ae.red("Notification was not queued.")),Yt(i)}}async function kp(e){try{let t=bn(),n=Math.min(Math.max(Number(e.days||30),1),90),{data:i}=await U.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([`${ae.bold("Active devices:")} ${i.activeDevices}`,`${ae.bold("Queued requests:")} ${r.queuedRequests}`,`${ae.bold("Requested:")} ${r.requested}`,`${ae.bold("Provider accepted:")} ${r.accepted}`,`${ae.bold("Failed:")} ${r.failed}`,`${ae.bold("Retried:")} ${r.retried}`,`${ae.bold("Invalid devices:")} ${r.invalidDevices}`,`${ae.bold("Acceptance:")} ${o}`].join(`
700
+ `))}catch(t){Yt(t)}}import vo from"axios";import h from"chalk";import{execSync as Le,spawnSync as Pe}from"child_process";import{createRequire as Pc}from"module";import wn from"crypto";import V from"fs";import Q from"path";import yt from"os";import Rc from"adm-zip";var Ze=e=>typeof e!="string"?void 0:e.trim()||void 0,Ai=e=>(Ze(e?.teamId)||Ze(e?.developerTeamId)||Ze(e?.issuerId)||Ze(e?.meta?.teamId)||Ze(e?.meta?.developerTeamId)||Ze(e?.meta?.issuerId))?.toUpperCase(),bi=e=>Ze(e?.keyId)||Ze(e?.meta?.keyId),Cc=(e,t)=>{let n=Ze(e)?.toLowerCase().replace(/_/g,"-");return t==="development"?n==="development"||n==="dev":t==="adhoc"?["adhoc","ad-hoc","internal","staging","stage","preview"].includes(n||""):["store","app-store","appstore","production","prod"].includes(n||"")},fo=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"}},Si=(e,t,n)=>e?.type!=="ios_cert"||e?.platform&&e.platform!=="ios"||!Ze(e?.s3Key)||!Cc(e?.distributionType,n)?!1:Ai(e)===t.trim().toUpperCase();var mo=(e,t,n,i,r,o)=>{let s=["sigh","renew"];return e==="development"&&s.push("--development"),e==="adhoc"&&s.push("--adhoc"),s.push("--app_identifier",t,"--provisioning_name",n,"--cert_id",i,"--force","--output_path",r,"--filename",o),s};var Nc=Pc(import.meta.url);vo.defaults.proxy=!1;function vn(e,t){if(!V.existsSync(e))return;let n=V.readdirSync(e);for(let i of n){let r=Q.join(e,i);if(V.statSync(r).isDirectory()){let s=vn(r,t);if(s)return s}else if(t.test(i))return r}}var xt=e=>String(e||"").trim().toLowerCase().replace(/_/g,"-"),go=e=>String(e||"unknown").trim().replace(/[^a-zA-Z0-9._-]/g,"_")||"unknown",xc=(e,t)=>`ios-certificates/${go(e)}/${go(t)}/`;function kc(e){return"'"+e.replace(/'/g,"'\\''")+"'"}function kt(...e){let t=e.join(`
616
701
  `).split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return t.length>0?t.slice(-8).join(`
617
- `):void 0}function Nc(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 kc(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 _c(e){let t=e?.match(/ruby\s+(\d+)\.(\d+)/);return t?{major:Number(t[1]),minor:Number(t[2])}:null}function $c(e,t,n){let i=_c(e);return i?i.major!==t?i.major<t:i.minor<n:!1}function wi(e){let t=process.env.HOME||yt.homedir(),n=process.env.FASTLANE_GEM_HOME||Q.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",Q.join(n,"bin/fastlane"),"fastlane"].filter(Boolean);for(let r of i){if(r.includes("/")&&!B.existsSync(r))continue;let o=Pe(r,["--version"],{env:e,stdio:"ignore"});if(!o.error&&o.status===0)return{command:r,shellCommand:xc(r),env:e}}return null}function Tc(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:kt(t.stdout,t.stderr)||"RubyGems is not available."};let n=Nc("ruby",["-v"],e);if($c(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(`
618
- `)};let i=process.env.HOME||yt.homedir(),r=process.env.FASTLANE_GEM_HOME||Q.join(i,".local/share/fastlane/3.4.0"),o=Q.join(r,"bin");B.mkdirSync(o,{recursive:!0}),g.info(h.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=kt(s.stdout,s.stderr);return g.warn(h.yellow("Automatic fastlane install failed.")),a&&g.warn(h.dim(a)),{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,a].filter(Boolean).join(`
619
- `)||void 0}}return g.success(h.green("\u2713 fastlane installed into the local Mach cache.")),{ok:!0}}function Fc(){return!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY}function Oc(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."};g.info(h.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."}:(g.success(h.green("\u2713 fastlane installed with Homebrew.")),{ok:!0})}async function Dc(e){if(!Fc())return!1;g.warn(h.yellow("fastlane is required for iOS certificate/profile sync, but it was not found.")),e&&g.info(h.dim(e));let t=await Pi({message:"Install fastlane now with Homebrew?",initialValue:!0});return L(t)?(ee("Operation cancelled"),!1):!!t}async function Mc(){let e=St(),t=wi(e);if(t)return t;let n=Tc(e);e=St();let i=wi(e);if(i)return i;if(await Dc(n.detail)){let r=Oc(e);e=St();let o=wi(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:
702
+ `):void 0}function _c(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 $c(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 Oc(e){let t=e?.match(/ruby\s+(\d+)\.(\d+)/);return t?{major:Number(t[1]),minor:Number(t[2])}:null}function Tc(e,t,n){let i=Oc(e);return i?i.major!==t?i.major<t:i.minor<n:!1}function Ci(e){let t=process.env.HOME||yt.homedir(),n=process.env.FASTLANE_GEM_HOME||Q.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",Q.join(n,"bin/fastlane"),"fastlane"].filter(Boolean);for(let r of i){if(r.includes("/")&&!V.existsSync(r))continue;let o=Pe(r,["--version"],{env:e,stdio:"ignore"});if(!o.error&&o.status===0)return{command:r,shellCommand:kc(r),env:e}}return null}function Fc(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:kt(t.stdout,t.stderr)||"RubyGems is not available."};let n=_c("ruby",["-v"],e);if(Tc(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(`
703
+ `)};let i=process.env.HOME||yt.homedir(),r=process.env.FASTLANE_GEM_HOME||Q.join(i,".local/share/fastlane/3.4.0"),o=Q.join(r,"bin");V.mkdirSync(o,{recursive:!0}),g.info(h.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=kt(s.stdout,s.stderr);return g.warn(h.yellow("Automatic fastlane install failed.")),a&&g.warn(h.dim(a)),{ok:!1,detail:[n?`Detected Ruby: ${n}`:void 0,a].filter(Boolean).join(`
704
+ `)||void 0}}return g.success(h.green("\u2713 fastlane installed into the local Mach cache.")),{ok:!0}}function Dc(){return!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY}function Mc(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."};g.info(h.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."}:(g.success(h.green("\u2713 fastlane installed with Homebrew.")),{ok:!0})}async function Vc(e){if(!Dc())return!1;g.warn(h.yellow("fastlane is required for iOS certificate/profile sync, but it was not found.")),e&&g.info(h.dim(e));let t=await Pi({message:"Install fastlane now with Homebrew?",initialValue:!0});return L(t)?(q("Operation cancelled"),!1):!!t}async function Bc(){let e=St(),t=Ci(e);if(t)return t;let n=Fc(e);e=St();let i=Ci(e);if(i)return i;if(await Vc(n.detail)){let r=Mc(e);e=St();let o=Ci(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:
620
705
  ${r.detail}`:void 0,"Try running manually: brew install fastlane","Then run mach credentials again."].filter(Boolean).join(`
621
706
  `))}throw new Error(["fastlane is required for iOS certificate/profile sync, but it was not found on PATH.",n.detail?`Automatic install failed:
622
707
  ${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(`
623
- `))}var le=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},Ri=e=>le(e.password)||le(e.p12Password)||le(e.certificatePassword)||le(e.meta?.password)||le(e.meta?.p12Password)||le(e.meta?.certificatePassword),Co=e=>le(e.keystorePassword)||le(e.storePassword)||le(e.meta?.keystorePassword)||le(e.meta?.storePassword),vo=e=>le(e.keyPassword)||le(e.meta?.keyPassword),Bc=e=>le(e.alias)||le(e.meta?.alias),En=e=>e.credentialId||e.id,Pn=e=>e.bundleId||e.bundleIdentifier||e.meta?.bundleId||e.meta?.bundleIdentifier,zt=e=>e.distributionType||e.meta?.distributionType,mo=e=>!!Ri(e)||!!Co(e)||!!vo(e),Eo=async(e,t,n)=>{if(!["ios_cert","android_keystore"].includes(n.type)||mo(n))return n;let i=Pn(n),r=zt(n);if(!i||!r)return n;try{let s=(await U.get("/credentials/resolve",{params:{projectId:e,platform:t,bundleId:i,distributionType:r}})).data.credentials||[],a=En(n),l=s.find(c=>{if(c.type!==n.type)return!1;let d=En(c);return a&&d===a?!0:Pn(c)===i&&Nt(zt(c))===Nt(r)&&mo(c)});return l?{...n,...l,meta:{...n.meta,...l.meta}}:n}catch{return n}},Vc=e=>{let t=Nt(e);return t==="store"||t==="app-store"?"PRODUCTION":["adhoc","ad-hoc","internal","staging","stage"].includes(t)?"STAGING":"DEVELOPMENT"},Po=(e,t)=>{let n=Ri(e);if(n)return n;let i=Vc(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=>le(t[o])).find(Boolean)||""},jc=(e,t)=>{let n=Nt(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(u=>`KEYSTORE_PASSWORD_${u}`),"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(u=>`KEYSTORE_ALIAS_${u}`),"ANDROID_KEY_ALIAS","KEYSTORE_ALIAS"],l=Co(e)||Ri(e)||o.map(u=>le(t[u])).find(Boolean)||"",c=vo(e)||s.map(u=>le(t[u])).find(Boolean)||l;return{alias:Bc(e)||a.map(u=>le(t[u])).find(Boolean)||"",keystorePassword:l,keyPassword:c}},go=(e,t,n)=>{let i=e.includes(".")?e.replace(/\.[^.]+$/i,".zip"):`${e}.zip`,r=Q.basename(e),o=new Ec;return o.addLocalFile(e,void 0,r),o.addFile(t,Buffer.from(n.endsWith(`
708
+ `))}var le=e=>{if(typeof e!="string")return;let t=e.trim();return t.length>0?t:void 0},Ri=e=>le(e.password)||le(e.p12Password)||le(e.certificatePassword)||le(e.meta?.password)||le(e.meta?.p12Password)||le(e.meta?.certificatePassword),Eo=e=>le(e.keystorePassword)||le(e.storePassword)||le(e.meta?.keystorePassword)||le(e.meta?.storePassword),Po=e=>le(e.keyPassword)||le(e.meta?.keyPassword),jc=e=>le(e.alias)||le(e.meta?.alias),En=e=>e.credentialId||e.id,Pn=e=>e.bundleId||e.bundleIdentifier||e.meta?.bundleId||e.meta?.bundleIdentifier,zt=e=>e.distributionType||e.meta?.distributionType,ho=e=>!!Ri(e)||!!Eo(e)||!!Po(e),Ro=async(e,t,n)=>{if(!["ios_cert","android_keystore"].includes(n.type)||ho(n))return n;let i=Pn(n),r=zt(n);if(!i||!r)return n;try{let s=(await U.get("/credentials/resolve",{params:{projectId:e,platform:t,bundleId:i,distributionType:r}})).data.credentials||[],a=En(n),l=s.find(c=>{if(c.type!==n.type)return!1;let d=En(c);return a&&d===a?!0:Pn(c)===i&&xt(zt(c))===xt(r)&&ho(c)});return l?{...n,...l,meta:{...n.meta,...l.meta}}:n}catch{return n}},Lc=e=>{let t=xt(e);return t==="store"||t==="app-store"?"PRODUCTION":["adhoc","ad-hoc","internal","staging","stage"].includes(t)?"STAGING":"DEVELOPMENT"},No=(e,t)=>{let n=Ri(e);if(n)return n;let i=Lc(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=>le(t[o])).find(Boolean)||""},Uc=(e,t)=>{let n=xt(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(u=>`KEYSTORE_PASSWORD_${u}`),"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(u=>`KEYSTORE_ALIAS_${u}`),"ANDROID_KEY_ALIAS","KEYSTORE_ALIAS"],l=Eo(e)||Ri(e)||o.map(u=>le(t[u])).find(Boolean)||"",c=Po(e)||s.map(u=>le(t[u])).find(Boolean)||l;return{alias:jc(e)||a.map(u=>le(t[u])).find(Boolean)||"",keystorePassword:l,keyPassword:c}},yo=(e,t,n)=>{let i=e.includes(".")?e.replace(/\.[^.]+$/i,".zip"):`${e}.zip`,r=Q.basename(e),o=new Rc;return o.addLocalFile(e,void 0,r),o.addFile(t,Buffer.from(n.endsWith(`
624
709
  `)?n:`${n}
625
- `,"utf8")),o.writeZip(i),i},ho=(e,t)=>{let n=Fe(e,t)||{},i=Nt(n.distribution),r=Nt(n.environment);return i==="store"||r==="production"||r==="store"?"store":"internal"},Lc=["development","preview","production"],Uc="U27F4V844T",Ci=null;function xn(){return Ci||(Ci=Pc("@expo/apple-utils")),Ci}function yo(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 Wc(e){let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr);process.stdout.write=(i,...r)=>t(yo(i),...r),process.stderr.write=(i,...r)=>n(yo(i),...r);try{return await e()}finally{process.stdout.write=t,process.stderr.write=n}}function Ro(e){return B.existsSync(Q.resolve(e))?void 0:"File not found"}function Gc(){try{let e=`./${A.configFileName}`;return B.existsSync(e)?JSON.parse(B.readFileSync(e,"utf-8")):{}}catch{return{}}}function Zc(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=Cn.randomBytes(2).toString("hex").toUpperCase(),s=` ${r}-${o}`;return`${`MACH Push ${n}`.slice(0,Math.max(1,50-s.length))}${s}`}async function Hc(e){let t=e.submit?.production?.ios?.appleId||e.submit?.preview?.ios?.appleId||e.submit?.development?.ios?.appleId,n=await Te({message:"Apple ID (for Apple Developer Portal):",initialValue:t,validate:i=>i.includes("@")?void 0:"Enter a valid Apple ID email"});return L(n)&&(ee("Operation cancelled"),process.exit(0)),n}async function Xc(e){let t=await ht({message:`Apple password for ${e} (used only for Apple login, not stored):`,validate:n=>n.trim()?void 0:"Password is required"});return L(t)&&(ee("Operation cancelled"),process.exit(0)),t}function Kc(e){return(Array.isArray(e?.services)?e.services:[]).some(n=>n?.id===Uc||/apple push notification|apns/i.test(String(n?.name||"")))}async function Jc(e){let{Keys:t}=xn(),n=ct();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(Kc);return n.stop(h.green(`Found ${o.length} APNs key${o.length===1?"":"s"}.`)),o}catch(i){throw n.stop(h.red("Could not fetch APNs keys from Apple.")),i}}async function Yc(e){let{Keys:t}=xn(),i=(await Jc(e)).filter(l=>l.canRevoke!==!1);if(i.length===0)return g.warn(h.yellow("No revokable APNs keys were found for this Apple team.")),!1;let r=await be({message:"Select an APNs key to revoke:",options:i.map(l=>({value:l.id,label:`${l.name||"Untitled APNs key"} (${l.id})`,hint:l.canDownload?"APNs key, private key may still be downloadable":"APNs key"}))});L(r)&&(ee("Operation cancelled"),process.exit(0));let o=i.find(l=>l.id===r);g.warn(h.yellow("Revoking this key can break push notifications for any service currently using it."));let s=await Pi({message:`Revoke "${o?.name||"Untitled APNs key"}" (${r})? This cannot be undone.`,initialValue:!1});if(L(s)&&(ee("Operation cancelled"),process.exit(0)),!s)return g.info(h.dim("APNs key was not revoked.")),!1;let a=ct();try{return a.start(`Revoking APNs key ${r}...`),await t.revokeKeyAsync(e,{id:r}),a.stop(h.green(`Revoked APNs key ${r}.`)),!0}catch(l){throw a.stop(h.red(`Could not revoke APNs key ${r}.`)),l}}async function zc(e,t){let{Keys:n}=xn(),i=0;for(;;){let r=t(),o=ct();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(h.green(`APNs key generated: ${s.id}`)),{keyId:s.id,keyName:r,privateKey:a}}catch(s){if(o.stop(h.red("APNs key generation failed.")),qc(s)&&i<3){i+=1,g.warn(h.yellow("Apple says that APNs key name already exists. Retrying with a new generated name..."));continue}if(!xo(s))throw s;No(s);let a=await be({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((L(a)||a==="exit")&&(ee("Operation cancelled"),process.exit(0)),a==="revoke"&&await Yc(e))continue}}}async function Qc(e,t){let n=await Hc(e);try{let i=await Xc(n),{Auth:r}=xn();g.info(h.dim("Signing in to Apple Developer Portal..."));let o=await Wc(()=>r.loginAsync({username:n,password:i},{autoResolveProvider:!0})),s=String(o?.context?.teamId||"").trim().toUpperCase(),a=await zc(o.context,()=>Zc(e,t));return{keyId:a.keyId,teamId:s,privateKey:a.privateKey}}catch(i){throw g.error(h.red("APNs key generation failed.")),i}}function xo(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
626
- `);return/maximum allowed number.*keys/i.test(t)||/already reached the maximum/i.test(t)}function qc(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
627
- `);return/another key with same name exists/i.test(t)||/same name already exists/i.test(t)}function No(e){if(g.warn(h.yellow(e?.message||"Could not generate APNs key automatically.")),xo(e)){g.info(h.dim("Apple rejected the request because this team is already at its APNs auth-key limit.")),g.info(h.dim("If you saved an existing .p8 file, upload it here. If not, delete an unused APNs key in Apple Developer, then generate again.")),g.info(h.dim("Apple only lets you download an APNs .p8 private key when the key is first created."));return}g.info(h.dim("You can upload an existing .p8 key, retry generation, or exit and try again later."))}async function vi(){let e=await be({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 L(e)&&(ee("Operation cancelled"),process.exit(0)),e==="all"?Lc:[e]}async function el(e,t,n,i){let r=i.teamId||e.teamId;if(!r){let o=await Te({message:"Apple Team ID:",validate:s=>/^[A-Z0-9]{10}$/i.test(s.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});L(o)&&(ee("Operation cancelled"),process.exit(0)),r=o.trim().toUpperCase()}for(let o of t)await Sn("apns",{...e,environment:o,privateKey:i.privateKey,teamId:r,keyId:i.keyId,bundleId:n})}async function Io(e,t,n){let i=await Te({message:"Path to APNs auth key (.p8):",validate:Ro});L(i)&&(ee("Operation cancelled"),process.exit(0));let r=await Te({message:"Apple Team ID:",initialValue:e.teamId,validate:s=>s.trim()?void 0:"Team ID is required"});L(r)&&(ee("Operation cancelled"),process.exit(0));let o=await Te({message:"APNs Key ID:",initialValue:e.keyId,validate:s=>s.trim()?void 0:"Key ID is required"});L(o)&&(ee("Operation cancelled"),process.exit(0));for(let s of t)await Sn("apns",{...e,environment:s,file:i,teamId:r,keyId:o,bundleId:n})}async function tl(e){let t=Gc(),n=e.bundleId||nt(t)||t.push?.iosBundleId;for(;;){let i=await be({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(L(i)&&(ee("Operation cancelled"),process.exit(0)),i==="upload"){let r=await vi();await Io(e,r,n);return}try{let r=await Qc(t,n),o=await vi();await el(e,o,n,r);return}catch(r){No(r);let o=await be({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((L(o)||o==="exit")&&(ee("Operation cancelled"),process.exit(0)),o==="upload"){let s=await vi();await Io(e,s,n);return}}}}async function nl(e){let t=await Te({message:"Path to Firebase service account JSON:",validate:Ro});L(t)&&(ee("Operation cancelled"),process.exit(0));let n;try{n=JSON.parse(B.readFileSync(t,"utf8"))}catch(i){ee(`Invalid Firebase service account JSON: ${i.message}`),process.exit(1)}await Sn("fcm",{...e,serviceAccount:n})}async function il(e,t){if(t==="ios"){await tl(e);return}await nl(e)}function rl(e,t,n){let i=B.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}`,l=Cn.createSign("SHA256");l.update(a);let c=l.sign({key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${c}`}async function ol(e,t,n,i){let r=rl(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"}}),g.info(h.dim(` \u2713 Registered: ${s.name}`))}catch(a){let l=a.response?.data?.errors;l?.some(d=>d.code==="ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE"||d.detail?.toLowerCase().includes("already registered")||d.detail?.toLowerCase().includes("already exists"))?g.info(h.dim(` Already on Portal: ${s.name}`)):g.warn(h.yellow(` Could not register ${s.name}: ${l?.[0]?.detail||a.message}`))}}var sl=async e=>{Sc(h.bgCyan.black(A.cliTag("Credentials")));let t=await be({message:"Select platform:",options:[{value:"ios",label:"iOS"},{value:"android",label:"Android"}]});L(t)&&(ee("Operation cancelled"),process.exit(0));let n=await be({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((L(n)||n==="exit")&&(ee("Operation cancelled"),process.exit(0)),n==="back")return sl(e);n==="setup"?await al({...e,platform:t}):n==="download"?await wl({...e,platform:t}):n==="service"?await Vi({...e,platform:t}):n==="push"&&await il(e,t),wc(h.green("Done!"))},al=async e=>{let t=ct(),n=e.platform,i=`./${A.configFileName}`;if(!B.existsSync(i)){g.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(B.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){g.error(`${A.configFileName} is missing projectId.`);return}let s=Object.keys(r.build||{}),a=u=>{let p=Fe(r,u)||{};return n==="android"?ho(r,u)==="store"?"store":"adhoc":kn({buildProfile:u,profile:p})},l=u=>{let p=Fe(r,u)||{};return[p.environment?`environment: ${p.environment}`:void 0,p.distribution?`distribution: ${p.distribution}`:void 0,n==="ios"?`signing: ${a(u)}`:void 0].filter(Boolean).join(", ")||"No behavior fields configured"},c=e.profile,d=e.credentialType;if(d&&!Mt(d)){g.error("Credential type must be development, adhoc, or store.");return}if(c&&s.length>0&&!Fe(r,c)){g.error(`Build profile '${c}' was not found in ${A.configFileName}.`);return}if(!c&&d){let u=Mt(d),p=s.filter(f=>a(f)===u);if(p.length===1)c=p[0];else if(p.length>1&&process.stdin.isTTY&&process.stdout.isTTY){let f=await be({message:`Select the ${u} build profile:`,options:p.map(m=>({value:m,label:m,hint:l(m)}))});L(f)&&(ee("Operation cancelled"),process.exit(0)),c=f}else if(p.length>1){g.error(`More than one profile uses ${u} credentials. Pass --profile with one of: ${p.join(", ")}.`);return}else if(s.length===1)c=s[0];else if(s.length>1){g.error(`No configured profile resolves to ${u}. Pass --profile explicitly.`);return}else c=u}if(!c){let u=s.length>0?s.map(f=>({value:f,label:f,hint:l(f)})):[{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"}],p=await be({message:s.length>0?"Select build profile:":"Select credential type:",options:u});L(p)&&(ee("Operation cancelled"),process.exit(0)),c=p,d=s.length>0?a(c):p==="production"?"store":p==="staging"?"adhoc":"development"}if(e.awsProfile&&g.warn(h.yellow(`Ignoring --aws-profile. Authenticating with ${A.name} Cloud...`)),g.info(h.dim(`Setting up credentials for: ${c}`)),n==="ios")await cl(o,c,e,r,d);else{let u=ho(r,c);await Sl(o,c,u,e,r)}};async function cl(e,t,n,i,r){let o=n.bundleId;if(!o){let c=i.submit?.[t]?.ios?.bundleIdentifier||i.submit?.[t]?.ios?.bundleId||nt(i,t),d=[];try{let p=(await U.get(`/credentials/${e}`)).data.credentials||[];d=[...new Set(p.filter(f=>f.platform==="ios"&&f.bundleId&&f.bundleId!=="*").map(f=>f.bundleId))]}catch{}if(c&&!d.includes(c)&&d.unshift(c),d.length>0){let u=[...d.map(f=>({value:f,label:f,hint:f===c?"from config":void 0})),{value:"__new__",label:"+ Enter a new Bundle ID"}],p=await be({message:"Which Bundle ID are you setting up credentials for?",options:u});if(L(p)&&(ee("Operation cancelled"),process.exit(0)),p==="__new__"){let f=await Te({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:m=>m.includes(".")?void 0:"Please enter a valid Bundle ID"});L(f)&&(ee("Operation cancelled"),process.exit(0)),o=f}else o=p}else{let u=await Te({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:p=>p.includes(".")?void 0:"Please enter a valid Bundle ID"});L(u)&&(ee("Operation cancelled"),process.exit(0)),o=u}}g.info(h.dim(`Bundle ID: ${o}`));let s=kn({buildProfile:t,profile:Fe(i,t)||{},requestedCredentialType:r});g.info(h.dim(`Credential storage type: ${s}`));let a=i.submit?.production?.ios?.appleId;a&&g.info(h.dim(`Using Apple ID from config: ${a}`)),await bl(e,o,t,s,s==="store"?"appstore":s==="adhoc"?"adhoc":"development",n,i,a)}var xi=e=>le(e.expiresAt)||le(e.expires)||le(e.expirationDate)||le(e.meta?.expiresAt)||le(e.meta?.expires),ll=e=>{let t=Mt(zt(e));return t==="development"?"Development":t==="adhoc"?"Ad Hoc":t==="store"?"App Store":zt(e)||"Unknown signing type"},dl=e=>{let t=e.credential,n=Pn(t)||"all apps",i=ll(t),r=xi(t);return[e.projectName,i,n,r?`expires ${r}`:void 0].filter(Boolean).join(" \xB7 ")},Qt=e=>e==="development"?"Apple Development":"Apple Distribution",ko=e=>e==="development"?"Development":e==="adhoc"?"Ad Hoc":"App Store",Ni=e=>{let t=xi(e);if(!t)return!1;let n=Date.parse(t);return Number.isFinite(n)&&n<=Date.now()},ul=(e,t,n,i)=>{if(e?.type!=="ios_profile"||e?.platform&&e.platform!=="ios"||!le(e?.s3Key)||Ni(e)||Pn(e)!==n||Mt(zt(e))!==(i==="appstore"?"store":i))return!1;let o=Ai(e);return!o||o===t.trim().toUpperCase()},pl=e=>le(e?.certificateSha1)||le(e?.meta?.certificateSha1),fl=e=>{let t=e?.profileCertificateSha1s??e?.meta?.profileCertificateSha1s;return Array.isArray(t)?t.filter(n=>typeof n=="string").map(n=>n.replace(/[^a-fA-F0-9]/g,"").toUpperCase()).filter(Boolean):[]},ml=(e,t)=>{let n=pl(t)?.replace(/[^a-fA-F0-9]/g,"").toUpperCase();return!!n&&fl(e).includes(n)};async function gl(e,t,n,i){let o=(await U.get(`/credentials/${e}`)).data.credentials||[],s=o.filter(l=>Si(l,t,i)&&!Ni(l)).map(l=>({projectId:e,projectName:"This project",credential:l,certificateId:bi(l),teamId:t})),a=o.filter(l=>ul(l,t,n,i));return{certificates:s,profiles:a}}async function Ao(e,t,n){let r=((await U.get("/projects")).data.projects||[]).filter(a=>a.projectId!==n),o=(await Promise.all(r.map(async a=>{if(!a.projectId)return[];try{return((await U.get(`/credentials/${a.projectId}`)).data.credentials||[]).filter(d=>Si(d,e,t)&&!Ni(d)).map(d=>({projectId:a.projectId,projectName:a.name||a.slug||a.projectId,credential:d,certificateId:bi(d),teamId:e}))}catch{return[]}}))).flat(),s=new Map;for(let a of o){let l=`${a.projectId}:${a.certificateId||En(a.credential)}`,c=s.get(l);(!c||String(a.credential.createdAt||"")>String(c.credential.createdAt||""))&&s.set(l,a)}return[...s.values()]}var Ei=e=>String(e||"").replace(/[^a-zA-Z0-9]/g,"").toUpperCase();async function hl(e,t,n,i,r,o){let s=await Rn(r,i,o);if(s.length===0)throw new Error(`No active ${Qt(i)} certificates were returned by the Apple Developer Portal.`);let a=Jt(t,n),l=new Set(a.map(p=>p.serial)),c=s.filter(p=>l.has(Ei(p.serial)));if(e.certificateId){let p=s.find(f=>f.id===e.certificateId);if(p&&l.has(Ei(p.serial)))return p.id;if(p&&c.length===1)return g.warn(h.yellow("The saved Apple certificate ID is stale. Mach matched the selected P12 to the active portal certificate by serial number instead.")),c[0].id}if(c.length===1)return g.info(h.dim(`Matched the selected saved P12 to Apple certificate ${c[0].name||c[0].id}.`)),c[0].id;if(c.length===0)throw new Error("The selected .p12 does not contain an active certificate returned by the Apple Developer Portal. Mach will not create a profile with a different certificate; choose another P12 or create a new Apple certificate.");let d=Qt(i);g.warn(h.yellow("The selected P12 contains multiple active Apple certificates. Select the exact certificate to use below."));let u=await be({message:`Which ${d} certificate matches the selected saved P12?`,options:[...c.map(p=>({value:p.id,label:[p.name||`${d} certificate`,p.expires].filter(Boolean).join(" \xB7 "),hint:p.serial?`serial ${p.serial}`:void 0})),{value:"cancel",label:"Cancel"}]});if(!(L(u)||u==="cancel"))return u}async function yl(e,t,n){let i="";for(let o=1;o<=5;o++)try{let s=await U.get(`/credentials/${t}/download`,{params:{projectId:e,format:"proxy"},responseType:"arraybuffer"});B.writeFileSync(n,Buffer.from(s.data));return}catch(s){if(i=s?.response?.data?.message||s?.message||String(s),!$o(i)||o>=5)break;let l=Math.min(15e3,1e3*Math.pow(2,o-1));g.warn(h.yellow(`Certificate download was interrupted (${i}). Retrying with a fresh secure link in ${Math.round(l/1e3)}s\u2026 (${o}/5)`)),await _o(l)}throw new Error(`Could not download the saved Mach certificate after 5 attempts: ${i||"Unknown network error"}`)}async function Il({targetProjectId:e,targetBundleId:t,targetDistributionType:n,matchType:i,candidate:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c}){let d=await Eo(r.projectId,"ios",r.credential),u=Po(d,{})||void 0,p=B.mkdtempSync(Q.join(yt.tmpdir(),`${A.nameLower}-reuse-cert-`)),f=Q.join(p,"selected-signing-certificate.p12"),m=`${A.nameLower} ${i} ${t}`,E=`${A.nameLower}-${i}-${Date.now()}.mobileprovision`;try{g.info(h.dim(`Downloading the selected certificate from ${r.projectName}\u2026`));let v=En(d);if(!v)throw new Error("The selected Mach certificate no longer has a credential ID.");await yl(r.projectId,v,f),g.info(h.dim("Importing the selected certificate into Mach\u2019s team keychain\u2026"));let P=D=>Pe("security",["import",f,"-k",a,"-P",D,"-T","/usr/bin/codesign"],{encoding:"utf-8"}),F,C=await uo({storedPassword:u,tryPassword:D=>(D===""&&u&&g.warn(h.dim("Saved P12 did not unlock with its stored password; trying the legacy empty-password format\u2026")),F=P(D),!F.error&&F.status===0),requestPassword:async()=>{g.warn(h.yellow("This saved P12 is password protected, but Mach does not have its password."));let D=await ht({message:`P12 password for ${r.projectName}'s saved certificate:`,validate:ce=>ce.length>0?void 0:"The certificate password is required"});return L(D)?void 0:D}});if(C.status==="cancelled")return!1;if(C.status==="failed")throw new Error(kt(F?.stdout,F?.stderr)||"Could not import the selected .p12 certificate. Check its password.");let N=C.password,b=Pe("security",["set-key-partition-list","-S","apple-tool:,apple:,codesign:","-s","-k",l,a],{encoding:"utf-8"});if(b.error||b.status!==0)throw new Error(kt(b.stdout,b.stderr)||"Could not grant codesign access to the imported certificate.");let k=await hl(r,f,N,i,s,o.shellCommand);if(!k)return!1;g.info(h.blue(`Creating a new ${ko(i)} profile for ${t}\u2026`));let _=Pe(o.command,po(i,t,m,k,p,E),{cwd:process.cwd(),env:s,stdio:"inherit"});if(_.error||_.status!==0)throw new Error("Apple could not create the provisioning profile with the selected certificate.");let S=vn(p,/\.mobileprovision$/);if(!S)throw new Error("The new provisioning profile was not produced by fastlane.");let $=Et(S);mn($,{bundleIdentifier:t,teamId:c.teamId,distributionType:n});let j=fn(Jt(f,N),$),x={certificateSha1:j.sha1,certificateSha256:j.sha256,certificateSerial:j.serial,profileCertificateSha1s:$.certificateSha1s,profileCertificateSha256s:$.certificateSha256s},M=xi(d);return await at(e,f,"ios_cert",t,n,void 0,M,c.teamId,k,N,void 0,void 0,c.teamId,c.teamName,c.developerTeamId||c.teamId,c.appStoreConnectTeamId,c.providerId,c.providerName,x),await at(e,S,"ios_profile",t,n,void 0,void 0,c.teamId,void 0,void 0,void 0,void 0,c.teamId,c.teamName,c.developerTeamId||c.teamId,c.appStoreConnectTeamId,c.providerId,c.providerName,x),g.success(h.green(`\u2713 Reused the saved certificate and created credentials for ${t}.`)),!0}finally{try{B.rmSync(p,{recursive:!0,force:!0})}catch{}}}async function wn({savedCertificates:e,targetProjectId:t,targetBundleId:n,targetDistributionType:i,matchType:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c}){let d=Qt(r),u=await be({message:`Select a saved ${d} certificate to reuse:`,options:[...e.map((f,m)=>({value:String(m),label:dl(f),hint:f.certificateId?`Apple Team ${f.teamId}`:`Apple Team ${f.teamId} \xB7 legacy record; Apple certificate matching may be requested`})),{value:"cancel",label:"Cancel"}]});if(L(u)||u==="cancel")return!1;let p=e[Number(u)];if(!p)throw new Error("The selected saved certificate is no longer available.");return Il({targetProjectId:t,targetBundleId:n,targetDistributionType:i,matchType:r,candidate:p,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c})}async function Al(e){let t="MATCH_ENCRYPTION_PASSPHRASE";try{let s=((await U.get(`/projects/${e}/secrets/export?env=development`)).data.secrets||{})[t];if(s&&!s.includes("[Decryption Failed]"))return g.info(h.dim("Using existing encryption passphrase from Dashboard")),s;if(s&&s.includes("[Decryption Failed]")){g.warn(h.yellow("\u26A0\uFE0F Existing MATCH_PASSWORD could not be decrypted (encryption key changed).")),g.info(h.dim("Generating a fresh passphrase and cleaning old certificates..."));let a=Cn.randomBytes(32).toString("base64");try{await U.post(`/projects/${e}/secrets`,{key:t,value:a,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 New encryption passphrase generated and saved"))}catch{}try{await U.post("/credentials/clean-match-storage",{projectId:e}),g.success(h.green("\u2713 Cleaned old certificates from storage"))}catch{}return a}}catch(r){g.info(h.dim(`Could not fetch existing passphrase from Dashboard: ${r.message}`))}let n=await be({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((L(n)||n==="cancel")&&(ee("Operation cancelled"),process.exit(0)),n==="enter"){let r=await ht({message:"Enter your MATCH_PASSWORD (encryption passphrase):",validate:s=>s.length>0?void 0:"Passphrase is required"});L(r)&&(ee("Operation cancelled"),process.exit(0));let o=r;try{await U.post(`/projects/${e}/secrets`,{key:t,value:o,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)"}),g.success(h.green("\u2713 Saved passphrase to Dashboard"))}catch{}return o}let i=Cn.randomBytes(32).toString("base64");try{await U.post(`/projects/${e}/secrets`,{key:t,value:i,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 Generated and saved encryption passphrase to Dashboard"))}catch(r){g.warn(h.yellow(`Could not save passphrase to Dashboard: ${r.message}`))}return i}async function bl(e,t,n,i,r,o,s,a){let l=ct(),c=!1,d=v=>{l.start(v),c=!0},u=v=>{c&&(l.stop(v),c=!1)};g.info(h.blue("Configuring iOS certificate management..."));let p,f,m=Bt(s,n),E=m;if(!a){let v=await Te({message:"Apple ID (for Apple Developer Portal):",placeholder:"your-email@example.com",validate:P=>P.includes("@")?void 0:"Please enter a valid email"});L(v)&&(ee("Operation cancelled"),process.exit(0)),a=v}try{let v=await Al(e),P="",F="";try{let x=await U.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),F=x.data.credentials.region||"ap-south-1",P=x.data.credentials.bucket||A.bucketPrefix,process.env.AWS_REGION=F,delete process.env.AWS_PROFILE)}catch(x){throw g.error(`Failed to authenticate with ${A.name} Cloud.`),x}if(!P||!F){g.error(`Failed to resolve S3 configuration from ${A.name} Cloud.`);return}let C=o.teamId||m.teamId||s.submit?.production?.ios?.appleTeamId;if(!C)try{let M=(await U.get(`/projects/${e}/secrets`)).data.secrets?.find(D=>D.key==="APPLE_TEAM_ID");M&&(C=M.value,g.info(h.dim(`Using Team ID from Dashboard: ${C}`)))}catch{}C&&C===s.submit?.production?.ios?.appleTeamId&&g.info(h.dim(`Using Apple Team ID from config: ${C}`));let N=await Vt({appleId:a,config:s,profile:n,initialTeam:{...m,teamId:C,developerTeamId:m.developerTeamId||C},promptToPersistConfig:!C,saveTeamId:C?void 0:x=>bo(e,x)});if(!N?.teamId)return;C=N.teamId;let b={...m,...N,teamId:C,developerTeamId:N.developerTeamId||m.developerTeamId||C};E=b;let k=Rc(e,C);g.info(h.dim(`Using match storage prefix: ${k}`));let _=await Mc(),S={..._.env};process.env.CI||delete S.CI,d(`Preparing ${r} certificate sync...`),u("Starting certificate sync...");let $=`${A.buildPrefix}-${C}-${r}.keychain-db`,j=A.keychainPassword;try{let M=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${$}`;g.info(h.dim(`Ensuring keychain exists: ${$}`));try{je(`security create-keychain -p ${j} ${$} 2>/dev/null || true`),je(`security unlock-keychain -p ${j} ${$}`),je(`security set-keychain-settings ${$}`);let V=je("security list-keychains -d user").toString();if(!V.includes($)){g.info(h.dim(`Adding ${$} to search list`));let ne=[...V.replace(/"/g,"").split(`
628
- `).map(Y=>Y.trim()).filter(Y=>Y.length>0),M].join(" ");je(`security list-keychains -d user -s ${ne}`)}}catch(V){g.warn(h.dim("Keychain setup warning (non-critical): "+V.message))}let D,ce;try{let J=((await U.get(`/credentials/${e}`)).data.credentials||[]).find(ne=>ne.type==="asc_api_key"&&ne.issuerId);if(J){let ne=await U.get(`/credentials/${J.credentialId}/download`,{params:{projectId:e,format:"raw"}});if(ne.data.downloadUrl){let K=await(await import("axios")).default.get(ne.data.downloadUrl,{responseType:"arraybuffer"}),pe=Q.join(yt.tmpdir(),`mach-asc-${Date.now()}`);B.mkdirSync(pe,{recursive:!0}),p=Q.join(pe,`AuthKey_${J.keyId}.p8`),B.writeFileSync(p,Buffer.from(K.data)),D=J.keyId,ce=J.issuerId,g.success(h.green("\u2713 ASC API key loaded \u2014 no 2FA required for Portal operations"))}}}catch(V){g.warn(h.dim(`Could not load ASC API key: ${V.message}. Will fall back to Apple ID auth.`))}g.info(h.dim("Generating secure P12 export password..."));let Se=To();g.success(h.green("\u2713 Secure P12 password generated.")),f=B.mkdtempSync(Q.join(yt.tmpdir(),`${A.nameLower}-match-${r}-`));let Z={...S,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:v,FASTLANE_USER:a,FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_TEAM_ID:C,MATCH_KEYCHAIN_NAME:M,MATCH_KEYCHAIN_PASSWORD:j,TERM:process.env.TERM||"xterm-256color",SHELL:process.env.SHELL||"/bin/zsh",MATCH_OUTPUT_PATH:f,MATCH_STORAGE_MODE:"s3",MATCH_S3_REGION:F,MATCH_S3_BUCKET:P,MATCH_S3_OBJECT_PREFIX:k,MATCH_USERNAME:a,MATCH_APP_IDENTIFIER:t,MATCH_TYPE:r,[`${A.envPrefix}P12_PASSWORD`]:Se,...p&&D&&ce?{APP_STORE_CONNECT_API_KEY_KEY_ID:D,APP_STORE_CONNECT_API_KEY_ISSUER_ID:ce,APP_STORE_CONNECT_API_KEY_KEY_FILEPATH:p,FASTLANE_SKIP_2FA:"1"}:{}};if(o.force){g.warn(h.yellow(`
629
- \u26A0\uFE0F Force flag detected: Hard resetting ${r} certificates...`)),g.info(h.dim("Detected decryption failure loop. Clearing remote storage directly to allow fresh generation.")),g.info(h.dim(`Cleaning match storage for Team ID: ${C}...`));try{(await U.post("/credentials/clean-match-storage",{projectId:e,teamId:C,storagePrefix:k})).data.status==="success"&&g.success(h.green(`\u2713 Cleared S3 storage for Team ID: ${C}`))}catch(V){g.warn(h.yellow(`S3 cleanup via API failed: ${V.message}`)),g.info(h.dim("Continuing to attempt standard nuke..."))}try{je(`${_.shellCommand} match nuke ${r} --skip_confirmation`,{stdio:"inherit",cwd:process.cwd(),env:Z}),g.success(h.green(`\u2713 Nuked existing ${r} credentials`))}catch{g.warn(h.yellow("Standard nuke failed (likely due to password mismatch).")),g.info(h.dim("Since S3 was cleared manually, proceeding to generation..."))}}let Le=r==="adhoc"||r==="development";if(r==="adhoc"||r==="development")try{g.info(h.blue("Fetching registered devices..."));let J=(await U.get("/devices",C?{params:{teamId:C}}:void 0)).data.devices||[];if(C)try{let ne=await U.get("/devices",{params:{teamId:"LEGACY"}}),Y=new Map;for(let K of[...J,...ne.data.devices||[]])Y.set(K.udid,K);J=Array.from(Y.values())}catch{}if(J.length===0)g.warn(h.yellow("No registered devices found. Profile will only include devices already on the Apple Developer Portal.")),g.info(h.dim(`Register devices with: ${A.nameLower} device register`));else{let{multiselect:ne}=await import("@clack/prompts"),Y=await ne({message:`Select devices to include in the ${r} profile:`,options:J.map(K=>({value:K.udid,label:`${K.name} (${K.udid.substring(0,12)}...)`,hint:K.model||K.platform})),initialValues:J.map(K=>K.udid)});if(!L(Y)&&Y.length>0){let K=J.filter(pe=>Y.includes(pe.udid));if(g.info(h.blue(`Registering ${K.length} device(s) on Apple Developer Portal...`)),C&&await Promise.all(K.filter(pe=>!pe.teamId).map(pe=>U.post("/devices",{udid:pe.udid,name:pe.name,platform:"ios",addedVia:pe.addedVia||"cli",teamId:C,teamName:b.teamName}).catch(()=>{}))),p&&D&&ce)await ol(K,D,ce,p);else{g.info(h.dim("You will be prompted for a 2FA code once \u2014 type it and press Enter."));for(let pe of K){let et=pe.name.replace(/"/g,'\\"');Pe(`${_.shellCommand} run register_device name:"${et}" udid:"${pe.udid}"`,{shell:!0,env:Z,stdio:"inherit",cwd:process.cwd()})}}g.info(h.green("\u2713 Device registration complete.")),Le=!0}}}catch(V){g.warn(h.yellow(`Could not fetch registered devices: ${V.message}`)),g.info(h.dim("Continuing without explicit device registration."))}let de=r,O={certificates:[],profiles:[]};try{O=await gl(e,C,t,de)}catch{}let T=Qt(de),G=ko(de),W=O.certificates.some(V=>O.profiles.some(J=>ml(J,V.credential)));if(!o.force&&W){g.success(h.green(`\u2713 Existing ${T} certificate and ${G} profile pair verified in Mach for ${t}.`));let V=await be({message:`What should Mach do with the existing ${G} profile?`,options:[{value:"refresh_profile",label:`Recreate the ${G} profile with the saved certificate`,hint:"Recommended \u2014 refreshes the Apple profile without creating another certificate"},{value:"reuse_profile",label:"Reuse the verified profile unchanged",hint:"Skips Apple Portal changes when the registered devices and entitlements are unchanged"},{value:"sync",label:"Continue with normal certificate sync",hint:"Use only when you need a different signing identity"}],initialValue:"refresh_profile"});if(L(V)){ee("Operation cancelled");return}if(V==="reuse_profile"){g.info(h.dim("Reusing the verified certificate and profile pair; no Apple Portal changes were made."));return}if(V==="refresh_profile"){if(await wn({savedCertificates:O.certificates,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:_,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:b}))return;throw new Error("Provisioning profile refresh was cancelled or could not be completed. No new certificate was requested.")}}if(O.certificates.length>0&&!o.force){O.profiles.length>0&&g.warn(h.yellow("Existing iOS credential records do not prove that the profile was generated with the saved certificate. Mach will safely regenerate the profile from the selected P12."));let V=await be({message:`A saved ${T} certificate already exists in this Mach project.`,options:[{value:"reuse",label:`Create or refresh the ${G} profile with the saved certificate`,hint:"Recommended \u2014 no new Apple certificate is requested"},{value:"sync",label:"Continue with normal certificate sync",hint:"May ask Apple to create another certificate if Match storage is incomplete"}]});if(L(V)){ee("Operation cancelled");return}if(V==="reuse"){if(await wn({savedCertificates:O.certificates,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:_,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:b}))return;throw new Error("Saved certificate reuse was cancelled or could not be completed. No new certificate was requested.")}}let z=[];try{z=await Ao(C,de,e)}catch{}if(z.length>0){let V=await be({message:`Saved ${T} certificate${z.length===1?"":"s"} found for Apple Team ${C}.`,options:[{value:"reuse",label:"Reuse a saved certificate",hint:`${z.length} compatible certificate${z.length===1?"":"s"} found \u2014 no new Apple certificate is requested`},{value:"sync",label:"Continue with normal certificate sync",hint:"Use this only when you need a different signing identity"}]});if(L(V)){ee("Operation cancelled");return}if(V==="reuse"){if(await wn({savedCertificates:z,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:_,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:b}))return;throw new Error("Saved certificate reuse was cancelled or could not be completed. No new certificate was requested.")}}try{let V=`${A.nameLower} ${r} ${t}`,J=kc(_.shellCommand,r,t,V,Le);Le&&g.info(h.dim(`Refreshing ${r} provisioning profile when device list changes (--force_for_new_devices).`));let ne=Pe(J,{shell:!0,cwd:process.cwd(),env:Z,stdio:"inherit",encoding:"utf-8"});if(ne.status!==0){g.warn(h.yellow(`
630
- Certificate sync failed. Attempting to create App ID and retry...`));try{je(`${_.shellCommand} produce --app_identifier "${t}" --app_name "${t}" --skip_itc`,{stdio:"inherit",env:Z}),g.success(h.green("\u2713 App ID created successfully")),g.info(h.blue("Retrying certificate sync...")),ne=Pe(J,{shell:!0,cwd:process.cwd(),env:Z,stdio:"inherit",encoding:"utf-8"})}catch{}if(ne.status!==0)throw new Error("fastlane match failed")}}catch(V){let J=Qt(de);if(g.warn(h.yellow(`
631
- Certificate sync failed. This can be caused by an incorrect encryption passphrase, an expired Apple session, or the ${J} certificate limit.`)),z.length===0)try{z=await Ao(C,de,e)}catch{}let ne=await be({message:"What would you like to do?",options:[...z.length>0?[{value:"reuse_saved",label:"Reuse a saved Mach certificate",hint:`${z.length} compatible certificate${z.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(L(ne)||ne==="cancel")throw V;if(ne==="reuse_saved"){if(await wn({savedCertificates:z,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:_,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:b}))return;throw V}else if(ne==="retry_password"){g.info(h.dim(`
632
- You are overriding the dashboard passphrase for this session.`));let Y=await ht({message:"Enter the correct MATCH_PASSWORD for this project:"});if(Y&&!L(Y)){v=Y,g.info(h.blue("Retrying with provided passphrase..."));let K={...Z,MATCH_PASSWORD:v};if(Pe(`${_.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:K}).status===0)await U.post(`/projects/${e}/secrets`,{key:"MATCH_ENCRYPTION_PASSPHRASE",value:v,description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 Dashboard passphrase updated."));else throw new Error("Sync failed again with provided passphrase.")}else throw V}else if(ne==="check_portal")try{let Y=await Rn(Z,r,_.shellCommand);if(Y.length>0){if(g.info(h.dim(`Found ${Y.length} existing ${r} certificates on the portal.`)),await vl(r,Z,e,_.shellCommand,Y)&&(g.info(h.blue("Retrying certificate sync...")),Pe(`${_.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:Z}).status!==0))throw new Error("Retry failed")}else throw g.error(h.red("No existing certificates found on portal to resolve.")),V}catch(Y){throw g.warn(h.dim(`Portal check warning: ${Y.message}`)),V}else throw V}g.success(h.green("\u2713 Certificates fetched and synced"));let se=f,X=Q.join(se,`${A.fastlanePrefix}_export.p12`),ue=vn(se,/\.mobileprovision$/);try{let J=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${$}`;B.existsSync(se)||B.mkdirSync(se,{recursive:!0}),g.info(h.dim("Exporting certificate from keychain for dashboard upload..."));let ne=je(`security find-identity -v -p codesigning "${J}"`,{encoding:"utf-8"});g.info(h.dim(`Identities in keychain:
633
- ${ne.trim()}`));let Y=Pe("security",["export","-k",J,"-t","identities","-f","pkcs12","-o",X,"-P",Se],{encoding:"utf-8"});if(Y.error||Y.status!==0)throw new Error(kt(Y.stdout,Y.stderr)||"security could not export the signing certificate.");try{let K=Pe("openssl",["pkcs12","-in",X,"-nokeys","-passin",`pass:${Se}`,"-legacy"],{encoding:"utf-8"});if((K.error||K.status!==0)&&(K=Pe("openssl",["pkcs12","-in",X,"-nokeys","-passin",`pass:${Se}`],{encoding:"utf-8"})),K.error||K.status!==0)throw new Error(kt(K.stdout,K.stderr)||"openssl could not read the exported P12.");let pe=K.stdout||"";if(!pe.includes(C))throw new Error(`Exported P12 does not contain identity for team ${C}. Found: ${pe.substring(0,200)}`);g.success(h.green(`\u2713 P12 verified \u2014 contains correct team identity (${C})`))}catch(K){throw new Error(`P12 verification failed: ${K.message}`)}}catch{g.warn(h.dim("Could not export certificate from keychain."))}o.teamId&&!C&&await bo(e,o.teamId);let ye=B.existsSync(X)?X:vn(se,/\.p12$/);if(ye&&ue){let V,J,ne,Y;try{Y=Et(ue),mn(Y,{bundleIdentifier:t,teamId:b.teamId||o.teamId||C,distributionType:i}),ne=fn(Jt(ye,Se),Y),g.success(h.green(`\u2713 Provisioning profile verified against signing certificate (${ne.sha1.slice(0,12)}\u2026).`))}catch(pe){throw new Error(`Refusing to upload an iOS certificate/profile mismatch: ${pe.message}`)}let K={certificateSha1:ne.sha1,certificateSha256:ne.sha256,certificateSerial:ne.serial,profileCertificateSha1s:Y.certificateSha1s,profileCertificateSha256s:Y.certificateSha256s};try{let et=(await Rn(Z,r,_.shellCommand)).find(Re=>Ei(Re.serial)===ne.serial);et?(V=et.expires,J=et.id):g.warn(h.yellow("The matching certificate could not be identified on the Apple portal, so Mach will save the verified fingerprint without a portal ID."))}catch{g.warn(h.dim("Could not fetch expiration date or ID for dashboard record."))}await at(e,ye,"ios_cert",t,i,void 0,V,o.teamId||C,J,Se,void 0,void 0,b.teamId,b.teamName,b.developerTeamId,b.appStoreConnectTeamId,b.providerId,b.providerName,K),await at(e,ue,"ios_profile",t,i,void 0,V,o.teamId||C,void 0,void 0,void 0,void 0,b.teamId,b.teamName,b.developerTeamId,b.appStoreConnectTeamId,b.providerId,b.providerName,K),g.success(h.green("\u2713 Both iOS certificate and provisioning profile uploaded successfully"))}else g.warn(h.yellow("Certificates generated but not found in expected location.")),g.info(h.dim("Falling back to manual upload...")),await So(e,t,i,E)}catch(x){u("Certificate fetch failed"),g.error(h.red(`Error: ${x.message}`)),g.info(h.dim("Falling back to manual upload...")),await So(e,t,i,E)}}catch(v){u("iOS setup failed"),g.error(h.red(`Error: ${v.message}`))}finally{if(p)try{B.rmSync(Q.dirname(p),{recursive:!0,force:!0})}catch{}if(f)try{B.rmSync(f,{recursive:!0,force:!0})}catch{}}}async function bo(e,t){try{await U.post(`/projects/${e}/secrets`,{key:"APPLE_TEAM_ID",value:t,description:"Apple Developer Team ID (used for iOS signing)"}),g.success(h.green(`\u2713 Saved Team ID ${t} to Dashboard`))}catch(n){g.warn(h.yellow(`Could not save Team ID to Dashboard: ${n.message}`))}}async function So(e,t,n,i={}){g.info(h.yellow(`
634
- Manual Upload Mode`)),g.info("Please provide your certificate and provisioning profile:");let r=await Te({message:"Path to .p12 certificate file:",validate:f=>B.existsSync(f)?void 0:"File not found"});L(r)&&(ee("Operation cancelled"),process.exit(0));let o=await Te({message:"Path to .mobileprovision file:",validate:f=>B.existsSync(f)?void 0:"File not found"});L(o)&&(ee("Operation cancelled"),process.exit(0));let s=await ht({message:"P12 password (leave empty only when the certificate has no password):"});L(s)&&(ee("Operation cancelled"),process.exit(0));let a=r,l=o,c,d;try{d=Et(l),mn(d,{bundleIdentifier:t,teamId:i.teamId,distributionType:n}),c=fn(Jt(a,s),d)}catch(f){throw new Error(`The selected .p12 and .mobileprovision do not form a valid signing pair: ${f.message}`)}let u={certificateSha1:c.sha1,certificateSha256:c.sha256,certificateSerial:c.serial,profileCertificateSha1s:d.certificateSha1s,profileCertificateSha256s:d.certificateSha256s},p=ct();p.start(`Uploading to ${A.name} Dashboard...`);try{await at(e,a,"ios_cert",t,n,s,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,u),await at(e,l,"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,u),p.stop("Upload complete"),g.success(h.green("\u2713 iOS credentials uploaded successfully"))}catch(f){throw p.stop("Upload failed"),f}}async function Sl(e,t,n,i,r){let o=ct();g.step(h.blue("Android Credential Setup"));let s=i.bundleId;if(!s){let u=bt(r,t),p=[];try{let m=(await U.get(`/credentials/${e}`)).data.credentials||[];p=[...new Set(m.filter(E=>E.platform==="android"&&E.bundleId&&E.bundleId!=="*").map(E=>E.bundleId))]}catch{}if(u&&!p.includes(u)&&p.unshift(u),p.length>0){let f=[...p.map(E=>({value:E,label:E,hint:E===u?"from config":void 0})),{value:"__new__",label:"+ Enter a new Package Name"}],m=await be({message:"Which Package Name are you setting up credentials for?",options:f});if(L(m)&&(ee("Operation cancelled"),process.exit(0)),m==="__new__"){let E=await Te({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:v=>v.includes(".")?void 0:"Please enter a valid package name"});L(E)&&(ee("Operation cancelled"),process.exit(0)),s=E}else s=m}else{let f=await Te({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:m=>m.includes(".")?void 0:"Please enter a valid package name"});L(f)&&(ee("Operation cancelled"),process.exit(0)),s=f}}try{let f=((await U.get(`/credentials/${e}`)).data.credentials||[]).find(m=>m.platform==="android"&&m.distributionType===n&&m.bundleId===s);if(f){g.warn(h.yellow(`\u26A0\uFE0F Existing Android credentials found for ${n}`));let m=await Te({message:"What would you like to do? (use/new/cancel)",validate:E=>{let v=E.toLowerCase();if(!(v==="use"||v==="new"||v==="cancel"))return"Please type: use, new, or cancel"}});if(L(m)||m.toLowerCase()==="cancel")return;if(m.toLowerCase()==="use"){g.success(h.green("\u2713 Using existing credentials."));return}await U.delete(`/credentials/${f.credentialId}?projectId=${e}`)}}catch{}let a="./android/app/my-release-key.jks";if(B.existsSync(a)){let u=await Pi({message:"Upload existing keystore?"});if(u&&!L(u)){let p=await Te({message:"Key alias:",initialValue:"my-key-alias"});if(L(p))return;let f=await ht({message:"Keystore password:"});if(L(f))return;let m=await ht({message:"Key password (leave blank if same as keystore password):"});if(L(m))return;let E=m.trim()||f;await at(e,a,"android_keystore",s,n,p,void 0,void 0,void 0,void 0,f,E),g.success(h.green("\u2713 Keystore uploaded"));return}}g.info(h.blue("Generating new Android keystore..."));let l=i.keyAlias||`${A.nameLower}-${Cl()}`,c=To(),d=`./${A.nameLower}-${t}.jks`;B.existsSync(d)&&B.unlinkSync(d),o.start("Generating keystore...");try{let u=c.replace(/'/g,"'\\''");je(`keytool -genkeypair -v -keystore "${d}" -alias "${l}" -keyalg RSA -keysize 2048 -validity 10000 -storepass '${u}' -keypass '${u}' -dname "CN=${A.name} Build, OU=Mobile, O=Company, L=City, S=State, C=US"`,{stdio:"inherit"}),o.stop("Keystore generated"),await at(e,d,"android_keystore",s,n,l,void 0,void 0,void 0,void 0,c,c),g.success(h.green("\u2713 Android credentials uploaded successfully")),g.info(h.cyan(`Key Alias: ${l}`))}catch(u){throw o.stop("Generation failed"),new Error(`Keystore generation failed: ${u.message}`)}}var _o=e=>new Promise(t=>setTimeout(t,e));function $o(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 at(e,t,n,i,r,o,s,a,l,c,d,u,p,f,m,E,v,P,F){let C=Q.basename(t);g.info(h.dim(`Uploading ${C} (Isolated process)...`));let N=new URL(import.meta.url),b=Q.dirname(N.pathname),_=[Q.join(b,"commands","isolated-upload.js"),e,t,n,i,r,o||"undefined",s||"undefined",a||"undefined",l||"undefined",c||"undefined",d||"undefined",u||"undefined",p||"undefined",f||"undefined",m||"undefined",E||"undefined",v||"undefined",P||"undefined",F?JSON.stringify(F):"undefined"],S="",$=5;for(let j=1;j<=$;j++){let x=Pe("node",_,{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(x.status===0&&x.stdout.includes("SUCCESS")){g.info(h.dim(`\u2713 ${C} uploaded and registered.`));return}if(x.status===0){g.warn(h.yellow(`Isolated upload finished but success not confirmed: ${x.stdout}`));return}if(S=(x.stderr||x.stdout||x.error?.message||"Unknown isolated upload failure").trim(),!$o(S)||j>=$)throw g.error(h.red(`Isolated Upload Failed: ${S}`)),new Error(S);let D=Math.min(3e4,1500*Math.pow(2,j-1));g.warn(h.yellow(`Upload failed with a transient error. Retrying ${C} in ${Math.round(D/1e3)}s... (${j}/${$})`)),await _o(D)}throw new Error(S||"Unknown isolated upload failure")}async function wl(e){let t=ct(),n=e.platform,i=`./${A.configFileName}`;if(!B.existsSync(i)){g.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(B.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){g.error(`${A.configFileName} is missing projectId.`);return}try{t.start("Fetching project secrets...");let a=(await U.get(`/projects/${o}/secrets/export?env=all`)).data.secrets||{};t.stop("Secrets fetched and merged."),t.start("Fetching credentials...");let c=(await U.get(`/credentials/${o}`)).data.credentials||[];t.stop(`Found ${c.length} metadata records.`);let d=c.filter(m=>m.platform===n);if(d.length===0){g.info(`No ${n} credentials found on Dashboard.`);return}let u="./credentials.json",p={};if(B.existsSync(u))try{p=JSON.parse(B.readFileSync(u,"utf-8"))}catch{g.warn("Could not parse existing credentials.json, creating a new one.")}p[n]||(p[n]={});let f=Q.join(process.cwd(),"credentials",n);B.existsSync(f)||B.mkdirSync(f,{recursive:!0});for(let m of d){t.start(`Downloading ${m.type} (${m.distributionType})...`);try{let E=await U.get(`/credentials/${m.credentialId}/download`,{params:{projectId:o,format:"raw"}});if(E.data.status==="success"&&E.data.downloadUrl){let v=Q.join(process.cwd(),"credentials",n,m.distributionType);B.existsSync(v)||B.mkdirSync(v,{recursive:!0});let P=m.s3Key?.split(".").pop()||(m.type.includes("keystore")?"jks":m.type.includes("cert")?"p12":"mobileprovision"),F=`${m.type}.${P}`,C=Q.join(v,F),N=await wo.get(E.data.downloadUrl,{responseType:"arraybuffer"});B.writeFileSync(C,Buffer.from(N.data));let b=Q.join("credentials",n,m.distributionType,F),k="",_="",S={alias:"",keystorePassword:"",keyPassword:""};if(n==="ios"&&m.type==="ios_cert"||n==="android"&&m.type==="android_keystore"){let $=await Eo(o,n,m);if(n==="ios"&&m.type==="ios_cert"&&P.toLowerCase()==="p12"){if(k=Po($,a),k){let j=go(C,`${Q.basename(C,Q.extname(C))}-password.txt`,k);_=Q.join("credentials",n,m.distributionType,Q.basename(j))}}else if(n==="android"&&m.type==="android_keystore"&&(S=jc($,a),S.keystorePassword||S.keyPassword)){let j=[S.alias?`keyAlias=${S.alias}`:void 0,S.keystorePassword?`keystorePassword=${S.keystorePassword}`:void 0,S.keyPassword?`keyPassword=${S.keyPassword}`:void 0].filter(Boolean).join(`
635
- `),x=go(C,`${Q.basename(C,Q.extname(C))}-passwords.txt`,j);_=Q.join("credentials",n,m.distributionType,Q.basename(x))}}if(n==="android")m.type==="android_keystore"&&(p.android.keystore={keystorePath:b,keystorePassword:S.keystorePassword,keyAlias:S.alias,keyPassword:S.keyPassword},_&&(p.android.keystore.keystoreArchivePath=_));else if(n==="ios"){let $=m.distributionType==="store"?"production":m.distributionType==="adhoc"?"staging":"development";p.ios[$]||(p.ios[$]={}),m.type==="ios_cert"?(p.ios[$].certificatePath=b,p.ios[$].certificatePassword=k,_&&(p.ios[$].certificateArchivePath=_)):m.type==="ios_profile"&&(p.ios[$].provisioningProfilePath=b)}t.stop(`\u2713 ${m.type} (${m.distributionType}) saved${_?" with password archive":""}.`)}}catch(E){let v=E.response?.data?.message||E.message;t.stop(h.dim(`- Skipped ${m.type} (${m.distributionType}): ${v}`))}}B.writeFileSync(u,JSON.stringify(p,null,2)),g.success(h.green("\u2713 Local credentials.json updated.")),Cc("Credentials have been synced to your local machine. Ensure credentials.json and credentials/ is added to your .gitignore.","Sync Complete")}catch(s){t.stop(h.red("Sync failed.")),g.error(`Error: ${s.message}`)}}function To(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_+=",t="";for(let n=0;n<24;n++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}function Cl(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 vl(e,t,n,i,r){let o=r||await Rn(t,e,i);if(!o||o.length===0)return!1;let s=await be({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 L(s)||s==="cancel"?!1:s==="nuke"?(je(`${i} match nuke ${e}`,{stdio:"inherit",cwd:process.cwd(),env:t}),!0):typeof s=="string"&&s.startsWith("revoke:")?(await El(t,s.split(":")[1],i),!0):!1}async function Rn(e,t,n){let i=t==="development"?"development":"distribution",r=`
710
+ `,"utf8")),o.writeZip(i),i},Io=(e,t)=>{let n=Te(e,t)||{},i=xt(n.distribution),r=xt(n.environment);return i==="store"||r==="production"||r==="store"?"store":"internal"},Wc=["development","preview","production"],Gc="U27F4V844T",wi=null;function Nn(){return wi||(wi=Nc("@expo/apple-utils")),wi}function Ao(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 Zc(e){let t=process.stdout.write.bind(process.stdout),n=process.stderr.write.bind(process.stderr);process.stdout.write=(i,...r)=>t(Ao(i),...r),process.stderr.write=(i,...r)=>n(Ao(i),...r);try{return await e()}finally{process.stdout.write=t,process.stderr.write=n}}function xo(e){return V.existsSync(Q.resolve(e))?void 0:"File not found"}function Hc(){try{let e=`./${A.configFileName}`;return V.existsSync(e)?JSON.parse(V.readFileSync(e,"utf-8")):{}}catch{return{}}}function Xc(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=wn.randomBytes(2).toString("hex").toUpperCase(),s=` ${r}-${o}`;return`${`MACH Push ${n}`.slice(0,Math.max(1,50-s.length))}${s}`}async function Kc(e){let t=e.submit?.production?.ios?.appleId||e.submit?.preview?.ios?.appleId||e.submit?.development?.ios?.appleId,n=await Oe({message:"Apple ID (for Apple Developer Portal):",initialValue:t,validate:i=>i.includes("@")?void 0:"Enter a valid Apple ID email"});return L(n)&&(q("Operation cancelled"),process.exit(0)),n}async function Jc(e){let t=await ht({message:`Apple password for ${e} (used only for Apple login, not stored):`,validate:n=>n.trim()?void 0:"Password is required"});return L(t)&&(q("Operation cancelled"),process.exit(0)),t}function Yc(e){return(Array.isArray(e?.services)?e.services:[]).some(n=>n?.id===Gc||/apple push notification|apns/i.test(String(n?.name||"")))}async function zc(e){let{Keys:t}=Nn(),n=ct();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(Yc);return n.stop(h.green(`Found ${o.length} APNs key${o.length===1?"":"s"}.`)),o}catch(i){throw n.stop(h.red("Could not fetch APNs keys from Apple.")),i}}async function Qc(e){let{Keys:t}=Nn(),i=(await zc(e)).filter(l=>l.canRevoke!==!1);if(i.length===0)return g.warn(h.yellow("No revokable APNs keys were found for this Apple team.")),!1;let r=await be({message:"Select an APNs key to revoke:",options:i.map(l=>({value:l.id,label:`${l.name||"Untitled APNs key"} (${l.id})`,hint:l.canDownload?"APNs key, private key may still be downloadable":"APNs key"}))});L(r)&&(q("Operation cancelled"),process.exit(0));let o=i.find(l=>l.id===r);g.warn(h.yellow("Revoking this key can break push notifications for any service currently using it."));let s=await Pi({message:`Revoke "${o?.name||"Untitled APNs key"}" (${r})? This cannot be undone.`,initialValue:!1});if(L(s)&&(q("Operation cancelled"),process.exit(0)),!s)return g.info(h.dim("APNs key was not revoked.")),!1;let a=ct();try{return a.start(`Revoking APNs key ${r}...`),await t.revokeKeyAsync(e,{id:r}),a.stop(h.green(`Revoked APNs key ${r}.`)),!0}catch(l){throw a.stop(h.red(`Could not revoke APNs key ${r}.`)),l}}async function qc(e,t){let{Keys:n}=Nn(),i=0;for(;;){let r=t(),o=ct();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(h.green(`APNs key generated: ${s.id}`)),{keyId:s.id,keyName:r,privateKey:a}}catch(s){if(o.stop(h.red("APNs key generation failed.")),tl(s)&&i<3){i+=1,g.warn(h.yellow("Apple says that APNs key name already exists. Retrying with a new generated name..."));continue}if(!ko(s))throw s;_o(s);let a=await be({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((L(a)||a==="exit")&&(q("Operation cancelled"),process.exit(0)),a==="revoke"&&await Qc(e))continue}}}async function el(e,t){let n=await Kc(e);try{let i=await Jc(n),{Auth:r}=Nn();g.info(h.dim("Signing in to Apple Developer Portal..."));let o=await Zc(()=>r.loginAsync({username:n,password:i},{autoResolveProvider:!0})),s=String(o?.context?.teamId||"").trim().toUpperCase(),a=await qc(o.context,()=>Xc(e,t));return{keyId:a.keyId,teamId:s,privateKey:a.privateKey}}catch(i){throw g.error(h.red("APNs key generation failed.")),i}}function ko(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
711
+ `);return/maximum allowed number.*keys/i.test(t)||/already reached the maximum/i.test(t)}function tl(e){let t=[e?.message,e?.response?.data,e?.cause?.message].filter(Boolean).join(`
712
+ `);return/another key with same name exists/i.test(t)||/same name already exists/i.test(t)}function _o(e){if(g.warn(h.yellow(e?.message||"Could not generate APNs key automatically.")),ko(e)){g.info(h.dim("Apple rejected the request because this team is already at its APNs auth-key limit.")),g.info(h.dim("If you saved an existing .p8 file, upload it here. If not, delete an unused APNs key in Apple Developer, then generate again.")),g.info(h.dim("Apple only lets you download an APNs .p8 private key when the key is first created."));return}g.info(h.dim("You can upload an existing .p8 key, retry generation, or exit and try again later."))}async function vi(){let e=await be({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 L(e)&&(q("Operation cancelled"),process.exit(0)),e==="all"?Wc:[e]}async function nl(e,t,n,i){let r=i.teamId||e.teamId;if(!r){let o=await Oe({message:"Apple Team ID:",validate:s=>/^[A-Z0-9]{10}$/i.test(s.trim())?void 0:"Team ID must be exactly 10 letters/numbers"});L(o)&&(q("Operation cancelled"),process.exit(0)),r=o.trim().toUpperCase()}for(let o of t)await Sn("apns",{...e,environment:o,privateKey:i.privateKey,teamId:r,keyId:i.keyId,bundleId:n})}async function bo(e,t,n){let i=await Oe({message:"Path to APNs auth key (.p8):",validate:xo});L(i)&&(q("Operation cancelled"),process.exit(0));let r=await Oe({message:"Apple Team ID:",initialValue:e.teamId,validate:s=>s.trim()?void 0:"Team ID is required"});L(r)&&(q("Operation cancelled"),process.exit(0));let o=await Oe({message:"APNs Key ID:",initialValue:e.keyId,validate:s=>s.trim()?void 0:"Key ID is required"});L(o)&&(q("Operation cancelled"),process.exit(0));for(let s of t)await Sn("apns",{...e,environment:s,file:i,teamId:r,keyId:o,bundleId:n})}async function il(e){let t=Hc(),n=e.bundleId||nt(t)||t.push?.iosBundleId;for(;;){let i=await be({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(L(i)&&(q("Operation cancelled"),process.exit(0)),i==="upload"){let r=await vi();await bo(e,r,n);return}try{let r=await el(t,n),o=await vi();await nl(e,o,n,r);return}catch(r){_o(r);let o=await be({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((L(o)||o==="exit")&&(q("Operation cancelled"),process.exit(0)),o==="upload"){let s=await vi();await bo(e,s,n);return}}}}async function rl(e){let t=await Oe({message:"Path to Firebase service account JSON:",validate:xo});L(t)&&(q("Operation cancelled"),process.exit(0));let n;try{n=JSON.parse(V.readFileSync(t,"utf8"))}catch(i){q(`Invalid Firebase service account JSON: ${i.message}`),process.exit(1)}await Sn("fcm",{...e,serviceAccount:n})}async function ol(e,t){if(t==="ios"){await il(e);return}await rl(e)}function sl(e,t,n){let i=V.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}`,l=wn.createSign("SHA256");l.update(a);let c=l.sign({key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${c}`}async function al(e,t,n,i){let r=sl(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"}}),g.info(h.dim(` \u2713 Registered: ${s.name}`))}catch(a){let l=a.response?.data?.errors;l?.some(d=>d.code==="ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE"||d.detail?.toLowerCase().includes("already registered")||d.detail?.toLowerCase().includes("already exists"))?g.info(h.dim(` Already on Portal: ${s.name}`)):g.warn(h.yellow(` Could not register ${s.name}: ${l?.[0]?.detail||a.message}`))}}var cl=e=>{let t=String(e||"").trim().toLowerCase();if(t&&(t==="ios"||t==="android"))return t},ll=async e=>{wc(h.bgCyan.black(A.cliTag("Credentials")));let t=cl(e.platform);if(e.platform&&!t){q("Invalid platform. Use `ios` or `android`."),process.exitCode=1;return}let n=t||await be({message:"Select platform:",options:[{value:"ios",label:"iOS"},{value:"android",label:"Android"}]});L(n)&&(q("Operation cancelled"),process.exit(0));let i=await be({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:n==="ios"?"Upload APNs key":"Upload Firebase service account"},{value:"back",label:"Go back"},{value:"exit",label:"Exit"}].filter(r=>(n==="android"&&r.value==="service"&&(r.label="Google Service Account (JSON)"),!0))});if((L(i)||i==="exit")&&(q("Operation cancelled"),process.exit(0)),i==="back")return ll(e);i==="setup"?await dl({...e,platform:n}):i==="download"?await El({...e,platform:n}):i==="service"?await Bi({...e,platform:n}):i==="push"&&await ol(e,n),vc(h.green("Done!"))},dl=async e=>{let t=ct(),n=e.platform,i=`./${A.configFileName}`;if(!V.existsSync(i)){g.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(V.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){g.error(`${A.configFileName} is missing projectId.`);return}let s=Object.keys(r.build||{}),a=u=>{let p=Te(r,u)||{};return n==="android"?Io(r,u)==="store"?"store":"adhoc":kn({buildProfile:u,profile:p})},l=u=>{let p=Te(r,u)||{};return[p.environment?`environment: ${p.environment}`:void 0,p.distribution?`distribution: ${p.distribution}`:void 0,n==="ios"?`signing: ${a(u)}`:void 0].filter(Boolean).join(", ")||"No behavior fields configured"},c=e.profile,d=e.credentialType;if(d&&!Mt(d)){g.error("Credential type must be development, adhoc, or store.");return}if(c&&s.length>0&&!Te(r,c)){g.error(`Build profile '${c}' was not found in ${A.configFileName}.`);return}if(!c&&d){let u=Mt(d),p=s.filter(f=>a(f)===u);if(p.length===1)c=p[0];else if(p.length>1&&process.stdin.isTTY&&process.stdout.isTTY){let f=await be({message:`Select the ${u} build profile:`,options:p.map(m=>({value:m,label:m,hint:l(m)}))});L(f)&&(q("Operation cancelled"),process.exit(0)),c=f}else if(p.length>1){g.error(`More than one profile uses ${u} credentials. Pass --profile with one of: ${p.join(", ")}.`);return}else if(s.length===1)c=s[0];else if(s.length>1){g.error(`No configured profile resolves to ${u}. Pass --profile explicitly.`);return}else c=u}if(!c){let u=s.length>0?s.map(f=>({value:f,label:f,hint:l(f)})):[{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"}],p=await be({message:s.length>0?"Select build profile:":"Select credential type:",options:u});L(p)&&(q("Operation cancelled"),process.exit(0)),c=p,d=s.length>0?a(c):p==="production"?"store":p==="staging"?"adhoc":"development"}if(e.awsProfile&&g.warn(h.yellow(`Ignoring --aws-profile. Authenticating with ${A.name} Cloud...`)),g.info(h.dim(`Setting up credentials for: ${c}`)),n==="ios")await ul(o,c,e,r,d);else{let u=Io(r,c);await vl(o,c,u,e,r)}};async function ul(e,t,n,i,r){let o=n.bundleId;if(!o){let c=i.submit?.[t]?.ios?.bundleIdentifier||i.submit?.[t]?.ios?.bundleId||nt(i,t),d=[];try{let p=(await U.get(`/credentials/${e}`)).data.credentials||[];d=[...new Set(p.filter(f=>f.platform==="ios"&&f.bundleId&&f.bundleId!=="*").map(f=>f.bundleId))]}catch{}if(c&&!d.includes(c)&&d.unshift(c),d.length>0){let u=[...d.map(f=>({value:f,label:f,hint:f===c?"from config":void 0})),{value:"__new__",label:"+ Enter a new Bundle ID"}],p=await be({message:"Which Bundle ID are you setting up credentials for?",options:u});if(L(p)&&(q("Operation cancelled"),process.exit(0)),p==="__new__"){let f=await Oe({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:m=>m.includes(".")?void 0:"Please enter a valid Bundle ID"});L(f)&&(q("Operation cancelled"),process.exit(0)),o=f}else o=p}else{let u=await Oe({message:"iOS Bundle ID (e.g. com.example.app):",placeholder:"com.example.app",validate:p=>p.includes(".")?void 0:"Please enter a valid Bundle ID"});L(u)&&(q("Operation cancelled"),process.exit(0)),o=u}}g.info(h.dim(`Bundle ID: ${o}`));let s=kn({buildProfile:t,profile:Te(i,t)||{},requestedCredentialType:r});g.info(h.dim(`Credential storage type: ${s}`));let a=i.submit?.production?.ios?.appleId;a&&g.info(h.dim(`Using Apple ID from config: ${a}`)),await wl(e,o,t,s,s==="store"?"appstore":s==="adhoc"?"adhoc":"development",n,i,a)}var Ni=e=>le(e.expiresAt)||le(e.expires)||le(e.expirationDate)||le(e.meta?.expiresAt)||le(e.meta?.expires),pl=e=>{let t=Mt(zt(e));return t==="development"?"Development":t==="adhoc"?"Ad Hoc":t==="store"?"App Store":zt(e)||"Unknown signing type"},fl=e=>{let t=e.credential,n=Pn(t)||"all apps",i=pl(t),r=Ni(t);return[e.projectName,i,n,r?`expires ${r}`:void 0].filter(Boolean).join(" \xB7 ")},Qt=e=>e==="development"?"Apple Development":"Apple Distribution",$o=e=>e==="development"?"Development":e==="adhoc"?"Ad Hoc":"App Store",xi=e=>{let t=Ni(e);if(!t)return!1;let n=Date.parse(t);return Number.isFinite(n)&&n<=Date.now()},ml=(e,t,n,i)=>{if(e?.type!=="ios_profile"||e?.platform&&e.platform!=="ios"||!le(e?.s3Key)||xi(e)||Pn(e)!==n||Mt(zt(e))!==(i==="appstore"?"store":i))return!1;let o=Ai(e);return!o||o===t.trim().toUpperCase()},gl=e=>le(e?.certificateSha1)||le(e?.meta?.certificateSha1),hl=e=>{let t=e?.profileCertificateSha1s??e?.meta?.profileCertificateSha1s;return Array.isArray(t)?t.filter(n=>typeof n=="string").map(n=>n.replace(/[^a-fA-F0-9]/g,"").toUpperCase()).filter(Boolean):[]},yl=(e,t)=>{let n=gl(t)?.replace(/[^a-fA-F0-9]/g,"").toUpperCase();return!!n&&hl(e).includes(n)};async function Il(e,t,n,i){let o=(await U.get(`/credentials/${e}`)).data.credentials||[],s=o.filter(l=>Si(l,t,i)&&!xi(l)).map(l=>({projectId:e,projectName:"This project",credential:l,certificateId:bi(l),teamId:t})),a=o.filter(l=>ml(l,t,n,i));return{certificates:s,profiles:a}}async function So(e,t,n){let r=((await U.get("/projects")).data.projects||[]).filter(a=>a.projectId!==n),o=(await Promise.all(r.map(async a=>{if(!a.projectId)return[];try{return((await U.get(`/credentials/${a.projectId}`)).data.credentials||[]).filter(d=>Si(d,e,t)&&!xi(d)).map(d=>({projectId:a.projectId,projectName:a.name||a.slug||a.projectId,credential:d,certificateId:bi(d),teamId:e}))}catch{return[]}}))).flat(),s=new Map;for(let a of o){let l=`${a.projectId}:${a.certificateId||En(a.credential)}`,c=s.get(l);(!c||String(a.credential.createdAt||"")>String(c.credential.createdAt||""))&&s.set(l,a)}return[...s.values()]}var Ei=e=>String(e||"").replace(/[^a-zA-Z0-9]/g,"").toUpperCase();async function Al(e,t,n,i,r,o){let s=await Rn(r,i,o);if(s.length===0)throw new Error(`No active ${Qt(i)} certificates were returned by the Apple Developer Portal.`);let a=Jt(t,n),l=new Set(a.map(p=>p.serial)),c=s.filter(p=>l.has(Ei(p.serial)));if(e.certificateId){let p=s.find(f=>f.id===e.certificateId);if(p&&l.has(Ei(p.serial)))return p.id;if(p&&c.length===1)return g.warn(h.yellow("The saved Apple certificate ID is stale. Mach matched the selected P12 to the active portal certificate by serial number instead.")),c[0].id}if(c.length===1)return g.info(h.dim(`Matched the selected saved P12 to Apple certificate ${c[0].name||c[0].id}.`)),c[0].id;if(c.length===0)throw new Error("The selected .p12 does not contain an active certificate returned by the Apple Developer Portal. Mach will not create a profile with a different certificate; choose another P12 or create a new Apple certificate.");let d=Qt(i);g.warn(h.yellow("The selected P12 contains multiple active Apple certificates. Select the exact certificate to use below."));let u=await be({message:`Which ${d} certificate matches the selected saved P12?`,options:[...c.map(p=>({value:p.id,label:[p.name||`${d} certificate`,p.expires].filter(Boolean).join(" \xB7 "),hint:p.serial?`serial ${p.serial}`:void 0})),{value:"cancel",label:"Cancel"}]});if(!(L(u)||u==="cancel"))return u}async function bl(e,t,n){let i="";for(let o=1;o<=5;o++)try{let s=await U.get(`/credentials/${t}/download`,{params:{projectId:e,format:"proxy"},responseType:"arraybuffer"});V.writeFileSync(n,Buffer.from(s.data));return}catch(s){if(i=s?.response?.data?.message||s?.message||String(s),!To(i)||o>=5)break;let l=Math.min(15e3,1e3*Math.pow(2,o-1));g.warn(h.yellow(`Certificate download was interrupted (${i}). Retrying with a fresh secure link in ${Math.round(l/1e3)}s\u2026 (${o}/5)`)),await Oo(l)}throw new Error(`Could not download the saved Mach certificate after 5 attempts: ${i||"Unknown network error"}`)}async function Sl({targetProjectId:e,targetBundleId:t,targetDistributionType:n,matchType:i,candidate:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c}){let d=await Ro(r.projectId,"ios",r.credential),u=No(d,{})||void 0,p=V.mkdtempSync(Q.join(yt.tmpdir(),`${A.nameLower}-reuse-cert-`)),f=Q.join(p,"selected-signing-certificate.p12"),m=`${A.nameLower} ${i} ${t}`,P=`${A.nameLower}-${i}-${Date.now()}.mobileprovision`;try{g.info(h.dim(`Downloading the selected certificate from ${r.projectName}\u2026`));let v=En(d);if(!v)throw new Error("The selected Mach certificate no longer has a credential ID.");await bl(r.projectId,v,f),g.info(h.dim("Importing the selected certificate into Mach\u2019s team keychain\u2026"));let R=D=>Pe("security",["import",f,"-k",a,"-P",D,"-T","/usr/bin/codesign"],{encoding:"utf-8"}),O,C=await fo({storedPassword:u,tryPassword:D=>(D===""&&u&&g.warn(h.dim("Saved P12 did not unlock with its stored password; trying the legacy empty-password format\u2026")),O=R(D),!O.error&&O.status===0),requestPassword:async()=>{g.warn(h.yellow("This saved P12 is password protected, but Mach does not have its password."));let D=await ht({message:`P12 password for ${r.projectName}'s saved certificate:`,validate:ce=>ce.length>0?void 0:"The certificate password is required"});return L(D)?void 0:D}});if(C.status==="cancelled")return!1;if(C.status==="failed")throw new Error(kt(O?.stdout,O?.stderr)||"Could not import the selected .p12 certificate. Check its password.");let x=C.password,S=Pe("security",["set-key-partition-list","-S","apple-tool:,apple:,codesign:","-s","-k",l,a],{encoding:"utf-8"});if(S.error||S.status!==0)throw new Error(kt(S.stdout,S.stderr)||"Could not grant codesign access to the imported certificate.");let _=await Al(r,f,x,i,s,o.shellCommand);if(!_)return!1;g.info(h.blue(`Creating a new ${$o(i)} profile for ${t}\u2026`));let k=Pe(o.command,mo(i,t,m,_,p,P),{cwd:process.cwd(),env:s,stdio:"inherit"});if(k.error||k.status!==0)throw new Error("Apple could not create the provisioning profile with the selected certificate.");let b=vn(p,/\.mobileprovision$/);if(!b)throw new Error("The new provisioning profile was not produced by fastlane.");let $=Et(b);mn($,{bundleIdentifier:t,teamId:c.teamId,distributionType:n});let j=fn(Jt(f,x),$),N={certificateSha1:j.sha1,certificateSha256:j.sha256,certificateSerial:j.serial,profileCertificateSha1s:$.certificateSha1s,profileCertificateSha256s:$.certificateSha256s},M=Ni(d);return await at(e,f,"ios_cert",t,n,void 0,M,c.teamId,_,x,void 0,void 0,c.teamId,c.teamName,c.developerTeamId||c.teamId,c.appStoreConnectTeamId,c.providerId,c.providerName,N),await at(e,b,"ios_profile",t,n,void 0,void 0,c.teamId,void 0,void 0,void 0,void 0,c.teamId,c.teamName,c.developerTeamId||c.teamId,c.appStoreConnectTeamId,c.providerId,c.providerName,N),g.success(h.green(`\u2713 Reused the saved certificate and created credentials for ${t}.`)),!0}finally{try{V.rmSync(p,{recursive:!0,force:!0})}catch{}}}async function Cn({savedCertificates:e,targetProjectId:t,targetBundleId:n,targetDistributionType:i,matchType:r,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c}){let d=Qt(r),u=await be({message:`Select a saved ${d} certificate to reuse:`,options:[...e.map((f,m)=>({value:String(m),label:fl(f),hint:f.certificateId?`Apple Team ${f.teamId}`:`Apple Team ${f.teamId} \xB7 legacy record; Apple certificate matching may be requested`})),{value:"cancel",label:"Cancel"}]});if(L(u)||u==="cancel")return!1;let p=e[Number(u)];if(!p)throw new Error("The selected saved certificate is no longer available.");return Sl({targetProjectId:t,targetBundleId:n,targetDistributionType:i,matchType:r,candidate:p,fastlane:o,matchEnv:s,keychainPath:a,keychainPassword:l,teamMeta:c})}async function Cl(e){let t="MATCH_ENCRYPTION_PASSPHRASE";try{let s=((await U.get(`/projects/${e}/secrets/export?env=development`)).data.secrets||{})[t];if(s&&!s.includes("[Decryption Failed]"))return g.info(h.dim("Using existing encryption passphrase from Dashboard")),s;if(s&&s.includes("[Decryption Failed]")){g.warn(h.yellow("\u26A0\uFE0F Existing MATCH_PASSWORD could not be decrypted (encryption key changed).")),g.info(h.dim("Generating a fresh passphrase and cleaning old certificates..."));let a=wn.randomBytes(32).toString("base64");try{await U.post(`/projects/${e}/secrets`,{key:t,value:a,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 New encryption passphrase generated and saved"))}catch{}try{await U.post("/credentials/clean-match-storage",{projectId:e}),g.success(h.green("\u2713 Cleaned old certificates from storage"))}catch{}return a}}catch(r){g.info(h.dim(`Could not fetch existing passphrase from Dashboard: ${r.message}`))}let n=await be({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((L(n)||n==="cancel")&&(q("Operation cancelled"),process.exit(0)),n==="enter"){let r=await ht({message:"Enter your MATCH_PASSWORD (encryption passphrase):",validate:s=>s.length>0?void 0:"Passphrase is required"});L(r)&&(q("Operation cancelled"),process.exit(0));let o=r;try{await U.post(`/projects/${e}/secrets`,{key:t,value:o,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)"}),g.success(h.green("\u2713 Saved passphrase to Dashboard"))}catch{}return o}let i=wn.randomBytes(32).toString("base64");try{await U.post(`/projects/${e}/secrets`,{key:t,value:i,type:"managed",description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 Generated and saved encryption passphrase to Dashboard"))}catch(r){g.warn(h.yellow(`Could not save passphrase to Dashboard: ${r.message}`))}return i}async function wl(e,t,n,i,r,o,s,a){let l=ct(),c=!1,d=v=>{l.start(v),c=!0},u=v=>{c&&(l.stop(v),c=!1)};g.info(h.blue("Configuring iOS certificate management..."));let p,f,m=Vt(s,n),P=m;if(!a){let v=await Oe({message:"Apple ID (for Apple Developer Portal):",placeholder:"your-email@example.com",validate:R=>R.includes("@")?void 0:"Please enter a valid email"});L(v)&&(q("Operation cancelled"),process.exit(0)),a=v}try{let v=await Cl(e),R="",O="";try{let N=await U.post("/credentials/build-server-token",{projectId:e});N.data.status==="success"&&N.data.credentials&&(process.env.AWS_ACCESS_KEY_ID=N.data.credentials.accessKeyId,process.env.AWS_SECRET_ACCESS_KEY=N.data.credentials.secretAccessKey,N.data.credentials.sessionToken&&(process.env.AWS_SESSION_TOKEN=N.data.credentials.sessionToken),O=N.data.credentials.region||"ap-south-1",R=N.data.credentials.bucket||A.bucketPrefix,process.env.AWS_REGION=O,delete process.env.AWS_PROFILE)}catch(N){throw g.error(`Failed to authenticate with ${A.name} Cloud.`),N}if(!R||!O){g.error(`Failed to resolve S3 configuration from ${A.name} Cloud.`);return}let C=o.teamId||m.teamId||s.submit?.production?.ios?.appleTeamId;if(!C)try{let M=(await U.get(`/projects/${e}/secrets`)).data.secrets?.find(D=>D.key==="APPLE_TEAM_ID");M&&(C=M.value,g.info(h.dim(`Using Team ID from Dashboard: ${C}`)))}catch{}C&&C===s.submit?.production?.ios?.appleTeamId&&g.info(h.dim(`Using Apple Team ID from config: ${C}`));let x=await Bt({appleId:a,config:s,profile:n,initialTeam:{...m,teamId:C,developerTeamId:m.developerTeamId||C},promptToPersistConfig:!C,saveTeamId:C?void 0:N=>Co(e,N)});if(!x?.teamId)return;C=x.teamId;let S={...m,...x,teamId:C,developerTeamId:x.developerTeamId||m.developerTeamId||C};P=S;let _=xc(e,C);g.info(h.dim(`Using match storage prefix: ${_}`));let k=await Bc(),b={...k.env};process.env.CI||delete b.CI,d(`Preparing ${r} certificate sync...`),u("Starting certificate sync...");let $=`${A.buildPrefix}-${C}-${r}.keychain-db`,j=A.keychainPassword;try{let M=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${$}`;g.info(h.dim(`Ensuring keychain exists: ${$}`));try{Le(`security create-keychain -p ${j} ${$} 2>/dev/null || true`),Le(`security unlock-keychain -p ${j} ${$}`),Le(`security set-keychain-settings ${$}`);let B=Le("security list-keychains -d user").toString();if(!B.includes($)){g.info(h.dim(`Adding ${$} to search list`));let ne=[...B.replace(/"/g,"").split(`
713
+ `).map(Y=>Y.trim()).filter(Y=>Y.length>0),M].join(" ");Le(`security list-keychains -d user -s ${ne}`)}}catch(B){g.warn(h.dim("Keychain setup warning (non-critical): "+B.message))}let D,ce;try{let J=((await U.get(`/credentials/${e}`)).data.credentials||[]).find(ne=>ne.type==="asc_api_key"&&ne.issuerId);if(J){let ne=await U.get(`/credentials/${J.credentialId}/download`,{params:{projectId:e,format:"raw"}});if(ne.data.downloadUrl){let K=await(await import("axios")).default.get(ne.data.downloadUrl,{responseType:"arraybuffer"}),pe=Q.join(yt.tmpdir(),`mach-asc-${Date.now()}`);V.mkdirSync(pe,{recursive:!0}),p=Q.join(pe,`AuthKey_${J.keyId}.p8`),V.writeFileSync(p,Buffer.from(K.data)),D=J.keyId,ce=J.issuerId,g.success(h.green("\u2713 ASC API key loaded \u2014 no 2FA required for Portal operations"))}}}catch(B){g.warn(h.dim(`Could not load ASC API key: ${B.message}. Will fall back to Apple ID auth.`))}g.info(h.dim("Generating secure P12 export password..."));let Se=Fo();g.success(h.green("\u2713 Secure P12 password generated.")),f=V.mkdtempSync(Q.join(yt.tmpdir(),`${A.nameLower}-match-${r}-`));let Z={...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:v,FASTLANE_USER:a,FASTLANE_SKIP_UPDATE_CHECK:"1",FASTLANE_TEAM_ID:C,MATCH_KEYCHAIN_NAME:M,MATCH_KEYCHAIN_PASSWORD:j,TERM:process.env.TERM||"xterm-256color",SHELL:process.env.SHELL||"/bin/zsh",MATCH_OUTPUT_PATH:f,MATCH_STORAGE_MODE:"s3",MATCH_S3_REGION:O,MATCH_S3_BUCKET:R,MATCH_S3_OBJECT_PREFIX:_,MATCH_USERNAME:a,MATCH_APP_IDENTIFIER:t,MATCH_TYPE:r,[`${A.envPrefix}P12_PASSWORD`]:Se,...p&&D&&ce?{APP_STORE_CONNECT_API_KEY_KEY_ID:D,APP_STORE_CONNECT_API_KEY_ISSUER_ID:ce,APP_STORE_CONNECT_API_KEY_KEY_FILEPATH:p,FASTLANE_SKIP_2FA:"1"}:{}};if(o.force){g.warn(h.yellow(`
714
+ \u26A0\uFE0F Force flag detected: Hard resetting ${r} certificates...`)),g.info(h.dim("Detected decryption failure loop. Clearing remote storage directly to allow fresh generation.")),g.info(h.dim(`Cleaning match storage for Team ID: ${C}...`));try{(await U.post("/credentials/clean-match-storage",{projectId:e,teamId:C,storagePrefix:_})).data.status==="success"&&g.success(h.green(`\u2713 Cleared S3 storage for Team ID: ${C}`))}catch(B){g.warn(h.yellow(`S3 cleanup via API failed: ${B.message}`)),g.info(h.dim("Continuing to attempt standard nuke..."))}try{Le(`${k.shellCommand} match nuke ${r} --skip_confirmation`,{stdio:"inherit",cwd:process.cwd(),env:Z}),g.success(h.green(`\u2713 Nuked existing ${r} credentials`))}catch{g.warn(h.yellow("Standard nuke failed (likely due to password mismatch).")),g.info(h.dim("Since S3 was cleared manually, proceeding to generation..."))}}let Ue=r==="adhoc"||r==="development";if(r==="adhoc"||r==="development")try{g.info(h.blue("Fetching registered devices..."));let J=(await U.get("/devices",C?{params:{teamId:C}}:void 0)).data.devices||[];if(C)try{let ne=await U.get("/devices",{params:{teamId:"LEGACY"}}),Y=new Map;for(let K of[...J,...ne.data.devices||[]])Y.set(K.udid,K);J=Array.from(Y.values())}catch{}if(J.length===0)g.warn(h.yellow("No registered devices found. Profile will only include devices already on the Apple Developer Portal.")),g.info(h.dim(`Register devices with: ${A.nameLower} device register`));else{let{multiselect:ne}=await import("@clack/prompts"),Y=await ne({message:`Select devices to include in the ${r} profile:`,options:J.map(K=>({value:K.udid,label:`${K.name} (${K.udid.substring(0,12)}...)`,hint:K.model||K.platform})),initialValues:J.map(K=>K.udid)});if(!L(Y)&&Y.length>0){let K=J.filter(pe=>Y.includes(pe.udid));if(g.info(h.blue(`Registering ${K.length} device(s) on Apple Developer Portal...`)),C&&await Promise.all(K.filter(pe=>!pe.teamId).map(pe=>U.post("/devices",{udid:pe.udid,name:pe.name,platform:"ios",addedVia:pe.addedVia||"cli",teamId:C,teamName:S.teamName}).catch(()=>{}))),p&&D&&ce)await al(K,D,ce,p);else{g.info(h.dim("You will be prompted for a 2FA code once \u2014 type it and press Enter."));for(let pe of K){let et=pe.name.replace(/"/g,'\\"');Pe(`${k.shellCommand} run register_device name:"${et}" udid:"${pe.udid}"`,{shell:!0,env:Z,stdio:"inherit",cwd:process.cwd()})}}g.info(h.green("\u2713 Device registration complete.")),Ue=!0}}}catch(B){g.warn(h.yellow(`Could not fetch registered devices: ${B.message}`)),g.info(h.dim("Continuing without explicit device registration."))}let de=r,F={certificates:[],profiles:[]};try{F=await Il(e,C,t,de)}catch{}let T=Qt(de),G=$o(de),W=F.certificates.some(B=>F.profiles.some(J=>yl(J,B.credential)));if(!o.force&&W){g.success(h.green(`\u2713 Existing ${T} certificate and ${G} profile pair verified in Mach for ${t}.`));let B=await be({message:`What should Mach do with the existing ${G} profile?`,options:[{value:"refresh_profile",label:`Recreate the ${G} profile with the saved certificate`,hint:"Recommended \u2014 refreshes the Apple profile without creating another certificate"},{value:"reuse_profile",label:"Reuse the verified profile unchanged",hint:"Skips Apple Portal changes when the registered devices and entitlements are unchanged"},{value:"sync",label:"Continue with normal certificate sync",hint:"Use only when you need a different signing identity"}],initialValue:"refresh_profile"});if(L(B)){q("Operation cancelled");return}if(B==="reuse_profile"){g.info(h.dim("Reusing the verified certificate and profile pair; no Apple Portal changes were made."));return}if(B==="refresh_profile"){if(await Cn({savedCertificates:F.certificates,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:k,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:S}))return;throw new Error("Provisioning profile refresh was cancelled or could not be completed. No new certificate was requested.")}}if(F.certificates.length>0&&!o.force){F.profiles.length>0&&g.warn(h.yellow("Existing iOS credential records do not prove that the profile was generated with the saved certificate. Mach will safely regenerate the profile from the selected P12."));let B=await be({message:`A saved ${T} certificate already exists in this Mach project.`,options:[{value:"reuse",label:`Create or refresh the ${G} profile with the saved certificate`,hint:"Recommended \u2014 no new Apple certificate is requested"},{value:"sync",label:"Continue with normal certificate sync",hint:"May ask Apple to create another certificate if Match storage is incomplete"}]});if(L(B)){q("Operation cancelled");return}if(B==="reuse"){if(await Cn({savedCertificates:F.certificates,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:k,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:S}))return;throw new Error("Saved certificate reuse was cancelled or could not be completed. No new certificate was requested.")}}let z=[];try{z=await So(C,de,e)}catch{}if(z.length>0){let B=await be({message:`Saved ${T} certificate${z.length===1?"":"s"} found for Apple Team ${C}.`,options:[{value:"reuse",label:"Reuse a saved certificate",hint:`${z.length} compatible certificate${z.length===1?"":"s"} found \u2014 no new Apple certificate is requested`},{value:"sync",label:"Continue with normal certificate sync",hint:"Use this only when you need a different signing identity"}]});if(L(B)){q("Operation cancelled");return}if(B==="reuse"){if(await Cn({savedCertificates:z,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:k,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:S}))return;throw new Error("Saved certificate reuse was cancelled or could not be completed. No new certificate was requested.")}}try{let B=`${A.nameLower} ${r} ${t}`,J=$c(k.shellCommand,r,t,B,Ue);Ue&&g.info(h.dim(`Refreshing ${r} provisioning profile when device list changes (--force_for_new_devices).`));let ne=Pe(J,{shell:!0,cwd:process.cwd(),env:Z,stdio:"inherit",encoding:"utf-8"});if(ne.status!==0){g.warn(h.yellow(`
715
+ Certificate sync failed. Attempting to create App ID and retry...`));try{Le(`${k.shellCommand} produce --app_identifier "${t}" --app_name "${t}" --skip_itc`,{stdio:"inherit",env:Z}),g.success(h.green("\u2713 App ID created successfully")),g.info(h.blue("Retrying certificate sync...")),ne=Pe(J,{shell:!0,cwd:process.cwd(),env:Z,stdio:"inherit",encoding:"utf-8"})}catch{}if(ne.status!==0)throw new Error("fastlane match failed")}}catch(B){let J=Qt(de);if(g.warn(h.yellow(`
716
+ Certificate sync failed. This can be caused by an incorrect encryption passphrase, an expired Apple session, or the ${J} certificate limit.`)),z.length===0)try{z=await So(C,de,e)}catch{}let ne=await be({message:"What would you like to do?",options:[...z.length>0?[{value:"reuse_saved",label:"Reuse a saved Mach certificate",hint:`${z.length} compatible certificate${z.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(L(ne)||ne==="cancel")throw B;if(ne==="reuse_saved"){if(await Cn({savedCertificates:z,targetProjectId:e,targetBundleId:t,targetDistributionType:i,matchType:de,fastlane:k,matchEnv:Z,keychainPath:M,keychainPassword:j,teamMeta:S}))return;throw B}else if(ne==="retry_password"){g.info(h.dim(`
717
+ You are overriding the dashboard passphrase for this session.`));let Y=await ht({message:"Enter the correct MATCH_PASSWORD for this project:"});if(Y&&!L(Y)){v=Y,g.info(h.blue("Retrying with provided passphrase..."));let K={...Z,MATCH_PASSWORD:v};if(Pe(`${k.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:K}).status===0)await U.post(`/projects/${e}/secrets`,{key:"MATCH_ENCRYPTION_PASSPHRASE",value:v,description:"Encryption passphrase for iOS certificates (fastlane match)",visibility:"secret"}),g.success(h.green("\u2713 Dashboard passphrase updated."));else throw new Error("Sync failed again with provided passphrase.")}else throw B}else if(ne==="check_portal")try{let Y=await Rn(Z,r,k.shellCommand);if(Y.length>0){if(g.info(h.dim(`Found ${Y.length} existing ${r} certificates on the portal.`)),await Rl(r,Z,e,k.shellCommand,Y)&&(g.info(h.blue("Retrying certificate sync...")),Pe(`${k.shellCommand} match ${r}`,{shell:!0,stdio:"inherit",cwd:process.cwd(),env:Z}).status!==0))throw new Error("Retry failed")}else throw g.error(h.red("No existing certificates found on portal to resolve.")),B}catch(Y){throw g.warn(h.dim(`Portal check warning: ${Y.message}`)),B}else throw B}g.success(h.green("\u2713 Certificates fetched and synced"));let se=f,X=Q.join(se,`${A.fastlanePrefix}_export.p12`),ue=vn(se,/\.mobileprovision$/);try{let J=`${process.env.HOME||"/Users/"+(process.env.USER||A.nameLower)}/Library/Keychains/${$}`;V.existsSync(se)||V.mkdirSync(se,{recursive:!0}),g.info(h.dim("Exporting certificate from keychain for dashboard upload..."));let ne=Le(`security find-identity -v -p codesigning "${J}"`,{encoding:"utf-8"});g.info(h.dim(`Identities in keychain:
718
+ ${ne.trim()}`));let Y=Pe("security",["export","-k",J,"-t","identities","-f","pkcs12","-o",X,"-P",Se],{encoding:"utf-8"});if(Y.error||Y.status!==0)throw new Error(kt(Y.stdout,Y.stderr)||"security could not export the signing certificate.");try{let K=Pe("openssl",["pkcs12","-in",X,"-nokeys","-passin",`pass:${Se}`,"-legacy"],{encoding:"utf-8"});if((K.error||K.status!==0)&&(K=Pe("openssl",["pkcs12","-in",X,"-nokeys","-passin",`pass:${Se}`],{encoding:"utf-8"})),K.error||K.status!==0)throw new Error(kt(K.stdout,K.stderr)||"openssl could not read the exported P12.");let pe=K.stdout||"";if(!pe.includes(C))throw new Error(`Exported P12 does not contain identity for team ${C}. Found: ${pe.substring(0,200)}`);g.success(h.green(`\u2713 P12 verified \u2014 contains correct team identity (${C})`))}catch(K){throw new Error(`P12 verification failed: ${K.message}`)}}catch{g.warn(h.dim("Could not export certificate from keychain."))}o.teamId&&!C&&await Co(e,o.teamId);let Ie=V.existsSync(X)?X:vn(se,/\.p12$/);if(Ie&&ue){let B,J,ne,Y;try{Y=Et(ue),mn(Y,{bundleIdentifier:t,teamId:S.teamId||o.teamId||C,distributionType:i}),ne=fn(Jt(Ie,Se),Y),g.success(h.green(`\u2713 Provisioning profile verified against signing certificate (${ne.sha1.slice(0,12)}\u2026).`))}catch(pe){throw new Error(`Refusing to upload an iOS certificate/profile mismatch: ${pe.message}`)}let K={certificateSha1:ne.sha1,certificateSha256:ne.sha256,certificateSerial:ne.serial,profileCertificateSha1s:Y.certificateSha1s,profileCertificateSha256s:Y.certificateSha256s};try{let et=(await Rn(Z,r,k.shellCommand)).find(Re=>Ei(Re.serial)===ne.serial);et?(B=et.expires,J=et.id):g.warn(h.yellow("The matching certificate could not be identified on the Apple portal, so Mach will save the verified fingerprint without a portal ID."))}catch{g.warn(h.dim("Could not fetch expiration date or ID for dashboard record."))}await at(e,Ie,"ios_cert",t,i,void 0,B,o.teamId||C,J,Se,void 0,void 0,S.teamId,S.teamName,S.developerTeamId,S.appStoreConnectTeamId,S.providerId,S.providerName,K),await at(e,ue,"ios_profile",t,i,void 0,B,o.teamId||C,void 0,void 0,void 0,void 0,S.teamId,S.teamName,S.developerTeamId,S.appStoreConnectTeamId,S.providerId,S.providerName,K),g.success(h.green("\u2713 Both iOS certificate and provisioning profile uploaded successfully"))}else g.warn(h.yellow("Certificates generated but not found in expected location.")),g.info(h.dim("Falling back to manual upload...")),await wo(e,t,i,P)}catch(N){u("Certificate fetch failed"),g.error(h.red(`Error: ${N.message}`)),g.info(h.dim("Falling back to manual upload...")),await wo(e,t,i,P)}}catch(v){u("iOS setup failed"),g.error(h.red(`Error: ${v.message}`))}finally{if(p)try{V.rmSync(Q.dirname(p),{recursive:!0,force:!0})}catch{}if(f)try{V.rmSync(f,{recursive:!0,force:!0})}catch{}}}async function Co(e,t){try{await U.post(`/projects/${e}/secrets`,{key:"APPLE_TEAM_ID",value:t,description:"Apple Developer Team ID (used for iOS signing)"}),g.success(h.green(`\u2713 Saved Team ID ${t} to Dashboard`))}catch(n){g.warn(h.yellow(`Could not save Team ID to Dashboard: ${n.message}`))}}async function wo(e,t,n,i={}){g.info(h.yellow(`
719
+ Manual Upload Mode`)),g.info("Please provide your certificate and provisioning profile:");let r=await Oe({message:"Path to .p12 certificate file:",validate:f=>V.existsSync(f)?void 0:"File not found"});L(r)&&(q("Operation cancelled"),process.exit(0));let o=await Oe({message:"Path to .mobileprovision file:",validate:f=>V.existsSync(f)?void 0:"File not found"});L(o)&&(q("Operation cancelled"),process.exit(0));let s=await ht({message:"P12 password (leave empty only when the certificate has no password):"});L(s)&&(q("Operation cancelled"),process.exit(0));let a=r,l=o,c,d;try{d=Et(l),mn(d,{bundleIdentifier:t,teamId:i.teamId,distributionType:n}),c=fn(Jt(a,s),d)}catch(f){throw new Error(`The selected .p12 and .mobileprovision do not form a valid signing pair: ${f.message}`)}let u={certificateSha1:c.sha1,certificateSha256:c.sha256,certificateSerial:c.serial,profileCertificateSha1s:d.certificateSha1s,profileCertificateSha256s:d.certificateSha256s},p=ct();p.start(`Uploading to ${A.name} Dashboard...`);try{await at(e,a,"ios_cert",t,n,s,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,u),await at(e,l,"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,u),p.stop("Upload complete"),g.success(h.green("\u2713 iOS credentials uploaded successfully"))}catch(f){throw p.stop("Upload failed"),f}}async function vl(e,t,n,i,r){let o=ct();g.step(h.blue("Android Credential Setup"));let s=i.bundleId;if(!s){let u=bt(r,t),p=[];try{let m=(await U.get(`/credentials/${e}`)).data.credentials||[];p=[...new Set(m.filter(P=>P.platform==="android"&&P.bundleId&&P.bundleId!=="*").map(P=>P.bundleId))]}catch{}if(u&&!p.includes(u)&&p.unshift(u),p.length>0){let f=[...p.map(P=>({value:P,label:P,hint:P===u?"from config":void 0})),{value:"__new__",label:"+ Enter a new Package Name"}],m=await be({message:"Which Package Name are you setting up credentials for?",options:f});if(L(m)&&(q("Operation cancelled"),process.exit(0)),m==="__new__"){let P=await Oe({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:v=>v.includes(".")?void 0:"Please enter a valid package name"});L(P)&&(q("Operation cancelled"),process.exit(0)),s=P}else s=m}else{let f=await Oe({message:"Android Package Name (e.g. com.example.app):",placeholder:"com.example.app",validate:m=>m.includes(".")?void 0:"Please enter a valid package name"});L(f)&&(q("Operation cancelled"),process.exit(0)),s=f}}try{let f=((await U.get(`/credentials/${e}`)).data.credentials||[]).find(m=>m.platform==="android"&&m.distributionType===n&&m.bundleId===s);if(f){g.warn(h.yellow(`\u26A0\uFE0F Existing Android credentials found for ${n}`));let m=await Oe({message:"What would you like to do? (use/new/cancel)",validate:P=>{let v=P.toLowerCase();if(!(v==="use"||v==="new"||v==="cancel"))return"Please type: use, new, or cancel"}});if(L(m)||m.toLowerCase()==="cancel")return;if(m.toLowerCase()==="use"){g.success(h.green("\u2713 Using existing credentials."));return}await U.delete(`/credentials/${f.credentialId}?projectId=${e}`)}}catch{}let a="./android/app/my-release-key.jks";if(V.existsSync(a)){let u=await Pi({message:"Upload existing keystore?"});if(u&&!L(u)){let p=await Oe({message:"Key alias:",initialValue:"my-key-alias"});if(L(p))return;let f=await ht({message:"Keystore password:"});if(L(f))return;let m=await ht({message:"Key password (leave blank if same as keystore password):"});if(L(m))return;let P=m.trim()||f;await at(e,a,"android_keystore",s,n,p,void 0,void 0,void 0,void 0,f,P),g.success(h.green("\u2713 Keystore uploaded"));return}}g.info(h.blue("Generating new Android keystore..."));let l=i.keyAlias||`${A.nameLower}-${Pl()}`,c=Fo(),d=`./${A.nameLower}-${t}.jks`;V.existsSync(d)&&V.unlinkSync(d),o.start("Generating keystore...");try{let u=c.replace(/'/g,"'\\''");Le(`keytool -genkeypair -v -keystore "${d}" -alias "${l}" -keyalg RSA -keysize 2048 -validity 10000 -storepass '${u}' -keypass '${u}' -dname "CN=${A.name} Build, OU=Mobile, O=Company, L=City, S=State, C=US"`,{stdio:"inherit"}),o.stop("Keystore generated"),await at(e,d,"android_keystore",s,n,l,void 0,void 0,void 0,void 0,c,c),g.success(h.green("\u2713 Android credentials uploaded successfully")),g.info(h.cyan(`Key Alias: ${l}`))}catch(u){throw o.stop("Generation failed"),new Error(`Keystore generation failed: ${u.message}`)}}var Oo=e=>new Promise(t=>setTimeout(t,e));function To(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 at(e,t,n,i,r,o,s,a,l,c,d,u,p,f,m,P,v,R,O){let C=Q.basename(t);g.info(h.dim(`Uploading ${C} (Isolated process)...`));let x=new URL(import.meta.url),S=Q.dirname(x.pathname),k=[Q.join(S,"commands","isolated-upload.js"),e,t,n,i,r,o||"undefined",s||"undefined",a||"undefined",l||"undefined",c||"undefined",d||"undefined",u||"undefined",p||"undefined",f||"undefined",m||"undefined",P||"undefined",v||"undefined",R||"undefined",O?JSON.stringify(O):"undefined"],b="",$=5;for(let j=1;j<=$;j++){let N=Pe("node",k,{stdio:"pipe",encoding:"utf-8",env:{...process.env,AT_CLI_ISOLATED:"1"}});if(N.status===0&&N.stdout.includes("SUCCESS")){g.info(h.dim(`\u2713 ${C} uploaded and registered.`));return}if(N.status===0){g.warn(h.yellow(`Isolated upload finished but success not confirmed: ${N.stdout}`));return}if(b=(N.stderr||N.stdout||N.error?.message||"Unknown isolated upload failure").trim(),!To(b)||j>=$)throw g.error(h.red(`Isolated Upload Failed: ${b}`)),new Error(b);let D=Math.min(3e4,1500*Math.pow(2,j-1));g.warn(h.yellow(`Upload failed with a transient error. Retrying ${C} in ${Math.round(D/1e3)}s... (${j}/${$})`)),await Oo(D)}throw new Error(b||"Unknown isolated upload failure")}async function El(e){let t=ct(),n=e.platform,i=`./${A.configFileName}`;if(!V.existsSync(i)){g.error(`No ${A.configFileName} found. Run \`${A.nameLower} init\` or \`${A.nameLower} link\` first.`);return}let r=JSON.parse(V.readFileSync(i,"utf-8")),{projectId:o}=r;if(!o){g.error(`${A.configFileName} is missing projectId.`);return}try{t.start("Fetching project secrets...");let a=(await U.get(`/projects/${o}/secrets/export?env=all`)).data.secrets||{};t.stop("Secrets fetched and merged."),t.start("Fetching credentials...");let c=(await U.get(`/credentials/${o}`)).data.credentials||[];t.stop(`Found ${c.length} metadata records.`);let d=c.filter(m=>m.platform===n);if(d.length===0){g.info(`No ${n} credentials found on Dashboard.`);return}let u="./credentials.json",p={};if(V.existsSync(u))try{p=JSON.parse(V.readFileSync(u,"utf-8"))}catch{g.warn("Could not parse existing credentials.json, creating a new one.")}p[n]||(p[n]={});let f=Q.join(process.cwd(),"credentials",n);V.existsSync(f)||V.mkdirSync(f,{recursive:!0});for(let m of d){t.start(`Downloading ${m.type} (${m.distributionType})...`);try{let P=await U.get(`/credentials/${m.credentialId}/download`,{params:{projectId:o,format:"raw"}});if(P.data.status==="success"&&P.data.downloadUrl){let v=Q.join(process.cwd(),"credentials",n,m.distributionType);V.existsSync(v)||V.mkdirSync(v,{recursive:!0});let R=m.s3Key?.split(".").pop()||(m.type.includes("keystore")?"jks":m.type.includes("cert")?"p12":"mobileprovision"),O=`${m.type}.${R}`,C=Q.join(v,O),x=await vo.get(P.data.downloadUrl,{responseType:"arraybuffer"});V.writeFileSync(C,Buffer.from(x.data));let S=Q.join("credentials",n,m.distributionType,O),_="",k="",b={alias:"",keystorePassword:"",keyPassword:""};if(n==="ios"&&m.type==="ios_cert"||n==="android"&&m.type==="android_keystore"){let $=await Ro(o,n,m);if(n==="ios"&&m.type==="ios_cert"&&R.toLowerCase()==="p12"){if(_=No($,a),_){let j=yo(C,`${Q.basename(C,Q.extname(C))}-password.txt`,_);k=Q.join("credentials",n,m.distributionType,Q.basename(j))}}else if(n==="android"&&m.type==="android_keystore"&&(b=Uc($,a),b.keystorePassword||b.keyPassword)){let j=[b.alias?`keyAlias=${b.alias}`:void 0,b.keystorePassword?`keystorePassword=${b.keystorePassword}`:void 0,b.keyPassword?`keyPassword=${b.keyPassword}`:void 0].filter(Boolean).join(`
720
+ `),N=yo(C,`${Q.basename(C,Q.extname(C))}-passwords.txt`,j);k=Q.join("credentials",n,m.distributionType,Q.basename(N))}}if(n==="android")m.type==="android_keystore"&&(p.android.keystore={keystorePath:S,keystorePassword:b.keystorePassword,keyAlias:b.alias,keyPassword:b.keyPassword},k&&(p.android.keystore.keystoreArchivePath=k));else if(n==="ios"){let $=m.distributionType==="store"?"production":m.distributionType==="adhoc"?"staging":"development";p.ios[$]||(p.ios[$]={}),m.type==="ios_cert"?(p.ios[$].certificatePath=S,p.ios[$].certificatePassword=_,k&&(p.ios[$].certificateArchivePath=k)):m.type==="ios_profile"&&(p.ios[$].provisioningProfilePath=S)}t.stop(`\u2713 ${m.type} (${m.distributionType}) saved${k?" with password archive":""}.`)}}catch(P){let v=P.response?.data?.message||P.message;t.stop(h.dim(`- Skipped ${m.type} (${m.distributionType}): ${v}`))}}V.writeFileSync(u,JSON.stringify(p,null,2)),g.success(h.green("\u2713 Local credentials.json updated.")),Ec("Credentials have been synced to your local machine. Ensure credentials.json and credentials/ is added to your .gitignore.","Sync Complete")}catch(s){t.stop(h.red("Sync failed.")),g.error(`Error: ${s.message}`)}}function Fo(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_+=",t="";for(let n=0;n<24;n++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}function Pl(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 Rl(e,t,n,i,r){let o=r||await Rn(t,e,i);if(!o||o.length===0)return!1;let s=await be({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 L(s)||s==="cancel"?!1:s==="nuke"?(Le(`${i} match nuke ${e}`,{stdio:"inherit",cwd:process.cwd(),env:t}),!0):typeof s=="string"&&s.startsWith("revoke:")?(await Nl(t,s.split(":")[1],i),!0):!1}async function Rn(e,t,n){let i=t==="development"?"development":"distribution",r=`
636
721
  lane :${A.fastlanePrefix}_list_certs do
637
722
  require 'spaceship'
638
723
  require 'json'
@@ -667,7 +752,7 @@ lane :${A.fastlanePrefix}_list_certs do
667
752
  $stderr.puts "ERROR: #{e.message}"
668
753
  exit 1
669
754
  end
670
- end`,o=Q.join(yt.tmpdir(),`/tmp/${A.nameLower}-list-certs-${Date.now()}`),s=Q.join(o,"fastlane"),a=Q.join(s,"Fastfile");try{B.existsSync(s)||B.mkdirSync(s,{recursive:!0}),B.writeFileSync(a,r);let c=je(`${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 c?JSON.parse(c[1]):[]}finally{B.existsSync(o)&&B.rmSync(o,{recursive:!0,force:!0})}}async function El(e,t,n){let i=`
755
+ end`,o=Q.join(yt.tmpdir(),`/tmp/${A.nameLower}-list-certs-${Date.now()}`),s=Q.join(o,"fastlane"),a=Q.join(s,"Fastfile");try{V.existsSync(s)||V.mkdirSync(s,{recursive:!0}),V.writeFileSync(a,r);let c=Le(`${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 c?JSON.parse(c[1]):[]}finally{V.existsSync(o)&&V.rmSync(o,{recursive:!0,force:!0})}}async function Nl(e,t,n){let i=`
671
756
  lane :${A.fastlanePrefix}_revoke_cert do
672
757
  require 'spaceship'
673
758
  begin
@@ -679,4 +764,4 @@ lane :${A.fastlanePrefix}_revoke_cert do
679
764
  $stderr.puts "ERROR: #{e.message}"
680
765
  exit 1
681
766
  end
682
- end`,r=Q.join(yt.tmpdir(),`/tmp/${A.nameLower}-revoke-cert-${Date.now()}`),o=Q.join(r,"fastlane"),s=Q.join(o,"Fastfile");try{B.existsSync(o)||B.mkdirSync(o,{recursive:!0}),B.writeFileSync(s,i),je(`${n} ${A.fastlanePrefix}_revoke_cert`,{env:{...e,CI:"1",FASTLANE_FASTFILE:s},cwd:r,stdio:["inherit","pipe","inherit"]})}finally{B.existsSync(r)&&B.rmSync(r,{recursive:!0,force:!0})}}export{Nl as a,Vo as b,_n as c,Bt as d,Ti as e,Fe as f,Ge as g,bt as h,nt as i,kl as j,md as k,gd as l,hd as m,yd as n,Ki as o,Id as p,on as q,zi as r,sn as s,kd as t,$s as u,_d as v,$d as w,Fs as x,Xn as y,Td as z,Fd as A,Gt as B,an as C,er as D,tr as E,Xd as F,Kd as G,Jd as H,Yd as I,pu as J,fu as K,la as L,ze as M,mu as N,Au as O,gr as P,hr as Q,bu as R,Eu as S,Pu as T,Et as U,Jt as V,fn as W,sp as X,xt as Y,Vi as Z,hi as _,wp as $,Cp as aa,Sn as ba,vp as ca,Ep as da,ho as ea,sl as fa,al as ga,wl as ha};
767
+ end`,r=Q.join(yt.tmpdir(),`/tmp/${A.nameLower}-revoke-cert-${Date.now()}`),o=Q.join(r,"fastlane"),s=Q.join(o,"Fastfile");try{V.existsSync(o)||V.mkdirSync(o,{recursive:!0}),V.writeFileSync(s,i),Le(`${n} ${A.fastlanePrefix}_revoke_cert`,{env:{...e,CI:"1",FASTLANE_FASTFILE:s},cwd:r,stdio:["inherit","pipe","inherit"]})}finally{V.existsSync(r)&&V.rmSync(r,{recursive:!0,force:!0})}}export{$l as a,Lo as b,_n as c,Vt as d,Oi as e,Te as f,Ge as g,bt as h,nt as i,Ol as j,yd as k,Id as l,Ad as m,bd as n,Ki as o,Sd as p,on as q,zi as r,sn as s,Od as t,Ts as u,Td as v,Fd as w,Ds as x,Xn as y,Dd as z,Md as A,Gt as B,an as C,er as D,lr as E,tr as F,Yd as G,zd as H,Qd as I,qd as J,hu as K,yu as L,ua as M,ze as N,Iu as O,wu as P,yr as Q,Ir as R,vu as S,xu as T,ku as U,Et as V,Jt as W,fn as X,up as Y,Nt as Z,Bi as _,hi as $,Rp as aa,Np as ba,Sn as ca,xp as da,kp as ea,Io as fa,cl as ga,ll as ha,dl as ia,El as ja};