@brightsideoy/kama 0.1.0-alpha.155 → 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 +229 -231
- 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 +100 -28
- 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 +131 -18
- package/templates/astro-starter/src/pages/[...slug].astro +10 -9
- package/definitions/_page.yaml +0 -52
- package/dist/assets/index-DGHRgyms.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,21 +503,14 @@ 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
|
-
|
|
539
|
-
cmsFullUrl = detectedCmsDomain.startsWith('http')
|
|
540
|
-
? detectedCmsDomain
|
|
541
|
-
: `https://${detectedCmsDomain.replace(/^https?:\/\//, '')}`;
|
|
542
|
-
console.log(`ℹ️ Auto-detected CMS Admin Domain: ${cmsFullUrl}`);
|
|
512
|
+
cmsFullUrl = detectedCmsDomain.startsWith('http') ? detectedCmsDomain : `https://${detectedCmsDomain.replace(/^https?:\/\//, '')}`;
|
|
543
513
|
} else {
|
|
544
|
-
// Fallback prompt only if no wrangler config was found
|
|
545
514
|
const cmsDomainInput = (await rl.question('CMS API Domain (e.g., admin.brand.com): ')).trim();
|
|
546
515
|
cmsFullUrl = `https://${cmsDomainInput.replace(/^https?:\/\//, '')}`;
|
|
547
516
|
}
|
|
@@ -551,7 +520,6 @@ async function createNewSiteOnly() {
|
|
|
551
520
|
|
|
552
521
|
console.log(`\n✨ Site created in sites/${siteFolder}!`);
|
|
553
522
|
console.log(`📦 Run 'npm install' at workspace root.`);
|
|
554
|
-
console.log(`🌱 Run 'npm run dev' to boot up and seed the new site data.`);
|
|
555
523
|
}
|
|
556
524
|
|
|
557
525
|
/**
|
|
@@ -559,20 +527,12 @@ async function createNewSiteOnly() {
|
|
|
559
527
|
*/
|
|
560
528
|
async function bundleWorkspaceSchemas(targetRootDir) {
|
|
561
529
|
let rootDir = targetRootDir || process.cwd();
|
|
562
|
-
|
|
563
|
-
if (basename(rootDir) === 'kama-worker') {
|
|
564
|
-
rootDir = resolve(rootDir, '..');
|
|
565
|
-
}
|
|
530
|
+
if (basename(rootDir) === 'kama-worker') rootDir = resolve(rootDir, '..');
|
|
566
531
|
|
|
567
532
|
try {
|
|
568
533
|
let compilerPath = join(__dirname, '../dist/schema-compiler.js');
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
const compilerUrl = pathToFileURL(compilerPath).href;
|
|
575
|
-
await import(compilerUrl);
|
|
534
|
+
if (!existsSync(compilerPath)) compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
|
|
535
|
+
await import(pathToFileURL(compilerPath).href);
|
|
576
536
|
} catch (e) {
|
|
577
537
|
console.error(`❌ Schema compilation failed:`, e.message || e);
|
|
578
538
|
}
|
|
@@ -580,100 +540,166 @@ async function bundleWorkspaceSchemas(targetRootDir) {
|
|
|
580
540
|
|
|
581
541
|
/**
|
|
582
542
|
* COMMAND: npx kama promote
|
|
583
|
-
* Promote current Local workspace to Cloudflare Edge
|
|
584
543
|
*/
|
|
585
544
|
async function promoteLocalToCloudflare() {
|
|
586
545
|
const rootDir = process.cwd();
|
|
587
|
-
const
|
|
546
|
+
const workerDir = join(rootDir, 'kama-worker');
|
|
547
|
+
const rootPkgPath = join(rootDir, 'package.json');
|
|
588
548
|
|
|
589
|
-
if (!existsSync(
|
|
590
|
-
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.');
|
|
591
551
|
return;
|
|
592
552
|
}
|
|
593
553
|
|
|
594
|
-
console.log('\n🌐 ---
|
|
554
|
+
console.log('\n🌐 --- UPGRADING WORKSPACE TO CLOUDFLARE EDGE --- 🌐\n');
|
|
595
555
|
|
|
596
556
|
try {
|
|
597
557
|
execSync('npx wrangler whoami', { stdio: 'pipe' });
|
|
598
558
|
console.log('✅ Logged in to Cloudflare.');
|
|
599
559
|
} catch (e) {
|
|
600
560
|
console.log('🌐 Launching browser for Cloudflare login...');
|
|
601
|
-
try {
|
|
602
|
-
|
|
603
|
-
} catch (loginError) {
|
|
604
|
-
console.log('❌ Cloudflare login failed or was cancelled.');
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
561
|
+
try { execSync('npx wrangler login', { stdio: 'inherit' }); }
|
|
562
|
+
catch (loginError) { console.log('❌ Cloudflare login failed.'); return; }
|
|
607
563
|
}
|
|
608
564
|
|
|
609
565
|
const cmsDomain = (await rl.question('\nCMS Admin Domain (e.g., admin.yourdomain.com): ')).trim();
|
|
610
566
|
|
|
611
567
|
const sitesFolderDir = join(rootDir, 'sites');
|
|
612
568
|
let siteDomain = '';
|
|
569
|
+
let siteDir = null;
|
|
613
570
|
if (existsSync(sitesFolderDir)) {
|
|
614
|
-
|
|
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
|
+
}
|
|
615
576
|
}
|
|
616
577
|
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
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, '_');
|
|
621
580
|
let d1DatabaseId = '00000000-0000-0000-0000-000000000000';
|
|
622
581
|
|
|
623
582
|
try {
|
|
624
583
|
const d1Output = execSync(`npx wrangler d1 create ${dbName}`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
625
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}/);
|
|
626
585
|
if (match) d1DatabaseId = match[0];
|
|
627
|
-
} catch (err) {
|
|
628
|
-
|
|
629
|
-
|
|
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
|
+
};
|
|
630
611
|
|
|
612
|
+
currentConfig.dev = currentConfig.dev || { host: 'localhost', port: 8787 };
|
|
631
613
|
currentConfig.cache = { enabled: true };
|
|
632
614
|
currentConfig.vars.CDN_DOMAIN = cmsDomain;
|
|
633
|
-
if (siteDomain) {
|
|
634
|
-
currentConfig.vars.PUBLIC_FRONTEND_URL = `https://${siteDomain}`;
|
|
635
|
-
}
|
|
615
|
+
if (siteDomain) currentConfig.vars.PUBLIC_FRONTEND_URL = `https://${siteDomain}`;
|
|
636
616
|
currentConfig.routes = [{ pattern: cmsDomain, custom_domain: true }];
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
617
|
+
currentConfig.d1_databases = [{ binding: 'DB', database_name: dbName, database_id: d1DatabaseId }];
|
|
618
|
+
currentConfig.r2_buckets = [{ binding: 'MEDIA_BUCKET', bucket_name: bucketName }];
|
|
640
619
|
|
|
641
620
|
writeFileSync(workerWranglerPath, JSON.stringify(currentConfig, null, 2));
|
|
642
621
|
|
|
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
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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));
|
|
671
699
|
}
|
|
672
700
|
}
|
|
673
701
|
|
|
674
|
-
console.log(`\n✅ Workspace successfully
|
|
675
|
-
console.log(`\nNext steps:`);
|
|
676
|
-
console.log(` 1. Run 'npm run deploy:cms' from the root to publish your backend and database.`);
|
|
702
|
+
console.log(`\n✅ Workspace successfully upgraded to Cloudflare Edge!`);
|
|
677
703
|
}
|
|
678
704
|
|
|
679
705
|
/**
|
|
@@ -687,19 +713,54 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
687
713
|
|
|
688
714
|
if (!existsSync(templateDir)) {
|
|
689
715
|
console.error(`❌ Error: Astro template not found at ${templateDir}`);
|
|
690
|
-
console.error(`Please ensure your Kama package installation is complete and templates are published.`);
|
|
691
716
|
return;
|
|
692
717
|
}
|
|
693
718
|
|
|
694
719
|
cpSync(templateDir, siteDir, { recursive: true });
|
|
695
720
|
|
|
721
|
+
const tsConfig = {
|
|
722
|
+
extends: "astro/tsconfigs/strict",
|
|
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));
|
|
727
|
+
|
|
696
728
|
const templatePkgPath = join(siteDir, 'package.json.template');
|
|
697
729
|
if (existsSync(templatePkgPath)) {
|
|
698
|
-
const
|
|
730
|
+
const rawContent = readFileSync(templatePkgPath, 'utf-8')
|
|
699
731
|
.replace(/\{\{SITE_NAME\}\}/g, siteFolder)
|
|
700
732
|
.replace(/\{\{KAMA_VERSION\}\}/g, currentKamaVersion);
|
|
701
733
|
|
|
702
|
-
|
|
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));
|
|
703
764
|
unlinkSync(templatePkgPath);
|
|
704
765
|
}
|
|
705
766
|
|
|
@@ -707,114 +768,51 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
707
768
|
const safeSiteLabel = siteLabel.replace(/'/g, "''");
|
|
708
769
|
const channelKey = siteFolder.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
|
|
709
770
|
const treeKey = 'main-tree';
|
|
710
|
-
|
|
711
|
-
// 🎯 FIX: Completely Generate wrangler.json structurally from scratch with `-site` name appended
|
|
712
771
|
const safeWorkerName = `${siteFolder.toLowerCase().replace(/[^a-z0-9-]/g, '-')}-site`;
|
|
713
772
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
name: safeWorkerName, // 🎯 Uses sanitized name (e.g. doc-kamaengine-com-site)
|
|
718
|
-
compatibility_date: "2024-09-23",
|
|
719
|
-
compatibility_flags: ["nodejs_compat"],
|
|
720
|
-
cache: { enabled: true },
|
|
721
|
-
assets: {
|
|
722
|
-
directory: "./dist/client",
|
|
723
|
-
binding: "ASSETS",
|
|
724
|
-
run_worker_first: true
|
|
725
|
-
},
|
|
726
|
-
kv_namespaces: [
|
|
727
|
-
{
|
|
728
|
-
binding: "SESSION",
|
|
729
|
-
id: "REPLACE_WITH_YOUR_SESSION_KV_ID"
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
binding: "HTML_CACHE",
|
|
733
|
-
id: "REPLACE_WITH_YOUR_HTML_CACHE_KV_ID"
|
|
734
|
-
}
|
|
735
|
-
],
|
|
736
|
-
services: [
|
|
737
|
-
{
|
|
738
|
-
binding: "CMS_WORKER",
|
|
739
|
-
service: workerName // 🎯 Correctly links back to the CMS worker
|
|
740
|
-
}
|
|
741
|
-
],
|
|
742
|
-
vars: {
|
|
743
|
-
PUBLIC_CMS_URL: cmsFullUrl,
|
|
744
|
-
PUBLIC_API_URL: cmsFullUrl,
|
|
745
|
-
PUBLIC_CHANNEL_ID: channelKey,
|
|
746
|
-
PUBLIC_TREE_ID: treeKey,
|
|
747
|
-
PUBLIC_HOME_SLUG: "home",
|
|
748
|
-
PUBLIC_SITE_NAME: siteLabel
|
|
749
|
-
}
|
|
750
|
-
};
|
|
773
|
+
if (isCloudflare) {
|
|
774
|
+
let sessionId = "REPLACE_WITH_YOUR_SESSION_KV_ID";
|
|
775
|
+
let htmlCacheId = "REPLACE_WITH_YOUR_HTML_CACHE_KV_ID";
|
|
751
776
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
777
|
+
try {
|
|
778
|
+
const prefix = siteFolder.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase();
|
|
779
|
+
const sessionOut = execSync(`npx wrangler kv namespace create "SESSION_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
780
|
+
if (sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)) sessionId = sessionOut.match(/"id":\s*"([a-f0-9]{32})"/)[1];
|
|
781
|
+
const cacheOut = execSync(`npx wrangler kv namespace create "HTML_CACHE_${prefix}"`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
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
|
+
};
|
|
761
797
|
|
|
762
|
-
|
|
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));
|
|
800
|
+
}
|
|
763
801
|
|
|
764
802
|
const seedSql = `
|
|
765
803
|
-- Seed data for site: ${safeSiteLabel}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
INSERT OR IGNORE INTO
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson)
|
|
773
|
-
VALUES ('${treeKey}', 'Main Tree', 'navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
|
|
774
|
-
|
|
775
|
-
INSERT OR IGNORE INTO channel_trees (channelId, treeId, key)
|
|
776
|
-
VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
|
|
777
|
-
|
|
778
|
-
-- 3. Create the Home Page
|
|
779
|
-
INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson)
|
|
780
|
-
SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"– ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}'
|
|
781
|
-
WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
|
|
782
|
-
|
|
783
|
-
-- 4. Attach the Home Page to the Channel
|
|
784
|
-
INSERT OR IGNORE INTO node_channels (nodeId, channelId)
|
|
785
|
-
VALUES (
|
|
786
|
-
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
787
|
-
(SELECT id FROM channels WHERE key = '${channelKey}')
|
|
788
|
-
);
|
|
789
|
-
|
|
790
|
-
-- 5. Attach the Home Page to the Main Tree
|
|
791
|
-
INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder)
|
|
792
|
-
VALUES (
|
|
793
|
-
(SELECT id FROM trees WHERE key = '${treeKey}'),
|
|
794
|
-
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
795
|
-
NULL,
|
|
796
|
-
0
|
|
797
|
-
);
|
|
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);
|
|
798
810
|
`;
|
|
799
811
|
|
|
800
812
|
const workerDir = join(rootDir, 'kama-worker');
|
|
801
|
-
|
|
802
|
-
if (existsSync(workerDir)) {
|
|
803
|
-
appendFileSync(seedPath, seedSql);
|
|
804
|
-
}
|
|
813
|
+
if (existsSync(workerDir)) appendFileSync(join(workerDir, 'seed.sql'), seedSql);
|
|
805
814
|
|
|
806
|
-
|
|
807
|
-
const envContent = [
|
|
808
|
-
`# Local Development Overrides (Production uses wrangler.json vars)`,
|
|
809
|
-
`PUBLIC_CMS_URL="http://localhost:8787"`,
|
|
810
|
-
`PUBLIC_API_URL="http://localhost:8787"`,
|
|
811
|
-
`PUBLIC_CHANNEL_ID="${channelKey}"`,
|
|
812
|
-
`PUBLIC_TREE_ID="${treeKey}"`,
|
|
813
|
-
`PUBLIC_HOME_SLUG="home"`,
|
|
814
|
-
`PUBLIC_SITE_NAME="${siteLabel.replace(/"/g, '\\"')}"`
|
|
815
|
-
].join('\n') + '\n';
|
|
816
|
-
|
|
817
|
-
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`);
|
|
818
816
|
}
|
|
819
817
|
|
|
820
818
|
main().catch(console.error);
|