@autofleet/cli 2.33.1 → 2.33.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.
package/dist/e2e.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{S as e,c as t,i as n,l as r,n as i,w as a}from"./utils-BM4JK9OB.js";import o from"node:path";import s from"p-retry";const c=[`identity-ms`,`vehicle-ms`,`ride-ms`,`vehicle-live-data-ms`,`pricing-ms`,`payment-ms`,`route-plan-ms`,`task-ms`,`audit-ms`,`pgweb`,`placement-ms`,`demand-prediction-ms`,`control-center-ms`,`setting-ms`,`api-gateway-ms`],l={start:`--e2eBranch=<branchName> --branches="{\\"ride-ms\\": \\"AUT-7070\\"}"`,getIpsForEnv:`--variationId=<yourVariationUuid> --cluster=<dev1/e2eManager>`},u=e=>Object.keys(l).includes(e),{positionals:d,values:f,help:p}=a({strict:!0,binName:`autofleet-e2e`,allowPositionals:!0,options:{e2eBranch:{type:`string`,default:`master`,description:`Name of e2e branch`},branches:{type:`string`,default:``,description:`"ride-ms": "AUT-7070"`},cluster:{type:`string`,short:`c`,description:`The cluster name. One of dev1, e2eManager, expManager`},variationId:{type:`string`,short:`i`,description:`The variation id`}},commands:l});d.length||(console.log(p),process.exit(0));const[m]=d;if(u(m)||n(Error(`Command ${m} does not exist`),p),m===`start`){let t=(f.branches?.replace(`{`,` `)||``).replace(/[^a-z0-9]/gi,``),n=`${o.resolve()}/bin/utils/e2e.sh`,i=`${o.resolve()}/e2e.sh`;r({newFilePath:i,filePath:n,linesToReplace:[{find:`$E2E_BRANCH_PLACE_HOLDER$`,replace:f.e2eBranch},{find:`$BRANCHES_PLACE_HOLDER$`,replace:f.branches},{find:`$NAME_PLACE_HOLDER$`,replace:t}]}),await e(`chmod`,[`+x ${i} && ${i}`]),console.log(`finished e2e`)}const{cluster:h,variationId:g}=f;h||n(Error(`cluster required`),p),g||n(Error(`variationId required`),p);let _;try{_=await i({clusterName:h,variationId:g})}catch(e){n(e)}m===`getIpsForEnv`&&(await Promise.all(c.map(t=>e(`kubectl`,[`annotate`,_,`service`,t,`cloud.google.com/load-balancer-type-`],{print:!1}))),await Promise.all(c.map(t=>e(`kubectl`,[`patch`,`svc`,_,t,`-p`,`{"spec": {"type": "LoadBalancer"}}`],{print:!1}))),console.log(`exposed services successfully. the services are now creating public ips.`),await s(async()=>{let{stdout:n}=await e(`kubectl`,[_,`get`,`services`],{print:!1}),r=t(n);if(r.some(e=>e.includes(`<pending>`)))throw Error(`Some services are still pending`);r.forEach(e=>console.log(e))},{retries:10,factor:1,maxTimeout:5e3,randomize:!0}),process.exit(0));export{};
2
+ import{S as e,c as t,i as n,l as r,n as i,w as a}from"./utils-BWVzszbR.js";import o from"node:path";import s from"p-retry";const c=[`identity-ms`,`vehicle-ms`,`ride-ms`,`vehicle-live-data-ms`,`pricing-ms`,`payment-ms`,`route-plan-ms`,`task-ms`,`audit-ms`,`pgweb`,`placement-ms`,`demand-prediction-ms`,`control-center-ms`,`setting-ms`,`api-gateway-ms`],l={start:`--e2eBranch=<branchName> --branches="{\\"ride-ms\\": \\"AUT-7070\\"}"`,getIpsForEnv:`--variationId=<yourVariationUuid> --cluster=<dev1/e2eManager>`},u=e=>Object.keys(l).includes(e),{positionals:d,values:f,help:p}=a({strict:!0,binName:`autofleet-e2e`,allowPositionals:!0,options:{e2eBranch:{type:`string`,default:`master`,description:`Name of e2e branch`},branches:{type:`string`,default:``,description:`"ride-ms": "AUT-7070"`},cluster:{type:`string`,short:`c`,description:`The cluster name. One of dev1, e2eManager, expManager`},variationId:{type:`string`,short:`i`,description:`The variation id`}},commands:l});d.length||(console.log(p),process.exit(0));const[m]=d;if(u(m)||n(Error(`Command ${m} does not exist`),p),m===`start`){let t=(f.branches?.replace(`{`,` `)||``).replace(/[^a-z0-9]/gi,``),n=`${o.resolve()}/bin/utils/e2e.sh`,i=`${o.resolve()}/e2e.sh`;r({newFilePath:i,filePath:n,linesToReplace:[{find:`$E2E_BRANCH_PLACE_HOLDER$`,replace:f.e2eBranch},{find:`$BRANCHES_PLACE_HOLDER$`,replace:f.branches},{find:`$NAME_PLACE_HOLDER$`,replace:t}]}),await e(`chmod`,[`+x ${i} && ${i}`]),console.log(`finished e2e`)}const{cluster:h,variationId:g}=f;h||n(Error(`cluster required`),p),g||n(Error(`variationId required`),p);let _;try{_=await i({clusterName:h,variationId:g})}catch(e){n(e)}m===`getIpsForEnv`&&(await Promise.all(c.map(t=>e(`kubectl`,[`annotate`,_,`service`,t,`cloud.google.com/load-balancer-type-`],{print:!1}))),await Promise.all(c.map(t=>e(`kubectl`,[`patch`,`svc`,_,t,`-p`,`{"spec": {"type": "LoadBalancer"}}`],{print:!1}))),console.log(`exposed services successfully. the services are now creating public ips.`),await s(async()=>{let{stdout:n}=await e(`kubectl`,[_,`get`,`services`],{print:!1}),r=t(n);if(r.some(e=>e.includes(`<pending>`)))throw Error(`Some services are still pending`);r.forEach(e=>console.log(e))},{retries:10,factor:1,maxTimeout:5e3,randomize:!0}),process.exit(0));export{};
3
3
  //# sourceMappingURL=e2e.js.map
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import{S as e,_ as t,g as n,h as r,i,m as a,v as o,w as s,y as c}from"./utils-BM4JK9OB.js";import{basename as l,sep as u}from"node:path";import{readdir as d}from"node:fs/promises";import{randomUUID as f}from"node:crypto";const p=[`premajor`,`preminor`,`prepatch`,`prerelease`],m=[`major`,`minor`,`patch`,...p],h={bumpVersion:`[${m.join(`|`)}]`,openPR:`Opens github UI for creating a PR from the current branch.`,releaseBeta:`Bumps version if needed, and publishes a beta release to NPM registry.`},g=e=>Object.keys(h).includes(e),_=async({versionType:t,packageName:n,preReleaseId:r=``})=>{let{stdout:i}=await e(`npm`,[`version`,t,`--no-git-tag-version`,`--preid`,r],{print:!1,cwd:n?`.${u}packages${u}${n}`:void 0});return await e(`git`,[`add`,`package*`],{print:!1}),await e(`git`,[`commit`,`-m`,`${t} version: ${i}`],{print:!1}),console.log(`Created commit for version bump: ${t}. Version is now ${i}`),i},v=async e=>{let t=await c(),{default:{version:n}}=await import(`${e?`${t}${u}packages${u}${e}`:t}${u}package.json`,{with:{type:`json`}});return n.replace(/\d+\.\d+\.\d+(?:-beta-([\w]+)?\.\d+)?/,`$1`)},{positionals:y,help:b}=s({strict:!0,binName:`git autofleet`,allowPositionals:!0,options:{},commands:h});y.length||(console.log(b),process.exit(0));const[x,S,C]=y;if(g(x)||i(Error(`Command ${x} does not exist`),b),x===`openPR`){let[t,n]=await Promise.all([c(),o()]);await e(`open`,[`https://github.com/Autofleet/${l(t)}/compare/${n}?expand=1`],{print:!1}),process.exit(0)}async function w(){let e=await c();return e.split(u).pop()===`autorepo`?e:!1}async function T({message:e,pathIfAutorepo:t}){t??=await w();let r=C;if(t){let a=(await d(`${t}${u}packages`)).filter(e=>!e.startsWith(`.`));r?a.includes(r)||i(Error(`Package name ${r} does not exist in autorepo packages`),b):r=await n({message:e,choices:a.map(e=>({name:e,value:e}))}),r||i(Error(`No package name provided, exiting...`),b)}return r}if(x===`bumpVersion`){let e=await T({message:`Which package do you want to bump?`}),t=S||await n({message:`Which version type do you want to bump?`,choices:(x===`bumpVersion`?m:p).map(e=>({name:e,value:e}))});t||i(Error(`Must explicitly define version type.\n\tVersion type can be one of: ${m.join(`, `)}`),b);let r=await o();[`main`,`master`].includes(r)&&(await a(`Are you sure you want to bump version on main branch?`)||process.exit(0)),await _({versionType:t,packageName:e}),process.exit(0)}if(x===`releaseBeta`){let n=await w(),s=await T({message:`Which package do you want to release?`,pathIfAutorepo:n});S&&!p.includes(S)&&i(Error(`Invalid version type: ${S}\n\tVersion must be a prerelease type. (${p.join(`, `)})`),b);let c=await o();[`main`,`master`].includes(c)&&i(Error(`Cannot release beta from main branch`),b);let l=s?`.${u}packages${u}${s}`:void 0,d=!(await t(s?`.${u}packages${u}${s}${u}package.json`:`package.json`)).split(`
2
+ import{S as e,_ as t,g as n,h as r,i,m as a,v as o,w as s,y as c}from"./utils-BWVzszbR.js";import{basename as l,sep as u}from"node:path";import{readdir as d}from"node:fs/promises";import{randomUUID as f}from"node:crypto";const p=[`premajor`,`preminor`,`prepatch`,`prerelease`],m=[`major`,`minor`,`patch`,...p],h={bumpVersion:`[${m.join(`|`)}]`,openPR:`Opens github UI for creating a PR from the current branch.`,releaseBeta:`Bumps version if needed, and publishes a beta release to NPM registry.`},g=e=>Object.keys(h).includes(e),_=async({versionType:t,packageName:n,preReleaseId:r=``})=>{let{stdout:i}=await e(`npm`,[`version`,t,`--no-git-tag-version`,`--preid`,r],{print:!1,cwd:n?`.${u}packages${u}${n}`:void 0});return await e(`git`,[`add`,`package*`],{print:!1}),await e(`git`,[`commit`,`-m`,`${t} version: ${i}`],{print:!1}),console.log(`Created commit for version bump: ${t}. Version is now ${i}`),i},v=async e=>{let t=await c(),{default:{version:n}}=await import(`${e?`${t}${u}packages${u}${e}`:t}${u}package.json`,{with:{type:`json`}});return n.replace(/\d+\.\d+\.\d+(?:-beta-([\w]+)?\.\d+)?/,`$1`)},{positionals:y,help:b}=s({strict:!0,binName:`git autofleet`,allowPositionals:!0,options:{},commands:h});y.length||(console.log(b),process.exit(0));const[x,S,C]=y;if(g(x)||i(Error(`Command ${x} does not exist`),b),x===`openPR`){let[t,n]=await Promise.all([c(),o()]);await e(`open`,[`https://github.com/Autofleet/${l(t)}/compare/${n}?expand=1`],{print:!1}),process.exit(0)}async function w(){let e=await c();return e.split(u).pop()===`autorepo`?e:!1}async function T({message:e,pathIfAutorepo:t}){t??=await w();let r=C;if(t){let a=(await d(`${t}${u}packages`)).filter(e=>!e.startsWith(`.`));r?a.includes(r)||i(Error(`Package name ${r} does not exist in autorepo packages`),b):r=await n({message:e,choices:a.map(e=>({name:e,value:e}))}),r||i(Error(`No package name provided, exiting...`),b)}return r}if(x===`bumpVersion`){let e=await T({message:`Which package do you want to bump?`}),t=S||await n({message:`Which version type do you want to bump?`,choices:(x===`bumpVersion`?m:p).map(e=>({name:e,value:e}))});t||i(Error(`Must explicitly define version type.\n\tVersion type can be one of: ${m.join(`, `)}`),b);let r=await o();[`main`,`master`].includes(r)&&(await a(`Are you sure you want to bump version on main branch?`)||process.exit(0)),await _({versionType:t,packageName:e}),process.exit(0)}if(x===`releaseBeta`){let n=await w(),s=await T({message:`Which package do you want to release?`,pathIfAutorepo:n});S&&!p.includes(S)&&i(Error(`Invalid version type: ${S}\n\tVersion must be a prerelease type. (${p.join(`, `)})`),b);let c=await o();[`main`,`master`].includes(c)&&i(Error(`Cannot release beta from main branch`),b);let l=s?`.${u}packages${u}${s}`:void 0,d=!(await t(s?`.${u}packages${u}${s}${u}package.json`:`package.json`)).split(`
3
3
  `).some(e=>/^\+\s*"version":\s*"\d+\.\d+\.\d+(?:-(?:[\w-]+\.)?\d+)?",/.test(e))||await a(`Version already bumped on branch. Should version be re-bumped?`),m=d&&await v(s),h=d&&await _({versionType:S||`prerelease`,preReleaseId:`beta-${m||f().split(`-`)[0]}`,packageName:s}),g=n?`pnpm`:`npm`;await e(g,[`run`,`build`],{cwd:l});let y=await r({message:`In case your token requires an OTP, please enter it:`});try{await e(g,[`publish`,`--tag`,`beta`,`--@autofleet:registry=https://registry.npmjs.org`,...y?[`--otp`,y]:[],...n?[`--no-git-checks`]:[]],{cwd:l})}catch(e){console.error(e),i(`Failed to publish beta version`)}if(h)console.log(`Published beta version with new version: ${h}`);else{let{stdout:t}=await e(g,[`info`,`.`,`version`],{print:!1,cwd:l});console.log(`Published beta version with existing version: ${t}`)}process.exit(0)}export{};
4
4
  //# sourceMappingURL=git-autofleet.js.map
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{C as e,S as t,T as n,a as r,b as i,c as a,d as o,f as s,g as c,i as l,m as u,n as d,o as f,p,r as m,s as h,t as g,u as _,v as ee,w as v,x as y,y as b}from"./utils-BM4JK9OB.js";import{styleText as x}from"node:util";import*as te from"node:fs";import S from"node:fs";import{execFile as ne,execSync as C,spawn as re}from"node:child_process";import{confirm as w}from"@inquirer/prompts";import*as T from"node:path";import E,{basename as D,join as O,resolve as k,sep as ie}from"node:path";import{mkdir as ae,readFile as A,writeFile as j}from"node:fs/promises";import*as oe from"node:os";import se,{EOL as M,homedir as ce}from"node:os";import{randomUUID as le}from"node:crypto";import{setTimeout as ue}from"node:timers/promises";import{cwd as de}from"node:process";function N(e){return e.replace(/^[\^~]/,``)}function P(e){let t=N(e),n=/^(\d+)/.exec(t);return n?parseInt(n[1],10):0}function fe(e,t){return P(t)>P(e)}function pe(e,t){if(e.includes(`-`)||t.includes(`-`))return!1;let n=e=>e.split(`.`).map(Number),[r,i,a]=n(e),[o,s,c]=n(t);return r===o?i===s?a>c:i>s:r>o}const F=E.join(se.homedir(),`.autofleet`,`update-check.json`);function me(){try{return JSON.parse(S.readFileSync(F,`utf-8`))}catch{return null}}function he(e){try{S.mkdirSync(E.dirname(F),{recursive:!0}),S.writeFileSync(F,JSON.stringify(e))}catch{}}function ge(e,t){try{return C(`${e} ${t.join(` `)}`,{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()||null}catch{return null}}function _e(){let e=process.argv[1]??``;for(let{pm:t,args:n}of[{pm:`pnpm`,args:[`root`,`-g`]},{pm:`yarn`,args:[`global`,`dir`]},{pm:`npm`,args:[`root`,`-g`]}]){let r=ge(t,n);if(r&&e.startsWith(r))return t}return`npm`}function ve(e){return e===`pnpm`?`pnpm add -g @autofleet/cli@latest`:e===`yarn`?`yarn global add @autofleet/cli@latest`:`${E.join(E.dirname(process.execPath),`npm`)} install -g @autofleet/cli@latest`}function ye(){ne(`npm`,[`view`,`@autofleet/cli@latest`,`version`],{encoding:`utf-8`,timeout:15e3},(e,t)=>{if(e||!t.trim())return;let n=t.trim();n&&he({latestVersion:n,checkedAt:Date.now()})}).unref()}async function be(e=!1){if(e)return;let t=me();if(t&&pe(t.latestVersion,n)&&await u(`New @autofleet/cli version available (${n} → ${t.latestVersion}). Update now?`)){let e=ve(_e());console.log(`Updating @autofleet/cli...`),C(e,{stdio:`inherit`}),console.log(`✓ Updated! Please re-run your command.`),process.exit(0)}(t?Date.now()-t.checkedAt:1/0)>864e5&&ye()}const I=`.mirrord`;async function L({makeDir:e=!1}={}){let t=O(await b(),I);return e&&await ae(t,{recursive:!0}),O(t,`mirrord.json`)}async function xe(e=le()){let t=await L({makeDir:!0}),n={feature:{network:{incoming:{mode:`steal`,http_filter:{ports:[8080],path_filter:`^(?!/alive|/ready)`}},outgoing:!0},fs:`read`,env:!0},target:{namespace:e},agent:{ephemeral:!0,startup_timeout:600,communication_timeout:120,namespace:e}};return await j(t,JSON.stringify(n,null,2)),{mirrordConfigData:n,mirrordPath:t}}async function Se(){try{let e=await A(await L(),{encoding:`utf-8`});return JSON.parse(e||`{}`)?.target?.namespace??``}catch{return``}}function Ce(e){process.once(`exit`,e),process.once(`SIGTERM`,e),process.once(`SIGINT`,e)}function R(e){return e&&=e.trim(),e&&(e.startsWith(`'`)&&e.endsWith(`'`)&&(e=e.slice(1,-1)),e)}const z=`livenessProbe`,B=`readinessProbe`,V=e=>`jsonpath='{.spec.template.spec.containers[?(@.name=="worker")].${e}}'`,H=(...e)=>`{"spec": {"template": {"spec": {"containers": [{"name": "worker",${e.map(([e,t])=>`"${e}": ${t}`).join(`,`)}}]}}}}`;var we=async(e,n,r)=>{console.log(`Will now disable health check to allow debugging.`);let[{stdout:i},{stdout:a}]=await Promise.all([t(`kubectl`,[`get`,`deployment/${r}`,e,`-o`,V(z)],{print:!1}),t(`kubectl`,[`get`,`deployment/${r}`,e,`-o`,V(B)],{print:!1})]);i&&=R(i),a&&=R(a),(i||a)&&(await t(`kubectl`,[`patch`,`deployment/${r}`,e,`--patch`,H([z,`null`],[B,`null`])],{print:!1}),console.log(`Health check disabled, will now start mirrord and run "npm run dev". Make sure to attach a debugger!`));let o=new AbortController;Ce(async()=>{globalThis.executedExitHooks||(globalThis.executedExitHooks=!0,o.abort(),(i||a)&&(console.log(`Re-enabling health check.`),await t(`kubectl`,[`patch`,`deployment/${r}`,e,`--patch`,`'${H([z,i],[B,a])}'`],{print:!1,shell:!0}),console.log(`health check enabled.`)),process.exit(0))});try{let e=await L();await t(`mirrord`,[`exec`,`-t`,`deployment/${r}`,`-n`,n,`-f`,e,`--steal`,`npm`,`run`,`dev`],{signal:o.signal})}catch(e){if(e&&typeof e==`object`&&`code`in e&&e.code===`ABORT_ERR`)return;l(e)}},Te=async(e,n)=>{if(await m(e),e===`expManager`||e===`dev1`){let{variationId:e}=await _({variationId:n},[`variationId`]);e!==``&&(await r()===e&&(console.log(`Already connected to simulation with uuid: ${e}, skipping namespace switch...`),process.exit(0)),await t(`kubectl`,[`config`,`set-context`,`--current`,`--namespace=${e}`],{print:!1}),console.log(`Switched to simulation with uuid: ${e} successfully`))}process.exit(0)};async function Ee(){try{await t(`telepresence`,[`version`],{print:!1})}catch{l(`Telepresence is not installed. Please install it from:
2
+ import{C as e,S as t,T as n,a as r,b as i,c as a,d as o,f as s,g as c,i as l,m as u,n as d,o as f,p,r as m,s as h,t as g,u as _,v as ee,w as v,x as y,y as b}from"./utils-BWVzszbR.js";import{styleText as x}from"node:util";import*as te from"node:fs";import S from"node:fs";import{execFile as ne,execSync as C,spawn as re}from"node:child_process";import{confirm as w}from"@inquirer/prompts";import*as T from"node:path";import E,{basename as D,join as O,resolve as k,sep as ie}from"node:path";import{mkdir as ae,readFile as A,writeFile as j}from"node:fs/promises";import*as oe from"node:os";import se,{EOL as M,homedir as ce}from"node:os";import{randomUUID as le}from"node:crypto";import{setTimeout as ue}from"node:timers/promises";import{cwd as de}from"node:process";function N(e){return e.replace(/^[\^~]/,``)}function P(e){let t=N(e),n=/^(\d+)/.exec(t);return n?parseInt(n[1],10):0}function fe(e,t){return P(t)>P(e)}function pe(e,t){if(e.includes(`-`)||t.includes(`-`))return!1;let n=e=>e.split(`.`).map(Number),[r,i,a]=n(e),[o,s,c]=n(t);return r===o?i===s?a>c:i>s:r>o}const F=E.join(se.homedir(),`.autofleet`,`update-check.json`);function me(){try{return JSON.parse(S.readFileSync(F,`utf-8`))}catch{return null}}function he(e){try{S.mkdirSync(E.dirname(F),{recursive:!0}),S.writeFileSync(F,JSON.stringify(e))}catch{}}function ge(e,t){try{return C(`${e} ${t.join(` `)}`,{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()||null}catch{return null}}function _e(){let e=process.argv[1]??``;for(let{pm:t,args:n}of[{pm:`pnpm`,args:[`root`,`-g`]},{pm:`yarn`,args:[`global`,`dir`]},{pm:`npm`,args:[`root`,`-g`]}]){let r=ge(t,n);if(r&&e.startsWith(r))return t}return`npm`}function ve(e){return e===`pnpm`?`pnpm add -g @autofleet/cli@latest`:e===`yarn`?`yarn global add @autofleet/cli@latest`:`${E.join(E.dirname(process.execPath),`npm`)} install -g @autofleet/cli@latest`}function ye(){ne(`npm`,[`view`,`@autofleet/cli@latest`,`version`],{encoding:`utf-8`,timeout:15e3},(e,t)=>{if(e||!t.trim())return;let n=t.trim();n&&he({latestVersion:n,checkedAt:Date.now()})}).unref()}async function be(e=!1){if(e)return;let t=me();if(t&&pe(t.latestVersion,n)&&await u(`New @autofleet/cli version available (${n} → ${t.latestVersion}). Update now?`)){let e=ve(_e());console.log(`Updating @autofleet/cli...`),C(e,{stdio:`inherit`}),console.log(`✓ Updated! Please re-run your command.`),process.exit(0)}(t?Date.now()-t.checkedAt:1/0)>864e5&&ye()}const I=`.mirrord`;async function L({makeDir:e=!1}={}){let t=O(await b(),I);return e&&await ae(t,{recursive:!0}),O(t,`mirrord.json`)}async function xe(e=le()){let t=await L({makeDir:!0}),n={feature:{network:{incoming:{mode:`steal`,http_filter:{ports:[8080],path_filter:`^(?!/alive|/ready)`}},outgoing:!0},fs:`read`,env:!0},target:{namespace:e},agent:{ephemeral:!0,startup_timeout:600,communication_timeout:120,namespace:e}};return await j(t,JSON.stringify(n,null,2)),{mirrordConfigData:n,mirrordPath:t}}async function Se(){try{let e=await A(await L(),{encoding:`utf-8`});return JSON.parse(e||`{}`)?.target?.namespace??``}catch{return``}}function Ce(e){process.once(`exit`,e),process.once(`SIGTERM`,e),process.once(`SIGINT`,e)}function R(e){return e&&=e.trim(),e&&(e.startsWith(`'`)&&e.endsWith(`'`)&&(e=e.slice(1,-1)),e)}const z=`livenessProbe`,B=`readinessProbe`,V=e=>`jsonpath='{.spec.template.spec.containers[?(@.name=="worker")].${e}}'`,H=(...e)=>`{"spec": {"template": {"spec": {"containers": [{"name": "worker",${e.map(([e,t])=>`"${e}": ${t}`).join(`,`)}}]}}}}`;var we=async(e,n,r)=>{console.log(`Will now disable health check to allow debugging.`);let[{stdout:i},{stdout:a}]=await Promise.all([t(`kubectl`,[`get`,`deployment/${r}`,e,`-o`,V(z)],{print:!1}),t(`kubectl`,[`get`,`deployment/${r}`,e,`-o`,V(B)],{print:!1})]);i&&=R(i),a&&=R(a),(i||a)&&(await t(`kubectl`,[`patch`,`deployment/${r}`,e,`--patch`,H([z,`null`],[B,`null`])],{print:!1}),console.log(`Health check disabled, will now start mirrord and run "npm run dev". Make sure to attach a debugger!`));let o=new AbortController;Ce(async()=>{globalThis.executedExitHooks||(globalThis.executedExitHooks=!0,o.abort(),(i||a)&&(console.log(`Re-enabling health check.`),await t(`kubectl`,[`patch`,`deployment/${r}`,e,`--patch`,`'${H([z,i],[B,a])}'`],{print:!1,shell:!0}),console.log(`health check enabled.`)),process.exit(0))});try{let e=await L();await t(`mirrord`,[`exec`,`-t`,`deployment/${r}`,`-n`,n,`-f`,e,`--steal`,`npm`,`run`,`dev`],{signal:o.signal})}catch(e){if(e&&typeof e==`object`&&`code`in e&&e.code===`ABORT_ERR`)return;l(e)}},Te=async(e,n)=>{if(await m(e),e===`expManager`||e===`dev1`){let{variationId:e}=await _({variationId:n},[`variationId`]);e!==``&&(await r()===e&&(console.log(`Already connected to simulation with uuid: ${e}, skipping namespace switch...`),process.exit(0)),await t(`kubectl`,[`config`,`set-context`,`--current`,`--namespace=${e}`],{print:!1}),console.log(`Switched to simulation with uuid: ${e} successfully`))}process.exit(0)};async function Ee(){try{await t(`telepresence`,[`version`],{print:!1})}catch{l(`Telepresence is not installed. Please install it from:
3
3
  https://www.telepresence.io/docs/latest/quick-start/`)}}function De(){return c({message:`Do you want to leave the connection or create a new one?`,choices:[{name:`Leave the current connection`,value:`leave`},{name:`Create a new connection`,value:`connect`}],default:`connect`})}async function Oe(e){await Ee();let{cluster:n=``,service:r=``}=e;await m(n);let i=await De();if([`leave`,`connect`].includes(i)||l(`Invalid action, how did you get here? 🤔`),i===`leave`){await t(`telepresence`,[`leave`,r]),console.log(`Disconnected! 👋`);return}let a=e.variationId||await p(),o=e[`local-port`]&&Number.parseInt(e[`local-port`],10)||Number.parseInt(await s()||``,10);await t(`telepresence`,[`connect`,`--namespace=${a}`]),await t(`telepresence`,[`intercept`,r,`--port`,o.toString(),`--env-file=./.env`]),console.log(`Everything is set up! 🚀`),console.log(`You can now access the service at localhost:${o}`),console.log(`You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.`),process.exit(0)}var ke=async(e,n,r)=>{r||l(Error(`service is required for exposeService`),n),await t(`kubectl`,[`patch`,`svc`,e,r,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),console.log(`exposed ${r} successfully. the service is now creating an internal load balancer ip to use with vpn`),process.exit(0)},Ae=async(e,n,r,i,a)=>{let o=Number.parseInt(e[`local-port`]??`5432`,10);Number.isNaN(o)&&l(Error(`if defined, local-port must be a number`),i);let s=`afpass_${r}`,c=`postgres`,u=r.replaceAll(`-`,`_`),d=a?`${a.replaceAll(`-`,`_`)||``}_${u}`:`postgres`,f=`postgres://${c}:${s}@localhost:${o}/${d}?&nickname=var_${r}`;console.log(`Forwarding db to local port ${o}.\naccess the DB at ${f}\nPress ctrl+c to stop.`);let p=` DB_USERNAME=${c}
4
4
  DB_PASSWORD=${s}
5
5
  DB_NAME=${a?d:`<service_name>_${u}`}`;console.log(`Generated database environment for local development:
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["version","packageJson.version","variationId","asyncSpawn","service","prefix","variationId","cluster","asyncSpawn","asyncSpawn","values","cluster","service","service","help","asyncSpawn","prefix","values","help","variationId","service","asyncSpawn","prefix","values","service","help","asyncSpawn","prefix","asyncSpawn","prefix","asyncSpawn","prefix","variationId","asyncSpawn","serviceName: string | undefined","asyncSpawn","npmTokenFlags: string[]","buildArgFlags: string[]","targetFlag: string[]","buildArgs: Record<string, string>","prefix","envNameToUse: string","cluster","variationId","asyncSpawn","prefix","variationId","path","os","asyncSpawn","asyncSpawn","name","asyncSpawn","version","packages: PackageInfo[]","majorUpdates: MajorUpdateInfo[]","path","parseArgs","mirrordConfig","dockerInit","updateAutofleetPackages","switchCluster","openRedis","prefix: string","mirrord","exposeService","forwardDb","forwardService","getIps","enableSimulator","rabbitCreds","updateExp","localDev"],"sources":["../bin/utils/version-utils.ts","../bin/utils/version-check.ts","../bin/utils/mirrord.ts","../bin/utils/exitHandler.ts","../bin/commands/base/mirrord.ts","../bin/commands/base/switchCluster.ts","../bin/commands/base/telepresenceWizard.ts","../bin/commands/base/exposeService.ts","../bin/commands/base/forwardDb.ts","../bin/commands/base/forwardService.ts","../bin/commands/base/getIps.ts","../bin/commands/base/enableSimulator.ts","../bin/commands/base/rabbitCreds.ts","../bin/commands/base/updateExp.ts","../bin/utils/env.ts","../bin/commands/base/localDev.ts","../bin/commands/base/mirrordConfig.ts","../bin/commands/base/dockerInit.ts","../bin/commands/base/openRedis.ts","../bin/commands/base/updateAutofleetPackages.ts","../bin/commands/base/claude-init/index.ts","../bin/index.ts"],"sourcesContent":["export function parseVersion(version: string): string {\n return version.replace(/^[\\^~]/, '');\n}\n\nexport function getMajorVersion(version: string): number {\n const cleaned = parseVersion(version);\n const match = /^(\\d+)/.exec(cleaned);\n return match ? parseInt(match[1], 10) : 0;\n}\n\nexport function isMajorUpdate(currentVersion: string, latestVersion: string): boolean {\n return getMajorVersion(latestVersion) > getMajorVersion(currentVersion);\n}\n\nexport function isNewer(latest: string, current: string): boolean {\n // ignore pre-release versions (e.g. 2.22.0-beta.1)\n if (latest.includes('-') || current.includes('-')) return false;\n const parse = (v: string) => v.split('.').map(Number) as [number, number, number];\n const [lMaj, lMin, lPat] = parse(latest);\n const [cMaj, cMin, cPat] = parse(current);\n if (lMaj !== cMaj) return lMaj > cMaj;\n if (lMin !== cMin) return lMin > cMin;\n return lPat > cPat;\n}\n","import { execFile, execSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport { promptForConfirmation } from './inquirer.js';\nimport { isNewer } from './version-utils.js';\n\nconst CACHE_FILE = path.join(os.homedir(), '.autofleet', 'update-check.json');\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface UpdateCache {\n latestVersion: string;\n checkedAt: number;\n}\n\nfunction readCache(): UpdateCache | null {\n try {\n return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeCache(data: UpdateCache): void {\n try {\n fs.mkdirSync(path.dirname(CACHE_FILE), { recursive: true });\n fs.writeFileSync(CACHE_FILE, JSON.stringify(data));\n } catch {\n // ignore write errors\n }\n}\n\nfunction getGlobalRoot(pm: string, args: string[]): string | null {\n try {\n const root = execSync(`${pm} ${args.join(' ')}`, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();\n return root || null;\n } catch {\n return null;\n }\n}\n\nfunction detectPackageManager(): string {\n const script = process.argv[1] ?? '';\n const candidates: { pm: string; args: string[]; }[] = [\n { pm: 'pnpm', args: ['root', '-g'] },\n { pm: 'yarn', args: ['global', 'dir'] },\n { pm: 'npm', args: ['root', '-g'] },\n ];\n for (const { pm, args } of candidates) {\n const root = getGlobalRoot(pm, args);\n if (root && script.startsWith(root)) return pm;\n }\n return 'npm';\n}\n\nfunction buildInstallCommand(pm: string): string {\n if (pm === 'pnpm') return 'pnpm add -g @autofleet/cli@latest';\n if (pm === 'yarn') return 'yarn global add @autofleet/cli@latest';\n const npmBin = path.join(path.dirname(process.execPath), 'npm');\n return `${npmBin} install -g @autofleet/cli@latest`;\n}\n\nfunction fetchLatestVersionInBackground(): void {\n const child = execFile(\n 'npm',\n ['view', '@autofleet/cli@latest', 'version'],\n { encoding: 'utf-8', timeout: 15_000 },\n (error, stdout) => {\n if (error || !stdout.trim()) return;\n const latest = stdout.trim();\n if (latest) {\n writeCache({ latestVersion: latest, checkedAt: Date.now() });\n }\n },\n );\n child.unref();\n}\n\nexport async function checkForCliUpdate(quiet = false): Promise<void> {\n if (quiet) return;\n const cache = readCache();\n\n if (cache && isNewer(cache.latestVersion, packageJson.version)) {\n const shouldUpdate = await promptForConfirmation(\n `New @autofleet/cli version available (${packageJson.version} → ${cache.latestVersion}). Update now?`,\n );\n if (shouldUpdate) {\n const pm = detectPackageManager();\n const installCmd = buildInstallCommand(pm);\n console.log('Updating @autofleet/cli...');\n execSync(installCmd, { stdio: 'inherit' });\n console.log('✓ Updated! Please re-run your command.');\n process.exit(0);\n }\n }\n\n const cacheAge = cache ? Date.now() - cache.checkedAt : Infinity;\n if (cacheAge > CHECK_INTERVAL_MS) {\n fetchLatestVersionInBackground();\n }\n}\n","import { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { getGitPath } from './git.js';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\n\nexport const MIRRORD_FOLDER_NAME = '.mirrord';\n\nexport async function getMirrodConfigPath({ makeDir = false } = {}) {\n const repoPath = await getGitPath();\n const mirrordPath = join(repoPath, MIRRORD_FOLDER_NAME);\n if (makeDir) {\n await mkdir(mirrordPath, { recursive: true });\n }\n return join(mirrordPath, 'mirrord.json');\n}\n\nexport async function writeMirrordFile(variationId: string = randomUUID()) {\n const mirrordPath = await getMirrodConfigPath({ makeDir: true });\n /* eslint-disable camelcase */\n const mirrordConfigData = {\n feature: {\n network: {\n incoming: {\n mode: 'steal',\n http_filter: {\n ports: [8080],\n path_filter: '^(?!/alive|/ready)',\n },\n },\n outgoing: true,\n },\n fs: 'read',\n env: true,\n },\n target: {\n namespace: variationId,\n },\n agent: {\n ephemeral: true,\n startup_timeout: 600,\n communication_timeout: 120,\n namespace: variationId,\n },\n };\n /* eslint-enable camelcase */\n await writeFile(mirrordPath, JSON.stringify(mirrordConfigData, null, 2));\n\n return { mirrordConfigData, mirrordPath };\n}\n\nexport async function getVariationIdFromMirrodConfig() {\n try {\n const mirrordPath = await getMirrodConfigPath();\n const mirrordConfigDataString = await readFile(mirrordPath, { encoding: 'utf-8' });\n const mirrordConfigData = JSON.parse(mirrordConfigDataString || '{}') as { target?: { namespace?: string; }; };\n return mirrordConfigData?.target?.namespace ?? '';\n } catch {\n return '';\n }\n}\n","export function registerProcessForCleanup(onExit: (e?: unknown) => void | PromiseLike<void>) {\n process.once('exit', onExit);\n process.once('SIGTERM', onExit);\n process.once('SIGINT', onExit);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { registerProcessForCleanup } from '../../utils/exitHandler.js';\nimport { getMirrodConfigPath } from '../../utils/mirrord.js';\n\ndeclare global {\n var executedExitHooks: boolean;\n}\n\nfunction trimProbeString(str: string): string {\n str &&= str.trim();\n if (!str) {\n return str;\n }\n if (str.startsWith('\\'') && str.endsWith('\\'')) {\n str = str.slice(1, -1);\n }\n return str;\n}\n\nconst LIVENESS_PROBE = 'livenessProbe';\nconst READINESS_PROBE = 'readinessProbe';\nconst WORKER_PATH = (leaf: string) => `jsonpath='{.spec.template.spec.containers[?(@.name==\"worker\")].${leaf}}'`;\nconst SET_PROBE_VALUES = (...probeAndValues: [string, string][]) =>\n `{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"worker\",${probeAndValues\n .map(([probe, value]) => `\"${probe}\": ${value}`)\n .join(',')}}]}}}}`;\n\nexport default async (prefix: string, variationId: string, service?: string) => {\n console.log('Will now disable health check to allow debugging.');\n let [{ stdout: livenessProbe }, { stdout: readinessProbe }] = await Promise.all([\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(LIVENESS_PROBE)], { print: false }),\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(READINESS_PROBE)], { print: false }),\n ]);\n livenessProbe &&= trimProbeString(livenessProbe);\n readinessProbe &&= trimProbeString(readinessProbe);\n if (livenessProbe || readinessProbe) {\n await asyncSpawn('kubectl', ['patch', `deployment/${service}`, prefix, '--patch', SET_PROBE_VALUES([LIVENESS_PROBE, 'null'], [READINESS_PROBE, 'null'])], { print: false });\n console.log('Health check disabled, will now start mirrord and run \"npm run dev\". Make sure to attach a debugger!');\n }\n const abortController = new AbortController();\n registerProcessForCleanup(async () => {\n if (globalThis.executedExitHooks) {\n return;\n }\n globalThis.executedExitHooks = true;\n abortController.abort();\n if (livenessProbe || readinessProbe) {\n console.log('Re-enabling health check.');\n await asyncSpawn(\n 'kubectl',\n [\n 'patch',\n `deployment/${service}`,\n prefix,\n '--patch',\n `'${SET_PROBE_VALUES(\n [LIVENESS_PROBE, livenessProbe],\n [READINESS_PROBE, readinessProbe],\n )}'`,\n ],\n { print: false, shell: true },\n );\n console.log('health check enabled.');\n }\n process.exit(0);\n });\n try {\n const mirrordPath = await getMirrodConfigPath();\n await asyncSpawn('mirrord', ['exec', '-t', `deployment/${service}`, '-n', variationId, '-f', mirrordPath, '--steal', 'npm', 'run', 'dev'], { signal: abortController.signal });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ABORT_ERR') {\n return;\n }\n endWithError(error as Error);\n }\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getCurrentNamespace } from '../../utils/index.js';\nimport { fillMissingRequiredValues } from '../../utils/inquirer.js';\n\nexport default async (cluster: string, variationId?: string) => {\n await connectToCluster(cluster);\n\n if (cluster === 'expManager' || cluster === 'dev1') {\n const { variationId: namespace } = await fillMissingRequiredValues({ variationId }, ['variationId']);\n if (namespace !== '') {\n if (await getCurrentNamespace() === namespace) {\n console.log(`Already connected to simulation with uuid: ${namespace}, skipping namespace switch...`);\n process.exit(0);\n }\n await asyncSpawn('kubectl', ['config', 'set-context', '--current', `--namespace=${namespace}`], { print: false });\n console.log(`Switched to simulation with uuid: ${namespace} successfully`);\n }\n }\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getVariationId, getLocalPort, safeSelect } from '../../utils/inquirer.js';\nimport { connectToCluster, endWithError } from '../../utils/index.js';\nimport type { Values } from '../../index.js';\n\nasync function ensureTelepresenceInstalled() {\n try {\n await asyncSpawn('telepresence', ['version'], { print: false });\n } catch {\n endWithError('Telepresence is not installed. Please install it from:\\nhttps://www.telepresence.io/docs/latest/quick-start/');\n }\n}\n\nfunction leaveOrConnect() {\n return safeSelect({\n message: 'Do you want to leave the connection or create a new one?',\n choices: [\n { name: 'Leave the current connection', value: 'leave' },\n { name: 'Create a new connection', value: 'connect' },\n ] as const,\n default: 'connect',\n });\n}\n\nexport default async function telepresenceWizard(values: Values): Promise<void> {\n await ensureTelepresenceInstalled();\n\n const { cluster = '', service = '' } = values; // Values should be defined by now, thanks to inquirer. Default to hint to TS we always have values.\n await connectToCluster(cluster);\n\n const action = await leaveOrConnect();\n if (!['leave', 'connect'].includes(action!)) {\n endWithError('Invalid action, how did you get here? 🤔');\n }\n if (action === 'leave') {\n await asyncSpawn('telepresence', ['leave', service]);\n console.log('Disconnected! 👋');\n return;\n }\n const namespace = values.variationId || await getVariationId();\n const localPort = (values['local-port'] && Number.parseInt(values['local-port'], 10)) || Number.parseInt((await getLocalPort()) || '', 10);\n await asyncSpawn('telepresence', ['connect', `--namespace=${namespace}`]);\n await asyncSpawn('telepresence', ['intercept', service, '--port', localPort.toString(), '--env-file=./.env']);\n console.log('Everything is set up! 🚀');\n console.log(`You can now access the service at localhost:${localPort}`);\n console.log('You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.');\n process.exit(0);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\nexport default async (prefix: string, help: string, service?: string) => {\n if (!service) {\n endWithError(new Error('service is required for exposeService'), help);\n }\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, service, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n console.log(`exposed ${service} successfully. the service is now creating an internal load balancer ip to use with vpn`);\n process.exit(0);\n};\n","import { setTimeout } from 'node:timers/promises';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n 'local-port'?: string;\n 'skip-open'?: boolean;\n}\n\nexport default async (values: Values, prefix: string, variationId: string, help: string, service?: string) => {\n const localPort = Number.parseInt(values['local-port'] ?? '5432', 10);\n if (Number.isNaN(localPort)) {\n endWithError(new Error('if defined, local-port must be a number'), help);\n }\n const DB_PASSWORD = `afpass_${variationId}`;\n const USER_NAME = 'postgres';\n const variationUnderScore = variationId.replaceAll('-', '_');\n const DB_NAME = service ? `${service.replaceAll('-', '_') || ''}_${variationUnderScore}` : 'postgres';\n\n const postgressPath = `postgres://${USER_NAME}:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?&nickname=var_${variationId}`;\n console.log(`Forwarding db to local port ${localPort}.\\naccess the DB at ${postgressPath}\\nPress ctrl+c to stop.`);\n\n const dbEnvs = ` DB_USERNAME=${USER_NAME}\n DB_PASSWORD=${DB_PASSWORD}\n DB_NAME=${service ? DB_NAME : `<service_name>_${variationUnderScore}`}`;\n console.log('Generated database environment for local development:\\n', dbEnvs);\n\n if (!values['skip-open']) {\n console.log('\\n' + styleText('cyan', '[Tip] Already have Postico open? Use --skip-open (or -o) to skip opening a new window.') + '\\n');\n setTimeout(1500).then(() => asyncSpawn('open', [postgressPath], { print: false })).catch(() => null);\n }\n await asyncSpawn('kubectl', [prefix, 'port-forward', `svc/p${variationId}-postgresql`, `${localPort}:5432`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n port?: string;\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, help: string, service?: string) => {\n const port = Number.parseInt(values.port ?? '8080', 10);\n const localPort = Number.parseInt(values['local-port'] ?? '', 10) || port;\n if (!service) {\n endWithError(new Error('service is required for forwardService'), help);\n }\n if (!port || Number.isNaN(port)) {\n endWithError(new Error('port is required and must be a numbers'), help);\n }\n if (localPort && Number.isNaN(localPort)) {\n endWithError(new Error('local-port must be a number'), help);\n }\n let { stdout: podName } = await asyncSpawn('kubectl', ['get', 'pods', prefix, '-l', `service=${service}`, '-o', 'jsonpath=\"{.items[0].metadata.name}\"'], { print: false });\n podName &&= podName.trim();\n if (!podName) {\n endWithError(new Error(`No pods found for service ${service}`));\n }\n if (podName.startsWith('\"') && podName.endsWith('\"')) {\n podName = podName.slice(1, -1);\n }\n console.log(`Found pod ${podName}, serving locally on port ${localPort} from remote port ${port}.\\nPress ctrl+c to stop.`);\n await asyncSpawn('kubectl', ['port-forward', prefix, podName, `${localPort}:${port}`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { parseIps } from '../../utils/index.js';\n\nexport default async (prefix: string) => {\n const { stdout } = await asyncSpawn('kubectl', [prefix, 'get', 'services'], { print: false });\n const ips = parseIps(stdout);\n ips.forEach(ip => console.log(ip));\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async (prefix: string, variationId: string) => {\n const SIMULATION_CLUSTER_FRONT = 'simulation-cluster-front';\n await asyncSpawn('kubectl', ['annotate', prefix, 'service', SIMULATION_CLUSTER_FRONT, 'cloud.google.com/load-balancer-type-']);\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, SIMULATION_CLUSTER_FRONT, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n await asyncSpawn('kubectl', ['create', prefix, 'rolebinding', 'admin', '--clusterrole=cluster-admin', `--serviceaccount=${variationId}:default`]);\n console.log(`Successfully exposed ${SIMULATION_CLUSTER_FRONT} and added role binding to dispatch simulations`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async () => {\n const getArgs = (dataKey: string) => ['get', 'secret', 'rabbitmq-default-user', '-o', `jsonpath=\"{.data.${dataKey}}\"`];\n const [{ stdout: username }, { stdout: password }] = await Promise.all([\n asyncSpawn('kubectl', getArgs('username'), { print: false }),\n asyncSpawn('kubectl', getArgs('password'), { print: false }),\n ]);\n console.log(`username: ${Buffer.from(username, 'base64').toString('ascii')}`);\n console.log(`password: ${Buffer.from(password, 'base64').toString('ascii')}`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { basename, join, sep } from 'node:path';\nimport { cwd } from 'node:process';\nimport { getCurrentBranch, getGitPath, getRemoteUrl } from '../../utils/git.js';\nimport { getAutorepoAppName } from '../../utils/inquirer.js';\nimport { homedir } from 'node:os';\nimport { readFile } from 'node:fs/promises';\n\nconst NPM_AUTH_TOKEN_REGEX = /_authToken\\s*=\\s*\"?([^\\s\"]+)\"?/;\n\nconst resolveNpmToken = async (): Promise<string | undefined> => {\n if (process.env.NPM_TOKEN) return process.env.NPM_TOKEN;\n try {\n const npmrc = await readFile(join(homedir(), '.npmrc'), 'utf-8');\n const match = NPM_AUTH_TOKEN_REGEX.exec(npmrc);\n return match?.[1];\n } catch {\n return undefined;\n }\n};\n\nexport default async (prefix: string) => {\n const gitPath = await getGitPath();\n const remoteUrl = await getRemoteUrl();\n const isAutorepo = remoteUrl\n ? /[/:]Autofleet\\/autorepo(\\.git)?$/i.test(remoteUrl)\n : gitPath.split(sep).pop() === 'autorepo';\n let serviceName: string | undefined;\n if (isAutorepo) {\n serviceName = await getAutorepoAppName(gitPath);\n if (!serviceName) {\n console.error('No service name provided, exiting...');\n process.exit(1);\n }\n } else {\n serviceName = basename(cwd());\n }\n const [branchName, archResult] = await Promise.all([getCurrentBranch(), asyncSpawn('uname', ['-m'], { print: false })]);\n const arch = archResult.stdout.trim();\n const date = new Date();\n const dateSuffix = `${date.getHours().toString().padStart(2, '0')}-${date.getMinutes().toString().padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}`;\n const sanitizedBranch = branchName.replace(/[^a-zA-Z0-9._-]/g, '-');\n const imageName = `gcr.io/autofleetprod/${serviceName}:${sanitizedBranch}-${dateSuffix}`;\n console.log(`Building and pushing image ${imageName}`);\n const platformFlag = arch === 'x86_64' ? [] : ['--platform', 'linux/amd64'];\n\n const npmTokenFlags: string[] = [];\n let buildArgFlags: string[] = [];\n let targetFlag: string[] = [];\n\n if (isAutorepo) {\n npmTokenFlags.push('--secret', 'id=npm_token,env=NPM_TOKEN');\n const { stdout: packagesOutput } = await asyncSpawn('ls', ['-1', 'packages'], { print: false });\n const packages = packagesOutput.trim().replace(/\\n/g, ' ');\n\n const buildArgs: Record<string, string> = {\n APP: serviceName,\n PACKAGES: packages,\n BRANCH: branchName,\n };\n\n const projectJsonPath = `${gitPath}/apps/${serviceName}/project.json`;\n const projectJson = JSON.parse(await readFile(projectJsonPath, 'utf-8'));\n const tags = projectJson.tags || [];\n\n // Apps with elasticsearch tag need NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed certs\n if (tags.includes('elasticsearch')) {\n buildArgs.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n const targetBuildType = serviceName.endsWith('-ms') ? 'backend' : 'frontend';\n if (targetBuildType === 'frontend') {\n const apiSource = ['partner-admin', 'web-booker', 'driver-level-ordering-portal'].includes(serviceName) ? 'client' : 'api';\n buildArgs.API_SOURCE = apiSource;\n }\n\n buildArgFlags = Object.entries(buildArgs)\n .flatMap(([key, val]) => ['--build-arg', `${key}=${val}`]);\n\n targetFlag = ['--target', targetBuildType];\n } else {\n const npmToken = await resolveNpmToken();\n if (!npmToken) {\n console.error('NPM_TOKEN not found in environment or ~/.npmrc, exiting...');\n process.exit(1);\n }\n\n npmTokenFlags.push('--build-arg', `NPM_TOKEN=${npmToken}`);\n }\n\n await asyncSpawn('docker', ['build', '.', '-f', 'Dockerfile', ...targetFlag, ...platformFlag, '-t', imageName, ...buildArgFlags, ...npmTokenFlags]);\n await asyncSpawn('docker', ['push', imageName]);\n const { stdout: podDescription } = await asyncSpawn('kubectl', ['describe', 'pod', prefix, '-l', `service=${serviceName}`], { print: false });\n if (podDescription.includes('Init Containers:')) {\n await asyncSpawn('kubectl', ['patch', `deployment/${serviceName}`, prefix, '--patch', `{\"spec\": {\"template\": {\"spec\": {\"initContainers\": [{\"name\": \"init\",\"image\": \"${imageName}\"}]}}}}`]);\n }\n await asyncSpawn('kubectl', ['set', 'image', `deployment/${serviceName}`, `worker=${imageName}`, prefix]);\n await asyncSpawn('kubectl', ['rollout', 'status', 'deployments', serviceName, prefix]);\n process.exit(0);\n};\n","import { EOL } from 'node:os';\nimport { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\n\nexport async function setEnvValue(repoRoot: string, key: string, value: string): Promise<boolean> {\n const filePath = resolve(repoRoot, '.env');\n const envFileContent = await readFile(filePath, 'utf8');\n const envVars = envFileContent.split(EOL);\n\n // (?<!#\\\\s*) Negative lookbehind to avoid matching comments (lines that starts with #).\n // There is a double slash in the RegExp constructor to escape it.\n // (?==) Positive lookahead to check if there is an equal sign right after the key.\n // This is to prevent matching keys prefixed with the key of the env var to update.\n const regexString = `(?<!#\\\\s*)${key}(?==)`;\n const matchingLine = envVars.find((line: string) => line.match(regexString));\n\n if (matchingLine?.split('=').at(-1) === value) {\n return false;\n }\n\n const target = matchingLine ? envVars.indexOf(matchingLine) : -1;\n\n if (target !== -1) {\n envVars.splice(target, 1, `${key}=${value}`);\n } else {\n envVars.push(`${key}=${value}`);\n }\n\n await writeFile(filePath, envVars.join(EOL));\n return true;\n}\n","import { basename } from 'node:path';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getGitPath } from '../../utils/git.js';\nimport { endWithError } from '../../utils/index.js';\nimport { setEnvValue } from '../../utils/env.js';\n\nexport default async (prefix: string, cluster: string, variationId: string) => {\n const LOCAL_ENV_NAME = 'LOCAL_ENV_NAME';\n const API_GATEWAY_MS = 'api-gateway-ms';\n const CONTROL_CENTER_MS = 'control-center-ms';\n let envNameToUse: string;\n if (cluster.toLocaleLowerCase().includes('prod')) {\n envNameToUse = 'production';\n } else if (cluster === 'staging') {\n envNameToUse = 'staging';\n } else {\n envNameToUse = `simulator-${variationId}`;\n }\n\n const repoPath = await getGitPath();\n if (basename(repoPath) !== 'control-center') {\n endWithError(new Error('The `localDev` command must be run from the control-center repository'));\n }\n\n const apiGatewayMsIP = 'localhost:8081';\n const changedAiGatewayMsIP = await setEnvValue(repoPath, 'API_GATEWAY_MS_SERVICE_HOST', apiGatewayMsIP);\n\n if (changedAiGatewayMsIP) {\n console.log(`Updated .env file to use ${API_GATEWAY_MS} IP (${apiGatewayMsIP}).`);\n }\n\n const controlCenterMsIP = 'localhost:8085';\n const changedControlCenterIP = await setEnvValue(repoPath, 'CONTROL_CENTER_MS_SERVICE_HOST', controlCenterMsIP);\n\n if (changedControlCenterIP) {\n console.log(`Updated .env file to use ${CONTROL_CENTER_MS} IP (${controlCenterMsIP}).`);\n }\n\n const changedEnvName = await setEnvValue(repoPath, LOCAL_ENV_NAME, envNameToUse);\n\n if (changedEnvName) {\n console.log(`Updated .env file ${LOCAL_ENV_NAME} to ${envNameToUse} (used for firebase setup).`);\n }\n\n const controlCenterProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${CONTROL_CENTER_MS}`, '8085:80'], { print: false });\n const apiGatewayProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${API_GATEWAY_MS}`, '8081:80'], { print: false });\n\n console.log(`Starting port-forwarding of ${CONTROL_CENTER_MS} to port 8085`);\n console.log(`Starting port-forwarding of ${API_GATEWAY_MS} to port 8081`);\n console.log('Press Ctrl+C to stop the port-forwarding processes.');\n\n await Promise.all([controlCenterProcess, apiGatewayProcess]);\n};\n","import { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { isPathIgnored } from '../../utils/git.js';\nimport { writeMirrordFile, MIRRORD_FOLDER_NAME } from '../../utils/mirrord.js';\n\nasync function addToGitIgnore(mirrordPath: string) {\n const isIgnored = await isPathIgnored(MIRRORD_FOLDER_NAME);\n if (isIgnored) {\n return;\n }\n const gitIgnoreFile = resolve(mirrordPath, '..', '..', '.gitignore');\n const gitIgnoreFileContent = await readFile(gitIgnoreFile, 'utf8');\n const gitIgnoreFileContentLines = gitIgnoreFileContent.split('\\n').filter(Boolean);\n gitIgnoreFileContentLines.push(MIRRORD_FOLDER_NAME);\n await writeFile(gitIgnoreFile, `${gitIgnoreFileContentLines.join('\\n')}\\n`);\n}\n\nexport default async (variationId?: string) => {\n const { mirrordConfigData, mirrordPath } = await writeMirrordFile(variationId);\n await addToGitIgnore(mirrordPath);\n console.log('Wrote the default mirrord config for the requested variation ID', { mirrordConfigData });\n process.exit(0);\n};\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\n\nconst dockerComposeFile = `\nservices:\n redis:\n image: redis:6\n ports:\n - \"6379:6379\"\n volumes:\n - redis_data:/data\n command: redis-server --appendonly yes\n\n rabbitmq:\n image: rabbitmq:3.12.13-management\n ports:\n - \"5672:5672\" # AMQP protocol port\n - \"15672:15672\" # Management UI port\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n environment:\n - RABBITMQ_DEFAULT_USER=guest\n - RABBITMQ_DEFAULT_PASS=guest\n\n postgres:\n image: postgis/postgis:14-3.3\n platform: linux/amd64\n ports:\n - \"5432:5432\"\n volumes:\n - postgres_data:/var/lib/postgresql/data\n environment:\n - POSTGRES_DB=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_PASSWORD=postgres\n\n elasticsearch:\n image: docker.elastic.co/elasticsearch/elasticsearch:8.8.1\n ports:\n - \"9200:9200\"\n - \"9300:9300\"\n environment:\n - discovery.type=single-node\n - xpack.security.enabled=false\n - xpack.security.transport.ssl.enabled=false\n - xpack.security.http.ssl.enabled=false\n - ES_JAVA_OPTS=-Xms1g -Xmx1g\n volumes:\n - elasticsearch_data:/usr/share/elasticsearch/data\n ulimits:\n memlock:\n soft: -1\n hard: -1\n mem_limit: 2g\n\n kibana:\n image: docker.elastic.co/kibana/kibana:8.8.1\n ports:\n - \"5601:5601\"\n environment:\n - ELASTICSEARCH_HOSTS=http://elasticsearch:9200\n depends_on:\n - elasticsearch\n\nvolumes:\n redis_data:\n rabbitmq_data:\n postgres_data:\n elasticsearch_data:\n`;\n\nexport default async () => {\n const dockerComposePath = path.join(os.tmpdir(), 'docker-compose.yml');\n fs.writeFileSync(dockerComposePath, dockerComposeFile);\n await asyncSpawn('docker-compose', ['-f', dockerComposePath, 'up', '-d'], { print: false });\n console.log('--------------------------------------------------------------------------------');\n console.log('Successfully started the services:\\n');\n console.log('redis: localhost:6379 🚀');\n console.log('postgres: localhost:5432, user: postgres, password: postgres 🐘');\n console.log('rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇');\n console.log('elasticsearch: localhost:9200 ❓');\n console.log('kibana: http://localhost:5601 ❓');\n process.exit(0);\n};\n","import { spawn } from 'node:child_process';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getRedisRegion, isSimulationCluster } from '../../utils/index.js';\nimport { safeSelect } from '../../utils/inquirer.js';\nimport { createDeferredPromise } from '../../utils/promise.js';\n\ninterface RedisInstance {\n displayName?: string;\n host: string;\n name: string;\n}\n\nexport default async (clusterName: string) => {\n if (isSimulationCluster(clusterName)) {\n console.error('Connecting to Redis is not supported for simulation clusters (need to be added)');\n process.exit(1);\n }\n\n const {\n project,\n name,\n } = await connectToCluster(clusterName);\n const redisRegion = getRedisRegion(clusterName);\n const { stdout: redisInstances } = await asyncSpawn('gcloud', ['redis', 'instances', 'list', '--region', redisRegion, '--project', project || name, '--format', 'json'], { print: false });\n let redisInstancesJson;\n try {\n redisInstancesJson = JSON.parse(redisInstances) as RedisInstance[];\n } catch (e) {\n console.error('Failed to parse redis instances', { redisInstances, e });\n process.exit(1);\n }\n\n const redisNameToIpMap = Object.fromEntries(redisInstancesJson.map((instance: RedisInstance) => {\n const redisPath = instance.name.split('/');\n return [instance.displayName || redisPath?.at(-1) || instance.name, instance.host];\n }));\n\n const redisIp = await safeSelect({\n message: 'which redis instance do you want to connect to?',\n choices: Object.entries(redisNameToIpMap).map(([name, ip]) => ({ name, value: ip })),\n default: Object.keys(redisNameToIpMap)[0],\n });\n\n if (!redisIp) {\n console.error('No redis instance selected');\n process.exit(1);\n }\n\n const { stdout: allPodsName } = await asyncSpawn('kubectl', ['get', 'pods', '--no-headers', '-o', 'custom-columns=:metadata.name'], { print: false });\n const redisPodName = allPodsName.split('\\n').find(podName => podName.includes('redis'));\n\n if (!redisPodName?.trim()) {\n console.error('No redis pod found');\n process.exit(1);\n }\n\n try {\n const { promise, resolve, reject } = createDeferredPromise<void>();\n const shell = spawn('kubectl', [\n 'exec',\n '-it',\n redisPodName,\n '--',\n 'redis-cli',\n '-h',\n redisIp,\n ], {\n stdio: 'inherit',\n shell: true,\n });\n shell.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n shell.on('error', (error) => {\n console.error('Process error:', error);\n reject(error);\n });\n\n console.log('Connecting to Redis... Could take a few seconds ⏱️');\n\n await promise;\n\n process.exit(0);\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n process.exit(1);\n }\n};\n","import { readFile } from 'node:fs/promises';\nimport { cwd } from 'node:process';\nimport { join } from 'node:path';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { parseVersion, getMajorVersion, isMajorUpdate } from '../../utils/version-utils.js';\nimport { confirm } from '@inquirer/prompts';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface PackageInfo {\n name: string;\n currentVersion: string;\n latestVersion: string;\n isDev: boolean;\n}\n\ninterface MajorUpdateInfo {\n name: string;\n fromMajor: number;\n toMajor: number;\n currentVersion: string;\n latestVersion: string;\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', packageName, 'version'], { print: false });\n return stdout.trim();\n } catch (_error) {\n console.error(`Failed to get latest version for ${packageName}:`, _error);\n throw _error;\n }\n}\n\nasync function getPeerDependencies(packageName: string, version: string): Promise<Record<string, string> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependencies', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function getPeerDependenciesMeta(packageName: string, version: string): Promise<Record<string, { optional?: boolean; }> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependenciesMeta', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const packageJsonPath = join(cwd(), 'package.json');\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return endWithError(new Error(`Failed to read package.json at ${packageJsonPath}`));\n }\n}\n\nfunction getAutofleetPackages(packageJson: PackageJson): PackageInfo[] {\n const packages: PackageInfo[] = [];\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: false });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(packageJson.devDependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: true });\n }\n }\n }\n\n return packages;\n}\n\ninterface UpdateOptions {\n dryRun?: boolean;\n yes?: boolean;\n quiet?: boolean;\n}\n\nexport default async ({ dryRun = false, yes = false, quiet = false }: UpdateOptions = {}) => {\n const log = (...args: unknown[]) => {\n if (!quiet) console.log(...args);\n };\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN MODE] - No packages will be installed') + '\\n');\n }\n log('Scanning for @autofleet packages...\\n');\n\n const packageJson = await readPackageJson();\n const autofleetPackages = getAutofleetPackages(packageJson);\n\n if (autofleetPackages.length === 0) {\n console.log('No @autofleet packages found in this repository.');\n process.exit(0);\n }\n\n log(`Found ${autofleetPackages.length} @autofleet package(s):\\n`);\n autofleetPackages.forEach((pkg) => {\n log(` - ${pkg.name} (${pkg.currentVersion})`);\n });\n log('');\n\n log('Fetching latest versions...\\n');\n\n // Fetch latest versions\n for (const pkg of autofleetPackages) {\n try {\n pkg.latestVersion = await getLatestVersion(pkg.name);\n } catch {\n endWithError(new Error(`Failed to fetch latest version for ${pkg.name}`));\n }\n }\n\n // Check for packages that are already up to date\n const packagesToUpdate = autofleetPackages.filter(\n pkg => parseVersion(pkg.currentVersion) !== pkg.latestVersion,\n );\n\n if (packagesToUpdate.length === 0) {\n console.log('All @autofleet packages are already up to date!');\n process.exit(0);\n }\n\n // Identify major version updates\n const majorUpdates: MajorUpdateInfo[] = [];\n\n for (const pkg of packagesToUpdate) {\n if (isMajorUpdate(pkg.currentVersion, pkg.latestVersion)) {\n majorUpdates.push({\n name: pkg.name,\n fromMajor: getMajorVersion(pkg.currentVersion),\n toMajor: getMajorVersion(pkg.latestVersion),\n currentVersion: parseVersion(pkg.currentVersion),\n latestVersion: pkg.latestVersion,\n });\n }\n }\n\n // Show major version update warning\n if (majorUpdates.length > 0) {\n log(styleText('yellow', '⚠️ WARNING: The following packages have major version updates:') + '\\n');\n for (const update of majorUpdates) {\n log(` - ${update.name}: v${update.fromMajor}.x.x → v${update.toMajor}.x.x (${update.currentVersion} → ${update.latestVersion})`);\n }\n log('');\n\n if (!dryRun && !yes) {\n const shouldContinue = await confirm({\n message: 'Major version updates may contain breaking changes. Do you want to continue?',\n default: true,\n });\n\n if (!shouldContinue) {\n console.log('Aborting package updates.');\n process.exit(0);\n }\n log('');\n }\n }\n\n // Show packages to update (always print this — it's the key output)\n console.log('Packages to update:\\n');\n for (const pkg of packagesToUpdate) {\n const isMajor = majorUpdates.some(b => b.name === pkg.name);\n const marker = isMajor ? (quiet ? '(major)' : styleText('yellow', '(major)')) : '';\n console.log(` ${pkg.name}: ${parseVersion(pkg.currentVersion)} → ${pkg.latestVersion} ${marker}`);\n }\n console.log('');\n\n // Collect all peer dependencies\n const missingRequiredPeerDeps = new Map<string, string>();\n const missingOptionalPeerDeps = new Map<string, string>();\n\n log('Checking peer dependencies...\\n');\n for (const pkg of packagesToUpdate) {\n const [peerDeps, peerDepsMeta] = await Promise.all([\n getPeerDependencies(pkg.name, pkg.latestVersion),\n getPeerDependenciesMeta(pkg.name, pkg.latestVersion),\n ]);\n\n if (peerDeps) {\n for (const [peerName, peerVersion] of Object.entries(peerDeps)) {\n // Check if peer dependency is already in package.json\n const currentPeerVersion\n = packageJson.dependencies?.[peerName]\n || packageJson.devDependencies?.[peerName];\n\n if (!currentPeerVersion) {\n // Check if this peer dependency is optional\n const isOptional = peerDepsMeta?.[peerName]?.optional === true;\n if (isOptional) {\n missingOptionalPeerDeps.set(peerName, peerVersion);\n } else {\n missingRequiredPeerDeps.set(peerName, peerVersion);\n }\n }\n }\n }\n }\n\n // Handle missing required peer dependencies\n if (missingRequiredPeerDeps.size > 0) {\n log(styleText('yellow', '⚠️ The following peer dependencies are required but not installed:') + '\\n');\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n log(` - ${name}@${version}`);\n }\n log('');\n\n let installRequired = yes; // auto-accept in yes mode\n if (!dryRun && !yes) {\n installRequired = await confirm({\n message: 'Do you want to install these peer dependencies?',\n default: true,\n });\n\n if (!installRequired) {\n console.log(styleText('red', '⚠️ Warning: Skipping peer dependencies may cause issues.'));\n }\n log('');\n }\n\n if (installRequired) {\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would prompt to install required peer dependencies') + '\\n');\n }\n }\n\n // Handle missing optional peer dependencies\n if (missingOptionalPeerDeps.size > 0) {\n log(styleText('cyan', 'ℹ️ The following optional peer dependencies are not installed:') + '\\n');\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n log(` - ${name}@${version} ${styleText('dim', '(optional)')}`);\n }\n log('');\n\n let installOptional = false; // default: skip in yes mode\n if (!dryRun && !yes) {\n installOptional = await confirm({\n message: 'Do you want to install these optional peer dependencies?',\n default: false,\n });\n log('');\n }\n\n if (installOptional) {\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would prompt to install optional peer dependencies') + '\\n');\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would install the following packages:') + '\\n');\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n packagesToInstall.forEach((pkg) => {\n log(` - ${pkg}`);\n });\n log('\\n' + styleText('yellow', '[DRY RUN] Would run: npm dedupe'));\n console.log('\\n' + styleText('green', '✓ Dry run completed successfully!'));\n process.exit(0);\n }\n\n log('Installing packages...\\n');\n\n // Install packages\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n\n try {\n await asyncSpawn('npm', ['install', ...packagesToInstall], { print: !quiet });\n } catch {\n endWithError(new Error('Failed to install packages'));\n }\n\n log('\\nDeduplicating packages...\\n');\n\n try {\n await asyncSpawn('npm', ['dedupe'], { print: !quiet });\n } catch {\n console.error(styleText('yellow', '⚠️ Warning: Failed to deduplicate packages'));\n }\n\n console.log(styleText('green', '✓ All @autofleet packages have been updated successfully!'));\n process.exit(0);\n};\n","import { execSync } from 'node:child_process';\nimport * as path from 'node:path';\nimport fs from 'node:fs';\n\nconst __dirname = import.meta.dirname;\n\nconst isPluginInstalled = (pluginIdentifier: string): boolean => {\n try {\n const output = execSync('claude plugin list', { encoding: 'utf-8' });\n return output.includes(`${pluginIdentifier}`);\n } catch {\n return false;\n }\n};\n\nconst addMarketplace = (marketplacePath: string): void => {\n console.log('📥 Adding Autofleet marketplace...');\n try {\n execSync(`claude plugin marketplace remove autofleet`, { stdio: 'pipe' });\n } catch {\n // Marketplace might not exist, that's fine\n }\n try {\n execSync(`claude plugin marketplace add ${marketplacePath}`, { stdio: 'pipe' });\n console.log('✓ Marketplace added\\n');\n } catch {\n console.log('⚠️ Failed to add marketplace\\n');\n process.exit(1);\n }\n};\n\nconst bumpPluginVersion = (distPluginJsonPath: string): void => {\n const distPluginJson = JSON.parse(fs.readFileSync(distPluginJsonPath, 'utf-8'));\n const [major, minor, patch] = distPluginJson.version.split('.').map(Number);\n const newVersion = `${major}.${minor}.${patch + 1}`;\n\n distPluginJson.version = newVersion;\n fs.writeFileSync(distPluginJsonPath, JSON.stringify(distPluginJson, null, 2) + '\\n');\n};\n\nconst installOrUpdatePlugin = (pluginIdentifier: string, marketplacePath: string): void => {\n if (!isPluginInstalled(pluginIdentifier)) {\n try {\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('⚠️ Failed to install plugin\\n');\n process.exit(1);\n }\n }\n\n console.log('ℹ️ Plugin already installed, reinstalling to get latest version...');\n try {\n const distPluginJsonPath = path.join(marketplacePath, 'plugins/autofleet/.claude-plugin/plugin.json');\n bumpPluginVersion(distPluginJsonPath);\n execSync(`claude plugin remove ${pluginIdentifier}`, { stdio: 'pipe' });\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('⚠️ Failed to reinstall plugin\\n');\n process.exit(1);\n }\n};\n\nexport default () => {\n console.log('🚀 Setting up Autofleet Claude Code plugin...\\n');\n const marketplacePath = path.resolve(__dirname, './claude-marketplace');\n\n addMarketplace(marketplacePath);\n installOrUpdatePlugin('autofleet@autofleet', marketplacePath);\n\n console.log('🎉 Plugin setup complete!\\n');\n process.exit(0);\n};\n","#!/usr/bin/env node\nimport parseArgs from './utils/parser.js';\nimport {\n SUPPORTED_CLUSTERS,\n connectAndGetPrefix, endWithError,\n} from './utils/index.js';\nimport { fillMissingRequiredValues } from './utils/inquirer.js';\nimport { checkForCliUpdate } from './utils/version-check.js';\nimport { getVariationIdFromMirrodConfig } from './utils/mirrord.js';\nimport {\n mirrord,\n switchCluster,\n telepresenceWizard,\n enableSimulator,\n exposeService,\n forwardDb,\n forwardService,\n getIps,\n localDev,\n rabbitCreds,\n updateExp,\n mirrordConfig,\n dockerInit,\n openRedis,\n updateAutofleetPackages,\n claudeInit,\n} from './commands/index.js';\n\nconst clusterOptions = SUPPORTED_CLUSTERS.join('/');\nconst variationAndCluster = `--variationId=<yourVariationUuid> --cluster=<${clusterOptions}>`;\n\nconst COMMANDS = {\n switchCluster: variationAndCluster,\n exposeService: `--service=<driver-ms> ${variationAndCluster}`,\n forwardDb: `${variationAndCluster} --local-port=<localPort>`,\n forwardService: `--service=<driver-ms> ${variationAndCluster} --port=<port> --local-port=<localPort>`,\n getIps: variationAndCluster,\n enableSimulator: variationAndCluster,\n rabbitCreds: variationAndCluster,\n updateExp: variationAndCluster,\n telepresenceWizard: `--service=<driver-ms> ${variationAndCluster} --local-port=<localPort>`,\n localDev: variationAndCluster,\n mirrord: `--service=<driver-ms> ${variationAndCluster}`,\n mirrordConfig: '--variationId=<yourVariationUuid>',\n dockerInit: '',\n openRedis: '--cluster=<${clusterOptions}',\n updateAutofleetPackages: '',\n claudeInit: '',\n};\ntype Command = keyof typeof COMMANDS;\nconst isCommand = (c: string): c is Command => Object.keys(COMMANDS).includes(c);\n\nconst { positionals, values, help } = parseArgs({\n strict: true,\n binName: 'autofleet',\n allowPositionals: true,\n options: {\n cluster: {\n type: 'string',\n short: 'c',\n description: 'The cluster name. One of dev1, e2eManager, expManager',\n },\n variationId: {\n type: 'string',\n short: 'i',\n description: 'The variation id',\n },\n service: {\n type: 'string',\n short: 's',\n description: 'The service name',\n },\n port: {\n type: 'string',\n short: 'p',\n description: 'The remote port to forward',\n },\n 'local-port': {\n type: 'string',\n short: 'l',\n description: 'The local port to forward to',\n },\n 'prefer-pod': {\n type: 'boolean',\n short: 'r',\n default: false,\n description: 'Wether the mirrord command should run against the pod, rather than the deployment.',\n },\n 'dry-run': {\n type: 'boolean',\n short: 'd',\n default: false,\n description: 'Perform a dry run without installing packages',\n },\n yes: {\n type: 'boolean',\n short: 'y',\n default: false,\n description: 'Auto-accept all prompts (non-interactive mode)',\n },\n quiet: {\n type: 'boolean',\n short: 'q',\n default: false,\n description: 'Minimize output (useful for CI/LLM usage)',\n },\n 'skip-open': {\n type: 'boolean',\n short: 'o',\n default: false,\n description: 'Skip opening Postico automatically (forwardDb)',\n },\n },\n commands: COMMANDS,\n});\n\nexport type Values = typeof values;\ntype ValueWithDefault<T = keyof Values> = T | { option: T; defaultVal: string; };\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nif (positionals.length > 1) {\n endWithError('Only one command is allowed', help);\n}\n\nconst [command] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nawait checkForCliUpdate(values.quiet);\n\nconst COMMAND_REQUIRED_VALUES_MAP: Partial<Record<Command, ValueWithDefault[]>> = {\n switchCluster: ['cluster'],\n exposeService: ['cluster', 'variationId', 'service'],\n forwardDb: ['cluster', 'variationId', { option: 'local-port', defaultVal: '5432' }],\n forwardService: ['cluster', 'variationId', 'service', 'port'],\n telepresenceWizard: ['cluster', 'service'],\n mirrordConfig: ['variationId'],\n mirrord: ['cluster', { option: 'variationId', defaultVal: command === 'mirrord' ? await getVariationIdFromMirrodConfig() : '' }, 'service'],\n dockerInit: [],\n openRedis: ['cluster'],\n updateAutofleetPackages: [],\n claudeInit: [],\n};\n\nawait fillMissingRequiredValues(\n values,\n COMMAND_REQUIRED_VALUES_MAP[command] ?? ['cluster', 'variationId'],\n);\nconst { cluster, variationId, service } = values;\n\nswitch (command) {\n case 'mirrordConfig':\n await mirrordConfig(variationId);\n break;\n case 'dockerInit':\n await dockerInit();\n break;\n case 'updateAutofleetPackages':\n await updateAutofleetPackages({ dryRun: values['dry-run'], yes: values.yes, quiet: values.quiet });\n break;\n case 'claudeInit':\n claudeInit();\n break;\n}\n\nif (!cluster) {\n endWithError(new Error('cluster required'), help);\n}\n\nswitch (command) {\n case 'telepresenceWizard':\n await telepresenceWizard(values);\n break;\n case 'switchCluster':\n await switchCluster(cluster, variationId);\n break;\n case 'openRedis':\n await openRedis(cluster);\n break;\n}\n\nif (!variationId) {\n endWithError(new Error('variationId required'), help);\n}\n\nlet prefix: string;\ntry {\n prefix = await connectAndGetPrefix({ clusterName: cluster, variationId });\n} catch (error) {\n endWithError(error as Error);\n}\n\nswitch (command) {\n case 'mirrord':\n await mirrord(prefix, variationId, service);\n break;\n case 'exposeService':\n await exposeService(prefix, help, service);\n break;\n case 'forwardDb':\n await forwardDb(values, prefix, variationId, help, service);\n break;\n case 'forwardService':\n await forwardService(values, prefix, help, service);\n break;\n case 'getIps':\n await getIps(prefix);\n break;\n case 'enableSimulator':\n await enableSimulator(prefix, variationId);\n break;\n case 'rabbitCreds':\n await rabbitCreds();\n break;\n case 'updateExp':\n await updateExp(prefix);\n break;\n case 'localDev':\n await localDev(prefix, cluster, variationId);\n break;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["version","packageJson.version","variationId","asyncSpawn","service","prefix","variationId","cluster","asyncSpawn","asyncSpawn","values","cluster","service","service","help","asyncSpawn","prefix","values","help","variationId","service","asyncSpawn","prefix","values","service","help","asyncSpawn","prefix","asyncSpawn","prefix","asyncSpawn","prefix","variationId","asyncSpawn","serviceName: string | undefined","asyncSpawn","npmTokenFlags: string[]","buildArgFlags: string[]","targetFlag: string[]","buildArgs: Record<string, string>","prefix","envNameToUse: string","cluster","variationId","asyncSpawn","prefix","variationId","path","os","asyncSpawn","asyncSpawn","name","asyncSpawn","version","packages: PackageInfo[]","majorUpdates: MajorUpdateInfo[]","path","parseArgs","mirrordConfig","dockerInit","updateAutofleetPackages","switchCluster","openRedis","prefix: string","mirrord","exposeService","forwardDb","forwardService","getIps","enableSimulator","rabbitCreds","updateExp","localDev"],"sources":["../bin/utils/version-utils.ts","../bin/utils/version-check.ts","../bin/utils/mirrord.ts","../bin/utils/exitHandler.ts","../bin/commands/base/mirrord.ts","../bin/commands/base/switchCluster.ts","../bin/commands/base/telepresenceWizard.ts","../bin/commands/base/exposeService.ts","../bin/commands/base/forwardDb.ts","../bin/commands/base/forwardService.ts","../bin/commands/base/getIps.ts","../bin/commands/base/enableSimulator.ts","../bin/commands/base/rabbitCreds.ts","../bin/commands/base/updateExp.ts","../bin/utils/env.ts","../bin/commands/base/localDev.ts","../bin/commands/base/mirrordConfig.ts","../bin/commands/base/dockerInit.ts","../bin/commands/base/openRedis.ts","../bin/commands/base/updateAutofleetPackages.ts","../bin/commands/base/claude-init/index.ts","../bin/index.ts"],"sourcesContent":["export function parseVersion(version: string): string {\n return version.replace(/^[\\^~]/, '');\n}\n\nexport function getMajorVersion(version: string): number {\n const cleaned = parseVersion(version);\n const match = /^(\\d+)/.exec(cleaned);\n return match ? parseInt(match[1], 10) : 0;\n}\n\nexport function isMajorUpdate(currentVersion: string, latestVersion: string): boolean {\n return getMajorVersion(latestVersion) > getMajorVersion(currentVersion);\n}\n\nexport function isNewer(latest: string, current: string): boolean {\n // ignore pre-release versions (e.g. 2.22.0-beta.1)\n if (latest.includes('-') || current.includes('-')) return false;\n const parse = (v: string) => v.split('.').map(Number) as [number, number, number];\n const [lMaj, lMin, lPat] = parse(latest);\n const [cMaj, cMin, cPat] = parse(current);\n if (lMaj !== cMaj) return lMaj > cMaj;\n if (lMin !== cMin) return lMin > cMin;\n return lPat > cPat;\n}\n","import { execFile, execSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport { promptForConfirmation } from './inquirer.js';\nimport { isNewer } from './version-utils.js';\n\nconst CACHE_FILE = path.join(os.homedir(), '.autofleet', 'update-check.json');\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface UpdateCache {\n latestVersion: string;\n checkedAt: number;\n}\n\nfunction readCache(): UpdateCache | null {\n try {\n return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction writeCache(data: UpdateCache): void {\n try {\n fs.mkdirSync(path.dirname(CACHE_FILE), { recursive: true });\n fs.writeFileSync(CACHE_FILE, JSON.stringify(data));\n } catch {\n // ignore write errors\n }\n}\n\nfunction getGlobalRoot(pm: string, args: string[]): string | null {\n try {\n const root = execSync(`${pm} ${args.join(' ')}`, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();\n return root || null;\n } catch {\n return null;\n }\n}\n\nfunction detectPackageManager(): string {\n const script = process.argv[1] ?? '';\n const candidates: { pm: string; args: string[]; }[] = [\n { pm: 'pnpm', args: ['root', '-g'] },\n { pm: 'yarn', args: ['global', 'dir'] },\n { pm: 'npm', args: ['root', '-g'] },\n ];\n for (const { pm, args } of candidates) {\n const root = getGlobalRoot(pm, args);\n if (root && script.startsWith(root)) return pm;\n }\n return 'npm';\n}\n\nfunction buildInstallCommand(pm: string): string {\n if (pm === 'pnpm') return 'pnpm add -g @autofleet/cli@latest';\n if (pm === 'yarn') return 'yarn global add @autofleet/cli@latest';\n const npmBin = path.join(path.dirname(process.execPath), 'npm');\n return `${npmBin} install -g @autofleet/cli@latest`;\n}\n\nfunction fetchLatestVersionInBackground(): void {\n const child = execFile(\n 'npm',\n ['view', '@autofleet/cli@latest', 'version'],\n { encoding: 'utf-8', timeout: 15_000 },\n (error, stdout) => {\n if (error || !stdout.trim()) return;\n const latest = stdout.trim();\n if (latest) {\n writeCache({ latestVersion: latest, checkedAt: Date.now() });\n }\n },\n );\n child.unref();\n}\n\nexport async function checkForCliUpdate(quiet = false): Promise<void> {\n if (quiet) return;\n const cache = readCache();\n\n if (cache && isNewer(cache.latestVersion, packageJson.version)) {\n const shouldUpdate = await promptForConfirmation(\n `New @autofleet/cli version available (${packageJson.version} → ${cache.latestVersion}). Update now?`,\n );\n if (shouldUpdate) {\n const pm = detectPackageManager();\n const installCmd = buildInstallCommand(pm);\n console.log('Updating @autofleet/cli...');\n execSync(installCmd, { stdio: 'inherit' });\n console.log('✓ Updated! Please re-run your command.');\n process.exit(0);\n }\n }\n\n const cacheAge = cache ? Date.now() - cache.checkedAt : Infinity;\n if (cacheAge > CHECK_INTERVAL_MS) {\n fetchLatestVersionInBackground();\n }\n}\n","import { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { getGitPath } from './git.js';\nimport { mkdir, writeFile, readFile } from 'node:fs/promises';\n\nexport const MIRRORD_FOLDER_NAME = '.mirrord';\n\nexport async function getMirrodConfigPath({ makeDir = false } = {}) {\n const repoPath = await getGitPath();\n const mirrordPath = join(repoPath, MIRRORD_FOLDER_NAME);\n if (makeDir) {\n await mkdir(mirrordPath, { recursive: true });\n }\n return join(mirrordPath, 'mirrord.json');\n}\n\nexport async function writeMirrordFile(variationId: string = randomUUID()) {\n const mirrordPath = await getMirrodConfigPath({ makeDir: true });\n const mirrordConfigData = {\n feature: {\n network: {\n incoming: {\n mode: 'steal',\n http_filter: {\n ports: [8080],\n path_filter: '^(?!/alive|/ready)',\n },\n },\n outgoing: true,\n },\n fs: 'read',\n env: true,\n },\n target: {\n namespace: variationId,\n },\n agent: {\n ephemeral: true,\n startup_timeout: 600,\n communication_timeout: 120,\n namespace: variationId,\n },\n };\n await writeFile(mirrordPath, JSON.stringify(mirrordConfigData, null, 2));\n\n return { mirrordConfigData, mirrordPath };\n}\n\nexport async function getVariationIdFromMirrodConfig() {\n try {\n const mirrordPath = await getMirrodConfigPath();\n const mirrordConfigDataString = await readFile(mirrordPath, { encoding: 'utf-8' });\n const mirrordConfigData = JSON.parse(mirrordConfigDataString || '{}') as { target?: { namespace?: string; }; };\n return mirrordConfigData?.target?.namespace ?? '';\n } catch {\n return '';\n }\n}\n","export function registerProcessForCleanup(onExit: (e?: unknown) => void | PromiseLike<void>) {\n process.once('exit', onExit);\n process.once('SIGTERM', onExit);\n process.once('SIGINT', onExit);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { registerProcessForCleanup } from '../../utils/exitHandler.js';\nimport { getMirrodConfigPath } from '../../utils/mirrord.js';\n\ndeclare global {\n var executedExitHooks: boolean;\n}\n\nfunction trimProbeString(str: string): string {\n str &&= str.trim();\n if (!str) {\n return str;\n }\n if (str.startsWith('\\'') && str.endsWith('\\'')) {\n str = str.slice(1, -1);\n }\n return str;\n}\n\nconst LIVENESS_PROBE = 'livenessProbe';\nconst READINESS_PROBE = 'readinessProbe';\nconst WORKER_PATH = (leaf: string) => `jsonpath='{.spec.template.spec.containers[?(@.name==\"worker\")].${leaf}}'`;\nconst SET_PROBE_VALUES = (...probeAndValues: [string, string][]) =>\n `{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"worker\",${probeAndValues\n .map(([probe, value]) => `\"${probe}\": ${value}`)\n .join(',')}}]}}}}`;\n\nexport default async (prefix: string, variationId: string, service?: string) => {\n console.log('Will now disable health check to allow debugging.');\n let [{ stdout: livenessProbe }, { stdout: readinessProbe }] = await Promise.all([\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(LIVENESS_PROBE)], { print: false }),\n asyncSpawn('kubectl', ['get', `deployment/${service}`, prefix, '-o', WORKER_PATH(READINESS_PROBE)], { print: false }),\n ]);\n livenessProbe &&= trimProbeString(livenessProbe);\n readinessProbe &&= trimProbeString(readinessProbe);\n if (livenessProbe || readinessProbe) {\n await asyncSpawn('kubectl', ['patch', `deployment/${service}`, prefix, '--patch', SET_PROBE_VALUES([LIVENESS_PROBE, 'null'], [READINESS_PROBE, 'null'])], { print: false });\n console.log('Health check disabled, will now start mirrord and run \"npm run dev\". Make sure to attach a debugger!');\n }\n const abortController = new AbortController();\n registerProcessForCleanup(async () => {\n if (globalThis.executedExitHooks) {\n return;\n }\n globalThis.executedExitHooks = true;\n abortController.abort();\n if (livenessProbe || readinessProbe) {\n console.log('Re-enabling health check.');\n await asyncSpawn(\n 'kubectl',\n [\n 'patch',\n `deployment/${service}`,\n prefix,\n '--patch',\n `'${SET_PROBE_VALUES(\n [LIVENESS_PROBE, livenessProbe],\n [READINESS_PROBE, readinessProbe],\n )}'`,\n ],\n { print: false, shell: true },\n );\n console.log('health check enabled.');\n }\n process.exit(0);\n });\n try {\n const mirrordPath = await getMirrodConfigPath();\n await asyncSpawn('mirrord', ['exec', '-t', `deployment/${service}`, '-n', variationId, '-f', mirrordPath, '--steal', 'npm', 'run', 'dev'], { signal: abortController.signal });\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'ABORT_ERR') {\n return;\n }\n endWithError(error as Error);\n }\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getCurrentNamespace } from '../../utils/index.js';\nimport { fillMissingRequiredValues } from '../../utils/inquirer.js';\n\nexport default async (cluster: string, variationId?: string) => {\n await connectToCluster(cluster);\n\n if (cluster === 'expManager' || cluster === 'dev1') {\n const { variationId: namespace } = await fillMissingRequiredValues({ variationId }, ['variationId']);\n if (namespace !== '') {\n if (await getCurrentNamespace() === namespace) {\n console.log(`Already connected to simulation with uuid: ${namespace}, skipping namespace switch...`);\n process.exit(0);\n }\n await asyncSpawn('kubectl', ['config', 'set-context', '--current', `--namespace=${namespace}`], { print: false });\n console.log(`Switched to simulation with uuid: ${namespace} successfully`);\n }\n }\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getVariationId, getLocalPort, safeSelect } from '../../utils/inquirer.js';\nimport { connectToCluster, endWithError } from '../../utils/index.js';\nimport type { Values } from '../../index.js';\n\nasync function ensureTelepresenceInstalled() {\n try {\n await asyncSpawn('telepresence', ['version'], { print: false });\n } catch {\n endWithError('Telepresence is not installed. Please install it from:\\nhttps://www.telepresence.io/docs/latest/quick-start/');\n }\n}\n\nfunction leaveOrConnect() {\n return safeSelect({\n message: 'Do you want to leave the connection or create a new one?',\n choices: [\n { name: 'Leave the current connection', value: 'leave' },\n { name: 'Create a new connection', value: 'connect' },\n ] as const,\n default: 'connect',\n });\n}\n\nexport default async function telepresenceWizard(values: Values): Promise<void> {\n await ensureTelepresenceInstalled();\n\n const { cluster = '', service = '' } = values; // Values should be defined by now, thanks to inquirer. Default to hint to TS we always have values.\n await connectToCluster(cluster);\n\n const action = await leaveOrConnect();\n if (!['leave', 'connect'].includes(action!)) {\n endWithError('Invalid action, how did you get here? 🤔');\n }\n if (action === 'leave') {\n await asyncSpawn('telepresence', ['leave', service]);\n console.log('Disconnected! 👋');\n return;\n }\n const namespace = values.variationId || await getVariationId();\n const localPort = (values['local-port'] && Number.parseInt(values['local-port'], 10)) || Number.parseInt((await getLocalPort()) || '', 10);\n await asyncSpawn('telepresence', ['connect', `--namespace=${namespace}`]);\n await asyncSpawn('telepresence', ['intercept', service, '--port', localPort.toString(), '--env-file=./.env']);\n console.log('Everything is set up! 🚀');\n console.log(`You can now access the service at localhost:${localPort}`);\n console.log('You can only have one connection at a time. If you want to connect to a different service, you need to leave the current connection first.');\n process.exit(0);\n}\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\nexport default async (prefix: string, help: string, service?: string) => {\n if (!service) {\n endWithError(new Error('service is required for exposeService'), help);\n }\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, service, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n console.log(`exposed ${service} successfully. the service is now creating an internal load balancer ip to use with vpn`);\n process.exit(0);\n};\n","import { setTimeout } from 'node:timers/promises';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n 'local-port'?: string;\n 'skip-open'?: boolean;\n}\n\nexport default async (values: Values, prefix: string, variationId: string, help: string, service?: string) => {\n const localPort = Number.parseInt(values['local-port'] ?? '5432', 10);\n if (Number.isNaN(localPort)) {\n endWithError(new Error('if defined, local-port must be a number'), help);\n }\n const DB_PASSWORD = `afpass_${variationId}`;\n const USER_NAME = 'postgres';\n const variationUnderScore = variationId.replaceAll('-', '_');\n const DB_NAME = service ? `${service.replaceAll('-', '_') || ''}_${variationUnderScore}` : 'postgres';\n\n const postgressPath = `postgres://${USER_NAME}:${DB_PASSWORD}@localhost:${localPort}/${DB_NAME}?&nickname=var_${variationId}`;\n console.log(`Forwarding db to local port ${localPort}.\\naccess the DB at ${postgressPath}\\nPress ctrl+c to stop.`);\n\n const dbEnvs = ` DB_USERNAME=${USER_NAME}\n DB_PASSWORD=${DB_PASSWORD}\n DB_NAME=${service ? DB_NAME : `<service_name>_${variationUnderScore}`}`;\n console.log('Generated database environment for local development:\\n', dbEnvs);\n\n if (!values['skip-open']) {\n console.log('\\n' + styleText('cyan', '[Tip] Already have Postico open? Use --skip-open (or -o) to skip opening a new window.') + '\\n');\n setTimeout(1500).then(() => asyncSpawn('open', [postgressPath], { print: false })).catch(() => null);\n }\n await asyncSpawn('kubectl', [prefix, 'port-forward', `svc/p${variationId}-postgresql`, `${localPort}:5432`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\n\ninterface Values {\n port?: string;\n 'local-port'?: string;\n}\n\nexport default async (values: Values, prefix: string, help: string, service?: string) => {\n const port = Number.parseInt(values.port ?? '8080', 10);\n const localPort = Number.parseInt(values['local-port'] ?? '', 10) || port;\n if (!service) {\n endWithError(new Error('service is required for forwardService'), help);\n }\n if (!port || Number.isNaN(port)) {\n endWithError(new Error('port is required and must be a numbers'), help);\n }\n if (localPort && Number.isNaN(localPort)) {\n endWithError(new Error('local-port must be a number'), help);\n }\n let { stdout: podName } = await asyncSpawn('kubectl', ['get', 'pods', prefix, '-l', `service=${service}`, '-o', 'jsonpath=\"{.items[0].metadata.name}\"'], { print: false });\n podName &&= podName.trim();\n if (!podName) {\n endWithError(new Error(`No pods found for service ${service}`));\n }\n if (podName.startsWith('\"') && podName.endsWith('\"')) {\n podName = podName.slice(1, -1);\n }\n console.log(`Found pod ${podName}, serving locally on port ${localPort} from remote port ${port}.\\nPress ctrl+c to stop.`);\n await asyncSpawn('kubectl', ['port-forward', prefix, podName, `${localPort}:${port}`], { print: false });\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { parseIps } from '../../utils/index.js';\n\nexport default async (prefix: string) => {\n const { stdout } = await asyncSpawn('kubectl', [prefix, 'get', 'services'], { print: false });\n const ips = parseIps(stdout);\n ips.forEach(ip => console.log(ip));\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async (prefix: string, variationId: string) => {\n const SIMULATION_CLUSTER_FRONT = 'simulation-cluster-front';\n await asyncSpawn('kubectl', ['annotate', prefix, 'service', SIMULATION_CLUSTER_FRONT, 'cloud.google.com/load-balancer-type-']);\n await asyncSpawn('kubectl', ['patch', 'svc', prefix, SIMULATION_CLUSTER_FRONT, '-p', '{\"spec\": {\"type\": \"LoadBalancer\"}}']);\n await asyncSpawn('kubectl', ['create', prefix, 'rolebinding', 'admin', '--clusterrole=cluster-admin', `--serviceaccount=${variationId}:default`]);\n console.log(`Successfully exposed ${SIMULATION_CLUSTER_FRONT} and added role binding to dispatch simulations`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\n\nexport default async () => {\n const getArgs = (dataKey: string) => ['get', 'secret', 'rabbitmq-default-user', '-o', `jsonpath=\"{.data.${dataKey}}\"`];\n const [{ stdout: username }, { stdout: password }] = await Promise.all([\n asyncSpawn('kubectl', getArgs('username'), { print: false }),\n asyncSpawn('kubectl', getArgs('password'), { print: false }),\n ]);\n console.log(`username: ${Buffer.from(username, 'base64').toString('ascii')}`);\n console.log(`password: ${Buffer.from(password, 'base64').toString('ascii')}`);\n process.exit(0);\n};\n","import asyncSpawn from '../../utils/asyncSpawn.js';\nimport { basename, join, sep } from 'node:path';\nimport { cwd } from 'node:process';\nimport { getCurrentBranch, getGitPath, getRemoteUrl } from '../../utils/git.js';\nimport { getAutorepoAppName } from '../../utils/inquirer.js';\nimport { homedir } from 'node:os';\nimport { readFile } from 'node:fs/promises';\n\nconst NPM_AUTH_TOKEN_REGEX = /_authToken\\s*=\\s*\"?([^\\s\"]+)\"?/;\n\nconst resolveNpmToken = async (): Promise<string | undefined> => {\n if (process.env.NPM_TOKEN) return process.env.NPM_TOKEN;\n try {\n const npmrc = await readFile(join(homedir(), '.npmrc'), 'utf-8');\n const match = NPM_AUTH_TOKEN_REGEX.exec(npmrc);\n return match?.[1];\n } catch {\n return undefined;\n }\n};\n\nexport default async (prefix: string) => {\n const gitPath = await getGitPath();\n const remoteUrl = await getRemoteUrl();\n const isAutorepo = remoteUrl\n ? /[/:]Autofleet\\/autorepo(\\.git)?$/i.test(remoteUrl)\n : gitPath.split(sep).pop() === 'autorepo';\n let serviceName: string | undefined;\n if (isAutorepo) {\n serviceName = await getAutorepoAppName(gitPath);\n if (!serviceName) {\n console.error('No service name provided, exiting...');\n process.exit(1);\n }\n } else {\n serviceName = basename(cwd());\n }\n const [branchName, archResult] = await Promise.all([getCurrentBranch(), asyncSpawn('uname', ['-m'], { print: false })]);\n const arch = archResult.stdout.trim();\n const date = new Date();\n const dateSuffix = `${date.getHours().toString().padStart(2, '0')}-${date.getMinutes().toString().padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}`;\n const sanitizedBranch = branchName.replace(/[^a-zA-Z0-9._-]/g, '-');\n const imageName = `gcr.io/autofleetprod/${serviceName}:${sanitizedBranch}-${dateSuffix}`;\n console.log(`Building and pushing image ${imageName}`);\n const platformFlag = arch === 'x86_64' ? [] : ['--platform', 'linux/amd64'];\n\n const npmTokenFlags: string[] = [];\n let buildArgFlags: string[] = [];\n let targetFlag: string[] = [];\n\n if (isAutorepo) {\n npmTokenFlags.push('--secret', 'id=npm_token,env=NPM_TOKEN');\n const { stdout: packagesOutput } = await asyncSpawn('ls', ['-1', 'packages'], { print: false });\n const packages = packagesOutput.trim().replace(/\\n/g, ' ');\n\n const buildArgs: Record<string, string> = {\n APP: serviceName,\n PACKAGES: packages,\n BRANCH: branchName,\n };\n\n const projectJsonPath = `${gitPath}/apps/${serviceName}/project.json`;\n const projectJson = JSON.parse(await readFile(projectJsonPath, 'utf-8'));\n const tags = projectJson.tags || [];\n\n // Apps with elasticsearch tag need NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed certs\n if (tags.includes('elasticsearch')) {\n buildArgs.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n const targetBuildType = serviceName.endsWith('-ms') ? 'backend' : 'frontend';\n if (targetBuildType === 'frontend') {\n const apiSource = ['partner-admin', 'web-booker', 'driver-level-ordering-portal'].includes(serviceName) ? 'client' : 'api';\n buildArgs.API_SOURCE = apiSource;\n }\n\n buildArgFlags = Object.entries(buildArgs)\n .flatMap(([key, val]) => ['--build-arg', `${key}=${val}`]);\n\n targetFlag = ['--target', targetBuildType];\n } else {\n const npmToken = await resolveNpmToken();\n if (!npmToken) {\n console.error('NPM_TOKEN not found in environment or ~/.npmrc, exiting...');\n process.exit(1);\n }\n\n npmTokenFlags.push('--build-arg', `NPM_TOKEN=${npmToken}`);\n }\n\n await asyncSpawn('docker', ['build', '.', '-f', 'Dockerfile', ...targetFlag, ...platformFlag, '-t', imageName, ...buildArgFlags, ...npmTokenFlags]);\n await asyncSpawn('docker', ['push', imageName]);\n const { stdout: podDescription } = await asyncSpawn('kubectl', ['describe', 'pod', prefix, '-l', `service=${serviceName}`], { print: false });\n if (podDescription.includes('Init Containers:')) {\n await asyncSpawn('kubectl', ['patch', `deployment/${serviceName}`, prefix, '--patch', `{\"spec\": {\"template\": {\"spec\": {\"initContainers\": [{\"name\": \"init\",\"image\": \"${imageName}\"}]}}}}`]);\n }\n await asyncSpawn('kubectl', ['set', 'image', `deployment/${serviceName}`, `worker=${imageName}`, prefix]);\n await asyncSpawn('kubectl', ['rollout', 'status', 'deployments', serviceName, prefix]);\n process.exit(0);\n};\n","import { EOL } from 'node:os';\nimport { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\n\nexport async function setEnvValue(repoRoot: string, key: string, value: string): Promise<boolean> {\n const filePath = resolve(repoRoot, '.env');\n const envFileContent = await readFile(filePath, 'utf8');\n const envVars = envFileContent.split(EOL);\n\n // (?<!#\\\\s*) Negative lookbehind to avoid matching comments (lines that starts with #).\n // There is a double slash in the RegExp constructor to escape it.\n // (?==) Positive lookahead to check if there is an equal sign right after the key.\n // This is to prevent matching keys prefixed with the key of the env var to update.\n const regexString = `(?<!#\\\\s*)${key}(?==)`;\n const matchingLine = envVars.find((line: string) => line.match(regexString));\n\n if (matchingLine?.split('=').at(-1) === value) {\n return false;\n }\n\n const target = matchingLine ? envVars.indexOf(matchingLine) : -1;\n\n if (target !== -1) {\n envVars.splice(target, 1, `${key}=${value}`);\n } else {\n envVars.push(`${key}=${value}`);\n }\n\n await writeFile(filePath, envVars.join(EOL));\n return true;\n}\n","import { basename } from 'node:path';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { getGitPath } from '../../utils/git.js';\nimport { endWithError } from '../../utils/index.js';\nimport { setEnvValue } from '../../utils/env.js';\n\nexport default async (prefix: string, cluster: string, variationId: string) => {\n const LOCAL_ENV_NAME = 'LOCAL_ENV_NAME';\n const API_GATEWAY_MS = 'api-gateway-ms';\n const CONTROL_CENTER_MS = 'control-center-ms';\n let envNameToUse: string;\n if (cluster.toLocaleLowerCase().includes('prod')) {\n envNameToUse = 'production';\n } else if (cluster === 'staging') {\n envNameToUse = 'staging';\n } else {\n envNameToUse = `simulator-${variationId}`;\n }\n\n const repoPath = await getGitPath();\n if (basename(repoPath) !== 'control-center') {\n endWithError(new Error('The `localDev` command must be run from the control-center repository'));\n }\n\n const apiGatewayMsIP = 'localhost:8081';\n const changedAiGatewayMsIP = await setEnvValue(repoPath, 'API_GATEWAY_MS_SERVICE_HOST', apiGatewayMsIP);\n\n if (changedAiGatewayMsIP) {\n console.log(`Updated .env file to use ${API_GATEWAY_MS} IP (${apiGatewayMsIP}).`);\n }\n\n const controlCenterMsIP = 'localhost:8085';\n const changedControlCenterIP = await setEnvValue(repoPath, 'CONTROL_CENTER_MS_SERVICE_HOST', controlCenterMsIP);\n\n if (changedControlCenterIP) {\n console.log(`Updated .env file to use ${CONTROL_CENTER_MS} IP (${controlCenterMsIP}).`);\n }\n\n const changedEnvName = await setEnvValue(repoPath, LOCAL_ENV_NAME, envNameToUse);\n\n if (changedEnvName) {\n console.log(`Updated .env file ${LOCAL_ENV_NAME} to ${envNameToUse} (used for firebase setup).`);\n }\n\n const controlCenterProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${CONTROL_CENTER_MS}`, '8085:80'], { print: false });\n const apiGatewayProcess = asyncSpawn('kubectl', ['port-forward', prefix, `svc/${API_GATEWAY_MS}`, '8081:80'], { print: false });\n\n console.log(`Starting port-forwarding of ${CONTROL_CENTER_MS} to port 8085`);\n console.log(`Starting port-forwarding of ${API_GATEWAY_MS} to port 8081`);\n console.log('Press Ctrl+C to stop the port-forwarding processes.');\n\n await Promise.all([controlCenterProcess, apiGatewayProcess]);\n};\n","import { resolve } from 'node:path';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { isPathIgnored } from '../../utils/git.js';\nimport { writeMirrordFile, MIRRORD_FOLDER_NAME } from '../../utils/mirrord.js';\n\nasync function addToGitIgnore(mirrordPath: string) {\n const isIgnored = await isPathIgnored(MIRRORD_FOLDER_NAME);\n if (isIgnored) {\n return;\n }\n const gitIgnoreFile = resolve(mirrordPath, '..', '..', '.gitignore');\n const gitIgnoreFileContent = await readFile(gitIgnoreFile, 'utf8');\n const gitIgnoreFileContentLines = gitIgnoreFileContent.split('\\n').filter(Boolean);\n gitIgnoreFileContentLines.push(MIRRORD_FOLDER_NAME);\n await writeFile(gitIgnoreFile, `${gitIgnoreFileContentLines.join('\\n')}\\n`);\n}\n\nexport default async (variationId?: string) => {\n const { mirrordConfigData, mirrordPath } = await writeMirrordFile(variationId);\n await addToGitIgnore(mirrordPath);\n console.log('Wrote the default mirrord config for the requested variation ID', { mirrordConfigData });\n process.exit(0);\n};\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\n\nconst dockerComposeFile = `\nservices:\n redis:\n image: redis:6\n ports:\n - \"6379:6379\"\n volumes:\n - redis_data:/data\n command: redis-server --appendonly yes\n\n rabbitmq:\n image: rabbitmq:3.12.13-management\n ports:\n - \"5672:5672\" # AMQP protocol port\n - \"15672:15672\" # Management UI port\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n environment:\n - RABBITMQ_DEFAULT_USER=guest\n - RABBITMQ_DEFAULT_PASS=guest\n\n postgres:\n image: postgis/postgis:14-3.3\n platform: linux/amd64\n ports:\n - \"5432:5432\"\n volumes:\n - postgres_data:/var/lib/postgresql/data\n environment:\n - POSTGRES_DB=postgres\n - POSTGRES_USER=postgres\n - POSTGRES_PASSWORD=postgres\n\n elasticsearch:\n image: docker.elastic.co/elasticsearch/elasticsearch:8.8.1\n ports:\n - \"9200:9200\"\n - \"9300:9300\"\n environment:\n - discovery.type=single-node\n - xpack.security.enabled=false\n - xpack.security.transport.ssl.enabled=false\n - xpack.security.http.ssl.enabled=false\n - ES_JAVA_OPTS=-Xms1g -Xmx1g\n volumes:\n - elasticsearch_data:/usr/share/elasticsearch/data\n ulimits:\n memlock:\n soft: -1\n hard: -1\n mem_limit: 2g\n\n kibana:\n image: docker.elastic.co/kibana/kibana:8.8.1\n ports:\n - \"5601:5601\"\n environment:\n - ELASTICSEARCH_HOSTS=http://elasticsearch:9200\n depends_on:\n - elasticsearch\n\nvolumes:\n redis_data:\n rabbitmq_data:\n postgres_data:\n elasticsearch_data:\n`;\n\nexport default async () => {\n const dockerComposePath = path.join(os.tmpdir(), 'docker-compose.yml');\n fs.writeFileSync(dockerComposePath, dockerComposeFile);\n await asyncSpawn('docker-compose', ['-f', dockerComposePath, 'up', '-d'], { print: false });\n console.log('--------------------------------------------------------------------------------');\n console.log('Successfully started the services:\\n');\n console.log('redis: localhost:6379 🚀');\n console.log('postgres: localhost:5432, user: postgres, password: postgres 🐘');\n console.log('rabbitmq: localhost:5672 and http://localhost:15672, user: guest, password: guest 🐇');\n console.log('elasticsearch: localhost:9200 ❓');\n console.log('kibana: http://localhost:5601 ❓');\n process.exit(0);\n};\n","import { spawn } from 'node:child_process';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { connectToCluster, getRedisRegion, isSimulationCluster } from '../../utils/index.js';\nimport { safeSelect } from '../../utils/inquirer.js';\nimport { createDeferredPromise } from '../../utils/promise.js';\n\ninterface RedisInstance {\n displayName?: string;\n host: string;\n name: string;\n}\n\nexport default async (clusterName: string) => {\n if (isSimulationCluster(clusterName)) {\n console.error('Connecting to Redis is not supported for simulation clusters (need to be added)');\n process.exit(1);\n }\n\n const {\n project,\n name,\n } = await connectToCluster(clusterName);\n const redisRegion = getRedisRegion(clusterName);\n const { stdout: redisInstances } = await asyncSpawn('gcloud', ['redis', 'instances', 'list', '--region', redisRegion, '--project', project || name, '--format', 'json'], { print: false });\n let redisInstancesJson;\n try {\n redisInstancesJson = JSON.parse(redisInstances) as RedisInstance[];\n } catch (e) {\n console.error('Failed to parse redis instances', { redisInstances, e });\n process.exit(1);\n }\n\n const redisNameToIpMap = Object.fromEntries(redisInstancesJson.map((instance: RedisInstance) => {\n const redisPath = instance.name.split('/');\n return [instance.displayName || redisPath?.at(-1) || instance.name, instance.host];\n }));\n\n const redisIp = await safeSelect({\n message: 'which redis instance do you want to connect to?',\n choices: Object.entries(redisNameToIpMap).map(([name, ip]) => ({ name, value: ip })),\n default: Object.keys(redisNameToIpMap)[0],\n });\n\n if (!redisIp) {\n console.error('No redis instance selected');\n process.exit(1);\n }\n\n const { stdout: allPodsName } = await asyncSpawn('kubectl', ['get', 'pods', '--no-headers', '-o', 'custom-columns=:metadata.name'], { print: false });\n const redisPodName = allPodsName.split('\\n').find(podName => podName.includes('redis'));\n\n if (!redisPodName?.trim()) {\n console.error('No redis pod found');\n process.exit(1);\n }\n\n try {\n const { promise, resolve, reject } = createDeferredPromise<void>();\n const shell = spawn('kubectl', [\n 'exec',\n '-it',\n redisPodName,\n '--',\n 'redis-cli',\n '-h',\n redisIp,\n ], {\n stdio: 'inherit',\n shell: true,\n });\n shell.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n shell.on('error', (error) => {\n console.error('Process error:', error);\n reject(error);\n });\n\n console.log('Connecting to Redis... Could take a few seconds ⏱️');\n\n await promise;\n\n process.exit(0);\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n process.exit(1);\n }\n};\n","import { readFile } from 'node:fs/promises';\nimport { cwd } from 'node:process';\nimport { join } from 'node:path';\nimport { styleText } from 'node:util';\nimport asyncSpawn from '../../utils/asyncSpawn.js';\nimport { endWithError } from '../../utils/index.js';\nimport { parseVersion, getMajorVersion, isMajorUpdate } from '../../utils/version-utils.js';\nimport { confirm } from '@inquirer/prompts';\n\ninterface PackageJson {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface PackageInfo {\n name: string;\n currentVersion: string;\n latestVersion: string;\n isDev: boolean;\n}\n\ninterface MajorUpdateInfo {\n name: string;\n fromMajor: number;\n toMajor: number;\n currentVersion: string;\n latestVersion: string;\n}\n\nasync function getLatestVersion(packageName: string): Promise<string> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', packageName, 'version'], { print: false });\n return stdout.trim();\n } catch (_error) {\n console.error(`Failed to get latest version for ${packageName}:`, _error);\n throw _error;\n }\n}\n\nasync function getPeerDependencies(packageName: string, version: string): Promise<Record<string, string> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependencies', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function getPeerDependenciesMeta(packageName: string, version: string): Promise<Record<string, { optional?: boolean; }> | undefined> {\n try {\n const { stdout } = await asyncSpawn('npm', ['view', `${packageName}@${version}`, 'peerDependenciesMeta', '--json'], { print: false });\n const trimmedOutput = stdout.trim();\n if (!trimmedOutput || trimmedOutput === '') {\n return undefined;\n }\n return JSON.parse(trimmedOutput);\n } catch {\n return undefined;\n }\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const packageJsonPath = join(cwd(), 'package.json');\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return endWithError(new Error(`Failed to read package.json at ${packageJsonPath}`));\n }\n}\n\nfunction getAutofleetPackages(packageJson: PackageJson): PackageInfo[] {\n const packages: PackageInfo[] = [];\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: false });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(packageJson.devDependencies)) {\n if (name.startsWith('@autofleet/')) {\n packages.push({ name, currentVersion: version, latestVersion: '', isDev: true });\n }\n }\n }\n\n return packages;\n}\n\ninterface UpdateOptions {\n dryRun?: boolean;\n yes?: boolean;\n quiet?: boolean;\n}\n\nexport default async ({ dryRun = false, yes = false, quiet = false }: UpdateOptions = {}) => {\n const log = (...args: unknown[]) => {\n if (!quiet) console.log(...args);\n };\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN MODE] - No packages will be installed') + '\\n');\n }\n log('Scanning for @autofleet packages...\\n');\n\n const packageJson = await readPackageJson();\n const autofleetPackages = getAutofleetPackages(packageJson);\n\n if (autofleetPackages.length === 0) {\n console.log('No @autofleet packages found in this repository.');\n process.exit(0);\n }\n\n log(`Found ${autofleetPackages.length} @autofleet package(s):\\n`);\n autofleetPackages.forEach((pkg) => {\n log(` - ${pkg.name} (${pkg.currentVersion})`);\n });\n log('');\n\n log('Fetching latest versions...\\n');\n\n // Fetch latest versions\n for (const pkg of autofleetPackages) {\n try {\n pkg.latestVersion = await getLatestVersion(pkg.name);\n } catch {\n endWithError(new Error(`Failed to fetch latest version for ${pkg.name}`));\n }\n }\n\n // Check for packages that are already up to date\n const packagesToUpdate = autofleetPackages.filter(\n pkg => parseVersion(pkg.currentVersion) !== pkg.latestVersion,\n );\n\n if (packagesToUpdate.length === 0) {\n console.log('All @autofleet packages are already up to date!');\n process.exit(0);\n }\n\n // Identify major version updates\n const majorUpdates: MajorUpdateInfo[] = [];\n\n for (const pkg of packagesToUpdate) {\n if (isMajorUpdate(pkg.currentVersion, pkg.latestVersion)) {\n majorUpdates.push({\n name: pkg.name,\n fromMajor: getMajorVersion(pkg.currentVersion),\n toMajor: getMajorVersion(pkg.latestVersion),\n currentVersion: parseVersion(pkg.currentVersion),\n latestVersion: pkg.latestVersion,\n });\n }\n }\n\n // Show major version update warning\n if (majorUpdates.length > 0) {\n log(styleText('yellow', '⚠️ WARNING: The following packages have major version updates:') + '\\n');\n for (const update of majorUpdates) {\n log(` - ${update.name}: v${update.fromMajor}.x.x → v${update.toMajor}.x.x (${update.currentVersion} → ${update.latestVersion})`);\n }\n log('');\n\n if (!dryRun && !yes) {\n const shouldContinue = await confirm({\n message: 'Major version updates may contain breaking changes. Do you want to continue?',\n default: true,\n });\n\n if (!shouldContinue) {\n console.log('Aborting package updates.');\n process.exit(0);\n }\n log('');\n }\n }\n\n // Show packages to update (always print this — it's the key output)\n console.log('Packages to update:\\n');\n for (const pkg of packagesToUpdate) {\n const isMajor = majorUpdates.some(b => b.name === pkg.name);\n const marker = isMajor ? (quiet ? '(major)' : styleText('yellow', '(major)')) : '';\n console.log(` ${pkg.name}: ${parseVersion(pkg.currentVersion)} → ${pkg.latestVersion} ${marker}`);\n }\n console.log('');\n\n // Collect all peer dependencies\n const missingRequiredPeerDeps = new Map<string, string>();\n const missingOptionalPeerDeps = new Map<string, string>();\n\n log('Checking peer dependencies...\\n');\n for (const pkg of packagesToUpdate) {\n const [peerDeps, peerDepsMeta] = await Promise.all([\n getPeerDependencies(pkg.name, pkg.latestVersion),\n getPeerDependenciesMeta(pkg.name, pkg.latestVersion),\n ]);\n\n if (peerDeps) {\n for (const [peerName, peerVersion] of Object.entries(peerDeps)) {\n // Check if peer dependency is already in package.json\n const currentPeerVersion\n = packageJson.dependencies?.[peerName]\n || packageJson.devDependencies?.[peerName];\n\n if (!currentPeerVersion) {\n // Check if this peer dependency is optional\n const isOptional = peerDepsMeta?.[peerName]?.optional === true;\n if (isOptional) {\n missingOptionalPeerDeps.set(peerName, peerVersion);\n } else {\n missingRequiredPeerDeps.set(peerName, peerVersion);\n }\n }\n }\n }\n }\n\n // Handle missing required peer dependencies\n if (missingRequiredPeerDeps.size > 0) {\n log(styleText('yellow', '⚠️ The following peer dependencies are required but not installed:') + '\\n');\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n log(` - ${name}@${version}`);\n }\n log('');\n\n let installRequired = yes; // auto-accept in yes mode\n if (!dryRun && !yes) {\n installRequired = await confirm({\n message: 'Do you want to install these peer dependencies?',\n default: true,\n });\n\n if (!installRequired) {\n console.log(styleText('red', '⚠️ Warning: Skipping peer dependencies may cause issues.'));\n }\n log('');\n }\n\n if (installRequired) {\n for (const [name, version] of missingRequiredPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would prompt to install required peer dependencies') + '\\n');\n }\n }\n\n // Handle missing optional peer dependencies\n if (missingOptionalPeerDeps.size > 0) {\n log(styleText('cyan', 'ℹ️ The following optional peer dependencies are not installed:') + '\\n');\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n log(` - ${name}@${version} ${styleText('dim', '(optional)')}`);\n }\n log('');\n\n let installOptional = false; // default: skip in yes mode\n if (!dryRun && !yes) {\n installOptional = await confirm({\n message: 'Do you want to install these optional peer dependencies?',\n default: false,\n });\n log('');\n }\n\n if (installOptional) {\n for (const [name, version] of missingOptionalPeerDeps.entries()) {\n packagesToUpdate.push({\n name,\n currentVersion: '',\n latestVersion: version.replace(/^[\\^~]/, ''),\n isDev: false,\n });\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would prompt to install optional peer dependencies') + '\\n');\n }\n }\n\n if (dryRun) {\n log(styleText('yellow', '[DRY RUN] Would install the following packages:') + '\\n');\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n packagesToInstall.forEach((pkg) => {\n log(` - ${pkg}`);\n });\n log('\\n' + styleText('yellow', '[DRY RUN] Would run: npm dedupe'));\n console.log('\\n' + styleText('green', '✓ Dry run completed successfully!'));\n process.exit(0);\n }\n\n log('Installing packages...\\n');\n\n // Install packages\n const packagesToInstall = packagesToUpdate.map(pkg => `${pkg.name}@${pkg.latestVersion}`);\n\n try {\n await asyncSpawn('npm', ['install', ...packagesToInstall], { print: !quiet });\n } catch {\n endWithError(new Error('Failed to install packages'));\n }\n\n log('\\nDeduplicating packages...\\n');\n\n try {\n await asyncSpawn('npm', ['dedupe'], { print: !quiet });\n } catch {\n console.error(styleText('yellow', '⚠️ Warning: Failed to deduplicate packages'));\n }\n\n console.log(styleText('green', '✓ All @autofleet packages have been updated successfully!'));\n process.exit(0);\n};\n","import { execSync } from 'node:child_process';\nimport * as path from 'node:path';\nimport fs from 'node:fs';\n\nconst __dirname = import.meta.dirname;\n\nconst isPluginInstalled = (pluginIdentifier: string): boolean => {\n try {\n const output = execSync('claude plugin list', { encoding: 'utf-8' });\n return output.includes(`${pluginIdentifier}`);\n } catch {\n return false;\n }\n};\n\nconst addMarketplace = (marketplacePath: string): void => {\n console.log('📥 Adding Autofleet marketplace...');\n try {\n execSync(`claude plugin marketplace remove autofleet`, { stdio: 'pipe' });\n } catch {\n // Marketplace might not exist, that's fine\n }\n try {\n execSync(`claude plugin marketplace add ${marketplacePath}`, { stdio: 'pipe' });\n console.log('✓ Marketplace added\\n');\n } catch {\n console.log('⚠️ Failed to add marketplace\\n');\n process.exit(1);\n }\n};\n\nconst bumpPluginVersion = (distPluginJsonPath: string): void => {\n const distPluginJson = JSON.parse(fs.readFileSync(distPluginJsonPath, 'utf-8'));\n const [major, minor, patch] = distPluginJson.version.split('.').map(Number);\n const newVersion = `${major}.${minor}.${patch + 1}`;\n\n distPluginJson.version = newVersion;\n fs.writeFileSync(distPluginJsonPath, JSON.stringify(distPluginJson, null, 2) + '\\n');\n};\n\nconst installOrUpdatePlugin = (pluginIdentifier: string, marketplacePath: string): void => {\n if (!isPluginInstalled(pluginIdentifier)) {\n try {\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('⚠️ Failed to install plugin\\n');\n process.exit(1);\n }\n }\n\n console.log('ℹ️ Plugin already installed, reinstalling to get latest version...');\n try {\n const distPluginJsonPath = path.join(marketplacePath, 'plugins/autofleet/.claude-plugin/plugin.json');\n bumpPluginVersion(distPluginJsonPath);\n execSync(`claude plugin remove ${pluginIdentifier}`, { stdio: 'pipe' });\n execSync(`claude plugin install ${pluginIdentifier}`, { stdio: 'inherit' });\n } catch {\n console.log('⚠️ Failed to reinstall plugin\\n');\n process.exit(1);\n }\n};\n\nexport default () => {\n console.log('🚀 Setting up Autofleet Claude Code plugin...\\n');\n const marketplacePath = path.resolve(__dirname, './claude-marketplace');\n\n addMarketplace(marketplacePath);\n installOrUpdatePlugin('autofleet@autofleet', marketplacePath);\n\n console.log('🎉 Plugin setup complete!\\n');\n process.exit(0);\n};\n","#!/usr/bin/env node\nimport parseArgs from './utils/parser.js';\nimport {\n SUPPORTED_CLUSTERS,\n connectAndGetPrefix, endWithError,\n} from './utils/index.js';\nimport { fillMissingRequiredValues } from './utils/inquirer.js';\nimport { checkForCliUpdate } from './utils/version-check.js';\nimport { getVariationIdFromMirrodConfig } from './utils/mirrord.js';\nimport {\n mirrord,\n switchCluster,\n telepresenceWizard,\n enableSimulator,\n exposeService,\n forwardDb,\n forwardService,\n getIps,\n localDev,\n rabbitCreds,\n updateExp,\n mirrordConfig,\n dockerInit,\n openRedis,\n updateAutofleetPackages,\n claudeInit,\n} from './commands/index.js';\n\nconst clusterOptions = SUPPORTED_CLUSTERS.join('/');\nconst variationAndCluster = `--variationId=<yourVariationUuid> --cluster=<${clusterOptions}>`;\n\nconst COMMANDS = {\n switchCluster: variationAndCluster,\n exposeService: `--service=<driver-ms> ${variationAndCluster}`,\n forwardDb: `${variationAndCluster} --local-port=<localPort>`,\n forwardService: `--service=<driver-ms> ${variationAndCluster} --port=<port> --local-port=<localPort>`,\n getIps: variationAndCluster,\n enableSimulator: variationAndCluster,\n rabbitCreds: variationAndCluster,\n updateExp: variationAndCluster,\n telepresenceWizard: `--service=<driver-ms> ${variationAndCluster} --local-port=<localPort>`,\n localDev: variationAndCluster,\n mirrord: `--service=<driver-ms> ${variationAndCluster}`,\n mirrordConfig: '--variationId=<yourVariationUuid>',\n dockerInit: '',\n openRedis: '--cluster=<${clusterOptions}',\n updateAutofleetPackages: '',\n claudeInit: '',\n};\ntype Command = keyof typeof COMMANDS;\nconst isCommand = (c: string): c is Command => Object.keys(COMMANDS).includes(c);\n\nconst { positionals, values, help } = parseArgs({\n strict: true,\n binName: 'autofleet',\n allowPositionals: true,\n options: {\n cluster: {\n type: 'string',\n short: 'c',\n description: 'The cluster name. One of dev1, e2eManager, expManager',\n },\n variationId: {\n type: 'string',\n short: 'i',\n description: 'The variation id',\n },\n service: {\n type: 'string',\n short: 's',\n description: 'The service name',\n },\n port: {\n type: 'string',\n short: 'p',\n description: 'The remote port to forward',\n },\n 'local-port': {\n type: 'string',\n short: 'l',\n description: 'The local port to forward to',\n },\n 'prefer-pod': {\n type: 'boolean',\n short: 'r',\n default: false,\n description: 'Wether the mirrord command should run against the pod, rather than the deployment.',\n },\n 'dry-run': {\n type: 'boolean',\n short: 'd',\n default: false,\n description: 'Perform a dry run without installing packages',\n },\n yes: {\n type: 'boolean',\n short: 'y',\n default: false,\n description: 'Auto-accept all prompts (non-interactive mode)',\n },\n quiet: {\n type: 'boolean',\n short: 'q',\n default: false,\n description: 'Minimize output (useful for CI/LLM usage)',\n },\n 'skip-open': {\n type: 'boolean',\n short: 'o',\n default: false,\n description: 'Skip opening Postico automatically (forwardDb)',\n },\n },\n commands: COMMANDS,\n});\n\nexport type Values = typeof values;\ntype ValueWithDefault<T = keyof Values> = T | { option: T; defaultVal: string; };\n\nif (!positionals.length) {\n console.log(help);\n process.exit(0);\n}\n\nif (positionals.length > 1) {\n endWithError('Only one command is allowed', help);\n}\n\nconst [command] = positionals;\nif (!isCommand(command)) {\n endWithError(new Error(`Command ${command} does not exist`), help);\n}\n\nawait checkForCliUpdate(values.quiet);\n\nconst COMMAND_REQUIRED_VALUES_MAP: Partial<Record<Command, ValueWithDefault[]>> = {\n switchCluster: ['cluster'],\n exposeService: ['cluster', 'variationId', 'service'],\n forwardDb: ['cluster', 'variationId', { option: 'local-port', defaultVal: '5432' }],\n forwardService: ['cluster', 'variationId', 'service', 'port'],\n telepresenceWizard: ['cluster', 'service'],\n mirrordConfig: ['variationId'],\n mirrord: ['cluster', { option: 'variationId', defaultVal: command === 'mirrord' ? await getVariationIdFromMirrodConfig() : '' }, 'service'],\n dockerInit: [],\n openRedis: ['cluster'],\n updateAutofleetPackages: [],\n claudeInit: [],\n};\n\nawait fillMissingRequiredValues(\n values,\n COMMAND_REQUIRED_VALUES_MAP[command] ?? ['cluster', 'variationId'],\n);\nconst { cluster, variationId, service } = values;\n\nswitch (command) {\n case 'mirrordConfig':\n await mirrordConfig(variationId);\n break;\n case 'dockerInit':\n await dockerInit();\n break;\n case 'updateAutofleetPackages':\n await updateAutofleetPackages({ dryRun: values['dry-run'], yes: values.yes, quiet: values.quiet });\n break;\n case 'claudeInit':\n claudeInit();\n break;\n}\n\nif (!cluster) {\n endWithError(new Error('cluster required'), help);\n}\n\nswitch (command) {\n case 'telepresenceWizard':\n await telepresenceWizard(values);\n break;\n case 'switchCluster':\n await switchCluster(cluster, variationId);\n break;\n case 'openRedis':\n await openRedis(cluster);\n break;\n}\n\nif (!variationId) {\n endWithError(new Error('variationId required'), help);\n}\n\nlet prefix: string;\ntry {\n prefix = await connectAndGetPrefix({ clusterName: cluster, variationId });\n} catch (error) {\n endWithError(error as Error);\n}\n\nswitch (command) {\n case 'mirrord':\n await mirrord(prefix, variationId, service);\n break;\n case 'exposeService':\n await exposeService(prefix, help, service);\n break;\n case 'forwardDb':\n await forwardDb(values, prefix, variationId, help, service);\n break;\n case 'forwardService':\n await forwardService(values, prefix, help, service);\n break;\n case 'getIps':\n await getIps(prefix);\n break;\n case 'enableSimulator':\n await enableSimulator(prefix, variationId);\n break;\n case 'rabbitCreds':\n await rabbitCreds();\n break;\n case 'updateExp':\n await updateExp(prefix);\n break;\n case 'localDev':\n await localDev(prefix, cluster, variationId);\n break;\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import{parseArgs as e}from"node:util";import t from"node:fs";import{spawn as n}from"node:child_process";import{confirm as r,input as i,select as a}from"@inquirer/prompts";import{sep as o}from"node:path";import{readdir as s}from"node:fs/promises";var c=`2.33.2`;const l={help:{type:`boolean`,short:`h`,default:!1,description:`Show help (prints this message)`},version:{type:`boolean`,short:`v`,default:!1,description:`Show version number`},quiet:{type:`boolean`,short:`q`,default:!1,description:`Skip interactive prompts (e.g. version update check)`}};function u(t){t.options={...l,...t.options};let n=e(t),{values:r}=n;r.version&&(console.log(c),process.exit(0));let i=t.commands?`
2
+
3
+ Commands:
4
+ ${Object.entries(t.commands).map(([e,t])=>`${e.padEnd(30,` `)} ${t}`).join(`
5
+ `)}
6
+ `:``,a=Math.max.apply(null,Object.values(t.options).map(({description:e})=>e.length)),o=`
7
+ ${t.binName} ${i?`[command] `:``}<options>${i}
8
+ Options:
9
+ ${Object.entries(t.options).map(([e,{description:t,type:n,short:r}])=>`${(r?`--${e}, -${r}`:`--${e}`).padEnd(30,` `)} ${t.padEnd(a+10,` `)} [${n}]`).join(`
10
+ `)}
11
+ `;return r.help&&(console.log(o),process.exit(0)),{...n,help:o}}const d=()=>{if(Promise.withResolvers)return Promise.withResolvers();let e,t;return{promise:new Promise((n,r)=>{e=r,t=n}),reject:e,resolve:t}};var f=async(e,t,{print:r=!0,env:i={},signal:a,shell:o,cwd:s}={})=>{typeof t==`boolean`&&(r=t,t=void 0);let c=Error(`asyncSpawn call site`),l=c.stack?c.stack.replace(/^.*/,` ...`):null,{promise:u,reject:f,resolve:p}=d(),m=n(e,t,{env:Object.assign(i,process.env),signal:a,shell:o,cwd:s});r&&(m.stdout.pipe(process.stdout),m.stderr.pipe(process.stderr));let h=``,g=``;m.stdout?.on(`data`,e=>{h+=e}),m.stderr?.on(`data`,e=>{g+=e});let _=r?`exit`:`close`;function v(e){m.removeListener(_,y),Object.assign(e,{pid:m.pid,stdout:h,stderr:g,status:null,signal:null}),f(e)}function y(n,r){m.removeListener(`error`,v);let i={pid:m.pid,stdout:h,stderr:g,status:n,signal:r};if(n!==0){let a=typeof t!=`boolean`&&` ${t?.join(` `)}`||``,o=r?Error(`${e}${a} exited with signal: ${r}`):Error(`${e}${a} exited with non-zero code: ${n}`);o.stack&&l&&(o.stack+=`\n${l}`),Object.assign(o,i),f(o)}else p(i)}return m.once(_,y),m.once(`error`,v),u};const p=async()=>{let{stdout:e}=await f(`git`,[`branch`,`--show-current`],{print:!1});return e.trim()},m=async()=>{let{stdout:e}=await f(`git`,[`rev-parse`,`--show-toplevel`],{print:!1});return e.trim()},h=async(e=`origin`)=>{try{let{stdout:t}=await f(`git`,[`config`,`--get`,`remote.${e}.url`],{print:!1});return t.trim()}catch{return``}},g=async e=>{let{stdout:t}=await f(`git`,[`diff`,`origin/master..`,e],{print:!1});return t},_=async e=>{try{return await f(`git`,[`check-ignore`,e],{print:!1}),!0}catch{return!1}};function v(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function(){var r,i=this.e,a=0;function o(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(o);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(o,s)}else a|=1}catch(e){return s(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function s(n){return i=i===t?n:new e(n,i),o()}return o()}}}Symbol.dispose??=Symbol.for(`nodejs.dispose`),Symbol.asyncDispose??=Symbol.for(`nodejs.asyncDispose`);let y;const b=()=>y?.();function x(){return process.once(`beforeExit`,b),{[Symbol.dispose](){process.off(`beforeExit`,b),y=void 0}}}async function S(e,...t){try{try{var n=v();n.u(x());let r=e(...t);return y=r.cancel,await r}catch(e){n.e=e}finally{n.d()}}catch(e){e instanceof Error&&[`CancelPromptError`,`ExitPromptError`].includes(e.constructor.name)&&Y(`Cancelled! 👋`),Y(e);return}}function C(...e){return S(a,...e)}function w(...e){return S(i,...e)}const T=e=>e.charAt(0).toUpperCase()+e.slice(1).split(/(?=[A-Z])/).join(` `);function E(){return C({message:`Which environment do you want to use?`,choices:V.map(e=>({name:T(e),value:e})),default:`expManager`})}async function D(e){return C({message:`Using from autorepo, Which app do you want to use?`,choices:(await s(`${e}${o}apps`)).filter(e=>!e.startsWith(`.`)&&!e.endsWith(`-e2e`)).map(e=>({name:e,value:e}))})}async function O(){let e=await m(),t=e.split(o).pop();return t===`autorepo`?D(e):w({message:`Enter the service name:`,default:t})}function k(e=`default`){return w({message:`Enter your simulator id (Press enter to pass):`,default:e})}async function A(e=`8080`,t=!1){return w({message:`Enter the ${t?`local `:``}port:`,default:e,validate(e){return/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(e)?!0:`Please enter a valid port number`}})}async function j(e=`5432`){return A(e,!0)}const M={cluster:E,variationId:k,service:O,port:(e=`8080`)=>A(e),"local-port":j};async function N(e,t){for(let n of t){let t=typeof n==`object`?n.option:n,r=typeof n==`object`?n.defaultVal:void 0;if(typeof t!=`string`)throw Error(`Invalid option ${String(t)}`);let i=M[t];if(!i)throw Error(`No value getter for ${String(t)}`);e[t]??=await i(r)}return e}async function P(e,t=!0){return S(r,{message:e,default:t})}const F={prodUs:[`us-prod-autofleet`,`us-central1`,`autofleet-production`],prodEu:[`eu-prod-autofleet`,`europe-west1`,`autofleetprod`],prodJp:[`jp-autofleet`,`asia-northeast1`,`autofleet-japan`]},I={dev1:[`dev-cluster-2`,`europe-west1`,`dev1-experiment-manager`],e2eManager:[`e2e-cluster-2`,`europe-west1`,`e2e-project-1`],expManager:[`af-experiment-manager`,`europe-west1`]},L={staging:[`stg-autofleet`,`europe-west1`,`autofleet-staging`],loadTest:[`lt-autofleet-production`,`asia-northeast1`,`load-testing-428806`]},R={osrmProd:[`maps-prod`,`europe-west1`,`af-mapping`]},z={...F,...I,...L,...R},B={staging:`europe-west1`},V=Object.keys(z),H=async e=>{let t=z[e];if(!t)throw Error(`Cluster name ${e} does not exist!`);let[n,r,i]=t;return F[e]&&!await P(`❌❌ Are you sure you want to run this command on ${e}? ❌❌`,!1)?(console.log(`Aborting...`),process.exit(1)):{name:n,region:r,project:i}},U=({newFilePath:e,filePath:n,linesToReplace:r})=>{let i=t.readFileSync(n,`utf8`);for(let{find:e,replace:t}of r)i=i.replace(e,t);t.writeFileSync(e,i)};async function W(){try{let{stdout:e}=await f(`kubectl`,[`config`,`current-context`],{print:!1});return e.trim()}catch{return null}}const G=async e=>{let{name:t,region:n,project:r}=await H(e),i=`gke_${r||t}_${n}_${t}`;return await W()===i?(console.log(`Already connected to ${e}, skipping connection to cluster...`),{name:t,region:n,project:r}):(await f(`gcloud`,[`container`,`clusters`,`get-credentials`,t,`--region`,n,`--project`,r||t],{print:!1}),console.log(`Switched to ${e} successfully`),{name:t,region:n,project:r})};async function K(){try{let{stdout:e}=await f(`kubectl`,[`config`,`view`,`--minify`,`--output`,`jsonpath={..namespace}`],{print:!1});return e.trim()}catch{return`default`}}const q=async({clusterName:e,variationId:t})=>(await G(e),`--namespace=${t}`),J=e=>{let t=e.split(`
12
+ `).filter(Boolean);t.shift();let n=t.map(e=>{let[t,n,r,i,a,o]=e.split(/(\s+)/).map(e=>e.trim()).filter(Boolean);return`${t.replace(/-/g,`_`).toUpperCase()}_SERVICE_HOST=${i}`});return n=n.filter(e=>!e.includes(`none`)&&!e.includes(`undefined`)),n};function Y(e,t){return e instanceof Error||(e=Error(e)),console.error(e),t&&console.log(t),process.exit(1)}const X=e=>Object.keys(I).includes(e),Z=e=>B[e]||z[e][1];export{d as C,f as S,c as T,g as _,K as a,h as b,J as c,D as d,j as f,C as g,w as h,Y as i,U as l,P as m,q as n,Z as o,k as p,G as r,X as s,V as t,N as u,p as v,u as w,_ as x,m as y};
13
+ //# sourceMappingURL=utils-BWVzszbR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-BWVzszbR.js","names":["parseArgs","nativeParseArgs","packageJson.version","reject!: PromiseWithResolvers<T>['reject']","resolve!: PromiseWithResolvers<T>['resolve']","result: SpawnResult","signal","asyncSpawn","path","cancelFn: (() => void) | undefined","asyncSpawn"],"sources":["../package.json","../bin/utils/parser.ts","../bin/utils/promise.ts","../bin/utils/asyncSpawn.ts","../bin/utils/git.ts","../bin/utils/inquirer.ts","../bin/utils/index.ts"],"sourcesContent":["","import { parseArgs as nativeParseArgs, type ParseArgsConfig } from 'node:util';\nimport packageJson from '../../package.json' with { type: 'json' };\n\ntype ParseArgsOptionConfig = NonNullable<ParseArgsConfig['options']>[string] & { description: string; };\ntype ParseArgsParams = Omit<ParseArgsConfig, 'options'> & { binName: string; options: Record<string, ParseArgsOptionConfig>; commands?: Record<string, string>; };\n\nconst GLOBAL_OPTIONS = {\n help: {\n type: 'boolean',\n short: 'h',\n default: false,\n description: 'Show help (prints this message)',\n },\n version: {\n type: 'boolean',\n short: 'v',\n default: false,\n description: 'Show version number',\n },\n quiet: {\n type: 'boolean',\n short: 'q',\n default: false,\n description: 'Skip interactive prompts (e.g. version update check)',\n },\n} satisfies ParseArgsParams['options'];\n\ntype Expanded<T extends ParseArgsParams> = T & { options: T['options'] & typeof GLOBAL_OPTIONS; };\ntype Parsed<T extends ParseArgsParams> = ReturnType<typeof nativeParseArgs<Expanded<T>>> & { help: string; };\n\nexport default function parseArgs<T extends ParseArgsParams = ParseArgsParams>(params: T): Parsed<T> {\n params.options = { ...GLOBAL_OPTIONS, ...params.options };\n const data = nativeParseArgs(params as Expanded<T>);\n const { values } = data;\n if ((values as { version: boolean; }).version) {\n console.log(packageJson.version);\n process.exit(0);\n }\n\n const commands = !params.commands ? '' : `\n\nCommands:\n ${Object.entries(params.commands).map(([command, example]) => `${command.padEnd(30, ' ')} ${example}`).join('\\n ')}\n`;\n\n const longestDescriptionLength = Math.max.apply(null, Object.values(params.options).map(({ description }) => description.length));\n\n const help = `\n${params.binName} ${commands ? '[command] ' : ''}<options>${commands}\nOptions:\n ${Object.entries(params.options).map(([option, { description, type, short }]) => {\n const key = short ? `--${option}, -${short}` : `--${option}`;\n return `${key.padEnd(30, ' ')} ${description.padEnd(longestDescriptionLength + 10, ' ')} [${type}]`;\n }).join('\\n ')}\n`;\n\n if ((values as { help: boolean; }).help) {\n console.log(help);\n process.exit(0);\n }\n\n return { ...data, help };\n}\n","declare global {\n interface PromiseWithResolvers<T> {\n promise: Promise<T>;\n resolve: (value: T | PromiseLike<T>) => void;\n reject: (reason?: any) => void; \n }\n interface PromiseConstructor {\n /**\n * Creates a new Promise and returns it in an object, along with its resolve and reject functions.\n * @returns An object with the properties `promise`, `resolve`, and `reject`.\n *\n * ```ts\n * const { promise, resolve, reject } = Promise.withResolvers<T>();\n * ```\n */\n withResolvers<T>(): PromiseWithResolvers<T>;\n }\n}\n\nexport const createDeferredPromise = <T>() => {\n if (Promise.withResolvers) {\n return Promise.withResolvers<T>();\n }\n let reject!: PromiseWithResolvers<T>['reject'];\n let resolve!: PromiseWithResolvers<T>['resolve'];\n const promise = new Promise<T>((res, rej) => {\n reject = rej;\n resolve = res;\n });\n return { promise, reject, resolve };\n};\n","import { spawn } from 'node:child_process';\nimport { createDeferredPromise } from './promise.js';\n\ninterface SpawnResult {\n pid?: number;\n stdout: string;\n stderr: string;\n status: number | null;\n signal: string | null;\n}\n\nexport default async (\n command: string,\n args?: boolean | readonly string[],\n {\n print = true,\n env = {},\n signal,\n shell,\n cwd,\n }: { print?: boolean; env?: NodeJS.ProcessEnv; signal?: AbortSignal; shell?: string | boolean; cwd?: string; } = {},\n) => {\n if (typeof args === 'boolean') {\n print = args;\n args = undefined;\n }\n const stubError = new Error('asyncSpawn call site');\n const callerStack = stubError.stack ? stubError.stack.replace(/^.*/, ' ...') : null;\n const { promise, reject, resolve } = createDeferredPromise<SpawnResult>();\n const child = spawn(command, args, { env: Object.assign(env, process.env), signal, shell, cwd });\n if (print) {\n child.stdout.pipe(process.stdout);\n child.stderr.pipe(process.stderr);\n }\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (data) => {\n stdout += data;\n });\n child.stderr?.on('data', (data) => {\n stderr += data;\n });\n const completionEventName = print ? 'exit' : 'close';\n function errorListener(error: Error) {\n child.removeListener(completionEventName, completionListener);\n Object.assign(error, {\n pid: child.pid,\n stdout,\n stderr,\n status: null,\n signal: null,\n });\n reject(error);\n }\n function completionListener(code: number | null, signal: string | null) {\n child.removeListener('error', errorListener);\n const result: SpawnResult = {\n pid: child.pid,\n stdout,\n stderr,\n status: code,\n signal,\n };\n if (code !== 0) {\n const argumentString = (typeof args !== 'boolean' && ` ${args?.join(' ')}`) || '';\n const error = signal\n ? new Error(`${command}${argumentString} exited with signal: ${signal}`)\n : new Error(`${command}${argumentString} exited with non-zero code: ${code}`);\n if (error.stack && callerStack) {\n error.stack += `\\n${callerStack}`;\n }\n Object.assign(error, result);\n reject(error);\n } else {\n resolve(result);\n }\n }\n\n child.once(completionEventName, completionListener);\n child.once('error', errorListener);\n return promise;\n};\n","import asyncSpawn from './asyncSpawn.js';\n\nexport const getCurrentBranch = async () => {\n const { stdout: currentBranch } = await asyncSpawn('git', ['branch', '--show-current'], { print: false });\n return currentBranch.trim();\n};\n\nexport const getGitPath = async () => {\n const { stdout: gitPath } = await asyncSpawn('git', ['rev-parse', '--show-toplevel'], { print: false });\n return gitPath.trim();\n};\n\nexport const getRemoteUrl = async (remote = 'origin') => {\n try {\n const { stdout } = await asyncSpawn('git', ['config', '--get', `remote.${remote}.url`], { print: false });\n return stdout.trim();\n } catch {\n return '';\n }\n};\n\nexport const getChangesOfFile = async (filePath: string) => {\n const { stdout: changes } = await asyncSpawn('git', ['diff', 'origin/master..', filePath], { print: false });\n return changes;\n};\n\nexport const isPathIgnored = async (path: string) => {\n try {\n await asyncSpawn('git', ['check-ignore', path], { print: false });\n return true;\n } catch {\n return false;\n }\n};\n","import { confirm, input, select } from '@inquirer/prompts';\nimport type { Prompt } from '@inquirer/type';\nimport { getGitPath } from './git.js';\nimport { SUPPORTED_CLUSTERS, endWithError } from './index.js';\nimport { sep } from 'node:path';\nimport { readdir } from 'node:fs/promises';\n\ndeclare global {\n interface SymbolConstructor {\n /** A method that is used to release resources held by an object. Called by the semantics of the `using` statement. */\n readonly dispose: unique symbol;\n /** A method that is used to asynchronously release resources held by an object. Called by the semantics of the `await using` statement. */\n readonly asyncDispose: unique symbol;\n }\n}\n// @ts-expect-error polyfill for node < 18.18\nSymbol.dispose ??= Symbol.for('nodejs.dispose');\n// @ts-expect-error polyfill for node < 18.18\nSymbol.asyncDispose ??= Symbol.for('nodejs.asyncDispose');\nlet cancelFn: (() => void) | undefined;\nconst handler = () => cancelFn?.();\nfunction addExitListener() {\n process.once('beforeExit', handler);\n return {\n [Symbol.dispose]() {\n process.off('beforeExit', handler);\n cancelFn = undefined;\n },\n };\n}\n\nasync function inquirerWrapper<Value, Config>(fn: Prompt<Value, Config>, ...params: Parameters<Prompt<Value, Config>>) {\n try {\n using _ = addExitListener();\n const result = fn(...params);\n cancelFn = result.cancel;\n return await result;\n } catch (error) {\n if (error instanceof Error && ['CancelPromptError', 'ExitPromptError'].includes(error.constructor.name)) {\n endWithError('Cancelled! 👋');\n }\n endWithError(error as Error);\n return undefined;\n }\n}\n\nexport function safeSelect<Value = string>(...params: Parameters<typeof select<Value>>) {\n return inquirerWrapper(select, ...params);\n}\n\nexport function safeInput(...params: Parameters<typeof input>) {\n return inquirerWrapper(input, ...params);\n}\n\nconst splitWordAtCapital = (str: string) => str.charAt(0).toUpperCase() + str.slice(1).split(/(?=[A-Z])/).join(' ');\n\nfunction getEnvironment() {\n return safeSelect({\n message: 'Which environment do you want to use?',\n choices: SUPPORTED_CLUSTERS.map(cluster => ({ name: splitWordAtCapital(cluster), value: cluster })),\n default: 'expManager',\n });\n}\n\nexport async function getAutorepoAppName(currentServicePath: string) {\n const appNames = (await readdir(`${currentServicePath}${sep}apps`)).filter(name => !name.startsWith('.') && !name.endsWith('-e2e'));\n return safeSelect({\n message: 'Using from autorepo, Which app do you want to use?',\n choices: appNames.map(app => ({ name: app, value: app })),\n });\n}\n\nasync function getServiceName() {\n const gitPath = await getGitPath();\n const defaultValue = gitPath.split(sep).pop();\n if (defaultValue === 'autorepo') {\n return getAutorepoAppName(gitPath);\n }\n return safeInput({ message: 'Enter the service name:', default: defaultValue });\n}\n\nexport function getVariationId(defaultVal = 'default') {\n return safeInput({ message: 'Enter your simulator id (Press enter to pass):', default: defaultVal });\n}\n\nasync function getPort(defaultVal = '8080', isLocal = false) {\n return safeInput({\n message: `Enter the ${isLocal ? 'local ' : ''}port:`,\n default: defaultVal,\n validate(value) {\n // Regex source: https://stackoverflow.com/a/12968117\n if (!/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(value)) {\n return 'Please enter a valid port number';\n }\n return true;\n },\n });\n}\n\nexport async function getLocalPort(defaultVal = '5432') {\n return getPort(defaultVal, true);\n}\n\nconst VALUE_GETTER_MAP = {\n cluster: getEnvironment,\n variationId: getVariationId,\n service: getServiceName,\n port: (defaultVal = '8080') => getPort(defaultVal),\n 'local-port': getLocalPort,\n} as const;\n\nexport async function fillMissingRequiredValues<T extends { [key in keyof typeof VALUE_GETTER_MAP]?: string }>(values: T, requiredValues: (keyof T | { option: keyof T; defaultVal: string; })[]) {\n for (const value of requiredValues) {\n const option = typeof value === 'object' ? value.option : value;\n const defaultVal = typeof value === 'object' ? value.defaultVal : undefined;\n if (typeof option !== 'string') {\n throw new Error(`Invalid option ${String(option)}`);\n }\n const getter = VALUE_GETTER_MAP[option as keyof typeof VALUE_GETTER_MAP];\n if (!getter) {\n throw new Error(`No value getter for ${String(option)}`);\n }\n\n values[option] ??= await getter(defaultVal) as T[keyof T & string];\n }\n return values;\n}\n\nexport async function promptForConfirmation(message: string, defaultVal = true) {\n return inquirerWrapper(confirm, { message, default: defaultVal });\n}\n","#!/usr/bin/env node\nimport fs from 'node:fs';\nimport asyncSpawn from './asyncSpawn.js';\nimport { promptForConfirmation } from './inquirer.js';\n\nconst IP_LINE_SUFFIX = 'SERVICE_HOST';\nconst PROD_CLUSTER_TO_CMD_MAP = {\n prodUs: ['us-prod-autofleet', 'us-central1', 'autofleet-production'],\n prodEu: ['eu-prod-autofleet', 'europe-west1', 'autofleetprod'],\n prodJp: ['jp-autofleet', 'asia-northeast1', 'autofleet-japan'],\n};\nconst SIMULATION_CLUSTER_TO_CMD_MAP = {\n dev1: ['dev-cluster-2', 'europe-west1', 'dev1-experiment-manager'],\n e2eManager: ['e2e-cluster-2', 'europe-west1', 'e2e-project-1'],\n expManager: ['af-experiment-manager', 'europe-west1'],\n};\nconst STAGING_CLUSTER_TO_CMD_MAP = {\n staging: ['stg-autofleet', 'europe-west1', 'autofleet-staging'],\n loadTest: ['lt-autofleet-production', 'asia-northeast1', 'load-testing-428806'],\n};\nconst MAPPING_CLUSTER_TO_CMD_MAP = {\n osrmProd: ['maps-prod', 'europe-west1', 'af-mapping'],\n};\nconst CLUSTER_TO_CMD_MAP = {\n ...PROD_CLUSTER_TO_CMD_MAP,\n ...SIMULATION_CLUSTER_TO_CMD_MAP,\n ...STAGING_CLUSTER_TO_CMD_MAP,\n ...MAPPING_CLUSTER_TO_CMD_MAP,\n};\n\nconst CLUSTER_TO_REDIS_REGION = {\n staging: 'europe-west1',\n};\n\nexport const SUPPORTED_CLUSTERS = Object.keys(CLUSTER_TO_CMD_MAP) as (keyof typeof CLUSTER_TO_CMD_MAP)[];\n\nconst getClusterDetails = async (clusterName: string) => {\n const command = CLUSTER_TO_CMD_MAP[clusterName as keyof typeof CLUSTER_TO_CMD_MAP];\n if (!command) {\n throw new Error(`Cluster name ${clusterName} does not exist!`);\n }\n const [name, region, project] = command;\n\n if (\n PROD_CLUSTER_TO_CMD_MAP[clusterName as keyof typeof PROD_CLUSTER_TO_CMD_MAP]\n && !(await promptForConfirmation(`❌❌ Are you sure you want to run this command on ${clusterName}? ❌❌`, false))) {\n console.log('Aborting...');\n return process.exit(1);\n }\n\n return { name, region, project };\n};\n\nexport const replaceInFile = ({ newFilePath, filePath, linesToReplace }: { newFilePath: string; filePath: string; linesToReplace: { find: string; replace: string; }[]; }) => {\n let fileAsString = fs.readFileSync(filePath, 'utf8');\n for (const { find, replace } of linesToReplace) {\n fileAsString = fileAsString.replace(find, replace);\n }\n fs.writeFileSync(newFilePath, fileAsString);\n};\n\nexport async function getCurrentCluster() {\n try {\n const { stdout } = await asyncSpawn('kubectl', ['config', 'current-context'], { print: false });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\nexport const connectToCluster = async (clusterName: string) => {\n const { name, region, project } = await getClusterDetails(clusterName);\n\n const expectedContext = `gke_${project || name}_${region}_${name}`;\n const currentContext = await getCurrentCluster();\n if (currentContext === expectedContext) {\n console.log(`Already connected to ${clusterName}, skipping connection to cluster...`);\n return { name, region, project };\n }\n\n await asyncSpawn('gcloud', ['container', 'clusters', 'get-credentials', name, '--region', region, '--project', project || name], { print: false });\n\n console.log(`Switched to ${clusterName} successfully`);\n\n return { name, region, project };\n};\n\nexport async function getCurrentNamespace() {\n try {\n const { stdout } = await asyncSpawn('kubectl', ['config', 'view', '--minify', '--output', 'jsonpath={..namespace}'], { print: false });\n return stdout.trim();\n } catch {\n return 'default'; // If no namespace is set, it defaults to 'default'\n }\n}\n\nexport const connectAndGetPrefix = async ({ clusterName, variationId }: { clusterName: string; variationId: string; }) => {\n await connectToCluster(clusterName);\n return `--namespace=${variationId}`;\n};\n\nexport const parseIps = (ips: string) => {\n const ipLines = ips.split('\\n').filter(Boolean);\n ipLines.shift();\n\n let formattedIps = ipLines.map((ipLine) => {\n const [name, _type, _clusterIp, externalIp, _port, _age] = ipLine.split(/(\\s+)/).map(s => s.trim()).filter(Boolean);\n const serviceName = name.replace(/-/g, '_').toUpperCase();\n const formattedLine = `${serviceName}_${IP_LINE_SUFFIX}=${externalIp}`;\n return formattedLine;\n });\n formattedIps = formattedIps.filter(formattedIp => !formattedIp.includes('none') && !formattedIp.includes('undefined'));\n return formattedIps;\n};\n\nexport function endWithError(error: string | Error, helpText?: string): never {\n if (!(error instanceof Error)) {\n error = new Error(error);\n }\n console.error(error);\n if (helpText) {\n console.log(helpText);\n }\n return process.exit(1);\n}\n\nexport const isSimulationCluster = (clusterName: string) => Object.keys(SIMULATION_CLUSTER_TO_CMD_MAP).includes(clusterName);\n\nexport const getRedisRegion = (clusterName: string) => CLUSTER_TO_REDIS_REGION[clusterName as keyof typeof CLUSTER_TO_REDIS_REGION]\n || CLUSTER_TO_CMD_MAP[clusterName as keyof typeof CLUSTER_TO_CMD_MAP][1];\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/cli",
3
- "version": "2.33.1",
3
+ "version": "2.33.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "devDependencies": {
package/project.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "command": "pnpm tsdown -W {projectRoot}"
10
10
  },
11
11
  "lint": {
12
- "command": "eslint {projectRoot}"
12
+ "command": "node ./packages/lint/bin/oxlint.cjs {projectRoot}"
13
13
  },
14
14
  "test": {
15
15
  "command": "node --run coverage",
@@ -19,6 +19,9 @@
19
19
  },
20
20
  "typecheck": {
21
21
  "command": "node ./scripts/type-check.mjs {projectRoot}/tsconfig.json"
22
+ },
23
+ "lint-strict": {
24
+ "command": "eslint {projectRoot}"
22
25
  }
23
26
  },
24
27
  "tags": []
@@ -1,13 +0,0 @@
1
- import{parseArgs as e}from"node:util";import t from"node:fs";import{spawn as n}from"node:child_process";import{confirm as r,input as i,select as a}from"@inquirer/prompts";import{sep as o}from"node:path";import{readdir as s}from"node:fs/promises";var c=`2.33.1`;const l={help:{type:`boolean`,short:`h`,default:!1,description:`Show help (prints this message)`},version:{type:`boolean`,short:`v`,default:!1,description:`Show version number`},quiet:{type:`boolean`,short:`q`,default:!1,description:`Skip interactive prompts (e.g. version update check)`}};function u(t){t.options={...l,...t.options};let n=e(t),{values:r}=n;r.version&&(console.log(c),process.exit(0));let i=t.commands?`
2
-
3
- Commands:
4
- ${Object.entries(t.commands).map(([e,t])=>`${e.padEnd(30,` `)} ${t}`).join(`
5
- `)}
6
- `:``,a=Math.max.apply(null,Object.values(t.options).map(({description:e})=>e.length)),o=`
7
- ${t.binName} ${i?`[command] `:``}<options>${i}
8
- Options:
9
- ${Object.entries(t.options).map(([e,{description:t,type:n,short:r}])=>`${(r?`--${e}, -${r}`:`--${e}`).padEnd(30,` `)} ${t.padEnd(a+10,` `)} [${n}]`).join(`
10
- `)}
11
- `;return r.help&&(console.log(o),process.exit(0)),{...n,help:o}}const d=()=>{if(Promise.withResolvers)return Promise.withResolvers();let e,t;return{promise:new Promise((n,r)=>{e=r,t=n}),reject:e,resolve:t}};var f=async(e,t,{print:r=!0,env:i={},signal:a,shell:o,cwd:s}={})=>{typeof t==`boolean`&&(r=t,t=void 0);let c=Error(),l=c.stack?c.stack.replace(/^.*/,` ...`):null,{promise:u,reject:f,resolve:p}=d(),m=n(e,t,{env:Object.assign(i,process.env),signal:a,shell:o,cwd:s});r&&(m.stdout.pipe(process.stdout),m.stderr.pipe(process.stderr));let h=``,g=``;m.stdout?.on(`data`,e=>{h+=e}),m.stderr?.on(`data`,e=>{g+=e});let _=r?`exit`:`close`;function v(e){m.removeListener(_,y),Object.assign(e,{pid:m.pid,stdout:h,stderr:g,status:null,signal:null}),f(e)}function y(n,r){m.removeListener(`error`,v);let i={pid:m.pid,stdout:h,stderr:g,status:n,signal:r};if(n!==0){let a=typeof t!=`boolean`&&` ${t?.join(` `)}`||``,o=r?Error(`${e}${a} exited with signal: ${r}`):Error(`${e}${a} exited with non-zero code: ${n}`);o.stack&&l&&(o.stack+=`\n${l}`),Object.assign(o,i),f(o)}else p(i)}return m.once(_,y),m.once(`error`,v),u};const p=async()=>{let{stdout:e}=await f(`git`,[`branch`,`--show-current`],{print:!1});return e.trim()},m=async()=>{let{stdout:e}=await f(`git`,[`rev-parse`,`--show-toplevel`],{print:!1});return e.trim()},h=async(e=`origin`)=>{try{let{stdout:t}=await f(`git`,[`config`,`--get`,`remote.${e}.url`],{print:!1});return t.trim()}catch{return``}},g=async e=>{let{stdout:t}=await f(`git`,[`diff`,`origin/master..`,e],{print:!1});return t},_=async e=>{try{return await f(`git`,[`check-ignore`,e],{print:!1}),!0}catch{return!1}};function v(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function(){var r,i=this.e,a=0;function o(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(o);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(o,s)}else a|=1}catch(e){return s(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function s(n){return i=i===t?n:new e(n,i),o()}return o()}}}Symbol.dispose??=Symbol.for(`nodejs.dispose`),Symbol.asyncDispose??=Symbol.for(`nodejs.asyncDispose`);let y;const b=()=>y?.();function x(){return process.once(`beforeExit`,b),{[Symbol.dispose](){process.off(`beforeExit`,b),y=void 0}}}async function S(e,...t){try{try{var n=v();n.u(x());let r=e(...t);return y=r.cancel,await r}catch(e){n.e=e}finally{n.d()}}catch(e){e instanceof Error&&[`CancelPromptError`,`ExitPromptError`].includes(e.constructor.name)&&Y(`Cancelled! 👋`),Y(e);return}}function C(...e){return S(a,...e)}function w(...e){return S(i,...e)}const T=e=>e.charAt(0).toUpperCase()+e.slice(1).split(/(?=[A-Z])/).join(` `);function E(){return C({message:`Which environment do you want to use?`,choices:V.map(e=>({name:T(e),value:e})),default:`expManager`})}async function D(e){return C({message:`Using from autorepo, Which app do you want to use?`,choices:(await s(`${e}${o}apps`)).filter(e=>!e.startsWith(`.`)&&!e.endsWith(`-e2e`)).map(e=>({name:e,value:e}))})}async function O(){let e=await m(),t=e.split(o).pop();return t===`autorepo`?D(e):w({message:`Enter the service name:`,default:t})}function k(e=`default`){return w({message:`Enter your simulator id (Press enter to pass):`,default:e})}async function A(e=`8080`,t=!1){return w({message:`Enter the ${t?`local `:``}port:`,default:e,validate(e){return/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(e)?!0:`Please enter a valid port number`}})}async function j(e=`5432`){return A(e,!0)}const M={cluster:E,variationId:k,service:O,port:(e=`8080`)=>A(e),"local-port":j};async function N(e,t){for(let n of t){let t=typeof n==`object`?n.option:n,r=typeof n==`object`?n.defaultVal:void 0;if(typeof t!=`string`)throw Error(`Invalid option ${String(t)}`);let i=M[t];if(!i)throw Error(`No value getter for ${String(t)}`);e[t]??=await i(r)}return e}async function P(e,t=!0){return S(r,{message:e,default:t})}const F={prodUs:[`us-prod-autofleet`,`us-central1`,`autofleet-production`],prodEu:[`eu-prod-autofleet`,`europe-west1`,`autofleetprod`],prodJp:[`jp-autofleet`,`asia-northeast1`,`autofleet-japan`]},I={dev1:[`dev-cluster-2`,`europe-west1`,`dev1-experiment-manager`],e2eManager:[`e2e-cluster-2`,`europe-west1`,`e2e-project-1`],expManager:[`af-experiment-manager`,`europe-west1`]},L={staging:[`stg-autofleet`,`europe-west1`,`autofleet-staging`],loadTest:[`lt-autofleet-production`,`asia-northeast1`,`load-testing-428806`]},R={osrmProd:[`maps-prod`,`europe-west1`,`af-mapping`]},z={...F,...I,...L,...R},B={staging:`europe-west1`},V=Object.keys(z),H=async e=>{let t=z[e];if(!t)throw Error(`Cluster name ${e} does not exist!`);let[n,r,i]=t;return F[e]&&!await P(`❌❌ Are you sure you want to run this command on ${e}? ❌❌`,!1)?(console.log(`Aborting...`),process.exit(1)):{name:n,region:r,project:i}},U=({newFilePath:e,filePath:n,linesToReplace:r})=>{let i=t.readFileSync(n,`utf8`);for(let{find:e,replace:t}of r)i=i.replace(e,t);t.writeFileSync(e,i)};async function W(){try{let{stdout:e}=await f(`kubectl`,[`config`,`current-context`],{print:!1});return e.trim()}catch{return null}}const G=async e=>{let{name:t,region:n,project:r}=await H(e),i=`gke_${r||t}_${n}_${t}`;return await W()===i?(console.log(`Already connected to ${e}, skipping connection to cluster...`),{name:t,region:n,project:r}):(await f(`gcloud`,[`container`,`clusters`,`get-credentials`,t,`--region`,n,`--project`,r||t],{print:!1}),console.log(`Switched to ${e} successfully`),{name:t,region:n,project:r})};async function K(){try{let{stdout:e}=await f(`kubectl`,[`config`,`view`,`--minify`,`--output`,`jsonpath={..namespace}`],{print:!1});return e.trim()}catch{return`default`}}const q=async({clusterName:e,variationId:t})=>(await G(e),`--namespace=${t}`),J=e=>{let t=e.split(`
12
- `).filter(Boolean);t.shift();let n=t.map(e=>{let[t,n,r,i,a,o]=e.split(/(\s+)/).map(e=>e.trim()).filter(Boolean);return`${t.replace(/-/g,`_`).toUpperCase()}_SERVICE_HOST=${i}`});return n=n.filter(e=>!e.includes(`none`)&&!e.includes(`undefined`)),n};function Y(e,t){return e instanceof Error||(e=Error(e)),console.error(e),t&&console.log(t),process.exit(1)}const X=e=>Object.keys(I).includes(e),Z=e=>B[e]||z[e][1];export{d as C,f as S,c as T,g as _,K as a,h as b,J as c,D as d,j as f,C as g,w as h,Y as i,U as l,P as m,q as n,Z as o,k as p,G as r,X as s,V as t,N as u,p as v,u as w,_ as x,m as y};
13
- //# sourceMappingURL=utils-BM4JK9OB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-BM4JK9OB.js","names":["parseArgs","nativeParseArgs","packageJson.version","reject!: PromiseWithResolvers<T>['reject']","resolve!: PromiseWithResolvers<T>['resolve']","result: SpawnResult","signal","asyncSpawn","path","cancelFn: (() => void) | undefined","asyncSpawn"],"sources":["../package.json","../bin/utils/parser.ts","../bin/utils/promise.ts","../bin/utils/asyncSpawn.ts","../bin/utils/git.ts","../bin/utils/inquirer.ts","../bin/utils/index.ts"],"sourcesContent":["","import { parseArgs as nativeParseArgs, type ParseArgsConfig } from 'node:util';\nimport packageJson from '../../package.json' with { type: 'json' };\n\ntype ParseArgsOptionConfig = NonNullable<ParseArgsConfig['options']>[string] & { description: string; };\ntype ParseArgsParams = Omit<ParseArgsConfig, 'options'> & { binName: string; options: Record<string, ParseArgsOptionConfig>; commands?: Record<string, string>; };\n\nconst GLOBAL_OPTIONS = {\n help: {\n type: 'boolean',\n short: 'h',\n default: false,\n description: 'Show help (prints this message)',\n },\n version: {\n type: 'boolean',\n short: 'v',\n default: false,\n description: 'Show version number',\n },\n quiet: {\n type: 'boolean',\n short: 'q',\n default: false,\n description: 'Skip interactive prompts (e.g. version update check)',\n },\n} satisfies ParseArgsParams['options'];\n\ntype Expanded<T extends ParseArgsParams> = T & { options: T['options'] & typeof GLOBAL_OPTIONS; };\ntype Parsed<T extends ParseArgsParams> = ReturnType<typeof nativeParseArgs<Expanded<T>>> & { help: string; };\n\nexport default function parseArgs<T extends ParseArgsParams = ParseArgsParams>(params: T): Parsed<T> {\n params.options = { ...GLOBAL_OPTIONS, ...params.options };\n const data = nativeParseArgs(params as Expanded<T>);\n const { values } = data;\n if ((values as { version: boolean; }).version) {\n console.log(packageJson.version);\n process.exit(0);\n }\n\n const commands = !params.commands ? '' : `\n\nCommands:\n ${Object.entries(params.commands).map(([command, example]) => `${command.padEnd(30, ' ')} ${example}`).join('\\n ')}\n`;\n\n const longestDescriptionLength = Math.max.apply(null, Object.values(params.options).map(({ description }) => description.length));\n\n const help = `\n${params.binName} ${commands ? '[command] ' : ''}<options>${commands}\nOptions:\n ${Object.entries(params.options).map(([option, { description, type, short }]) => {\n const key = short ? `--${option}, -${short}` : `--${option}`;\n return `${key.padEnd(30, ' ')} ${description.padEnd(longestDescriptionLength + 10, ' ')} [${type}]`;\n }).join('\\n ')}\n`;\n\n if ((values as { help: boolean; }).help) {\n console.log(help);\n process.exit(0);\n }\n\n return { ...data, help };\n}\n","declare global {\n interface PromiseWithResolvers<T> {\n promise: Promise<T>;\n resolve: (value: T | PromiseLike<T>) => void;\n reject: (reason?: any) => void; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n interface PromiseConstructor {\n /**\n * Creates a new Promise and returns it in an object, along with its resolve and reject functions.\n * @returns An object with the properties `promise`, `resolve`, and `reject`.\n *\n * ```ts\n * const { promise, resolve, reject } = Promise.withResolvers<T>();\n * ```\n */\n withResolvers<T>(): PromiseWithResolvers<T>;\n }\n}\n\nexport const createDeferredPromise = <T>() => {\n if (Promise.withResolvers) {\n return Promise.withResolvers<T>();\n }\n let reject!: PromiseWithResolvers<T>['reject'];\n let resolve!: PromiseWithResolvers<T>['resolve'];\n const promise = new Promise<T>((res, rej) => {\n reject = rej;\n resolve = res;\n });\n return { promise, reject, resolve };\n};\n","import { spawn } from 'node:child_process';\nimport { createDeferredPromise } from './promise.js';\n\ninterface SpawnResult {\n pid?: number;\n stdout: string;\n stderr: string;\n status: number | null;\n signal: string | null;\n}\n\nexport default async (\n command: string,\n args?: boolean | readonly string[],\n {\n print = true,\n env = {},\n signal,\n shell,\n cwd,\n }: { print?: boolean; env?: NodeJS.ProcessEnv; signal?: AbortSignal; shell?: string | boolean; cwd?: string; } = {},\n) => {\n if (typeof args === 'boolean') {\n print = args;\n args = undefined;\n }\n const stubError = new Error();\n const callerStack = stubError.stack ? stubError.stack.replace(/^.*/, ' ...') : null;\n const { promise, reject, resolve } = createDeferredPromise<SpawnResult>();\n const child = spawn(command, args, { env: Object.assign(env, process.env), signal, shell, cwd });\n if (print) {\n child.stdout.pipe(process.stdout);\n child.stderr.pipe(process.stderr);\n }\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (data) => {\n stdout += data;\n });\n child.stderr?.on('data', (data) => {\n stderr += data;\n });\n const completionEventName = print ? 'exit' : 'close';\n function errorListener(error: Error) {\n child.removeListener(completionEventName, completionListener);\n Object.assign(error, {\n pid: child.pid,\n stdout,\n stderr,\n status: null,\n signal: null,\n });\n reject(error);\n }\n function completionListener(code: number | null, signal: string | null) {\n child.removeListener('error', errorListener);\n const result: SpawnResult = {\n pid: child.pid,\n stdout,\n stderr,\n status: code,\n signal,\n };\n if (code !== 0) {\n const argumentString = (typeof args !== 'boolean' && ` ${args?.join(' ')}`) || '';\n const error = signal\n ? new Error(`${command}${argumentString} exited with signal: ${signal}`)\n : new Error(`${command}${argumentString} exited with non-zero code: ${code}`);\n if (error.stack && callerStack) {\n error.stack += `\\n${callerStack}`;\n }\n Object.assign(error, result);\n reject(error);\n } else {\n resolve(result);\n }\n }\n\n child.once(completionEventName, completionListener);\n child.once('error', errorListener);\n return promise;\n};\n","import asyncSpawn from './asyncSpawn.js';\n\nexport const getCurrentBranch = async () => {\n const { stdout: currentBranch } = await asyncSpawn('git', ['branch', '--show-current'], { print: false });\n return currentBranch.trim();\n};\n\nexport const getGitPath = async () => {\n const { stdout: gitPath } = await asyncSpawn('git', ['rev-parse', '--show-toplevel'], { print: false });\n return gitPath.trim();\n};\n\nexport const getRemoteUrl = async (remote = 'origin') => {\n try {\n const { stdout } = await asyncSpawn('git', ['config', '--get', `remote.${remote}.url`], { print: false });\n return stdout.trim();\n } catch {\n return '';\n }\n};\n\nexport const getChangesOfFile = async (filePath: string) => {\n const { stdout: changes } = await asyncSpawn('git', ['diff', 'origin/master..', filePath], { print: false });\n return changes;\n};\n\nexport const isPathIgnored = async (path: string) => {\n try {\n await asyncSpawn('git', ['check-ignore', path], { print: false });\n return true;\n } catch {\n return false;\n }\n};\n","import { confirm, input, select } from '@inquirer/prompts';\nimport type { Prompt } from '@inquirer/type';\nimport { getGitPath } from './git.js';\nimport { SUPPORTED_CLUSTERS, endWithError } from './index.js';\nimport { sep } from 'node:path';\nimport { readdir } from 'node:fs/promises';\n\ndeclare global {\n interface SymbolConstructor {\n /** A method that is used to release resources held by an object. Called by the semantics of the `using` statement. */\n readonly dispose: unique symbol;\n /** A method that is used to asynchronously release resources held by an object. Called by the semantics of the `await using` statement. */\n readonly asyncDispose: unique symbol;\n }\n}\n// @ts-expect-error polyfill for node < 18.18\nSymbol.dispose ??= Symbol.for('nodejs.dispose');\n// @ts-expect-error polyfill for node < 18.18\nSymbol.asyncDispose ??= Symbol.for('nodejs.asyncDispose');\nlet cancelFn: (() => void) | undefined;\nconst handler = () => cancelFn?.();\nfunction addExitListener() {\n process.once('beforeExit', handler);\n return {\n [Symbol.dispose]() {\n process.off('beforeExit', handler);\n cancelFn = undefined;\n },\n };\n}\n\nasync function inquirerWrapper<Value, Config>(fn: Prompt<Value, Config>, ...params: Parameters<Prompt<Value, Config>>) {\n try {\n using _ = addExitListener();\n const result = fn(...params);\n cancelFn = result.cancel;\n return await result;\n } catch (error) {\n if (error instanceof Error && ['CancelPromptError', 'ExitPromptError'].includes(error.constructor.name)) {\n endWithError('Cancelled! 👋');\n }\n endWithError(error as Error);\n return undefined;\n }\n}\n\nexport function safeSelect<Value = string>(...params: Parameters<typeof select<Value>>) {\n return inquirerWrapper(select, ...params);\n}\n\nexport function safeInput(...params: Parameters<typeof input>) {\n return inquirerWrapper(input, ...params);\n}\n\nconst splitWordAtCapital = (str: string) => str.charAt(0).toUpperCase() + str.slice(1).split(/(?=[A-Z])/).join(' ');\n\nfunction getEnvironment() {\n return safeSelect({\n message: 'Which environment do you want to use?',\n choices: SUPPORTED_CLUSTERS.map(cluster => ({ name: splitWordAtCapital(cluster), value: cluster })),\n default: 'expManager',\n });\n}\n\nexport async function getAutorepoAppName(currentServicePath: string) {\n const appNames = (await readdir(`${currentServicePath}${sep}apps`)).filter(name => !name.startsWith('.') && !name.endsWith('-e2e'));\n return safeSelect({\n message: 'Using from autorepo, Which app do you want to use?',\n choices: appNames.map(app => ({ name: app, value: app })),\n });\n}\n\nasync function getServiceName() {\n const gitPath = await getGitPath();\n const defaultValue = gitPath.split(sep).pop();\n if (defaultValue === 'autorepo') {\n return getAutorepoAppName(gitPath);\n }\n return safeInput({ message: 'Enter the service name:', default: defaultValue });\n}\n\nexport function getVariationId(defaultVal = 'default') {\n return safeInput({ message: 'Enter your simulator id (Press enter to pass):', default: defaultVal });\n}\n\nasync function getPort(defaultVal = '8080', isLocal = false) {\n return safeInput({\n message: `Enter the ${isLocal ? 'local ' : ''}port:`,\n default: defaultVal,\n validate(value) {\n // Regex source: https://stackoverflow.com/a/12968117\n if (!/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(value)) {\n return 'Please enter a valid port number';\n }\n return true;\n },\n });\n}\n\nexport async function getLocalPort(defaultVal = '5432') {\n return getPort(defaultVal, true);\n}\n\nconst VALUE_GETTER_MAP = {\n cluster: getEnvironment,\n variationId: getVariationId,\n service: getServiceName,\n port: (defaultVal = '8080') => getPort(defaultVal),\n 'local-port': getLocalPort,\n} as const;\n\nexport async function fillMissingRequiredValues<T extends { [key in keyof typeof VALUE_GETTER_MAP]?: string }>(values: T, requiredValues: (keyof T | { option: keyof T; defaultVal: string; })[]) {\n for (const value of requiredValues) {\n const option = typeof value === 'object' ? value.option : value;\n const defaultVal = typeof value === 'object' ? value.defaultVal : undefined;\n if (typeof option !== 'string') {\n throw new Error(`Invalid option ${String(option)}`);\n }\n const getter = VALUE_GETTER_MAP[option as keyof typeof VALUE_GETTER_MAP];\n if (!getter) {\n throw new Error(`No value getter for ${String(option)}`);\n }\n\n values[option] ??= await getter(defaultVal) as T[keyof T & string];\n }\n return values;\n}\n\nexport async function promptForConfirmation(message: string, defaultVal = true) {\n return inquirerWrapper(confirm, { message, default: defaultVal });\n}\n","#!/usr/bin/env node\nimport fs from 'node:fs';\nimport asyncSpawn from './asyncSpawn.js';\nimport { promptForConfirmation } from './inquirer.js';\n\nconst IP_LINE_SUFFIX = 'SERVICE_HOST';\nconst PROD_CLUSTER_TO_CMD_MAP = {\n prodUs: ['us-prod-autofleet', 'us-central1', 'autofleet-production'],\n prodEu: ['eu-prod-autofleet', 'europe-west1', 'autofleetprod'],\n prodJp: ['jp-autofleet', 'asia-northeast1', 'autofleet-japan'],\n};\nconst SIMULATION_CLUSTER_TO_CMD_MAP = {\n dev1: ['dev-cluster-2', 'europe-west1', 'dev1-experiment-manager'],\n e2eManager: ['e2e-cluster-2', 'europe-west1', 'e2e-project-1'],\n expManager: ['af-experiment-manager', 'europe-west1'],\n};\nconst STAGING_CLUSTER_TO_CMD_MAP = {\n staging: ['stg-autofleet', 'europe-west1', 'autofleet-staging'],\n loadTest: ['lt-autofleet-production', 'asia-northeast1', 'load-testing-428806'],\n};\nconst MAPPING_CLUSTER_TO_CMD_MAP = {\n osrmProd: ['maps-prod', 'europe-west1', 'af-mapping'],\n};\nconst CLUSTER_TO_CMD_MAP = {\n ...PROD_CLUSTER_TO_CMD_MAP,\n ...SIMULATION_CLUSTER_TO_CMD_MAP,\n ...STAGING_CLUSTER_TO_CMD_MAP,\n ...MAPPING_CLUSTER_TO_CMD_MAP,\n};\n\nconst CLUSTER_TO_REDIS_REGION = {\n staging: 'europe-west1',\n};\n\nexport const SUPPORTED_CLUSTERS = Object.keys(CLUSTER_TO_CMD_MAP) as (keyof typeof CLUSTER_TO_CMD_MAP)[];\n\nconst getClusterDetails = async (clusterName: string) => {\n const command = CLUSTER_TO_CMD_MAP[clusterName as keyof typeof CLUSTER_TO_CMD_MAP];\n if (!command) {\n throw new Error(`Cluster name ${clusterName} does not exist!`);\n }\n const [name, region, project] = command;\n\n if (\n PROD_CLUSTER_TO_CMD_MAP[clusterName as keyof typeof PROD_CLUSTER_TO_CMD_MAP]\n && !(await promptForConfirmation(`❌❌ Are you sure you want to run this command on ${clusterName}? ❌❌`, false))) {\n console.log('Aborting...');\n return process.exit(1);\n }\n\n return { name, region, project };\n};\n\nexport const replaceInFile = ({ newFilePath, filePath, linesToReplace }: { newFilePath: string; filePath: string; linesToReplace: { find: string; replace: string; }[]; }) => {\n let fileAsString = fs.readFileSync(filePath, 'utf8');\n for (const { find, replace } of linesToReplace) {\n fileAsString = fileAsString.replace(find, replace);\n }\n fs.writeFileSync(newFilePath, fileAsString);\n};\n\nexport async function getCurrentCluster() {\n try {\n const { stdout } = await asyncSpawn('kubectl', ['config', 'current-context'], { print: false });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\nexport const connectToCluster = async (clusterName: string) => {\n const { name, region, project } = await getClusterDetails(clusterName);\n\n const expectedContext = `gke_${project || name}_${region}_${name}`;\n const currentContext = await getCurrentCluster();\n if (currentContext === expectedContext) {\n console.log(`Already connected to ${clusterName}, skipping connection to cluster...`);\n return { name, region, project };\n }\n\n await asyncSpawn('gcloud', ['container', 'clusters', 'get-credentials', name, '--region', region, '--project', project || name], { print: false });\n\n console.log(`Switched to ${clusterName} successfully`);\n\n return { name, region, project };\n};\n\nexport async function getCurrentNamespace() {\n try {\n const { stdout } = await asyncSpawn('kubectl', ['config', 'view', '--minify', '--output', 'jsonpath={..namespace}'], { print: false });\n return stdout.trim();\n } catch {\n return 'default'; // If no namespace is set, it defaults to 'default'\n }\n}\n\nexport const connectAndGetPrefix = async ({ clusterName, variationId }: { clusterName: string; variationId: string; }) => {\n await connectToCluster(clusterName);\n return `--namespace=${variationId}`;\n};\n\nexport const parseIps = (ips: string) => {\n const ipLines = ips.split('\\n').filter(Boolean);\n ipLines.shift();\n\n let formattedIps = ipLines.map((ipLine) => {\n const [name, _type, _clusterIp, externalIp, _port, _age] = ipLine.split(/(\\s+)/).map(s => s.trim()).filter(Boolean);\n const serviceName = name.replace(/-/g, '_').toUpperCase();\n const formattedLine = `${serviceName}_${IP_LINE_SUFFIX}=${externalIp}`;\n return formattedLine;\n });\n formattedIps = formattedIps.filter(formattedIp => !formattedIp.includes('none') && !formattedIp.includes('undefined'));\n return formattedIps;\n};\n\nexport function endWithError(error: string | Error, helpText?: string): never {\n if (!(error instanceof Error)) {\n error = new Error(error);\n }\n console.error(error);\n if (helpText) {\n console.log(helpText);\n }\n return process.exit(1);\n}\n\nexport const isSimulationCluster = (clusterName: string) => Object.keys(SIMULATION_CLUSTER_TO_CMD_MAP).includes(clusterName);\n\nexport const getRedisRegion = (clusterName: string) => CLUSTER_TO_REDIS_REGION[clusterName as keyof typeof CLUSTER_TO_REDIS_REGION]\n || CLUSTER_TO_CMD_MAP[clusterName as keyof typeof CLUSTER_TO_CMD_MAP][1];\n"],"mappings":"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"}