@brightsideoy/kama 0.1.0-alpha.12 → 0.1.0-alpha.121

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 (86) hide show
  1. package/README.md +195 -0
  2. package/bin/cli.js +602 -0
  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 +17 -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 +44 -0
  29. package/content/definitions/node-layouts/two-column.yml +49 -0
  30. package/content/definitions/nodes/address.yaml +40 -0
  31. package/content/definitions/nodes/article.yaml +48 -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 +57 -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-C6GoXL-R.js +162 -0
  46. package/dist/assets/index-Drmp3h6P.css +1 -0
  47. package/dist/index.html +13 -0
  48. package/dist/index.js +12209 -2045
  49. package/documentation/SCHEMAS.md +182 -0
  50. package/package.json +14 -11
  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 +62 -0
  68. package/templates/astro-starter/src/components/global/Footer.astro +48 -0
  69. package/templates/astro-starter/src/components/global/Header.astro +92 -0
  70. package/templates/astro-starter/src/components/global/NavigationMenu.astro +450 -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 +201 -0
  81. package/templates/astro-starter/src/pages/llms-full.txt.ts +161 -0
  82. package/templates/astro-starter/src/pages/llms.txt.ts +107 -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
  86. package/test-local.sh +76 -0
@@ -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,17 @@
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
+ meta:
15
+ label: "SEO"
16
+ fields:
17
+ 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"
@@ -0,0 +1,31 @@
1
+ id: tree-base
2
+ label: Tree 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: "Label"
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
+ index: true
24
+ public: 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."
@@ -0,0 +1,8 @@
1
+ fields:
2
+ showInMenus:
3
+ type: boolean
4
+ label: Show in Menus
5
+ default: true
6
+ position: sidebar
7
+ public: true
8
+ variant: alert
@@ -0,0 +1,12 @@
1
+ id: content
2
+ label: Content
3
+
4
+ layout:
5
+ columns: "1fr"
6
+ areas:
7
+ - ["content"]
8
+
9
+ regions:
10
+ content:
11
+ label: Content
12
+ allowedBlocks: "*"
@@ -0,0 +1,25 @@
1
+ id: landing-page
2
+ label: Landing Page
3
+
4
+ layout:
5
+ columns: "1fr"
6
+ areas:
7
+ - ["header"]
8
+ - ["content"]
9
+ - ["footer"]
10
+
11
+ regions:
12
+ header:
13
+ label: Header
14
+ inherit: parent
15
+ allowedBlocks: "*"
16
+ content:
17
+ label: Content
18
+ allowedBlocks: "*"
19
+ footer:
20
+ label: Footer
21
+ inherit: parent
22
+ disallowedBlocks:
23
+ - hero
24
+ - image_card
25
+ - header_image
@@ -0,0 +1,44 @@
1
+ id: single-column
2
+ label: Single Column
3
+
4
+ layout:
5
+ columns: "1fr"
6
+ areas:
7
+ - ["header"]
8
+ - ["content"]
9
+ - ["footer"]
10
+
11
+ regions:
12
+ header:
13
+ label: Header Image
14
+ showLabel: true
15
+ inherit: parent
16
+ allowOverride: true
17
+ dropType: image
18
+ maxPreviewWidth: 800px
19
+ multiple: false
20
+ maxSizeMB: 20
21
+ allowedTypes: ["image/*"]
22
+ crops:
23
+ standard:
24
+ label: "Desktop Header (4:1)"
25
+ aspectRatio: 4.0
26
+ tablet:
27
+ label: "Tablet Header (2:1)"
28
+ aspectRatio: 2.0
29
+ mobile:
30
+ label: "Mobile Header (4:3)"
31
+ aspectRatio: 1.33
32
+ public: true
33
+
34
+ content:
35
+ label: Content
36
+ allowedBlocks: "*"
37
+
38
+ footer:
39
+ label: Footer
40
+ inherit: parent
41
+ disallowedBlocks:
42
+ - hero
43
+ - image_card
44
+ - header_image