@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,49 @@
1
+ # content/definitions/layouts/two-column-split.yml
2
+ id: two-column
3
+ label: Two Column
4
+
5
+ layout:
6
+ columns: "10fr 4fr"
7
+ areas:
8
+ - ["header", "header"]
9
+ - ["content", "sidebar"] # 👈 Changed 'main' to 'content' to match old data!
10
+ - ["footer", "footer"]
11
+
12
+ regions:
13
+ header:
14
+ label: Header Image
15
+ showLabel: true
16
+ inherit: parent
17
+ allowOverride: true
18
+ dropType: image
19
+ maxPreviewWidth: 800px
20
+ multiple: false
21
+ maxSizeMB: 20
22
+ allowedTypes: ["image/*"]
23
+ crops:
24
+ standard:
25
+ label: "Desktop Header (4:1)"
26
+ aspectRatio: 4.0
27
+ tablet:
28
+ label: "Tablet Header (2:1)"
29
+ aspectRatio: 2.0
30
+ mobile:
31
+ label: "Mobile Header (4:3)"
32
+ aspectRatio: 1.33
33
+ public: true
34
+ content: # 👈 Changed 'main' to 'content'
35
+ label: Content
36
+ allowedBlocks: "*"
37
+ sidebar:
38
+ label: Sidebar
39
+ disallowedBlocks:
40
+ - hero
41
+ - image_card
42
+ - header_image
43
+ footer:
44
+ label: Footer
45
+ inherit: parent
46
+ disallowedBlocks:
47
+ - hero
48
+ - image_card
49
+ - header_image
@@ -0,0 +1,40 @@
1
+ id: address
2
+ label: Address
3
+ inTree: false
4
+
5
+ tabs:
6
+ settings:
7
+ label: "Address"
8
+ fields:
9
+ title:
10
+ label: Address Title
11
+ required: true
12
+
13
+ street:
14
+ label: Street
15
+
16
+ city:
17
+ label: City
18
+
19
+ area:
20
+ label: County / Area
21
+
22
+ zip:
23
+ label: ZIP
24
+
25
+ country:
26
+ label: Country
27
+
28
+ geolocation:
29
+ label: "Geolocation"
30
+ fields:
31
+ lat:
32
+ label: Latitude
33
+
34
+ lng:
35
+ label: Longitude
36
+
37
+ timezone:
38
+ label: Timezone
39
+
40
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,48 @@
1
+ id: article
2
+ label: Article
3
+ inTree: false
4
+ hasCanvas: true
5
+ directLinking: true
6
+
7
+ regions:
8
+ content:
9
+ label: Content
10
+
11
+ allowedBlocks:
12
+ - header
13
+ - hero
14
+ - text
15
+ - image_card
16
+ - header_image
17
+ - two-column
18
+ - three-column
19
+ - single_image
20
+
21
+ tabs:
22
+ settings:
23
+ label: "Article"
24
+ fields:
25
+ <<: !include ../field-sets/page-base.yaml
26
+
27
+ title:
28
+ label: Article title
29
+ required: true
30
+
31
+ slug:
32
+ linkedTo: "title"
33
+
34
+ articleDate:
35
+ type: date
36
+ label: Article Date
37
+ public: true
38
+ default: now
39
+ index: true
40
+
41
+ abstract:
42
+ label: Abstract
43
+ type: textarea
44
+ public: true
45
+
46
+ meta: !include ../field-sets/page-meta.yaml
47
+ social: !include ../field-sets/page-social.yaml
48
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,55 @@
1
+ id: event
2
+ label: Event
3
+ inTree: false
4
+ hasCanvas: true
5
+ directLinking: true
6
+
7
+ regions:
8
+ main:
9
+ label: Content
10
+
11
+ allowedBlocks:
12
+ - header
13
+ - hero
14
+ - text
15
+ - image_card
16
+ - header_image
17
+ - two-column
18
+ - three-column
19
+ - single_image
20
+
21
+ tabs:
22
+ settings:
23
+ label: "Event"
24
+ fields:
25
+ <<: !include ../field-sets/page-base.yaml
26
+
27
+ title:
28
+ label: Event Title
29
+ required: true
30
+ showAsEditorTitle: true
31
+
32
+ slug:
33
+ linkedTo: "title"
34
+
35
+ startTime:
36
+ type: datetime
37
+ label: Starts
38
+ public: true
39
+ index: true
40
+ showAsEditorTitle: true
41
+
42
+ endTime:
43
+ type: datetime
44
+ label: Finishes
45
+ public: true
46
+ index: true
47
+
48
+ abstract:
49
+ label: Abstract
50
+ type: textarea
51
+ public: true
52
+
53
+ meta: !include ../field-sets/page-meta.yaml
54
+ social: !include ../field-sets/page-social.yaml
55
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,29 @@
1
+ id: external-link
2
+ label: External Link
3
+ inTree: true
4
+
5
+ tabs:
6
+ settings:
7
+ label: "Link"
8
+ fields:
9
+ <<: !include ../field-sets/page-base.yaml
10
+
11
+ title:
12
+ label: Link Text
13
+
14
+ iconName:
15
+ label: Icon
16
+ type: icon
17
+ dbType: text
18
+ packages: ["heroicons", "lucide", "mdi"]
19
+
20
+ slug:
21
+ label: Slug
22
+ linkedTo: "menuTitle, title"
23
+
24
+ url:
25
+ label: URL
26
+ type: text
27
+ public: true
28
+
29
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,48 @@
1
+ id: page-skeleton
2
+ label: Page Skeleton
3
+ description: Clean slate for pages with custom CSS and HTML
4
+ inTree: true
5
+ inVault: true
6
+ hasCanvas: true
7
+ directLinking: true
8
+
9
+ defaultLayout: "content"
10
+
11
+ allowedBlocks: "html"
12
+
13
+ tabs:
14
+ settings:
15
+ label: "Page"
16
+ fields:
17
+ # 🎯 1. Include FieldSet Bundle
18
+ - fieldSet: page-base
19
+
20
+ - menuTitle:
21
+ label: Menu Title
22
+ type: text
23
+ dbType: text
24
+ public: true
25
+ css:
26
+ label: "CSS"
27
+ fields:
28
+ - css:
29
+ label: "CSS"
30
+ type: textarea
31
+ public: true
32
+ jsHeader:
33
+ label: "JavaScript"
34
+ fields:
35
+ - jsHeader:
36
+ label: "JS in Header"
37
+ type: textarea
38
+ public: true
39
+
40
+ - jsFooter:
41
+ label: "JS in Footer"
42
+ type: textarea
43
+ public: true
44
+
45
+ # Dedicated Tab Inclusions
46
+ meta: !include ../field-sets/page-seo.yaml
47
+ social: !include ../field-sets/page-social.yaml
48
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,57 @@
1
+ id: page
2
+ label: Page
3
+ inTree: true
4
+ inVault: true
5
+ hasCanvas: true
6
+ directLinking: true
7
+
8
+ defaultLayout: "single-column"
9
+
10
+ allowedBlocks: "*"
11
+
12
+ tabs:
13
+ settings:
14
+ label: "Page"
15
+ fields:
16
+ # 🎯 1. Include FieldSet Bundle
17
+ - fieldSet: page-base
18
+
19
+ # 🎯 3. Inline Fields
20
+ - layoutId:
21
+ label: Page Layout
22
+ type: layout-select
23
+ dbType: text
24
+ default: "inherit"
25
+ inheritsFromParent: true
26
+ allowedLayouts:
27
+ - two-column
28
+ - single-column
29
+ - three-column
30
+ - landing-page
31
+ options:
32
+ - { label: "Inherit Layout", value: "inherit" }
33
+
34
+ - subpageLayoutId:
35
+ label: Subpages Layout Rule
36
+ type: layout-select
37
+ dbType: text
38
+ default: "inherit"
39
+ inheritsFromParent: true
40
+ allowedLayouts:
41
+ - two-column
42
+ - three-column
43
+ - single-column
44
+ - landing-page
45
+ options:
46
+ - { label: "Inherit Layout", value: "inherit" }
47
+
48
+ - menuTitle:
49
+ label: Menu Title
50
+ type: text
51
+ dbType: text
52
+ public: true
53
+
54
+ # Dedicated Tab Inclusions
55
+ meta: !include ../field-sets/page-seo.yaml
56
+ social: !include ../field-sets/page-social.yaml
57
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,41 @@
1
+ id: person
2
+ label: Person
3
+ inTree: false
4
+ inVault: true
5
+ hasCanvas: false
6
+
7
+ tabs:
8
+ settings:
9
+ label: "Person"
10
+ fields:
11
+ image:
12
+ label: Image
13
+ type: asset
14
+ multiple: false
15
+ maxSizeMB: 15
16
+ allowedTypes: ["image/*"]
17
+ maxPreviewWidth: 300
18
+ crops:
19
+ list_thumb:
20
+ label: "List View"
21
+ aspectRatio: 1
22
+ shape: "circle"
23
+ public: true
24
+
25
+ title:
26
+ label: Title
27
+ required: false
28
+
29
+ firstName:
30
+ label: First Name
31
+ showAsEditorTitle: true
32
+
33
+ lastName:
34
+ label: Last Name
35
+ showAsEditorTitle: true
36
+
37
+ position:
38
+ label: Position
39
+ required: false
40
+
41
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,89 @@
1
+ id: product
2
+ label: Product
3
+ inTree: false
4
+ inVault: true
5
+ hasCanvas: false
6
+ directLinking: true
7
+
8
+ layout:
9
+ columns: "3fr 1fr"
10
+ areas:
11
+ - ["main", "sidebar"]
12
+
13
+ regions:
14
+ main:
15
+ label: Product Content
16
+ sidebar:
17
+ label: Sidebar
18
+
19
+ allowedBlocks:
20
+ - header
21
+ - hero
22
+ - text
23
+ - image_card
24
+ - header_image
25
+ - two-column
26
+ - three-column
27
+ - single_image
28
+
29
+ tabs:
30
+ settings:
31
+ label: "Product"
32
+ fields:
33
+ <<: !include ../field-sets/page-base.yaml
34
+
35
+ title:
36
+ label: Product Name
37
+ required: true
38
+ public: true
39
+
40
+ slug:
41
+ linkedTo: "title"
42
+
43
+ price:
44
+ label: Price (€)
45
+ type: number
46
+ public: true
47
+
48
+ description:
49
+ label: Short Abstract
50
+ type: textarea
51
+ public: true
52
+
53
+ media:
54
+ label: "Media"
55
+ fields:
56
+ featuredImage:
57
+ label: Main Product Image
58
+ description: "This is the primary image used in product grids, search results, and catalogs."
59
+ type: asset
60
+ multiple: false
61
+ maxSizeMB: 15
62
+ allowedTypes: ["image/jpeg", "image/png", "image/webp"]
63
+ crops:
64
+ list_thumb:
65
+ label: "List View (4:3)"
66
+ aspectRatio: 1.333
67
+ catalog_card:
68
+ label: "Portrait Card (3:4)"
69
+ aspectRatio: 0.75
70
+ public: true
71
+
72
+ gallery:
73
+ label: Product Gallery
74
+ description: "Drag up to 10 images here for the product detail carousel."
75
+ type: asset
76
+ multiple: true
77
+ maxItems: 10
78
+ allowedTypes: ["image/jpeg", "image/png", "image/webp"]
79
+ crops:
80
+ carousel:
81
+ label: "Carousel Hero (16:9)"
82
+ aspectRatio: 1.777
83
+ zoom:
84
+ label: "Detail Zoom (Square)"
85
+ aspectRatio: 1.0
86
+ public: true
87
+
88
+ meta: !include ../field-sets/page-meta.yaml
89
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,24 @@
1
+ id: navigation
2
+ label: "Site Navigation"
3
+
4
+ tabs:
5
+ settings:
6
+ label: "Tree"
7
+ fields:
8
+ # 🎯 1. Merge the tree-base fields directly into this dictionary
9
+ fieldSet: tree-base
10
+
11
+ baseUrl:
12
+ label: Base URL
13
+ type: text
14
+ dbType: text
15
+ public: true
16
+
17
+ defaultLanguage:
18
+ label: Language / Locale
19
+ type: language-select
20
+ dbType: text
21
+ public: true
22
+
23
+ # 🎯 2. Mount the access file as an entirely separate tab
24
+ access: !include ../field-sets/access.yaml
@@ -0,0 +1,11 @@
1
+ import StarterKit from "@tiptap/starter-kit";
2
+ import type { RteProfile } from "../../utils/rteProfiles";
3
+
4
+ export const profile: RteProfile = {
5
+ toolbar: [
6
+ "bold",
7
+ "italic",
8
+ "superscript",
9
+ "subscript",
10
+ ],
11
+ };
@@ -0,0 +1,21 @@
1
+ import StarterKit from "@tiptap/starter-kit";
2
+ import type { RteProfile } from "../../utils/rteProfiles";
3
+ import Link from "../../src/utils/CmsLink";
4
+
5
+ export const profile: RteProfile = {
6
+ extensions: [StarterKit, Link.configure({ openOnClick: false })],
7
+ toolbar: [
8
+ "heading-1",
9
+ "heading-2",
10
+ "heading-3",
11
+ "heading-4",
12
+ "bold",
13
+ "italic",
14
+ "bullet-list",
15
+ "ordered-list",
16
+ "blockquote",
17
+ "link",
18
+ "superscript",
19
+ "subscript",
20
+ ],
21
+ };
@@ -0,0 +1,36 @@
1
+ // definitions/editor/header.ts
2
+ import StarterKit from "@tiptap/starter-kit";
3
+ import Document from "@tiptap/extension-document";
4
+ import Subscript from "@tiptap/extension-subscript";
5
+ import Superscript from "@tiptap/extension-superscript";
6
+ import type { RteProfile } from "../../src/utils/rteProfiles";
7
+ import Link from "../../src/utils/CmsLink";
8
+
9
+ // Custom document node forcing default top-level block to be a heading (H2)
10
+ const CustomDocument = Document.extend({
11
+ content: "heading block*",
12
+ });
13
+
14
+ export const profile: RteProfile = {
15
+ extensions: [
16
+ CustomDocument,
17
+ StarterKit.configure({
18
+ document: false, // Replaces TipTap's default Document with CustomDocument
19
+ heading: { levels: [1, 2, 3, 4] },
20
+ }),
21
+ Subscript.configure(),
22
+ Superscript.configure(),
23
+ Link.configure({ openOnClick: false }),
24
+ ],
25
+ toolbar: [
26
+ "heading-1",
27
+ "heading-2",
28
+ "heading-3",
29
+ "heading-4",
30
+ "bold",
31
+ "italic",
32
+ "superscript",
33
+ "subscript",
34
+ "link",
35
+ ],
36
+ };
@@ -0,0 +1,15 @@
1
+ import StarterKit from "@tiptap/starter-kit";
2
+ import type { RteProfile } from "../../utils/rteProfiles";
3
+ import Link from "../../src/utils/CmsLink";
4
+
5
+ export const profile: RteProfile = {
6
+ extensions: [StarterKit, Link.configure({ openOnClick: false })],
7
+ toolbar: [
8
+ "bold",
9
+ "italic",
10
+ "bullet-list",
11
+ "ordered-list",
12
+ "superscript",
13
+ "subscript",
14
+ ],
15
+ };
@@ -0,0 +1,12 @@
1
+ // definitions/validators/iban.ts
2
+
3
+ export const iban = (value: any, ruleValue: any, field: any) => {
4
+ if (!value || !ruleValue) return "";
5
+
6
+ const isValid = /^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/.test(String(value).toUpperCase());
7
+ if (!isValid) {
8
+ return field.rules?.customMessage || "Invalid IBAN format.";
9
+ }
10
+
11
+ return "";
12
+ };
@@ -0,0 +1,7 @@
1
+ // definitions/validators/test.ts
2
+ export const isMagicWord = (value: any, ruleValue: any, field: any) => {
3
+ if (value && value.toLowerCase() !== "magic") {
4
+ return field.rules?.customMessage || "You didn't say the magic word!";
5
+ }
6
+ return "";
7
+ };