@brightsideoy/kama 0.1.0-alpha.39 → 0.1.0-alpha.41

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 (40) hide show
  1. package/defaults/definitions/block-layouts/three-column.yaml +20 -0
  2. package/defaults/definitions/block-layouts/two-column.yaml +29 -0
  3. package/defaults/definitions/blocks/header.yaml +15 -0
  4. package/defaults/definitions/blocks/header_image.yaml +22 -0
  5. package/defaults/definitions/blocks/hero.yaml +27 -0
  6. package/defaults/definitions/blocks/image_card.yaml +53 -0
  7. package/defaults/definitions/blocks/text.yaml +16 -0
  8. package/defaults/definitions/channels/ecommerce.yaml +24 -0
  9. package/defaults/definitions/channels/website.yaml +32 -0
  10. package/defaults/definitions/field-sets/access.yaml +29 -0
  11. package/defaults/definitions/field-sets/channel-base.yaml +31 -0
  12. package/defaults/definitions/field-sets/comments.yaml +11 -0
  13. package/defaults/definitions/field-sets/content-block.yaml +46 -0
  14. package/defaults/definitions/field-sets/page-base.yaml +49 -0
  15. package/defaults/definitions/field-sets/page-meta.yaml +15 -0
  16. package/defaults/definitions/field-sets/page-social.yaml +80 -0
  17. package/defaults/definitions/field-sets/tree-base.yaml +31 -0
  18. package/defaults/definitions/field-sets/visibility.yaml +8 -0
  19. package/defaults/definitions/node-layouts/landing-page.yml +22 -0
  20. package/defaults/definitions/node-layouts/single-column.yml +38 -0
  21. package/defaults/definitions/node-layouts/three-column.yml +41 -0
  22. package/defaults/definitions/node-layouts/two-column.yml +40 -0
  23. package/defaults/definitions/nodes/address.yaml +32 -0
  24. package/defaults/definitions/nodes/article.yaml +41 -0
  25. package/defaults/definitions/nodes/event.yaml +40 -0
  26. package/defaults/definitions/nodes/external-link.yaml +26 -0
  27. package/defaults/definitions/nodes/page.yaml +63 -0
  28. package/defaults/definitions/nodes/person.yaml +35 -0
  29. package/defaults/definitions/nodes/product.yaml +79 -0
  30. package/defaults/definitions/trees/navigation.yaml +29 -0
  31. package/defaults/definitions/trees/social-links.yaml +9 -0
  32. package/definitions/_page.yaml +52 -0
  33. package/definitions/editor/default.ts +17 -0
  34. package/definitions/editor/header.ts +33 -0
  35. package/definitions/editor/minimal.ts +13 -0
  36. package/definitions/validators/iban.ts +12 -0
  37. package/definitions/validators/magic-word.ts +7 -0
  38. package/dist/index.js +10 -10
  39. package/package.json +3 -1
  40. package/scripts/bundle-definitions.js +40 -16
