@brightsideoy/kama 0.1.0-alpha.142 → 0.1.0-alpha.145

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 (57) hide show
  1. package/.wrangler/state/v3/cache/default/blobs/4de32ec3e619aa3f9acad3fb1a2528209381347d1cbb86e939e08724f5b35bc4000001a0b2b5b216 +0 -0
  2. package/.wrangler/state/v3/cache/default/blobs/5f895e5810a26a6319bbadde9d751e5b10faae6e141db1c454c5f53b3e725591000001a0b2b624a4 +0 -0
  3. package/.wrangler/state/v3/cache/default/blobs/74744186327d8aaf1c6078e50bc561135fd90690c96bd4b733035d0cb3fedb94000001a0b2b5be6b +0 -0
  4. package/.wrangler/state/v3/cache/default/blobs/79c1c81c1ddcd49f49eb27b9197ae0160c3a7981f308aee2ae972653de1b3668000001a0b2b60e76 +0 -0
  5. package/.wrangler/state/v3/cache/default/blobs/7cd29a3bd95a88e7e896a4ae253758cd9e4bde78fc371077f3fef974cd11c64d000001a0b098ff88 +0 -0
  6. package/.wrangler/state/v3/cache/default/blobs/7ecc4caad58c7ee119c02adb84132eaa691b9a171f932ab1c17e0f95c3fed2a8000001a0b2b5bf5e +0 -0
  7. package/.wrangler/state/v3/cache/default/blobs/81928c274111d2c3cbd3d7174136a2fdce83e267da8f8d0caf60d650396197f5000001a0b098de9d +0 -0
  8. package/.wrangler/state/v3/cache/default/blobs/8c3aa6f6625d7c0d682cb498e6715355aec1905909b04ead5e85adbca3989b19000001a0b098e4ac +0 -0
  9. package/.wrangler/state/v3/cache/default/blobs/97205d84c3e4399f6f51295e8381b21f2a8810cdaecc0ab13f2cadf712fae5f4000001a0b339609d +0 -0
  10. package/.wrangler/state/v3/cache/default/blobs/b48d02100b8f1a9520a209628a0778a0f9e0f4ce0643f8d59b3888bbd0f85fc2000001a0b2b63647 +0 -0
  11. package/.wrangler/state/v3/cache/default/blobs/cf30c018e70dad1c6859277e4361da657b79adf34e60cb05885eb32951fbbafc000001a0b09b168f +0 -0
  12. package/.wrangler/state/v3/cache/default/blobs/d0d796d0fe4efd55f61e0c3b8d30170a89703669a52854687186a66304adbf8a000001a0b2b6244d +0 -0
  13. package/.wrangler/state/v3/cache/miniflare-CacheObject/9f458c07675338a7426a7b81ac4fb1baf92d034efbcaaf4336379640ed744ded.sqlite +0 -0
  14. package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  15. package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  16. package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  17. package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/7cfce387cae19c0dfbb9cc4f2a9c353f60ca0a80fabd0b2e2837d152b58feaaa.sqlite +0 -0
  18. package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite +0 -0
  19. package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-shm +0 -0
  20. package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-wal +0 -0
  21. package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite +0 -0
  22. package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-shm +0 -0
  23. package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-wal +0 -0
  24. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite +0 -0
  25. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-shm +0 -0
  26. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-wal +0 -0
  27. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite +0 -0
  28. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-shm +0 -0
  29. package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-wal +0 -0
  30. package/.wrangler/state/v3/r2/kama-media/blobs/1c7705701fba41f9a2683025d40393711daffc55d32172088a62d8999017e9c6000001a0b339607a +0 -0
  31. package/.wrangler/state/v3/r2/kama-media/blobs/1ee266c53f586a4a57a1d21be291e34bb2e2236c15e43ae30497f6054290f01d000001a0b2b6248c +0 -0
  32. package/.wrangler/state/v3/r2/kama-media/blobs/6db1f8204b6d125f0911b3e42022258cc7e1c37a95c2ce7f5c7f14da31d408ec000001a0b2b60e1f +0 -0
  33. package/.wrangler/state/v3/r2/kama-media/blobs/97b86f251c5d30df5e1eab8662cab83f5f7c4583ad14fd2d5ea99f16fdcfd6ef000001a0b2b62482 +0 -0
  34. package/.wrangler/state/v3/r2/miniflare-R2BucketObject/9ffe30cff37d40b366f64100a8f041c0a1e5aee78708ba90b9ef4ca6a6b2d883.sqlite +0 -0
  35. package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite +0 -0
  36. package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-shm +0 -0
  37. package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-wal +0 -0
  38. package/README.md +16 -37
  39. package/bin/cli.js +190 -147
  40. package/definitions/_page.yaml +52 -0
  41. package/dist/assets/index-BSBvGvQz.css +1 -0
  42. package/dist/assets/index-RzfH6iq3.js +162 -0
  43. package/dist/dist-CZEgSuN0.js +8674 -0
  44. package/dist/index.html +2 -2
  45. package/dist/index.js +6856 -11229
  46. package/dist/schema-compiler.js +38 -0
  47. package/npm-test.sh +75 -0
  48. package/package.json +14 -10
  49. package/schema.sql +3 -2
  50. package/templates/astro-starter/src/components/blocks/ImageBlock.astro +20 -56
  51. package/templates/astro-starter/src/components/global/Header.astro +19 -12
  52. package/templates/astro-starter/src/components/ui/KamaImage.astro +49 -73
  53. package/templates/astro-starter/src/pages/[...slug].astro +16 -43
  54. package/templates/astro-starter/src/pages/media/[...path].ts +8 -1
  55. package/wrangler.json +22 -0
  56. package/dist/assets/index-Bv7fPRX7.css +0 -1
  57. package/dist/assets/index-SWBz-Fr1.js +0 -162
