@brightsideoy/kama 0.1.0-alpha.121 ā 0.1.0-alpha.123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +101 -14
- package/content/definitions/channels/website.yaml +24 -0
- package/content/definitions/node-layouts/single-column.yml +2 -5
- package/content/definitions/node-layouts/two-column.yml +2 -5
- package/content/definitions/nodes/page.yaml +16 -3
- package/dist/assets/index--F1RFBm2.js +162 -0
- package/dist/assets/{index-Drmp3h6P.css ā index-CEmkJap6.css} +1 -1
- package/dist/index.html +2 -2
- package/dist/index.js +1160 -998
- package/package.json +1 -1
- package/templates/astro-starter/src/components/global/Breadcrumb.astro +5 -2
- package/templates/astro-starter/src/components/global/Header.astro +11 -2
- package/templates/astro-starter/src/components/global/NavigationMenu.astro +18 -2
- package/templates/astro-starter/src/pages/[...slug].astro +40 -17
- package/templates/astro-starter/src/pages/llms-full.txt.ts +22 -12
- package/templates/astro-starter/src/pages/llms.txt.ts +18 -12
- package/dist/assets/index-C6GoXL-R.js +0 -162
- package/test-local.sh +0 -76
package/bin/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, unlinkSync, statSync } from 'node:fs';
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync, unlinkSync, statSync, appendFileSync } from 'node:fs';
|
|
4
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';
|
|
@@ -24,11 +24,39 @@ const rl = readline.createInterface({
|
|
|
24
24
|
output: process.stdout,
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
+
function showHelp() {
|
|
28
|
+
console.log('\nš„ --- KAMA ENGINE CLI --- š„\n');
|
|
29
|
+
console.log('Usage: npx kama <command> [options]\n');
|
|
30
|
+
console.log('Commands:');
|
|
31
|
+
console.log(' init Kickstart a new Monorepo (CMS Worker + Optional Astro Site)');
|
|
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');
|
|
34
|
+
console.log(' promote Promote the current Local workspace to Cloudflare Edge');
|
|
35
|
+
console.log(' help, -h Show this help message\n');
|
|
36
|
+
|
|
37
|
+
console.log('Workspace Scripts (Run from project root):');
|
|
38
|
+
console.log(' npm update Update to latest KAMA version');
|
|
39
|
+
console.log(' npm run dev Boot up the CMS backend and Astro frontend concurrently');
|
|
40
|
+
console.log(' npm run deploy:cms Deploy the backend worker and database to Cloudflare');
|
|
41
|
+
console.log(' npm run deploy:site Deploy the Astro frontend site to Cloudflare\n');
|
|
42
|
+
|
|
43
|
+
console.log('Examples:');
|
|
44
|
+
console.log(' npx kama init');
|
|
45
|
+
console.log(' npx kama add site');
|
|
46
|
+
console.log(' npx kama bundle\n');
|
|
47
|
+
}
|
|
48
|
+
|
|
27
49
|
async function main() {
|
|
28
50
|
const args = process.argv.slice(2);
|
|
29
51
|
const command = args[0]?.toLowerCase();
|
|
30
52
|
const subCommand = args[1]?.toLowerCase();
|
|
31
53
|
|
|
54
|
+
if (command === 'help' || command === '--help' || command === '-h') {
|
|
55
|
+
showHelp();
|
|
56
|
+
rl.close();
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
32
60
|
console.log('\nš„ --- KAMA ENGINE CLI --- š„\n');
|
|
33
61
|
|
|
34
62
|
if (command === 'init') {
|
|
@@ -45,10 +73,13 @@ async function main() {
|
|
|
45
73
|
console.log(' 2) npx kama add site - Add new Astro Site to current workspace (sites/)');
|
|
46
74
|
console.log(' 3) npx kama bundle - Bundle YAML schemas for Edge deployment');
|
|
47
75
|
console.log(' 4) npx kama promote - Promote current Local workspace to Cloudflare Edge');
|
|
76
|
+
console.log(' 5) Help - Show all commands and usage');
|
|
48
77
|
|
|
49
|
-
const choice = await rl.question('\nSelect choice [1/2/3/4]: ');
|
|
78
|
+
const choice = await rl.question('\nSelect choice [1/2/3/4/5]: ');
|
|
50
79
|
|
|
51
|
-
if (choice.trim() === '
|
|
80
|
+
if (choice.trim() === '5') {
|
|
81
|
+
showHelp();
|
|
82
|
+
} else if (choice.trim() === '4') {
|
|
52
83
|
await promoteLocalToCloudflare();
|
|
53
84
|
} else if (choice.trim() === '3') {
|
|
54
85
|
await bundleWorkspaceSchemas();
|
|
@@ -88,8 +119,14 @@ async function createFullWorkspace() {
|
|
|
88
119
|
const createSiteInput = await rl.question('\nš Do you want to scaffold an initial Astro frontend site? (y/n) [y]: ');
|
|
89
120
|
const shouldCreateSite = createSiteInput.trim().toLowerCase() !== 'n';
|
|
90
121
|
|
|
91
|
-
let
|
|
122
|
+
let siteFolderName = 'kama-starter';
|
|
92
123
|
let siteDomain = 'localhost:4321';
|
|
124
|
+
let cmsDomain = 'localhost:8787';
|
|
125
|
+
|
|
126
|
+
if (shouldCreateSite) {
|
|
127
|
+
// šÆ FIX: Default to 'kama-starter'
|
|
128
|
+
siteFolderName = (await rl.question('Astro package/folder name (e.g., my-website) [kama-starter]: ')).trim() || 'kama-starter';
|
|
129
|
+
}
|
|
93
130
|
|
|
94
131
|
if (isCloudflare) {
|
|
95
132
|
cmsDomain = (await rl.question('\nCMS Admin Domain (e.g., admin.t3cloud.eu): ')) || 'admin.t3cloud.eu';
|
|
@@ -105,8 +142,6 @@ async function createFullWorkspace() {
|
|
|
105
142
|
let dbName = `${projName}-db`.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
106
143
|
const bucketName = `${projName}-media-prod`.toLowerCase().replace(/[^a-z0-9_-]/g, '-');
|
|
107
144
|
|
|
108
|
-
const siteFolderName = isCloudflare ? siteDomain.split('.')[0] : 'web';
|
|
109
|
-
|
|
110
145
|
if (!isCurrentDir) {
|
|
111
146
|
console.log(`\nš Creating workspace folder at ./${projName}...`);
|
|
112
147
|
mkdirSync(rootDir, { recursive: true });
|
|
@@ -250,7 +285,8 @@ kama-worker/workspace-schemas.js
|
|
|
250
285
|
const cmsDir = join(rootDir, 'kama-worker');
|
|
251
286
|
mkdirSync(cmsDir, { recursive: true });
|
|
252
287
|
|
|
253
|
-
|
|
288
|
+
writeFileSync(join(cmsDir, 'seed.sql'), '-- Kama Auto-Generated Seed File\nSELECT 1;\n');
|
|
289
|
+
|
|
254
290
|
const cmsWorkerIndexContent = `import kamaWorker from '@brightsideoy/kama';
|
|
255
291
|
import customSchemas from './workspace-schemas.js';
|
|
256
292
|
|
|
@@ -283,8 +319,10 @@ export default {
|
|
|
283
319
|
scripts: {
|
|
284
320
|
"schema:local": `wrangler d1 execute ${dbName} --local --file=../node_modules/@brightsideoy/kama/schema.sql > /dev/null 2>&1`,
|
|
285
321
|
"schema:remote": `wrangler d1 execute ${dbName} --remote --file=../node_modules/@brightsideoy/kama/schema.sql`,
|
|
286
|
-
"
|
|
287
|
-
"
|
|
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 schema:local && npm run seed:local && wrangler dev",
|
|
325
|
+
"deploy": "npm run schema:remote && npm run seed:remote && wrangler deploy"
|
|
288
326
|
},
|
|
289
327
|
dependencies: {
|
|
290
328
|
'@brightsideoy/kama': currentKamaVersion,
|
|
@@ -392,7 +430,8 @@ async function createNewSiteOnly() {
|
|
|
392
430
|
const envChoice = await rl.question('\nChoice [1/2]: ');
|
|
393
431
|
const isCloudflare = envChoice.trim() === '2';
|
|
394
432
|
|
|
395
|
-
|
|
433
|
+
// šÆ FIX: Default to 'kama-starter'
|
|
434
|
+
const siteFolder = (await rl.question('Astro package/folder name (e.g., my-new-site) [kama-starter]: ')).trim() || 'kama-starter';
|
|
396
435
|
|
|
397
436
|
let siteDomain = 'localhost:4321';
|
|
398
437
|
let cmsFullUrl = 'http://localhost:8787';
|
|
@@ -405,7 +444,9 @@ async function createNewSiteOnly() {
|
|
|
405
444
|
|
|
406
445
|
await generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, targetWorkerName, isCloudflare);
|
|
407
446
|
|
|
408
|
-
console.log(`\n⨠Site created in sites/${siteFolder}
|
|
447
|
+
console.log(`\n⨠Site created in sites/${siteFolder}!`);
|
|
448
|
+
console.log(`š¦ Run 'npm install' at workspace root.`);
|
|
449
|
+
console.log(`š± Run 'npm run dev' to boot up and seed the new site data.`);
|
|
409
450
|
}
|
|
410
451
|
|
|
411
452
|
/**
|
|
@@ -588,12 +629,58 @@ async function generateAstroSite(rootDir, siteFolder, siteDomain, cmsFullUrl, wo
|
|
|
588
629
|
writeFileSync(wranglerPath, wranglerStr);
|
|
589
630
|
}
|
|
590
631
|
|
|
632
|
+
// šÆ FIX: Smart capitalization for dynamic site labels
|
|
633
|
+
const siteLabel = siteFolder.split(/[-_]/).map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
634
|
+
const safeSiteLabel = siteLabel.replace(/'/g, "''");
|
|
635
|
+
|
|
636
|
+
const channelKey = siteFolder.replace(/[^a-z0-9_-]/gi, '-').toLowerCase();
|
|
637
|
+
const treeKey = `${channelKey}-nav`;
|
|
638
|
+
|
|
639
|
+
// šÆ FIX: Inject `safeSiteLabel` into the logoText, titleSuffix, and titles!
|
|
640
|
+
const seedSql = `
|
|
641
|
+
-- Seed data for site: ${safeSiteLabel}
|
|
642
|
+
INSERT OR IGNORE INTO channels (key, label, channelType, defaultLanguage, isHidden, dataJson)
|
|
643
|
+
VALUES ('${channelKey}', '${safeSiteLabel}', 'website', 'en', 0, '{}');
|
|
644
|
+
|
|
645
|
+
INSERT OR IGNORE INTO trees (key, label, treeType, channelId, isHidden, dataJson)
|
|
646
|
+
VALUES ('${treeKey}', 'Main Navigation', 'main-navigation', (SELECT id FROM channels WHERE key = '${channelKey}'), 0, '{}');
|
|
647
|
+
|
|
648
|
+
INSERT OR IGNORE INTO channel_trees (channelId, treeId, key)
|
|
649
|
+
VALUES ((SELECT id FROM channels WHERE key = '${channelKey}'), (SELECT id FROM trees WHERE key = '${treeKey}'), 'main');
|
|
650
|
+
|
|
651
|
+
INSERT INTO content_nodes (contentType, title, slug, language, status, dataJson)
|
|
652
|
+
SELECT 'page', 'Welcome to ${safeSiteLabel}', 'home', 'en', 'published', '{"titleSuffix":"ā ${safeSiteLabel}","layoutId":"single-column","subpageLayoutId":"two-column","logoText":"${safeSiteLabel}"}'
|
|
653
|
+
WHERE NOT EXISTS (SELECT 1 FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}');
|
|
654
|
+
|
|
655
|
+
INSERT OR IGNORE INTO node_channels (nodeId, channelId)
|
|
656
|
+
VALUES (
|
|
657
|
+
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
658
|
+
(SELECT id FROM channels WHERE key = '${channelKey}')
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
INSERT OR IGNORE INTO tree_nodes (treeId, contentId, parentId, sortOrder)
|
|
662
|
+
VALUES (
|
|
663
|
+
(SELECT id FROM trees WHERE key = '${treeKey}'),
|
|
664
|
+
(SELECT id FROM content_nodes WHERE slug = 'home' AND title = 'Welcome to ${safeSiteLabel}' ORDER BY id DESC LIMIT 1),
|
|
665
|
+
NULL,
|
|
666
|
+
0
|
|
667
|
+
);
|
|
668
|
+
`;
|
|
669
|
+
|
|
670
|
+
const workerDir = join(rootDir, 'kama-worker');
|
|
671
|
+
const seedPath = join(workerDir, 'seed.sql');
|
|
672
|
+
if (existsSync(workerDir)) {
|
|
673
|
+
appendFileSync(seedPath, seedSql);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// šÆ FIX: Expose the title-cased name to Astro ENV vars as well
|
|
591
677
|
const envContent = [
|
|
592
678
|
`PUBLIC_CMS_URL="${cmsFullUrl}"`,
|
|
593
679
|
`PUBLIC_API_URL="${cmsFullUrl}"`,
|
|
594
|
-
`PUBLIC_CHANNEL_ID="
|
|
595
|
-
`PUBLIC_TREE_ID="
|
|
596
|
-
`
|
|
680
|
+
`PUBLIC_CHANNEL_ID="${channelKey}"`,
|
|
681
|
+
`PUBLIC_TREE_ID="${treeKey}"`,
|
|
682
|
+
`PUBLIC_HOME_SLUG="home"`,
|
|
683
|
+
`PUBLIC_SITE_NAME="${siteLabel.replace(/"/g, '\\"')}"`
|
|
597
684
|
].join('\n') + '\n';
|
|
598
685
|
|
|
599
686
|
writeFileSync(join(siteDir, '.env'), envContent);
|
|
@@ -11,6 +11,30 @@ tabs:
|
|
|
11
11
|
fields:
|
|
12
12
|
# šÆ 1. Natively merges channel-base fields into this tab
|
|
13
13
|
fieldSet: channel-base
|
|
14
|
+
design:
|
|
15
|
+
label: "Design"
|
|
16
|
+
fields:
|
|
17
|
+
favicon:
|
|
18
|
+
label: "Favicon"
|
|
19
|
+
type: image
|
|
20
|
+
maxPreviewWidth: 200px
|
|
21
|
+
multiple: true
|
|
22
|
+
allowedTypes: ["image/png", "image/x-icon", "image/svg"]
|
|
23
|
+
public: true
|
|
24
|
+
logoText:
|
|
25
|
+
label: Logo Text
|
|
26
|
+
type: text
|
|
27
|
+
required: false
|
|
28
|
+
public: true
|
|
29
|
+
|
|
30
|
+
logoImage:
|
|
31
|
+
label: "Logo Image"
|
|
32
|
+
type: image
|
|
33
|
+
maxPreviewWidth: 300px
|
|
34
|
+
multiple: false
|
|
35
|
+
allowedTypes: ["image/svg"]
|
|
36
|
+
public: true
|
|
37
|
+
|
|
14
38
|
meta:
|
|
15
39
|
label: "SEO"
|
|
16
40
|
fields:
|
|
@@ -21,14 +21,11 @@ regions:
|
|
|
21
21
|
allowedTypes: ["image/*"]
|
|
22
22
|
crops:
|
|
23
23
|
standard:
|
|
24
|
-
label: "Desktop Header (
|
|
25
|
-
aspectRatio:
|
|
24
|
+
label: "Desktop Header (3:1)"
|
|
25
|
+
aspectRatio: 3.0
|
|
26
26
|
tablet:
|
|
27
27
|
label: "Tablet Header (2:1)"
|
|
28
28
|
aspectRatio: 2.0
|
|
29
|
-
mobile:
|
|
30
|
-
label: "Mobile Header (4:3)"
|
|
31
|
-
aspectRatio: 1.33
|
|
32
29
|
public: true
|
|
33
30
|
|
|
34
31
|
content:
|
|
@@ -22,14 +22,11 @@ regions:
|
|
|
22
22
|
allowedTypes: ["image/*"]
|
|
23
23
|
crops:
|
|
24
24
|
standard:
|
|
25
|
-
label: "Desktop Header (
|
|
26
|
-
aspectRatio:
|
|
25
|
+
label: "Desktop Header (3:1)"
|
|
26
|
+
aspectRatio: 3.0
|
|
27
27
|
tablet:
|
|
28
28
|
label: "Tablet Header (2:1)"
|
|
29
29
|
aspectRatio: 2.0
|
|
30
|
-
mobile:
|
|
31
|
-
label: "Mobile Header (4:3)"
|
|
32
|
-
aspectRatio: 1.33
|
|
33
30
|
public: true
|
|
34
31
|
content: # š Changed 'main' to 'content'
|
|
35
32
|
label: Content
|
|
@@ -16,7 +16,22 @@ tabs:
|
|
|
16
16
|
# šÆ 1. Include FieldSet Bundle
|
|
17
17
|
- fieldSet: page-base
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
- logoText:
|
|
20
|
+
label: Logo Text
|
|
21
|
+
type: text
|
|
22
|
+
required: false
|
|
23
|
+
public: true
|
|
24
|
+
inherits: logoText
|
|
25
|
+
|
|
26
|
+
- logoImage:
|
|
27
|
+
label: "Logo Image"
|
|
28
|
+
type: image
|
|
29
|
+
maxPreviewWidth: 300px
|
|
30
|
+
multiple: false
|
|
31
|
+
allowedTypes: ["image/svg"]
|
|
32
|
+
public: true
|
|
33
|
+
inherits: logoImage
|
|
34
|
+
|
|
20
35
|
- layoutId:
|
|
21
36
|
label: Page Layout
|
|
22
37
|
type: layout-select
|
|
@@ -26,7 +41,6 @@ tabs:
|
|
|
26
41
|
allowedLayouts:
|
|
27
42
|
- two-column
|
|
28
43
|
- single-column
|
|
29
|
-
- three-column
|
|
30
44
|
- landing-page
|
|
31
45
|
options:
|
|
32
46
|
- { label: "Inherit Layout", value: "inherit" }
|
|
@@ -39,7 +53,6 @@ tabs:
|
|
|
39
53
|
inheritsFromParent: true
|
|
40
54
|
allowedLayouts:
|
|
41
55
|
- two-column
|
|
42
|
-
- three-column
|
|
43
56
|
- single-column
|
|
44
57
|
- landing-page
|
|
45
58
|
options:
|