@take-out/scripts 0.0.64 → 0.0.66

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.0.64",
3
+ "version": "0.0.66",
4
4
  "type": "module",
5
5
  "main": "./src/run.ts",
6
6
  "sideEffects": false,
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- const netstat = Bun.spawnSync(`netstat -rn`.split(' ')).stdout
3
+ import { spawnSync } from 'node:child_process'
4
+
5
+ const netstat = spawnSync('netstat', ['-rn'], { encoding: 'utf-8' }).stdout || ''
4
6
  const isTunnelActive = netstat.includes(`10.0.8/22`)
5
7
 
6
8
  if (!isTunnelActive) {
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import { spawnSync } from 'node:child_process'
4
+
3
5
  import { ensureExists } from '@take-out/helpers'
4
6
  import { loadEnv } from '@take-out/scripts/helpers/env-load'
5
7
 
@@ -40,10 +42,9 @@ export async function execWithEnvironment(
40
42
  }),
41
43
  } as any as Record<string, string>
42
44
 
43
- return Bun.spawnSync(command.split(' '), {
44
- stdin: 'ignore',
45
- stdout: 'inherit',
46
- stderr: 'inherit',
45
+ const parts = command.split(' ')
46
+ return spawnSync(parts[0]!, parts.slice(1), {
47
+ stdio: ['ignore', 'inherit', 'inherit'],
47
48
  env,
48
49
  })
49
50
  }
@@ -53,5 +54,5 @@ if (import.meta.main) {
53
54
  (process.env.NODE_ENV as 'development' | 'production') || 'development',
54
55
  process.argv.slice(3).join(' ')
55
56
  )
56
- process.exit(result.exitCode)
57
+ process.exit(result.status ?? 1)
57
58
  }
@@ -1,60 +1,22 @@
1
- import { readFileSync } from 'node:fs'
2
1
  import { join } from 'node:path'
3
2
 
4
3
  import { loadEnv } from './env-load'
5
4
  import { getDockerHost } from './get-docker-host'
6
5
  import { getZeroVersion } from './zero-get-version'
7
6
 
