@brightsideoy/kama 0.1.0-alpha.14 → 0.1.0-alpha.140

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 (85) hide show
  1. package/README.md +195 -0
  2. package/bin/cli.js +624 -180
  3. package/content/definitions/block-layouts/three-column.yaml +20 -0
  4. package/content/definitions/block-layouts/two-column.yaml +29 -0
  5. package/content/definitions/blocks/button.yaml +24 -0
  6. package/content/definitions/blocks/header.yaml +13 -0
  7. package/content/definitions/blocks/header_image.yaml +21 -0
  8. package/content/definitions/blocks/hero.yaml +28 -0
  9. package/content/definitions/blocks/html.yaml +12 -0
  10. package/content/definitions/blocks/image_card.yaml +56 -0
  11. package/content/definitions/blocks/single_image.yaml +27 -0
  12. package/content/definitions/blocks/text.yaml +15 -0
  13. package/content/definitions/channels/ecommerce.yaml +28 -0
  14. package/content/definitions/channels/website.yaml +41 -0
  15. package/content/definitions/field-sets/access.yaml +27 -0
  16. package/content/definitions/field-sets/channel-base.yaml +50 -0
  17. package/content/definitions/field-sets/channel-seo.yaml +21 -0
  18. package/content/definitions/field-sets/comments.yaml +11 -0
  19. package/content/definitions/field-sets/content-block.yaml +41 -0
  20. package/content/definitions/field-sets/page-base.yaml +44 -0
  21. package/content/definitions/field-sets/page-seo.yaml +34 -0
  22. package/content/definitions/field-sets/page-social.yaml +78 -0
  23. package/content/definitions/field-sets/schema-type.yaml +43 -0
  24. package/content/definitions/field-sets/tree-base.yaml +31 -0
  25. package/content/definitions/field-sets/visibility.yaml +8 -0
  26. package/content/definitions/node-layouts/content.yml +12 -0
  27. package/content/definitions/node-layouts/landing-page.yml +25 -0
  28. package/content/definitions/node-layouts/single-column.yml +41 -0
  29. package/content/definitions/node-layouts/two-column.yml +46 -0
  30. package/content/definitions/nodes/address.yaml +40 -0
  31. package/content/definitions/nodes/article.yaml +37 -0
  32. package/content/definitions/nodes/event.yaml +55 -0
  33. package/content/definitions/nodes/external-link.yaml +29 -0
  34. package/content/definitions/nodes/page-skeleton.yaml +48 -0
  35. package/content/definitions/nodes/page.yaml +70 -0
  36. package/content/definitions/nodes/person.yaml +41 -0
  37. package/content/definitions/nodes/product.yaml +89 -0
  38. package/content/definitions/trees/navigation.yaml +24 -0
  39. package/definitions/editor/button.ts +11 -0
  40. package/definitions/editor/default.ts +21 -0
  41. package/definitions/editor/header.ts +36 -0
  42. package/definitions/editor/minimal.ts +15 -0
  43. package/definitions/validators/iban.ts +12 -0
  44. package/definitions/validators/magic-word.ts +7 -0
  45. package/dist/assets/index-Bv7fPRX7.css +1 -0
  46. package/dist/assets/index-D5P3jaVv.js +162 -0
  47. package/dist/index.html +13 -0
  48. package/dist/index.js +12327 -2110
  49. package/documentation/SCHEMAS.md +182 -0
  50. package/package.json +12 -14
  51. package/schema.sql +204 -0
  52. package/templates/astro-starter/astro.config.mjs +40 -0
  53. package/templates/astro-starter/middleware/api-purge.ts +130 -0
  54. package/templates/astro-starter/middleware/index.ts +10 -0
  55. package/templates/astro-starter/middleware/kv-cache.ts +76 -0
  56. package/templates/astro-starter/middleware/response-headers.ts +43 -0
  57. package/templates/astro-starter/package.json.template +20 -0
  58. package/templates/astro-starter/public/css/standard-theme.css +157 -0
  59. package/templates/astro-starter/public/robots.txt +23 -0
  60. package/templates/astro-starter/src/components/blocks/BlockRenderer.astro +133 -0
  61. package/templates/astro-starter/src/components/blocks/ColumnLayout.astro +66 -0
  62. package/templates/astro-starter/src/components/blocks/HeaderImage.astro +131 -0
  63. package/templates/astro-starter/src/components/blocks/Hero.astro +218 -0
  64. package/templates/astro-starter/src/components/blocks/HtmlBlock.astro +24 -0
  65. package/templates/astro-starter/src/components/blocks/ImageBlock.astro +160 -0
  66. package/templates/astro-starter/src/components/blocks/TextBlock.astro +13 -0
  67. package/templates/astro-starter/src/components/global/Breadcrumb.astro +65 -0
  68. package/templates/astro-starter/src/components/global/Footer.astro +48 -0
  69. package/templates/astro-starter/src/components/global/Header.astro +101 -0
  70. package/templates/astro-starter/src/components/global/NavigationMenu.astro +466 -0
  71. package/templates/astro-starter/src/components/seo/SeoHead.astro +150 -0
  72. package/templates/astro-starter/src/components/ui/KamaImage.astro +149 -0
  73. package/templates/astro-starter/src/layouts/SkeletonLayout.astro +45 -0
  74. package/templates/astro-starter/src/layouts/StandardLayout.astro +52 -0
  75. package/templates/astro-starter/src/lib/cms.ts +149 -0
  76. package/templates/astro-starter/src/lib/media/kama-image-service.ts +41 -0
  77. package/templates/astro-starter/src/lib/media/media-proxy.ts +127 -0
  78. package/templates/astro-starter/src/lib/media/media-url.ts +34 -0
  79. package/templates/astro-starter/src/pages/404.astro +46 -0
  80. package/templates/astro-starter/src/pages/[...slug].astro +224 -0
  81. package/templates/astro-starter/src/pages/llms-full.txt.ts +171 -0
  82. package/templates/astro-starter/src/pages/llms.txt.ts +113 -0
  83. package/templates/astro-starter/src/pages/media/[...path].ts +7 -0
  84. package/templates/astro-starter/src/utils/tiptap.ts +113 -0
  85. package/templates/astro-starter/tsconfig.json +0 -0
