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 +77 -14
- package/package.json +10 -10
- package/src/generator.ts +78 -14
- package/src/templates.generated.ts +1 -1
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
|
|
1521
|
-
const
|
|
1522
|
-
|
|
1523
|
-
output: process.stdout
|
|
1524
|
-
})
|
|
1523
|
+
function loadEnvFile(dir) {
|
|
1524
|
+
const envPath = resolve(dir, '.env.local')
|
|
1525
|
+
if (!existsSync(envPath)) return {}
|
|
1525
1526
|
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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(
|
|
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
|
|
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:
|
|
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.
|
|
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
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
output: process.stdout
|
|
350
|
-
})
|
|
350
|
+
function loadEnvFile(dir) {
|
|
351
|
+
const envPath = resolve(dir, '.env.local')
|
|
352
|
+
if (!existsSync(envPath)) return {}
|
|
351
353
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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(
|
|
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
|
|
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:
|
|
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) {
|