@take-out/scripts 0.2.10 → 0.3.0-1775080607310

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@take-out/scripts",
3
- "version": "0.2.10",
3
+ "version": "0.3.0-1775080607310",
4
4
  "type": "module",
5
5
  "main": "./src/cmd.ts",
6
6
  "sideEffects": false,
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@clack/prompts": "^0.8.2",
32
- "@take-out/helpers": "0.2.10",
33
- "@take-out/run": "0.2.10",
32
+ "@take-out/helpers": "0.3.0-1775080607310",
33
+ "@take-out/run": "0.3.0-1775080607310",
34
34
  "picocolors": "^1.1.1"
35
35
  }
36
36
  }
@@ -93,5 +93,5 @@ await cmd`bootstrap project workspace and build initial packages`.run(
93
93
  console.info(`→ Created symlink: ${source} ⇢ ${target}`)
94
94
  }
95
95
  }
96
- }
96
+ },
97
97
  )
package/src/cmd.ts CHANGED
@@ -13,13 +13,13 @@ type CmdContext = {
13
13
  type Args<S extends string> = import('./helpers/args').Args<S>
14
14
 
15
15
  type RunFn<S extends string> = (
16
- fn: (ctx: Prettify<{ args: Args<S> } & CmdContext>) => Promise<void> | void
16
+ fn: (ctx: Prettify<{ args: Args<S> } & CmdContext>) => Promise<void> | void,
17
17
  ) => Promise<void>
18
18
 
19
19
  let _interceptCmd: ((info: { description: string; args?: string }) => void) | undefined
20
20
 
21
21
  export function setInterceptCmd(
22
- fn: ((info: { description: string; args?: string }) => void) | undefined
22
+ fn: ((info: { description: string; args?: string }) => void) | undefined,
23
23
  ) {
24
24
  _interceptCmd = fn
25
25
  }
package/src/dev-tunnel.ts CHANGED
@@ -65,7 +65,7 @@ await cmd`set up cloudflare dev tunnel for local development`
65
65
  const match1 = output.match(/Created tunnel .+ with id ([a-f0-9-]+)/i)
66
66
  const match2 = output.match(/Tunnel ([a-f0-9-]+) created/i)
67
67
  const match3 = output.match(
68
- /([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i
68
+ /([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i,
69
69
  )
70
70
 
71
71
  const tunnelId = match1?.[1] || match2?.[1] || match3?.[1]
@@ -83,7 +83,7 @@ await cmd`set up cloudflare dev tunnel for local development`
83
83
  try {
84
84
  const { stdout } = await run(
85
85
  `cloudflared tunnel list --name ${tunnelName} --output json`,
86
- { captureOutput: true }
86
+ { captureOutput: true },
87
87
  )
88
88
  const tunnels = JSON.parse(stdout)
89
89
  if (tunnels.length > 0) {
@@ -137,7 +137,7 @@ await cmd`set up cloudflare dev tunnel for local development`
137
137
  {
138
138
  captureOutput: true,
139
139
  silent: true,
140
- }
140
+ },
141
141
  )
142
142
 
143
143
  try {
@@ -145,7 +145,7 @@ await cmd`set up cloudflare dev tunnel for local development`
145
145
  const hostname = info.hostname || `${tunnelId}.cfargotunnel.com`
146
146
  fs.writeFileSync(
147
147
  path.join(TUNNEL_CONFIG_DIR, 'tunnel-url.txt'),
148
- `https://${hostname}`
148
+ `https://${hostname}`,
149
149
  )
150
150
  } catch (e) {
151
151
  // use fallback url already saved
package/src/env-pull.ts CHANGED
@@ -12,7 +12,7 @@ await cmd`pull environment variables from SST production`.run(async ({ path }) =
12
12
  const envFilePath = path.join(rootDir, '.env.production')
13
13
  if (fs.existsSync(envFilePath)) {
14
14
  console.error(
15
- '❌ Error: .env.production already exists. Please remove or rename it first.'
15
+ '❌ Error: .env.production already exists. Please remove or rename it first.',
16
16
  )
17
17
  process.exit(1)
18
18
  }
@@ -21,7 +21,7 @@ await cmd`pull environment variables from SST production`.run(async ({ path }) =
21
21
  const envVarsNeeded = packageJson.env ? Object.keys(packageJson.env) : []
22
22
  if (!envVarsNeeded.length) {
23
23
  console.error(
24
- `❌ Error: No environment variables specified in package.json 'env' array.`
24
+ `❌ Error: No environment variables specified in package.json 'env' array.`,
25
25
  )
26
26
  process.exit(1)
27
27
  }
@@ -49,7 +49,7 @@ await cmd`pull environment variables from SST production`.run(async ({ path }) =
49
49
  fs.writeFileSync(envFilePath, envFileContent)
50
50
 
51
51
  console.info(
52
- `✅ Success! ${foundCount} environment variables written to .env.production`
52
+ `✅ Success! ${foundCount} environment variables written to .env.production`,
53
53
  )
54
54
  } catch (error) {
55
55
  console.error('❌ Error fetching environment variables:', error)
package/src/env-update.ts CHANGED
@@ -98,7 +98,7 @@ await cmd`sync environment variables from package.json to matching files`
98
98
  : null
99
99
 
100
100
  const matchRe = new RegExp(
101
- '^' + filePattern.replace(/\./g, '\\.').replace(/\*/g, '[^/]*') + '$'
101
+ '^' + filePattern.replace(/\./g, '\\.').replace(/\*/g, '[^/]*') + '$',
102
102
  )
103
103
 
104
104
  function walk(dir: string) {
@@ -129,7 +129,7 @@ await cmd`sync environment variables from package.json to matching files`
129
129
  const preset = PRESETS[args.preset]
130
130
  if (!preset) {
131
131
  console.error(
132
- `Unknown preset: ${args.preset}\nAvailable: ${Object.keys(PRESETS).join(', ')}`
132
+ `Unknown preset: ${args.preset}\nAvailable: ${Object.keys(PRESETS).join(', ')}`,
133
133
  )
134
134
  process.exit(1)
135
135
  }
@@ -198,11 +198,11 @@ await cmd`sync environment variables from package.json to matching files`
198
198
  content: string,
199
199
  startMarker: string,
200
200
  endMarker: string,
201
- newSection: string
201
+ newSection: string,
202
202
  ): string {
203
203
  const re = new RegExp(
204
204
  `^([ \\t]*)${escapeRegExp(startMarker)}(.|\n)*?${escapeRegExp(endMarker)}`,
205
- 'gm'
205
+ 'gm',
206
206
  )
207
207
  return content.replace(re, (_match, indent) => {
208
208
  return `${indent}${startMarker}\n${newSection}\n${indent}${endMarker}`
@@ -211,7 +211,7 @@ await cmd`sync environment variables from package.json to matching files`
211
211
 
212
212
  function applyYamlMarkers(filePath: string, content: string): string {
213
213
  const markerMatch = content.match(
214
- new RegExp(`^(\\s*)${escapeRegExp(yamlStart)}`, 'm')
214
+ new RegExp(`^(\\s*)${escapeRegExp(yamlStart)}`, 'm'),
215
215
  )
216
216
  const indent = markerMatch?.[1] || ' '
217
217
 
@@ -261,7 +261,7 @@ await cmd`sync environment variables from package.json to matching files`
261
261
  lines.push(`${key}=${dep}`)
262
262
  } else if (typeof value === 'string' && value.startsWith('$dep:')) {
263
263
  console.warn(
264
- `could not resolve dependency version for ${value.slice('$dep:'.length)}`
264
+ `could not resolve dependency version for ${value.slice('$dep:'.length)}`,
265
265
  )
266
266
  } else if (typeof value === 'string' && value !== '') {
267
267
  lines.push(`${key}=${value}`)
@@ -6,7 +6,7 @@ import { cmd } from './cmd'
6
6
 
7
7
  export async function execWithEnvironment(
8
8
  environment: 'development' | 'production',
9
- command: string
9
+ command: string,
10
10
  ) {
11
11
  const { spawnSync } = await import('node:child_process')
12
12
  const { loadEnv } = await import('./helpers/env-load')
@@ -25,7 +25,7 @@ export async function execWithEnvironment(
25
25
  }
26
26
 
27
27
  console.info(
28
- `($): ${command} | env ${environment} ${USE_LOCAL_SERVER ? '| using local endpoints' : ''}`
28
+ `($): ${command} | env ${environment} ${USE_LOCAL_SERVER ? '| using local endpoints' : ''}`,
29
29
  )
30
30
 
31
31
  const devEnv = USE_LOCAL_SERVER ? await loadEnv('development') : null
@@ -53,9 +53,9 @@ if (import.meta.main) {
53
53
  async () => {
54
54
  const result = await execWithEnvironment(
55
55
  (process.env.NODE_ENV as 'development' | 'production') || 'development',
56
- process.argv.slice(3).join(' ')
56
+ process.argv.slice(3).join(' '),
57
57
  )
58
58
  process.exit(result.status ?? 1)
59
- }
59
+ },
60
60
  )
61
61
  }
@@ -28,7 +28,7 @@ export interface ContainerInfo {
28
28
  */
29
29
  export async function checkRestartLoops(
30
30
  ctx: SSHContext,
31
- options?: { excludePatterns?: string[] }
31
+ options?: { excludePatterns?: string[] },
32
32
  ): Promise<{
33
33
  hasLoop: boolean
34
34
  services: string[]
@@ -67,7 +67,7 @@ export async function checkRestartLoops(
67
67
  */
68
68
  export async function getContainerStatus(
69
69
  ctx: SSHContext,
70
- options?: { verbose?: boolean }
70
+ options?: { verbose?: boolean },
71
71
  ): Promise<Map<string, ContainerInfo>> {
72
72
  const { sshOpts, deployUser, deployHost, $ } = ctx
73
73
  try {
@@ -135,7 +135,7 @@ export async function getContainerStatus(
135
135
  */
136
136
  export async function checkContainerHealth(
137
137
  ctx: SSHContext,
138
- containerId: string
138
+ containerId: string,
139
139
  ): Promise<'healthy' | 'checking' | 'unhealthy'> {
140
140
  const { sshOpts, deployUser, deployHost, $ } = ctx
141
141
  try {
@@ -168,7 +168,7 @@ export async function checkContainerHealth(
168
168
  */
169
169
  export async function checkHttpHealth(
170
170
  ctx: SSHContext,
171
- options?: { endpoint?: string; containerFilter?: string }
171
+ options?: { endpoint?: string; containerFilter?: string },
172
172
  ): Promise<{
173
173
  healthy: boolean
174
174
  status?: number
@@ -213,7 +213,7 @@ export async function checkHttpHealth(
213
213
  export async function getContainerLogs(
214
214
  ctx: SSHContext,
215
215
  containerId: string,
216
- lines = 20
216
+ lines = 20,
217
217
  ): Promise<string[]> {
218
218
  const { sshOpts, deployUser, deployHost, $ } = ctx
219
219
  try {
@@ -17,7 +17,7 @@ interface DeployLockOptions {
17
17
 
18
18
  export async function acquireDeployLock(
19
19
  ssh: string,
20
- opts?: DeployLockOptions
20
+ opts?: DeployLockOptions,
21
21
  ): Promise<void> {
22
22
  const lockPath = opts?.path || DEFAULT_LOCK_PATH
23
23
  const maxAge = opts?.maxAgeMin || DEFAULT_MAX_AGE_MIN
@@ -40,14 +40,14 @@ export async function acquireDeployLock(
40
40
  throw new Error(
41
41
  `another deploy is in progress (${lockPath} exists on server). ` +
42
42
  `if stale, it will auto-expire after ${maxAge} minutes, ` +
43
- `or remove manually: ${ssh} "rm -rf ${lockPath}"`
43
+ `or remove manually: ${ssh} "rm -rf ${lockPath}"`,
44
44
  )
45
45
  }
46
46
  }
47
47
 
48
48
  export async function releaseDeployLock(
49
49
  ssh: string,
50
- opts?: DeployLockOptions
50
+ opts?: DeployLockOptions,
51
51
  ): Promise<void> {
52
52
  const lockPath = opts?.path || DEFAULT_LOCK_PATH
53
53
  try {
@@ -11,7 +11,7 @@ export async function ensureS3Bucket(
11
11
  options?: {
12
12
  region?: string
13
13
  retentionDays?: number
14
- }
14
+ },
15
15
  ): Promise<void> {
16
16
  const region = options?.region ?? 'us-west-1'
17
17
  const retentionDays = options?.retentionDays ?? 30
@@ -41,7 +41,7 @@ export async function ensureS3Bucket(
41
41
  LocationConstraint: region as any,
42
42
  },
43
43
  }),
44
- })
44
+ }),
45
45
  )
46
46
 
47
47
  // enable versioning for safety
@@ -51,7 +51,7 @@ export async function ensureS3Bucket(
51
51
  VersioningConfiguration: {
52
52
  Status: 'Enabled',
53
53
  },
54
- })
54
+ }),
55
55
  )
56
56
 
57
57
  // set lifecycle policy to automatically delete old backups
@@ -75,11 +75,11 @@ export async function ensureS3Bucket(
75
75
  },
76
76
  ],
77
77
  },
78
- })
78
+ }),
79
79
  )
80
80
 
81
81
  console.info(
82
- `✅ S3 bucket created with ${retentionDays} day retention: ${bucketName}`
82
+ `✅ S3 bucket created with ${retentionDays} day retention: ${bucketName}`,
83
83
  )
84
84
  } else {
85
85
  throw error
@@ -3,7 +3,7 @@ import { join } from 'node:path'
3
3
 
4
4
  export async function loadEnv(
5
5
  environment: 'development' | 'production' | 'dev-prod',
6
- options?: { optional?: string[]; envPath?: string }
6
+ options?: { optional?: string[]; envPath?: string },
7
7
  ) {
8
8
  const { loadEnv: vxrnLoadEnv } = await import('vxrn/loadEnv')
9
9
 
@@ -15,7 +15,7 @@ export function getDockerHost(): string {
15
15
  // Get the host IP from docker network
16
16
  const result = execSync(
17
17
  "docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'",
18
- { encoding: 'utf-8' }
18
+ { encoding: 'utf-8' },
19
19
  ).trim()
20
20
 
21
21
  if (result) {
@@ -23,7 +23,7 @@ function getFailedStepLogs(jobId: string, stepName: string): string {
23
23
  encoding: 'utf-8',
24
24
  shell: '/bin/bash',
25
25
  maxBuffer: 10 * 1024 * 1024,
26
- }
26
+ },
27
27
  )
28
28
  return logs
29
29
  } catch {
@@ -43,7 +43,7 @@ async function watchJob(
43
43
  runId: string,
44
44
  jobId: string,
45
45
  jobName: string,
46
- showOnlyFailed: boolean
46
+ showOnlyFailed: boolean,
47
47
  ) {
48
48
  try {
49
49
  const jobsJson = execSync(`gh run view ${runId} --json jobs`, {
@@ -114,7 +114,7 @@ async function watchJob(
114
114
  job.steps?.filter((s: any) => s.conclusion === 'failure') || []
115
115
  if (failedSteps.length > 0) {
116
116
  console.info(
117
- `Failed steps: ${failedSteps.map((s: any) => s.name).join(', ')}\n`
117
+ `Failed steps: ${failedSteps.map((s: any) => s.name).join(', ')}\n`,
118
118
  )
119
119
 
120
120
  for (const step of failedSteps) {
@@ -161,7 +161,7 @@ export async function githubTail(options: GithubTailOptions = {}) {
161
161
 
162
162
  let runsJson = execSync(
163
163
  `gh run list --commit ${latestCommit} --json databaseId,name,status,conclusion --limit 5`,
164
- { encoding: 'utf-8' }
164
+ { encoding: 'utf-8' },
165
165
  )
166
166
  let runs = JSON.parse(runsJson)
167
167
  let ciRun = runs.find((r: any) => r.name === workflowName)
@@ -176,7 +176,7 @@ export async function githubTail(options: GithubTailOptions = {}) {
176
176
 
177
177
  runsJson = execSync(
178
178
  `gh run list --commit ${latestCommit} --json databaseId,name,status,conclusion --limit 5`,
179
- { encoding: 'utf-8' }
179
+ { encoding: 'utf-8' },
180
180
  )
181
181
  runs = JSON.parse(runsJson)
182
182
  ciRun = runs.find((r: any) => r.name === workflowName)
@@ -185,7 +185,7 @@ export async function githubTail(options: GithubTailOptions = {}) {
185
185
  console.info('No CI run for remote HEAD, getting latest CI run...')
186
186
  runsJson = execSync(
187
187
  `gh run list --workflow=${workflowName} --json databaseId,name,status,conclusion,headSha --limit 1`,
188
- { encoding: 'utf-8' }
188
+ { encoding: 'utf-8' },
189
189
  )
190
190
  runs = JSON.parse(runsJson)
191
191
  ciRun = runs[0]
@@ -216,7 +216,7 @@ export async function githubTail(options: GithubTailOptions = {}) {
216
216
  }
217
217
 
218
218
  console.info(
219
- `\nJob: ${buildJob.name} - ${buildJob.status} (${buildJob.conclusion || 'in progress'})`
219
+ `\nJob: ${buildJob.name} - ${buildJob.status} (${buildJob.conclusion || 'in progress'})`,
220
220
  )
221
221
  console.info('─'.repeat(80))
222
222
 
@@ -11,7 +11,7 @@ export interface MultipassConfig {
11
11
 
12
12
  export function createMultipassConfig(
13
13
  name: string,
14
- sshKeyPath?: string
14
+ sshKeyPath?: string,
15
15
  ): MultipassConfig {
16
16
  return {
17
17
  vmName: name,
@@ -70,7 +70,7 @@ packages:
70
70
 
71
71
  try {
72
72
  await run(
73
- `multipass launch --name ${config.vmName} --cpus 4 --memory 4G --disk 20G --cloud-init ${cloudInitPath}`
73
+ `multipass launch --name ${config.vmName} --cpus 4 --memory 4G --disk 20G --cloud-init ${cloudInitPath}`,
74
74
  )
75
75
  } finally {
76
76
  await run(`rm -f ${cloudInitPath}`, { silent: true })
@@ -127,14 +127,14 @@ export async function setupVMSSH(config: MultipassConfig): Promise<void> {
127
127
  captureOutput: true,
128
128
  })
129
129
  await run(
130
- `multipass exec ${config.vmName} -- sh -c 'mkdir -p ~/.ssh && echo "${pubKey.trim()}" >> ~/.ssh/authorized_keys'`
130
+ `multipass exec ${config.vmName} -- sh -c 'mkdir -p ~/.ssh && echo "${pubKey.trim()}" >> ~/.ssh/authorized_keys'`,
131
131
  )
132
132
  console.info('✅ ssh key configured')
133
133
  }
134
134
 
135
135
  export async function setupPortForward(
136
136
  config: MultipassConfig,
137
- ports: { local: number; containerName: string; containerPort: number }[]
137
+ ports: { local: number; containerName: string; containerPort: number }[],
138
138
  ): Promise<void> {
139
139
  console.info('\n🌐 setting up port forwarding...\n')
140
140
 
@@ -148,7 +148,7 @@ export async function setupPortForward(
148
148
  for (const { local, containerName, containerPort } of ports) {
149
149
  const { stdout: containerIP } = await run(
150
150
  `multipass exec ${config.vmName} -- sudo docker inspect $(multipass exec ${config.vmName} -- sudo docker ps -q -f name=${containerName}) -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'`,
151
- { silent: true, captureOutput: true }
151
+ { silent: true, captureOutput: true },
152
152
  )
153
153
  console.info(`${containerName} container: ${containerIP.trim()}:${containerPort}`)
154
154
  forwards.push(`-L ${local}:${containerIP.trim()}:${containerPort}`)
@@ -167,7 +167,7 @@ export async function setupPortForward(
167
167
 
168
168
  await run(
169
169
  `ssh -i ${config.sshKeyPath} -o StrictHostKeyChecking=no -f -N ${forwards.join(' ')} ubuntu@${ip}`,
170
- { silent: true }
170
+ { silent: true },
171
171
  )
172
172
 
173
173
  console.info('✅ port forwarding active')
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export function parseEnvFile(
5
5
  content: string,
6
- options?: { allowedKeys?: string[] }
6
+ options?: { allowedKeys?: string[] },
7
7
  ): Record<string, string> {
8
8
  const result: Record<string, string> = {}
9
9
  const lines = content.split('\n')
@@ -28,7 +28,7 @@ function yamlSafe(value: string): string {
28
28
  export function processComposeEnv(
29
29
  composeFile: string,
30
30
  outputFile: string,
31
- envVars: Record<string, string | undefined>
31
+ envVars: Record<string, string | undefined>,
32
32
  ): void {
33
33
  let content = fs.readFileSync(composeFile, 'utf-8')
34
34
 
@@ -39,11 +39,11 @@ export function processComposeEnv(
39
39
  const value = envVars[varName]
40
40
  if (value) {
41
41
  console.info(
42
- ` ${varName}: ${value.slice(0, 50)}${value.length > 50 ? '...' : ''}`
42
+ ` ${varName}: ${value.slice(0, 50)}${value.length > 50 ? '...' : ''}`,
43
43
  )
44
44
  }
45
45
  return value ? yamlSafe(value) : defaultValue
46
- }
46
+ },
47
47
  )
48
48
 
49
49
  // replace standalone ${VAR} patterns
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export function resolveDepVersion(
5
5
  value: string | boolean,
6
- dependencies: Record<string, string> | undefined
6
+ dependencies: Record<string, string> | undefined,
7
7
  ): string | undefined {
8
8
  if (typeof value !== 'string' || !value.startsWith('$dep:')) return undefined
9
9
  const depName = value.slice('$dep:'.length)
@@ -35,7 +35,7 @@ const running: Record<string, Promise<unknown> | undefined | null> = {}
35
35
  export async function runInline(name: string, cb: () => Promise<void>) {
36
36
  const promise = cb()
37
37
  running[name] = promise
38
- return await promise
38
+ return promise
39
39
  }
40
40
 
41
41
  export async function run(
@@ -49,7 +49,7 @@ export async function run(
49
49
  detached?: boolean
50
50
  timeout?: number
51
51
  timing?: boolean | string
52
- }
52
+ },
53
53
  ) {
54
54
  const { env, cwd, silent, captureOutput, prefix, detached, timeout, timing } =
55
55
  options || {}
@@ -63,7 +63,7 @@ export async function run(
63
63
  const result = await promise
64
64
  const duration = Date.now() - startTime
65
65
  console.info(
66
- `\x1b[32m✓\x1b[0m \x1b[35m${name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`
66
+ `\x1b[32m✓\x1b[0m \x1b[35m${name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`,
67
67
  )
68
68
  return result
69
69
  } catch (error) {
@@ -124,7 +124,7 @@ export async function run(
124
124
 
125
125
  const processStream = (
126
126
  stream: NodeJS.ReadableStream | null,
127
- isStderr: boolean
127
+ isStderr: boolean,
128
128
  ): Promise<string> => {
129
129
  return new Promise((resolve) => {
130
130
  if (effectiveSilent && !captureOutput) {
@@ -253,7 +253,7 @@ export async function printTiming<T>(name: string, fn: () => Promise<T>): Promis
253
253
  const result = await fn()
254
254
  const duration = Date.now() - startTime
255
255
  console.info(
256
- `\x1b[32m✓\x1b[0m \x1b[35m${name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`
256
+ `\x1b[32m✓\x1b[0m \x1b[35m${name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`,
257
257
  )
258
258
  return result
259
259
  } catch (error) {
@@ -265,7 +265,7 @@ export async function printTiming<T>(name: string, fn: () => Promise<T>): Promis
265
265
 
266
266
  export async function runParallel(
267
267
  tasks: Array<{ name: string; fn: () => Promise<void>; condition?: () => boolean }>,
268
- options?: { maxParallelism?: number }
268
+ options?: { maxParallelism?: number },
269
269
  ) {
270
270
  const activeTasks = tasks.filter((task) => !task.condition || task.condition())
271
271
 
@@ -289,16 +289,16 @@ export async function runParallel(
289
289
  () => {
290
290
  const duration = Date.now() - startTime
291
291
  console.info(
292
- `\x1b[32m✓\x1b[0m task: \x1b[35m${task.name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`
292
+ `\x1b[32m✓\x1b[0m task: \x1b[35m${task.name}\x1b[0m completed in \x1b[33m${formatDuration(duration)}\x1b[0m`,
293
293
  )
294
294
  executing.delete(taskPromise)
295
295
  },
296
- (error) => {
296
+ (error: unknown) => {
297
297
  const duration = Date.now() - startTime
298
298
  console.error(`✗ task: ${task.name} failed after ${formatDuration(duration)}`)
299
299
  executing.delete(taskPromise)
300
300
  throw error
301
- }
301
+ },
302
302
  )
303
303
 
304
304
  results.push(taskPromise)
@@ -313,7 +313,7 @@ export async function runParallel(
313
313
 
314
314
  const totalDuration = Date.now() - taskStartTime
315
315
  console.info(
316
- `\nAll parallel tasks completed successfully in ${formatDuration(totalDuration)}`
316
+ `\nAll parallel tasks completed successfully in ${formatDuration(totalDuration)}`,
317
317
  )
318
318
  } catch (error) {
319
319
  const totalDuration = Date.now() - taskStartTime
@@ -16,7 +16,7 @@ async function sleep(ms: number) {
16
16
  export async function testSSHConnection(
17
17
  host: string,
18
18
  sshKey: string,
19
- options?: { retries?: number; retryDelayMs?: number }
19
+ options?: { retries?: number; retryDelayMs?: number },
20
20
  ): Promise<void> {
21
21
  const maxRetries = options?.retries ?? 3
22
22
  const retryDelay = options?.retryDelayMs ?? 5000
@@ -29,7 +29,7 @@ export async function testSSHConnection(
29
29
  try {
30
30
  await run(
31
31
  `ssh -i ${sshKey} -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${host} "echo 'SSH connection successful'"`,
32
- { silent: attempt > 1 }
32
+ { silent: attempt > 1 },
33
33
  )
34
34
  console.info('✅ ssh connection verified')
35
35
  return
@@ -37,7 +37,7 @@ export async function testSSHConnection(
37
37
  lastError = err as Error
38
38
  if (attempt < maxRetries) {
39
39
  console.info(
40
- ` ssh attempt ${attempt}/${maxRetries} failed, retrying in ${retryDelay / 1000}s...`
40
+ ` ssh attempt ${attempt}/${maxRetries} failed, retrying in ${retryDelay / 1000}s...`,
41
41
  )
42
42
  await sleep(retryDelay)
43
43
  }
@@ -45,6 +45,6 @@ export async function testSSHConnection(
45
45
  }
46
46
 
47
47
  throw new Error(
48
- `cannot connect to ${host} after ${maxRetries} attempts - check ssh key: ${sshKey}`
48
+ `cannot connect to ${host} after ${maxRetries} attempts - check ssh key: ${sshKey}`,
49
49
  )
50
50
  }
@@ -52,17 +52,17 @@ export async function verifyDatabaseConfig(): Promise<{
52
52
 
53
53
  if (deployHost && upstreamHost && deployHost !== upstreamHost) {
54
54
  errors.push(
55
- `ZERO_UPSTREAM_DB host (${upstreamHost}) does not match DEPLOY_DB host (${deployHost})`
55
+ `ZERO_UPSTREAM_DB host (${upstreamHost}) does not match DEPLOY_DB host (${deployHost})`,
56
56
  )
57
57
  }
58
58
  if (deployHost && cvrHost && deployHost !== cvrHost) {
59
59
  errors.push(
60
- `ZERO_CVR_DB host (${cvrHost}) does not match DEPLOY_DB host (${deployHost})`
60
+ `ZERO_CVR_DB host (${cvrHost}) does not match DEPLOY_DB host (${deployHost})`,
61
61
  )
62
62
  }
63
63
  if (deployHost && changeHost && deployHost !== changeHost) {
64
64
  errors.push(
65
- `ZERO_CHANGE_DB host (${changeHost}) does not match DEPLOY_DB host (${deployHost})`
65
+ `ZERO_CHANGE_DB host (${changeHost}) does not match DEPLOY_DB host (${deployHost})`,
66
66
  )
67
67
  }
68
68
 
@@ -78,7 +78,7 @@ export async function installUncloudCLI(version = '0.16.0') {
78
78
  console.info(` installing uncloud cli v${version}...`)
79
79
  await run(
80
80
  `curl -fsS https://get.uncloud.run/install.sh | sh -s -- --version ${version}`,
81
- { timeout: time.ms.seconds(30) }
81
+ { timeout: time.ms.seconds(30) },
82
82
  )
83
83
  console.info(' ✓ uncloud cli installed')
84
84
  }
@@ -18,7 +18,7 @@ export async function checkUncloudCLI(): Promise<void> {
18
18
  console.info(`✅ uncloud cli installed (${stdout.trim()})`)
19
19
  } catch {
20
20
  throw new Error(
21
- `uncloud cli not found - install: curl -fsS https://get.uncloud.run/install.sh | sh`
21
+ `uncloud cli not found - install: curl -fsS https://get.uncloud.run/install.sh | sh`,
22
22
  )
23
23
  }
24
24
  }
@@ -61,7 +61,7 @@ contexts:
61
61
  export async function initUncloud(
62
62
  host: string,
63
63
  sshKey: string,
64
- options: { noDNS?: boolean; noCaddy?: boolean; context?: string } = {}
64
+ options: { noDNS?: boolean; noCaddy?: boolean; context?: string } = {},
65
65
  ): Promise<void> {
66
66
  console.info('\n🚀 initializing uncloud...\n')
67
67
 
@@ -116,7 +116,7 @@ export async function initUncloud(
116
116
 
117
117
  export async function pushImage(
118
118
  imageName: string,
119
- config?: UncloudConfig
119
+ config?: UncloudConfig,
120
120
  ): Promise<void> {
121
121
  console.info('\n📤 pushing image to cluster...\n')
122
122
 
@@ -126,7 +126,7 @@ export async function pushImage(
126
126
 
127
127
  export async function deployStack(
128
128
  composeFile: string,
129
- options?: { profile?: string } & UncloudConfig
129
+ options?: { profile?: string } & UncloudConfig,
130
130
  ): Promise<void> {
131
131
  console.info('\n📦 deploying stack...\n')
132
132
 
@@ -159,7 +159,7 @@ export async function showContainers(config?: UncloudConfig): Promise<void> {
159
159
 
160
160
  export async function startService(
161
161
  service?: string,
162
- config?: UncloudConfig
162
+ config?: UncloudConfig,
163
163
  ): Promise<void> {
164
164
  const target = service || 'all services'
165
165
  console.info(`\n▶️ starting ${target}...\n`)
@@ -174,7 +174,7 @@ export async function startService(
174
174
 
175
175
  export async function stopService(
176
176
  service?: string,
177
- config?: UncloudConfig
177
+ config?: UncloudConfig,
178
178
  ): Promise<void> {
179
179
  const target = service || 'all services'
180
180
  console.info(`\n⏹️ stopping ${target}...\n`)
@@ -9,7 +9,7 @@ interface WaitForPortOptions {
9
9
 
10
10
  export async function waitForPort(
11
11
  port: number,
12
- options: WaitForPortOptions = {}
12
+ options: WaitForPortOptions = {},
13
13
  ): Promise<void> {
14
14
  const {
15
15
  host = '127.0.0.1',
@@ -15,7 +15,7 @@ async function getRequiredNodeVersion() {
15
15
  try {
16
16
  const nodeVersionContent = await fs.promises.readFile(
17
17
  path.join(process.cwd(), '.node-version'),
18
- 'utf-8'
18
+ 'utf-8',
19
19
  )
20
20
  return `v${nodeVersionContent.trim()}`
21
21
  } catch {}
@@ -23,7 +23,7 @@ async function getRequiredNodeVersion() {
23
23
  // fallback to package.json engines.node
24
24
  try {
25
25
  const packageJson = JSON.parse(
26
- await fs.promises.readFile(path.join(process.cwd(), 'package.json'), 'utf-8')
26
+ await fs.promises.readFile(path.join(process.cwd(), 'package.json'), 'utf-8'),
27
27
  )
28
28
  return packageJson?.engines?.node ? `v${packageJson.engines.node}` : null
29
29
  } catch {
@@ -38,7 +38,7 @@ export async function checkNodeVersion() {
38
38
  if (requiredNodeVersion) {
39
39
  if (currentNodeVersion !== requiredNodeVersion) {
40
40
  throw new Error(
41
- `\u001b[33mWarning: Incorrect Node.js version. Expected ${requiredNodeVersion} but got ${currentNodeVersion}\u001b[0m`
41
+ `\u001b[33mWarning: Incorrect Node.js version. Expected ${requiredNodeVersion} but got ${currentNodeVersion}\u001b[0m`,
42
42
  )
43
43
  }
44
44
  }
@@ -46,8 +46,8 @@ export async function checkNodeVersion() {
46
46
 
47
47
  if (import.meta.main) {
48
48
  await cmd`verify node version matches project requirements`.run(async () => {
49
- checkNodeVersion().catch((e: any) => {
50
- console.error(e.message)
49
+ checkNodeVersion().catch((e: unknown) => {
50
+ console.error((e as Error).message)
51
51
  process.exit(1)
52
52
  })
53
53
  })
package/src/release.ts CHANGED
@@ -13,7 +13,7 @@ await cmd`publish takeout packages to npm`
13
13
  --rerun boolean --republish boolean --finish boolean --skip-finish boolean
14
14
  --dry-run boolean --skip-test boolean --skip-build boolean --skip-version boolean
15
15
  --dirty boolean --tamagui-git-user boolean --sync-on-zero boolean --skip-on-zero-sync boolean
16
- --undocumented boolean --skip-all boolean`
16
+ --undocumented boolean --skip-all boolean`,
17
17
  )
18
18
  .run(async ({ args, $, run, path, os }) => {
19
19
  const fs = (await import('fs-extra')).default
@@ -102,11 +102,11 @@ await cmd`publish takeout packages to npm`
102
102
  })
103
103
  await fs.copy(
104
104
  path.join(onZeroTakeout, 'cli.cjs'),
105
- path.join(onZeroGithub, 'cli.cjs')
105
+ path.join(onZeroGithub, 'cli.cjs'),
106
106
  )
107
107
  await fs.copy(
108
108
  path.join(onZeroTakeout, 'tsconfig.json'),
109
- path.join(onZeroGithub, 'tsconfig.json')
109
+ path.join(onZeroGithub, 'tsconfig.json'),
110
110
  )
111
111
 
112
112
  // update package.json preserving github-specific fields
@@ -117,7 +117,7 @@ await cmd`publish takeout packages to npm`
117
117
  Object.entries(deps || {}).map(([k, v]) => [
118
118
  k,
119
119
  v.startsWith('workspace:') ? `^${version}` : v,
120
- ])
120
+ ]),
121
121
  )
122
122
  await fs.writeJSON(
123
123
  path.join(onZeroGithub, 'package.json'),
@@ -130,7 +130,7 @@ await cmd`publish takeout packages to npm`
130
130
  dependencies: convertDeps(takeoutPkg.dependencies),
131
131
  devDependencies: convertDeps(takeoutPkg.devDependencies),
132
132
  },
133
- { spaces: 2 }
133
+ { spaces: 2 },
134
134
  )
135
135
 
136
136
  // only commit if there are actual changes
@@ -213,11 +213,11 @@ await cmd`publish takeout packages to npm`
213
213
  path: path.join(cwd, 'package.json'),
214
214
  directory: location,
215
215
  }
216
- })
216
+ }),
217
217
  )
218
218
 
219
219
  const publishablePackages = allPackageJsons.filter(
220
- (x) => !x.json.skipPublish && !x.json.private
220
+ (x) => !x.json.skipPublish && !x.json.private,
221
221
  )
222
222
 
223
223
  return { allPackageJsons, publishablePackages }
@@ -300,7 +300,7 @@ await cmd`publish takeout packages to npm`
300
300
 
301
301
  if (!finish) {
302
302
  console.info(
303
- `Publishing in order:\n\n${packageJsons.map((x) => x.name).join('\n')}`
303
+ `Publishing in order:\n\n${packageJsons.map((x) => x.name).join('\n')}`,
304
304
  )
305
305
  }
306
306
 
@@ -314,7 +314,7 @@ await cmd`publish takeout packages to npm`
314
314
  process.exit(1)
315
315
  }
316
316
  }
317
- })
317
+ }),
318
318
  )
319
319
  }
320
320
 
@@ -397,7 +397,7 @@ await cmd`publish takeout packages to npm`
397
397
  }
398
398
 
399
399
  await writeJSON(pkgPath, next, { spaces: 2 })
400
- })
400
+ }),
401
401
  )
402
402
  }
403
403
 
@@ -425,7 +425,7 @@ await cmd`publish takeout packages to npm`
425
425
  {
426
426
  cwd,
427
427
  silent: true,
428
- }
428
+ },
429
429
  )
430
430
  } else {
431
431
  await run(`bun pm pack --filename ${tgzPath}`, {
@@ -444,7 +444,7 @@ await cmd`publish takeout packages to npm`
444
444
  },
445
445
  {
446
446
  concurrency: 15,
447
- }
447
+ },
448
448
  )
449
449
 
450
450
  console.info(`✅ ${dryRun ? '[dry-run] ' : ''}Published\n`)
@@ -463,7 +463,7 @@ await cmd`publish takeout packages to npm`
463
463
  }
464
464
  }
465
465
  await writeJSON(pkgPath, current, { spaces: 2 })
466
- })
466
+ }),
467
467
  )
468
468
  }
469
469
 
@@ -18,7 +18,7 @@ export function getEnvironment(resourceName: string) {
18
18
  const state = JSON.parse(result.stdout || '{}')
19
19
 
20
20
  const resource = state.latest.resources.find(
21
- (x: any) => x.outputs?._dev?.title === resourceName
21
+ (x: any) => x.outputs?._dev?.title === resourceName,
22
22
  )
23
23
 
24
24
  if (!resource) {
package/src/up.ts CHANGED
@@ -19,7 +19,7 @@ await cmd`upgrade packages by name or pattern`
19
19
  const packagePatterns: string[] = []
20
20
  const rootDir = process.cwd()
21
21
  const rootPackageJson = JSON.parse(
22
- fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8')
22
+ fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'),
23
23
  )
24
24
  const upgradeSets: Record<string, string[]> = rootPackageJson.upgradeSets || {}
25
25
 
@@ -58,7 +58,7 @@ await cmd`upgrade packages by name or pattern`
58
58
  // check if it's a monorepo with workspaces
59
59
  try {
60
60
  const packageJson = JSON.parse(
61
- fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')
61
+ fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'),
62
62
  )
63
63
  if (packageJson.workspaces) {
64
64
  let workspacePaths: string[] = []
@@ -172,7 +172,7 @@ await cmd`upgrade packages by name or pattern`
172
172
  function updatePackageJsonVersions(
173
173
  packageJsonPath: string,
174
174
  packagesToUpdate: string[],
175
- versionMap: Map<string, string>
175
+ versionMap: Map<string, string>,
176
176
  ): number {
177
177
  const content = fs.readFileSync(packageJsonPath, 'utf-8')
178
178
  const packageJson = JSON.parse(content) as PackageJson
@@ -221,7 +221,7 @@ await cmd`upgrade packages by name or pattern`
221
221
  async function updatePackages(
222
222
  packagesByWorkspace: Map<string, { dir: string; packages: string[] }>,
223
223
  rootDir: string,
224
- packageJsonFiles: string[]
224
+ packageJsonFiles: string[],
225
225
  ) {
226
226
  try {
227
227
  fs.rmSync(`node_modules/vite`, {
@@ -259,7 +259,7 @@ await cmd`upgrade packages by name or pattern`
259
259
  console.info(` ⊘ ${pkg} not found, skipping`)
260
260
  }
261
261
  }
262
- })
262
+ }),
263
263
  )
264
264
 
265
265
  if (versionMap.size === 0) {
@@ -280,7 +280,7 @@ await cmd`upgrade packages by name or pattern`
280
280
  const updates = updatePackageJsonVersions(
281
281
  packageJsonPath,
282
282
  packagesInWorkspace,
283
- versionMap
283
+ versionMap,
284
284
  )
285
285
  if (updates > 0) {
286
286
  const name = getWorkspaceName(packageJsonPath, rootDir)
@@ -312,7 +312,7 @@ await cmd`upgrade packages by name or pattern`
312
312
  } catch (retryError: any) {
313
313
  const retryStderr = retryError.stderr?.toString() || retryError.message || ''
314
314
  console.error(
315
- `🚨 'bun install' failed after cache clear: ${retryStderr.split('\n')[0]}`
315
+ `🚨 'bun install' failed after cache clear: ${retryStderr.split('\n')[0]}`,
316
316
  )
317
317
  }
318
318
  } else {
@@ -347,7 +347,7 @@ await cmd`upgrade packages by name or pattern`
347
347
  }
348
348
 
349
349
  console.info(
350
- `Found ${workspacePackageNames.size} workspace packages to exclude from updates`
350
+ `Found ${workspacePackageNames.size} workspace packages to exclude from updates`,
351
351
  )
352
352
 
353
353
  // build map of packages to update per workspace
@@ -383,7 +383,7 @@ await cmd`upgrade packages by name or pattern`
383
383
  const exactPatterns = packagePatterns.filter((p) => !p.includes('*'))
384
384
  if (exactPatterns.length === 0) {
385
385
  console.info(
386
- `Found 0 dependencies matching patterns: ${packagePatterns.join(', ')}`
386
+ `Found 0 dependencies matching patterns: ${packagePatterns.join(', ')}`,
387
387
  )
388
388
  console.info('No matching packages found to update.')
389
389
  return
@@ -415,7 +415,7 @@ await cmd`upgrade packages by name or pattern`
415
415
  fs.writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2) + '\n')
416
416
  } else {
417
417
  console.info(
418
- `Found ${allMatchingDeps.size} dependencies matching patterns: ${packagePatterns.join(', ')}`
418
+ `Found ${allMatchingDeps.size} dependencies matching patterns: ${packagePatterns.join(', ')}`,
419
419
  )
420
420
  console.info(`Found matches in ${packagesByWorkspace.size} workspace(s)`)
421
421
  }
@@ -429,7 +429,7 @@ await cmd`upgrade packages by name or pattern`
429
429
  // sync resolved $dep: values (like ZERO_VERSION) to all env targets
430
430
  if (
431
431
  Object.values(rootPackageJson.env || {}).some(
432
- (v: any) => typeof v === 'string' && v.startsWith('$dep:')
432
+ (v: any) => typeof v === 'string' && v.startsWith('$dep:'),
433
433
  )
434
434
  ) {
435
435
  console.info('\n🔄 Syncing env variables...')
@@ -33,7 +33,7 @@ await cmd`wait for dev server to be available`.run(async () => {
33
33
  }
34
34
 
35
35
  process.stdout.write(
36
- `Waiting to start dev watch until after dev server (wait ${CHECK_INTERVAL / 1000}s)...\n`
36
+ `Waiting to start dev watch until after dev server (wait ${CHECK_INTERVAL / 1000}s)...\n`,
37
37
  )
38
38
  }
39
39