spine-framework 0.1.6 → 0.1.9
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.
|
@@ -31,7 +31,6 @@ import type { Command } from 'commander'
|
|
|
31
31
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
|
|
32
32
|
import { resolve, dirname } from 'path'
|
|
33
33
|
import { fileURLToPath } from 'url'
|
|
34
|
-
import { adminDb } from '../../functions/_shared/index.ts'
|
|
35
34
|
|
|
36
35
|
const __filename = fileURLToPath(import.meta.url)
|
|
37
36
|
const __dirname = dirname(__filename)
|
|
@@ -70,13 +69,7 @@ async function runMigration(filename: string, dryRun: boolean): Promise<boolean>
|
|
|
70
69
|
return false
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
//
|
|
74
|
-
const { error } = await adminDb.rpc('exec_sql', { query: sql }).single()
|
|
75
|
-
if (!error) return true
|
|
76
|
-
|
|
77
|
-
// Fallback: use the Supabase /pg/query endpoint for raw SQL execution
|
|
78
|
-
console.log(` ⚠️ exec_sql not available, using direct SQL endpoint...`)
|
|
79
|
-
|
|
72
|
+
// Use the Supabase /pg/query endpoint for raw SQL execution
|
|
80
73
|
const pgResponse = await fetch(`${supabaseUrl}/pg/query`, {
|
|
81
74
|
method: 'POST',
|
|
82
75
|
headers: {
|
|
@@ -137,13 +130,15 @@ function scaffoldCustomWorkspace(dryRun: boolean): void {
|
|
|
137
130
|
|
|
138
131
|
async function checkAlreadyInitialized(): Promise<boolean> {
|
|
139
132
|
try {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
.
|
|
145
|
-
|
|
146
|
-
|
|
133
|
+
const supabaseUrl = process.env.SUPABASE_URL
|
|
134
|
+
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY
|
|
135
|
+
if (!supabaseUrl || !serviceKey) return false
|
|
136
|
+
const res = await fetch(
|
|
137
|
+
`${supabaseUrl}/rest/v1/apps?slug=eq.spine-core&select=slug&limit=1`,
|
|
138
|
+
{ headers: { apikey: serviceKey, Authorization: `Bearer ${serviceKey}` } }
|
|
139
|
+
)
|
|
140
|
+
const rows = await res.json() as any[]
|
|
141
|
+
return Array.isArray(rows) && rows.length > 0
|
|
147
142
|
} catch {
|
|
148
143
|
return false
|
|
149
144
|
}
|
|
@@ -229,12 +224,21 @@ async function initCommand(options: InitOptions): Promise<void> {
|
|
|
229
224
|
// Step 3: Record migration versions
|
|
230
225
|
if (!options.dryRun) {
|
|
231
226
|
console.log('\n📝 Step 3: Recording migration versions...')
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
227
|
+
const supabaseUrl = process.env.SUPABASE_URL!
|
|
228
|
+
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!
|
|
229
|
+
await fetch(`${supabaseUrl}/rest/v1/schema_migrations`, {
|
|
230
|
+
method: 'POST',
|
|
231
|
+
headers: {
|
|
232
|
+
'Content-Type': 'application/json',
|
|
233
|
+
'apikey': serviceKey,
|
|
234
|
+
'Authorization': `Bearer ${serviceKey}`,
|
|
235
|
+
'Prefer': 'resolution=merge-duplicates',
|
|
236
|
+
},
|
|
237
|
+
body: JSON.stringify([
|
|
235
238
|
{ version: '000_foundation', applied_at: new Date().toISOString() },
|
|
236
239
|
{ version: '001_seed', applied_at: new Date().toISOString() },
|
|
237
|
-
]
|
|
240
|
+
])
|
|
241
|
+
})
|
|
238
242
|
console.log(' ✓ Migration versions recorded')
|
|
239
243
|
}
|
|
240
244
|
|
|
@@ -18,11 +18,6 @@ import { createClient } from '@supabase/supabase-js'
|
|
|
18
18
|
|
|
19
19
|
// ─── ENVIRONMENT RESOLUTION ──────────────────────────────────────────────────
|
|
20
20
|
|
|
21
|
-
const _env = (globalThis as any).process?.env || {}
|
|
22
|
-
const supabaseUrl: string = _env.SUPABASE_URL!
|
|
23
|
-
const supabaseServiceKey: string = _env.SUPABASE_SERVICE_ROLE_KEY!
|
|
24
|
-
const supabaseAnonKey: string = _env.SUPABASE_ANON_KEY!
|
|
25
|
-
|
|
26
21
|
/**
|
|
27
22
|
* Active database schema name, read from `DB_SCHEMA` env var.
|
|
28
23
|
*
|
|
@@ -35,6 +30,10 @@ const supabaseAnonKey: string = _env.SUPABASE_ANON_KEY!
|
|
|
35
30
|
* @sideEffects none
|
|
36
31
|
* @calledBy adminDb, getUserDb (applied at client construction time)
|
|
37
32
|
*/
|
|
33
|
+
const _env = (globalThis as any).process?.env || {}
|
|
34
|
+
const supabaseUrl: string = _env.SUPABASE_URL!
|
|
35
|
+
const supabaseServiceKey: string = _env.SUPABASE_SERVICE_ROLE_KEY!
|
|
36
|
+
const supabaseAnonKey: string = _env.SUPABASE_ANON_KEY!
|
|
38
37
|
const dbSchema: string = _env.DB_SCHEMA || 'public'
|
|
39
38
|
|
|
40
39
|
// ─── CLIENTS ─────────────────────────────────────────────────────────────────
|
package/bin/spine-framework.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// This file is the npm bin entry point for spine-framework.
|
|
4
4
|
const { execFileSync } = require('child_process')
|
|
5
5
|
const { resolve } = require('path')
|
|
6
|
+
const fs = require('fs')
|
|
6
7
|
|
|
7
8
|
const pkgRoot = resolve(__dirname, '..')
|
|
8
9
|
const projectRoot = resolve(pkgRoot, '../..')
|
|
@@ -13,10 +14,19 @@ if (process.argv.length === 2) {
|
|
|
13
14
|
process.exit(0)
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
// Pre-parse credential flags so db.ts sees them as env vars at module load time.
|
|
18
|
+
// tsx evaluates db.ts before Commander parses args, so we must inject here.
|
|
19
|
+
const args = process.argv.slice(2)
|
|
20
|
+
const childEnv = { ...process.env }
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
if (args[i] === '--url' && args[i + 1]) childEnv.SUPABASE_URL = args[++i]
|
|
23
|
+
if (args[i] === '--anon-key' && args[i + 1]) childEnv.SUPABASE_ANON_KEY = args[++i]
|
|
24
|
+
if (args[i] === '--service-role-key' && args[i + 1]) childEnv.SUPABASE_SERVICE_ROLE_KEY = args[++i]
|
|
25
|
+
}
|
|
26
|
+
|
|
16
27
|
const entry = resolve(pkgRoot, '.framework/cli/index.ts')
|
|
17
28
|
|
|
18
29
|
// Find tsx: prefer consuming project's copy, fall back to our own
|
|
19
|
-
const fs = require('fs')
|
|
20
30
|
const tsxPaths = [
|
|
21
31
|
resolve(projectRoot, 'node_modules/.bin/tsx'),
|
|
22
32
|
resolve(pkgRoot, 'node_modules/.bin/tsx'),
|
|
@@ -29,7 +39,7 @@ if (!tsx) {
|
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
try {
|
|
32
|
-
execFileSync(tsx, [entry, ...process.argv.slice(2)], { stdio: 'inherit' })
|
|
42
|
+
execFileSync(tsx, [entry, ...process.argv.slice(2)], { stdio: 'inherit', env: childEnv })
|
|
33
43
|
} catch (e) {
|
|
34
44
|
process.exit(e.status ?? 1)
|
|
35
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/init.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoOxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAkBpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA0BH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,OAAO,iFAIlB,CAAA;AAGF;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,mFAWpC;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,KAAK,EAAE,GAAG,CAAA;CACX,CAAA;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,KAAK;;;;;;;;CAQjB,CAAA"}
|