package/bin/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { execSync } from 'node:child_process';
3
- import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, unlinkSync, statSync, appendFileSync } from 'node:fs';
4
- import { join, dirname, basename, relative, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
3
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, statSync, unlinkSync, appendFileSync } from 'node:fs';
4
+ import { join, dirname, basename, resolve, relative } from 'node:path';
5
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
6
  import * as readline from 'node:readline/promises';
7
7
 
8
8
  // Dynamically resolve current package version
@@ -30,7 +30,7 @@ function showHelp() {
30
30
  console.log('Commands:');
31
31
  console.log(' init Kickstart a new Monorepo (CMS Worker + Optional Astro Site)');
32
32
  console.log(' add site Add a new Astro Frontend Site to the current workspace (sites/)');
33
- console.log(' bundle Bundle YAML schemas into a static module for Edge deployment');
33
+ console.log(' bundle Compile and bundle YAML schemas into bundled-definitions.js for Edge deployment');
34
34
  console.log(' promote Promote the current Local workspace to Cloudflare Edge');
35
35
  console.log(' help, -h Show this help message\n');
36
36
 
@@ -71,7 +71,7 @@ async function main() {
71
71
  console.log('Available Commands:');
72
72
  console.log(' 1) npx kama init - Kickstart new Monorepo (CMS + Optional Site)');
73
73
  console.log(' 2) npx kama add site - Add new Astro Site to current workspace (sites/)');
74
- console.log(' 3) npx kama bundle - Bundle YAML schemas for Edge deployment');
74
+ console.log(' 3) npx kama bundle - Compile and bundle YAML schemas for Edge deployment');
75
75
  console.log(' 4) npx kama promote - Promote current Local workspace to Cloudflare Edge');
76
76
  console.log(' 5) Help - Show all commands and usage');
77
77
 
@@ -110,9 +110,9 @@ async function createFullWorkspace() {
110
110
  const projName = isCurrentDir ? cwdName : chosenFolder;
111
111
  const rootDir = isCurrentDir ? process.cwd() : join(process.cwd(), projName);
112
112
 
113
- console.log('\nšŸŒ Where do you plan to deploy KAMA?');
114
- console.log(' 1) Local Development Only (SQLite / Testing)');
115
- console.log(' 2) Cloudflare Edge (Workers / D1 / R2)');
113
+ console.log('\nšŸŒ Choose your Deployment Architecture:');
114
+ console.log(' 1) VPS / Local Server (Node.js, SQLite, Sharp cropping)');
115
+ console.log(' 2) Cloudflare Edge (Workers, D1, R2, CF Image Resizing)');
116
116
  const envChoice = await rl.question('\nChoice [1/2]: ');
117
117
  const isCloudflare = envChoice.trim() === '2';
118
118
 
@@ -150,16 +150,7 @@ async function createFullWorkspace() {
150
150
 
151
151
  writeFileSync(
152
152
  join(rootDir, '.gitignore'),
153
- `node_modules/
154
- .env
155
- .DS_Store
156
- kama-worker/.dev.vars
157
- kama-worker/.wrangler/
158
- sites/*/.env
159
- sites/*/.astro/
160
- sites/*/dist/
161
- kama-worker/workspace-schemas.js
162
- `
153
+ `node_modules/\n.env\n.DS_Store\nkama-worker/.dev.vars\nkama-worker/.env\nkama-worker/.wrangler/\nkama-worker/public/\nkama-worker/*.db\nsites/*/.env\nsites/*/.astro/\nsites/*/dist/\nkama-worker/bundled-definitions.js\n`
163
154
  );
164
155
 
165
156
  console.log(`\nšŸ“„ Copying default content definitions...`);
@@ -239,7 +230,7 @@ kama-worker/workspace-schemas.js
239
230
  console.log(`āš ļø Skipping database creation. We'll leave a placeholder in wrangler.json.`);
240
231
  }
241
232
  } else {
242
- console.log(`\nšŸ’» Local mode selected. Skipping Cloudflare authentication and domain setup...`);
233
+ console.log(`\nšŸ’» Local VPS mode selected. Skipping Cloudflare authentication and domain setup...`);
243
234
  }
244
235
 
245
236
  const rootScripts = {
@@ -257,21 +248,18 @@ kama-worker/workspace-schemas.js
257
248
  '@brightsideoy/kama': currentKamaVersion,
258
249
  },
259
250
  devDependencies: {
260
- 'wrangler': '^4.130.0'
251
+ 'wrangler': '^4.0.0'
261
252
  }
262
253
  };
263
254
 
264
- const bundleScript = 'npx kama bundle || node ./node_modules/@brightsideoy/kama/bin/cli.js bundle';
265
-
266
255
  if (shouldCreateSite) {
267
256
  rootPkg.devDependencies['concurrently'] = '^9.0.0';
268
257
  rootPkg.scripts['dev:site'] = `npm run dev -w sites/${siteFolderName}`;
269
-
270
- rootPkg.scripts['predev'] = bundleScript;
258
+ rootPkg.scripts['predev'] = 'npx kama bundle';
271
259
  rootPkg.scripts['dev'] = 'npx concurrently "npm run dev:cms" "npm run dev:site"';
272
260
  rootPkg.scripts['deploy:site'] = `npm run deploy -w sites/${siteFolderName}`;
273
261
  } else {
274
- rootPkg.scripts['predev'] = bundleScript;
262
+ rootPkg.scripts['predev'] = 'npx kama bundle';
275
263
  rootPkg.scripts['dev'] = 'npm run dev:cms';
276
264
  }
277
265
 
@@ -286,100 +274,182 @@ kama-worker/workspace-schemas.js
286
274
 
287
275
  writeFileSync(join(cmsDir, 'seed.sql'), '-- Kama Auto-Generated Seed File\nSELECT 1;\n');
288
276
 
289
- const cmsWorkerIndexContent = `import kamaWorker from '@brightsideoy/kama';
290
- import customSchemas from './workspace-schemas.js';
277
+ // Initial default bundle with dual exports to satisfy ESM and CJS consumers
278
+ const emptyDefs = `{ nodes: {}, trees: {}, blocks: {}, nodeLayouts: {}, blockLayouts: {}, channels: {} }`;
279
+ writeFileSync(join(cmsDir, 'bundled-definitions.js'), `const defs = ${emptyDefs};\nexport const BUNDLED_DEFINITIONS = defs;\nexport default defs;\n`);
280
+
281
+ // šŸŽÆ ARCHITECTURE SPLIT: Node.js vs Cloudflare
282
+ if (isCloudflare) {
283
+ const cmsWorkerIndexContent = `import kamaWorker from '@brightsideoy/kama';
284
+ import * as localBundle from './bundled-definitions.js';
291
285
 
292
286
  export default {
293
287
  async fetch(request, env, ctx) {
294
- // šŸŽÆ FIX 1: Safely unwrap the ESM default export so the Engine sees local schemas
295
- const resolvedSchemas = customSchemas.default || customSchemas;
296
-
297
- // šŸŽÆ FIX 2: Mutate the Cloudflare env directly instead of spreading it!
298
- // Spreading {...env} breaks Cloudflare D1/R2 proxy bindings.
299
- env.BUNDLED_DEFINITIONS = resolvedSchemas;
288
+ const schemas = localBundle.BUNDLED_DEFINITIONS || localBundle.default || localBundle;
289
+ // Inject runtime flag natively
290
+ const customEnv = { ...env, BUNDLED_DEFINITIONS: schemas, KAMA_RUNTIME: 'cloudflare' };
300
291
 
301
- // Execute the Hono app fetch handler
302
292
  if (kamaWorker && typeof kamaWorker.fetch === 'function') {
303
- return kamaWorker.fetch(request, env, ctx);
293
+ return kamaWorker.fetch(request, customEnv, ctx);
304
294
  }
305
295
 
306
- // Fallback just in case the export structure changes
307
296
  if (kamaWorker && kamaWorker.app && typeof kamaWorker.app.fetch === 'function') {
308
- return kamaWorker.app.fetch(request, env, ctx);
297
+ return kamaWorker.app.fetch(request, customEnv, ctx);
309
298
  }
310
299
 
311
300
  return new Response('Kama Engine Worker Ready', { status: 200 });
312
301
  }
313
302
  };
314
303
  `;
315
-
316
- writeFileSync(join(cmsDir, 'index.js'), cmsWorkerIndexContent);
317
-
318
- // šŸŽÆ THE FINAL FIX: Automatically run `npx kama bundle` before Dev or Deploy inside the worker!
319
- writeFileSync(
320
- join(cmsDir, 'package.json'),
321
- JSON.stringify({
304
+ writeFileSync(join(cmsDir, 'index.js'), cmsWorkerIndexContent);
305
+
306
+ writeFileSync(
307
+ join(cmsDir, 'package.json'),
308
+ JSON.stringify({
309
+ name: workerName,
310
+ type: 'module',
311
+ version: '1.0.0',
312
+ scripts: {
313
+ "schema:local": `wrangler d1 execute ${dbName} --local --file=../node_modules/@brightsideoy/kama/schema.sql > /dev/null 2>&1`,
314
+ "schema:remote": `wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`,
315
+ "seed:local": `wrangler d1 execute ${dbName} --local --file=seed.sql > /dev/null 2>&1`,
316
+ "seed:remote": `wrangler d1 execute ${dbName} --remote --file=seed.sql`,
317
+ "dev": "npm run schema:local && npm run seed:local && wrangler dev --remote --log-level warn --inspector-port=9230",
318
+ "deploy": "npm run schema:remote && npm run seed:remote && wrangler deploy"
319
+ },
320
+ dependencies: {
321
+ '@brightsideoy/kama': currentKamaVersion,
322
+ },
323
+ devDependencies: {
324
+ "wrangler": "^4.0.0"
325
+ },
326
+ }, null, 2)
327
+ );
328
+
329
+ const cmsWranglerConfig = {
330
+ $schema: '../node_modules/wrangler/config-schema.json',
322
331
  name: workerName,
323
- type: 'module',
324
- version: '1.0.0',
325
- scripts: {
326
- "bundle": "npx kama bundle",
327
- "schema:local": `wrangler d1 execute ${dbName} --local --file=../node_modules/@brightsideoy/kama/schema.sql > /dev/null 2>&1`,
328
- "schema:remote": `wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`,
329
- "seed:local": `wrangler d1 execute ${dbName} --local --file=seed.sql > /dev/null 2>&1`,
330
- "seed:remote": `wrangler d1 execute ${dbName} --remote --file=seed.sql`,
331
- "dev": "npm run bundle && npm run schema:local && npm run seed:local && wrangler dev",
332
- "deploy": "npm run bundle && npm run schema:remote && npm run seed:remote && wrangler deploy"
332
+ main: 'index.js',
333
+ compatibility_date: '2024-09-23',
334
+ compatibility_flags: ['nodejs_compat'],
335
+ assets: {
336
+ directory: '../node_modules/@brightsideoy/kama/dist',
337
+ binding: 'ASSETS'
333
338
  },
334
- dependencies: {
335
- '@brightsideoy/kama': currentKamaVersion,
339
+ images: {
340
+ binding: 'IMAGES'
336
341
  },
337
- devDependencies: {
338
- "wrangler": "^4.130.0",
339
- "tsx": "^4.19.2",
342
+ vars: {
343
+ CDN_DOMAIN: cmsDomain,
344
+ PUBLIC_FRONTEND_URL: (shouldCreateSite) ? `https://${siteDomain}` : 'http://localhost:4321',
345
+ CLOUDFLARE_ZONE_ID: "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID",
346
+ KAMA_RUNTIME: 'cloudflare'
340
347
  },
