@take-out/scripts 0.0.96 → 0.0.98

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.96",
3
+ "version": "0.0.98",
4
4
  "type": "module",
5
5
  "main": "./src/run.ts",
6
6
  "sideEffects": false,
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@clack/prompts": "^0.8.2",
32
- "@take-out/helpers": "0.0.96",
32
+ "@take-out/helpers": "0.0.98",
33
33
  "picocolors": "^1.1.1"
34
34
  },
35
35
  "peerDependencies": {
@@ -4,13 +4,10 @@ import { cmd } from './cmd'
4
4
 
5
5
  await cmd`bootstrap project workspace and build initial packages`.run(
6
6
  async ({ $, fs, path }) => {
7
- const { existsSync, mkdirSync, readFileSync, symlinkSync } = await import('node:fs')
8
- const { exists } = fs
9
-
10
- const hasPackages = await exists(`./packages`)
7
+ const hasPackages = fs.existsSync(`./packages`)
11
8
 
12
9
  // only run once
13
- if (!(await exists(`./node_modules/.bin/tko`))) {
10
+ if (!fs.existsSync(`./node_modules/.bin/tko`)) {
14
11
  if (hasPackages) {
15
12
  symlinkBins()
16
13
  }
@@ -19,8 +16,8 @@ await cmd`bootstrap project workspace and build initial packages`.run(
19
16
  // check if critical packages are built
20
17
  if (hasPackages) {
21
18
  const needsBuild =
22
- !(await exists(`./packages/helpers/dist`)) ||
23
- !(await exists(`./packages/cli/dist/esm`))
19
+ !fs.existsSync(`./packages/helpers/dist`) ||
20
+ !fs.existsSync(`./packages/cli/dist/esm`)
24
21
 
25
22
  if (needsBuild) {
26
23
  // build helpers first as other packages depend on it
@@ -37,7 +34,7 @@ await cmd`bootstrap project workspace and build initial packages`.run(
37
34
  function checkAndShowWelcome(cwd: string = process.cwd()): void {
38
35
  try {
39
36
  const packagePath = path.join(cwd, 'package.json')
40
- const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'))
37
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf-8'))
41
38
 
42
39
  if (pkg.takeout?.onboarded === false) {
43
40
  console.info()
@@ -70,8 +67,8 @@ await cmd`bootstrap project workspace and build initial packages`.run(
70
67
 
71
68
  const binDir = path.join(process.cwd(), 'node_modules', '.bin')
72
69
 
73
- if (!existsSync(binDir)) {
74
- mkdirSync(binDir, { recursive: true })
70
+ if (!fs.existsSync(binDir)) {
71
+ fs.mkdirSync(binDir, { recursive: true })
75
72
  }
76
73
 
77
74
  for (const pkg of packagesWithCLI) {
@@ -86,12 +83,12 @@ await cmd`bootstrap project workspace and build initial packages`.run(
86
83
  }
87
84
 
88
85
  function symlinkTo(source: string, target: string): void {
89
- if (existsSync(target)) {
86
+ if (fs.existsSync(target)) {
90
87
  console.info(`✓ Symlink already exists: ${target}`)
91
88
  return
92
89
  }
93
90
 
94
- symlinkSync(source, target)
91
+ fs.symlinkSync(source, target)
95
92
  console.info(`→ Created symlink: ${source} ⇢ ${target}`)
96
93
  }
97
94
  }
package/src/cmd.ts CHANGED
@@ -5,7 +5,7 @@ type CmdContext = {
5
5
  colors: typeof import('picocolors')
6
6
  prompt: typeof import('@clack/prompts')
7
7
  run: typeof import('./helpers/run').run
8
- fs: typeof import('node:fs/promises')
8
+ fs: typeof import('node:fs')
9
9
  path: typeof import('node:path')
10
10
  os: typeof import('node:os')
11
11
  }
@@ -56,7 +56,7 @@ function createCmd(description: string) {
56
56
  import(`@clack/prompts`),
57
57
  import(`./helpers/run`),
58
58
  import(`./helpers/args`),
59
- import(`node:fs/promises`),
59
+ import(`node:fs`),
60
60
  import(`node:path`),
61
61
  import(`node:os`),
62
62
  ])
package/src/dev-tunnel.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  await cmd`set up cloudflare dev tunnel for local development`
6
8
  .args('--port number')
7
9
  .run(async ({ args, run, os, path }) => {
8
- const { existsSync, mkdirSync, readFileSync, writeFileSync } = await import('node:fs')
9
10
  const { handleProcessExit } = await import('./helpers/handleProcessExit')
10
11
 
11
12
  handleProcessExit()
@@ -30,7 +31,7 @@ await cmd`set up cloudflare dev tunnel for local development`
30
31
 
31
32
  async function ensureAuthenticated(): Promise<boolean> {
32
33
  const certPath = path.join(os.homedir(), '.cloudflared', 'cert.pem')
33
- if (existsSync(certPath)) {
34
+ if (fs.existsSync(certPath)) {
34
35
  return true
35
36
  }
36
37
 
@@ -44,12 +45,12 @@ await cmd`set up cloudflare dev tunnel for local development`
44
45
  }
45
46
 
46
47
  async function getOrCreateTunnel(): Promise<string | null> {
47
- if (!existsSync(TUNNEL_CONFIG_DIR)) {
48
- mkdirSync(TUNNEL_CONFIG_DIR, { recursive: true })
48
+ if (!fs.existsSync(TUNNEL_CONFIG_DIR)) {
49
+ fs.mkdirSync(TUNNEL_CONFIG_DIR, { recursive: true })
49
50
  }
50
51
 
51
- if (existsSync(TUNNEL_ID_FILE)) {
52
- const tunnelId = readFileSync(TUNNEL_ID_FILE, 'utf-8').trim()
52
+ if (fs.existsSync(TUNNEL_ID_FILE)) {
53
+ const tunnelId = fs.readFileSync(TUNNEL_ID_FILE, 'utf-8').trim()
53
54
  return tunnelId
54
55
  }
55
56
 
@@ -70,7 +71,7 @@ await cmd`set up cloudflare dev tunnel for local development`
70
71
  const tunnelId = match1?.[1] || match2?.[1] || match3?.[1]
71
72
 
72
73
  if (tunnelId) {
73
- writeFileSync(TUNNEL_ID_FILE, tunnelId)
74
+ fs.writeFileSync(TUNNEL_ID_FILE, tunnelId)
74
75
  return tunnelId
75
76
  }
76
77
 
@@ -87,7 +88,7 @@ await cmd`set up cloudflare dev tunnel for local development`
87
88
  const tunnels = JSON.parse(stdout)
88
89
  if (tunnels.length > 0) {
89
90
  const tunnelId = tunnels[0].id
90
- writeFileSync(TUNNEL_ID_FILE, tunnelId)
91
+ fs.writeFileSync(TUNNEL_ID_FILE, tunnelId)
91
92
  return tunnelId
92
93
  }
93
94
  } catch (e) {
@@ -125,7 +126,7 @@ await cmd`set up cloudflare dev tunnel for local development`
125
126
 
126
127
  // save the expected url immediately so it's available right away
127
128
  const expectedUrl = `https://${tunnelId}.cfargotunnel.com`
128
- writeFileSync(path.join(TUNNEL_CONFIG_DIR, 'tunnel-url.txt'), expectedUrl)
129
+ fs.writeFileSync(path.join(TUNNEL_CONFIG_DIR, 'tunnel-url.txt'), expectedUrl)
129
130
  console.info(`\n🌐 Tunnel URL: ${expectedUrl}`)
130
131
 
131
132
  // get the public url in the background
@@ -142,7 +143,7 @@ await cmd`set up cloudflare dev tunnel for local development`
142
143
  try {
143
144
  const info = JSON.parse(stdout)
144
145
  const hostname = info.hostname || `${tunnelId}.cfargotunnel.com`
145
- writeFileSync(
146
+ fs.writeFileSync(
146
147
  path.join(TUNNEL_CONFIG_DIR, 'tunnel-url.txt'),
147
148
  `https://${hostname}`
148
149
  )
package/src/env-pull.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  await cmd`pull environment variables from SST production`.run(async ({ path }) => {
6
- const { existsSync, writeFileSync } = await import('node:fs')
7
8
  const { getEnvironment } = await import('./sst-get-environment')
8
9
 
9
10
  const rootDir = process.cwd()
10
11
 
11
12
  const envFilePath = path.join(rootDir, '.env.production')
12
- if (existsSync(envFilePath)) {
13
+ if (fs.existsSync(envFilePath)) {
13
14
  console.error(
14
15
  '❌ Error: .env.production already exists. Please remove or rename it first.'
15
16
  )
@@ -45,7 +46,7 @@ await cmd`pull environment variables from SST production`.run(async ({ path }) =
45
46
  process.exit(1)
46
47
  }
47
48
 
48
- writeFileSync(envFilePath, envFileContent)
49
+ fs.writeFileSync(envFilePath, envFileContent)
49
50
 
50
51
  console.info(
51
52
  `✅ Success! ${foundCount} environment variables written to .env.production`
package/src/env-update.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  await cmd`sync environment variables from package.json to CI and server configs`.run(
6
8
  async () => {
7
- const { readFileSync, writeFileSync } = await import('node:fs')
8
-
9
- const packageJson = JSON.parse(readFileSync('package.json', 'utf-8'))
9
+ const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'))
10
10
  const envVars = packageJson.env as Record<string, boolean | string>
11
11
 
12
12
  if (!envVars || Array.isArray(envVars) || typeof envVars !== 'object') {
@@ -36,7 +36,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
36
36
 
37
37
  function updateDeployYml() {
38
38
  const deployYmlPath = '.github/workflows/ci.yml'
39
- let deployYml = readFileSync(deployYmlPath, 'utf-8')
39
+ let deployYml = fs.readFileSync(deployYmlPath, 'utf-8')
40
40
 
41
41
  if (!deployYml.includes(yamlStartMarker) || !deployYml.includes(yamlEndMarker)) {
42
42
  throw new Error(`Markers not found in ${deployYmlPath}`)
@@ -49,7 +49,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
49
49
 
50
50
  const newDeployYml = replaceYamlSection(deployYml, envSection, { indent })
51
51
 
52
- writeFileSync(deployYmlPath, newDeployYml, 'utf-8')
52
+ fs.writeFileSync(deployYmlPath, newDeployYml, 'utf-8')
53
53
  console.info('✅ Updated Github workflow')
54
54
  }
55
55
 
@@ -60,7 +60,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
60
60
 
61
61
  for (const p of candidates) {
62
62
  try {
63
- envServer = readFileSync(p, 'utf-8')
63
+ envServer = fs.readFileSync(p, 'utf-8')
64
64
  envServerPath = p
65
65
  break
66
66
  } catch {}
@@ -86,7 +86,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
86
86
  `${jsStartMarker}\n${envExports}\n${jsEndMarker}`
87
87
  )
88
88
 
89
- writeFileSync(envServerPath, newEnvServer, 'utf-8')
89
+ fs.writeFileSync(envServerPath, newEnvServer, 'utf-8')
90
90
  console.info('✅ Updated server env')
91
91
  }
92
92
 
@@ -95,7 +95,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
95
95
 
96
96
  let dockerCompose = ''
97
97
  try {
98
- dockerCompose = readFileSync(dockerComposePath, 'utf-8')
98
+ dockerCompose = fs.readFileSync(dockerComposePath, 'utf-8')
99
99
  } catch (_error) {
100
100
  // file doesn't exist, skip
101
101
  return
@@ -128,7 +128,7 @@ await cmd`sync environment variables from package.json to CI and server configs`
128
128
 
129
129
  const newDockerCompose = replaceYamlSection(dockerCompose, envLines, { indent })
130
130
 
131
- writeFileSync(dockerComposePath, newDockerCompose, 'utf-8')
131
+ fs.writeFileSync(dockerComposePath, newDockerCompose, 'utf-8')
132
132
  console.info('✅ Updated docker-compose.yml')
133
133
  }
134
134
 
@@ -1,4 +1,4 @@
1
- import { existsSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
 
4
4
  import { loadEnv as vxrnLoadEnv } from 'vxrn/loadEnv'
@@ -31,7 +31,7 @@ function resolveEnvServerPath(): string {
31
31
  const candidates = ['src/constants/env-server.ts', 'src/server/env-server.ts']
32
32
  for (const candidate of candidates) {
33
33
  const full = join(process.cwd(), candidate)
34
- if (existsSync(full)) {
34
+ if (fs.existsSync(full)) {
35
35
  return full
36
36
  }
37
37
  }
@@ -1,4 +1,4 @@
1
- import { existsSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
 
4
4
  import { loadEnv } from './env-load'
@@ -12,7 +12,7 @@ export async function getTestEnv() {
12
12
  const envPath =
13
13
  ['src/constants/env-server', 'src/server/env-server']
14
14
  .map((p) => join(process.cwd(), p))
15
- .find((p) => existsSync(p + '.ts')) ||
15
+ .find((p) => fs.existsSync(p + '.ts')) ||
16
16
  join(process.cwd(), 'src/constants/env-server')
17
17
  const serverEnvFallback = await import(envPath)
18
18
 
@@ -1,4 +1,4 @@
1
- import { writeFileSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
 
3
3
  import { sleep } from '@take-out/helpers'
4
4
 
@@ -66,7 +66,7 @@ packages:
66
66
  `
67
67
 
68
68
  const cloudInitPath = `${process.cwd()}/.cloud-init.yml`
69
- writeFileSync(cloudInitPath, cloudInit)
69
+ fs.writeFileSync(cloudInitPath, cloudInit)
70
70
 
71
71
  try {
72
72
  await run(
@@ -1,4 +1,4 @@
1
- import { readFileSync, writeFileSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
 
3
3
  // make values safe for yaml map syntax (KEY: value)
4
4
  // handles multi-line values, special chars that break yaml parsing
@@ -30,7 +30,7 @@ export function processComposeEnv(
30
30
  outputFile: string,
31
31
  envVars: Record<string, string | undefined>
32
32
  ): void {
33
- let content = readFileSync(composeFile, 'utf-8')
33
+ let content = fs.readFileSync(composeFile, 'utf-8')
34
34
 
35
35
  // replace all ${VAR:-default} patterns with actual env values
36
36
  content = content.replace(
@@ -52,6 +52,6 @@ export function processComposeEnv(
52
52
  return value ? yamlSafe(value) : _match
53
53
  })
54
54
 
55
- writeFileSync(outputFile, content)
55
+ fs.writeFileSync(outputFile, content)
56
56
  console.info(`✅ processed compose file: ${outputFile}`)
57
57
  }
@@ -2,8 +2,7 @@
2
2
  * generic uncloud deployment helpers for ci/cd
3
3
  */
4
4
 
5
- import { existsSync } from 'node:fs'
6
- import { mkdir, writeFile } from 'node:fs/promises'
5
+ import fs from 'node:fs'
7
6
  import { homedir } from 'node:os'
8
7
  import { join } from 'node:path'
9
8
 
@@ -91,7 +90,7 @@ export async function setupSSHKey() {
91
90
  const sshKeyValue = process.env.DEPLOY_SSH_KEY
92
91
 
93
92
  // check if it's a path to an existing file (local usage) or key content (CI usage)
94
- if (existsSync(sshKeyValue)) {
93
+ if (fs.existsSync(sshKeyValue)) {
95
94
  console.info(` using ssh key from: ${sshKeyValue}`)
96
95
  return
97
96
  }
@@ -101,8 +100,8 @@ export async function setupSSHKey() {
101
100
  const sshDir = join(homedir(), '.ssh')
102
101
  const keyPath = join(sshDir, 'uncloud_deploy')
103
102
 
104
- if (!existsSync(sshDir)) {
105
- await mkdir(sshDir, { recursive: true })
103
+ if (!fs.existsSync(sshDir)) {
104
+ await fs.promises.mkdir(sshDir, { recursive: true })
106
105
  }
107
106
 
108
107
  // decode base64-encoded keys (github secrets often store keys as base64)
@@ -120,7 +119,7 @@ export async function setupSSHKey() {
120
119
  keyContent += '\n'
121
120
  }
122
121
 
123
- await writeFile(keyPath, keyContent, { mode: 0o600 })
122
+ await fs.promises.writeFile(keyPath, keyContent, { mode: 0o600 })
124
123
 
125
124
  // add host to known_hosts
126
125
  if (process.env.DEPLOY_HOST) {
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
  import { homedir } from 'node:os'
3
3
  import { join } from 'node:path'
4
4
 
@@ -27,13 +27,13 @@ function ensureUncloudContext(host: string, sshKey: string, contextName: string)
27
27
  const configDir = join(homedir(), '.config', 'uncloud')
28
28
  const configPath = join(configDir, 'config.yaml')
29
29
 
30
- if (!existsSync(configDir)) {
31
- mkdirSync(configDir, { recursive: true })
30
+ if (!fs.existsSync(configDir)) {
31
+ fs.mkdirSync(configDir, { recursive: true })
32
32
  }
33
33
 
34
34
  // check if config already has context pointing to correct host
35
- if (existsSync(configPath)) {
36
- const existing = readFileSync(configPath, 'utf-8')
35
+ if (fs.existsSync(configPath)) {
36
+ const existing = fs.readFileSync(configPath, 'utf-8')
37
37
  const hostname = host.split('@')[1]
38
38
  if (hostname && existing.includes(`${contextName}:`) && existing.includes(hostname)) {
39
39
  console.info(`✅ uncloud config already has ${contextName} context for ${host}`)
@@ -43,7 +43,7 @@ function ensureUncloudContext(host: string, sshKey: string, contextName: string)
43
43
 
44
44
  // only create config if it doesn't exist - don't overwrite existing config
45
45
  // which may have other contexts
46
- if (!existsSync(configPath)) {
46
+ if (!fs.existsSync(configPath)) {
47
47
  const config = `current_context: ${contextName}
48
48
  contexts:
49
49
  ${contextName}:
@@ -51,7 +51,7 @@ contexts:
51
51
  - ssh: ${host}
52
52
  ssh_key_file: ${sshKey}
53
53
  `
54
- writeFileSync(configPath, config)
54
+ fs.writeFileSync(configPath, config)
55
55
  console.info(`✅ created uncloud config at ${configPath}`)
56
56
  } else {
57
57
  console.info(`✅ using existing uncloud config (context: ${contextName})`)
@@ -1,8 +1,8 @@
1
- import { readFileSync } from 'node:fs'
1
+ import fs from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
 
4
4
  export function getZeroVersion() {
5
5
  const packageJsonPath = join(process.cwd(), 'package.json')
6
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
6
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
7
7
  return packageJson.dependencies?.['@rocicorp/zero']?.replace(/^[\^~]/, '')
8
8
  }
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  function getCurrentNodeVersion() {
@@ -7,12 +9,11 @@ function getCurrentNodeVersion() {
7
9
  }
8
10
 
9
11
  async function getRequiredNodeVersion() {
10
- const fs = await import('node:fs/promises')
11
12
  const path = await import('node:path')
12
13
 
13
14
  // try .node-version file first
14
15
  try {
15
- const nodeVersionContent = await fs.readFile(
16
+ const nodeVersionContent = await fs.promises.readFile(
16
17
  path.join(process.cwd(), '.node-version'),
17
18
  'utf-8'
18
19
  )
@@ -22,7 +23,7 @@ async function getRequiredNodeVersion() {
22
23
  // fallback to package.json engines.node
23
24
  try {
24
25
  const packageJson = JSON.parse(
25
- await fs.readFile(path.join(process.cwd(), 'package.json'), 'utf-8')
26
+ await fs.promises.readFile(path.join(process.cwd(), 'package.json'), 'utf-8')
26
27
  )
27
28
  return packageJson?.engines?.node ? `v${packageJson.engines.node}` : null
28
29
  } catch {
package/src/run.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { spawn } from 'node:child_process'
8
- import { promises as fs } from 'node:fs'
8
+ import fs from 'node:fs'
9
9
  import { join, relative, resolve } from 'node:path'
10
10
 
11
11
  import { handleProcessExit } from '@take-out/scripts/helpers/handleProcessExit'
@@ -101,7 +101,7 @@ if (runCommands.length === 0) {
101
101
  async function readPackageJson(directoryPath: string) {
102
102
  try {
103
103
  const packageJsonPath = join(directoryPath, 'package.json')
104
- const content = await fs.readFile(packageJsonPath, 'utf8')
104
+ const content = await fs.promises.readFile(packageJsonPath, 'utf8')
105
105
  return JSON.parse(content)
106
106
  } catch (_) {
107
107
  return null
@@ -124,7 +124,7 @@ async function getWorkspacePatterns(): Promise<string[]> {
124
124
 
125
125
  async function hasPackageJson(path: string): Promise<boolean> {
126
126
  try {
127
- await fs.access(join(path, 'package.json'))
127
+ await fs.promises.access(join(path, 'package.json'))
128
128
  return true
129
129
  } catch {
130
130
  return false
@@ -135,7 +135,7 @@ async function findPackageJsonDirs(basePath: string, maxDepth = 3): Promise<stri
135
135
  if (maxDepth <= 0) return []
136
136
 
137
137
  try {
138
- const entries = await fs.readdir(basePath, { withFileTypes: true })
138
+ const entries = await fs.promises.readdir(basePath, { withFileTypes: true })
139
139
  const results: string[] = []
140
140
 
141
141
  if (await hasPackageJson(basePath)) {
package/src/up.ts CHANGED
@@ -12,9 +12,6 @@ interface PackageJson {
12
12
  await cmd`upgrade packages by name or pattern`
13
13
  .args('--tag string --canary boolean --rc boolean')
14
14
  .run(async ({ args, $, path, fs }) => {
15
- const { existsSync, readdirSync, readFileSync, writeFileSync, rmSync } =
16
- await import('node:fs')
17
-
18
15
  let globalTag: string | undefined = args.tag
19
16
  if (args.canary) globalTag = 'canary'
20
17
  if (args.rc) globalTag = 'rc'
@@ -22,7 +19,7 @@ await cmd`upgrade packages by name or pattern`
22
19
  const packagePatterns: string[] = []
23
20
  const rootDir = process.cwd()
24
21
  const rootPackageJson = JSON.parse(
25
- readFileSync(path.join(rootDir, 'package.json'), 'utf-8')
22
+ fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8')
26
23
  )
27
24
  const upgradeSets: Record<string, string[]> = rootPackageJson.upgradeSets || {}
28
25
 
@@ -54,14 +51,14 @@ await cmd`upgrade packages by name or pattern`
54
51
  function findPackageJsonFiles(dir: string): string[] {
55
52
  const results: string[] = []
56
53
 
57
- if (existsSync(path.join(dir, 'package.json'))) {
54
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
58
55
  results.push(path.join(dir, 'package.json'))
59
56
  }
60
57
 
61
58
  // check if it's a monorepo with workspaces
62
59
  try {
63
60
  const packageJson = JSON.parse(
64
- readFileSync(path.join(dir, 'package.json'), 'utf-8')
61
+ fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')
65
62
  )
66
63
  if (packageJson.workspaces) {
67
64
  let workspacePaths: string[] = []
@@ -81,15 +78,15 @@ await cmd`upgrade packages by name or pattern`
81
78
  const baseDir = normalizedWorkspace.split('**')[0]!.replace(/\/$/, '')
82
79
  const basePath = path.join(dir, baseDir)
83
80
 
84
- if (existsSync(basePath)) {
81
+ if (fs.existsSync(basePath)) {
85
82
  const findPackages = (searchDir: string) => {
86
83
  try {
87
- const entries = readdirSync(searchDir, { withFileTypes: true })
84
+ const entries = fs.readdirSync(searchDir, { withFileTypes: true })
88
85
  for (const entry of entries) {
89
86
  if (entry.isDirectory() && entry.name !== 'node_modules') {
90
87
  const subPath = path.join(searchDir, entry.name)
91
88
  const pkgPath = path.join(subPath, 'package.json')
92
- if (existsSync(pkgPath)) {
89
+ if (fs.existsSync(pkgPath)) {
93
90
  results.push(pkgPath)
94
91
  }
95
92
  // recurse into subdirectories
@@ -105,15 +102,16 @@ await cmd`upgrade packages by name or pattern`
105
102
  } else if (normalizedWorkspace.includes('*')) {
106
103
  // simple glob pattern like "packages/*"
107
104
  const workspaceDir = normalizedWorkspace.replace(/\/\*$/, '')
108
- if (existsSync(path.join(dir, workspaceDir))) {
109
- const subdirs = readdirSync(path.join(dir, workspaceDir), {
110
- withFileTypes: true,
111
- })
105
+ if (fs.existsSync(path.join(dir, workspaceDir))) {
106
+ const subdirs = fs
107
+ .readdirSync(path.join(dir, workspaceDir), {
108
+ withFileTypes: true,
109
+ })
112
110
  .filter((dirent) => dirent.isDirectory())
113
111
  .map((dirent) => path.join(dir, workspaceDir, dirent.name))
114
112
 
115
113
  for (const subdir of subdirs) {
116
- if (existsSync(path.join(subdir, 'package.json'))) {
114
+ if (fs.existsSync(path.join(subdir, 'package.json'))) {
117
115
  results.push(path.join(subdir, 'package.json'))
118
116
  }
119
117
  }
@@ -121,7 +119,7 @@ await cmd`upgrade packages by name or pattern`
121
119
  } else {
122
120
  // exact path like "code/tamagui.dev" or "./code/sandbox"
123
121
  const pkgPath = path.join(dir, normalizedWorkspace, 'package.json')
124
- if (existsSync(pkgPath)) {
122
+ if (fs.existsSync(pkgPath)) {
125
123
  results.push(pkgPath)
126
124
  }
127
125
  }
@@ -136,7 +134,7 @@ await cmd`upgrade packages by name or pattern`
136
134
 
137
135
  function extractDependencies(packageJsonPath: string): string[] {
138
136
  try {
139
- const content = readFileSync(packageJsonPath, 'utf-8')
137
+ const content = fs.readFileSync(packageJsonPath, 'utf-8')
140
138
  const packageJson = JSON.parse(content) as PackageJson
141
139
 
142
140
  const deps: string[] = []
@@ -176,7 +174,7 @@ await cmd`upgrade packages by name or pattern`
176
174
  packagesToUpdate: string[],
177
175
  versionMap: Map<string, string>
178
176
  ): number {
179
- const content = readFileSync(packageJsonPath, 'utf-8')
177
+ const content = fs.readFileSync(packageJsonPath, 'utf-8')
180
178
  const packageJson = JSON.parse(content) as PackageJson
181
179
  let updatedCount = 0
182
180
 
@@ -214,7 +212,7 @@ await cmd`upgrade packages by name or pattern`
214
212
  updateDeps(packageJson.optionalDependencies)
215
213
 
216
214
  if (updatedCount > 0) {
217
- writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n')
215
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n')
218
216
  }
219
217
 
220
218
  return updatedCount
@@ -226,7 +224,7 @@ await cmd`upgrade packages by name or pattern`
226
224
  packageJsonFiles: string[]
227
225
  ) {
228
226
  try {
229
- rmSync(`node_modules/vite`, {
227
+ fs.rmSync(`node_modules/vite`, {
230
228
  recursive: true,
231
229
  force: true,
232
230
  })
@@ -338,7 +336,7 @@ await cmd`upgrade packages by name or pattern`
338
336
  if (packageJsonPath === path.join(rootDir, 'package.json')) continue
339
337
 
340
338
  try {
341
- const content = readFileSync(packageJsonPath, 'utf-8')
339
+ const content = fs.readFileSync(packageJsonPath, 'utf-8')
342
340
  const packageJson = JSON.parse(content)
343
341
  if (packageJson.name) {
344
342
  workspacePackageNames.add(packageJson.name)
@@ -405,7 +403,7 @@ await cmd`upgrade packages by name or pattern`
405
403
  })
406
404
 
407
405
  // insert placeholder so updatePackageJsonVersions can set the real version
408
- const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'))
406
+ const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath, 'utf-8'))
409
407
  if (!rootPkg.dependencies) {
410
408
  rootPkg.dependencies = {}
411
409
  }
@@ -414,7 +412,7 @@ await cmd`upgrade packages by name or pattern`
414
412
  rootPkg.dependencies[pkg] = '*'
415
413
  }
416
414
  }
417
- writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2) + '\n')
415
+ fs.writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2) + '\n')
418
416
  } else {
419
417
  console.info(
420
418
  `Found ${allMatchingDeps.size} dependencies matching patterns: ${packagePatterns.join(', ')}`
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  await cmd`update changelog with recent git commits`.run(async ({ path }) => {
6
8
  const { execSync } = await import('node:child_process')
7
- const { existsSync, readFileSync } = await import('node:fs')
8
9
 
9
10
  const CHANGELOG_PATH = path.join(process.cwd(), 'src/features/site/docs/changelog.mdx')
10
11
 
11
12
  function getLastSha(): string | null {
12
- if (!existsSync(CHANGELOG_PATH)) return null
13
+ if (!fs.existsSync(CHANGELOG_PATH)) return null
13
14
 
14
15
  try {
15
- const content = readFileSync(CHANGELOG_PATH, 'utf-8')
16
+ const content = fs.readFileSync(CHANGELOG_PATH, 'utf-8')
16
17
  const match = content.match(/\{\/\* last updated: ([a-f0-9]+) \*\/\}/)
17
18
  return match?.[1] || null
18
19
  } catch {
@@ -1,16 +1,10 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import fs from 'node:fs'
4
+
3
5
  import { cmd } from './cmd'
4
6
 
5
7
  await cmd`sync auto-generated env vars to local .env file`.run(async ({ path }) => {
6
- const {
7
- existsSync,
8
- readFileSync,
9
- writeFileSync,
10
- copyFileSync,
11
- renameSync,
12
- unlinkSync,
13
- } = await import('node:fs')
14
8
  const { getZeroVersion } = await import('./helpers/zero-get-version')
15
9
 
16
10
  // skip in CI environments
@@ -29,13 +23,13 @@ await cmd`sync auto-generated env vars to local .env file`.run(async ({ path })
29
23
  const END_MARKER = '# ---- END AUTO-GENERATED ----'
30
24
 
31
25
  function createEnvFromTemplate(): boolean {
32
- if (!existsSync(ENV_TEMPLATE_PATH)) {
26
+ if (!fs.existsSync(ENV_TEMPLATE_PATH)) {
33
27
  console.info('No .env.template found, skipping .env creation')
34
28
  return false
35
29
  }
36
30
 
37
31
  try {
38
- copyFileSync(ENV_TEMPLATE_PATH, ENV_PATH)
32
+ fs.copyFileSync(ENV_TEMPLATE_PATH, ENV_PATH)
39
33
  console.info('Created .env from .env.template')
40
34
  return true
41
35
  } catch (error) {
@@ -63,21 +57,21 @@ await cmd`sync auto-generated env vars to local .env file`.run(async ({ path })
63
57
 
64
58
  function updateEnvFile(): void {
65
59
  // ensure .env exists
66
- if (!existsSync(ENV_PATH)) {
60
+ if (!fs.existsSync(ENV_PATH)) {
67
61
  const created = createEnvFromTemplate()
68
- if (!created && !existsSync(ENV_PATH)) {
69
- writeFileSync(ENV_PATH, '')
62
+ if (!created && !fs.existsSync(ENV_PATH)) {
63
+ fs.writeFileSync(ENV_PATH, '')
70
64
  console.info('Created empty .env file')
71
65
  }
72
66
  }
73
67
 
74
68
  try {
75
69
  // create backup
76
- if (existsSync(ENV_PATH)) {
77
- copyFileSync(ENV_PATH, ENV_BACKUP_PATH)
70
+ if (fs.existsSync(ENV_PATH)) {
71
+ fs.copyFileSync(ENV_PATH, ENV_BACKUP_PATH)
78
72
  }
79
73
 
80
- const currentContent = readFileSync(ENV_PATH, 'utf-8')
74
+ const currentContent = fs.readFileSync(ENV_PATH, 'utf-8')
81
75
 
82
76
  const beginIndex = currentContent.indexOf(BEGIN_MARKER)
83
77
  const endIndex = currentContent.indexOf(END_MARKER)
@@ -107,20 +101,20 @@ await cmd`sync auto-generated env vars to local .env file`.run(async ({ path })
107
101
  }
108
102
 
109
103
  // write to temp file first (atomic operation)
110
- writeFileSync(ENV_TEMP_PATH, newContent)
104
+ fs.writeFileSync(ENV_TEMP_PATH, newContent)
111
105
 
112
106
  // validate temp file
113
- const tempContent = readFileSync(ENV_TEMP_PATH, 'utf-8')
107
+ const tempContent = fs.readFileSync(ENV_TEMP_PATH, 'utf-8')
114
108
  if (!tempContent.includes(BEGIN_MARKER) || !tempContent.includes(END_MARKER)) {
115
109
  throw new Error('Generated content validation failed')
116
110
  }
117
111
 
118
112
  // atomic replace
119
- renameSync(ENV_TEMP_PATH, ENV_PATH)
113
+ fs.renameSync(ENV_TEMP_PATH, ENV_PATH)
120
114
 
121
- if (existsSync(ENV_BACKUP_PATH)) {
115
+ if (fs.existsSync(ENV_BACKUP_PATH)) {
122
116
  try {
123
- unlinkSync(ENV_BACKUP_PATH)
117
+ fs.unlinkSync(ENV_BACKUP_PATH)
124
118
  } catch {
125
119
  // ignore cleanup errors
126
120
  }
@@ -131,9 +125,9 @@ await cmd`sync auto-generated env vars to local .env file`.run(async ({ path })
131
125
  console.error('Failed to update .env file:', error)
132
126
 
133
127
  // attempt to restore backup
134
- if (existsSync(ENV_BACKUP_PATH)) {
128
+ if (fs.existsSync(ENV_BACKUP_PATH)) {
135
129
  try {
136
- copyFileSync(ENV_BACKUP_PATH, ENV_PATH)
130
+ fs.copyFileSync(ENV_BACKUP_PATH, ENV_PATH)
137
131
  console.info('Restored .env from backup')
138
132
  } catch (restoreError) {
139
133
  console.error('Failed to restore backup:', restoreError)
@@ -141,9 +135,9 @@ await cmd`sync auto-generated env vars to local .env file`.run(async ({ path })
141
135
  }
142
136
 
143
137
  // clean up temp file
144
- if (existsSync(ENV_TEMP_PATH)) {
138
+ if (fs.existsSync(ENV_TEMP_PATH)) {
145
139
  try {
146
- unlinkSync(ENV_TEMP_PATH)
140
+ fs.unlinkSync(ENV_TEMP_PATH)
147
141
  } catch {
148
142
  // ignore cleanup errors
149
143
  }