@@ -0,0 +1,40 @@
1
+ # defaults/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
+ sidebar:
37
+ label: Sidebar
38
+ footer:
39
+ label: Footer
40
+ inherit: parent
@@ -0,0 +1,32 @@
1
+ id: address
2
+ label: Address
3
+ inTree: false
4
+
5
+ # 👉 TABS DEFINITION
6
+ tabs:
7
+ settings:
8
+ label: "Address"
9
+ fields:
10
+ - title:
11
+ label: Address Title
12
+ required: true
13
+ - street:
14
+ label: Street
15
+ - city:
16
+ label: City
17
+ - area:
18
+ label: County / Area
19
+ - zip:
20
+ label: ZIP
21
+ - country:
22
+ label: Country
23
+ geolocation:
24
+ label: "Geolocation"
25
+ fields:
26
+ - lat:
27
+ label: Latitude
28
+ - lng:
29
+ label: Longitude
30
+ - timezone:
31
+ label: Timezone
32
+ - fieldSet: access
@@ -0,0 +1,41 @@
1
+ id: article
2
+ label: Article
3
+ inTree: false
4
+ hasCanvas: true
5
+
6
+ regions:
7
+ content:
8
+ label: Content
9
+
10
+ allowedElements:
11
+ - header
12
+ - hero
13
+ - text
14
+ - image_card
15
+ - header_image
16
+ - two-column
17
+ - three-column
18
+
19
+ tabs:
20
+ settings:
21
+ label: "Article"
22
+ fields:
23
+ - fieldSet: page-base
24
+ - title:
25
+ label: Article title
26
+ required: true
27
+ - slug:
28
+ linkedTo: "title"
29
+ - articleDate:
30
+ type: date
31
+ label: Article Date
32
+ public: true
33
+ default: now
34
+ index: true
35
+ - abstract:
36
+ label: Abstract
37
+ type: textarea
38
+ public: true
39
+ - fieldSet: page-meta
40
+ - fieldSet: page-social
41
+ - fieldSet: access
@@ -0,0 +1,40 @@
1
+ id: event
2
+ label: Event
3
+ inTree: false
4
+ hasCanvas: true
5
+
6
+ regions:
7
+ main:
8
+ label: Content
9
+
10
+ allowedElements:
11
+ - title-set
12
+ - text-block
13
+
14
+ tabs:
15
+ settings:
16
+ label: Event
17
+ fields:
18
+ - fieldSet: page-base
19
+ - title:
20
+ label: Event Title
21
+ required: true
22
+ - slug:
23
+ linkedTo: "title"
24
+ - startTime:
25
+ type: datetime
26
+ label: Starts
27
+ public: true
28
+ index: true
29
+ - endTime:
30
+ type: datetime
31
+ label: Finishes
32
+ public: true
33
+ index: true
34
+ - abstract:
35
+ label: Abstract
36
+ type: textarea
37
+ public: true
38
+ - fieldSet: page-meta
39
+ - fieldSet: page-social
40
+ - fieldSet: access
@@ -0,0 +1,26 @@
1
+ id: external-link
2
+ label: External Link
3
+ inTree: true
4
+
5
+ tabs:
6
+ settings:
7
+ label: "Link"
8
+ fields:
9
+ - fieldSet: page-base
10
+ - nodeType
11
+ - title:
12
+ label: Link Text
13
+ - iconName:
14
+ label: Icon
15
+ type: icon
16
+ dbType: text
17
+ packages: ["heroicons", "lucide", "mdi"]
18
+ - slug:
19
+ label: Slug
20
+ linkedTo: "menuTitle, title"
21
+ - url:
22
+ label: URL
23
+ type: text
24
+ public: true
25
+
26
+ - fieldSet: access
@@ -0,0 +1,63 @@
1
+ id: page
2
+ label: Page
3
+ inTree: true
4
+ inVault: true
5
+ hasCanvas: true
6
+
7
+ # 👈 Keep this as the absolute last-resort fallback for the Public API
8
+ defaultLayout: "single-column"
9
+
10
+ # 👈 Cleaned up naming!
11
+ allowedBlocks:
12
+ - header
13
+ - hero
14
+ - text
15
+ - image_card
16
+ - header_image
17
+ - two-column
18
+ - three-column
19
+
20
+ tabs:
21
+ settings:
22
+ label: "Page"
23
+ fields:
24
+ - fieldSet: page-base
25
+
26
+ # 👉 THE CURRENT PAGE'S LAYOUT
27
+ - layoutId:
28
+ label: Page Layout
29
+ type: layout-select
30
+ dbType: text
31
+ default: "inherit"
32
+ inheritsFromParent: true # 👈 Tells the UI to bind to the parent!
33
+ allowedLayouts:
34
+ - two-column
35
+ - single-column
36
+ - three-column
37
+ - landing-page
38
+ options:
39
+ - { label: "Inherit Layout", value: "inherit" }
40
+
41
+ # 👉 THE BEHAVIOR FOR ALL CHILDREN
42
+ - subpageLayoutId:
43
+ label: Subpages Layout Rule
44
+ type: layout-select
45
+ dbType: text
46
+ default: "inherit"
47
+ inheritsFromParent: true # 👈 A child's subpage rules can ALSO inherit!
48
+ allowedLayouts:
49
+ - two-column
50
+ - three-column
51
+ - single-column
52
+ - landing-page
53
+ options:
54
+ - { label: "Inherit Layout", value: "inherit" }
55
+
56
+ - menuTitle:
57
+ label: Menu Title
58
+ type: text
59
+ dbType: text
60
+ public: true
61
+ - fieldSet: page-meta
62
+ - fieldSet: page-social
63
+ - fieldSet: access
@@ -0,0 +1,35 @@
1
+ id: person
2
+ label: Person
3
+ inTree: false
4
+ inVault: true
5
+ hasCanvas: false
6
+
7
+ # 👉 TABS DEFINITION
8
+ tabs:
9
+ settings:
10
+ label: "Person"
11
+ fields:
12
+ - image:
13
+ label: Image
14
+ type: asset
15
+ multiple: false
16
+ maxSizeMB: 15
17
+ allowedTypes: ["image/*"]
18
+ maxPreviewWidth: 300
19
+ crops:
20
+ list_thumb:
21
+ label: "List View"
22
+ aspectRatio: 1
23
+ shape: "circle"
24
+ public: true
25
+
26
+ - title:
27
+ label: Title
28
+ required: false
29
+ - firstName:
30
+ label: First Name
31
+ - lastName:
32
+ label: Last Name
33
+ - position:
34
+
35
+ - fieldSet: access
@@ -0,0 +1,79 @@
1
+ id: product
2
+ label: Product
3
+ inTree: false
4
+ inVault: true
5
+ hasCanvas: false
6
+
7
+ layout:
8
+ columns: "3fr 1fr"
9
+ areas:
10
+ - ["main", "sidebar"]
11
+
12
+ regions:
13
+ main:
14
+ label: Product Content
15
+ sidebar:
16
+ label: Sidebar
17
+
18
+ allowedElements:
19
+ - text-block
20
+ - image_card
21
+
22
+ tabs:
23
+ settings:
24
+ label: "Product"
25
+ fields:
26
+ - fieldSet: page-base
27
+ - title:
28
+ label: Product Name
29
+ required: true
30
+ public: true
31
+ - slug:
32
+ linkedTo: "title"
33
+ - price:
34
+ label: Price (€)
35
+ type: number
36
+ public: true
37
+ - description:
38
+ label: Short Abstract
39
+ type: textarea
40
+ public: true
41
+ - fieldSet: meta
42
+ - fieldSet: access
43
+
44
+ media:
45
+ label: "Media"
46
+ fields:
47
+ # 🎯 ZONE 1: The Main Image (Strict crops for lists/catalogs)
48
+ - featuredImage:
49
+ label: Main Product Image
50
+ description: "This is the primary image used in product grids, search results, and catalogs."
51
+ type: asset
52
+ multiple: false
53
+ maxSizeMB: 15
54
+ allowedTypes: ["image/jpeg", "image/png", "image/webp"]
55
+ crops:
56
+ list_thumb:
57
+ label: "List View (4:3)"
58
+ aspectRatio: 1.333
59
+ catalog_card:
60
+ label: "Portrait Card (3:4)"
61
+ aspectRatio: 0.75
62
+ public: true
63
+
64
+ # 🎯 ZONE 2: The Gallery (Different crops for the carousel)
65
+ - gallery:
66
+ label: Product Gallery
67
+ description: "Drag up to 10 images here for the product detail carousel."
68
+ type: asset
69
+ multiple: true
70
+ maxItems: 10
71
+ allowedTypes: ["image/jpeg", "image/png", "image/webp"]
72
+ crops:
73
+ carousel:
74
+ label: "Carousel Hero (16:9)"
75
+ aspectRatio: 1.777
76
+ zoom:
77
+ label: "Detail Zoom (Square)"
78
+ aspectRatio: 1.0
79
+ public: true
@@ -0,0 +1,29 @@
1
+ id: navigation
2
+ label: "Site Navigation"
3
+
4
+ tabs:
5
+ settings:
6
+ label: "Tree"
7
+ fields:
8
+ - fieldSet: tree-base
9
+ - baseUrl:
10
+ label: Base URL
11
+ type: text
12
+ dbType: text
13
+ public: true
14
+ - defaultLanguage:
15
+ label: Channel Language / Locale
16
+ type: language-select
17
+ dbType: text
18
+ public: true
19
+ - maxDepth:
20
+ type: select
21
+ label: "Maximum Menu Depth"
22
+ default: "3"
23
+ options:
24
+ - "1"
25
+ - "2"
26
+ - "3"
27
+ - "4"
28
+
29
+ - fieldSet: access
@@ -0,0 +1,9 @@
1
+ id: social-links
2
+ label: "Social links"
3
+
4
+ tabs:
5
+ settings:
6
+ label: "Tree"
7
+ fields:
8
+ - fieldSet: tree-base
9
+ - fieldSet: access
@@ -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
+ allowedElements:
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
@@ -0,0 +1,17 @@
1
+ import StarterKit from "@tiptap/starter-kit";
2
+ import Link from "@tiptap/extension-link";
3
+ import type { RteProfile } from "../../utils/rteProfiles";
4
+
5
+ export const profile: RteProfile = {
6
+ extensions: [StarterKit, Link.configure({ openOnClick: false })],
7
+ toolbar: [
8
+ "heading-1",
9
+ "heading-2",
10
+ "bold",
11
+ "italic",
12
+ "bullet-list",
13
+ "ordered-list",
14
+ "blockquote",
15
+ "link",
16
+ ],
17
+ };
@@ -0,0 +1,33 @@
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
+
8
+ // Custom document node forcing default top-level block to be a heading (H2)
9
+ const CustomDocument = Document.extend({
10
+ content: "heading block*",
11
+ });
12
+
13
+ export const profile: RteProfile = {
14
+ extensions: [
15
+ CustomDocument,
16
+ StarterKit.configure({
17
+ document: false, // Replaces TipTap's default Document with CustomDocument
18
+ heading: { levels: [1, 2, 3, 4] },
19
+ }),
20
+ Subscript.configure(),
21
+ Superscript.configure(),
22
+ ],
23
+ toolbar: [
24
+ "heading-1",
25
+ "heading-2",
26
+ "heading-3",
27
+ "heading-4",
28
+ "bold",
29
+ "italic",
30
+ "superscript",
31
+ "subscript",
32
+ ],
33
+ };
@@ -0,0 +1,13 @@
1
+ import StarterKit from "@tiptap/starter-kit";
2
+ import Link from "@tiptap/extension-link";
3
+ import type { RteProfile } from "../../utils/rteProfiles";
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
+ ],
13
+ };
@@ -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
+ };
package/dist/index.js CHANGED
@@ -7910,7 +7910,7 @@ bi.get("/", async (e) => {
7910
7910
  var xi = new e(), Si = null, Ci = (e) => {
7911
7911
  try {
7912
7912
  if (!Si) {
7913
- let t = e.env?.BUNDLED_DEFINITIONS, n = li(t), r = n.userTemplate || {
7913
+ let t = li(e.env?.BUNDLED_DEFINITIONS || Nr), n = t.userTemplate || {
7914
7914
  id: "userTemplate",
7915
7915
  label: "User Account",
7916
7916
  fields: {
@@ -7947,15 +7947,15 @@ var xi = new e(), Si = null, Ci = (e) => {
7947
7947
  }
7948
7948
  };
7949
7949
  Si = {
7950
- channelTemplate: n.channelTemplate || null,
7951
- treeTemplate: n.treeTemplate || null,
7952
- userTemplate: r,
7953
- channelSchemas: n.channels || n.channelSchemas || {},
7954
- treeSchemas: n.trees || n.treeSchemas || {},
7955
- nodes: n.nodes || n.nodeSchemas || {},
7956
- blocks: n.blocks || n.elements || {},
7957
- nodeLayouts: n.nodeLayouts || {},
7958
- blockLayouts: n.blockLayouts || {}
7950
+ channelTemplate: t.channelTemplate || null,
7951
+ treeTemplate: t.treeTemplate || null,
7952
+ userTemplate: n,
7953
+ channelSchemas: t.channels || t.channelSchemas || {},
7954
+ treeSchemas: t.trees || t.treeSchemas || {},
7955
+ nodes: t.nodes || t.nodeSchemas || {},
7956
+ blocks: t.blocks || t.elements || {},
7957
+ nodeLayouts: t.nodeLayouts || {},
7958
+ blockLayouts: t.blockLayouts || {}
7959
7959
  };
7960
7960
  }
7961
7961
  return e.json(Si, 200, { "Cache-Control": "public, max-age=300, stale-while-revalidate=86400" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightsideoy/kama",
3
- "version": "0.1.0-alpha.39",
3
+ "version": "0.1.0-alpha.41",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -16,6 +16,8 @@
16
16
  },
17
17
  "files": [
18
18
  "dist",
19
+ "defaults",
20
+ "definitions",
19
21
  "bin",
20
22
  "scripts",
21
23
  "schema.sql"