341
- }, null, 2)
342
- );
348
+ d1_databases: [{
349
+ binding: 'DB',
350
+ database_name: dbName,
351
+ database_id: d1DatabaseId,
352
+ }],
353
+ r2_buckets: [{
354
+ binding: 'MEDIA_BUCKET',
355
+ bucket_name: bucketName,
356
+ }],
357
+ routes: [{ pattern: cmsDomain, custom_domain: true }]
358
+ };
359
+
360
+ writeFileSync(join(cmsDir, 'wrangler.json'), JSON.stringify(cmsWranglerConfig, null, 2));
361
+ writeFileSync(join(cmsDir, '.dev.vars'), `# Cloudflare Edge Cache Purging Secrets\nCLOUDFLARE_API_TOKEN=cfut_YOUR_CUSTOM_PURGE_TOKEN\n`);
362
+ } else {
363
+ // --- NODE.JS ARCHITECTURE ---
364
+ const nodeServerContent = `import { serve } from '@hono/node-server';
365
+ import { serveStatic } from '@hono/node-server/serve-static';
366
+ import kamaApp from '@brightsideoy/kama';
367
+ import * as localBundle from './bundled-definitions.js';
368
+ import dotenv from 'dotenv';
369
+ import { readFileSync, existsSync } from 'node:fs';
370
+ import { join } from 'node:path';
371
+
372
+ dotenv.config();
373
+
374
+ // šŸŽÆ Dynamically find the Kama package dist folder (handles NPM workspace hoisting)
375
+ const possiblePaths = [
376
+ './node_modules/@brightsideoy/kama/dist',
377
+ '../node_modules/@brightsideoy/kama/dist',
378
+ '../../node_modules/@brightsideoy/kama/dist'
379
+ ];
380
+ const distPath = possiblePaths.find(p => existsSync(p));
381
+
382
+ if (!distPath) {
383
+ console.warn('āš ļø Could not locate @brightsideoy/kama/dist folder. Admin UI will not load.');
384
+ }
343
385
 
344
- const cmsWranglerConfig = {
345
- $schema: '../node_modules/wrangler/config-schema.json',
346
- name: workerName,
347
- main: 'index.js',
348
- compatibility_date: '2026-08-01',
349
- compatibility_flags: ['nodejs_compat'],
350
- assets: {
351
- directory: '../node_modules/@brightsideoy/kama/dist',
352
- binding: 'ASSETS'
353
- },
354
- images: {
355
- binding: 'IMAGES'
356
- },
357
- vars: {
358
- CDN_DOMAIN: cmsDomain,
359
- PUBLIC_FRONTEND_URL: (isCloudflare && shouldCreateSite) ? `https://${siteDomain}` : 'http://localhost:4321',
360
- CLOUDFLARE_ZONE_ID: isCloudflare ? "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID" : "local-zone-not-needed"
361
- },
362
- d1_databases: [{
363
- binding: 'DB',
364
- database_name: dbName,
365
- database_id: d1DatabaseId,
366
- }],
367
- r2_buckets: [{
368
- binding: 'MEDIA_BUCKET',
369
- bucket_name: bucketName,
370
- }],
371
- };
386
+ kamaApp.use('*', async (c, next) => {
387
+ c.env = {
388
+ ...process.env,
389
+ ...c.env,
390
+ BUNDLED_DEFINITIONS: localBundle.BUNDLED_DEFINITIONS,
391
+ KAMA_RUNTIME: 'node'
392
+ };
393
+ await next();
394
+ });
372
395
 
