@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.
- package/.wrangler/state/v3/cache/default/blobs/4de32ec3e619aa3f9acad3fb1a2528209381347d1cbb86e939e08724f5b35bc4000001a0b2b5b216 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/5f895e5810a26a6319bbadde9d751e5b10faae6e141db1c454c5f53b3e725591000001a0b2b624a4 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/74744186327d8aaf1c6078e50bc561135fd90690c96bd4b733035d0cb3fedb94000001a0b2b5be6b +0 -0
- package/.wrangler/state/v3/cache/default/blobs/79c1c81c1ddcd49f49eb27b9197ae0160c3a7981f308aee2ae972653de1b3668000001a0b2b60e76 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/7cd29a3bd95a88e7e896a4ae253758cd9e4bde78fc371077f3fef974cd11c64d000001a0b098ff88 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/7ecc4caad58c7ee119c02adb84132eaa691b9a171f932ab1c17e0f95c3fed2a8000001a0b2b5bf5e +0 -0
- package/.wrangler/state/v3/cache/default/blobs/81928c274111d2c3cbd3d7174136a2fdce83e267da8f8d0caf60d650396197f5000001a0b098de9d +0 -0
- package/.wrangler/state/v3/cache/default/blobs/8c3aa6f6625d7c0d682cb498e6715355aec1905909b04ead5e85adbca3989b19000001a0b098e4ac +0 -0
- package/.wrangler/state/v3/cache/default/blobs/97205d84c3e4399f6f51295e8381b21f2a8810cdaecc0ab13f2cadf712fae5f4000001a0b339609d +0 -0
- package/.wrangler/state/v3/cache/default/blobs/b48d02100b8f1a9520a209628a0778a0f9e0f4ce0643f8d59b3888bbd0f85fc2000001a0b2b63647 +0 -0
- package/.wrangler/state/v3/cache/default/blobs/cf30c018e70dad1c6859277e4361da657b79adf34e60cb05885eb32951fbbafc000001a0b09b168f +0 -0
- package/.wrangler/state/v3/cache/default/blobs/d0d796d0fe4efd55f61e0c3b8d30170a89703669a52854687186a66304adbf8a000001a0b2b6244d +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/9f458c07675338a7426a7b81ac4fb1baf92d034efbcaaf4336379640ed744ded.sqlite +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/7cfce387cae19c0dfbb9cc4f2a9c353f60ca0a80fabd0b2e2837d152b58feaaa.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-shm +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/a590acd76969f996ec6e4b599c3c09f58c283a76f2d61392b5d3046caf557602.sqlite-wal +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/observability/miniflare-wobs-trace-store/metadata.sqlite-wal +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/1c7705701fba41f9a2683025d40393711daffc55d32172088a62d8999017e9c6000001a0b339607a +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/1ee266c53f586a4a57a1d21be291e34bb2e2236c15e43ae30497f6054290f01d000001a0b2b6248c +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/6db1f8204b6d125f0911b3e42022258cc7e1c37a95c2ce7f5c7f14da31d408ec000001a0b2b60e1f +0 -0
- package/.wrangler/state/v3/r2/kama-media/blobs/97b86f251c5d30df5e1eab8662cab83f5f7c4583ad14fd2d5ea99f16fdcfd6ef000001a0b2b62482 +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/9ffe30cff37d40b366f64100a8f041c0a1e5aee78708ba90b9ef4ca6a6b2d883.sqlite +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-shm +0 -0
- package/.wrangler/state/v3/r2/miniflare-R2BucketObject/metadata.sqlite-wal +0 -0
- package/README.md +16 -37
- package/bin/cli.js +190 -147
- package/definitions/_page.yaml +52 -0
- package/dist/assets/index-BSBvGvQz.css +1 -0
- package/dist/assets/index-RzfH6iq3.js +162 -0
- package/dist/dist-CZEgSuN0.js +8674 -0
- package/dist/index.html +2 -2
- package/dist/index.js +6856 -11229
- package/dist/schema-compiler.js +38 -0
- package/npm-test.sh +75 -0
- package/package.json +14 -10
- package/schema.sql +3 -2
- package/templates/astro-starter/src/components/blocks/ImageBlock.astro +20 -56
- package/templates/astro-starter/src/components/global/Header.astro +19 -12
- package/templates/astro-starter/src/components/ui/KamaImage.astro +49 -73
- package/templates/astro-starter/src/pages/[...slug].astro +16 -43
- package/templates/astro-starter/src/pages/media/[...path].ts +8 -1
- package/wrangler.json +22 -0
- package/dist/assets/index-Bv7fPRX7.css +0 -1
- 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,
|
|
4
|
-
import { join, dirname, basename,
|
|
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
|
|
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 -
|
|
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š
|
|
114
|
-
console.log(' 1) Local
|
|
115
|
-
console.log(' 2) Cloudflare Edge (Workers
|
|
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.
|
|
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'] =
|
|
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
|
-
|
|
290
|
-
|
|
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
|
-
|
|
295
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
|
|
335
|
-
'
|
|
339
|
+
images: {
|
|
340
|
+
binding: 'IMAGES'
|
|
336
341
|
},
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
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
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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
|
-
|
|
374
|
-
|
|
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
|
-
|
|
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
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
|
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
|
-
*
|
|
530
|
+
* Loads the pre-compiled JS compiler natively without runtime tsx/type-stripping issues!
|
|
462
531
|
*/
|
|
463
532
|
async function bundleWorkspaceSchemas(targetRootDir) {
|
|
464
|
-
|
|
465
|
-
const defsDir = join(rootDir, 'content', 'definitions');
|
|
466
|
-
const workerDir = join(rootDir, 'kama-worker');
|
|
533
|
+
let rootDir = targetRootDir || process.cwd();
|
|
467
534
|
|
|
468
|
-
if (
|
|
469
|
-
|
|
470
|
-
return;
|
|
535
|
+
if (basename(rootDir) === 'kama-worker') {
|
|
536
|
+
rootDir = resolve(rootDir, '..');
|
|
471
537
|
}
|
|
472
538
|
|
|
473
|
-
|
|
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
|
-
|
|
476
|
-
if (!existsSync(
|
|
477
|
-
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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 =
|
|
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
|
|
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
|