spine-framework 0.1.44 → 0.1.46

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.
@@ -28,9 +28,10 @@
28
28
  */
29
29
 
30
30
  import type { Command } from 'commander'
31
- import { existsSync, readFileSync, readdirSync } from 'fs'
31
+ import { existsSync, readFileSync, readdirSync, cpSync, mkdirSync } from 'fs'
32
32
  import { resolve, dirname } from 'path'
33
33
  import { fileURLToPath } from 'url'
34
+ import { execSync } from 'child_process'
34
35
  import { adminDb } from '../../functions/_shared/index.ts'
35
36
 
36
37
  const __filename = fileURLToPath(import.meta.url)
@@ -286,14 +287,120 @@ async function recordInstallation(appSlug: string, accountId: string | null, dry
286
287
  }
287
288
  }
288
289
 
290
+ function isNpmPackage(slug: string): boolean {
291
+ return slug.includes('/') || slug.startsWith('spine-framework-') || slug.startsWith('@')
292
+ }
293
+
294
+ function resolveSlugFromPackage(pkg: string): string {
295
+ const manifest = resolve(PROJECT_ROOT, `node_modules/${pkg}/spine-manifest.json`)
296
+ if (existsSync(manifest)) {
297
+ try {
298
+ return JSON.parse(readFileSync(manifest, 'utf8')).slug
299
+ } catch { /* fall through */ }
300
+ }
301
+ const pkgJson = resolve(PROJECT_ROOT, `node_modules/${pkg}/package.json`)
302
+ if (existsSync(pkgJson)) {
303
+ try {
304
+ const meta = JSON.parse(readFileSync(pkgJson, 'utf8'))
305
+ if (meta.spine?.slug) return meta.spine.slug
306
+ } catch { /* fall through */ }
307
+ }
308
+ return pkg.replace(/^spine-framework-/, '').replace(/^@[^/]+\//, '')
309
+ }
310
+
311
+ async function checkPrerequisites(slug: string): Promise<void> {
312
+ const PREREQS: Record<string, string[]> = {
313
+ 'customer-portal': ['cortex'],
314
+ }
315
+ const required = PREREQS[slug]
316
+ if (!required || required.length === 0) return
317
+
318
+ for (const prereq of required) {
319
+ const { data } = await adminDb
320
+ .from('app_installations')
321
+ .select('id')
322
+ .eq('app_slug', prereq)
323
+ .eq('is_enabled', true)
324
+ .maybeSingle()
325
+
326
+ if (!data) {
327
+ console.error(` ❌ Prerequisite not installed: '${prereq}'`)
328
+ console.error(` Run: spine-framework install-app spine-framework-${prereq}`)
329
+ process.exit(1)
330
+ }
331
+ }
332
+ }
333
+
334
+ function copyAppFiles(pkg: string, slug: string): void {
335
+ const pkgDir = resolve(PROJECT_ROOT, `node_modules/${pkg}`)
336
+ const appDirs = ['pages', 'components', 'seed', 'api']
337
+ const appFiles = ['index.tsx', 'manifest.json', 'package.json']
338
+ const targetAppDir = resolve(PROJECT_ROOT, `custom/apps/${slug}`)
339
+ const targetFunctionsDir = resolve(PROJECT_ROOT, 'custom/functions')
340
+
341
+ mkdirSync(targetAppDir, { recursive: true })
342
+ mkdirSync(targetFunctionsDir, { recursive: true })
343
+
344
+ for (const file of appFiles) {
345
+ const src = resolve(pkgDir, file)
346
+ if (existsSync(src)) {
347
+ cpSync(src, resolve(targetAppDir, file), { force: true })
348
+ }
349
+ }
350
+
351
+ for (const dir of appDirs) {
352
+ const src = resolve(pkgDir, dir)
353
+ if (existsSync(src)) {
354
+ cpSync(src, resolve(targetAppDir, dir), { recursive: true, force: true })
355
+ }
356
+ }
357
+
358
+ const functionsDir = resolve(pkgDir, 'functions')
359
+ if (existsSync(functionsDir)) {
360
+ cpSync(functionsDir, targetFunctionsDir, { recursive: true, force: true })
361
+ const count = readdirSync(targetFunctionsDir).filter(f => f.endsWith('.ts')).length
362
+ console.log(` ✓ Copied functions (${count} files) → custom/functions/`)
363
+ }
364
+
365
+ console.log(` ✓ Ejected app files → custom/apps/${slug}/`)
366
+ }
367
+
289
368
  async function installApp(slug: string, options: InstallOptions): Promise<void> {
290
369
  console.log(`\n📦 Installing app '${slug}'...\n`)
291
370
 
292
- // 1. Find the app directory
293
- const appDir = resolve(PROJECT_ROOT, `custom/apps/${slug}`)
371
+ let resolvedSlug = slug
372
+ let packageName: string | null = null
373
+
374
+ if (isNpmPackage(slug)) {
375
+ packageName = slug
376
+ console.log(`📥 Step 1: Installing npm package...`)
377
+ const pkgDir = resolve(PROJECT_ROOT, `node_modules/${slug}`)
378
+ if (!existsSync(pkgDir)) {
379
+ try {
380
+ console.log(` Running: npm install ${slug}`)
381
+ execSync(`npm install ${slug}`, { cwd: PROJECT_ROOT, stdio: 'inherit' })
382
+ console.log(` ✓ Package installed`)
383
+ } catch (err: any) {
384
+ console.error(` ❌ npm install failed: ${err.message}`)
385
+ process.exit(1)
386
+ }
387
+ } else {
388
+ console.log(` ⏭️ Package already in node_modules`)
389
+ }
390
+ resolvedSlug = resolveSlugFromPackage(slug)
391
+ console.log(` ✓ App slug: ${resolvedSlug}`)
392
+
393
+ console.log(`\n📁 Step 2: Ejecting app files...`)
394
+ copyAppFiles(slug, resolvedSlug)
395
+ }
396
+
397
+ // Check prerequisites (e.g. portal requires cortex)
398
+ await checkPrerequisites(resolvedSlug)
399
+
400
+ const appDir = resolve(PROJECT_ROOT, `custom/apps/${resolvedSlug}`)
294
401
  if (!existsSync(appDir)) {
295
- console.error(` ❌ App directory not found: custom/apps/${slug}`)
296
- console.error(` Install the npm package first or create the app with 'spine-framework create-app ${slug}'`)
402
+ console.error(` ❌ App directory not found: custom/apps/${resolvedSlug}`)
403
+ console.error(` Install the npm package first or create the app with 'spine-framework create-app ${resolvedSlug}'`)
297
404
  process.exit(1)
298
405
  }
299
406
 
@@ -313,7 +420,7 @@ async function installApp(slug: string, options: InstallOptions): Promise<void>
313
420
  }
314
421
 
315
422
  // 3. Ensure app record in DB
316
- const appId = await ensureAppRecord(slug, appName)
423
+ const appId = await ensureAppRecord(resolvedSlug, appName)
317
424
 
318
425
  // 4. Process seed files
319
426
  const seedDir = resolve(appDir, 'seed')
@@ -364,12 +471,12 @@ async function installApp(slug: string, options: InstallOptions): Promise<void>
364
471
 
365
472
  // 5. Record installation
366
473
  console.log(`\n📝 Recording installation...`)
367
- await recordInstallation(slug, options.account || null, options.dryRun)
474
+ await recordInstallation(resolvedSlug, options.account || null, options.dryRun)
368
475
 
369
476
  console.log(`\n✅ App '${appName}' installed successfully!`)
370
477
  console.log(`\n Next steps:`)
371
478
  console.log(` 1. npm run assemble && netlify dev`)
372
- console.log(` 2. Navigate to /${slug} in your browser`)
479
+ console.log(` 2. Navigate to /${resolvedSlug} in your browser`)
373
480
  }
