@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 +2 -2
- package/src/build-initial.ts +9 -12
- package/src/cmd.ts +2 -2
- package/src/dev-tunnel.ts +11 -10
- package/src/env-pull.ts +4 -3
- package/src/env-update.ts +9 -9
- package/src/helpers/env-load.ts +2 -2
- package/src/helpers/get-test-env.ts +2 -2
- package/src/helpers/multipass.ts +2 -2
- package/src/helpers/process-compose-env.ts +3 -3
- package/src/helpers/uncloud-deploy.ts +5 -6
- package/src/helpers/uncloud.ts +7 -7
- package/src/helpers/zero-get-version.ts +2 -2
- package/src/node-version-check.ts +4 -3
- package/src/run.ts +4 -4
- package/src/up.ts +20 -22
- package/src/update-changelog.ts +4 -3
- package/src/update-local-env.ts +19 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@take-out/scripts",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
32
|
+
"@take-out/helpers": "0.0.98",
|
|
33
33
|
"picocolors": "^1.1.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
package/src/build-initial.ts
CHANGED
|
@@ -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
|
|
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 (!(
|
|
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
|
-
!(
|
|
23
|
-
!(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/src/helpers/env-load.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
|
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
|
|
package/src/helpers/multipass.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
|
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
|
|
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) {
|
package/src/helpers/uncloud.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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
|
|
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
|
|
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 =
|
|
110
|
-
|
|
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(', ')}`
|
package/src/update-changelog.ts
CHANGED
|
@@ -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 {
|
package/src/update-local-env.ts
CHANGED
|
@@ -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
|
}
|