373
- if (isCloudflare) {
374
- cmsWranglerConfig.routes = [{ pattern: cmsDomain, custom_domain: true }];
396
+ kamaApp.use('/media/*', serveStatic({ root: './' }));
397
+
398
+ if (distPath) {
399
+ kamaApp.use('/assets/*', serveStatic({ root: distPath }));
400
+
401
+ kamaApp.get('/*', async (c, next) => {
402
+ if (c.req.path.startsWith('/api') || c.req.path.startsWith('/media')) return next();
403
+
404
+ const indexPath = join(distPath, 'index.html');
405
+ if (existsSync(indexPath)) {
406
+ return c.html(readFileSync(indexPath, 'utf-8'));
375
407
  }
408
+ return next();
409
+ });
410
+ }
376
411
 
377
- writeFileSync(join(cmsDir, 'wrangler.json'), JSON.stringify(cmsWranglerConfig, null, 2));
412
+ const port = process.env.PORT || 8787;
413
+ console.log(\`šŸ”„ Kama Node Server & Admin UI running on http://localhost:\${port}\`);
414
+ if (distPath) console.log(\`šŸ‘‰ Serving Admin UI from: \${distPath}\`);
378
415
 
379
- writeFileSync(
380
- join(cmsDir, '.dev.vars'),
381
- `# Cloudflare Edge Cache Purging Secrets\nCLOUDFLARE_API_TOKEN=${isCloudflare ? 'cfut_YOUR_CUSTOM_PURGE_TOKEN' : 'local_token'}\n`
382
- );
416
+ serve({ fetch: kamaApp.fetch, port });
417
+ `;
418
+ writeFileSync(join(cmsDir, 'server.js'), nodeServerContent);
419
+
420
+ writeFileSync(
421
+ join(cmsDir, 'package.json'),
422
+ JSON.stringify({
423
+ name: workerName,
424
+ type: 'module',
425
+ version: '1.0.0',
426
+ scripts: {
427
+ "schema:local": "sqlite3 kama.db < ../node_modules/@brightsideoy/kama/schema.sql",
428
+ "seed:local": "sqlite3 kama.db < seed.sql",
429
+ "dev": "npm run schema:local && npm run seed:local && tsx server.js",
430
+ "start": "node server.js"
431
+ },
432
+ dependencies: {
433
+ '@brightsideoy/kama': currentKamaVersion,
434
+ '@hono/node-server': '^1.13.0',
435
+ '@libsql/client': '^0.14.0',
436
+ 'sharp': '^0.33.5',
437
+ 'dotenv': '^16.4.5'
438
+ },
439
+ devDependencies: {
440
+ "tsx": "^4.19.0"
441
+ },
442
+ }, null, 2)
443
+ );
444
+
445
+ writeFileSync(join(cmsDir, '.env'), `PORT=8787
446
+ KAMA_RUNTIME=node
447
+ DB_PATH=./kama.db
448
+ LOCAL_MEDIA_PATH=./public/media
449
+ PUBLIC_CMS_URL=${cmsFullUrl}
450
+ PUBLIC_FRONTEND_URL=${shouldCreateSite ? `http://${siteDomain}` : 'http://localhost:4321'}
451
+ `);
452
+ }
383
453
 
384
454
  await bundleWorkspaceSchemas(rootDir);
385
455
 
@@ -432,12 +502,11 @@ async function createNewSiteOnly() {
432
502
  }
433
503
 
434
504
  console.log('\nšŸŒ Deployment Mode:');
435
- console.log(' 1) Local Development');
505
+ console.log(' 1) VPS / Local Server (Node.js)');
436
506
  console.log(' 2) Cloudflare Edge');
437
507
  const envChoice = await rl.question('\nChoice [1/2]: ');
438
508
  const isCloudflare = envChoice.trim() === '2';
439
509
 
440
- // šŸŽÆ FIX: Default to 'kama-starter'
441
510
  const siteFolder = (await rl.question('Astro package/folder name (e.g., my-new-site) [kama-starter]: ')).trim() || 'kama-starter';
442
511
 
443
512
  let siteDomain = 'localhost:4321';
@@ -458,59 +527,30 @@ async function createNewSiteOnly() {
458
527
 
459
528
  /**
460
529
  * COMMAND: npx kama bundle
461
- * Reads YAML from workspace and builds a static module for the worker
530
+ * Loads the pre-compiled JS compiler natively without runtime tsx/type-stripping issues!
462
531
  */
463
532
  async function bundleWorkspaceSchemas(targetRootDir) {
464
- const rootDir = targetRootDir || process.cwd();
465
- const defsDir = join(rootDir, 'content', 'definitions');
466
- const workerDir = join(rootDir, 'kama-worker');
533
+ let rootDir = targetRootDir || process.cwd();
467
534
 
468
- if (!existsSync(defsDir)) {
469
- console.warn(`\nāš ļø Skipping schema bundling: 'content/definitions' folder not found at ${defsDir}`);
470
- return;
535
+ if (basename(rootDir) === 'kama-worker') {
536
+ rootDir = resolve(rootDir, '..');
471
537
  }
472
538
 
473
- console.log(`\nšŸ“¦ Bundling workspace YAML schemas for Edge deployment...`);
539
+ try {
540
+ // 1. First preference: built JavaScript bundle in node_modules/dist
541
+ let compilerPath = join(__dirname, '../dist/schema-compiler.js');
474
542
 
475
- function crawlDirectory(dir, baseDir, result = {}) {
476
- if (!existsSync(dir)) return result;
477
- const items = readdirSync(dir);
478
- for (const item of items) {
479
- const fullPath = join(dir, item);
480
- if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
481
- crawlDirectory(fullPath, baseDir, result);
482
- } else if (fullPath.endsWith('.yaml') || fullPath.endsWith('.yml')) {
483
- const relativePath = './' + relative(baseDir, fullPath).replace(/\\/g, '/');
484
- result[relativePath] = readFileSync(fullPath, 'utf-8');
485
- }
543
+ // 2. Fallback for local monorepo dev where ts source exists
544
+ if (!existsSync(compilerPath)) {
545
+ compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
486
546
  }
487
- return result;
488
- }
489
547
 
490
- const rawGlobs = {
491
- nodes: crawlDirectory(join(defsDir, 'nodes'), defsDir),
492
- trees: crawlDirectory(join(defsDir, 'trees'), defsDir),
493
- blocks: crawlDirectory(join(defsDir, 'blocks'), defsDir),
494
- nodeLayouts: crawlDirectory(join(defsDir, 'node-layouts'), defsDir),
495
- blockLayouts: crawlDirectory(join(defsDir, 'block-layouts'), defsDir),
496
- fieldSets: crawlDirectory(join(defsDir, 'field-sets'), defsDir),
497
- channels: crawlDirectory(join(defsDir, 'channels'), defsDir),
498
- };
499
-
500
- const fileContent = `// AUTO-GENERATED BUNDLE - DO NOT EDIT
501
- // This file is generated by 'npx kama bundle' prior to local dev or deployment.
502
-
503
- export default ${JSON.stringify(rawGlobs, null, 2)};
504
- `;
505
-
506
- if (!existsSync(workerDir)) {
507
- mkdirSync(workerDir, { recursive: true });
548
+ // šŸŽÆ Native Node ESM Import — Loads pure JS with zero runtime type-stripping errors!
549
+ const compilerUrl = pathToFileURL(compilerPath).href;
550
+ await import(compilerUrl);
551
+ } catch (e) {
552
+ console.error(`āŒ Schema compilation failed:`, e.message || e);
508
553
  }
509
-
510
- const outPath = join(workerDir, 'workspace-schemas.js');
511
- writeFileSync(outPath, fileContent, 'utf-8');
512
-
513
- console.log(`āœ… Schema bundle generated successfully at ${outPath}`);
514
554
  }
515
555
 
516
556
  /**
@@ -636,35 +676,39 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
636
676
  writeFileSync(wranglerPath, wranglerStr);
637
677
  }
638
678
 
639
- // šŸŽÆ FIX: Smart capitalization for dynamic site labels
640
679
  const siteLabel = siteFolder.split(/[-_]/).map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
641
680
  const safeSiteLabel = siteLabel.replace(/'/g, "''");
642
681
 
643
682
  const channelKey = siteFolder.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
644
- const treeKey = `${channelKey}-nav`;
683
+ const treeKey = 'main-tree';
645
684
 
646
- // šŸŽÆ FIX: Inject `safeSiteLabel` into the logoText, titleSuffix, and titles!
647
685
  const seedSql = `
648
686
  -- Seed data for site: ${safeSiteLabel}
687
+
688
+ -- 1. Create the Channel
649
689
  INSERT OR IGNORE INTO channels (key, label, channelType, defaultLanguage, isHidden, dataJson)
650
690
  VALUES ('${channelKey}', '${safeSiteLabel}', 'website', 'en', 0, '{}');
651
691
 
692
+ -- 2. Create the Tree and link it to the Channel
652
693
  INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson)
