@brightsideoy/kama 0.1.0-alpha.156 → 0.1.0-alpha.157
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/bin/cli.js +222 -253
- package/dist/assets/index-BesA3e7A.js +164 -0
- package/dist/assets/index-D6yHZ_u1.css +1 -0
- package/dist/{dist-C-WAK7EF.js → dist-mic4UZBb.js} +691 -439
- package/dist/index.html +2 -2
- package/dist/index.js +693 -439
- package/dist/schema-compiler.js +1 -1
- package/package.json +1 -1
- package/schema.sql +2 -2
- package/templates/astro-starter/src/components/blocks/BlockRenderer.astro +1 -0
- package/templates/astro-starter/src/components/blocks/ColumnLayout.astro +1 -0
- package/templates/astro-starter/src/components/blocks/HeaderImage.astro +1 -0
- package/templates/astro-starter/src/components/blocks/HtmlBlock.astro +2 -1
- package/templates/astro-starter/src/components/blocks/ImageBlock.astro +39 -71
- package/templates/astro-starter/src/components/blocks/TextBlock.astro +2 -0
- package/templates/astro-starter/src/components/global/Breadcrumb.astro +2 -0
- package/templates/astro-starter/src/components/global/Footer.astro +2 -0
- package/templates/astro-starter/src/components/global/Header.astro +99 -33
- package/templates/astro-starter/src/components/{seo/SeoHead.astro → global/MetaHead.astro} +101 -49
- package/templates/astro-starter/src/components/global/NavigationMenu.astro +1 -0
- package/templates/astro-starter/src/components/ui/KamaImage.astro +114 -67
- package/templates/astro-starter/src/layouts/SkeletonLayout.astro +5 -3
- package/templates/astro-starter/src/layouts/StandardLayout.astro +14 -5
- package/templates/astro-starter/src/lib/cms.ts +48 -0
- package/templates/astro-starter/src/lib/media/kama-image-service.ts +16 -1
- package/templates/astro-starter/src/lib/media/media-proxy.ts +8 -6
- package/templates/astro-starter/src/lib/media/media-url.ts +65 -1
- package/templates/astro-starter/src/middleware.ts +86 -17
- package/templates/astro-starter/src/pages/[...slug].astro +10 -22
- package/definitions/_page.yaml +0 -52
- package/dist/assets/index-DnRQYNN4.js +0 -164
- package/dist/assets/index-EaDn3OUJ.css +0 -1
- /package/templates/astro-starter/{public/css → src/styles}/standard-theme.css +0 -0
package/bin/cli.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, statSync, unlinkSync, appendFileSync } from 'node:fs';
|
|
4
|
-
import { join, dirname, basename, resolve
|
|
4
|
+
import { join, dirname, basename, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
6
|
import * as readline from 'node:readline/promises';
|
|
7
7
|
|
|
8
|
+
// 🎯 Always use the absolute newest ecosystem
|
|
9
|
+
const ASTRO_LATEST = "latest";
|
|
10
|
+
const ASTRO_NODE_LATEST = "latest";
|
|
11
|
+
const ASTRO_CF_LATEST = "latest";
|
|
12
|
+
const WRANGLER_LATEST = "latest";
|
|
13
|
+
|
|
8
14
|
// Dynamically resolve current package version
|
|
9
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
16
|
const __dirname = dirname(__filename);
|
|
@@ -247,11 +253,13 @@ async function createFullWorkspace() {
|
|
|
247
253
|
dependencies: {
|
|
248
254
|
'@brightsideoy/kama': currentKamaVersion,
|
|
249
255
|
},
|
|
250
|
-
devDependencies: {
|
|
251
|
-
'wrangler': '^4.0.0'
|
|
252
|
-
}
|
|
256
|
+
devDependencies: {}
|
|
253
257
|
};
|
|
254
258
|
|
|
259
|
+
if (isCloudflare) {
|
|
260
|
+
rootPkg.devDependencies['wrangler'] = WRANGLER_LATEST;
|
|
261
|
+
}
|
|
262
|
+
|
|
255
263
|
if (shouldCreateSite) {
|
|
256
264
|
rootPkg.devDependencies['concurrently'] = '^9.0.0';
|
|
257
265
|
rootPkg.scripts['dev:site'] = `npm run dev -w sites/${siteFolderName}`;
|
|
@@ -263,10 +271,7 @@ async function createFullWorkspace() {
|
|
|
263
271
|
rootPkg.scripts['dev'] = 'npm run dev:cms';
|
|
264
272
|
}
|
|
265
273
|
|
|
266
|
-
writeFileSync(
|
|
267
|
-
join(rootDir, 'package.json'),
|
|
268
|
-
JSON.stringify(rootPkg, null, 2)
|
|
269
|
-
);
|
|
274
|
+
writeFileSync(join(rootDir, 'package.json'), JSON.stringify(rootPkg, null, 2));
|
|
270
275
|
|
|
271
276
|
console.log(`\n☁️ Configuring CMS Worker '${workerName}' (${cmsDomain || 'localhost:8787'})...`);
|
|
272
277
|
const cmsDir = join(rootDir, 'kama-worker');
|
|
@@ -319,7 +324,7 @@ export default {
|
|
|
319
324
|
'@libsql/client': '^0.14.0'
|
|
320
325
|
},
|
|
321
326
|
devDependencies: {
|
|
322
|
-
"wrangler":
|
|
327
|
+
"wrangler": WRANGLER_LATEST
|
|
323
328
|
},
|
|
324
329
|
}, null, 2)
|
|
325
330
|
);
|
|
@@ -330,41 +335,29 @@ export default {
|
|
|
330
335
|
main: 'index.js',
|
|
331
336
|
compatibility_date: '2024-09-23',
|
|
332
337
|
compatibility_flags: ['nodejs_compat'],
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
},
|
|
336
|
-
|
|
337
|
-
directory: '../node_modules/@brightsideoy/kama/dist',
|
|
338
|
-
binding: 'ASSETS'
|
|
339
|
-
},
|
|
340
|
-
images: {
|
|
341
|
-
binding: 'IMAGES'
|
|
342
|
-
},
|
|
338
|
+
dev: { host: 'localhost', port: 8787 },
|
|
339
|
+
cache: { enabled: true },
|
|
340
|
+
assets: { directory: '../node_modules/@brightsideoy/kama/dist', binding: 'ASSETS' },
|
|
341
|
+
images: { binding: 'IMAGES' },
|
|
343
342
|
vars: {
|
|
344
|
-
CDN_DOMAIN: cmsDomain,
|
|
345
|
-
PUBLIC_FRONTEND_URL: (shouldCreateSite) ? `https://${siteDomain}` : 'http://localhost:4321',
|
|
343
|
+
CDN_DOMAIN: cmsDomain || 'localhost:8787',
|
|
344
|
+
PUBLIC_FRONTEND_URL: (shouldCreateSite) ? (siteDomain && siteDomain !== 'localhost:4321' ? `https://${siteDomain}` : 'http://localhost:4321') : 'http://localhost:4321',
|
|
346
345
|
CLOUDFLARE_ZONE_ID: "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID",
|
|
347
346
|
KAMA_RUNTIME: 'cloudflare'
|
|
348
347
|
},
|
|
349
|
-
d1_databases: [{
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
database_id: d1DatabaseId,
|
|
353
|
-
}],
|
|
354
|
-
r2_buckets: [{
|
|
355
|
-
binding: 'MEDIA_BUCKET',
|
|
356
|
-
bucket_name: bucketName,
|
|
357
|
-
}],
|
|
358
|
-
routes: [{ pattern: cmsDomain, custom_domain: true }]
|
|
348
|
+
d1_databases: [{ binding: 'DB', database_name: dbName, database_id: d1DatabaseId }],
|
|
349
|
+
r2_buckets: [{ binding: 'MEDIA_BUCKET', bucket_name: bucketName }],
|
|
350
|
+
routes: cmsDomain ? [{ pattern: cmsDomain, custom_domain: true }] : [{ pattern: "", custom_domain: true }]
|
|
359
351
|
};
|
|
360
352
|
|
|
361
353
|
writeFileSync(join(cmsDir, 'wrangler.json'), JSON.stringify(cmsWranglerConfig, null, 2));
|
|
362
354
|
|
|
355
|
+
// 🎯 FIX: CDN_DOMAIN left empty to auto-detect http://localhost:8787
|
|
363
356
|
writeFileSync(join(cmsDir, '.dev.vars'), `# Cloudflare Edge Cache Purging Secrets
|
|
364
357
|
CLOUDFLARE_API_TOKEN=cfut_YOUR_CUSTOM_PURGE_TOKEN
|
|
365
358
|
|
|
366
359
|
# Local Development Overrides (Takes precedence over wrangler.json vars during local dev)
|
|
367
|
-
CDN_DOMAIN=
|
|
360
|
+
CDN_DOMAIN=
|
|
368
361
|
PUBLIC_FRONTEND_URL=http://localhost:4321
|
|
369
362
|
`);
|
|
370
363
|
} else {
|
|
@@ -451,14 +444,7 @@ serve({ fetch: kamaApp.fetch, port }, (info) => {
|
|
|
451
444
|
);
|
|
452
445
|
|
|
453
446
|
// For Node mode, localhost is explicitly used
|
|
454
|
-
writeFileSync(join(cmsDir, '.env'), `PORT=8787
|
|
455
|
-
KAMA_RUNTIME=node
|
|
456
|
-
DB_PATH=./kama.db
|
|
457
|
-
LOCAL_MEDIA_PATH=./public/media
|
|
458
|
-
PUBLIC_CMS_URL=http://localhost:8787
|
|
459
|
-
PUBLIC_API_URL=http://localhost:8787
|
|
460
|
-
PUBLIC_FRONTEND_URL=http://localhost:4321
|
|
461
|
-
`);
|
|
447
|
+
writeFileSync(join(cmsDir, '.env'), `PORT=8787\nKAMA_RUNTIME=node\nDB_PATH=./kama.db\nLOCAL_MEDIA_PATH=./public/media\nPUBLIC_CMS_URL=http://127.0.0.1:8787\nPUBLIC_API_URL=http://127.0.0.1:8787\nPUBLIC_FRONTEND_URL=http://127.0.0.1:4321\n`);
|
|
462
448
|
}
|
|
463
449
|
|
|
464
450
|
await bundleWorkspaceSchemas(rootDir);
|
|
@@ -470,18 +456,14 @@ PUBLIC_FRONTEND_URL=http://localhost:4321
|
|
|
470
456
|
}
|
|
471
457
|
|
|
472
458
|
console.log(`\n✨ Workspace ready! Next steps:`);
|
|
473
|
-
if (!isCurrentDir) {
|
|
474
|
-
|
|
475
|
-
console.log(` 2. npm install`);
|
|
476
|
-
} else {
|
|
477
|
-
console.log(` 1. npm install`);
|
|
478
|
-
}
|
|
459
|
+
if (!isCurrentDir) console.log(` 1. cd ${projName}`);
|
|
460
|
+
console.log(` 2. npm install`);
|
|
479
461
|
|
|
480
462
|
if (isCloudflare) {
|
|
481
463
|
if (d1DatabaseId === '00000000-0000-0000-0000-000000000000') {
|
|
482
464
|
console.log(` 3. Run 'npx wrangler login' and create a D1 database manually.`);
|
|
483
465
|
}
|
|
484
|
-
console.log(` 4. Update CLOUDFLARE_ZONE_ID in kama-worker/wrangler.json
|
|
466
|
+
console.log(` 4. Update CLOUDFLARE_ZONE_ID in kama-worker/wrangler.json`);
|
|
485
467
|
console.log(` 5. Securely store your purge token: cd kama-worker && npx wrangler secret put CLOUDFLARE_API_TOKEN`);
|
|
486
468
|
console.log(` 6. Run 'npm run dev' from the workspace root to start everything.`);
|
|
487
469
|
} else {
|
|
@@ -492,7 +474,6 @@ PUBLIC_FRONTEND_URL=http://localhost:4321
|
|
|
492
474
|
|
|
493
475
|
/**
|
|
494
476
|
* COMMAND: npx kama add site
|
|
495
|
-
* Add Astro Site to existing workspace
|
|
496
477
|
*/
|
|
497
478
|
async function createNewSiteOnly() {
|
|
498
479
|
const rootDir = process.cwd();
|
|
@@ -505,18 +486,13 @@ async function createNewSiteOnly() {
|
|
|
505
486
|
let targetWorkerName = 'kama-worker';
|
|
506
487
|
let detectedCmsDomain = '';
|
|
507
488
|
|
|
508
|
-
// 🎯 Auto-detect existing worker name & CMS domain from kama-worker/wrangler.json
|
|
509
489
|
const cmsWranglerPath = join(rootDir, 'kama-worker', 'wrangler.json');
|
|
510
490
|
if (existsSync(cmsWranglerPath)) {
|
|
511
491
|
try {
|
|
512
492
|
const cmsWrangler = JSON.parse(readFileSync(cmsWranglerPath, 'utf-8'));
|
|
513
493
|
if (cmsWrangler.name) targetWorkerName = cmsWrangler.name;
|
|
514
|
-
|
|
515
|
-
if (cmsWrangler.
|
|
516
|
-
detectedCmsDomain = cmsWrangler.vars.CDN_DOMAIN;
|
|
517
|
-
} else if (cmsWrangler.routes?.[0]?.pattern) {
|
|
518
|
-
detectedCmsDomain = cmsWrangler.routes[0].pattern;
|
|
519
|
-
}
|
|
494
|
+
if (cmsWrangler.vars?.CDN_DOMAIN) detectedCmsDomain = cmsWrangler.vars.CDN_DOMAIN;
|
|
495
|
+
else if (cmsWrangler.routes?.[0]?.pattern) detectedCmsDomain = cmsWrangler.routes[0].pattern;
|
|
520
496
|
} catch (e) { }
|
|
521
497
|
}
|
|
522
498
|
|
|
@@ -527,18 +503,13 @@ async function createNewSiteOnly() {
|
|
|
527
503
|
const isCloudflare = envChoice.trim() === '2';
|
|
528
504
|
|
|
529
505
|
const siteFolder = (await rl.question('Astro package/folder name (e.g., my-new-site) [kama-starter]: ')).trim() || 'kama-starter';
|
|
530
|
-
|
|
531
506
|
let siteDomain = 'localhost:4321';
|
|
532
507
|
let cmsFullUrl = 'http://localhost:8787';
|
|
533
508
|
|
|
534
509
|
if (isCloudflare) {
|
|
535
510
|
siteDomain = (await rl.question('Website Domain (e.g., brand.com): ')).trim();
|
|
536
|
-
|
|
537
511
|
if (detectedCmsDomain) {
|
|
538
|
-
cmsFullUrl = detectedCmsDomain.startsWith('http')
|
|
539
|
-
? detectedCmsDomain
|
|
540
|
-
: `https://${detectedCmsDomain.replace(/^https?:\/\//, '')}`;
|
|
541
|
-
console.log(`ℹ️ Auto-detected CMS Admin Domain: ${cmsFullUrl}`);
|
|
512
|
+
cmsFullUrl = detectedCmsDomain.startsWith('http') ? detectedCmsDomain : `https://${detectedCmsDomain.replace(/^https?:\/\//, '')}`;
|
|
542
513
|
} else {
|
|
543
514
|
const cmsDomainInput = (await rl.question('CMS API Domain (e.g., admin.brand.com): ')).trim();
|
|
544
515
|
cmsFullUrl = `https://${cmsDomainInput.replace(/^https?:\/\//, '')}`;
|
|
@@ -549,7 +520,6 @@ async function createNewSiteOnly() {
|
|
|
549
520
|
|
|
550
521
|
console.log(`\n✨ Site created in sites/${siteFolder}!`);
|
|
551
522
|
console.log(`📦 Run 'npm install' at workspace root.`);
|
|
552
|
-
console.log(`🌱 Run 'npm run dev' to boot up and seed the new site data.`);
|
|
553
523
|
}
|
|
554
524
|
|
|
555
525
|
/**
|
|
@@ -557,20 +527,12 @@ async function createNewSiteOnly() {
|
|
|
557
527
|
*/
|
|
558
528
|
async function bundleWorkspaceSchemas(targetRootDir) {
|
|
559
529
|
let rootDir = targetRootDir || process.cwd();
|
|
560
|
-
|
|
561
|
-
if (basename(rootDir) === 'kama-worker') {
|
|
562
|
-
rootDir = resolve(rootDir, '..');
|
|
563
|
-
}
|
|
530
|
+
if (basename(rootDir) === 'kama-worker') rootDir = resolve(rootDir, '..');
|
|
564
531
|
|
|
565
532
|
try {
|
|
566
533
|
let compilerPath = join(__dirname, '../dist/schema-compiler.js');
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const compilerUrl = pathToFileURL(compilerPath).href;
|
|
573
|
-
await import(compilerUrl);
|
|
534
|
+
if (!existsSync(compilerPath)) compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
|
|
535
|
+
await import(pathToFileURL(compilerPath).href);
|
|
574
536
|
} catch (e) {
|
|
575
537
|
console.error(`❌ Schema compilation failed:`, e.message || e);
|
|
576
538
|
}
|
|
@@ -581,94 +543,163 @@ async function bundleWorkspaceSchemas(targetRootDir) {
|
|
|
581
543
|
*/
|
|
582
544
|
async function promoteLocalToCloudflare() {
|
|
583
545
|
const rootDir = process.cwd();
|
|
584
|
-
const
|
|
546
|
+
const workerDir = join(rootDir, 'kama-worker');
|
|
547
|
+
const rootPkgPath = join(rootDir, 'package.json');
|
|
585
548
|
|
|
586
|
-
if (!existsSync(
|
|
587
|
-
console.error('❌ Error: Could not find kama-worker
|
|
549
|
+
if (!existsSync(workerDir) || !existsSync(rootPkgPath)) {
|
|
550
|
+
console.error('❌ Error: Could not find kama-worker folder or package.json. Run this command inside your workspace root.');
|
|
588
551
|
return;
|
|
589
552
|
}
|
|
590
553
|
|
|
591
|
-
console.log('\n🌐 ---
|
|
554
|
+
console.log('\n🌐 --- UPGRADING WORKSPACE TO CLOUDFLARE EDGE --- 🌐\n');
|
|
592
555
|
|
|
593
556
|
try {
|
|
594
557
|
execSync('npx wrangler whoami', { stdio: 'pipe' });
|
|
595
558
|
console.log('✅ Logged in to Cloudflare.');
|
|
596
559
|
} catch (e) {
|
|
597
560
|
console.log('🌐 Launching browser for Cloudflare login...');
|
|
598
|
-
try {
|
|
599
|
-
|
|
600
|
-
} catch (loginError) {
|
|
601
|
-
console.log('❌ Cloudflare login failed or was cancelled.');
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
561
|
+
try { execSync('npx wrangler login', { stdio: 'inherit' }); }
|
|
562
|
+
catch (loginError) { console.log('❌ Cloudflare login failed.'); return; }
|
|
604
563
|
}
|
|
605
564
|
|
|
606
565
|
const cmsDomain = (await rl.question('\nCMS Admin Domain (e.g., admin.yourdomain.com): ')).trim();
|
|
607
566
|
|
|
608
567
|
const sitesFolderDir = join(rootDir, 'sites');
|
|
609
568
|
let siteDomain = '';
|
|
569
|
+
let siteDir = null;
|
|
610
570
|
if (existsSync(sitesFolderDir)) {
|
|
611
|
-
|
|
571
|
+
const sites = readdirSync(sitesFolderDir);
|
|
572
|
+
if (sites.length > 0) {
|
|
573
|
+
siteDir = join(sitesFolderDir, sites[0]);
|
|
574
|
+
siteDomain = (await rl.question('Frontend Website Domain (e.g., yourdomain.com): ')).trim();
|
|
575
|
+
}
|
|
612
576
|
}
|
|
613
577
|
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
console.log(`\n🗄️ Provisioning remote Cloudflare D1 Database '${dbName}'...`);
|
|
578
|
+
const projName = basename(rootDir);
|
|
579
|
+
let dbName = `${projName}-db`.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
618
580
|
let d1DatabaseId = '00000000-0000-0000-0000-000000000000';
|
|
619
581
|
|
|
620
582
|
try {
|
|
621
583
|
const d1Output = execSync(`npx wrangler d1 create ${dbName}`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
622
584
|
const match = d1Output.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/);
|
|
623
585
|
if (match) d1DatabaseId = match[0];
|
|
624
|
-
} catch (err) {
|
|
625
|
-
|
|
626
|
-
|
|
586
|
+
} catch (err) { }
|
|
587
|
+
|
|
588
|
+
// 1. Upgrade Root
|
|
589
|
+
const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));
|
|
590
|
+
rootPkg.devDependencies = rootPkg.devDependencies || {};
|
|
591
|
+
rootPkg.devDependencies['wrangler'] = WRANGLER_LATEST;
|
|
592
|
+
writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2));
|
|
593
|
+
|
|
594
|
+
// 2. Upgrade Worker
|
|
595
|
+
const workerName = `${projName}-worker`.toLowerCase().replace(/[^a-z0-9_-]/g, '-');
|
|
596
|
+
const bucketName = `${projName}-media-prod`.toLowerCase().replace(/[^a-z0-9_-]/g, '-');
|
|
597
|
+
const workerWranglerPath = join(workerDir, 'wrangler.json');
|
|
598
|
+
|
|
599
|
+
let currentConfig = existsSync(workerWranglerPath)
|
|
600
|
+
? JSON.parse(readFileSync(workerWranglerPath, 'utf-8'))
|
|
601
|
+
: {
|
|
602
|
+
$schema: '../node_modules/wrangler/config-schema.json',
|
|
603
|
+
name: workerName,
|
|
604
|
+
main: 'index.js',
|
|
605
|
+
compatibility_date: '2024-09-23',
|
|
606
|
+
compatibility_flags: ['nodejs_compat'],
|
|
607
|
+
assets: { directory: '../node_modules/@brightsideoy/kama/dist', binding: 'ASSETS' },
|
|
608
|
+
images: { binding: 'IMAGES' },
|
|
609
|
+
vars: { CLOUDFLARE_ZONE_ID: "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID", KAMA_RUNTIME: 'cloudflare' }
|
|
610
|
+
};
|
|
627
611
|
|
|
612
|
+
currentConfig.dev = currentConfig.dev || { host: 'localhost', port: 8787 };
|
|
628
613
|
currentConfig.cache = { enabled: true };
|
|
629
614
|
currentConfig.vars.CDN_DOMAIN = cmsDomain;
|
|
630
|
-
if (siteDomain) {
|
|
631
|
-
currentConfig.vars.PUBLIC_FRONTEND_URL = `https://${siteDomain}`;
|
|
632
|
-
}
|
|
615
|
+
if (siteDomain) currentConfig.vars.PUBLIC_FRONTEND_URL = `https://${siteDomain}`;
|
|
633
616
|
currentConfig.routes = [{ pattern: cmsDomain, custom_domain: true }];
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
617
|
+
currentConfig.d1_databases = [{ binding: 'DB', database_name: dbName, database_id: d1DatabaseId }];
|
|
618
|
+
currentConfig.r2_buckets = [{ binding: 'MEDIA_BUCKET', bucket_name: bucketName }];
|
|
637
619
|
|
|
638
620
|
writeFileSync(workerWranglerPath, JSON.stringify(currentConfig, null, 2));
|
|
639
621
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
622
|
+
// 🎯 FIX: CDN_DOMAIN left empty to auto-detect http://localhost:8787
|
|
623
|
+
if (!existsSync(join(workerDir, '.dev.vars'))) {
|
|
624
|
+
writeFileSync(join(workerDir, '.dev.vars'), `CLOUDFLARE_API_TOKEN=cfut_YOUR_CUSTOM_PURGE_TOKEN\nCDN_DOMAIN=\nPUBLIC_FRONTEND_URL=http://localhost:4321\n`);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
const workerIndexPath = join(workerDir, 'index.js');
|
|
628
|
+
if (!existsSync(workerIndexPath)) {
|
|
629
|
+
writeFileSync(workerIndexPath, `import kamaWorker from '@brightsideoy/kama';\nimport * as localBundle from './bundled-definitions.js';\nexport default {\n async fetch(request, env, ctx) {\n const schemas = localBundle.BUNDLED_DEFINITIONS || localBundle.default || localBundle;\n const customEnv = { ...env, BUNDLED_DEFINITIONS: schemas, KAMA_RUNTIME: 'cloudflare' };\n if (kamaWorker && typeof kamaWorker.fetch === 'function') return kamaWorker.fetch(request, customEnv, ctx);\n if (kamaWorker && kamaWorker.app && typeof kamaWorker.app.fetch === 'function') return kamaWorker.app.fetch(request, customEnv, ctx);\n return new Response('Kama Engine Worker Ready', { status: 200 });\n }\n};\n`);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const workerPkgPath = join(workerDir, 'package.json');
|
|
633
|
+
if (existsSync(workerPkgPath)) {
|
|
634
|
+
const workerPkg = JSON.parse(readFileSync(workerPkgPath, 'utf-8'));
|
|
635
|
+
workerPkg.scripts.dev = "npm run schema:local && npm run seed:local && wrangler dev --port 8787 --inspector-port 9239";
|
|
636
|
+
workerPkg.scripts.deploy = "npm run schema:remote && npm run seed:remote && wrangler deploy";
|
|
637
|
+
workerPkg.scripts["schema:remote"] = `wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`;
|
|
638
|
+
workerPkg.scripts["seed:remote"] = `wrangler d1 execute ${dbName} --remote --file=seed.sql`;
|
|
639
|
+
workerPkg.devDependencies = workerPkg.devDependencies || {};
|
|
640
|
+
workerPkg.devDependencies.wrangler = WRANGLER_LATEST;
|
|
641
|
+
writeFileSync(workerPkgPath, JSON.stringify(workerPkg, null, 2));
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// 3. Upgrade Site
|
|
645
|
+
if (siteDir && siteDomain) {
|
|
646
|
+
let sessionId = "REPLACE_WITH_YOUR_SESSION_KV_ID";
|
|
647
|
+
let htmlCacheId = "REPLACE_WITH_YOUR_HTML_CACHE_KV_ID";
|
|
648
|
+
const prefix = basename(siteDir).replace(/[^a-zA-Z0-9]/g, '_').toUpperCase();
|
|
649
|
+
|
|
650
|
+
try {
|
|
651
|
+
const sessionOut = execSync(`npx wrangler kv namespace create "SESSION_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
652
|
+
if (sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)) sessionId = sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)[1];
|
|
653
|
+
const cacheOut = execSync(`npx wrangler kv namespace create "HTML_CACHE_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
654
|
+
if (cacheOut.match(/"id":\s*"([a-f0-9]{32})"/)) htmlCacheId = cacheOut.match(/"id":\s*"([a-f0-9]{32})"/)[1];
|
|
655
|
+
} catch (err) { }
|
|
656
|
+
|
|
657
|
+
const siteWranglerPath = join(siteDir, 'wrangler.json');
|
|
658
|
+
const siteConfig = {
|
|
659
|
+
$schema: "node_modules/wrangler/config-schema.json",
|
|
660
|
+
name: `${basename(siteDir).toLowerCase().replace(/[^a-z0-9-]/g, '-')}-site`,
|
|
661
|
+
compatibility_date: "2024-09-23",
|
|
662
|
+
compatibility_flags: ["nodejs_compat"],
|
|
663
|
+
dev: { host: 'localhost', port: 4321 },
|
|
664
|
+
cache: { enabled: true },
|
|
665
|
+
assets: { directory: "./dist/client", binding: "ASSETS", run_worker_first: true },
|
|
666
|
+
kv_namespaces: [{ binding: "SESSION", id: sessionId }, { binding: "HTML_CACHE", id: htmlCacheId }],
|
|
667
|
+
services: [{ binding: "CMS_WORKER", service: currentConfig.name }],
|
|
668
|
+
routes: [{ pattern: siteDomain, zone_name: siteDomain, custom_domain: true, enabled: true, previews_enabled: false }],
|
|
669
|
+
vars: { PUBLIC_CMS_URL: `https://${cmsDomain}`, PUBLIC_API_URL: `https://${cmsDomain}` }
|
|
670
|
+
};
|
|
671
|
+
writeFileSync(siteWranglerPath, JSON.stringify(siteConfig, null, 2));
|
|
672
|
+
|
|
673
|
+
const sitePkgPath = join(siteDir, 'package.json');
|
|
674
|
+
if (existsSync(sitePkgPath)) {
|
|
675
|
+
const sitePkg = JSON.parse(readFileSync(sitePkgPath, 'utf-8'));
|
|
676
|
+
sitePkg.dependencies = sitePkg.dependencies || {};
|
|
677
|
+
sitePkg.dependencies['astro'] = ASTRO_LATEST;
|
|
678
|
+
|
|
679
|
+
if (sitePkg.dependencies['@astrojs/node']) delete sitePkg.dependencies['@astrojs/node'];
|
|
680
|
+
sitePkg.dependencies['@astrojs/cloudflare'] = ASTRO_CF_LATEST;
|
|
681
|
+
|
|
682
|
+
sitePkg.devDependencies = sitePkg.devDependencies || {};
|
|
683
|
+
sitePkg.devDependencies['wrangler'] = WRANGLER_LATEST;
|
|
684
|
+
|
|
685
|
+
writeFileSync(sitePkgPath, JSON.stringify(sitePkg, null, 2));
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// 🎯 100% BULLETPROOF CONFIG WRITE FOR CLOUDFLARE
|
|
689
|
+
const astroConfigPath = join(siteDir, 'astro.config.mjs');
|
|
690
|
+
const cfConfigContent = `import { defineConfig } from 'astro/config';\nimport cloudflare from '@astrojs/cloudflare';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport default defineConfig({\n output: 'server',\n trailingSlash: 'ignore',\n image: { service: { entrypoint: './src/lib/media/kama-image-service.ts' } },\n adapter: cloudflare({ imageService: process.env.NODE_ENV === 'production' ? "cloudflare" : "passthrough" }),\n vite: {\n resolve: { alias: { '@': path.resolve(__dirname, './src') } },\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n },\n environments: {\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n }\n }\n }\n});\n`;
|
|
691
|
+
writeFileSync(astroConfigPath, cfConfigContent);
|
|
692
|
+
|
|
693
|
+
const tsConfigPath = join(siteDir, 'tsconfig.json');
|
|
694
|
+
if (existsSync(tsConfigPath)) {
|
|
695
|
+
const tsConfig = JSON.parse(readFileSync(tsConfigPath, 'utf-8'));
|
|
696
|
+
tsConfig.compilerOptions = tsConfig.compilerOptions || {};
|
|
697
|
+
tsConfig.compilerOptions.types = ["@cloudflare/workers-types"];
|
|
698
|
+
writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2));
|
|
668
699
|
}
|
|
669
700
|
}
|
|
670
701
|
|
|
671
|
-
console.log(`\n✅ Workspace successfully
|
|
702
|
+
console.log(`\n✅ Workspace successfully upgraded to Cloudflare Edge!`);
|
|
672
703
|
}
|
|
673
704
|
|
|
674
705
|
/**
|
|
@@ -687,23 +718,49 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
687
718
|
|
|
688
719
|
cpSync(templateDir, siteDir, { recursive: true });
|
|
689
720
|
|
|
690
|
-
|
|
691
|
-
writeFileSync(join(siteDir, 'tsconfig.json'), JSON.stringify({
|
|
721
|
+
const tsConfig = {
|
|
692
722
|
extends: "astro/tsconfigs/strict",
|
|
693
|
-
compilerOptions: {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
698
|
-
}, null, 2));
|
|
723
|
+
compilerOptions: { baseUrl: ".", paths: { "@/*": ["src/*"] } }
|
|
724
|
+
};
|
|
725
|
+
if (isCloudflare) tsConfig.compilerOptions.types = ["@cloudflare/workers-types"];
|
|
726
|
+
writeFileSync(join(siteDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
|
|
699
727
|
|
|
700
728
|
const templatePkgPath = join(siteDir, 'package.json.template');
|
|
701
729
|
if (existsSync(templatePkgPath)) {
|
|
702
|
-
const
|
|
730
|
+
const rawContent = readFileSync(templatePkgPath, 'utf-8')
|
|
703
731
|
.replace(/\{\{SITE_NAME\}\}/g, siteFolder)
|
|
704
732
|
.replace(/\{\{KAMA_VERSION\}\}/g, currentKamaVersion);
|
|
705
733
|
|
|
706
|
-
|
|
734
|
+
const sitePkg = JSON.parse(rawContent);
|
|
735
|
+
|
|
736
|
+
sitePkg.dependencies = sitePkg.dependencies || {};
|
|
737
|
+
sitePkg.dependencies['astro'] = ASTRO_LATEST;
|
|
738
|
+
|
|
739
|
+
if (!isCloudflare) {
|
|
740
|
+
if (sitePkg.dependencies['@astrojs/cloudflare']) delete sitePkg.dependencies['@astrojs/cloudflare'];
|
|
741
|
+
if (sitePkg.dependencies['wrangler']) delete sitePkg.dependencies['wrangler'];
|
|
742
|
+
if (sitePkg.devDependencies && sitePkg.devDependencies['wrangler']) delete sitePkg.devDependencies['wrangler'];
|
|
743
|
+
|
|
744
|
+
sitePkg.dependencies['@astrojs/node'] = ASTRO_NODE_LATEST;
|
|
745
|
+
|
|
746
|
+
// 🎯 100% BULLETPROOF CONFIG WRITE FOR NODE
|
|
747
|
+
const astroConfigPath = join(siteDir, 'astro.config.mjs');
|
|
748
|
+
const nodeConfigContent = `import { defineConfig } from 'astro/config';\nimport node from '@astrojs/node';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport default defineConfig({\n output: 'server',\n trailingSlash: 'ignore',\n image: { service: { entrypoint: './src/lib/media/kama-image-service.ts' } },\n adapter: node({ mode: "standalone" }),\n vite: {\n resolve: { alias: { '@': path.resolve(__dirname, './src') } },\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n },\n environments: {\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n }\n }\n }\n});\n`;
|
|
749
|
+
writeFileSync(astroConfigPath, nodeConfigContent);
|
|
750
|
+
|
|
751
|
+
} else {
|
|
752
|
+
sitePkg.dependencies['@astrojs/cloudflare'] = ASTRO_CF_LATEST;
|
|
753
|
+
if (sitePkg.dependencies['wrangler']) delete sitePkg.dependencies['wrangler'];
|
|
754
|
+
sitePkg.devDependencies = sitePkg.devDependencies || {};
|
|
755
|
+
sitePkg.devDependencies['wrangler'] = WRANGLER_LATEST;
|
|
756
|
+
|
|
757
|
+
// 🎯 100% BULLETPROOF CONFIG WRITE FOR CLOUDFLARE
|
|
758
|
+
const astroConfigPath = join(siteDir, 'astro.config.mjs');
|
|
759
|
+
const cfConfigContent = `import { defineConfig } from 'astro/config';\nimport cloudflare from '@astrojs/cloudflare';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport default defineConfig({\n output: 'server',\n trailingSlash: 'ignore',\n image: { service: { entrypoint: './src/lib/media/kama-image-service.ts' } },\n adapter: cloudflare({ imageService: process.env.NODE_ENV === 'production' ? "cloudflare" : "passthrough" }),\n vite: {\n resolve: { alias: { '@': path.resolve(__dirname, './src') } },\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n },\n environments: {\n ssr: {\n external: ['cloudflare:workers', 'tinyexec', 'node:child_process', 'node:fs', 'node:url', 'node:path', 'node:stream', 'node:readline', 'node:stream/promises']\n }\n }\n }\n});\n`;
|
|
760
|
+
writeFileSync(astroConfigPath, cfConfigContent);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
writeFileSync(join(siteDir, 'package.json'), JSON.stringify(sitePkg, null, 2));
|
|
707
764
|
unlinkSync(templatePkgPath);
|
|
708
765
|
}
|
|
709
766
|
|
|
@@ -711,139 +768,51 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
711
768
|
const safeSiteLabel = siteLabel.replace(/'/g, "''");
|
|
712
769
|
const channelKey = siteFolder.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
|
|
713
770
|
const treeKey = 'main-tree';
|
|
714
|
-
|
|
715
|
-
// Sanitize worker name
|
|
716
771
|
const safeWorkerName = `${siteFolder.toLowerCase().replace(/[^a-z0-9-]/g, '-')}-site`;
|
|
717
772
|
|
|
718
|
-
// 🎯 2. Auto-provision KV Namespaces if running in Cloudflare mode
|
|
719
|
-
let sessionId = "REPLACE_WITH_YOUR_SESSION_KV_ID";
|
|
720
|
-
let htmlCacheId = "REPLACE_WITH_YOUR_HTML_CACHE_KV_ID";
|
|
721
|
-
|
|
722
773
|
if (isCloudflare) {
|
|
723
|
-
|
|
774
|
+
let sessionId = "REPLACE_WITH_YOUR_SESSION_KV_ID";
|
|
775
|
+
let htmlCacheId = "REPLACE_WITH_YOUR_HTML_CACHE_KV_ID";
|
|
776
|
+
|
|
724
777
|
try {
|
|
725
778
|
const prefix = siteFolder.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase();
|
|
726
|
-
|
|
727
|
-
console.log(` Creating Session KV...`);
|
|
728
779
|
const sessionOut = execSync(`npx wrangler kv namespace create "SESSION_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
729
|
-
|
|
730
|
-
if (sessionMatch) sessionId = sessionMatch[1];
|
|
731
|
-
|
|
732
|
-
console.log(` Creating Cache KV...`);
|
|
780
|
+
if (sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)) sessionId = sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)[1];
|
|
733
781
|
const cacheOut = execSync(`npx wrangler kv namespace create "HTML_CACHE_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
compatibility_flags: ["nodejs_compat"],
|
|
750
|
-
cache: { enabled: true },
|
|
751
|
-
assets: {
|
|
752
|
-
directory: "./dist/client",
|
|
753
|
-
binding: "ASSETS",
|
|
754
|
-
run_worker_first: true
|
|
755
|
-
},
|
|
756
|
-
kv_namespaces: [
|
|
757
|
-
{
|
|
758
|
-
binding: "SESSION",
|
|
759
|
-
id: sessionId
|
|
760
|
-
},
|
|
761
|
-
{
|
|
762
|
-
binding: "HTML_CACHE",
|
|
763
|
-
id: htmlCacheId
|
|
764
|
-
}
|
|
765
|
-
],
|
|
766
|
-
services: [
|
|
767
|
-
{
|
|
768
|
-
binding: "CMS_WORKER",
|
|
769
|
-
service: workerName
|
|
770
|
-
}
|
|
771
|
-
],
|
|
772
|
-
vars: {
|
|
773
|
-
PUBLIC_CMS_URL: cmsFullUrl,
|
|
774
|
-
PUBLIC_API_URL: cmsFullUrl,
|
|
775
|
-
PUBLIC_CHANNEL_ID: channelKey,
|
|
776
|
-
PUBLIC_TREE_ID: treeKey,
|
|
777
|
-
PUBLIC_HOME_SLUG: "home",
|
|
778
|
-
PUBLIC_SITE_NAME: siteLabel
|
|
779
|
-
}
|
|
780
|
-
};
|
|
782
|
+
if (cacheOut.match(/"id":\s*"([a-f0-9]{32})"/)) htmlCacheId = cacheOut.match(/"id":\s*"([a-f0-9]{32})"/)[1];
|
|
783
|
+
} catch (err) { }
|
|
784
|
+
|
|
785
|
+
const siteConfig = {
|
|
786
|
+
$schema: "node_modules/wrangler/config-schema.json",
|
|
787
|
+
name: safeWorkerName,
|
|
788
|
+
compatibility_date: "2024-09-23",
|
|
789
|
+
compatibility_flags: ["nodejs_compat"],
|
|
790
|
+
dev: { host: "localhost", port: 4321 },
|
|
791
|
+
cache: { enabled: true },
|
|
792
|
+
assets: { directory: "./dist/client", binding: "ASSETS", run_worker_first: true },
|
|
793
|
+
kv_namespaces: [{ binding: "SESSION", id: sessionId }, { binding: "HTML_CACHE", id: htmlCacheId }],
|
|
794
|
+
services: [{ binding: "CMS_WORKER", service: workerName }],
|
|
795
|
+
vars: { PUBLIC_CMS_URL: cmsFullUrl, PUBLIC_API_URL: cmsFullUrl, PUBLIC_CHANNEL_ID: channelKey, PUBLIC_TREE_ID: treeKey, PUBLIC_HOME_SLUG: "home", PUBLIC_SITE_NAME: siteLabel }
|
|
796
|
+
};
|
|
781
797
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
pattern: siteDomain,
|
|
785
|
-
custom_domain: true,
|
|
786
|
-
enabled: true,
|
|
787
|
-
previews_enabled: false
|
|
788
|
-
}];
|
|
798
|
+
if (siteDomain !== 'localhost:4321') siteConfig.routes = [{ pattern: siteDomain, custom_domain: true, enabled: true, previews_enabled: false }];
|
|
799
|
+
writeFileSync(join(siteDir, 'wrangler.json'), JSON.stringify(siteConfig, null, 2));
|
|
789
800
|
}
|
|
790
801
|
|
|
791
|
-
writeFileSync(wranglerPath, JSON.stringify(siteConfig, null, 2));
|
|
792
|
-
|
|
793
802
|
const seedSql = `
|
|
794
803
|
-- Seed data for site: ${safeSiteLabel}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
INSERT OR IGNORE INTO
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson)
|
|
802
|
-
VALUES ('${treeKey}', 'Main Tree', 'navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
|
|
803
|
-
|
|
804
|
-
INSERT OR IGNORE INTO channel_trees (channelId, treeId, key)
|
|
805
|
-
VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
|
|
806
|
-
|
|
807
|
-
-- 3. Create the Home Page
|
|
808
|
-
INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson)
|
|
809
|
-
SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"– ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}'
|
|
810
|
-
WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
|
|
811
|
-
|
|
812
|
-
-- 4. Attach the Home Page to the Channel
|
|
813
|
-
INSERT OR IGNORE INTO node_channels (nodeId, channelId)
|
|
814
|
-
VALUES (
|
|
815
|
-
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
816
|
-
(SELECT id FROM channels WHERE key = '${channelKey}')
|
|
817
|
-
);
|
|
818
|
-
|
|
819
|
-
-- 5. Attach the Home Page to the Main Tree
|
|
820
|
-
INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder)
|
|
821
|
-
VALUES (
|
|
822
|
-
(SELECT id FROM trees WHERE key = '${treeKey}'),
|
|
823
|
-
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
824
|
-
NULL,
|
|
825
|
-
0
|
|
826
|
-
);
|
|
804
|
+
INSERT OR IGNORE INTO channels (key, label, channelType, defaultLanguage, isHidden, dataJson) VALUES ('${channelKey}', '${safeSiteLabel}', 'website', 'en', 0, '{}');
|
|
805
|
+
INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson) VALUES ('${treeKey}', 'Main Tree', 'navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
|
|
806
|
+
INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
|
|
807
|
+
INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson) SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"– ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}' WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
|
|
808
|
+
INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ((SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1), (SELECT id FROM channels WHERE key = '${channelKey}'));
|
|
809
|
+
INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES ((SELECT id FROM trees WHERE key = '${treeKey}'), (SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1), NULL, 0);
|
|
827
810
|
`;
|
|
828
811
|
|
|
829
812
|
const workerDir = join(rootDir, 'kama-worker');
|
|
830
|
-
|
|
831
|
-
if (existsSync(workerDir)) {
|
|
832
|
-
appendFileSync(seedPath, seedSql);
|
|
833
|
-
}
|
|
813
|
+
if (existsSync(workerDir)) appendFileSync(join(workerDir, 'seed.sql'), seedSql);
|
|
834
814
|
|
|
835
|
-
|
|
836
|
-
const envContent = [
|
|
837
|
-
`# Local Development Overrides (Production uses wrangler.json vars)`,
|
|
838
|
-
`PUBLIC_CMS_URL="http://localhost:8787"`,
|
|
839
|
-
`PUBLIC_API_URL="http://localhost:8787"`,
|
|
840
|
-
`PUBLIC_CHANNEL_ID="${channelKey}"`,
|
|
841
|
-
`PUBLIC_TREE_ID="${treeKey}"`,
|
|
842
|
-
`PUBLIC_HOME_SLUG="home"`,
|
|
843
|
-
`PUBLIC_SITE_NAME="${siteLabel.replace(/"/g, '\\"')}"`
|
|
844
|
-
].join('\n') + '\n';
|
|
845
|
-
|
|
846
|
-
writeFileSync(join(siteDir, '.env'), envContent);
|
|
815
|
+
writeFileSync(join(siteDir, '.env'), `# Local Development Overrides\nPUBLIC_CMS_URL="http://127.0.0.1:8787"\nPUBLIC_API_URL="http://127.0.0.1:8787"\nPUBLIC_CHANNEL_ID="${channelKey}"\nPUBLIC_TREE_ID="${treeKey}"\nPUBLIC_HOME_SLUG="home"\nPUBLIC_SITE_NAME="${siteLabel.replace(/"/g, '\\"')}"\n`);
|
|
847
816
|
}
|
|
848
817
|
|
|
849
818
|
main().catch(console.error);
|