@autofleet/cli 2.27.0-alpha.2 → 2.27.1
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/claude-marketplace/plugins/autofleet/commands/update-packages.md +99 -21
- package/dist/e2e.js +1 -1
- package/dist/git-autofleet.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{utils-Dnt11RmF.js → utils-u-P48-YN.js} +2 -2
- package/dist/{utils-Dnt11RmF.js.map → utils-u-P48-YN.js.map} +1 -1
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -9
|
@@ -105,11 +105,18 @@ healthManagerOptions: {
|
|
|
105
105
|
rabbit: { connection: rabbit }, // include if service uses rabbit
|
|
106
106
|
events: { connection: events }, // include if service uses events — see Step 4
|
|
107
107
|
},
|
|
108
|
+
config: {
|
|
109
|
+
onReady: async () => {
|
|
110
|
+
await rabbit.startConsume(); // include if service uses rabbit — see Step 5
|
|
111
|
+
},
|
|
112
|
+
},
|
|
108
113
|
},
|
|
109
114
|
```
|
|
110
115
|
|
|
111
116
|
Only include clients that the service actually uses. The events instance must be created first — see Step 4.
|
|
112
117
|
|
|
118
|
+
If the service uses rabbit, include the `config.onReady` callback to start consumers only after the health manager confirms the service is fully initialized. This pairs with `autoStartConsumers: false` on the rabbit instance (Step 5.1).
|
|
119
|
+
|
|
113
120
|
### 1.6 Remove manual `/alive` endpoint and nitur import
|
|
114
121
|
|
|
115
122
|
```js
|
|
@@ -140,15 +147,19 @@ app.use(zehut.middleware({
|
|
|
140
147
|
}));
|
|
141
148
|
```
|
|
142
149
|
|
|
143
|
-
### 1.8 Add
|
|
150
|
+
### 1.8 Add peer dependencies
|
|
144
151
|
|
|
145
|
-
|
|
152
|
+
Super-express now requires `morgan` and `@autofleet/nitur` as peer dependencies. Install them if not already present:
|
|
146
153
|
|
|
147
154
|
```bash
|
|
148
|
-
npm install morgan
|
|
155
|
+
npm install morgan @autofleet/nitur
|
|
149
156
|
```
|
|
150
157
|
|
|
151
|
-
### 1.9
|
|
158
|
+
### 1.9 Note: readiness probe path changed
|
|
159
|
+
|
|
160
|
+
The readiness probe path changed from `/alive` to `/ready`. The `/alive` endpoint still exists (liveness check) but `/ready` is the new readiness endpoint. **Flag this to the user** — if the service has Helm charts or Kubernetes deployment configs, the readiness probe must be updated from `/alive` to `/ready` before deploying. Set `READINESS_PROBE_CHANGE_NEEDED` to `true` so you remember to include this in the PR (see Step 18).
|
|
161
|
+
|
|
162
|
+
### 1.10 Remove `/alive` endpoint tests
|
|
152
163
|
|
|
153
164
|
Search for tests that hit the `/alive` endpoint and remove them. The endpoint behavior has changed (now managed by HealthManager internally):
|
|
154
165
|
|
|
@@ -316,7 +327,7 @@ const events = require('./events');
|
|
|
316
327
|
|
|
317
328
|
**Applies when:** The service has `@autofleet/rabbit` in its dependencies.
|
|
318
329
|
|
|
319
|
-
### 5.1 Add logger and
|
|
330
|
+
### 5.1 Add logger, dontGracefulShutdown, and autoStartConsumers to constructor
|
|
320
331
|
|
|
321
332
|
Find the rabbit initialization file (usually `src/rabbit/index.ts`, `src/services/rabbit/index.ts`, or similar):
|
|
322
333
|
|
|
@@ -332,11 +343,14 @@ import logger from '../logger'; // adjust path based on file location
|
|
|
332
343
|
const rabbit = new RabbitMq({
|
|
333
344
|
logger,
|
|
334
345
|
dontGracefulShutdown: true,
|
|
346
|
+
autoStartConsumers: false,
|
|
335
347
|
});
|
|
336
348
|
```
|
|
337
349
|
|
|
338
350
|
**Critical:** `dontGracefulShutdown: true` is required because the health manager now handles graceful shutdown. Without this flag, rabbit will attempt to shut down independently, causing a double-shutdown conflict.
|
|
339
351
|
|
|
352
|
+
**Critical:** `autoStartConsumers: false` prevents rabbit from automatically starting message consumption on connect. Consumers must be started explicitly via `rabbit.startConsume()` inside `config.onReady` in SExpress/fastify-boilerplate (see Step 1.5 / Step 2.1). This ensures the service only starts processing messages after it is fully initialized and healthy.
|
|
353
|
+
|
|
340
354
|
---
|
|
341
355
|
|
|
342
356
|
## Step 6: Migrate @autofleet/node-common Router
|
|
@@ -495,7 +509,7 @@ module.exports = client;
|
|
|
495
509
|
|
|
496
510
|
If the service already has a Redis client file, ensure it uses `redis@4`'s `createClient` API and exports a connected client.
|
|
497
511
|
|
|
498
|
-
**Important:** If the service did NOT previously have a direct Redis client (i.e., you just created this file), the service now depends on `REDIS_HOST_NAME` and `REDIS_HOST_PORT` environment variables. Notify the user that these environment variables must be configured in the service's Helm chart / deployment config. Set `REDIS_HELM_CONFIG_NEEDED` to `true` so you remember to flag this in the PR (see Step
|
|
512
|
+
**Important:** If the service did NOT previously have a direct Redis client (i.e., you just created this file), the service now depends on `REDIS_HOST_NAME` and `REDIS_HOST_PORT` environment variables. Notify the user that these environment variables must be configured in the service's Helm chart / deployment config. Set `REDIS_HELM_CONFIG_NEEDED` to `true` so you remember to flag this in the PR (see Step 18).
|
|
499
513
|
|
|
500
514
|
### 7.3 Add the redis client to healthManagerOptions
|
|
501
515
|
|
|
@@ -759,11 +773,41 @@ Search the entire codebase for any remaining `require('bluebird')` or `import.*b
|
|
|
759
773
|
|
|
760
774
|
---
|
|
761
775
|
|
|
762
|
-
## Step 12: Migrate @autofleet/zehut type and trace changes
|
|
776
|
+
## Step 12: Migrate @autofleet/zehut type, user scope, and trace changes
|
|
763
777
|
|
|
764
|
-
**Applies when:** The service imports types or trace functions from `@autofleet/zehut`.
|
|
778
|
+
**Applies when:** The service imports types, user context, or trace functions from `@autofleet/zehut`.
|
|
765
779
|
|
|
766
|
-
### 12.1 Replace
|
|
780
|
+
### 12.1 Replace `getCurrentPayload` user extraction with `getUser()`
|
|
781
|
+
|
|
782
|
+
Search for any code that extracts the user object via `getCurrentPayload()` and `context.get('userObject')`. Replace with the new `getUser()` helper:
|
|
783
|
+
|
|
784
|
+
**ESM:**
|
|
785
|
+
```ts
|
|
786
|
+
// BEFORE
|
|
787
|
+
import zehut from '@autofleet/zehut';
|
|
788
|
+
const { context } = zehut.getCurrentPayload();
|
|
789
|
+
const user = context?.get('userObject');
|
|
790
|
+
|
|
791
|
+
// AFTER
|
|
792
|
+
import { getUser } from '@autofleet/zehut';
|
|
793
|
+
const user = getUser();
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**CJS:**
|
|
797
|
+
```js
|
|
798
|
+
// BEFORE
|
|
799
|
+
const zehut = require('@autofleet/zehut');
|
|
800
|
+
const { context } = zehut.getCurrentPayload();
|
|
801
|
+
const user = context?.get('userObject');
|
|
802
|
+
|
|
803
|
+
// AFTER
|
|
804
|
+
const { getUser } = require('@autofleet/zehut');
|
|
805
|
+
const user = getUser();
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
Search the entire codebase for `getCurrentPayload` and `userObject` to find all occurrences. This pattern may appear in middleware, route handlers, service files, or event publishers.
|
|
809
|
+
|
|
810
|
+
### 12.2 Replace old type imports
|
|
767
811
|
|
|
768
812
|
The `ApiUser` type has moved:
|
|
769
813
|
|
|
@@ -777,7 +821,7 @@ import { type User } from '@autofleet/zehut';
|
|
|
777
821
|
|
|
778
822
|
Update any interfaces that extend `ApiUser` to extend `User` instead.
|
|
779
823
|
|
|
780
|
-
### 12.
|
|
824
|
+
### 12.3 Use `traceTypes` constants instead of string literals
|
|
781
825
|
|
|
782
826
|
If the service uses `newTrace` with string arguments:
|
|
783
827
|
|
|
@@ -873,7 +917,29 @@ Search for all `await settings.setLocal` and `await.*setLocal` patterns and remo
|
|
|
873
917
|
|
|
874
918
|
---
|
|
875
919
|
|
|
876
|
-
## Step 16:
|
|
920
|
+
## Step 16: Fix transitive type errors with skipLibCheck
|
|
921
|
+
|
|
922
|
+
**Applies when:** The service uses TypeScript and `tsc` / `npm run build` produces type errors inside `node_modules` after the upgrade (e.g., errors in fastify, winston, or other transitive dependencies).
|
|
923
|
+
|
|
924
|
+
The updated `@autofleet/*` packages pull in newer versions of their transitive dependencies which may have type conflicts with each other. These are not bugs in your code — they are type mismatches between third-party packages in `node_modules`.
|
|
925
|
+
|
|
926
|
+
### 16.1 Enable skipLibCheck in tsconfig.json
|
|
927
|
+
|
|
928
|
+
Add or ensure `skipLibCheck: true` in the service's `tsconfig.json`:
|
|
929
|
+
|
|
930
|
+
```json
|
|
931
|
+
{
|
|
932
|
+
"compilerOptions": {
|
|
933
|
+
"skipLibCheck": true
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
This tells TypeScript to skip type checking of `.d.ts` files in `node_modules`, which eliminates transitive type errors while still fully type-checking your own code.
|
|
939
|
+
|
|
940
|
+
---
|
|
941
|
+
|
|
942
|
+
## Step 17: Verify the migration
|
|
877
943
|
|
|
878
944
|
After completing all applicable migrations:
|
|
879
945
|
|
|
@@ -887,11 +953,11 @@ If any step fails, read the error carefully — it likely points to a migration
|
|
|
887
953
|
|
|
888
954
|
---
|
|
889
955
|
|
|
890
|
-
## Step
|
|
956
|
+
## Step 18: Create or update the Pull Request
|
|
891
957
|
|
|
892
958
|
After all migrations pass verification, create a PR or update an existing one.
|
|
893
959
|
|
|
894
|
-
###
|
|
960
|
+
### 18.1 Check for an existing PR
|
|
895
961
|
|
|
896
962
|
Check if there is already an open PR for the current branch:
|
|
897
963
|
|
|
@@ -924,23 +990,27 @@ Build the PR body using this template. Fill in only the sections that apply base
|
|
|
924
990
|
- [ ] **database config** — password default null → ''
|
|
925
991
|
- [ ] **New Relic** — removed newrelic.js and initialization
|
|
926
992
|
- [ ] **bluebird** — replaced with promiseMap from node-common or native for...of, removed promisifyAll
|
|
927
|
-
- [ ] **zehut
|
|
993
|
+
- [ ] **zehut** — replaced getCurrentPayload/userObject with getUser(), replaced ApiUser with User, replaced string trace literals with traceTypes constants
|
|
928
994
|
- [ ] **obsolete dependencies** — removed worker-threads-pool, newrelic, bluebird
|
|
929
995
|
- [ ] **vitest config** — added joi alias and SSR noExternal
|
|
930
996
|
- [ ] **settings** — removed await from setLocal calls
|
|
997
|
+
- [ ] **skipLibCheck** — enabled in tsconfig.json to fix transitive type errors
|
|
931
998
|
|
|
932
999
|
### Notes
|
|
933
1000
|
<!-- Any additional context, things that need manual verification, or known issues -->
|
|
934
1001
|
|
|
935
1002
|
### Helm / Infra changes needed
|
|
936
1003
|
<!-- List any infrastructure changes required before deploying this PR -->
|
|
1004
|
+
<!-- Always fill this in if applicable — do not leave empty -->
|
|
937
1005
|
```
|
|
938
1006
|
|
|
939
|
-
**Important:**
|
|
940
|
-
- If
|
|
941
|
-
- If a new Redis client was created in Step 7 (the service didn't previously have one)
|
|
1007
|
+
**Important:** Always fill in the "Helm / Infra changes needed" section. Check for these:
|
|
1008
|
+
- If super-express was migrated (Step 1): "Readiness probe path must be updated from `/alive` to `/ready` in the Helm chart"
|
|
1009
|
+
- If a new Redis client was created in Step 7 (the service didn't previously have one): "Redis env vars `REDIS_HOST_NAME` and `REDIS_HOST_PORT` must be added to the Helm chart / deployment config"
|
|
1010
|
+
|
|
1011
|
+
If neither applies, write "None".
|
|
942
1012
|
|
|
943
|
-
###
|
|
1013
|
+
### 18.2 Create or update the PR
|
|
944
1014
|
|
|
945
1015
|
**If no PR exists** — create one:
|
|
946
1016
|
|
|
@@ -954,9 +1024,17 @@ gh pr create --title "Update @autofleet packages" --body "<description>"
|
|
|
954
1024
|
gh pr edit --body "<description>"
|
|
955
1025
|
```
|
|
956
1026
|
|
|
957
|
-
###
|
|
1027
|
+
### 18.3 Add PR comments for infrastructure changes
|
|
1028
|
+
|
|
1029
|
+
Add a comment to the PR for **each** applicable infrastructure change:
|
|
1030
|
+
|
|
1031
|
+
**If super-express was migrated (Step 1):**
|
|
1032
|
+
|
|
1033
|
+
```bash
|
|
1034
|
+
gh pr comment --body "⚠️ **Action required before deploy:** The readiness probe path has changed from \`/alive\` to \`/ready\`. The Helm chart / Kubernetes deployment config must be updated before deploying this PR."
|
|
1035
|
+
```
|
|
958
1036
|
|
|
959
|
-
If a new Redis client was created in Step 7 (the service did not previously have a direct Redis connection)
|
|
1037
|
+
**If a new Redis client was created in Step 7 (the service did not previously have a direct Redis connection):**
|
|
960
1038
|
|
|
961
1039
|
```bash
|
|
962
1040
|
gh pr comment --body "⚠️ **Action required before deploy:** This PR adds a new direct Redis client to the service. The following environment variables must be configured in the Helm chart before deploying:
|
|
@@ -966,6 +1044,6 @@ gh pr comment --body "⚠️ **Action required before deploy:** This PR adds a n
|
|
|
966
1044
|
Without these, the service will fail to connect to Redis on startup."
|
|
967
1045
|
```
|
|
968
1046
|
|
|
969
|
-
###
|
|
1047
|
+
### 18.4 Notify the user
|
|
970
1048
|
|
|
971
1049
|
Print the PR URL and remind the user about any infrastructure changes needed before merging.
|
package/dist/e2e.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,c as t,i as n,l as r,n as i,x as a}from"./utils-
|
|
2
|
+
import{C as e,c as t,i as n,l as r,n as i,x as a}from"./utils-u-P48-YN.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}=e({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 e=(f.branches?.replace(`{`,` `)||``).replace(/[^a-z0-9]/gi,``),t=`${o.resolve()}/bin/utils/e2e.sh`,n=`${o.resolve()}/e2e.sh`;r({newFilePath:n,filePath:t,linesToReplace:[{find:`$E2E_BRANCH_PLACE_HOLDER$`,replace:f.e2eBranch},{find:`$BRANCHES_PLACE_HOLDER$`,replace:f.branches},{find:`$NAME_PLACE_HOLDER$`,replace:e}]}),await a(`chmod`,[`+x ${n} && ${n}`]),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(e=>a(`kubectl`,[`annotate`,_,`service`,e,`cloud.google.com/load-balancer-type-`],{print:!1}))),await Promise.all(c.map(e=>a(`kubectl`,[`patch`,`svc`,_,e,`-p`,`{"spec": {"type": "LoadBalancer"}}`],{print:!1}))),console.log(`exposed services successfully. the services are now creating public ips.`),await s(async()=>{let{stdout:e}=await a(`kubectl`,[_,`get`,`services`],{print:!1}),n=t(e);if(n.some(e=>e.includes(`<pending>`)))throw Error(`Some services are still pending`);n.forEach(e=>console.log(e))},{retries:10,factor:1,maxTimeout:5e3,randomize:!0}),process.exit(0));export{};
|
|
3
3
|
//# sourceMappingURL=e2e.js.map
|
package/dist/git-autofleet.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,_ as t,g as n,h as r,i,m as a,v as o,x as s,y as c}from"./utils-
|
|
2
|
+
import{C as e,_ as t,g as n,h as r,i,m as a,v as o,x as s,y as c}from"./utils-u-P48-YN.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:e,packageName:t,preReleaseId:n=``})=>{let{stdout:r}=await s(`npm`,[`version`,e,`--no-git-tag-version`,`--preid`,n],{print:!1,cwd:t?`.${u}packages${u}${t}`:void 0});return await s(`git`,[`add`,`package*`],{print:!1}),await s(`git`,[`commit`,`-m`,`${e} version: ${r}`],{print:!1}),console.log(`Created commit for version bump: ${e}. Version is now ${r}`),r},v=async e=>{let t=await c(),{default:{version:n}}=await import(`${e?`${t}${u}packages${u}${e}`:t}${u}package.json`,{assert:{type:`json`},with:{type:`json`}});return n.replace(/\d+\.\d+\.\d+(?:-beta-([\w]+)?\.\d+)?/,`$1`)},{positionals:y,help:b}=e({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[e,t]=await Promise.all([c(),o()]);await s(`open`,[`https://github.com/Autofleet/${l(e)}/compare/${t}?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 e=await w(),n=await T({message:`Which package do you want to release?`,pathIfAutorepo:e});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=n?`.${u}packages${u}${n}`:void 0,d=!(await t(n?`.${u}packages${u}${n}${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(n),h=d&&await _({versionType:S||`prerelease`,preReleaseId:`beta-${m||f().split(`-`)[0]}`,packageName:n}),g=e?`pnpm`:`npm`;await s(g,[`run`,`build`],{cwd:l});let y=await r({message:`In case your token requires an OTP, please enter it:`});try{await s(g,[`publish`,`--tag`,`beta`,`--@autofleet:registry=https://registry.npmjs.org`,...y?[`--otp`,y]:[],...e?[`--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:e}=await s(g,[`info`,`.`,`version`],{print:!1,cwd:l});console.log(`Published beta version with existing version: ${e}`)}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,a as n,b as r,c as i,d as a,f as o,g as s,i as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as ee,w as te,x as _,y as v}from"./utils-
|
|
2
|
+
import{C as e,S as t,a as n,b as r,c as i,d as a,f as o,g as s,i as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as ee,w as te,x as _,y as v}from"./utils-u-P48-YN.js";import{styleText as y}from"node:util";import*as ne from"node:fs";import b from"node:fs";import{execFile as re,execSync as x,spawn as ie}from"node:child_process";import{confirm as S}from"@inquirer/prompts";import*as C from"node:path";import w,{basename as T,join as E,resolve as D,sep as ae}from"node:path";import{mkdir as oe,readFile as O,writeFile as k}from"node:fs/promises";import*as se from"node:os";import ce,{EOL as A}from"node:os";import{randomUUID as le}from"node:crypto";import{setTimeout as ue}from"node:timers/promises";import{cwd as j}from"node:process";function M(e){return e.replace(/^[\^~]/,``)}function N(e){let t=M(e),n=/^(\d+)/.exec(t);return n?parseInt(n[1],10):0}function de(e,t){return N(t)>N(e)}function fe(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 P=w.join(ce.homedir(),`.autofleet`,`update-check.json`);function pe(){try{return JSON.parse(b.readFileSync(P,`utf-8`))}catch{return null}}function me(e){try{b.mkdirSync(w.dirname(P),{recursive:!0}),b.writeFileSync(P,JSON.stringify(e))}catch{}}function he(e,t){try{return x(`${e} ${t.join(` `)}`,{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()||null}catch{return null}}function ge(){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=he(t,n);if(r&&e.startsWith(r))return t}return`npm`}function _e(e){return e===`pnpm`?`pnpm add -g @autofleet/cli@latest`:e===`yarn`?`yarn global add @autofleet/cli@latest`:`${w.join(w.dirname(process.execPath),`npm`)} install -g @autofleet/cli@latest`}function ve(){re(`npm`,[`view`,`@autofleet/cli@latest`,`version`],{encoding:`utf-8`,timeout:15e3},(e,t)=>{if(e||!t.trim())return;let n=t.trim();n&&me({latestVersion:n,checkedAt:Date.now()})}).unref()}async function ye(e=!1){if(e)return;let t=pe();if(t&&fe(t.latestVersion,te)&&await l(`New @autofleet/cli version available (${te} → ${t.latestVersion}). Update now?`)){let e=_e(ge());console.log(`Updating @autofleet/cli...`),x(e,{stdio:`inherit`}),console.log(`✓ Updated! Please re-run your command.`),process.exit(0)}(t?Date.now()-t.checkedAt:1/0)>864e5&&ve()}const F=`.mirrord`;async function I({makeDir:e=!1}={}){let t=E(await v(),F);return e&&await oe(t,{recursive:!0}),E(t,`mirrord.json`)}async function be(e=le()){let t=await I({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 k(t,JSON.stringify(n,null,2)),{mirrordConfigData:n,mirrordPath:t}}async function xe(){try{let e=await O(await I(),{encoding:`utf-8`});return JSON.parse(e||`{}`)?.target?.namespace??``}catch{return``}}function Se(e){process.once(`exit`,e),process.once(`SIGTERM`,e),process.once(`SIGINT`,e)}function L(e){return e&&=e.trim(),e&&(e.startsWith(`'`)&&e.endsWith(`'`)&&(e=e.slice(1,-1)),e)}const R=`livenessProbe`,z=`readinessProbe`,B=e=>`jsonpath='{.spec.template.spec.containers[?(@.name=="worker")].${e}}'`,V=(...e)=>`{"spec": {"template": {"spec": {"containers": [{"name": "worker",${e.map(([e,t])=>`"${e}": ${t}`).join(`,`)}}]}}}}`;var Ce=async(e,t,n)=>{console.log(`Will now disable health check to allow debugging.`);let[{stdout:r},{stdout:i}]=await Promise.all([_(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,B(R)],{print:!1}),_(`kubectl`,[`get`,`deployment/${n}`,e,`-o`,B(z)],{print:!1})]);r&&=L(r),i&&=L(i),(r||i)&&(await _(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,V([R,`null`],[z,`null`])],{print:!1}),console.log(`Health check disabled, will now start mirrord and run "npm run dev". Make sure to attach a debugger!`));let a=new AbortController;Se(async()=>{globalThis.executedExitHooks||(globalThis.executedExitHooks=!0,a.abort(),(r||i)&&(console.log(`Re-enabling health check.`),await _(`kubectl`,[`patch`,`deployment/${n}`,e,`--patch`,`'${V([R,r],[z,i])}'`],{print:!1,shell:!0}),console.log(`health check enabled.`)),process.exit(0))});try{let e=await I();await _(`mirrord`,[`exec`,`-t`,`deployment/${n}`,`-n`,t,`-f`,e,`--steal`,`npm`,`run`,`dev`],{signal:a.signal})}catch(e){if(e&&typeof e==`object`&&`code`in e&&e.code===`ABORT_ERR`)return;c(e)}},we=async(e,t)=>{if(await p(e),e===`expManager`||e===`dev1`){let{variationId:e}=await g({variationId:t},[`variationId`]);e!==``&&(await n()===e&&(console.log(`Already connected to simulation with uuid: ${e}, skipping namespace switch...`),process.exit(0)),await _(`kubectl`,[`config`,`set-context`,`--current`,`--namespace=${e}`],{print:!1}),console.log(`Switched to simulation with uuid: ${e} successfully`))}process.exit(0)};async function Te(){try{await _(`telepresence`,[`version`],{print:!1})}catch{c(`Telepresence is not installed. Please install it from:
|
|
3
3
|
https://www.telepresence.io/docs/latest/quick-start/`)}}function Ee(){return s({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 De(e){await Te();let{cluster:t=``,service:n=``}=e;await p(t);let r=await Ee();if([`leave`,`connect`].includes(r)||c(`Invalid action, how did you get here? 🤔`),r===`leave`){await _(`telepresence`,[`leave`,n]),console.log(`Disconnected! 👋`);return}let i=e.variationId||await f(),a=e[`local-port`]&&Number.parseInt(e[`local-port`],10)||Number.parseInt(await o()||``,10);await _(`telepresence`,[`connect`,`--namespace=${i}`]),await _(`telepresence`,[`intercept`,n,`--port`,a.toString(),`--env-file=./.env`]),console.log(`Everything is set up! 🚀`),console.log(`You can now access the service at localhost:${a}`),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 Oe=async(e,t,n)=>{n||c(Error(`service is required for exposeService`),t),await _(`kubectl`,[`patch`,`svc`,e,n,`-p`,`{"spec": {"type": "LoadBalancer"}}`]),console.log(`exposed ${n} successfully. the service is now creating an internal load balancer ip to use with vpn`),process.exit(0)},ke=async(e,t,n,r,i)=>{let a=Number.parseInt(e[`local-port`]??`5432`,10);Number.isNaN(a)&&c(Error(`if defined, local-port must be a number`),r);let o=`afpass_${n}`,s=`postgres`,l=n.replaceAll(`-`,`_`),u=i?`${i.replaceAll(`-`,`_`)||``}_${l}`:`postgres`,d=`postgres://${s}:${o}@localhost:${a}/${u}?&nickname=var_${n}`;console.log(`Forwarding db to local port ${a}.\naccess the DB at ${d}\nPress ctrl+c to stop.`);let f=` DB_USERNAME=${s}
|
|
4
4
|
DB_PASSWORD=${o}
|
|
5
5
|
DB_NAME=${i?u:`<service_name>_${l}`}`;console.log(`Generated database environment for local development:
|
|
@@ -1,4 +1,4 @@
|
|
|
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.27.
|
|
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.27.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
2
|
|
|
3
3
|
Commands:
|
|
4
4
|
${Object.entries(t.commands).map(([e,t])=>`${e.padEnd(30,` `)} ${t}`).join(`
|
|
@@ -10,4 +10,4 @@ Options:
|
|
|
10
10
|
`)}
|
|
11
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=>{let{stdout:t}=await f(`git`,[`diff`,`origin/master..`,e],{print:!1});return t},g=async e=>{try{return await f(`git`,[`check-ignore`,e],{print:!1}),!0}catch{return!1}};function _(){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 v;const y=()=>v?.();function b(){return process.once(`beforeExit`,y),{[Symbol.dispose](){process.off(`beforeExit`,y),v=void 0}}}async function x(e,...t){try{try{var n=_();n.u(b());let r=e(...t);return v=r.cancel,await r}catch(e){n.e=e}finally{n.d()}}catch(e){e instanceof Error&&[`CancelPromptError`,`ExitPromptError`].includes(e.constructor.name)&&J(`Cancelled! 👋`),J(e);return}}function S(...e){return x(a,...e)}function C(...e){return x(i,...e)}const w=e=>e.charAt(0).toUpperCase()+e.slice(1).split(/(?=[A-Z])/).join(` `);function T(){return S({message:`Which environment do you want to use?`,choices:B.map(e=>({name:w(e),value:e})),default:`expManager`})}async function E(e){return S({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 D(){let e=await m(),t=e.split(o).pop();return t===`autorepo`?E(e):C({message:`Enter the service name:`,default:t})}function O(e=`default`){return C({message:`Enter your simulator id (Press enter to pass):`,default:e})}async function k(e=`8080`,t=!1){return C({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 A(e=`5432`){return k(e,!0)}const j={cluster:T,variationId:O,service:D,port:(e=`8080`)=>k(e),"local-port":A};async function M(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=j[t];if(!i)throw Error(`No value getter for ${String(t)}`);e[t]??=await i(r)}return e}async function N(e,t=!0){return x(r,{message:e,default:t})}const P={prodUs:[`us-autofleet-production`,`us-central1`,`autofleet-production`],prodEu:[`eu-prod-autofleet`,`europe-west1`,`autofleetprod`],prodJp:[`jp-autofleet-production`,`asia-northeast1`,`autofleet-japan`]},F={dev1:[`dev-cluster-2`,`europe-west1`,`dev1-experiment-manager`],e2eManager:[`e2e-cluster-2`,`europe-west1`,`e2e-project-1`],expManager:[`af-experiment-manager`,`europe-west1`]},I={staging:[`stg-autofleet`,`europe-west1`,`autofleet-staging`],loadTest:[`lt-autofleet-production`,`asia-northeast1`,`load-testing-428806`]},L={osrmProd:[`maps-prod`,`europe-west1`,`af-mapping`]},R={...P,...F,...I,...L},z={staging:`europe-west1`},B=Object.keys(R),V=async e=>{let t=R[e];if(!t)throw Error(`Cluster name ${e} does not exist!`);let[n,r,i]=t;return P[e]&&!await N(`❌❌ Are you sure you want to run this command on ${e}? ❌❌`,!1)?(console.log(`Aborting...`),process.exit(1)):{name:n,region:r,project:i}},H=({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 U(){try{let{stdout:e}=await f(`kubectl`,[`config`,`current-context`],{print:!1});return e.trim()}catch{return null}}const W=async e=>{let{name:t,region:n,project:r}=await V(e),i=`gke_${r||t}_${n}_${t}`;return await U()===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 G(){try{let{stdout:e}=await f(`kubectl`,[`config`,`view`,`--minify`,`--output`,`jsonpath={..namespace}`],{print:!1});return e.trim()}catch{return`default`}}const K=async({clusterName:e,variationId:t})=>(await W(e),`--namespace=${t}`),q=e=>{let t=e.split(`
|
|
12
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 J(e,t){return e instanceof Error||(e=Error(e)),console.error(e),t&&console.log(t),process.exit(1)}const Y=e=>Object.keys(F).includes(e),X=e=>z[e]||R[e][1];export{u as C,d as S,h as _,G as a,g as b,q as c,E as d,A as f,S as g,C as h,J as i,H as l,N as m,K as n,X as o,O as p,W as r,Y as s,B as t,M as u,p as v,c as w,f as x,m as y};
|
|
13
|
-
//# sourceMappingURL=utils-
|
|
13
|
+
//# sourceMappingURL=utils-u-P48-YN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-Dnt11RmF.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 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-autofleet-production', 'us-central1', 'autofleet-production'],\n prodEu: ['eu-prod-autofleet', 'europe-west1', 'autofleetprod'],\n prodJp: ['jp-autofleet-production', '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":"6QCMA,MAAM,EAAiB,CACrB,KAAM,CACJ,KAAM,UACN,MAAO,IACP,QAAS,GACT,YAAa,kCACd,CACD,QAAS,CACP,KAAM,UACN,MAAO,IACP,QAAS,GACT,YAAa,sBACd,CACD,MAAO,CACL,KAAM,UACN,MAAO,IACP,QAAS,GACT,YAAa,uDACd,CACF,CAKD,SAAwBA,EAAuD,EAAsB,CACnG,EAAO,QAAU,CAAE,GAAG,EAAgB,GAAG,EAAO,QAAS,CACzD,IAAM,EAAOC,EAAgB,EAAsB,CAC7C,CAAE,UAAW,EACd,EAAiC,UACpC,QAAQ,IAAIC,EAAoB,CAChC,QAAQ,KAAK,EAAE,EAGjB,IAAM,EAAY,EAAO,SAAgB;;;IAGvC,OAAO,QAAQ,EAAO,SAAS,CAAC,KAAK,CAAC,EAAS,KAAa,GAAG,EAAQ,OAAO,GAAI,IAAI,CAAC,GAAG,IAAU,CAAC,KAAK;IAAO,CAAC;EAHhF,GAM9B,EAA2B,KAAK,IAAI,MAAM,KAAM,OAAO,OAAO,EAAO,QAAQ,CAAC,KAAK,CAAE,iBAAkB,EAAY,OAAO,CAAC,CAE3H,EAAO;EACb,EAAO,QAAQ,GAAG,EAAW,aAAe,GAAG,WAAW,EAAS;;IAEjE,OAAO,QAAQ,EAAO,QAAQ,CAAC,KAAK,CAAC,EAAQ,CAAE,cAAa,OAAM,YAE3D,IADK,EAAQ,KAAK,EAAO,KAAK,IAAU,KAAK,KACtC,OAAO,GAAI,IAAI,CAAC,GAAG,EAAY,OAAO,EAA2B,GAAI,IAAI,CAAC,IAAI,EAAK,GACjG,CAAC,KAAK;IAAO,CAAC;EAQhB,OALK,EAA8B,OACjC,QAAQ,IAAI,EAAK,CACjB,QAAQ,KAAK,EAAE,EAGV,CAAE,GAAG,EAAM,OAAM,CC1C1B,MAAa,MAAiC,CAC5C,GAAI,QAAQ,cACV,OAAO,QAAQ,eAAkB,CAEnC,IAAIC,EACAC,EAKJ,MAAO,CAAE,QAJO,IAAI,SAAY,EAAK,IAAQ,CAC3C,EAAS,EACT,EAAU,GACV,CACgB,SAAQ,QAAA,EAAS,EClBrC,IAAA,EAAe,MACb,EACA,EACA,CACE,QAAQ,GACR,MAAM,EAAE,CACR,SACA,QACA,OAC+G,EAAE,GAChH,CACC,OAAO,GAAS,YAClB,EAAQ,EACR,EAAO,IAAA,IAET,IAAM,EAAgB,OAAO,CACvB,EAAc,EAAU,MAAQ,EAAU,MAAM,QAAQ,MAAO,UAAU,CAAG,KAC5E,CAAE,UAAS,SAAQ,QAAA,GAAY,GAAoC,CACnE,EAAQ,EAAM,EAAS,EAAM,CAAE,IAAK,OAAO,OAAO,EAAK,QAAQ,IAAI,CAAE,SAAQ,QAAO,MAAK,CAAC,CAC5F,IACF,EAAM,OAAO,KAAK,QAAQ,OAAO,CACjC,EAAM,OAAO,KAAK,QAAQ,OAAO,EAEnC,IAAI,EAAS,GACT,EAAS,GACb,EAAM,QAAQ,GAAG,OAAS,GAAS,CACjC,GAAU,GACV,CACF,EAAM,QAAQ,GAAG,OAAS,GAAS,CACjC,GAAU,GACV,CACF,IAAM,EAAsB,EAAQ,OAAS,QAC7C,SAAS,EAAc,EAAc,CACnC,EAAM,eAAe,EAAqB,EAAmB,CAC7D,OAAO,OAAO,EAAO,CACnB,IAAK,EAAM,IACX,SACA,SACA,OAAQ,KACR,OAAQ,KACT,CAAC,CACF,EAAO,EAAM,CAEf,SAAS,EAAmB,EAAqB,EAAuB,CACtE,EAAM,eAAe,QAAS,EAAc,CAC5C,IAAMC,EAAsB,CAC1B,IAAK,EAAM,IACX,SACA,SACA,OAAQ,EACR,OAAA,EACD,CACD,GAAI,IAAS,EAAG,CACd,IAAM,EAAkB,OAAO,GAAS,WAAa,IAAI,GAAM,KAAK,IAAI,IAAO,GACzE,EAAQC,EACN,MAAM,GAAG,IAAU,EAAe,uBAAuBA,IAAS,CAClE,MAAM,GAAG,IAAU,EAAe,8BAA8B,IAAO,CAC3E,EAAM,OAAS,IACjB,EAAM,OAAS,KAAK,KAEtB,OAAO,OAAO,EAAO,EAAO,CAC5B,EAAO,EAAM,MAEb,EAAQ,EAAO,CAMnB,OAFA,EAAM,KAAK,EAAqB,EAAmB,CACnD,EAAM,KAAK,QAAS,EAAc,CAC3B,GC9ET,MAAa,EAAmB,SAAY,CAC1C,GAAM,CAAE,OAAQ,GAAkB,MAAMC,EAAW,MAAO,CAAC,SAAU,iBAAiB,CAAE,CAAE,MAAO,GAAO,CAAC,CACzG,OAAO,EAAc,MAAM,EAGhB,EAAa,SAAY,CACpC,GAAM,CAAE,OAAQ,GAAY,MAAMA,EAAW,MAAO,CAAC,YAAa,kBAAkB,CAAE,CAAE,MAAO,GAAO,CAAC,CACvG,OAAO,EAAQ,MAAM,EAGV,EAAmB,KAAO,IAAqB,CAC1D,GAAM,CAAE,OAAQ,GAAY,MAAMA,EAAW,MAAO,CAAC,OAAQ,kBAAmB,EAAS,CAAE,CAAE,MAAO,GAAO,CAAC,CAC5G,OAAO,GAGI,EAAgB,KAAO,IAAiB,CACnD,GAAI,CAEF,OADA,MAAMA,EAAW,MAAO,CAAC,eAAgBC,EAAK,CAAE,CAAE,MAAO,GAAO,CAAC,CAC1D,QACD,CACN,MAAO,ijCCNX,OAAO,UAAY,OAAO,IAAI,iBAAiB,CAE/C,OAAO,eAAiB,OAAO,IAAI,sBAAsB,CACzD,IAAIC,EACJ,MAAM,MAAgB,KAAY,CAClC,SAAS,GAAkB,CAEzB,OADA,QAAQ,KAAK,aAAc,EAAQ,CAC5B,CACL,CAAC,OAAO,UAAW,CACjB,QAAQ,IAAI,aAAc,EAAQ,CAClC,EAAW,IAAA,IAEd,CAGH,eAAe,EAA+B,EAA2B,GAAG,EAA2C,CACrH,GAAI,eACI,EAAA,EAAI,GAAiB,CAAA,CAC3B,IAAM,EAAS,EAAG,GAAG,EAAO,CAE5B,MADA,GAAW,EAAO,OACX,MAAM,sCACN,EAAO,CACV,aAAiB,OAAS,CAAC,oBAAqB,kBAAkB,CAAC,SAAS,EAAM,YAAY,KAAK,EACrG,EAAa,gBAAgB,CAE/B,EAAa,EAAe,CAC5B,QAIJ,SAAgB,EAA2B,GAAG,EAA0C,CACtF,OAAO,EAAgB,EAAQ,GAAG,EAAO,CAG3C,SAAgB,EAAU,GAAG,EAAkC,CAC7D,OAAO,EAAgB,EAAO,GAAG,EAAO,CAG1C,MAAM,EAAsB,GAAgB,EAAI,OAAO,EAAE,CAAC,aAAa,CAAG,EAAI,MAAM,EAAE,CAAC,MAAM,YAAY,CAAC,KAAK,IAAI,CAEnH,SAAS,GAAiB,CACxB,OAAO,EAAW,CAChB,QAAS,wCACT,QAAS,EAAmB,IAAI,IAAY,CAAE,KAAM,EAAmB,EAAQ,CAAE,MAAO,EAAS,EAAE,CACnG,QAAS,aACV,CAAC,CAGJ,eAAsB,EAAmB,EAA4B,CAEnE,OAAO,EAAW,CAChB,QAAS,qDACT,SAHgB,MAAM,EAAQ,GAAG,IAAqB,EAAI,MAAM,EAAE,OAAO,GAAQ,CAAC,EAAK,WAAW,IAAI,EAAI,CAAC,EAAK,SAAS,OAAO,CAAC,CAG/G,IAAI,IAAQ,CAAE,KAAM,EAAK,MAAO,EAAK,EAAE,CAC1D,CAAC,CAGJ,eAAe,GAAiB,CAC9B,IAAM,EAAU,MAAM,GAAY,CAC5B,EAAe,EAAQ,MAAM,EAAI,CAAC,KAAK,CAI7C,OAHI,IAAiB,WACZ,EAAmB,EAAQ,CAE7B,EAAU,CAAE,QAAS,0BAA2B,QAAS,EAAc,CAAC,CAGjF,SAAgB,EAAe,EAAa,UAAW,CACrD,OAAO,EAAU,CAAE,QAAS,iDAAkD,QAAS,EAAY,CAAC,CAGtG,eAAe,EAAQ,EAAa,OAAQ,EAAU,GAAO,CAC3D,OAAO,EAAU,CACf,QAAS,aAAa,EAAU,SAAW,GAAG,OAC9C,QAAS,EACT,SAAS,EAAO,CAKd,MAHK,2FAA2F,KAAK,EAAM,CAGpG,GAFE,oCAIZ,CAAC,CAGJ,eAAsB,EAAa,EAAa,OAAQ,CACtD,OAAO,EAAQ,EAAY,GAAK,CAGlC,MAAM,EAAmB,CACvB,QAAS,EACT,YAAa,EACb,QAAS,EACT,MAAO,EAAa,SAAW,EAAQ,EAAW,CAClD,aAAc,EACf,CAED,eAAsB,EAAyF,EAAW,EAAwE,CAChM,IAAK,IAAM,KAAS,EAAgB,CAClC,IAAM,EAAS,OAAO,GAAU,SAAW,EAAM,OAAS,EACpD,EAAa,OAAO,GAAU,SAAW,EAAM,WAAa,IAAA,GAClE,GAAI,OAAO,GAAW,SACpB,MAAU,MAAM,kBAAkB,OAAO,EAAO,GAAG,CAErD,IAAM,EAAS,EAAiB,GAChC,GAAI,CAAC,EACH,MAAU,MAAM,uBAAuB,OAAO,EAAO,GAAG,CAG1D,EAAO,KAAY,MAAM,EAAO,EAAW,CAE7C,OAAO,EAGT,eAAsB,EAAsB,EAAiB,EAAa,GAAM,CAC9E,OAAO,EAAgB,EAAS,CAAE,UAAS,QAAS,EAAY,CAAC,CC5HnE,MACM,EAA0B,CAC9B,OAAQ,CAAC,0BAA2B,cAAe,uBAAuB,CAC1E,OAAQ,CAAC,oBAAqB,eAAgB,gBAAgB,CAC9D,OAAQ,CAAC,0BAA2B,kBAAmB,kBAAkB,CAC1E,CACK,EAAgC,CACpC,KAAM,CAAC,gBAAiB,eAAgB,0BAA0B,CAClE,WAAY,CAAC,gBAAiB,eAAgB,gBAAgB,CAC9D,WAAY,CAAC,wBAAyB,eAAe,CACtD,CACK,EAA6B,CACjC,QAAS,CAAC,gBAAiB,eAAgB,oBAAoB,CAC/D,SAAU,CAAC,0BAA2B,kBAAmB,sBAAsB,CAChF,CACK,EAA6B,CACjC,SAAU,CAAC,YAAa,eAAgB,aAAa,CACtD,CACK,EAAqB,CACzB,GAAG,EACH,GAAG,EACH,GAAG,EACH,GAAG,EACJ,CAEK,EAA0B,CAC9B,QAAS,eACV,CAEY,EAAqB,OAAO,KAAK,EAAmB,CAE3D,EAAoB,KAAO,IAAwB,CACvD,IAAM,EAAU,EAAmB,GACnC,GAAI,CAAC,EACH,MAAU,MAAM,gBAAgB,EAAY,kBAAkB,CAEhE,GAAM,CAAC,EAAM,EAAQ,GAAW,EAShC,OANE,EAAwB,IACrB,CAAE,MAAM,EAAsB,mDAAmD,EAAY,MAAO,GAAM,EAC7G,QAAQ,IAAI,cAAc,CACnB,QAAQ,KAAK,EAAE,EAGjB,CAAE,OAAM,SAAQ,UAAS,EAGrB,GAAiB,CAAE,cAAa,WAAU,oBAAuH,CAC5K,IAAI,EAAe,EAAG,aAAa,EAAU,OAAO,CACpD,IAAK,GAAM,CAAE,OAAM,aAAa,EAC9B,EAAe,EAAa,QAAQ,EAAM,EAAQ,CAEpD,EAAG,cAAc,EAAa,EAAa,EAG7C,eAAsB,GAAoB,CACxC,GAAI,CACF,GAAM,CAAE,UAAW,MAAMC,EAAW,UAAW,CAAC,SAAU,kBAAkB,CAAE,CAAE,MAAO,GAAO,CAAC,CAC/F,OAAO,EAAO,MAAM,MACd,CACN,OAAO,MAIX,MAAa,EAAmB,KAAO,IAAwB,CAC7D,GAAM,CAAE,OAAM,SAAQ,WAAY,MAAM,EAAkB,EAAY,CAEhE,EAAkB,OAAO,GAAW,EAAK,GAAG,EAAO,GAAG,IAW5D,OAVuB,MAAM,GAAmB,GACzB,GACrB,QAAQ,IAAI,wBAAwB,EAAY,qCAAqC,CAC9E,CAAE,OAAM,SAAQ,UAAS,GAGlC,MAAMA,EAAW,SAAU,CAAC,YAAa,WAAY,kBAAmB,EAAM,WAAY,EAAQ,YAAa,GAAW,EAAK,CAAE,CAAE,MAAO,GAAO,CAAC,CAElJ,QAAQ,IAAI,eAAe,EAAY,eAAe,CAE/C,CAAE,OAAM,SAAQ,UAAS,GAGlC,eAAsB,GAAsB,CAC1C,GAAI,CACF,GAAM,CAAE,UAAW,MAAMA,EAAW,UAAW,CAAC,SAAU,OAAQ,WAAY,WAAY,yBAAyB,CAAE,CAAE,MAAO,GAAO,CAAC,CACtI,OAAO,EAAO,MAAM,MACd,CACN,MAAO,WAIX,MAAa,EAAsB,MAAO,CAAE,cAAa,kBACvD,MAAM,EAAiB,EAAY,CAC5B,eAAe,KAGX,EAAY,GAAgB,CACvC,IAAM,EAAU,EAAI,MAAM;EAAK,CAAC,OAAO,QAAQ,CAC/C,EAAQ,OAAO,CAEf,IAAI,EAAe,EAAQ,IAAK,GAAW,CACzC,GAAM,CAAC,EAAM,EAAO,EAAY,EAAY,EAAO,GAAQ,EAAO,MAAM,QAAQ,CAAC,IAAI,GAAK,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ,CAGnH,MADsB,GADF,EAAK,QAAQ,KAAM,IAAI,CAAC,aAAa,CACpB,gBAAqB,KAE1D,CAEF,MADA,GAAe,EAAa,OAAO,GAAe,CAAC,EAAY,SAAS,OAAO,EAAI,CAAC,EAAY,SAAS,YAAY,CAAC,CAC/G,GAGT,SAAgB,EAAa,EAAuB,EAA0B,CAQ5E,OAPM,aAAiB,QACrB,EAAY,MAAM,EAAM,EAE1B,QAAQ,MAAM,EAAM,CAChB,GACF,QAAQ,IAAI,EAAS,CAEhB,QAAQ,KAAK,EAAE,CAGxB,MAAa,EAAuB,GAAwB,OAAO,KAAK,EAA8B,CAAC,SAAS,EAAY,CAE/G,EAAkB,GAAwB,EAAwB,IAC1E,EAAmB,GAAgD"}
|
|
1
|
+
{"version":3,"file":"utils-u-P48-YN.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 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-autofleet-production', 'us-central1', 'autofleet-production'],\n prodEu: ['eu-prod-autofleet', 'europe-west1', 'autofleetprod'],\n prodJp: ['jp-autofleet-production', '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