@take-out/cli 0.0.39
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/LICENSE +21 -0
- package/README.md +274 -0
- package/cli.mjs +3 -0
- package/dist/cjs/cli.cjs +71 -0
- package/dist/cjs/cli.js +70 -0
- package/dist/cjs/cli.js.map +6 -0
- package/dist/cjs/cli.native.js +79 -0
- package/dist/cjs/cli.native.js.map +6 -0
- package/dist/cjs/commands/changed.cjs +212 -0
- package/dist/cjs/commands/changed.js +214 -0
- package/dist/cjs/commands/changed.js.map +6 -0
- package/dist/cjs/commands/changed.native.js +289 -0
- package/dist/cjs/commands/changed.native.js.map +6 -0
- package/dist/cjs/commands/docs.cjs +388 -0
- package/dist/cjs/commands/docs.js +313 -0
- package/dist/cjs/commands/docs.js.map +6 -0
- package/dist/cjs/commands/docs.native.js +476 -0
- package/dist/cjs/commands/docs.native.js.map +6 -0
- package/dist/cjs/commands/env-setup.cjs +90 -0
- package/dist/cjs/commands/env-setup.js +78 -0
- package/dist/cjs/commands/env-setup.js.map +6 -0
- package/dist/cjs/commands/env-setup.native.js +85 -0
- package/dist/cjs/commands/env-setup.native.js.map +6 -0
- package/dist/cjs/commands/onboard.cjs +479 -0
- package/dist/cjs/commands/onboard.js +631 -0
- package/dist/cjs/commands/onboard.js.map +6 -0
- package/dist/cjs/commands/onboard.native.js +608 -0
- package/dist/cjs/commands/onboard.native.js.map +6 -0
- package/dist/cjs/commands/run.cjs +148 -0
- package/dist/cjs/commands/run.js +116 -0
- package/dist/cjs/commands/run.js.map +6 -0
- package/dist/cjs/commands/run.native.js +140 -0
- package/dist/cjs/commands/run.native.js.map +6 -0
- package/dist/cjs/commands/script.cjs +379 -0
- package/dist/cjs/commands/script.js +339 -0
- package/dist/cjs/commands/script.js.map +6 -0
- package/dist/cjs/commands/script.native.js +449 -0
- package/dist/cjs/commands/script.native.js.map +6 -0
- package/dist/cjs/commands/sync.cjs +190 -0
- package/dist/cjs/commands/sync.js +168 -0
- package/dist/cjs/commands/sync.js.map +6 -0
- package/dist/cjs/commands/sync.native.js +211 -0
- package/dist/cjs/commands/sync.native.js.map +6 -0
- package/dist/cjs/constants/ascii.cjs +36 -0
- package/dist/cjs/constants/ascii.js +30 -0
- package/dist/cjs/constants/ascii.js.map +6 -0
- package/dist/cjs/constants/ascii.native.js +36 -0
- package/dist/cjs/constants/ascii.native.js.map +6 -0
- package/dist/cjs/index.cjs +64 -0
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/index.js.map +6 -0
- package/dist/cjs/index.native.js +94 -0
- package/dist/cjs/index.native.js.map +6 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +6 -0
- package/dist/cjs/types.native.js +15 -0
- package/dist/cjs/types.native.js.map +6 -0
- package/dist/cjs/utils/env-categories.cjs +272 -0
- package/dist/cjs/utils/env-categories.js +296 -0
- package/dist/cjs/utils/env-categories.js.map +6 -0
- package/dist/cjs/utils/env-categories.native.js +317 -0
- package/dist/cjs/utils/env-categories.native.js.map +6 -0
- package/dist/cjs/utils/env-setup.cjs +181 -0
- package/dist/cjs/utils/env-setup.js +190 -0
- package/dist/cjs/utils/env-setup.js.map +6 -0
- package/dist/cjs/utils/env-setup.native.js +264 -0
- package/dist/cjs/utils/env-setup.native.js.map +6 -0
- package/dist/cjs/utils/env.cjs +118 -0
- package/dist/cjs/utils/env.js +97 -0
- package/dist/cjs/utils/env.js.map +6 -0
- package/dist/cjs/utils/env.native.js +128 -0
- package/dist/cjs/utils/env.native.js.map +6 -0
- package/dist/cjs/utils/files.cjs +215 -0
- package/dist/cjs/utils/files.js +164 -0
- package/dist/cjs/utils/files.js.map +6 -0
- package/dist/cjs/utils/files.native.js +266 -0
- package/dist/cjs/utils/files.native.js.map +6 -0
- package/dist/cjs/utils/parallel-runner.cjs +99 -0
- package/dist/cjs/utils/parallel-runner.js +84 -0
- package/dist/cjs/utils/parallel-runner.js.map +6 -0
- package/dist/cjs/utils/parallel-runner.native.js +123 -0
- package/dist/cjs/utils/parallel-runner.native.js.map +6 -0
- package/dist/cjs/utils/ports.cjs +101 -0
- package/dist/cjs/utils/ports.js +81 -0
- package/dist/cjs/utils/ports.js.map +6 -0
- package/dist/cjs/utils/ports.native.js +130 -0
- package/dist/cjs/utils/ports.native.js.map +6 -0
- package/dist/cjs/utils/prerequisites.cjs +119 -0
- package/dist/cjs/utils/prerequisites.js +107 -0
- package/dist/cjs/utils/prerequisites.js.map +6 -0
- package/dist/cjs/utils/prerequisites.native.js +127 -0
- package/dist/cjs/utils/prerequisites.native.js.map +6 -0
- package/dist/cjs/utils/prompts.cjs +161 -0
- package/dist/cjs/utils/prompts.js +162 -0
- package/dist/cjs/utils/prompts.js.map +6 -0
- package/dist/cjs/utils/prompts.native.js +179 -0
- package/dist/cjs/utils/prompts.native.js.map +6 -0
- package/dist/cjs/utils/script-listing.cjs +113 -0
- package/dist/cjs/utils/script-listing.js +108 -0
- package/dist/cjs/utils/script-listing.js.map +6 -0
- package/dist/cjs/utils/script-listing.native.js +174 -0
- package/dist/cjs/utils/script-listing.native.js.map +6 -0
- package/dist/cjs/utils/sync.cjs +85 -0
- package/dist/cjs/utils/sync.js +70 -0
- package/dist/cjs/utils/sync.js.map +6 -0
- package/dist/cjs/utils/sync.native.js +84 -0
- package/dist/cjs/utils/sync.native.js.map +6 -0
- package/dist/cjs/utils/welcome.cjs +50 -0
- package/dist/cjs/utils/welcome.js +42 -0
- package/dist/cjs/utils/welcome.js.map +6 -0
- package/dist/cjs/utils/welcome.native.js +47 -0
- package/dist/cjs/utils/welcome.native.js.map +6 -0
- package/dist/esm/cli.js +79 -0
- package/dist/esm/cli.js.map +6 -0
- package/dist/esm/cli.mjs +71 -0
- package/dist/esm/cli.mjs.map +1 -0
- package/dist/esm/cli.native.js +69 -0
- package/dist/esm/cli.native.js.map +1 -0
- package/dist/esm/commands/changed.js +194 -0
- package/dist/esm/commands/changed.js.map +6 -0
- package/dist/esm/commands/changed.mjs +178 -0
- package/dist/esm/commands/changed.mjs.map +1 -0
- package/dist/esm/commands/changed.native.js +273 -0
- package/dist/esm/commands/changed.native.js.map +1 -0
- package/dist/esm/commands/docs.js +306 -0
- package/dist/esm/commands/docs.js.map +6 -0
- package/dist/esm/commands/docs.mjs +353 -0
- package/dist/esm/commands/docs.mjs.map +1 -0
- package/dist/esm/commands/docs.native.js +516 -0
- package/dist/esm/commands/docs.native.js.map +1 -0
- package/dist/esm/commands/env-setup.js +56 -0
- package/dist/esm/commands/env-setup.js.map +6 -0
- package/dist/esm/commands/env-setup.mjs +56 -0
- package/dist/esm/commands/env-setup.mjs.map +1 -0
- package/dist/esm/commands/env-setup.native.js +59 -0
- package/dist/esm/commands/env-setup.native.js.map +1 -0
- package/dist/esm/commands/onboard.js +645 -0
- package/dist/esm/commands/onboard.js.map +6 -0
- package/dist/esm/commands/onboard.mjs +445 -0
- package/dist/esm/commands/onboard.mjs.map +1 -0
- package/dist/esm/commands/onboard.native.js +584 -0
- package/dist/esm/commands/onboard.native.js.map +1 -0
- package/dist/esm/commands/run.js +95 -0
- package/dist/esm/commands/run.js.map +6 -0
- package/dist/esm/commands/run.mjs +114 -0
- package/dist/esm/commands/run.mjs.map +1 -0
- package/dist/esm/commands/run.native.js +133 -0
- package/dist/esm/commands/run.native.js.map +1 -0
- package/dist/esm/commands/script.js +338 -0
- package/dist/esm/commands/script.js.map +6 -0
- package/dist/esm/commands/script.mjs +336 -0
- package/dist/esm/commands/script.mjs.map +1 -0
- package/dist/esm/commands/script.native.js +445 -0
- package/dist/esm/commands/script.native.js.map +1 -0
- package/dist/esm/commands/sync.js +158 -0
- package/dist/esm/commands/sync.js.map +6 -0
- package/dist/esm/commands/sync.mjs +155 -0
- package/dist/esm/commands/sync.mjs.map +1 -0
- package/dist/esm/commands/sync.native.js +173 -0
- package/dist/esm/commands/sync.native.js.map +1 -0
- package/dist/esm/constants/ascii.js +14 -0
- package/dist/esm/constants/ascii.js.map +6 -0
- package/dist/esm/constants/ascii.mjs +12 -0
- package/dist/esm/constants/ascii.mjs.map +1 -0
- package/dist/esm/constants/ascii.native.js +12 -0
- package/dist/esm/constants/ascii.native.js.map +1 -0
- package/dist/esm/index.js +83 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/index.mjs +7 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +7 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +6 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/dist/esm/utils/env-categories.js +272 -0
- package/dist/esm/utils/env-categories.js.map +6 -0
- package/dist/esm/utils/env-categories.mjs +233 -0
- package/dist/esm/utils/env-categories.mjs.map +1 -0
- package/dist/esm/utils/env-categories.native.js +246 -0
- package/dist/esm/utils/env-categories.native.js.map +1 -0
- package/dist/esm/utils/env-setup.js +173 -0
- package/dist/esm/utils/env-setup.js.map +6 -0
- package/dist/esm/utils/env-setup.mjs +146 -0
- package/dist/esm/utils/env-setup.mjs.map +1 -0
- package/dist/esm/utils/env-setup.native.js +243 -0
- package/dist/esm/utils/env-setup.native.js.map +1 -0
- package/dist/esm/utils/env.js +83 -0
- package/dist/esm/utils/env.js.map +6 -0
- package/dist/esm/utils/env.mjs +90 -0
- package/dist/esm/utils/env.mjs.map +1 -0
- package/dist/esm/utils/env.native.js +99 -0
- package/dist/esm/utils/env.native.js.map +1 -0
- package/dist/esm/utils/files.js +150 -0
- package/dist/esm/utils/files.js.map +6 -0
- package/dist/esm/utils/files.mjs +187 -0
- package/dist/esm/utils/files.mjs.map +1 -0
- package/dist/esm/utils/files.native.js +247 -0
- package/dist/esm/utils/files.native.js.map +1 -0
- package/dist/esm/utils/parallel-runner.js +69 -0
- package/dist/esm/utils/parallel-runner.js.map +6 -0
- package/dist/esm/utils/parallel-runner.mjs +76 -0
- package/dist/esm/utils/parallel-runner.mjs.map +1 -0
- package/dist/esm/utils/parallel-runner.native.js +109 -0
- package/dist/esm/utils/parallel-runner.native.js.map +1 -0
- package/dist/esm/utils/ports.js +65 -0
- package/dist/esm/utils/ports.js.map +6 -0
- package/dist/esm/utils/ports.mjs +74 -0
- package/dist/esm/utils/ports.mjs.map +1 -0
- package/dist/esm/utils/ports.native.js +93 -0
- package/dist/esm/utils/ports.native.js.map +1 -0
- package/dist/esm/utils/prerequisites.js +91 -0
- package/dist/esm/utils/prerequisites.js.map +6 -0
- package/dist/esm/utils/prerequisites.mjs +91 -0
- package/dist/esm/utils/prerequisites.mjs.map +1 -0
- package/dist/esm/utils/prerequisites.native.js +97 -0
- package/dist/esm/utils/prerequisites.native.js.map +1 -0
- package/dist/esm/utils/prompts.js +139 -0
- package/dist/esm/utils/prompts.js.map +6 -0
- package/dist/esm/utils/prompts.mjs +112 -0
- package/dist/esm/utils/prompts.mjs.map +1 -0
- package/dist/esm/utils/prompts.native.js +115 -0
- package/dist/esm/utils/prompts.native.js.map +1 -0
- package/dist/esm/utils/script-listing.js +91 -0
- package/dist/esm/utils/script-listing.js.map +6 -0
- package/dist/esm/utils/script-listing.mjs +76 -0
- package/dist/esm/utils/script-listing.mjs.map +1 -0
- package/dist/esm/utils/script-listing.native.js +151 -0
- package/dist/esm/utils/script-listing.native.js.map +1 -0
- package/dist/esm/utils/sync.js +50 -0
- package/dist/esm/utils/sync.js.map +6 -0
- package/dist/esm/utils/sync.mjs +48 -0
- package/dist/esm/utils/sync.mjs.map +1 -0
- package/dist/esm/utils/sync.native.js +53 -0
- package/dist/esm/utils/sync.native.js.map +1 -0
- package/dist/esm/utils/welcome.js +21 -0
- package/dist/esm/utils/welcome.js.map +6 -0
- package/dist/esm/utils/welcome.mjs +15 -0
- package/dist/esm/utils/welcome.mjs.map +1 -0
- package/dist/esm/utils/welcome.native.js +18 -0
- package/dist/esm/utils/welcome.native.js.map +1 -0
- package/docs/aggregates.md +579 -0
- package/docs/cloudflare-dev-tunnel.md +41 -0
- package/docs/database.md +203 -0
- package/docs/docs.md +8 -0
- package/docs/emitters.md +562 -0
- package/docs/hot-updater.md +223 -0
- package/docs/native-hot-update.md +252 -0
- package/docs/one-components.md +234 -0
- package/docs/one-hooks.md +570 -0
- package/docs/one-routes.md +660 -0
- package/docs/package-json.md +115 -0
- package/docs/react-native-navigation-flow.md +184 -0
- package/docs/scripts.md +147 -0
- package/docs/sync-prompt.md +208 -0
- package/docs/tamagui.md +478 -0
- package/docs/testing-integration.md +564 -0
- package/docs/triggers.md +450 -0
- package/docs/zero.md +719 -0
- package/package.json +76 -0
- package/scripts/seed.ts +209 -0
- package/src/cli.ts +147 -0
- package/src/commands/changed.ts +313 -0
- package/src/commands/docs.ts +582 -0
- package/src/commands/env-setup.ts +69 -0
- package/src/commands/onboard.ts +1391 -0
- package/src/commands/run.ts +173 -0
- package/src/commands/script.ts +587 -0
- package/src/commands/sync.ts +305 -0
- package/src/constants/ascii.ts +17 -0
- package/src/index.ts +63 -0
- package/src/types.ts +59 -0
- package/src/utils/env-categories.ts +245 -0
- package/src/utils/env-setup.ts +338 -0
- package/src/utils/env.ts +127 -0
- package/src/utils/files.ts +302 -0
- package/src/utils/parallel-runner.ts +129 -0
- package/src/utils/ports.ts +77 -0
- package/src/utils/prerequisites.ts +137 -0
- package/src/utils/prompts.ts +197 -0
- package/src/utils/script-listing.ts +214 -0
- package/src/utils/sync.ts +101 -0
- package/src/withOpSqliteStatic.cjs +51 -0
- package/types/cli.d.ts +7 -0
- package/types/cli.d.ts.map +1 -0
- package/types/commands/changed.d.ts +14 -0
- package/types/commands/changed.d.ts.map +1 -0
- package/types/commands/docs.d.ts +5 -0
- package/types/commands/docs.d.ts.map +1 -0
- package/types/commands/env-setup.d.ts +25 -0
- package/types/commands/env-setup.d.ts.map +1 -0
- package/types/commands/onboard.d.ts +16 -0
- package/types/commands/onboard.d.ts.map +1 -0
- package/types/commands/run.d.ts +8 -0
- package/types/commands/run.d.ts.map +1 -0
- package/types/commands/script.d.ts +28 -0
- package/types/commands/script.d.ts.map +1 -0
- package/types/commands/sync.d.ts +5 -0
- package/types/commands/sync.d.ts.map +1 -0
- package/types/constants/ascii.d.ts +6 -0
- package/types/constants/ascii.d.ts.map +1 -0
- package/types/index.d.ts +12 -0
- package/types/index.d.ts.map +1 -0
- package/types/types.d.ts +54 -0
- package/types/types.d.ts.map +1 -0
- package/types/utils/env-categories.d.ts +8 -0
- package/types/utils/env-categories.d.ts.map +1 -0
- package/types/utils/env-setup.d.ts +10 -0
- package/types/utils/env-setup.d.ts.map +1 -0
- package/types/utils/env.d.ts +19 -0
- package/types/utils/env.d.ts.map +1 -0
- package/types/utils/files.d.ts +47 -0
- package/types/utils/files.d.ts.map +1 -0
- package/types/utils/parallel-runner.d.ts +15 -0
- package/types/utils/parallel-runner.d.ts.map +1 -0
- package/types/utils/ports.d.ts +16 -0
- package/types/utils/ports.d.ts.map +1 -0
- package/types/utils/prerequisites.d.ts +11 -0
- package/types/utils/prerequisites.d.ts.map +1 -0
- package/types/utils/prompts.d.ts +30 -0
- package/types/utils/prompts.d.ts.map +1 -0
- package/types/utils/script-listing.d.ts +7 -0
- package/types/utils/script-listing.d.ts.map +1 -0
- package/types/utils/sync.d.ts +16 -0
- package/types/utils/sync.d.ts.map +1 -0
- package/types/utils/welcome.d.ts +6 -0
- package/types/utils/welcome.d.ts.map +1 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import { resolve } from 'node:path'
|
|
3
|
+
|
|
4
|
+
import * as clack from '@clack/prompts'
|
|
5
|
+
import pc from 'picocolors'
|
|
6
|
+
|
|
7
|
+
import { updateEnvVariable, readEnvVariable, envFileExists, copyEnvFile } from './env'
|
|
8
|
+
import {
|
|
9
|
+
envCategories,
|
|
10
|
+
getRequiredCategories,
|
|
11
|
+
getOptionalCategories,
|
|
12
|
+
} from './env-categories'
|
|
13
|
+
|
|
14
|
+
import type { EnvCategory, EnvVariable } from '../types'
|
|
15
|
+
|
|
16
|
+
interface SetupOptions {
|
|
17
|
+
skipOptional?: boolean
|
|
18
|
+
envFile?: string
|
|
19
|
+
onlyCategory?: string
|
|
20
|
+
interactive?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function setupProductionEnv(
|
|
24
|
+
cwd: string,
|
|
25
|
+
options: SetupOptions = {}
|
|
26
|
+
): Promise<boolean> {
|
|
27
|
+
const envFile = options.envFile || '.env.production'
|
|
28
|
+
const fullPath = resolve(cwd, envFile)
|
|
29
|
+
|
|
30
|
+
// set up interrupt handler
|
|
31
|
+
const cleanup = () => {
|
|
32
|
+
console.info('\n' + pc.yellow('Setup interrupted. You can resume anytime with:'))
|
|
33
|
+
console.info(pc.cyan(' bun takeout env:setup'))
|
|
34
|
+
console.info(
|
|
35
|
+
pc.gray('\nNote: All environment variables are optional for local development.')
|
|
36
|
+
)
|
|
37
|
+
process.exit(0)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
process.on('SIGINT', cleanup)
|
|
41
|
+
process.on('SIGTERM', cleanup)
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
clack.intro(pc.bgCyan(pc.black(' Production Environment Setup ')))
|
|
45
|
+
|
|
46
|
+
console.info(pc.gray('All environment variables are optional.'))
|
|
47
|
+
console.info(pc.gray('You can skip any section or re-run this setup anytime.\n'))
|
|
48
|
+
|
|
49
|
+
// check if .env.production exists, if not create from example
|
|
50
|
+
if (!envFileExists(cwd, envFile)) {
|
|
51
|
+
const createFile = await clack.confirm({
|
|
52
|
+
message: `${envFile} doesn't exist. Create it from example?`,
|
|
53
|
+
initialValue: true,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
if (clack.isCancel(createFile) || !createFile) {
|
|
57
|
+
clack.cancel('Setup cancelled')
|
|
58
|
+
process.removeListener('SIGINT', cleanup)
|
|
59
|
+
process.removeListener('SIGTERM', cleanup)
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const exampleFile = '.env.production.example'
|
|
64
|
+
if (envFileExists(cwd, exampleFile)) {
|
|
65
|
+
copyEnvFile(cwd, exampleFile, envFile)
|
|
66
|
+
console.info(pc.green(`✓ Created ${envFile} from example\n`))
|
|
67
|
+
} else {
|
|
68
|
+
// create empty file
|
|
69
|
+
writeFileSync(fullPath, '# Production Environment Variables\n')
|
|
70
|
+
console.info(pc.green(`✓ Created empty ${envFile}\n`))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// filter categories if specific one requested
|
|
75
|
+
let categoriesToSetup = options.onlyCategory
|
|
76
|
+
? envCategories.filter((cat) => cat.id === options.onlyCategory)
|
|
77
|
+
: envCategories
|
|
78
|
+
|
|
79
|
+
if (categoriesToSetup.length === 0) {
|
|
80
|
+
clack.cancel(`Category "${options.onlyCategory}" not found`)
|
|
81
|
+
process.removeListener('SIGINT', cleanup)
|
|
82
|
+
process.removeListener('SIGTERM', cleanup)
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ask about setting up production env
|
|
87
|
+
if (options.interactive !== false && !options.onlyCategory) {
|
|
88
|
+
const setupProd = await clack.confirm({
|
|
89
|
+
message: 'Do you want to set up production environment variables?',
|
|
90
|
+
initialValue: false,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
if (clack.isCancel(setupProd) || !setupProd) {
|
|
94
|
+
clack.note(
|
|
95
|
+
`You can set up production environment later with:\n${pc.cyan('bun takeout env:setup')}`,
|
|
96
|
+
pc.yellow('Skipping production setup')
|
|
97
|
+
)
|
|
98
|
+
process.removeListener('SIGINT', cleanup)
|
|
99
|
+
process.removeListener('SIGTERM', cleanup)
|
|
100
|
+
return true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// process each category
|
|
105
|
+
for (const category of categoriesToSetup) {
|
|
106
|
+
const shouldSetup = await setupCategory(category, envFile, cwd, options)
|
|
107
|
+
if (!shouldSetup) {
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// summary
|
|
113
|
+
const configuredVars: string[] = []
|
|
114
|
+
const skippedVars: string[] = []
|
|
115
|
+
|
|
116
|
+
for (const category of categoriesToSetup) {
|
|
117
|
+
for (const variable of category.variables) {
|
|
118
|
+
const value = readEnvVariable(cwd, variable.key, envFile)
|
|
119
|
+
if (value && value !== '' && !value.includes('your-')) {
|
|
120
|
+
configuredVars.push(variable.key)
|
|
121
|
+
} else if (variable.required) {
|
|
122
|
+
skippedVars.push(variable.key)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (configuredVars.length > 0) {
|
|
128
|
+
clack.outro(pc.green('✓ Environment setup complete!'))
|
|
129
|
+
console.info(
|
|
130
|
+
pc.gray(`\nConfigured ${configuredVars.length} variables in ${envFile}`)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if (skippedVars.length > 0) {
|
|
134
|
+
console.info(
|
|
135
|
+
pc.yellow(
|
|
136
|
+
`\nNote: Some required variables were skipped. You'll need to configure these before deploying:`
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
skippedVars.forEach((v) => console.info(pc.gray(` - ${v}`)))
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.info(pc.cyan('\nYou can re-run this setup anytime with:'))
|
|
143
|
+
console.info(pc.gray(' bun takeout env:setup'))
|
|
144
|
+
console.info(pc.cyan('\nOr set up specific categories:'))
|
|
145
|
+
console.info(pc.gray(' bun takeout env:setup --category aws'))
|
|
146
|
+
console.info(pc.gray(' bun takeout env:setup --category apple'))
|
|
147
|
+
} else {
|
|
148
|
+
clack.outro(pc.yellow('No variables configured'))
|
|
149
|
+
console.info(pc.gray('\nYou can re-run this setup anytime with:'))
|
|
150
|
+
console.info(pc.gray(' bun takeout env:setup'))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
process.removeListener('SIGINT', cleanup)
|
|
154
|
+
process.removeListener('SIGTERM', cleanup)
|
|
155
|
+
return true
|
|
156
|
+
} catch (error) {
|
|
157
|
+
process.removeListener('SIGINT', cleanup)
|
|
158
|
+
process.removeListener('SIGTERM', cleanup)
|
|
159
|
+
if (error instanceof Error && error.message.includes('cancelled')) {
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
throw error
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function setupCategory(
|
|
167
|
+
category: EnvCategory,
|
|
168
|
+
envFile: string,
|
|
169
|
+
cwd: string,
|
|
170
|
+
options: SetupOptions
|
|
171
|
+
): Promise<boolean> {
|
|
172
|
+
const spinner = clack.spinner()
|
|
173
|
+
|
|
174
|
+
// build category prompt message
|
|
175
|
+
let message = `Set up ${pc.bold(category.name)}?`
|
|
176
|
+
if (!category.required) {
|
|
177
|
+
message += pc.gray(' (optional)')
|
|
178
|
+
}
|
|
179
|
+
if (category.setupTime) {
|
|
180
|
+
message += pc.yellow(` ${category.setupTime}`)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
console.info('') // add spacing
|
|
184
|
+
const setupCategory = await clack.confirm({
|
|
185
|
+
message,
|
|
186
|
+
initialValue: category.required,
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
if (clack.isCancel(setupCategory) || !setupCategory) {
|
|
190
|
+
console.info(pc.gray(` Skipping ${category.name}`))
|
|
191
|
+
return false
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
console.info(pc.gray(`\n${category.description}\n`))
|
|
195
|
+
|
|
196
|
+
// process each variable in the category
|
|
197
|
+
for (const variable of category.variables) {
|
|
198
|
+
await setupVariable(variable, envFile, cwd)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return true
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function setupVariable(
|
|
205
|
+
variable: EnvVariable,
|
|
206
|
+
envFile: string,
|
|
207
|
+
cwd: string
|
|
208
|
+
): Promise<void> {
|
|
209
|
+
// check if already configured
|
|
210
|
+
const existingValue = readEnvVariable(cwd, variable.key, envFile)
|
|
211
|
+
const hasValue =
|
|
212
|
+
existingValue && existingValue !== '' && !existingValue.includes('your-')
|
|
213
|
+
|
|
214
|
+
console.info('') // spacing
|
|
215
|
+
console.info(pc.bold(variable.label))
|
|
216
|
+
console.info(pc.gray(variable.description))
|
|
217
|
+
|
|
218
|
+
if (hasValue) {
|
|
219
|
+
const update = await clack.confirm({
|
|
220
|
+
message: `${pc.green('✓')} Already configured. Update?`,
|
|
221
|
+
initialValue: false,
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
if (clack.isCancel(update) || !update) {
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// show instructions
|
|
230
|
+
console.info('')
|
|
231
|
+
console.info(pc.cyan('Instructions:'))
|
|
232
|
+
variable.instructions.split('\n').forEach((line) => {
|
|
233
|
+
console.info(pc.gray(` ${line}`))
|
|
234
|
+
})
|
|
235
|
+
console.info('')
|
|
236
|
+
|
|
237
|
+
// handle different input types
|
|
238
|
+
let value: string | undefined
|
|
239
|
+
|
|
240
|
+
if (variable.generator) {
|
|
241
|
+
const generate = await clack.confirm({
|
|
242
|
+
message: `Generate ${variable.label} automatically?`,
|
|
243
|
+
initialValue: true,
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
if (!clack.isCancel(generate) && generate) {
|
|
247
|
+
value = variable.generator()
|
|
248
|
+
console.info(pc.green(`✓ Generated ${variable.label}`))
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!value) {
|
|
253
|
+
if (variable.type === 'multiline') {
|
|
254
|
+
console.info(pc.gray('Paste content (press Enter twice when done):'))
|
|
255
|
+
value = await readMultilineInput()
|
|
256
|
+
} else if (variable.type === 'secret') {
|
|
257
|
+
const result = await clack.password({
|
|
258
|
+
message: `Enter ${variable.label}:`,
|
|
259
|
+
mask: '*',
|
|
260
|
+
})
|
|
261
|
+
if (!clack.isCancel(result)) {
|
|
262
|
+
value = result
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
const result = await clack.text({
|
|
266
|
+
message: `Enter ${variable.label}:`,
|
|
267
|
+
placeholder: variable.placeholder,
|
|
268
|
+
defaultValue: variable.default,
|
|
269
|
+
validate: (val) => {
|
|
270
|
+
if (variable.required && !val) {
|
|
271
|
+
return 'This field is required'
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
})
|
|
275
|
+
if (!clack.isCancel(result)) {
|
|
276
|
+
value = result
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (value && !clack.isCancel(value)) {
|
|
282
|
+
updateEnvVariable(cwd, variable.key, value, envFile)
|
|
283
|
+
console.info(pc.green(`✓ Saved ${variable.key}`))
|
|
284
|
+
} else if (variable.required) {
|
|
285
|
+
console.info(pc.yellow(`⚠ Skipped required variable: ${variable.key}`))
|
|
286
|
+
} else {
|
|
287
|
+
console.info(pc.gray(` Skipped ${variable.key}`))
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async function readMultilineInput(): Promise<string> {
|
|
292
|
+
return new Promise((resolve) => {
|
|
293
|
+
const lines: string[] = []
|
|
294
|
+
let emptyLineCount = 0
|
|
295
|
+
|
|
296
|
+
const reader = process.stdin
|
|
297
|
+
reader.setEncoding('utf8')
|
|
298
|
+
|
|
299
|
+
const onData = (chunk: string) => {
|
|
300
|
+
const chunkLines = chunk.split('\n')
|
|
301
|
+
for (const line of chunkLines) {
|
|
302
|
+
if (line === '') {
|
|
303
|
+
emptyLineCount++
|
|
304
|
+
if (emptyLineCount >= 2) {
|
|
305
|
+
reader.removeListener('data', onData)
|
|
306
|
+
resolve(lines.join('\n'))
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
if (emptyLineCount === 1) {
|
|
311
|
+
lines.push('') // add the single empty line
|
|
312
|
+
}
|
|
313
|
+
emptyLineCount = 0
|
|
314
|
+
lines.push(line)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
reader.on('data', onData)
|
|
320
|
+
})
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export function listCategories(): void {
|
|
324
|
+
console.info(pc.bold('\nAvailable environment categories:\n'))
|
|
325
|
+
|
|
326
|
+
for (const category of envCategories) {
|
|
327
|
+
const status = category.required ? pc.red('required') : pc.gray('optional')
|
|
328
|
+
console.info(` ${pc.cyan(category.id.padEnd(12))} - ${category.name} ${status}`)
|
|
329
|
+
console.info(` ${pc.gray(category.description)}`)
|
|
330
|
+
if (category.setupTime) {
|
|
331
|
+
console.info(` ${pc.yellow(category.setupTime)}`)
|
|
332
|
+
}
|
|
333
|
+
console.info('')
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
console.info(pc.gray('Run setup for a specific category:'))
|
|
337
|
+
console.info(pc.cyan(' bun takeout env:setup --category <id>\n'))
|
|
338
|
+
}
|
package/src/utils/env.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment file operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { randomBytes } from 'node:crypto'
|
|
6
|
+
import { copyFileSync, existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
7
|
+
import { join } from 'node:path'
|
|
8
|
+
|
|
9
|
+
export function generateSecret(length = 32): string {
|
|
10
|
+
return randomBytes(length).toString('hex')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function envFileExists(cwd: string, filename = '.env'): boolean {
|
|
14
|
+
return existsSync(join(cwd, filename))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function copyEnvFile(
|
|
18
|
+
cwd: string,
|
|
19
|
+
source: string,
|
|
20
|
+
target: string
|
|
21
|
+
): { success: boolean; error?: string } {
|
|
22
|
+
const sourcePath = join(cwd, source)
|
|
23
|
+
const targetPath = join(cwd, target)
|
|
24
|
+
|
|
25
|
+
if (!existsSync(sourcePath)) {
|
|
26
|
+
return { success: false, error: `Source file ${source} not found` }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (existsSync(targetPath)) {
|
|
30
|
+
return { success: false, error: `Target file ${target} already exists` }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
copyFileSync(sourcePath, targetPath)
|
|
35
|
+
return { success: true }
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function updateEnvVariable(
|
|
45
|
+
cwd: string,
|
|
46
|
+
key: string,
|
|
47
|
+
value: string,
|
|
48
|
+
filename = '.env'
|
|
49
|
+
): { success: boolean; error?: string } {
|
|
50
|
+
const envPath = join(cwd, filename)
|
|
51
|
+
|
|
52
|
+
if (!existsSync(envPath)) {
|
|
53
|
+
return { success: false, error: `${filename} not found` }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
let content = readFileSync(envPath, 'utf-8')
|
|
58
|
+
|
|
59
|
+
// Check if key exists
|
|
60
|
+
const keyRegex = new RegExp(`^${key}=.*$`, 'm')
|
|
61
|
+
|
|
62
|
+
if (keyRegex.test(content)) {
|
|
63
|
+
// Replace existing value
|
|
64
|
+
content = content.replace(keyRegex, `${key}=${value}`)
|
|
65
|
+
} else {
|
|
66
|
+
// Append new key-value
|
|
67
|
+
content = content.trimEnd() + `\n${key}=${value}\n`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
writeFileSync(envPath, content, 'utf-8')
|
|
71
|
+
return { success: true }
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function createEnvLocal(cwd: string): { success: boolean; error?: string } {
|
|
81
|
+
const envLocalPath = join(cwd, '.env.local')
|
|
82
|
+
|
|
83
|
+
if (existsSync(envLocalPath)) {
|
|
84
|
+
return { success: true } // Already exists, that's fine
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const template = `# Local environment overrides
|
|
88
|
+
# This file is gitignored and never committed
|
|
89
|
+
# Add your personal secrets and local configuration here
|
|
90
|
+
# These values override .env
|
|
91
|
+
|
|
92
|
+
# Example:
|
|
93
|
+
# BETTER_AUTH_SECRET=your-secret-here
|
|
94
|
+
# AWS_ACCESS_KEY_ID=your-key-here
|
|
95
|
+
`
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
writeFileSync(envLocalPath, template, 'utf-8')
|
|
99
|
+
return { success: true }
|
|
100
|
+
} catch (error) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function readEnvVariable(
|
|
109
|
+
cwd: string,
|
|
110
|
+
key: string,
|
|
111
|
+
filename = '.env'
|
|
112
|
+
): string | null {
|
|
113
|
+
const envPath = join(cwd, filename)
|
|
114
|
+
|
|
115
|
+
if (!existsSync(envPath)) {
|
|
116
|
+
return null
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
const content = readFileSync(envPath, 'utf-8')
|
|
121
|
+
const keyRegex = new RegExp(`^${key}=(.*)$`, 'm')
|
|
122
|
+
const match = content.match(keyRegex)
|
|
123
|
+
return match?.[1]?.trim().replace(/^["']|["']$/g, '') || null
|
|
124
|
+
} catch {
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
127
|
+
}
|