653
- VALUES ('${treeKey}', 'Main Navigation', 'main-navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
694
+ VALUES ('${treeKey}', 'Main Tree', 'main-navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
654
695
 
655
696
  INSERT OR IGNORE INTO channel_trees (channelId, treeId, key)
656
697
  VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
657
698
 
699
+ -- 3. Create the Home Page
658
700
  INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson)
659
701
  SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"– ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}'
660
702
  WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
661
703
 
704
+ -- 4. Attach the Home Page to the Channel
662
705
  INSERT OR IGNORE INTO node_channels (nodeId, channelId)
663
706
  VALUES (
664
707
  (SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
665
708
  (SELECT id FROM channels WHERE key = '${channelKey}')
666
709
  );
667
710
 
711
+ -- 5. Attach the Home Page to the Main Tree
668
712
  INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder)
669
713
  VALUES (
670
714
  (SELECT id FROM trees WHERE key = '${treeKey}'),
@@ -680,7 +724,6 @@ VALUES (
680
724
  appendFileSync(seedPath, seedSql);
681
725
  }
682
726
 
683
- // šŸŽÆ FIX: Expose the title-cased name to Astro ENV vars as well
684
727
  const envContent = [
685
728
  `PUBLIC_CMS_URL="${cmsFullUrl}"`,
686
729
  `PUBLIC_API_URL="${cmsFullUrl}"`,
@@ -0,0 +1,52 @@
1
+ id: _page
2
+ label: Page Old
3
+ inTree: true
4
+ inVault: true
5
+ hasCanvas: true
6
+
7
+ layout:
8
+ columns: "10fr 4fr"
9
+ areas:
10
+ - ["header", "header"]
11
+ - ["main", "sidebar"]
12
+ - ["footer", "footer"]
13
+
14
+ regions:
15
+ header:
16
+ label: Header
17
+ inherit: parent
18
+ main:
19
+ label: Content
20
+ sidebar:
21
+ label: Sidebar
22
+ footer:
23
+ label: Footer
24
+ inherit: parent
25
+
26
+ allowedBlocks:
27
+ - header
28
+ - hero
29
+ - text
30
+ - image_card
31
+
32
+ # šŸ‘‰ TABS DEFINITION
33
+ tabs:
34
+ settings:
35
+ label: "Page"
36
+ fields:
37
+ # Imports core fields: title, slug, isHidden
38
+ - fieldSet: page-base
39
+
40
+ # Overrides & custom properties
41
+ - menuTitle:
42
+ label: Menu Title
43
+ type: text
44
+ dbType: text
45
+ public: true
46
+ placeholder: "Short title for navigation menus"
47
+
48
+ # SEO / OpenGraph metadata
49
+ - fieldSet: meta
50
+
51
+ # Role permissions & access control
52
+ - fieldSet: access