374
481
 
375
482
  export function registerInstallAppCommands(program: Command) {
@@ -380,3 +380,12 @@ export {
380
380
  expectErrorResponse
381
381
  } from './testing'
382
382
  export type { TestContext, TestPrincipal, TestLogger } from './testing'
383
+
384
+ export {
385
+ resolveTypeIds,
386
+ resolveTypeId,
387
+ resolveLinkTypeIds,
388
+ resolveAccountId,
389
+ resolveAgentId,
390
+ resolvePromptConfigId
391
+ } from './resolve-ids'
@@ -0,0 +1,106 @@
1
+ // Slug-based ID resolution utilities
2
+ // Custom app code must never hardcode UUIDs — IDs differ on every fresh install.
3
+ // All functions that need entity IDs must call resolveIds() at request time.
4
+
5
+ import { adminDb } from './db'
6
+
7
+ interface ResolvedIds {
8
+ types: Record<string, string>
9
+ linkTypes: Record<string, string>
10
+ accounts: Record<string, string>
11
+ }
12
+
13
+ // Resolve type IDs by (kind, slug) pairs
14
+ export async function resolveTypeIds(
15
+ pairs: Array<{ kind: string; slug: string }>
16
+ ): Promise<Record<string, string>> {
17
+ if (pairs.length === 0) return {}
18
+
19
+ const { data, error } = await adminDb
20
+ .from('types')
21
+ .select('id, kind, slug')
22
+ .in('slug', pairs.map(p => p.slug))
23
+ .in('kind', [...new Set(pairs.map(p => p.kind))])
24
+
25
+ if (error) throw new Error(`resolveTypeIds failed: ${error.message}`)
26
+
27
+ const result: Record<string, string> = {}
28
+ for (const row of data || []) {
29
+ const key = `${row.kind}/${row.slug}`
30
+ result[key] = row.id
31
+ }
32
+
33
+ for (const pair of pairs) {
34
+ const key = `${pair.kind}/${pair.slug}`
35
+ if (!result[key]) throw new Error(`Type not found: ${key}`)
36
+ }
37
+
38
+ return result
39
+ }
40
+
41
+ // Resolve a single type ID — throws if not found
42
+ export async function resolveTypeId(kind: string, slug: string): Promise<string> {
43
+ const ids = await resolveTypeIds([{ kind, slug }])
44
+ return ids[`${kind}/${slug}`]
45
+ }
46
+
47
+ // Resolve link type IDs by slug
48
+ export async function resolveLinkTypeIds(slugs: string[]): Promise<Record<string, string>> {
49
+ if (slugs.length === 0) return {}
50
+
51
+ const { data, error } = await adminDb
52
+ .from('link_types')
53
+ .select('id, slug')
54
+ .in('slug', slugs)
55
+
56
+ if (error) throw new Error(`resolveLinkTypeIds failed: ${error.message}`)
57
+
58
+ const result: Record<string, string> = {}
59
+ for (const row of data || []) {
60
+ result[row.slug] = row.id
61
+ }
62
+
63
+ for (const slug of slugs) {
64
+ if (!result[slug]) throw new Error(`Link type not found: ${slug}`)
65
+ }
66
+
67
+ return result
68
+ }
69
+
70
+ // Resolve account ID by slug
71
+ export async function resolveAccountId(slug: string): Promise<string> {
72
+ const { data, error } = await adminDb
73
+ .from('accounts')
74
+ .select('id')
75
+ .eq('slug', slug)
76
+ .single()
77
+
78
+ if (error || !data) throw new Error(`Account not found: ${slug}`)
79
+ return data.id
80
+ }
81
+
82
+ // Resolve AI agent ID by name
83
+ export async function resolveAgentId(name: string): Promise<string> {
84
+ const { data, error } = await adminDb
85
+ .from('ai_agents')
86
+ .select('id')
87
+ .eq('name', name)
88
+ .eq('is_active', true)
89
+ .single()
90
+
91
+ if (error || !data) throw new Error(`AI agent not found: ${name}`)
92
+ return data.id
93
+ }
94
+
95
+ // Resolve prompt config ID by slug
96
+ export async function resolvePromptConfigId(slug: string): Promise<string> {
97
+ const { data, error } = await adminDb
98
+ .from('prompt_configs')
99
+ .select('id')
100
+ .eq('slug', slug)
101
+ .eq('is_active', true)
102
+ .single()
103
+
104
+ if (error || !data) throw new Error(`Prompt config not found: ${slug}`)
105
+ return data.id
106
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"install-app.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/install-app.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAyVxC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,QAgB1D"}
1
+ {"version":3,"file":"install-app.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/install-app.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAocxC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,QAgB1D"}
@@ -295,4 +295,5 @@ export type { AppManifest, NavItem } from './app-manifest';
295
295
  */
296
296
  export { makeTestContext, mockPrincipal, mockLogger, mockEvent, mockNetlifyContext, cleanup, setupTests, expectSuccessResponse, expectErrorResponse } from './testing';
297
297
  export type { TestContext, TestPrincipal, TestLogger } from './testing';
298
+ export { resolveTypeIds, resolveTypeId, resolveLinkTypeIds, resolveAccountId, resolveAgentId, resolvePromptConfigId } from './resolve-ids';
298
299
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare function resolveTypeIds(pairs: Array<{
2
+ kind: string;
3
+ slug: string;
4
+ }>): Promise<Record<string, string>>;
5
+ export declare function resolveTypeId(kind: string, slug: string): Promise<string>;
6
+ export declare function resolveLinkTypeIds(slugs: string[]): Promise<Record<string, string>>;
7
+ export declare function resolveAccountId(slug: string): Promise<string>;
8
+ export declare function resolveAgentId(name: string): Promise<string>;
9
+ export declare function resolvePromptConfigId(slug: string): Promise<string>;
10
+ //# sourceMappingURL=resolve-ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-ids.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/resolve-ids.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,CAClC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAuBjC;AAGD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E;AAGD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoBzF;AAGD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpE;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAGD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUzE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spine-framework",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "private": false,
5
5
  "description": "Spine — enterprise application framework built on Supabase + Netlify + React",
6
6
  "type": "module",