@@ -0,0 +1,20 @@
1
+ id: three-column
2
+ label: Three Columns (33/33/33)
3
+ showLabel: false
4
+ group: Sub-Layouts
5
+
6
+ layout:
7
+ columns: "1fr 1fr 1fr"
8
+ areas:
9
+ - ["left", "middle", "right"]
10
+
11
+ regions:
12
+ left:
13
+ label: Left Column
14
+ showLabel: false # 👈 Hides "LEFT COLUMN" header on this region cell
15
+ middle:
16
+ label: Middle Column
17
+ showLabel: false # 👈 Hides "LEFT COLUMN" header on this region cell
18
+ right:
19
+ label: Right Column
20
+ showLabel: false # 👈 Keeps "RIGHT COLUMN" visible
@@ -0,0 +1,29 @@
1
+ id: two-column
2
+ label: Two Columns (50/50)
3
+ showLabel: false # 👈 Hides the main "Two Columns" badge on the canvas
4
+ group: Sub-Layouts
5
+
6
+ layout:
7
+ columns: "1fr 1fr"
8
+ areas:
9
+ - ["left", "right"]
10
+
11
+ regions:
12
+ left:
13
+ label: Left Column
14
+ showLabel: false # 👈 Hides "LEFT COLUMN" header on this region cell
15
+ right:
16
+ label: Right Column
17
+ showLabel: false # 👈 Keeps "RIGHT COLUMN" visible
18
+
19
+ # Optional: We can give the layout block its own settings!
20
+ fields:
21
+ gap:
22
+ label: Column Gap
23
+ type: select
24
+ default: "2rem"
25
+ options:
26
+ - { label: "None", value: "0" }
27
+ - { label: "Small", value: "1rem" }
28
+ - { label: "Medium", value: "2rem" }
29
+ - { label: "Large", value: "4rem" }
@@ -0,0 +1,24 @@
1
+ id: button
2
+ label: Button
3
+ group: Content
4
+ description: A customizable button link.
5
+
6
+ fields:
7
+ text:
8
+ label: Text
9
+ type: richtext
10
+ editor: button
11
+ public: true
12
+ link:
13
+ label: Link
14
+ type: link
15
+ position: sidebar
16
+ allowedLinkTypes:
17
+ - tree
18
+ - node
19
+ - url
20
+ - file
21
+ - email
22
+ - telephone
23
+ tabs:
24
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,13 @@
1
+ id: header
2
+ label: Header
3
+ group: Content
4
+
5
+ fields:
6
+ headline:
7
+ type: richtext
8
+ editor: header
9
+ label: Headline
10
+ public: true
11
+
12
+ tabs:
13
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,21 @@
1
+ id: header_image
2
+ label: Header Image
3
+ group: Media
4
+ description: Image for page header.
5
+
6
+ fields:
7
+ image:
8
+ label: Image
9
+ type: asset
10
+ required: true
11
+ multiple: false
12
+ maxSizeMB: 15
13
+ allowedTypes: ["image/*"]
14
+ crops:
15
+ standard:
16
+ label: "Page header (21:9)"
17
+ aspectRatio: 2.333
18
+ public: true
19
+
20
+ tabs:
21
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,28 @@
1
+ id: hero
2
+ label: Hero
3
+ group: Content
4
+
5
+ fields:
6
+ heroBadge:
7
+ type: text
8
+ label: Badge
9
+ public: true
10
+
11
+ heroTitle:
12
+ type: text
13
+ label: Title
14
+ public: true
15
+
16
+ heroSubTitle:
17
+ type: text
18
+ label: Sub-Title
19
+ public: true
20
+
21
+ headline:
22
+ type: richtext
23
+ editor: header
24
+ label: Headline
25
+ public: true
26
+
27
+ tabs:
28
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,12 @@
1
+ id: html
2
+ label: HTML
3
+ group: Content
4
+
5
+ fields:
6
+ body:
7
+ label: HTML
8
+ type: textarea
9
+ public: true
10
+
11
+ tabs:
12
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,56 @@
1
+ id: image_card
2
+ label: Image Card
3
+ group: Content
4
+ description: A versatile card with an image, text, and a CTA button.
5
+
6
+ fields:
7
+ image:
8
+ label: Card Image
9
+ showLabel: false
10
+ type: asset
11
+ required: true
12
+ multiple: false
13
+ maxSizeMB: 15
14
+ maxPreviewWidth: 300px
15
+ allowedTypes: ["image/*"]
16
+ crops:
17
+ standard:
18
+ label: "Card Header (16:9)"
19
+ aspectRatio: 3.0
20
+ public: true
21
+
22
+ headline:
23
+ label: Headline
24
+ type: text
25
+ required: true
26
+ public: true
27
+ default: "Headline..."
28
+
29
+ summary:
30
+ label: Text
31
+ description: Keep it brief, 2-3 sentences max.
32
+ type: richtext
33
+ editor: minimal
34
+ public: true
35
+ default: "Card text content..."
36
+
37
+ link:
38
+ label: Link
39
+ type: link
40
+ allowedLinkTypes:
41
+ - tree
42
+ - node
43
+ - url
44
+ - file
45
+ - email
46
+ - telephone
47
+
48
+ linkText:
49
+ label: Button Text
50
+ type: text
51
+ description: "e.g., 'Read More' or 'Buy Now'"
52
+ default: "Read More"
53
+ public: true
54
+
55
+ tabs:
56
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,27 @@
1
+ id: single_image
2
+ label: Single Image
3
+ group: Media
4
+ description: Just a single image block.
5
+
6
+ fields:
7
+ image:
8
+ label: Image
9
+ type: asset
10
+ required: true
11
+ multiple: false
12
+ maxSizeMB: 15
13
+ allowedTypes: ["image/*"]
14
+ public: true
15
+
16
+ link:
17
+ label: Link
18
+ type: link
19
+ position: sidebar
20
+ allowedLinkTypes:
21
+ - tree
22
+ - node
23
+ - url
24
+ - file
25
+
26
+ tabs:
27
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,15 @@
1
+ id: text
2
+ label: Text
3
+ group: Content
4
+ description: Paragraph body
5
+
6
+ # Main content fields
7
+ fields:
8
+ body:
9
+ label: Text
10
+ type: richtext
11
+ editor: default
12
+ allowSplit: true
13
+ public: true
14
+
15
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,28 @@
1
+ id: ecommerce
2
+ label: "E-Commerce"
3
+
4
+ tabs:
5
+ settings:
6
+ label: "Channel"
7
+ fields:
8
+ fieldSet: channel-base
9
+ currency:
10
+ label: Default Currency
11
+ type: select
12
+ default: "EUR"
13
+ options:
14
+ - "EUR"
15
+ - "USD"
16
+ - "GBP"
17
+ checkoutUrl:
18
+ label: Checkout Endpoint URL
19
+ type: text
20
+ public: true
21
+ meta:
22
+ label: "SEO"
23
+ fields:
24
+ fieldSet: channel-seo
25
+ access:
26
+ label: "Access"
27
+ fields:
28
+ fieldSet: access
@@ -0,0 +1,41 @@
1
+ id: website
2
+ label: "Website"
3
+
4
+ # 🎯 2. Mounts the access tab automatically (engine natively resolves fieldSets into tabs if configured in the field set)
5
+ fieldSets:
6
+ - access
7
+
8
+ tabs:
9
+ settings:
10
+ label: "Channel"
11
+ fields:
12
+ # 🎯 1. Natively merges channel-base fields into this tab
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
+
38
+ meta:
39
+ label: "SEO"
40
+ fields:
41
+ fieldSet: channel-seo
@@ -0,0 +1,27 @@
1
+ # 📂 content/definitions/field-sets/access.yaml
2
+ label: "Access"
3
+ fields:
4
+ isHidden:
5
+ type: boolean
6
+ label: Hidden
7
+ default: false
8
+ public: false
9
+ variant: danger
10
+ dbType: integer
11
+ index: true
12
+ position: sidebar
13
+ liveSync: true
14
+
15
+ startShowingAt:
16
+ type: datetime
17
+ label: Start Showing At
18
+ position: sidebar
19
+ public: false
20
+ index: true
21
+
22
+ stopShowingAt:
23
+ type: datetime
24
+ label: Stop Showing At
25
+ position: sidebar
26
+ public: false
27
+ index: true
@@ -0,0 +1,50 @@
1
+ id: channel-base
2
+ label: Channel Base Properties
3
+
4
+ fields:
5
+ id:
6
+ label: Internal ID
7
+ type: hidden
8
+ dbType: integer
9
+ primaryKey: true
10
+
11
+ label:
12
+ label: Channel Name
13
+ type: text
14
+ dbType: text
15
+ public: true
16
+ rules:
17
+ required: true
18
+
19
+ key:
20
+ label: "API Identifier"
21
+ type: slug
22
+ dbType: text
23
+ public: true
24
+ index: true
25
+ linkedTo: label
26
+ placeholder: "e.g. main-site, store-eu"
27
+ rules:
28
+ required: true
29
+ unique: true
30
+ pattern: "^[a-z0-9-_]+$"
31
+ customMessage: "API key must be unique and contain only lowercase letters, numbers, hyphens, or underscores."
32
+
33
+ baseUrl:
34
+ label: Base URL
35
+ type: text
36
+ dbType: text
37
+ public: true
38
+
39
+ defaultLanguage:
40
+ label: Default Language
41
+ type: language-select
42
+ dbType: text
43
+ public: true
44
+
45
+ supportedLanguages:
46
+ label: Supported Languages
47
+ type: language-select
48
+ multiple: true
49
+ dbType: json
50
+ public: true
@@ -0,0 +1,21 @@
1
+ fields:
2
+ metaDescription:
3
+ label: Meta Description
4
+ type: textarea
5
+ dbType: text
6
+ required: false
7
+ public: true
8
+
9
+ titlePrefix:
10
+ label: Title Prefix
11
+ type: text
12
+ dbType: text
13
+ required: false
14
+ public: true
15
+
16
+ titleSuffix:
17
+ label: Title Suffix
18
+ type: text
19
+ dbType: text
20
+ required: false
21
+ public: true
@@ -0,0 +1,11 @@
1
+ tab:
2
+ id: comments
3
+ label: "Comments"
4
+
5
+ fields:
6
+ isHidden:
7
+ type: textarea
8
+ label: Comments
9
+ public: false
10
+ index: true
11
+ position: sidebar
@@ -0,0 +1,41 @@
1
+ id:
2
+ label: ID
3
+ type: hidden
4
+ dbType: text
5
+ primaryKey: true
6
+
7
+ contentId:
8
+ label: Node ID
9
+ type: text
10
+ dbType: text
11
+ rules:
12
+ required: true
13
+
14
+ sortOrder:
15
+ label: Sort Order
16
+ type: number
17
+ dbType: integer
18
+ rules:
19
+ required: true
20
+
21
+ elementType:
22
+ label: Element Component Type
23
+ type: text
24
+ dbType: text
25
+ rules:
26
+ required: true
27
+
28
+ dataJson:
29
+ label: Content Field Data
30
+ type: json
31
+ dbType: json
32
+ rules:
33
+ required: true
34
+
35
+ region:
36
+ label: Grid Region
37
+ type: text
38
+ dbType: text
39
+ default: "main"
40
+ rules:
41
+ required: true
@@ -0,0 +1,44 @@
1
+ id:
2
+ label: ID
3
+ type: hidden
4
+ dbType: text
5
+ primaryKey: true
6
+ public: true
7
+
8
+ channelId:
9
+ label: Channel ID
10
+ type: hidden
11
+ dbType: text
12
+ public: true
13
+ index: true
14
+
15
+ nodeType:
16
+ label: Type
17
+ type: select
18
+ dbType: text
19
+ default: "page"
20
+ public: true
21
+ position: sidebar
22
+ rules:
23
+ required: true
24
+
25
+ title:
26
+ label: Page Title
27
+ type: text
28
+ dbType: text
29
+ public: true
30
+ rules:
31
+ required: true
32
+
33
+ slug:
34
+ label: URL Slug
35
+ type: slug
36
+ linkedTo: title
37
+ dbType: text
38
+ public: true
39
+ index: true
40
+ rules:
41
+ required: true
42
+ uniqueSibling: true
43
+ pattern: "^[a-z0-9_-]+$"
44
+ customMessage: "Slug can only contain lowercase letters, numbers, hyphens, and underscores."
@@ -0,0 +1,34 @@
1
+ label: "SEO"
2
+ fields:
3
+ # 🎯 1. Include the single field definition file
4
+ - schemaType: !include ./schema-type.yaml
5
+
6
+ # 🎯 2. Override the default for this specific section
7
+ - schemaType:
8
+ default: "WebPage"
9
+
10
+ # 🎯 3. Standard inline fields as sequence array items
11
+ - metaDescription:
12
+ label: Meta Description
13
+ type: textarea
14
+ public: true
15
+
16
+ - metaKeywords:
17
+ label: Meta Keywords
18
+ type: textarea
19
+ required: false
20
+ public: true
21
+
22
+ - titlePrefix:
23
+ label: Title Prefix
24
+ type: text
25
+ required: false
26
+ public: true
27
+ inherits: titlePrefix
28
+
29
+ - titleSuffix:
30
+ label: Title Suffix
31
+ type: text
32
+ required: false
33
+ public: true
34
+ inherits: titleSuffix
@@ -0,0 +1,78 @@
1
+ label: "Social"
2
+
3
+ fields:
4
+ # --- Facebook / Open Graph Texts ---
5
+ fbTitle:
6
+ label: "Facebook Title (og:title)"
7
+ type: text
8
+ inherits: title # 🔗 Syncs from SEO Title automatically
9
+ public: true
10
+ description: "The title of your article as it should appear on Facebook."
11
+
12
+ fbDescription:
13
+ label: "Facebook Description (og:description)"
14
+ type: textarea
15
+ inherits: metaDescription # 🔗 Syncs from main SEO description
16
+ public: true
17
+ description: "A 2-4 sentence summary of the content."
18
+
19
+ # --- X (Twitter) Texts ---
20
+ xTitle:
21
+ label: "X Title (twitter:title)"
22
+ type: text
23
+ inherits: fbTitle # 🔗 Cascades from Facebook Title
24
+ public: true
25
+ description: "Keep it concise (under 70 characters is ideal for X)."
26
+
27
+ xDescription:
28
+ label: "X Description (twitter:description)"
29
+ type: textarea
30
+ inherits: fbDescription
31
+ public: true
32
+
33
+ # ==========================================
34
+ # SOCIAL IMAGES (The Waterfall)
35
+ # ==========================================
36
+
37
+ # 1. The Source Image
38
+ socialImage:
39
+ label: "Master Social Image"
40
+ type: image
41
+ maxPreviewWidth: 620px
42
+ multiple: false
43
+ maxSizeMB: 10
44
+ allowedTypes: ["image/jpeg", "image/png", "image/webp"]
45
+ public: true
46
+
47
+ # 2. The Auto-Synced Crops
48
+ fbImage:
49
+ label: "Facebook / LinkedIn Image"
50
+ type: image
51
+ maxPreviewWidth: 620px
52
+ inherits: socialImage
53
+ public: true
54
+ description: "Auto-cropped to 1.91:1. Drop a new image here to override."
55
+ crops:
56
+ aspectRatio: 1.91
57
+
58
+ xImage:
59
+ label: "X (Twitter) Image"
60
+ type: image
61
+ maxPreviewWidth: 620px
62
+ inherits: socialImage
63
+ public: true
64
+ description: "Auto-cropped to 2:1. Drop a new image here to override."
65
+ crops:
66
+ aspectRatio: 2.0
67
+
68
+ whatsappImage:
69
+ label: "Messaging / Square Image"
70
+ type: image
71
+ maxPreviewWidth: 620px
72
+ inherits: socialImage
73
+ public: true
74
+ description: "Auto-cropped to 1:1. Drop a new image here to override."
75
+ crops:
76
+ whatsappImage:
77
+ label: "WhatsApp Image (1:1)"
78
+ aspectRatio: 1.0
@@ -0,0 +1,43 @@
1
+ type: select
2
+ label: "Schema.org Entity Type"
3
+ default: "WebPage"
4
+ public: true
5
+ options:
6
+ - label: "Standard Pages"
7
+ choices:
8
+ - label: "Standard Web Page"
9
+ value: "WebPage"
10
+ - label: "About Page"
11
+ value: "AboutPage"
12
+ - label: "Contact Page"
13
+ value: "ContactPage"
14
+ - label: "FAQ / Help Page"
15
+ value: "FAQPage"
16
+ - label: "Directory / Collection Page"
17
+ value: "CollectionPage"
18
+
19
+ - label: "Editorial & Articles"
20
+ choices:
21
+ - label: "General Article"
22
+ value: "Article"
23
+ - label: "Blog Post"
24
+ value: "BlogPosting"
25
+ - label: "Technical Docs / Guide"
26
+ value: "TechArticle"
27
+ - label: "News / Press Release"
28
+ value: "NewsArticle"
29
+ - label: "Whitepaper / Report"
30
+ value: "Report"
31
+
32
+ - label: "Commercial & Intent"
33
+ choices:
34
+ - label: "Service / Capability"
35
+ value: "Service"
36
+ - label: "Product / E-commerce Item"
37
+ value: "Product"
38
+ - label: "Educational Course"
39
+ value: "Course"
40
+ - label: "Event / Webinar"
41
+ value: "Event"
42
+ - label: "Job Career Listing"
43
+ value: "JobPosting"