8
- // extract the port from a postgres connection string
9
- function getPortFromConnectionString(url: string | undefined): string | undefined {
10
- if (!url) return undefined
11
- try {
12
- // handle postgresql:// URLs
13
- const match = url.match(/:(\d+)\//)
14
- return match?.[1]
15
- } catch {
16
- return undefined
17
- }
18
- }
19
-
20
- // read a specific env var directly from .env.development file
21
- // (process.env may have production values if NODE_ENV=production)
22
- function getDevEnvVar(key: string): string | undefined {
23
- try {
24
- const envPath = join(process.cwd(), '.env.development')
25
- const content = readFileSync(envPath, 'utf-8')
26
- const regex = new RegExp(`^${key}=["']?([^"'\\n]+)["']?`, 'm')
27
- const match = content.match(regex)
28
- return match?.[1]
29
- } catch {
30
- return undefined
31
- }
32
- }
33
-
34
- function getDevDbPort(): string | undefined {
35
- const url = getDevEnvVar('ZERO_UPSTREAM_DB')
36
- return url ? getPortFromConnectionString(url) : undefined
37
- }
38
-
39
7
  export async function getTestEnv() {
40
8
  const zeroVersion = getZeroVersion()
41
9
  const dockerHost = getDockerHost()
42
10
  const devEnv = await loadEnv('development')
43
11
  const serverEnvFallback = await import(join(process.cwd(), 'src/server/env-server'))
44
12
 
45
- // determine db port from (in order of priority):
46
- // 1. DOCKER_DB_PORT env var
47
- // 2. port from ZERO_UPSTREAM_DB in .env.development file (read directly to avoid
48
- // bun auto-loading .env.production when NODE_ENV=production)
49
- // 3. default 5432
50
- const dbPort = process.env.DOCKER_DB_PORT || getDevDbPort() || '5432'
13
+ // ports come from VITE_PORT_* in .env.development (loaded by loadEnv)
14
+ const dbPort = process.env.VITE_PORT_POSTGRES || '5433'
15
+ const appPort = process.env.VITE_PORT_WEB || '8081'
16
+ const minioPort = process.env.VITE_PORT_MINIO || '9200'
51
17
 
52
18
  const dockerDbBase = `postgresql://user:password@127.0.0.1:${dbPort}`
53
19
 
54
- // use dev BETTER_AUTH_SECRET for CI/staging to match local dev database keys
55
- // (better-auth encrypts JWKS private keys with this secret, so it must match)
56
- const devAuthSecret = getDevEnvVar('BETTER_AUTH_SECRET')
57
-
58
20
  return {
59
21
  ...serverEnvFallback,
60
22
  ...devEnv,
@@ -64,16 +26,14 @@ export async function getTestEnv() {
64
26
  }),
65
27
  DO_NOT_TRACK: '1',
66
28
  ZERO_VERSION: zeroVersion,
67
- ZERO_MUTATE_URL: `http://${dockerHost}:8081/api/zero/push`,
68
- ZERO_QUERY_URL: `http://${dockerHost}:8081/api/zero/pull`,
29
+ ZERO_MUTATE_URL: `http://${dockerHost}:${appPort}/api/zero/push`,
30
+ ZERO_QUERY_URL: `http://${dockerHost}:${appPort}/api/zero/pull`,
69
31
  ZERO_UPSTREAM_DB: `${dockerDbBase}/postgres`,
70
32
  ZERO_CVR_DB: `${dockerDbBase}/zero_cvr`,
71
33
  ZERO_CHANGE_DB: `${dockerDbBase}/zero_cdb`,
72
- CLOUDFLARE_R2_ENDPOINT: 'http://127.0.0.1:9200',
73
- CLOUDFLARE_R2_PUBLIC_URL: 'http://127.0.0.1:9200',
34
+ CLOUDFLARE_R2_ENDPOINT: `http://127.0.0.1:${minioPort}`,
35
+ CLOUDFLARE_R2_PUBLIC_URL: `http://127.0.0.1:${minioPort}`,
74
36
  CLOUDFLARE_R2_ACCESS_KEY: 'minio',
75
37
  CLOUDFLARE_R2_SECRET_KEY: 'minio_password',
76
- // ensure auth secret matches dev db keys
77
- ...(devAuthSecret && { BETTER_AUTH_SECRET: devAuthSecret }),
78
38
  }
79
39
  }
@@ -1,9 +1,9 @@
1
+ import { spawn, type ChildProcess } from 'node:child_process'
1
2
  import { cpus } from 'node:os'
2
3
 
3
4
  import type { Timer } from '@take-out/helpers'
4
- import type { ChildProcess } from 'node:child_process'
5
5
 
6
- export type ProcessType = ChildProcess | Bun.Subprocess
6
+ export type ProcessType = ChildProcess
7
7
  export type ProcessHandler = (process: ProcessType) => void
8
8
 
9
9
  // track if we're in cleanup state (another process failed)
