kofi-stack-template-generator 2.1.11 → 2.1.13

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/dist/index.js CHANGED
@@ -1503,6 +1503,8 @@ main()
1503
1503
  vfs.writeFile(`${scriptsPath}/dev.mjs`, devScript);
1504
1504
  }
1505
1505
  function generateSetupConvexScript(vfs, scriptsPath, config) {
1506
+ const isMonorepo = config.structure === "monorepo";
1507
+ const backendDir = isMonorepo ? "../packages/backend" : ".";
1506
1508
  const setupScript = `#!/usr/bin/env node
1507
1509
  /**
1508
1510
  * Setup Convex - Interactive setup wizard for Convex
@@ -1516,30 +1518,86 @@ import * as readline from 'readline'
1516
1518
 
1517
1519
  const __dirname = dirname(fileURLToPath(import.meta.url))
1518
1520
  const projectDir = resolve(__dirname, '..')
1521
+ const backendDir = resolve(projectDir, '${backendDir}')
1519
1522
 
1520
- function prompt(question) {
1521
- const rl = readline.createInterface({
1522
- input: process.stdin,
1523
- output: process.stdout
1524
- })
1523
+ function loadEnvFile(dir) {
1524
+ const envPath = resolve(dir, '.env.local')
1525
+ if (!existsSync(envPath)) return {}
1525
1526
 
1526
- return new Promise((resolve) => {
1527
- rl.question(question, (answer) => {
1528
- rl.close()
1529
- resolve(answer.trim())
1530
- })
1531
- })
1527
+ const content = readFileSync(envPath, 'utf-8')
1528
+ const env = {}
1529
+
1530
+ for (const line of content.split('\\n')) {
1531
+ const trimmed = line.trim()
1532
+ if (!trimmed || trimmed.startsWith('#')) continue
1533
+ const eqIndex = trimmed.indexOf('=')
1534
+ if (eqIndex === -1) continue
1535
+ const key = trimmed.slice(0, eqIndex)
1536
+ let value = trimmed.slice(eqIndex + 1)
1537
+ if ((value.startsWith('"') && value.endsWith('"')) ||
1538
+ (value.startsWith("'") && value.endsWith("'"))) {
1539
+ value = value.slice(1, -1)
1540
+ }
1541
+ if (value) env[key] = value
1542
+ }
1543
+ return env
1544
+ }
1545
+
1546
+ function syncEnvToConvex(envVars) {
1547
+ // Required env vars that Better Auth needs in Convex cloud
1548
+ const requiredVars = ['BETTER_AUTH_SECRET', 'SITE_URL']
1549
+
1550
+ for (const varName of requiredVars) {
1551
+ if (envVars[varName]) {
1552
+ try {
1553
+ console.log(\` Setting \${varName} in Convex...\`)
1554
+ execSync(\`npx convex env set \${varName} "\${envVars[varName]}"\`, {
1555
+ cwd: backendDir,
1556
+ stdio: 'pipe'
1557
+ })
1558
+ } catch (error) {
1559
+ console.warn(\` \u26A0\uFE0F Could not set \${varName}: \${error.message}\`)
1560
+ }
1561
+ }
1562
+ }
1563
+
1564
+ // Optional OAuth env vars - only sync if they have values
1565
+ const optionalVars = [
1566
+ 'GITHUB_CLIENT_ID', 'GITHUB_CLIENT_SECRET',
1567
+ 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET',
1568
+ 'RESEND_API_KEY', 'RESEND_FROM_EMAIL'
1569
+ ]
1570
+
1571
+ for (const varName of optionalVars) {
1572
+ if (envVars[varName]) {
1573
+ try {
1574
+ execSync(\`npx convex env set \${varName} "\${envVars[varName]}"\`, {
1575
+ cwd: backendDir,
1576
+ stdio: 'pipe'
1577
+ })
1578
+ } catch (error) {
1579
+ // Silent fail for optional vars
1580
+ }
1581
+ }
1582
+ }
1532
1583
  }
1533
1584
 
1534
1585
  async function main() {
1535
1586
  console.log('\\n\u{1F527} Convex Setup Wizard\\n')
1536
1587
 
1537
1588
  // Check if already configured
1538
- const envPath = resolve(projectDir, '.env.local')
1589
+ const envPath = resolve(backendDir, '.env.local')
1539
1590
  if (existsSync(envPath)) {
1540
1591
  const content = readFileSync(envPath, 'utf-8')
1541
1592
  if (content.includes('CONVEX_DEPLOYMENT=') && !content.includes('CONVEX_DEPLOYMENT=\\n')) {
1542
- console.log('\u2705 Convex is already configured!')
1593
+ console.log('\u2705 Convex deployment already configured!')
1594
+
1595
+ // Sync env vars even if deployment exists
1596
+ console.log('\\n\u{1F4E4} Syncing environment variables to Convex cloud...')
1597
+ const envVars = loadEnvFile(backendDir)
1598
+ syncEnvToConvex(envVars)
1599
+
1600
+ console.log('\\n\u2705 Setup complete!')
1543
1601
  console.log(' Run "pnpm dev" to start development.\\n')
1544
1602
  return
1545
1603
  }
@@ -1552,11 +1610,16 @@ async function main() {
1552
1610
 
1553
1611
  try {
1554
1612
  spawnSync('npx', ['convex', 'dev', '--once'], {
1555
- cwd: projectDir,
1613
+ cwd: backendDir,
1556
1614
  stdio: 'inherit',
1557
1615
  shell: true
1558
1616
  })
1559
1617
 
1618
+ // After setup, sync env vars to Convex cloud
1619
+ console.log('\\n\u{1F4E4} Syncing environment variables to Convex cloud...')
1620
+ const envVars = loadEnvFile(backendDir)
1621
+ syncEnvToConvex(envVars)
1622
+
1560
1623
  console.log('\\n\u2705 Convex setup complete!')
1561
1624
  console.log(' Run "pnpm dev" to start development.\\n')
1562
1625
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.1.11",
3
+ "version": "2.1.13",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -10,20 +10,20 @@
10
10
  "types": "./dist/index.d.ts"
11
11
  }
12
12
  },
13
+ "scripts": {
14
+ "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
15
+ "dev": "tsup src/index.ts --format esm --dts --watch",
16
+ "prebuild": "node scripts/generate-templates.js",
17
+ "typecheck": "tsc --noEmit"
18
+ },
13
19
  "dependencies": {
20
+ "kofi-stack-types": "^2.1.0",
14
21
  "handlebars": "^4.7.8",
15
- "memfs": "^4.9.0",
16
- "kofi-stack-types": "^2.1.0"
22
+ "memfs": "^4.9.0"
17
23
  },
18
24
  "devDependencies": {
19
25
  "@types/node": "^20.0.0",
20
26
  "tsup": "^8.0.0",
21
27
  "typescript": "^5.0.0"
22
- },
23
- "scripts": {
24
- "build": "pnpm run prebuild && tsup src/index.ts --format esm --dts",
25
- "dev": "tsup src/index.ts --format esm --dts --watch",
26
- "prebuild": "node scripts/generate-templates.js",
27
- "typecheck": "tsc --noEmit"
28
28
  }
29
- }
29
+ }
package/src/generator.ts CHANGED
@@ -329,6 +329,9 @@ function generateSetupConvexScript(
329
329
  scriptsPath: string,
330
330
  config: ProjectConfig
331
331
  ): void {
332
+ const isMonorepo = config.structure === 'monorepo'
333
+ const backendDir = isMonorepo ? '../packages/backend' : '.'
334
+
332
335
  const setupScript = `#!/usr/bin/env node
333
336
  /**
334
337
  * Setup Convex - Interactive setup wizard for Convex
@@ -342,30 +345,86 @@ import * as readline from 'readline'
342
345
 
343
346
  const __dirname = dirname(fileURLToPath(import.meta.url))
344
347
  const projectDir = resolve(__dirname, '..')
348
+ const backendDir = resolve(projectDir, '${backendDir}')
345
349
 
346
- function prompt(question) {
347
- const rl = readline.createInterface({
348
- input: process.stdin,
349
- output: process.stdout
350
- })
350
+ function loadEnvFile(dir) {
351
+ const envPath = resolve(dir, '.env.local')
352
+ if (!existsSync(envPath)) return {}
351
353
 
352
- return new Promise((resolve) => {
353
- rl.question(question, (answer) => {
354
- rl.close()
355
- resolve(answer.trim())
356
- })
357
- })
354
+ const content = readFileSync(envPath, 'utf-8')
355
+ const env = {}
356
+
357
+ for (const line of content.split('\\n')) {
358
+ const trimmed = line.trim()
359
+ if (!trimmed || trimmed.startsWith('#')) continue
360
+ const eqIndex = trimmed.indexOf('=')
361
+ if (eqIndex === -1) continue
362
+ const key = trimmed.slice(0, eqIndex)
363
+ let value = trimmed.slice(eqIndex + 1)
364
+ if ((value.startsWith('"') && value.endsWith('"')) ||
365
+ (value.startsWith("'") && value.endsWith("'"))) {
366
+ value = value.slice(1, -1)
367
+ }
368
+ if (value) env[key] = value
369
+ }
370
+ return env
371
+ }
372
+
373
+ function syncEnvToConvex(envVars) {
374
+ // Required env vars that Better Auth needs in Convex cloud
375
+ const requiredVars = ['BETTER_AUTH_SECRET', 'SITE_URL']
376
+
377
+ for (const varName of requiredVars) {
378
+ if (envVars[varName]) {
379
+ try {
380
+ console.log(\` Setting \${varName} in Convex...\`)
381
+ execSync(\`npx convex env set \${varName} "\${envVars[varName]}"\`, {
382
+ cwd: backendDir,
383
+ stdio: 'pipe'
384
+ })
385
+ } catch (error) {
386
+ console.warn(\` ⚠️ Could not set \${varName}: \${error.message}\`)
387
+ }
388
+ }
389
+ }
390
+
391
+ // Optional OAuth env vars - only sync if they have values
392
+ const optionalVars = [
393
+ 'GITHUB_CLIENT_ID', 'GITHUB_CLIENT_SECRET',
394
+ 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET',
395
+ 'RESEND_API_KEY', 'RESEND_FROM_EMAIL'
396
+ ]
397
+
398
+ for (const varName of optionalVars) {
399
+ if (envVars[varName]) {
400
+ try {
401
+ execSync(\`npx convex env set \${varName} "\${envVars[varName]}"\`, {
402
+ cwd: backendDir,
403
+ stdio: 'pipe'
404
+ })
405
+ } catch (error) {
406
+ // Silent fail for optional vars
407
+ }
408
+ }
409
+ }
358
410
  }
359
411
 
360
412
  async function main() {
361
413
  console.log('\\n🔧 Convex Setup Wizard\\n')
362
414
 
363
415
  // Check if already configured
364
- const envPath = resolve(projectDir, '.env.local')
416
+ const envPath = resolve(backendDir, '.env.local')
365
417
  if (existsSync(envPath)) {
366
418
  const content = readFileSync(envPath, 'utf-8')
367
419
  if (content.includes('CONVEX_DEPLOYMENT=') && !content.includes('CONVEX_DEPLOYMENT=\\n')) {
368
- console.log('✅ Convex is already configured!')
420
+ console.log('✅ Convex deployment already configured!')
421
+
422
+ // Sync env vars even if deployment exists
423
+ console.log('\\n📤 Syncing environment variables to Convex cloud...')
424
+ const envVars = loadEnvFile(backendDir)
425
+ syncEnvToConvex(envVars)
426
+
427
+ console.log('\\n✅ Setup complete!')
369
428
  console.log(' Run "pnpm dev" to start development.\\n')
370
429
  return
371
430
  }
@@ -378,11 +437,16 @@ async function main() {
378
437
 
379
438
  try {
380
439
  spawnSync('npx', ['convex', 'dev', '--once'], {
381
- cwd: projectDir,
440
+ cwd: backendDir,
382
441
  stdio: 'inherit',
383
442
  shell: true
384
443
  })
385
444
 
445
+ // After setup, sync env vars to Convex cloud
446
+ console.log('\\n📤 Syncing environment variables to Convex cloud...')
447
+ const envVars = loadEnvFile(backendDir)
448
+ syncEnvToConvex(envVars)
449
+
386
450
  console.log('\\n✅ Convex setup complete!')
387
451
  console.log(' Run "pnpm dev" to start development.\\n')
388
452
  } catch (error) {
@@ -1,6 +1,6 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-14T04:39:40.149Z
3
+ // Generated: 2026-01-15T00:46:15.242Z
4
4
  // Template count: 90
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {