@brightsideoy/kama 0.1.0-alpha.114 → 0.1.0-alpha.116

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.
Files changed (60) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +130 -221
  3. package/content/definitions/blocks/button.yaml +7 -8
  4. package/content/definitions/blocks/header.yaml +7 -9
  5. package/content/definitions/blocks/header_image.yaml +14 -15
  6. package/content/definitions/blocks/hero.yaml +22 -21
  7. package/content/definitions/blocks/image_card.yaml +46 -47
  8. package/content/definitions/blocks/single_image.yaml +19 -20
  9. package/content/definitions/blocks/text.yaml +8 -9
  10. package/content/definitions/channels/ecommerce.yaml +14 -16
  11. package/content/definitions/channels/website.yaml +20 -21
  12. package/content/definitions/field-sets/access.yaml +3 -5
  13. package/content/definitions/field-sets/channel-base.yaml +25 -25
  14. package/content/definitions/field-sets/content-block.yaml +36 -41
  15. package/content/definitions/field-sets/page-base.yaml +40 -45
  16. package/content/definitions/field-sets/page-meta.yaml +1 -4
  17. package/content/definitions/field-sets/page-social.yaml +6 -8
  18. package/content/definitions/field-sets/tree-base.yaml +25 -25
  19. package/content/definitions/nodes/address.yaml +29 -21
  20. package/content/definitions/nodes/article.yaml +24 -19
  21. package/content/definitions/nodes/event.yaml +32 -26
  22. package/content/definitions/nodes/external-link.yaml +20 -17
  23. package/content/definitions/nodes/page.yaml +38 -35
  24. package/content/definitions/nodes/person.yaml +29 -27
  25. package/content/definitions/nodes/product.yaml +52 -49
  26. package/content/definitions/trees/navigation.yaml +26 -21
  27. package/content/definitions/trees/social-links.yaml +5 -2
  28. package/dist/assets/index-BN9yFvBt.js +162 -0
  29. package/dist/assets/index-CSj1Dbsz.css +1 -0
  30. package/dist/index.html +2 -2
  31. package/dist/index.js +6850 -4563
  32. package/package.json +5 -6
  33. package/schema.sql +5 -13
  34. package/templates/astro-starter/astro.config.mjs +29 -13
  35. package/templates/astro-starter/src/components/blocks/BlockRenderer.astro +125 -0
  36. package/templates/astro-starter/src/components/blocks/ColumnLayout.astro +66 -0
  37. package/templates/astro-starter/src/components/blocks/HeaderImage.astro +131 -0
  38. package/templates/astro-starter/src/components/blocks/Hero.astro +218 -0
  39. package/templates/astro-starter/src/components/blocks/ImageBlock.astro +160 -0
  40. package/templates/astro-starter/src/components/blocks/TextBlock.astro +13 -0
  41. package/templates/astro-starter/src/components/global/Breadcrumb.astro +62 -0
  42. package/templates/astro-starter/src/components/global/Footer.astro +48 -0
  43. package/templates/astro-starter/src/components/global/Header.astro +92 -0
  44. package/templates/astro-starter/src/components/global/NavigationMenu.astro +450 -0
  45. package/templates/astro-starter/src/components/ui/KamaImage.astro +148 -0
  46. package/templates/astro-starter/src/kama-image-service.ts +41 -0
  47. package/templates/astro-starter/src/layouts/Layout.astro +270 -10
  48. package/templates/astro-starter/src/lib/cms.ts +149 -0
  49. package/templates/astro-starter/src/lib/media-url.ts +34 -0
  50. package/templates/astro-starter/src/middleware.ts +238 -28
  51. package/templates/astro-starter/src/pages/404.astro +46 -0
  52. package/templates/astro-starter/src/pages/[...slug].astro +226 -9
  53. package/templates/astro-starter/src/pages/media/[...path].ts +113 -0
  54. package/templates/astro-starter/tsconfig.json +0 -0
  55. package/test-local.sh +9 -1
  56. package/dist/assets/index-10GEw0KY.css +0 -1
  57. package/dist/assets/index-DcFVWhF4.js +0 -1394
  58. package/kama-worker/bundled-definitions.js +0 -2394
  59. package/kama-worker/bundled-definitions.ts +0 -2395
  60. package/scripts/bundle-definitions.js +0 -224
package/README.md CHANGED
@@ -81,7 +81,7 @@ KAMA doesn't just serve content; it actively manages its lifecycle across the gl
81
81
 
82
82
  At the heart of KAMA is the Schema Engine. Instead of complex database migrations, you define your content models, layouts, and reusable blocks in simple YAML files. KAMA dynamically bundles these definitions at build-time to auto-generate your entire Admin UI, database indexes, and API endpoints.
83
83
 
84
- **[Read the full Schema Documentation here](documentation/SCHEMAS.md)**
84
+ **[Read the full Schema Documentation here](/@brightsideoy/kama/documentation/SCHEMAS.md)**
85
85
 
86
86
  <br>
87
87
 
package/bin/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { execSync } from 'node:child_process';
3
- import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, unlinkSync } from 'node:fs';
4
- import { join, dirname, basename } from 'node:path';
3
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, unlinkSync, statSync } from 'node:fs';
4
+ import { join, dirname, basename, relative, resolve } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import * as readline from 'node:readline/promises';
7
7
 
@@ -37,16 +37,21 @@ async function main() {
37
37
  await createNewSiteOnly();
38
38
  } else if (command === 'promote') {
39
39
  await promoteLocalToCloudflare();
40
+ } else if (command === 'bundle') {
41
+ await bundleWorkspaceSchemas();
40
42
  } else {
41
43
  console.log('Available Commands:');
42
44
  console.log(' 1) npx kama init - Kickstart new Monorepo (CMS + Optional Site)');
43
45
  console.log(' 2) npx kama add site - Add new Astro Site to current workspace (sites/)');
44
- console.log(' 3) npx kama promote - Promote current Local workspace to Cloudflare Edge');
46
+ console.log(' 3) npx kama bundle - Bundle YAML schemas for Edge deployment');
47
+ console.log(' 4) npx kama promote - Promote current Local workspace to Cloudflare Edge');
45
48
 
46
- const choice = await rl.question('\nSelect choice [1/2/3]: ');
49
+ const choice = await rl.question('\nSelect choice [1/2/3/4]: ');
47
50
 
48
- if (choice.trim() === '3') {
51
+ if (choice.trim() === '4') {
49
52
  await promoteLocalToCloudflare();
53
+ } else if (choice.trim() === '3') {
54
+ await bundleWorkspaceSchemas();
50
55
  } else if (choice.trim() === '2') {
51
56
  await createNewSiteOnly();
52
57
  } else {
@@ -115,31 +120,23 @@ async function createFullWorkspace() {
115
120
  .env
116
121
  .DS_Store
117
122
  kama-worker/.dev.vars
118
- kama-worker/bundled-definitions.js
119
- kama-worker/bundled-definitions.ts
120
123
  kama-worker/.wrangler/
121
124
  sites/*/.env
122
125
  sites/*/.astro/
123
126
  sites/*/dist/
127
+ kama-worker/workspace-schemas.js
124
128
  `
125
129
  );
126
130
 
127
- const schemaCategories = [
128
- 'block-layouts',
129
- 'blocks',
130
- 'channels',
131
- 'field-sets',
132
- 'node-layouts',
133
- 'nodes',
134
- 'trees'
135
- ];
136
-
137
- for (const category of schemaCategories) {
138
- mkdirSync(join(rootDir, 'content', 'definitions', category), { recursive: true });
131
+ console.log(`\n📄 Copying default content definitions...`);
132
+ const sourceDefsDir = join(__dirname, '../content/definitions');
133
+ const targetDefsDir = join(rootDir, 'content', 'definitions');
134
+ if (existsSync(sourceDefsDir)) {
135
+ cpSync(sourceDefsDir, targetDefsDir, { recursive: true });
136
+ } else {
137
+ console.warn(`⚠️ Could not find default content definitions at ${sourceDefsDir}`);
139
138
  }
140
139
 
141
- scaffoldSampleSchemas(rootDir);
142
-
143
140
  let d1DatabaseId = '00000000-0000-0000-0000-000000000000';
144
141
  let isAuthenticated = false;
145
142
 
@@ -212,9 +209,8 @@ sites/*/dist/
212
209
  }
213
210
 
214
211
  const rootScripts = {
215
- 'bundle:schemas': 'node node_modules/@brightsideoy/kama/scripts/bundle-definitions.js',
216
- 'dev:cms': 'npm run bundle:schemas && npm run dev -w kama-worker',
217
- 'deploy:cms': 'npm run bundle:schemas && npm run deploy -w kama-worker',
212
+ 'dev:cms': 'npm run dev -w kama-worker',
213
+ 'deploy:cms': 'npm run deploy -w kama-worker',
218
214
  };
219
215
 
220
216
  const rootPkg = {
@@ -226,15 +222,23 @@ sites/*/dist/
226
222
  dependencies: {
227
223
  '@brightsideoy/kama': currentKamaVersion,
228
224
  },
229
- devDependencies: {}
225
+ devDependencies: {
226
+ 'wrangler': '^4.130.0' // 🎯 UPDATED TO V4
227
+ }
230
228
  };
231
229
 
230
+ const bundleScript = 'npx kama bundle || node ./node_modules/@brightsideoy/kama/bin/cli.js bundle';
231
+
232
232
  if (shouldCreateSite) {
233
233
  rootPkg.devDependencies['concurrently'] = '^9.0.0';
234
234
  rootPkg.scripts['dev:site'] = `npm run dev -w sites/${siteFolderName}`;
235
+
236
+ // 🎯 Inject schema bundling hook with fallback execution path
237
+ rootPkg.scripts['predev'] = bundleScript;
235
238
  rootPkg.scripts['dev'] = 'npx concurrently "npm run dev:cms" "npm run dev:site"';
236
239
  rootPkg.scripts['deploy:site'] = `npm run deploy -w sites/${siteFolderName}`;
237
240
  } else {
241
+ rootPkg.scripts['predev'] = bundleScript;
238
242
  rootPkg.scripts['dev'] = 'npm run dev:cms';
239
243
  }
240
244
 
@@ -247,20 +251,20 @@ sites/*/dist/
247
251
  const cmsDir = join(rootDir, 'kama-worker');
248
252
  mkdirSync(cmsDir, { recursive: true });
249
253
 
254
+ // 🎯 Worker entry point now attempts to load the workspace schemas
250
255
  const cmsWorkerIndexContent = `import kamaWorker from '@brightsideoy/kama';
251
- import * as bundledModule from './bundled-definitions.js';
252
-
253
- const BUNDLED_DEFINITIONS = bundledModule.BUNDLED_DEFINITIONS || bundledModule;
256
+ import customSchemas from './workspace-schemas.js';
254
257
 
255
258
  export default {
256
259
  async fetch(request, env, ctx) {
257
- const customEnv = {
258
- ...env,
259
- BUNDLED_DEFINITIONS,
260
- };
261
-
262
- return kamaWorker.fetch(request, customEnv, ctx);
263
- },
260
+ if (typeof kamaWorker === 'function') {
261
+ return kamaWorker(request, env, ctx, customSchemas);
262
+ }
263
+ if (kamaWorker && typeof kamaWorker.fetch === 'function') {
264
+ return kamaWorker.fetch(request, env, ctx, customSchemas);
265
+ }
266
+ return new Response('Kama Engine Worker Ready', { status: 200 });
267
+ }
264
268
  };
265
269
  `;
266
270
 
@@ -273,9 +277,9 @@ export default {
273
277
  type: 'module',
274
278
  version: '1.0.0',
275
279
  scripts: {
276
- "bundle:schemas": "node ../node_modules/@brightsideoy/kama/scripts/bundle-definitions.js",
277
- "schema:local": `npm run bundle:schemas && wrangler d1 execute ${dbName} --local --file=../node_modules/@brightsideoy/kama/schema.sql`,
278
- "schema:remote": `npm run bundle:schemas && wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`,
280
+ // 🎯 SILENCED SQL ARRAYS ON LOCAL DEV
281
+ "schema:local": `wrangler d1 execute ${dbName} --local --file=../node_modules/@brightsideoy/kama/schema.sql > /dev/null 2>&1`,
282
+ "schema:remote": `wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`,
279
283
  "dev": "npm run schema:local && wrangler dev",
280
284
  "deploy": "npm run schema:remote && wrangler deploy"
281
285
  },
@@ -283,8 +287,8 @@ export default {
283
287
  '@brightsideoy/kama': currentKamaVersion,
284
288
  },
285
289
  devDependencies: {
286
- wrangler: '^4.0.0',
287
- tsx: '^4.19.2',
290
+ "wrangler": "^4.130.0", // 🎯 UPDATED TO V4
291
+ "tsx": "^4.19.2",
288
292
  },
289
293
  }, null, 2)
290
294
  );
@@ -329,6 +333,9 @@ export default {
329
333
  `# Cloudflare Edge Cache Purging Secrets\nCLOUDFLARE_API_TOKEN=${isCloudflare ? 'cfut_YOUR_CUSTOM_PURGE_TOKEN' : 'local_token'}\n`
330
334
  );
331
335
 
336
+ // Attempt an initial bundle right away so it exists before the user runs anything
337
+ await bundleWorkspaceSchemas(rootDir);
338
+
332
339
  if (shouldCreateSite) {
333
340
  await generateAstroSite(rootDir, siteFolderName, siteDomain, cmsFullUrl, workerName, isCloudflare);
334
341
  } else {
@@ -399,6 +406,63 @@ async function createNewSiteOnly() {
399
406
  console.log(`\n✨ Site created in sites/${siteFolder}! Run 'npm install' at workspace root.`);
400
407
  }
401
408
 
409
+ /**
410
+ * COMMAND: npx kama bundle
411
+ * Reads YAML from workspace and builds a static module for the worker
412
+ */
413
+ async function bundleWorkspaceSchemas(targetRootDir) {
414
+ const rootDir = targetRootDir || process.cwd();
415
+ const defsDir = join(rootDir, 'content', 'definitions');
416
+ const workerDir = join(rootDir, 'kama-worker');
417
+
418
+ if (!existsSync(defsDir)) {
419
+ console.warn(`\n⚠️ Skipping schema bundling: 'content/definitions' folder not found at ${defsDir}`);
420
+ return;
421
+ }
422
+
423
+ console.log(`\n📦 Bundling workspace YAML schemas for Edge deployment...`);
424
+
425
+ function crawlDirectory(dir, baseDir, result = {}) {
426
+ if (!existsSync(dir)) return result;
427
+ const items = readdirSync(dir);
428
+ for (const item of items) {
429
+ const fullPath = join(dir, item);
430
+ if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
431
+ crawlDirectory(fullPath, baseDir, result);
432
+ } else if (fullPath.endsWith('.yaml') || fullPath.endsWith('.yml')) {
433
+ const relativePath = './' + relative(baseDir, fullPath).replace(/\\/g, '/');
434
+ result[relativePath] = readFileSync(fullPath, 'utf-8');
435
+ }
436
+ }
437
+ return result;
438
+ }
439
+
440
+ const rawGlobs = {
441
+ nodes: crawlDirectory(join(defsDir, 'nodes'), defsDir),
442
+ trees: crawlDirectory(join(defsDir, 'trees'), defsDir),
443
+ blocks: crawlDirectory(join(defsDir, 'blocks'), defsDir),
444
+ nodeLayouts: crawlDirectory(join(defsDir, 'node-layouts'), defsDir),
445
+ blockLayouts: crawlDirectory(join(defsDir, 'block-layouts'), defsDir),
446
+ fieldSets: crawlDirectory(join(defsDir, 'field-sets'), defsDir),
447
+ channels: crawlDirectory(join(defsDir, 'channels'), defsDir),
448
+ };
449
+
450
+ const fileContent = `// AUTO-GENERATED BUNDLE - DO NOT EDIT
451
+ // This file is generated by 'npx kama bundle' prior to local dev or deployment.
452
+
453
+ export default ${JSON.stringify(rawGlobs, null, 2)};
454
+ `;
455
+
456
+ if (!existsSync(workerDir)) {
457
+ mkdirSync(workerDir, { recursive: true });
458
+ }
459
+
460
+ const outPath = join(workerDir, 'workspace-schemas.js');
461
+ writeFileSync(outPath, fileContent, 'utf-8');
462
+
463
+ console.log(`✅ Schema bundle generated successfully at ${outPath}`);
464
+ }
465
+
402
466
  /**
403
467
  * COMMAND: npx kama promote
404
468
  * Promote current Local workspace to Cloudflare Edge
@@ -480,114 +544,7 @@ async function promoteLocalToCloudflare() {
480
544
  }
481
545
 
482
546
  /**
483
- * Helper: Scaffolds initial starter schemas for all category folders
484
- */
485
- function scaffoldSampleSchemas(rootDir) {
486
- const defsDir = join(rootDir, 'content', 'definitions');
487
-
488
- writeFileSync(join(defsDir, 'channels', 'website.yaml'), `id: website
489
- label: Main Website
490
- defaultLanguage: en
491
- languages:
492
- - en
493
- - fi
494
- `);
495
-
496
- writeFileSync(join(defsDir, 'nodes', 'page.yaml'), `id: page
497
- label: Page
498
- inTree: true
499
- inVault: false
500
- hasCanvas: true
501
- tabs:
502
- settings:
503
- label: Settings
504
- fields:
505
- title:
506
- label: Page Title
507
- type: text
508
- required: true
509
- slug:
510
- label: URL Slug
511
- type: slug
512
- linkedTo: title
513
- `);
514
-
515
- writeFileSync(join(defsDir, 'nodes', 'article.yaml'), `id: article
516
- label: Article
517
- inTree: false
518
- inVault: true
519
- hasCanvas: true
520
- tabs:
521
- settings:
522
- label: Settings
523
- fields:
524
- title:
525
- label: Title
526
- type: text
527
- required: true
528
- slug:
529
- label: Slug
530
- type: slug
531
- linkedTo: title
532
- `);
533
-
534
- writeFileSync(join(defsDir, 'blocks', 'hero.yaml'), `id: hero
535
- label: Hero Section
536
- fields:
537
- heading:
538
- label: Heading
539
- type: text
540
- required: true
541
- subheading:
542
- label: Subheading
543
- type: text
544
- `);
545
-
546
- writeFileSync(join(defsDir, 'blocks', 'text.yaml'), `id: text
547
- label: Text Block
548
- fields:
549
- content:
550
- label: Content
551
- type: richtext
552
- `);
553
-
554
- writeFileSync(join(defsDir, 'block-layouts', 'two-column.yaml'), `id: two-column
555
- label: Two Column Layout
556
- regions:
557
- left:
558
- label: Left Column
559
- right:
560
- label: Right Column
561
- `);
562
-
563
- writeFileSync(join(defsDir, 'node-layouts', 'single-column.yml'), `id: single-column
564
- label: Single Column Page
565
- regions:
566
- main:
567
- label: Main Content Area
568
- `);
569
-
570
- writeFileSync(join(defsDir, 'field-sets', 'page-base.yaml'), `id: page-base
571
- label: Base Page Fields
572
- fields:
573
- metaTitle:
574
- label: Meta Title
575
- type: text
576
- metaDescription:
577
- label: Meta Description
578
- type: text
579
- `);
580
-
581
- writeFileSync(join(defsDir, 'trees', 'navigation.yaml'), `id: navigation
582
- label: Main Navigation Tree
583
- maxDepth: 3
584
- allowedNodeTypes:
585
- - page
586
- `);
587
- }
588
-
589
- /**
590
- * Helper: Copies the Astro starter template and configures environment variables
547
+ * Helper: Copies the Astro starter template and hydrates runtime tokens
591
548
  */
592
549
  async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, workerName = 'kama-worker', isCloudflare = false) {
593
550
  console.log(`\n🚀 Scaffolding Astro site (${siteFolder}) mapped to ${siteDomain} (Service: ${workerName})...`);
@@ -601,10 +558,10 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
601
558
  return;
602
559
  }
603
560
 
604
- // 1. Copy the full template structure recursively
561
+ // 1. Copy the full, complete starter template directory directly
605
562
  cpSync(templateDir, siteDir, { recursive: true });
606
563
 
607
- // 2. Hydrate package.json template with dynamic values
564
+ // 2. Hydrate package.json from template
608
565
  const templatePkgPath = join(siteDir, 'package.json.template');
609
566
  if (existsSync(templatePkgPath)) {
610
567
  const pkgContent = readFileSync(templatePkgPath, 'utf-8')
@@ -615,81 +572,33 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
615
572
  unlinkSync(templatePkgPath);
616
573
  }
617
574
 
618
- // 3. Generate dynamic wrangler.json configuration for the frontend
619
- const siteWranglerConfig = {
620
- $schema: 'node_modules/wrangler/config-schema.json',
621
- name: siteFolder,
622
- compatibility_date: '2026-08-01',
623
- compatibility_flags: ['nodejs_compat'],
624
- assets: {
625
- directory: './dist/client',
626
- binding: 'ASSETS',
627
- html_handling: 'drop-trailing-slash',
628
- not_found_handling: '404-page',
629
- run_worker_first: true
630
- },
631
- services: [{ binding: 'CMS_WORKER', service: workerName }],
632
- kv_namespaces: [{ binding: "HTML_CACHE", id: "REPLACE_WITH_YOUR_KV_ID", preview_id: "LOCAL_DEV_KV" }],
633
- vars: {
634
- PUBLIC_CMS_URL: cmsFullUrl,
635
- PUBLIC_API_URL: cmsFullUrl,
636
- },
637
- };
638
-
639
- if (isCloudflare) {
640
- siteWranglerConfig.routes = [{ pattern: siteDomain, custom_domain: true }];
641
- }
642
-
643
- writeFileSync(
644
- join(siteDir, 'wrangler.json'),
645
- JSON.stringify(siteWranglerConfig, null, 2)
646
- );
575
+ // 3. Hydrate wrangler.json tokens
576
+ const wranglerPath = join(siteDir, 'wrangler.json');
577
+ if (existsSync(wranglerPath)) {
578
+ let wranglerStr = readFileSync(wranglerPath, 'utf-8')
579
+ .replace(/\{\{SITE_NAME\}\}/g, siteFolder)
580
+ .replace(/\{\{WORKER_NAME\}\}/g, workerName)
581
+ .replace(/\{\{CMS_URL\}\}/g, cmsFullUrl);
647
582
 
648
- // 4. Create dynamic .env file
649
- writeFileSync(
650
- join(siteDir, '.env'),
651
- `PUBLIC_CMS_URL="${cmsFullUrl}"\nPUBLIC_API_URL="${cmsFullUrl}"\n`
652
- );
583
+ if (isCloudflare) {
584
+ const configObj = JSON.parse(wranglerStr);
585
+ configObj.routes = [{ pattern: siteDomain, custom_domain: true }];
586
+ wranglerStr = JSON.stringify(configObj, null, 2);
587
+ }
653
588
 
654
- // 5. Configure Astro & Vite to bypass disk-based SSR dependency optimization
655
- const cmsHostname = cmsFullUrl.replace(/^https?:\/\//, '').split(':')[0];
656
- const astroConfigContent = `import { defineConfig } from 'astro/config';
657
- import cloudflare from '@astrojs/cloudflare';
658
-
659
- export default defineConfig({
660
- output: 'server',
661
- trailingSlash: 'ignore',
662
- image: {
663
- remotePatterns: [
664
- { protocol: 'http', hostname: 'localhost', port: '8787' },
665
- { protocol: '${isCloudflare ? 'https' : 'http'}', hostname: '${cmsHostname}' }
666
- ]
667
- },
668
- build: {
669
- inlineStylesheets: 'always',
670
- },
671
- adapter: cloudflare({
672
- imageService: 'cloudflare',
673
- }),
674
- vite: {
675
- optimizeDeps: {
676
- exclude: ['cloudflare:workers', 'astro']
677
- },
678
- ssr: {
679
- target: 'webworker',
680
- noExternal: true,
681
- external: ['cloudflare:workers', 'node:process']
589
+ writeFileSync(wranglerPath, wranglerStr);
682
590
  }
683
- }
684
- });`;
685
-
686
- writeFileSync(join(siteDir, 'astro.config.mjs'), astroConfigContent);
687
591
 
688
- if (isCloudflare) {
689
- console.log(`\n⚠️ Note for Astro Frontend: You will need to create a KV Namespace for the HTML Cache.`);
690
- console.log(` Run: npx wrangler kv:namespace create HTML_CACHE`);
691
- console.log(` Then update the ID in sites/${siteFolder}/wrangler.json`);
692
- }
592
+ // 4. Create dynamic .env file
593
+ const envContent = [
594
+ `PUBLIC_CMS_URL="${cmsFullUrl}"`,
595
+ `PUBLIC_API_URL="${cmsFullUrl}"`,
596
+ `PUBLIC_CHANNEL_ID="website"`,
597
+ `PUBLIC_TREE_ID="main-navigation"`,
598
+ `PUBLIC_SITE_NAME="KAMA Starter"`
599
+ ].join('\n') + '\n';
600
+
601
+ writeFileSync(join(siteDir, '.env'), envContent);
693
602
  }
694
603
 
695
604
  main().catch(console.error);
@@ -4,12 +4,11 @@ group: Content
4
4
  description: Button text
5
5
 
6
6
  fields:
7
- - text:
8
- label: Text
9
- type: richtext
10
- editor: button
11
- public: true
7
+ text:
8
+ label: Text
9
+ type: richtext
10
+ editor: button
11
+ public: true
12
12
 
13
- - fieldSet: access
14
- - hidden:
15
- default: false
13
+ tabs:
14
+ access: !include ../field-sets/access.yaml
@@ -3,13 +3,11 @@ label: Header
3
3
  group: Content
4
4
 
5
5
  fields:
6
- - headline:
7
- type: richtext
8
- editor: header
9
- label: Headline
10
- public: true
11
- default: "Header here..."
6
+ headline:
7
+ type: richtext
8
+ editor: header
9
+ label: Headline
10
+ public: true
12
11
 
13
- - fieldSet: access
14
- - hidden:
15
- default: false
12
+ tabs:
13
+ access: !include ../field-sets/access.yaml
@@ -4,19 +4,18 @@ group: Media
4
4
  description: Image for page header.
5
5
 
6
6
  fields:
7
- - image:
8
- label: Image
9
- type: asset
10
- required: true
11
- multiple: false
12
- maxSizeMB: 15
13
- allowedTypes: ["image/*"]
14
- crops:
15
- standard:
16
- label: "Page header (21:9)"
17
- aspectRatio: 2.333
18
- public: true
7
+ image:
8
+ label: Image
9
+ type: asset
10
+ required: true
11
+ multiple: false
12
+ maxSizeMB: 15
13
+ allowedTypes: ["image/*"]
14
+ crops:
15
+ standard:
16
+ label: "Page header (21:9)"
17
+ aspectRatio: 2.333
18
+ public: true
19
19
 
20
- - fieldSet: access
21
- - hidden:
22
- default: false
20
+ tabs:
21
+ access: !include ../field-sets/access.yaml
@@ -3,25 +3,26 @@ label: Hero
3
3
  group: Content
4
4
 
5
5
  fields:
6
- - heroBadge:
7
- type: text
8
- label: Badge
9
- public: true
10
- - heroTitle:
11
- type: text
12
- label: Title
13
- public: true
14
- - heroSubTitle:
15
- type: text
16
- label: Sub-Title
17
- public: true
18
- - headline:
19
- type: richtext
20
- editor: header
21
- label: Headline
22
- public: true
23
- default: "Header here..."
6
+ heroBadge:
7
+ type: text
8
+ label: Badge
9
+ public: true
24
10
 
25
- - fieldSet: access
26
- - hidden:
27
- default: false
11
+ heroTitle:
12
+ type: text
13
+ label: Title
14
+ public: true
15
+
16
+ heroSubTitle:
17
+ type: text
18
+ label: Sub-Title
19
+ public: true
20
+
21
+ headline:
22
+ type: richtext
23
+ editor: header
24
+ label: Headline
25
+ public: true
26
+
27
+ tabs:
28
+ access: !include ../field-sets/access.yaml