spine-framework 0.1.20 → 0.1.21
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.
|
@@ -30,9 +30,6 @@ const PACKAGE_ROOT = resolve(__dirname, '../../..')
|
|
|
30
30
|
|
|
31
31
|
interface InitOptions {
|
|
32
32
|
dryRun: boolean
|
|
33
|
-
url?: string
|
|
34
|
-
anonKey?: string
|
|
35
|
-
serviceRoleKey?: string
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
function scaffoldCustomWorkspace(dryRun: boolean): void {
|
|
@@ -58,33 +55,44 @@ function scaffoldCustomWorkspace(dryRun: boolean): void {
|
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
function writeEnvFile(
|
|
58
|
+
function writeEnvFile(dryRun: boolean): void {
|
|
62
59
|
const envPath = resolve(PROJECT_ROOT, '.env')
|
|
60
|
+
|
|
61
|
+
if (existsSync(envPath)) {
|
|
62
|
+
console.log(' ⏭️ .env already exists, skipping')
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
63
66
|
const envContent = [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
'# ─── Supabase ────────────────────────────────────────────────────────────────',
|
|
68
|
+
'# Get these from: https://supabase.com/dashboard/project/_/settings/api',
|
|
69
|
+
'SUPABASE_URL=https://your-project.supabase.co',
|
|
70
|
+
'SUPABASE_ANON_KEY=your-anon-key',
|
|
71
|
+
'SUPABASE_SERVICE_ROLE_KEY=your-service-role-key',
|
|
72
|
+
'',
|
|
73
|
+
'# DB password for running migrations (direct Postgres connection)',
|
|
74
|
+
'# Get from: https://supabase.com/dashboard/project/_/settings/database',
|
|
75
|
+
'SUPABASE_DB_PASSWORD=your-db-password',
|
|
76
|
+
'',
|
|
77
|
+
'# ─── Vite / Frontend ─────────────────────────────────────────────────────────',
|
|
78
|
+
'VITE_SUPABASE_URL=https://your-project.supabase.co',
|
|
79
|
+
'VITE_SUPABASE_ANON_KEY=your-anon-key',
|
|
80
|
+
'VITE_APP_NAME=Spine',
|
|
81
|
+
'',
|
|
82
|
+
'# ─── OpenAI ──────────────────────────────────────────────────────────────────',
|
|
83
|
+
'OPENAI_API_KEY=your-openai-api-key',
|
|
84
|
+
'',
|
|
85
|
+
'# ─── App config ──────────────────────────────────────────────────────────────',
|
|
86
|
+
'DB_SCHEMA=public',
|
|
71
87
|
].join('\n') + '\n'
|
|
72
88
|
|
|
73
89
|
if (dryRun) {
|
|
74
|
-
console.log(
|
|
90
|
+
console.log(' [dry-run] Would write .env with placeholder values')
|
|
75
91
|
return
|
|
76
92
|
}
|
|
77
93
|
|
|
78
|
-
const existed = existsSync(envPath)
|
|
79
94
|
writeFileSync(envPath, envContent, 'utf8')
|
|
80
|
-
console.log(
|
|
81
|
-
|
|
82
|
-
// Also inject into process.env for the rest of this run
|
|
83
|
-
process.env.SUPABASE_URL = url
|
|
84
|
-
process.env.SUPABASE_ANON_KEY = anonKey
|
|
85
|
-
process.env.SUPABASE_SERVICE_ROLE_KEY = serviceRoleKey
|
|
86
|
-
process.env.VITE_SUPABASE_URL = url
|
|
87
|
-
process.env.VITE_SUPABASE_ANON_KEY = anonKey
|
|
95
|
+
console.log(' ✓ Created .env')
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
function copyFrameworkFiles(dryRun: boolean): void {
|
|
@@ -129,40 +137,30 @@ function copyFrameworkFiles(dryRun: boolean): void {
|
|
|
129
137
|
async function initCommand(options: InitOptions): Promise<void> {
|
|
130
138
|
console.log('\n🚀 Spine Framework — Init\n')
|
|
131
139
|
|
|
132
|
-
// Step 1:
|
|
133
|
-
|
|
134
|
-
console.log('🔑 Step 1: Writing environment configuration...')
|
|
135
|
-
writeEnvFile(options.url, options.anonKey, options.serviceRoleKey, options.dryRun)
|
|
136
|
-
} else if (!process.env.SUPABASE_URL) {
|
|
137
|
-
console.error('❌ No Supabase credentials found.')
|
|
138
|
-
console.error(' spine-framework init --url <url> --anon-key <key> --service-role-key <key>')
|
|
139
|
-
process.exit(1)
|
|
140
|
-
} else {
|
|
141
|
-
console.log(' ✓ Using existing .env credentials')
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Step 2: Copy framework files to project root
|
|
145
|
-
console.log('\n📦 Step 2: Installing framework files...')
|
|
140
|
+
// Step 1: Copy framework files to project root
|
|
141
|
+
console.log('📦 Step 1: Installing framework files...')
|
|
146
142
|
copyFrameworkFiles(options.dryRun)
|
|
147
143
|
|
|
148
|
-
// Step
|
|
149
|
-
console.log('\n📁 Step
|
|
144
|
+
// Step 2: Scaffold custom workspace
|
|
145
|
+
console.log('\n📁 Step 2: Scaffolding custom workspace...')
|
|
150
146
|
scaffoldCustomWorkspace(options.dryRun)
|
|
151
147
|
|
|
148
|
+
// Step 3: Write .env with placeholders
|
|
149
|
+
console.log('\n🔑 Step 3: Writing environment configuration...')
|
|
150
|
+
writeEnvFile(options.dryRun)
|
|
151
|
+
|
|
152
152
|
console.log('\n✅ Project initialized!')
|
|
153
|
-
console.log('\n Next
|
|
154
|
-
console.log('
|
|
155
|
-
console.log('
|
|
156
|
-
console.log('
|
|
153
|
+
console.log('\n Next steps:')
|
|
154
|
+
console.log(' 1. Fill in your Supabase credentials in .env')
|
|
155
|
+
console.log(' (get them from https://supabase.com/dashboard/project/_/settings/api)')
|
|
156
|
+
console.log(' 2. Run: npx spine-framework migrate --db-password <your-db-password>')
|
|
157
|
+
console.log(' (get DB password from https://supabase.com/dashboard/project/_/settings/database)')
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
export function registerInitCommands(program: Command) {
|
|
160
161
|
program
|
|
161
162
|
.command('init')
|
|
162
|
-
.description('
|
|
163
|
-
.option('--url <url>', 'Supabase project URL')
|
|
164
|
-
.option('--anon-key <key>', 'Supabase anon key')
|
|
165
|
-
.option('--service-role-key <key>', 'Supabase service role key')
|
|
163
|
+
.description('Install framework files, scaffold custom/ workspace, and write .env template')
|
|
166
164
|
.option('--dry-run', 'Show what would happen without making changes', false)
|
|
167
165
|
.action(async (opts) => {
|
|
168
166
|
try {
|
|
@@ -28,7 +28,7 @@ const __dirname = dirname(__filename)
|
|
|
28
28
|
const MIGRATIONS_DIR = resolve(__dirname, '../../migrations')
|
|
29
29
|
|
|
30
30
|
interface MigrateOptions {
|
|
31
|
-
dbPassword
|
|
31
|
+
dbPassword?: string
|
|
32
32
|
dryRun: boolean
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -36,16 +36,21 @@ async function migrateCommand(options: MigrateOptions): Promise<void> {
|
|
|
36
36
|
console.log('\n🗄️ Spine Framework — Migrate\n')
|
|
37
37
|
|
|
38
38
|
const supabaseUrl = process.env.SUPABASE_URL
|
|
39
|
-
if (!supabaseUrl) {
|
|
40
|
-
console.error('❌ SUPABASE_URL not set.
|
|
39
|
+
if (!supabaseUrl || supabaseUrl === 'https://your-project.supabase.co') {
|
|
40
|
+
console.error('❌ SUPABASE_URL not set. Fill in your .env file first.')
|
|
41
|
+
process.exit(1)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dbPassword = options.dbPassword || process.env.SUPABASE_DB_PASSWORD
|
|
45
|
+
if (!dbPassword || dbPassword === 'your-db-password') {
|
|
46
|
+
console.error('❌ SUPABASE_DB_PASSWORD not set.')
|
|
47
|
+
console.error(' Add it to .env or pass --db-password <password>')
|
|
48
|
+
console.error(' Get it from: https://supabase.com/dashboard/project/_/settings/database')
|
|
41
49
|
process.exit(1)
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
// Derive connection string from Supabase URL
|
|
45
|
-
// Format: https://<ref>.supabase.co → postgres://postgres.<ref>:<password>@aws-0-<region>.pooler.supabase.com:5432/postgres
|
|
46
|
-
// Use direct connection (port 5432) via the db.<ref>.supabase.co host
|
|
47
52
|
const projectRef = supabaseUrl.replace('https://', '').split('.')[0]
|
|
48
|
-
const connectionString = `postgresql://postgres:${
|
|
53
|
+
const connectionString = `postgresql://postgres:${dbPassword}@db.${projectRef}.supabase.co:5432/postgres`
|
|
49
54
|
|
|
50
55
|
if (!existsSync(MIGRATIONS_DIR)) {
|
|
51
56
|
console.error(`❌ Migrations directory not found: ${MIGRATIONS_DIR}`)
|
|
@@ -120,7 +125,7 @@ export function registerMigrateCommands(program: Command) {
|
|
|
120
125
|
program
|
|
121
126
|
.command('migrate')
|
|
122
127
|
.description('Apply SQL migrations via direct Postgres connection')
|
|
123
|
-
.
|
|
128
|
+
.option('--db-password <password>', 'DB password override (default: reads SUPABASE_DB_PASSWORD from .env)')
|
|
124
129
|
.option('--dry-run', 'Show what would happen without making changes', false)
|
|
125
130
|
.action(async (opts) => {
|
|
126
131
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/init.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/init.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA4IxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAcpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/migrate.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/migrate.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuGxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,QAevD"}
|