@brightsideoy/kama 0.1.0-alpha.143 ā 0.1.0-alpha.146
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 +188 -139
- package/definitions/_page.yaml +52 -0
- package/dist/assets/index-BSBvGvQz.css +1 -0
- package/dist/assets/index-BjQIQ8dq.js +162 -0
- package/dist/dist-LuTXtohj.js +8657 -0
- package/dist/index.html +2 -2
- package/dist/index.js +4994 -9394
- 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-BcbVkck_.js +0 -162
- package/dist/assets/index-Bv7fPRX7.css +0 -1
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,93 +274,183 @@ 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
|
-
const
|
|
295
|
-
|
|
288
|
+
const schemas = localBundle.BUNDLED_DEFINITIONS || localBundle.default || localBundle;
|
|
289
|
+
// Inject runtime flag natively
|
|
290
|
+
const customEnv = { ...env, BUNDLED_DEFINITIONS: schemas, KAMA_RUNTIME: 'cloudflare' };
|
|
296
291
|
|
|
297
292
|
if (kamaWorker && typeof kamaWorker.fetch === 'function') {
|
|
298
|
-
return kamaWorker.fetch(request,
|
|
293
|
+
return kamaWorker.fetch(request, customEnv, ctx);
|
|
299
294
|
}
|
|
300
295
|
|
|
301
296
|
if (kamaWorker && kamaWorker.app && typeof kamaWorker.app.fetch === 'function') {
|
|
302
|
-
return kamaWorker.app.fetch(request,
|
|
297
|
+
return kamaWorker.app.fetch(request, customEnv, ctx);
|
|
303
298
|
}
|
|
304
299
|
|
|
305
300
|
return new Response('Kama Engine Worker Ready', { status: 200 });
|
|
306
301
|
}
|
|
307
302
|
};
|
|
308
303
|
`;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
+
'@libsql/client': '^0.14.0'
|
|
323
|
+
},
|
|
324
|
+
devDependencies: {
|
|
325
|
+
"wrangler": "^4.0.0"
|
|
326
|
+
},
|
|
327
|
+
}, null, 2)
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
const cmsWranglerConfig = {
|
|
331
|
+
$schema: '../node_modules/wrangler/config-schema.json',
|
|
315
332
|
name: workerName,
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
"seed:local": `wrangler d1 execute ${dbName} --local --file=seed.sql > /dev/null 2>&1`,
|
|
323
|
-
"seed:remote": `wrangler d1 execute ${dbName} --remote --file=seed.sql`,
|
|
324
|
-
"dev": "npm run bundle && npm run schema:local && npm run seed:local && wrangler dev",
|
|
325
|
-
"deploy": "npm run bundle && npm run schema:remote && npm run seed:remote && wrangler deploy"
|
|
333
|
+
main: 'index.js',
|
|
334
|
+
compatibility_date: '2024-09-23',
|
|
335
|
+
compatibility_flags: ['nodejs_compat'],
|
|
336
|
+
assets: {
|
|
337
|
+
directory: '../node_modules/@brightsideoy/kama/dist',
|
|
338
|
+
binding: 'ASSETS'
|
|
326
339
|
},
|
|
327
|
-
|
|
328
|
-
'
|
|
340
|
+
images: {
|
|
341
|
+
binding: 'IMAGES'
|
|
329
342
|
},
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
343
|
+
vars: {
|
|
344
|
+
CDN_DOMAIN: cmsDomain,
|
|
345
|
+
PUBLIC_FRONTEND_URL: (shouldCreateSite) ? `https://${siteDomain}` : 'http://localhost:4321',
|
|
346
|
+
CLOUDFLARE_ZONE_ID: "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID",
|
|
347
|
+
KAMA_RUNTIME: 'cloudflare'
|
|
333
348
|
},
|
|
334
|
-
|
|
335
|
-
|
|
349
|
+
d1_databases: [{
|
|
350
|
+
binding: 'DB',
|
|
351
|
+
database_name: dbName,
|
|
352
|
+
database_id: d1DatabaseId,
|
|
353
|
+
}],
|
|
354
|
+
r2_buckets: [{
|
|
355
|
+
binding: 'MEDIA_BUCKET',
|
|
356
|
+
bucket_name: bucketName,
|
|
357
|
+
}],
|
|
358
|
+
routes: [{ pattern: cmsDomain, custom_domain: true }]
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
writeFileSync(join(cmsDir, 'wrangler.json'), JSON.stringify(cmsWranglerConfig, null, 2));
|
|
362
|
+
writeFileSync(join(cmsDir, '.dev.vars'), `# Cloudflare Edge Cache Purging Secrets\nCLOUDFLARE_API_TOKEN=cfut_YOUR_CUSTOM_PURGE_TOKEN\n`);
|
|
363
|
+
} else {
|
|
364
|
+
// --- NODE.JS ARCHITECTURE ---
|
|
365
|
+
const nodeServerContent = `import { serve } from '@hono/node-server';
|
|
366
|
+
import { serveStatic } from '@hono/node-server/serve-static';
|
|
367
|
+
import kamaApp from '@brightsideoy/kama';
|
|
368
|
+
import * as localBundle from './bundled-definitions.js';
|
|
369
|
+
import dotenv from 'dotenv';
|
|
370
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
371
|
+
import { join } from 'node:path';
|
|
372
|
+
|
|
373
|
+
dotenv.config();
|
|
374
|
+
|
|
375
|
+
// šÆ Dynamically find the Kama package dist folder (handles NPM workspace hoisting)
|
|
376
|
+
const possiblePaths = [
|
|
377
|
+
'./node_modules/@brightsideoy/kama/dist',
|
|
378
|
+
'../node_modules/@brightsideoy/kama/dist',
|
|
379
|
+
'../../node_modules/@brightsideoy/kama/dist'
|
|
380
|
+
];
|
|
381
|
+
const distPath = possiblePaths.find(p => existsSync(p));
|
|
382
|
+
|
|
383
|
+
if (!distPath) {
|
|
384
|
+
console.warn('ā ļø Could not locate @brightsideoy/kama/dist folder. Admin UI will not load.');
|
|
385
|
+
}
|
|
336
386
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
},
|
|
347
|
-
images: {
|
|
348
|
-
binding: 'IMAGES'
|
|
349
|
-
},
|
|
350
|
-
vars: {
|
|
351
|
-
CDN_DOMAIN: cmsDomain,
|
|
352
|
-
PUBLIC_FRONTEND_URL: (isCloudflare && shouldCreateSite) ? `https://${siteDomain}` : 'http://localhost:4321',
|
|
353
|
-
CLOUDFLARE_ZONE_ID: isCloudflare ? "REPLACE_WITH_YOUR_32_CHAR_ZONE_ID" : "local-zone-not-needed"
|
|
354
|
-
},
|
|
355
|
-
d1_databases: [{
|
|
356
|
-
binding: 'DB',
|
|
357
|
-
database_name: dbName,
|
|
358
|
-
database_id: d1DatabaseId,
|
|
359
|
-
}],
|
|
360
|
-
r2_buckets: [{
|
|
361
|
-
binding: 'MEDIA_BUCKET',
|
|
362
|
-
bucket_name: bucketName,
|
|
363
|
-
}],
|
|
364
|
-
};
|
|
387
|
+
kamaApp.use('*', async (c, next) => {
|
|
388
|
+
c.env = {
|
|
389
|
+
...process.env,
|
|
390
|
+
...c.env,
|
|
391
|
+
BUNDLED_DEFINITIONS: localBundle.BUNDLED_DEFINITIONS,
|
|
392
|
+
KAMA_RUNTIME: 'node'
|
|
393
|
+
};
|
|
394
|
+
await next();
|
|
395
|
+
});
|
|
365
396
|
|
|
366
|
-
|
|
367
|
-
|
|
397
|
+
kamaApp.use('/media/*', serveStatic({ root: './' }));
|
|
398
|
+
|
|
399
|
+
if (distPath) {
|
|
400
|
+
kamaApp.use('/assets/*', serveStatic({ root: distPath }));
|
|
401
|
+
|
|
402
|
+
kamaApp.get('/*', async (c, next) => {
|
|
403
|
+
if (c.req.path.startsWith('/api') || c.req.path.startsWith('/media')) return next();
|
|
404
|
+
|
|
405
|
+
const indexPath = join(distPath, 'index.html');
|
|
406
|
+
if (existsSync(indexPath)) {
|
|
407
|
+
return c.html(readFileSync(indexPath, 'utf-8'));
|
|
368
408
|
}
|
|
409
|
+
return next();
|
|
410
|
+
});
|
|
411
|
+
}
|
|
369
412
|
|
|
370
|
-
|
|
413
|
+
const port = process.env.PORT || 8787;
|
|
414
|
+
console.log(\`š„ Kama Node Server & Admin UI running on http://localhost:\${port}\`);
|
|
415
|
+
if (distPath) console.log(\`š Serving Admin UI from: \${distPath}\`);
|
|
371
416
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
417
|
+
serve({ fetch: kamaApp.fetch, port });
|
|
418
|
+
`;
|
|
419
|
+
writeFileSync(join(cmsDir, 'server.js'), nodeServerContent);
|
|
420
|
+
|
|
421
|
+
writeFileSync(
|
|
422
|
+
join(cmsDir, 'package.json'),
|
|
423
|
+
JSON.stringify({
|
|
424
|
+
name: workerName,
|
|
425
|
+
type: 'module',
|
|
426
|
+
version: '1.0.0',
|
|
427
|
+
scripts: {
|
|
428
|
+
"schema:local": "sqlite3 kama.db < ../node_modules/@brightsideoy/kama/schema.sql",
|
|
429
|
+
"seed:local": "sqlite3 kama.db < seed.sql",
|
|
430
|
+
"dev": "npm run schema:local && npm run seed:local && tsx server.js",
|
|
431
|
+
"start": "node server.js"
|
|
432
|
+
},
|
|
433
|
+
dependencies: {
|
|
434
|
+
'@brightsideoy/kama': currentKamaVersion,
|
|
435
|
+
'@hono/node-server': '^1.13.0',
|
|
436
|
+
'@libsql/client': '^0.14.0',
|
|
437
|
+
'sharp': '^0.33.5',
|
|
438
|
+
'dotenv': '^16.4.5'
|
|
439
|
+
},
|
|
440
|
+
devDependencies: {
|
|
441
|
+
"tsx": "^4.19.0"
|
|
442
|
+
},
|
|
443
|
+
}, null, 2)
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
writeFileSync(join(cmsDir, '.env'), `PORT=8787
|
|
447
|
+
KAMA_RUNTIME=node
|
|
448
|
+
DB_PATH=./kama.db
|
|
449
|
+
LOCAL_MEDIA_PATH=./public/media
|
|
450
|
+
PUBLIC_CMS_URL=${cmsFullUrl}
|
|
451
|
+
PUBLIC_FRONTEND_URL=${shouldCreateSite ? `http://${siteDomain}` : 'http://localhost:4321'}
|
|
452
|
+
`);
|
|
453
|
+
}
|
|
376
454
|
|
|
377
455
|
await bundleWorkspaceSchemas(rootDir);
|
|
378
456
|
|
|
@@ -425,7 +503,7 @@ async function createNewSiteOnly() {
|
|
|
425
503
|
}
|
|
426
504
|
|
|
427
505
|
console.log('\nš Deployment Mode:');
|
|
428
|
-
console.log(' 1) Local
|
|
506
|
+
console.log(' 1) VPS / Local Server (Node.js)');
|
|
429
507
|
console.log(' 2) Cloudflare Edge');
|
|
430
508
|
const envChoice = await rl.question('\nChoice [1/2]: ');
|
|
431
509
|
const isCloudflare = envChoice.trim() === '2';
|
|
@@ -450,65 +528,30 @@ async function createNewSiteOnly() {
|
|
|
450
528
|
|
|
451
529
|
/**
|
|
452
530
|
* COMMAND: npx kama bundle
|
|
453
|
-
*
|
|
531
|
+
* Loads the pre-compiled JS compiler natively without runtime tsx/type-stripping issues!
|
|
454
532
|
*/
|
|
455
533
|
async function bundleWorkspaceSchemas(targetRootDir) {
|
|
456
534
|
let rootDir = targetRootDir || process.cwd();
|
|
457
535
|
|
|
458
|
-
// Fix directory target if executed directly inside the worker package
|
|
459
536
|
if (basename(rootDir) === 'kama-worker') {
|
|
460
537
|
rootDir = resolve(rootDir, '..');
|
|
461
538
|
}
|
|
462
539
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (!existsSync(defsDir)) {
|
|
467
|
-
console.warn(`\nā ļø Skipping schema bundling: 'content/definitions' folder not found at ${defsDir}`);
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
console.log(`\nš¦ Bundling workspace YAML schemas for Edge deployment...`);
|
|
540
|
+
try {
|
|
541
|
+
// 1. First preference: built JavaScript bundle in node_modules/dist
|
|
542
|
+
let compilerPath = join(__dirname, '../dist/schema-compiler.js');
|
|
472
543
|
|
|
473
|
-
|
|
474
|
-
if (!existsSync(
|
|
475
|
-
|
|
476
|
-
for (const item of items) {
|
|
477
|
-
const fullPath = join(dir, item);
|
|
478
|
-
if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
|
|
479
|
-
crawlDirectory(fullPath, baseDir, result);
|
|
480
|
-
} else if (fullPath.endsWith('.yaml') || fullPath.endsWith('.yml')) {
|
|
481
|
-
const relativePath = './' + relative(baseDir, fullPath).replace(/\\/g, '/');
|
|
482
|
-
result[relativePath] = readFileSync(fullPath, 'utf-8');
|
|
483
|
-
}
|
|
544
|
+
// 2. Fallback for local monorepo dev where ts source exists
|
|
545
|
+
if (!existsSync(compilerPath)) {
|
|
546
|
+
compilerPath = join(__dirname, '../scripts/schema-compiler.ts');
|
|
484
547
|
}
|
|
485
|
-
return result;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
const rawGlobs = {
|
|
489
|
-
nodes: crawlDirectory(join(defsDir, 'nodes'), defsDir),
|
|
490
|
-
trees: crawlDirectory(join(defsDir, 'trees'), defsDir),
|
|
491
|
-
blocks: crawlDirectory(join(defsDir, 'blocks'), defsDir),
|
|
492
|
-
nodeLayouts: crawlDirectory(join(defsDir, 'node-layouts'), defsDir),
|
|
493
|
-
blockLayouts: crawlDirectory(join(defsDir, 'block-layouts'), defsDir),
|
|
494
|
-
fieldSets: crawlDirectory(join(defsDir, 'field-sets'), defsDir),
|
|
495
|
-
channels: crawlDirectory(join(defsDir, 'channels'), defsDir),
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
const fileContent = `// AUTO-GENERATED BUNDLE - DO NOT EDIT
|
|
499
|
-
// This file is generated by 'npx kama bundle' prior to local dev or deployment.
|
|
500
|
-
|
|
501
|
-
export default ${JSON.stringify(rawGlobs, null, 2)};
|
|
502
|
-
`;
|
|
503
548
|
|
|
504
|
-
|
|
505
|
-
|
|
549
|
+
// šÆ Native Node ESM Import ā Loads pure JS with zero runtime type-stripping errors!
|
|
550
|
+
const compilerUrl = pathToFileURL(compilerPath).href;
|
|
551
|
+
await import(compilerUrl);
|
|
552
|
+
} catch (e) {
|
|
553
|
+
console.error(`ā Schema compilation failed:`, e.message || e);
|
|
506
554
|
}
|
|
507
|
-
|
|
508
|
-
const outPath = join(workerDir, 'workspace-schemas.js');
|
|
509
|
-
writeFileSync(outPath, fileContent, 'utf-8');
|
|
510
|
-
|
|
511
|
-
console.log(`ā
Schema bundle generated successfully at ${outPath}`);
|
|
512
555
|
}
|
|
513
556
|
|
|
514
557
|
/**
|
|
@@ -638,29 +681,35 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
638
681
|
const safeSiteLabel = siteLabel.replace(/'/g, "''");
|
|
639
682
|
|
|
640
683
|
const channelKey = siteFolder.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
|
|
641
|
-
const treeKey =
|
|
684
|
+
const treeKey = 'main-tree';
|
|
642
685
|
|
|
643
686
|
const seedSql = `
|
|
644
687
|
-- Seed data for site: ${safeSiteLabel}
|
|
688
|
+
|
|
689
|
+
-- 1. Create the Channel
|
|
645
690
|
INSERT OR IGNORE INTO channels (key, label, channelType, defaultLanguage, isHidden, dataJson)
|
|
646
691
|
VALUES ('${channelKey}', '${safeSiteLabel}', 'website', 'en', 0, '{}');
|
|
647
692
|
|
|
693
|
+
-- 2. Create the Tree and link it to the Channel
|
|
648
694
|
INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson)
|
|
649
|
-
VALUES ('${treeKey}', 'Main
|
|
695
|
+
VALUES ('${treeKey}', 'Main Tree', 'main-navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
|
|
650
696
|
|
|
651
697
|
INSERT OR IGNORE INTO channel_trees (channelId, treeId, key)
|
|
652
698
|
VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
|
|
653
699
|
|
|
700
|
+
-- 3. Create the Home Page
|
|
654
701
|
INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson)
|
|
655
702
|
SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"ā ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}'
|
|
656
703
|
WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
|
|
657
704
|
|
|
705
|
+
-- 4. Attach the Home Page to the Channel
|
|
658
706
|
INSERT OR IGNORE INTO node_channels (nodeId, channelId)
|
|
659
707
|
VALUES (
|
|
660
708
|
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
661
709
|
(SELECT id FROM channels WHERE key = '${channelKey}')
|
|
662
710
|
);
|
|
663
711
|
|
|
712
|
+
-- 5. Attach the Home Page to the Main Tree
|
|
664
713
|
INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder)
|
|
665
714
|
VALUES (
|
|
666
715
|
(SELECT id FROM trees WHERE key = '${treeKey}'),
|
|
@@ -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
|