@@ -94,11 +94,11 @@ export async function run(
94
94
  let didTimeOut = false
95
95
 
96
96
  try {
97
- const shell = Bun.spawn(['bash', '-c', command], {
97
+ const shell = spawn('bash', ['-c', command], {
98
98
  env: { ...process.env, ...env },
99
99
  cwd,
100
- stdout: 'pipe',
101
- stderr: 'pipe', // always pipe stderr so we can capture it for error messages
100
+ stdio: ['ignore', 'pipe', 'pipe'],
101
+ detached: detached ?? false,
102
102
  })
103
103
 
104
104
  if (detached) {
@@ -128,27 +128,26 @@ export async function run(
128
128
  }
129
129
  }
130
130
 
131
- const processStream = async (
132
- stream: ReadableStream<Uint8Array> | undefined,
131
+ const processStream = (
132
+ stream: NodeJS.ReadableStream | null,
133
133
  isStderr: boolean
134
134
  ): Promise<string> => {
135
- if (effectiveSilent && !captureOutput) {
136
- return ''
137
- }
138
-
139
- if (!stream) return ''
135
+ return new Promise((resolve) => {
136
+ if (effectiveSilent && !captureOutput) {
137
+ resolve('')
138
+ return
139
+ }
140
140
 
141
- let buffer = ''
142
- let captured = ''
143
- const decoder = new TextDecoder()
144
- const reader = stream.getReader()
141
+ if (!stream) {
142
+ resolve('')
143
+ return
144
+ }
145
145
 
146
- try {
147
- while (true) {
148
- const { done, value } = await reader.read()
149
- if (done) break
146
+ let buffer = ''
147
+ let captured = ''
150
148
 
151
- const text = buffer + decoder.decode(value, { stream: true })
149
+ stream.on('data', (chunk: Buffer) => {
150
+ const text = buffer + chunk.toString()
152
151
  const lines = text.split('\n')
153
152
 
154
153
  // keep last partial line in buffer
@@ -164,32 +163,35 @@ export async function run(
164
163
  writeOutput(line + '\n', isStderr)
165
164
  }
166
165
  }
167
- }
166
+ })
168
167
 
169
- // output any remaining buffer
170
- if (buffer) {
171
- captured += buffer
172
- if (!captureOutput || prefix) {
173
- writeOutput(buffer + '\n', isStderr)
168
+ stream.on('end', () => {
169
+ // output any remaining buffer
170
+ if (buffer) {
171
+ captured += buffer
172
+ if (!captureOutput || prefix) {
173
+ writeOutput(buffer + '\n', isStderr)
174
+ }
174
175
  }
175
- }
176
- } catch (err) {
177
- console.error(`Error reading stream!`, err)
178
- } finally {
179
- reader.releaseLock()
180
- }
181
-
182
- return captured
176
+ resolve(captured)
177
+ })
178
+
179
+ stream.on('error', (err) => {
180
+ console.error(`Error reading stream!`, err)
181
+ resolve(captured)
182
+ })
183
+ })
183
184
  }
184
185
 
185
- // always process both streams
186
- const [stdout, stderr] = await Promise.all([
186
+ // process both streams and wait for exit
187
+ const [stdout, stderr, exitCode] = await Promise.all([
187
188
  processStream(shell.stdout, false),
188
189
  processStream(shell.stderr, true),
190
+ new Promise<number | null>((resolve) => {
191
+ shell.on('close', (code) => resolve(code))
192
+ }),
189
193
  ])
190
194
 
191
- const exitCode = await shell.exited
192
-
193
195
  if (timeoutId) {
194
196
  clearTimeout(timeoutId)
195
197
  }
package/src/release.ts CHANGED
@@ -190,10 +190,13 @@ async function main() {
190
190
  // pack with bun (properly converts workspace:* to versions)
191
191
  // use swap-exports for packages with build scripts, otherwise just pack
192
192
  if (json.scripts?.build) {
193
- await run(`bun run build --swap-exports -- bun pm pack --filename ${tgzPath}`, {
194
- cwd,
195
- silent: true,
196
- })
193
+ await run(
194
+ `bun run build --swap-exports -- bun pm pack --filename ${tgzPath}`,
195
+ {
196
+ cwd,
197
+ silent: true,
198
+ }
199
+ )
197
200
  } else {
198
201
  await run(`bun pm pack --filename ${tgzPath}`, {
199
202
  cwd,
@@ -1,18 +1,21 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import { spawnSync } from 'node:child_process'
4
+
3
5
  export function getEnvironment(resourceName: string) {
4
6
  if (!resourceName) {
5
7
  console.error(`No resouce name given:
6
-
8
+
7
9
  bun scripts/get-environment.ts [resourceName]
8
10
  `)
9
11
  process.exit(1)
10
12
  }
11
13
 
12
14
  console.info(`Getting environment for ${resourceName}...`)
13
- const state = JSON.parse(
14
- Bun.spawnSync(`bun sst state export --stage production`.split(' ')).stdout.toString()
15
- )
15
+ const result = spawnSync('bun', ['sst', 'state', 'export', '--stage', 'production'], {
16
+ encoding: 'utf-8',
17
+ })
18
+ const state = JSON.parse(result.stdout || '{}')
16
19
 
17
20
  const resource = state.latest.resources.find(
18
21
  (x: any) => x.outputs?._dev?.title === resourceName