@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,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync command - sync fork with upstream Takeout repository
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { execSync, spawn, spawnSync } from 'node:child_process'
|
|
6
|
+
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs'
|
|
7
|
+
import { tmpdir } from 'node:os'
|
|
8
|
+
import { dirname, join, parse } from 'node:path'
|
|
9
|
+
import { fileURLToPath } from 'node:url'
|
|
10
|
+
|
|
11
|
+
import { defineCommand } from 'citty'
|
|
12
|
+
import pc from 'picocolors'
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
confirmContinue,
|
|
16
|
+
promptSelect,
|
|
17
|
+
showError,
|
|
18
|
+
showInfo,
|
|
19
|
+
showStep,
|
|
20
|
+
showSuccess,
|
|
21
|
+
} from '../utils/prompts'
|
|
22
|
+
|
|
23
|
+
const UPSTREAM_REPO = 'tamagui/takeout3'
|
|
24
|
+
const UPSTREAM_REMOTE = 'takeout-upstream'
|
|
25
|
+
const TAKEOUT_FILE = '.takeout'
|
|
26
|
+
|
|
27
|
+
function getSyncPrompt(): string {
|
|
28
|
+
try {
|
|
29
|
+
// find package root by looking for package.json
|
|
30
|
+
const currentDir = dirname(fileURLToPath(import.meta.url))
|
|
31
|
+
let packageRoot = currentDir
|
|
32
|
+
|
|
33
|
+
// go up directories until we find package.json with name @take-out/cli
|
|
34
|
+
while (packageRoot !== parse(packageRoot).root) {
|
|
35
|
+
const pkgPath = join(packageRoot, 'package.json')
|
|
36
|
+
if (existsSync(pkgPath)) {
|
|
37
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))
|
|
38
|
+
if (pkg.name === '@take-out/cli') {
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
packageRoot = dirname(packageRoot)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const promptPath = join(packageRoot, 'docs', 'sync-prompt.md')
|
|
46
|
+
return readFileSync(promptPath, 'utf-8')
|
|
47
|
+
} catch (error) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Could not load sync prompt: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function checkToolAvailable(command: string): boolean {
|
|
55
|
+
try {
|
|
56
|
+
// use 'where' on windows, 'which' on unix
|
|
57
|
+
const checkCmd = process.platform === 'win32' ? 'where' : 'which'
|
|
58
|
+
const result = spawnSync(checkCmd, [command])
|
|
59
|
+
return result.status === 0
|
|
60
|
+
} catch {
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function ensureUpstreamRemote(): boolean {
|
|
66
|
+
try {
|
|
67
|
+
// check if remote exists
|
|
68
|
+
const remotes = execSync('git remote', { encoding: 'utf-8' })
|
|
69
|
+
if (!remotes.includes(UPSTREAM_REMOTE)) {
|
|
70
|
+
execSync(`git remote add ${UPSTREAM_REMOTE} git@github.com:${UPSTREAM_REPO}.git`, {
|
|
71
|
+
stdio: 'pipe',
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
execSync(`git fetch ${UPSTREAM_REMOTE} --quiet`, { stdio: 'pipe' })
|
|
75
|
+
return true
|
|
76
|
+
} catch {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getUpstreamHeadSha(): string | null {
|
|
82
|
+
try {
|
|
83
|
+
const sha = execSync(`git rev-parse ${UPSTREAM_REMOTE}/main`, { encoding: 'utf-8' })
|
|
84
|
+
return sha.trim()
|
|
85
|
+
} catch {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function writeTakeoutConfig(sha: string): void {
|
|
91
|
+
const configPath = join(process.cwd(), TAKEOUT_FILE)
|
|
92
|
+
const date = new Date().toISOString().split('T')[0]
|
|
93
|
+
const content = `# takeout sync tracking file
|
|
94
|
+
# this file tracks the last synced commit from upstream takeout
|
|
95
|
+
sha=${sha}
|
|
96
|
+
date=${date}
|
|
97
|
+
`
|
|
98
|
+
writeFileSync(configPath, content)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const syncCommand = defineCommand({
|
|
102
|
+
meta: {
|
|
103
|
+
name: 'sync',
|
|
104
|
+
description: 'Sync your fork with the latest Takeout repository',
|
|
105
|
+
},
|
|
106
|
+
async run() {
|
|
107
|
+
showStep('Takeout Repository Sync')
|
|
108
|
+
console.info()
|
|
109
|
+
|
|
110
|
+
showInfo('Takeout sync uses AI to intelligently merge upstream changes')
|
|
111
|
+
console.info()
|
|
112
|
+
console.info(pc.gray('How it works:'))
|
|
113
|
+
console.info(pc.gray(' • Analyzes commits from upstream Takeout repository'))
|
|
114
|
+
console.info(pc.gray(' • Determines which changes are relevant to your fork'))
|
|
115
|
+
console.info(pc.gray(' • Applies changes while preserving your customizations'))
|
|
116
|
+
console.info(pc.gray(' • Handles package ejection automatically'))
|
|
117
|
+
console.info(pc.gray(' • Asks for your input when decisions are needed'))
|
|
118
|
+
console.info()
|
|
119
|
+
|
|
120
|
+
// check what tools are available
|
|
121
|
+
const hasClaudeCode = checkToolAvailable('claude')
|
|
122
|
+
const hasCursor = checkToolAvailable('cursor-agent')
|
|
123
|
+
const hasAider = checkToolAvailable('aider')
|
|
124
|
+
|
|
125
|
+
const options: Array<{
|
|
126
|
+
value: string
|
|
127
|
+
label: string
|
|
128
|
+
hint: string
|
|
129
|
+
}> = []
|
|
130
|
+
|
|
131
|
+
if (hasClaudeCode) {
|
|
132
|
+
options.push({
|
|
133
|
+
value: 'claude-code',
|
|
134
|
+
label: 'Claude Code (recommended)',
|
|
135
|
+
hint: 'Run sync automatically with Claude Code CLI',
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (hasCursor) {
|
|
140
|
+
options.push({
|
|
141
|
+
value: 'cursor',
|
|
142
|
+
label: 'Cursor Agent',
|
|
143
|
+
hint: 'Run sync automatically with Cursor CLI',
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (hasAider) {
|
|
148
|
+
options.push({
|
|
149
|
+
value: 'aider',
|
|
150
|
+
label: 'Aider',
|
|
151
|
+
hint: 'Run sync automatically with Aider CLI',
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
options.push({
|
|
156
|
+
value: 'show-prompt',
|
|
157
|
+
label: 'Show prompt (copy & paste manually)',
|
|
158
|
+
hint: 'Display the full prompt to use with any LLM',
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const choice = await promptSelect<string>('How would you like to sync?', options)
|
|
162
|
+
|
|
163
|
+
if (choice === 'cancel') {
|
|
164
|
+
console.info()
|
|
165
|
+
showInfo('Sync cancelled')
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.info()
|
|
170
|
+
|
|
171
|
+
// fetch upstream to get the target SHA before syncing
|
|
172
|
+
console.info(pc.dim('Fetching upstream repository...'))
|
|
173
|
+
if (!ensureUpstreamRemote()) {
|
|
174
|
+
showError('Failed to fetch upstream repository')
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const upstreamSha = getUpstreamHeadSha()
|
|
179
|
+
if (!upstreamSha) {
|
|
180
|
+
showError('Failed to get upstream HEAD SHA')
|
|
181
|
+
return
|
|
182
|
+
}
|
|
183
|
+
console.info(pc.dim(`Target SHA: ${upstreamSha.slice(0, 7)}`))
|
|
184
|
+
console.info()
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
const prompt = getSyncPrompt()
|
|
188
|
+
|
|
189
|
+
if (choice === 'show-prompt') {
|
|
190
|
+
console.info(pc.dim('='.repeat(80)))
|
|
191
|
+
console.info(prompt)
|
|
192
|
+
console.info(pc.dim('='.repeat(80)))
|
|
193
|
+
console.info()
|
|
194
|
+
showInfo('Copy the prompt above and paste it into your preferred LLM')
|
|
195
|
+
console.info()
|
|
196
|
+
console.info(pc.gray('Recommended LLMs:'))
|
|
197
|
+
console.info(pc.gray(' • Claude Code (best for complex instructions)'))
|
|
198
|
+
console.info(pc.gray(' • ChatGPT'))
|
|
199
|
+
console.info(pc.gray(' • Cursor'))
|
|
200
|
+
console.info(pc.gray(' • Aider'))
|
|
201
|
+
console.info()
|
|
202
|
+
} else if (choice === 'claude-code') {
|
|
203
|
+
showInfo('Starting Claude Code with sync prompt...')
|
|
204
|
+
console.info()
|
|
205
|
+
console.info(
|
|
206
|
+
pc.dim(
|
|
207
|
+
'Note: Claude Code will run in headless mode and make changes automatically.'
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
console.info(pc.dim('You will be asked to confirm important decisions.'))
|
|
211
|
+
console.info()
|
|
212
|
+
|
|
213
|
+
const shouldContinue = await confirmContinue('Continue with Claude Code?', true)
|
|
214
|
+
if (!shouldContinue) {
|
|
215
|
+
showInfo('Sync cancelled')
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// write prompt to temp file to avoid shell escaping issues
|
|
220
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'takeout-sync-'))
|
|
221
|
+
const promptFile = join(tempDir, 'prompt.md')
|
|
222
|
+
writeFileSync(promptFile, prompt)
|
|
223
|
+
|
|
224
|
+
// run claude with prompt from stdin
|
|
225
|
+
const claude = spawn('claude', ['-p', '-'], {
|
|
226
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
claude.stdin?.write(prompt)
|
|
230
|
+
claude.stdin?.end()
|
|
231
|
+
|
|
232
|
+
claude.on('close', (code) => {
|
|
233
|
+
console.info()
|
|
234
|
+
if (code === 0) {
|
|
235
|
+
writeTakeoutConfig(upstreamSha)
|
|
236
|
+
showSuccess('Sync completed successfully!')
|
|
237
|
+
console.info(pc.dim(`Updated .takeout to ${upstreamSha.slice(0, 7)}`))
|
|
238
|
+
} else {
|
|
239
|
+
showError(`Claude Code exited with code ${code}`)
|
|
240
|
+
}
|
|
241
|
+
})
|
|
242
|
+
} else if (choice === 'cursor') {
|
|
243
|
+
showInfo('Starting Cursor Agent with sync prompt...')
|
|
244
|
+
console.info()
|
|
245
|
+
|
|
246
|
+
const shouldContinue = await confirmContinue('Continue with Cursor?', true)
|
|
247
|
+
if (!shouldContinue) {
|
|
248
|
+
showInfo('Sync cancelled')
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// run cursor agent with prompt from stdin
|
|
253
|
+
const cursor = spawn('cursor-agent', ['-p', '-'], {
|
|
254
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
cursor.stdin?.write(prompt)
|
|
258
|
+
cursor.stdin?.end()
|
|
259
|
+
|
|
260
|
+
cursor.on('close', (code) => {
|
|
261
|
+
console.info()
|
|
262
|
+
if (code === 0) {
|
|
263
|
+
writeTakeoutConfig(upstreamSha)
|
|
264
|
+
showSuccess('Sync completed successfully!')
|
|
265
|
+
console.info(pc.dim(`Updated .takeout to ${upstreamSha.slice(0, 7)}`))
|
|
266
|
+
} else {
|
|
267
|
+
showError(`Cursor Agent exited with code ${code}`)
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
} else if (choice === 'aider') {
|
|
271
|
+
showInfo('Starting Aider with sync prompt...')
|
|
272
|
+
console.info()
|
|
273
|
+
|
|
274
|
+
const shouldContinue = await confirmContinue('Continue with Aider?', true)
|
|
275
|
+
if (!shouldContinue) {
|
|
276
|
+
showInfo('Sync cancelled')
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// write prompt to temp file for aider
|
|
281
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'takeout-sync-'))
|
|
282
|
+
const promptFile = join(tempDir, 'prompt.md')
|
|
283
|
+
writeFileSync(promptFile, prompt)
|
|
284
|
+
|
|
285
|
+
// run aider with message from file
|
|
286
|
+
const aider = spawn('aider', ['--message-file', promptFile, '--no-stream'], {
|
|
287
|
+
stdio: 'inherit',
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
aider.on('close', (code) => {
|
|
291
|
+
console.info()
|
|
292
|
+
if (code === 0) {
|
|
293
|
+
writeTakeoutConfig(upstreamSha)
|
|
294
|
+
showSuccess('Sync completed successfully!')
|
|
295
|
+
console.info(pc.dim(`Updated .takeout to ${upstreamSha.slice(0, 7)}`))
|
|
296
|
+
} else {
|
|
297
|
+
showError(`Aider exited with code ${code}`)
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
} catch (error) {
|
|
302
|
+
showError(error instanceof Error ? error.message : 'Unknown error')
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ASCII art constants for Takeout branding
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// TAKEOUT in block letters with chinese accent line
|
|
6
|
+
// chinese chars: 麵(noodles) 碼(code) 飯(rice)
|
|
7
|
+
export const TAKEOUT_ASCII = `
|
|
8
|
+
████████╗ █████╗ ██╗ ██╗███████╗ ██████╗ ██╗ ██╗████████╗
|
|
9
|
+
╚══██╔══╝██╔══██╗██║ ██╔╝██╔════╝██╔═══██╗██║ ██║╚══██╔══╝
|
|
10
|
+
██║ ███████║█████╔╝ █████╗ ██║ ██║██║ ██║ ██║
|
|
11
|
+
██║ ██╔══██║██╔═██╗ ██╔══╝ ██║ ██║██║ ██║ ██║
|
|
12
|
+
██║ ██║ ██║██║ ██╗███████╗╚██████╔╝╚██████╔╝ ██║
|
|
13
|
+
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝
|
|
14
|
+
麵 碼 飯
|
|
15
|
+
`.trim()
|
|
16
|
+
|
|
17
|
+
export const WELCOME_BANNER = TAKEOUT_ASCII
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Takeout CLI - Library exports
|
|
3
|
+
*
|
|
4
|
+
* Use these utilities programmatically in your own scripts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Types
|
|
8
|
+
export type * from './types'
|
|
9
|
+
|
|
10
|
+
// Prerequisites checking
|
|
11
|
+
export {
|
|
12
|
+
checkAllPrerequisites,
|
|
13
|
+
checkBun,
|
|
14
|
+
checkDocker,
|
|
15
|
+
checkGit,
|
|
16
|
+
checkNode,
|
|
17
|
+
hasRequiredPrerequisites,
|
|
18
|
+
} from './utils/prerequisites'
|
|
19
|
+
|
|
20
|
+
// Port management
|
|
21
|
+
export {
|
|
22
|
+
checkAllPorts,
|
|
23
|
+
checkPort,
|
|
24
|
+
getConflictingPorts,
|
|
25
|
+
hasPortConflicts,
|
|
26
|
+
TAKEOUT_PORTS,
|
|
27
|
+
} from './utils/ports'
|
|
28
|
+
|
|
29
|
+
// Environment file operations
|
|
30
|
+
export {
|
|
31
|
+
copyEnvFile,
|
|
32
|
+
createEnvLocal,
|
|
33
|
+
envFileExists,
|
|
34
|
+
generateSecret,
|
|
35
|
+
readEnvVariable,
|
|
36
|
+
updateEnvVariable,
|
|
37
|
+
} from './utils/env'
|
|
38
|
+
|
|
39
|
+
// File operations
|
|
40
|
+
export {
|
|
41
|
+
checkOnboarded,
|
|
42
|
+
markOnboarded,
|
|
43
|
+
updateAppConfig,
|
|
44
|
+
updatePackageJson,
|
|
45
|
+
} from './utils/files'
|
|
46
|
+
|
|
47
|
+
// Prompts (for building custom CLIs)
|
|
48
|
+
export {
|
|
49
|
+
confirmContinue,
|
|
50
|
+
displayOutro,
|
|
51
|
+
displayPortConflicts,
|
|
52
|
+
displayPrerequisites,
|
|
53
|
+
displayWelcome,
|
|
54
|
+
promptPassword,
|
|
55
|
+
promptSelect,
|
|
56
|
+
promptText,
|
|
57
|
+
showError,
|
|
58
|
+
showInfo,
|
|
59
|
+
showSpinner,
|
|
60
|
+
showStep,
|
|
61
|
+
showSuccess,
|
|
62
|
+
showWarning,
|
|
63
|
+
} from './utils/prompts'
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface PrerequisiteCheck {
|
|
2
|
+
name: string
|
|
3
|
+
required: boolean
|
|
4
|
+
installed: boolean
|
|
5
|
+
version?: string
|
|
6
|
+
requiredVersion?: string
|
|
7
|
+
message?: string
|
|
8
|
+
installUrl?: string
|
|
9
|
+
recommendation?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PortCheck {
|
|
13
|
+
port: number
|
|
14
|
+
name: string
|
|
15
|
+
inUse: boolean
|
|
16
|
+
pid?: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ProjectIdentity {
|
|
20
|
+
name: string
|
|
21
|
+
bundleId: string
|
|
22
|
+
domain: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface OnboardingConfig {
|
|
26
|
+
skipPrerequisites?: boolean
|
|
27
|
+
skipServices?: boolean
|
|
28
|
+
skipMigrations?: boolean
|
|
29
|
+
autoStart?: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface EnvironmentSetup {
|
|
33
|
+
authSecret: string
|
|
34
|
+
githubClientId?: string
|
|
35
|
+
githubClientSecret?: string
|
|
36
|
+
domain: string
|
|
37
|
+
serverUrl: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface EnvVariable {
|
|
41
|
+
key: string
|
|
42
|
+
label: string
|
|
43
|
+
description: string
|
|
44
|
+
instructions: string
|
|
45
|
+
required: boolean
|
|
46
|
+
type: 'text' | 'secret' | 'multiline'
|
|
47
|
+
default?: string
|
|
48
|
+
placeholder?: string
|
|
49
|
+
generator?: () => string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface EnvCategory {
|
|
53
|
+
id: string
|
|
54
|
+
name: string
|
|
55
|
+
description: string
|
|
56
|
+
required: boolean
|
|
57
|
+
setupTime?: string
|
|
58
|
+
variables: EnvVariable[]
|
|
59
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import pc from 'picocolors'
|
|
2
|
+
|
|
3
|
+
import type { EnvVariable, EnvCategory } from '../types'
|
|
4
|
+
|
|
5
|
+
export const envCategories: EnvCategory[] = [
|
|
6
|
+
{
|
|
7
|
+
id: 'core',
|
|
8
|
+
name: 'Core Configuration',
|
|
9
|
+
description: 'Essential configuration for your production deployment',
|
|
10
|
+
required: true,
|
|
11
|
+
variables: [
|
|
12
|
+
{
|
|
13
|
+
key: 'BETTER_AUTH_SECRET',
|
|
14
|
+
label: 'Authentication Secret',
|
|
15
|
+
description: 'Secret key for session encryption and JWT signing',
|
|
16
|
+
instructions: `Generate a secure random key:\n${pc.cyan('openssl rand -hex 32')}`,
|
|
17
|
+
required: true,
|
|
18
|
+
type: 'secret',
|
|
19
|
+
generator: () => {
|
|
20
|
+
const crypto = require('node:crypto')
|
|
21
|
+
return crypto.randomBytes(32).toString('hex')
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'BETTER_AUTH_URL',
|
|
26
|
+
label: 'Authentication URL',
|
|
27
|
+
description: 'The public URL where your app will be hosted',
|
|
28
|
+
instructions: 'Enter your production domain (e.g., https://your-app.com)',
|
|
29
|
+
required: true,
|
|
30
|
+
type: 'text',
|
|
31
|
+
placeholder: 'https://your-app.com',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: 'ONE_SERVER_URL',
|
|
35
|
+
label: 'Server URL',
|
|
36
|
+
description: 'The URL for your main server',
|
|
37
|
+
instructions: 'Usually the same as your authentication URL',
|
|
38
|
+
required: true,
|
|
39
|
+
type: 'text',
|
|
40
|
+
placeholder: 'https://your-app.com',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
key: 'VITE_PUBLIC_ZERO_SERVER',
|
|
44
|
+
label: 'Zero Sync Server URL',
|
|
45
|
+
description: 'WebSocket server for real-time sync',
|
|
46
|
+
instructions: 'Typically a subdomain like https://zero.your-app.com',
|
|
47
|
+
required: true,
|
|
48
|
+
type: 'text',
|
|
49
|
+
placeholder: 'https://zero.your-app.com',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'database',
|
|
55
|
+
name: 'Database (PostgreSQL)',
|
|
56
|
+
description:
|
|
57
|
+
'Production database configuration - set by deployment platform (SST/uncloud)',
|
|
58
|
+
required: false,
|
|
59
|
+
variables: [
|
|
60
|
+
// Note: ZERO_UPSTREAM_DB, ZERO_CVR_DB, and ZERO_CHANGE_DB are set dynamically
|
|
61
|
+
// by the deployment platform (SST or uncloud) and should NOT be configured here
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'storage',
|
|
66
|
+
name: 'File Storage (S3/R2)',
|
|
67
|
+
description: 'Object storage for user uploads and media files',
|
|
68
|
+
required: false,
|
|
69
|
+
variables: [
|
|
70
|
+
{
|
|
71
|
+
key: 'CLOUDFLARE_R2_ENDPOINT',
|
|
72
|
+
label: 'Storage Endpoint',
|
|
73
|
+
description: 'S3-compatible storage endpoint',
|
|
74
|
+
instructions: `Options:\n${pc.cyan('Cloudflare R2')}: https://[account-id].r2.cloudflarestorage.com\n${pc.cyan('AWS S3')}: https://s3.[region].amazonaws.com\n${pc.cyan('DigitalOcean Spaces')}: https://[region].digitaloceanspaces.com`,
|
|
75
|
+
required: false,
|
|
76
|
+
type: 'text',
|
|
77
|
+
placeholder: 'https://account-id.r2.cloudflarestorage.com',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: 'CLOUDFLARE_R2_ACCESS_KEY',
|
|
81
|
+
label: 'Storage Access Key',
|
|
82
|
+
description: 'Access key ID for your storage service',
|
|
83
|
+
instructions: 'Get this from your storage provider dashboard',
|
|
84
|
+
required: false,
|
|
85
|
+
type: 'text',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: 'CLOUDFLARE_R2_SECRET_KEY',
|
|
89
|
+
label: 'Storage Secret Key',
|
|
90
|
+
description: 'Secret access key for your storage service',
|
|
91
|
+
instructions: 'Keep this secure - it provides full access to your storage',
|
|
92
|
+
required: false,
|
|
93
|
+
type: 'secret',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: 'CLOUDFLARE_R2_PUBLIC_URL',
|
|
97
|
+
label: 'Public Storage URL',
|
|
98
|
+
description: 'Public URL for serving stored files',
|
|
99
|
+
instructions: 'Usually a CDN URL or custom domain pointing to your bucket',
|
|
100
|
+
required: false,
|
|
101
|
+
type: 'text',
|
|
102
|
+
placeholder: 'https://cdn.your-app.com',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'apple',
|
|
108
|
+
name: 'Apple App Store',
|
|
109
|
+
description: 'Configuration for iOS app and push notifications',
|
|
110
|
+
required: false,
|
|
111
|
+
variables: [
|
|
112
|
+
{
|
|
113
|
+
key: 'APNS_TEAM_ID',
|
|
114
|
+
label: 'Apple Team ID',
|
|
115
|
+
description: 'Your Apple Developer Team ID',
|
|
116
|
+
instructions: `Find in Apple Developer Portal:\n1. Go to ${pc.cyan('https://developer.apple.com/account')}\n2. Look for "Team ID" in Membership Details`,
|
|
117
|
+
required: false,
|
|
118
|
+
type: 'text',
|
|
119
|
+
placeholder: 'XXXXXXXXXX',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
key: 'APNS_KEY_ID',
|
|
123
|
+
label: 'APNs Key ID',
|
|
124
|
+
description: 'Push notification authentication key ID',
|
|
125
|
+
instructions: `Create in Apple Developer Portal:\n1. Go to Certificates, Identifiers & Profiles\n2. Keys → Create a Key\n3. Check "Apple Push Notifications service (APNs)"\n4. Download the .p8 file and note the Key ID`,
|
|
126
|
+
required: false,
|
|
127
|
+
type: 'text',
|
|
128
|
+
placeholder: 'XXXXXXXXXX',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
key: 'APNS_KEY',
|
|
132
|
+
label: 'APNs Key Content',
|
|
133
|
+
description: 'Contents of your APNs .p8 key file',
|
|
134
|
+
instructions: 'Paste the entire contents of the .p8 file you downloaded',
|
|
135
|
+
required: false,
|
|
136
|
+
type: 'multiline',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
key: 'APNS_ENDPOINT',
|
|
140
|
+
label: 'APNs Endpoint',
|
|
141
|
+
description: 'Apple Push Notification service endpoint',
|
|
142
|
+
instructions: `Production: ${pc.green('https://api.push.apple.com')}\nSandbox: ${pc.yellow('https://api.sandbox.push.apple.com')}`,
|
|
143
|
+
required: false,
|
|
144
|
+
type: 'text',
|
|
145
|
+
default: 'https://api.push.apple.com',
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: 'email',
|
|
151
|
+
name: 'Email Service',
|
|
152
|
+
description: 'Transactional email configuration',
|
|
153
|
+
required: false,
|
|
154
|
+
variables: [
|
|
155
|
+
{
|
|
156
|
+
key: 'POSTMARK_SERVER_TOKEN',
|
|
157
|
+
label: 'Postmark Server Token',
|
|
158
|
+
description: 'API token for sending emails via Postmark',
|
|
159
|
+
instructions: `Get your token:\n1. Sign up at ${pc.cyan('https://postmarkapp.com')}\n2. Create a Server\n3. Go to Servers → API Tokens\n4. Copy your Server API Token\n\n${pc.yellow('Note: Free tier includes 100 emails/month')}`,
|
|
160
|
+
required: false,
|
|
161
|
+
type: 'text',
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'github',
|
|
167
|
+
name: 'GitHub OAuth',
|
|
168
|
+
description: 'Enable GitHub sign-in for your app',
|
|
169
|
+
required: false,
|
|
170
|
+
variables: [
|
|
171
|
+
{
|
|
172
|
+
key: 'ONECHAT_GITHUB_CLIENT_ID',
|
|
173
|
+
label: 'GitHub OAuth Client ID',
|
|
174
|
+
description: 'Client ID for GitHub OAuth application',
|
|
175
|
+
instructions: `Create GitHub OAuth App:\n1. Go to ${pc.cyan('https://github.com/settings/developers')}\n2. New OAuth App\n3. Set Authorization callback URL:\n ${pc.green('https://your-app.com/api/auth/callback/github')}\n4. Copy the Client ID`,
|
|
176
|
+
required: false,
|
|
177
|
+
type: 'text',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
key: 'ONECHAT_GITHUB_CLIENT_SECRET',
|
|
181
|
+
label: 'GitHub OAuth Client Secret',
|
|
182
|
+
description: 'Client secret for GitHub OAuth application',
|
|
183
|
+
instructions: 'Copy the Client Secret from your GitHub OAuth App settings',
|
|
184
|
+
required: false,
|
|
185
|
+
type: 'secret',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: 'aws',
|
|
191
|
+
name: 'AWS Deployment',
|
|
192
|
+
description: 'AWS credentials for SST deployment',
|
|
193
|
+
required: false,
|
|
194
|
+
setupTime: '~30 minutes',
|
|
195
|
+
variables: [
|
|
196
|
+
{
|
|
197
|
+
key: 'AWS_ACCESS_KEY_ID',
|
|
198
|
+
label: 'AWS Access Key ID',
|
|
199
|
+
description: 'Access key for AWS deployment',
|
|
200
|
+
instructions: `${pc.yellow('⚠️ Setting up AWS takes about 30 minutes')}\n\nFollow the SST guide for AWS setup:\n${pc.cyan('https://sst.dev/docs/aws-accounts/')}\n\nQuick steps:\n1. Create AWS account or use existing\n2. Create IAM user with AdministratorAccess\n3. Generate access keys\n4. Copy Access Key ID`,
|
|
201
|
+
required: false,
|
|
202
|
+
type: 'text',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
key: 'AWS_SECRET_ACCESS_KEY',
|
|
206
|
+
label: 'AWS Secret Access Key',
|
|
207
|
+
description: 'Secret key for AWS deployment',
|
|
208
|
+
instructions: 'Copy the Secret Access Key from IAM user creation',
|
|
209
|
+
required: false,
|
|
210
|
+
type: 'secret',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
key: 'AWS_REGION',
|
|
214
|
+
label: 'AWS Region',
|
|
215
|
+
description: 'AWS region for deployment',
|
|
216
|
+
instructions:
|
|
217
|
+
'Choose a region close to your users (e.g., us-west-1, us-east-1, eu-west-1)',
|
|
218
|
+
required: false,
|
|
219
|
+
type: 'text',
|
|
220
|
+
default: 'us-west-1',
|
|
221
|
+
placeholder: 'us-west-1',
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
},
|
|
225
|
+
]
|
|
226
|
+
|
|
227
|
+
export function getCategoryById(id: string): EnvCategory | undefined {
|
|
228
|
+
return envCategories.find((cat) => cat.id === id)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function getRequiredCategories(): EnvCategory[] {
|
|
232
|
+
return envCategories.filter((cat) => cat.required)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function getOptionalCategories(): EnvCategory[] {
|
|
236
|
+
return envCategories.filter((cat) => !cat.required)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function getAllVariables(): EnvVariable[] {
|
|
240
|
+
return envCategories.flatMap((cat) => cat.variables)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function getVariableByKey(key: string): EnvVariable | undefined {
|
|
244
|
+
return getAllVariables().find((v) => v.key === key)
|
|
245
|
+
}
|