@nextblock-cms/cortex 0.20.3 → 0.21.1

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 (100) hide show
  1. package/README.md +46 -0
  2. package/client.cjs +1 -0
  3. package/client.es.js +3 -7
  4. package/index.cjs +1 -0
  5. package/index.es.js +24 -277
  6. package/lib/ai-block-generation.cjs +4 -0
  7. package/lib/ai-block-generation.es.js +143 -182
  8. package/lib/ai-client.cjs +1 -0
  9. package/lib/ai-client.d.ts +1 -1
  10. package/lib/ai-client.es.js +101 -135
  11. package/lib/ai-config.cjs +1 -0
  12. package/lib/ai-config.es.js +89 -108
  13. package/lib/ai-cortex-widget-builder.cjs +1 -0
  14. package/lib/ai-cortex-widget-builder.es.js +56 -70
  15. package/lib/ai-global-agent-content-ops-tools.cjs +1 -0
  16. package/lib/ai-global-agent-content-ops-tools.d.ts +1943 -68
  17. package/lib/ai-global-agent-content-ops-tools.es.js +185 -199
  18. package/lib/ai-global-agent-custom-block-tools.cjs +1 -0
  19. package/lib/ai-global-agent-custom-block-tools.d.ts +2160 -95
  20. package/lib/ai-global-agent-custom-block-tools.es.js +226 -223
  21. package/lib/ai-global-agent-db-tools.cjs +1 -0
  22. package/lib/ai-global-agent-db-tools.d.ts +2708 -98
  23. package/lib/ai-global-agent-db-tools.es.js +1013 -986
  24. package/lib/ai-global-agent-ecommerce.cjs +1 -0
  25. package/lib/ai-global-agent-ecommerce.es.js +3 -7
  26. package/lib/ai-global-agent-site-tools.cjs +2 -0
  27. package/lib/ai-global-agent-site-tools.d.ts +10695 -500
  28. package/lib/ai-global-agent-site-tools.es.js +750 -757
  29. package/lib/ai-global-agent-theming-tools.cjs +1 -0
  30. package/lib/ai-global-agent-theming-tools.d.ts +2905 -105
  31. package/lib/ai-global-agent-theming-tools.es.js +326 -396
  32. package/lib/ai-global-agent-tools.cjs +15 -0
  33. package/lib/ai-global-agent-tools.d.ts +4 -2230
  34. package/lib/ai-global-agent-tools.es.js +3899 -4328
  35. package/lib/ai-key-crypto.cjs +1 -0
  36. package/lib/ai-key-crypto.es.js +63 -82
  37. package/lib/ai-key-verification.cjs +1 -0
  38. package/lib/ai-key-verification.es.js +74 -63
  39. package/lib/ai-model-catalog.cjs +1 -0
  40. package/lib/ai-model-catalog.es.js +18 -22
  41. package/lib/ai-model-registry.cjs +2 -0
  42. package/lib/ai-model-registry.es.js +246 -309
  43. package/lib/ai-seo-metadata.cjs +3 -0
  44. package/lib/ai-seo-metadata.es.js +143 -185
  45. package/lib/ai-vision.cjs +3 -0
  46. package/lib/ai-vision.d.ts +6 -6
  47. package/lib/ai-vision.es.js +161 -215
  48. package/lib/block-content-schemas.cjs +1 -0
  49. package/lib/block-content-schemas.es.js +324 -254
  50. package/lib/cortex-widget-registry.cjs +1 -0
  51. package/lib/cortex-widget-registry.es.js +35 -43
  52. package/lib/cortex-widget-schema.cjs +4 -0
  53. package/lib/cortex-widget-schema.es.js +280 -309
  54. package/lib/editor-document-from-html.cjs +1 -0
  55. package/lib/editor-document-from-html.es.js +334 -278
  56. package/lib/fetch-host-guard.cjs +1 -0
  57. package/lib/fetch-host-guard.d.ts +2 -0
  58. package/lib/fetch-host-guard.es.js +30 -0
  59. package/lib/mcp-server.cjs +1 -0
  60. package/lib/mcp-server.es.js +155 -173
  61. package/lib/mcp-tokens.cjs +1 -0
  62. package/lib/mcp-tokens.es.js +95 -107
  63. package/lib/mcp-tool-registry.cjs +5 -0
  64. package/lib/mcp-tool-registry.es.js +533 -411
  65. package/lib/site-brief.cjs +2 -0
  66. package/lib/site-brief.es.js +102 -108
  67. package/lib/vision-image-download.cjs +1 -0
  68. package/lib/vision-image-download.d.ts +43 -0
  69. package/lib/vision-image-download.es.js +120 -0
  70. package/lib/zod-config.cjs +1 -0
  71. package/lib/zod-config.es.js +5 -6
  72. package/package.json +13 -12
  73. package/client.cjs.js +0 -1
  74. package/index.cjs.js +0 -1
  75. package/lib/ai-block-generation.cjs.js +0 -5
  76. package/lib/ai-client.cjs.js +0 -1
  77. package/lib/ai-config.cjs.js +0 -1
  78. package/lib/ai-cortex-widget-builder.cjs.js +0 -1
  79. package/lib/ai-global-agent-content-ops-tools.cjs.js +0 -1
  80. package/lib/ai-global-agent-custom-block-tools.cjs.js +0 -1
  81. package/lib/ai-global-agent-db-tools.cjs.js +0 -1
  82. package/lib/ai-global-agent-ecommerce.cjs.js +0 -1
  83. package/lib/ai-global-agent-site-tools.cjs.js +0 -3
  84. package/lib/ai-global-agent-theming-tools.cjs.js +0 -3
  85. package/lib/ai-global-agent-tools.cjs.js +0 -15
  86. package/lib/ai-key-crypto.cjs.js +0 -1
  87. package/lib/ai-key-verification.cjs.js +0 -1
  88. package/lib/ai-model-catalog.cjs.js +0 -1
  89. package/lib/ai-model-registry.cjs.js +0 -2
  90. package/lib/ai-seo-metadata.cjs.js +0 -4
  91. package/lib/ai-vision.cjs.js +0 -3
  92. package/lib/block-content-schemas.cjs.js +0 -1
  93. package/lib/cortex-widget-registry.cjs.js +0 -1
  94. package/lib/cortex-widget-schema.cjs.js +0 -5
  95. package/lib/editor-document-from-html.cjs.js +0 -1
  96. package/lib/mcp-server.cjs.js +0 -1
  97. package/lib/mcp-tokens.cjs.js +0 -1
  98. package/lib/mcp-tool-registry.cjs.js +0 -6
  99. package/lib/site-brief.cjs.js +0 -2
  100. package/lib/zod-config.cjs.js +0 -1
@@ -1,262 +1,332 @@
1
- import "./zod-config.es.js";
2
- import { z as t } from "zod";
3
- const d = [
4
- "text",
5
- "heading",
6
- "image",
7
- "button",
8
- "posts_grid",
9
- "video_embed",
10
- "section",
11
- "form",
12
- "testimonial",
13
- "product_grid",
14
- "featured_product",
15
- "cart",
16
- "checkout",
17
- "product_details"
18
- ], b = t.enum(d), m = t.object({
19
- direction: t.string().optional(),
20
- stops: t.array(t.object({ color: t.string(), position: t.number() })),
21
- type: t.enum(["linear", "radial"])
22
- }), g = t.object({
23
- gradient: m.optional(),
24
- image: t.object({
25
- alt_text: t.string().optional(),
26
- blur_data_url: t.string().optional(),
27
- external_url: t.string().optional(),
28
- height: t.number().optional(),
29
- media_id: t.string().optional(),
30
- object_key: t.string().optional(),
31
- overlay: t.object({
32
- gradient: m,
33
- type: t.literal("gradient")
34
- }).optional(),
35
- position: t.enum(["center", "top", "bottom", "left", "right"]),
36
- quality: t.number().nullable().optional(),
37
- size: t.enum(["cover", "contain"]),
38
- width: t.number().optional()
39
- }).optional(),
40
- min_height: t.string().optional(),
41
- solid_color: t.string().optional(),
42
- theme: t.enum(["primary", "secondary", "muted", "accent", "destructive"]).optional(),
43
- type: t.enum(["none", "theme", "solid", "gradient", "image"])
44
- }), f = t.string().regex(/^[a-z][a-z0-9-]*$/), p = t.object({
45
- block_type: t.union([b, f]),
46
- content: t.record(t.string(), t.any()),
47
- temp_id: t.string().optional()
48
- }), y = t.object({
49
- background: g,
50
- column_blocks: t.array(t.array(p))
51
- }), h = t.object({
52
- // Slider settings mirror the editor's "Enable Slider (Carousel layout)" panel:
53
- // `autoplay` rotates the slides every `timeframe` SECONDS (5 when omitted).
54
- autoplay: t.boolean().optional(),
55
- background: g,
56
- column_blocks: t.array(t.array(p)),
57
- column_gap: t.enum(["none", "sm", "md", "lg", "xl"]),
58
- container_type: t.enum(["full-width", "container", "container-sm", "container-lg", "container-xl"]),
59
- // The editor's "Hero Section (Prioritized image loading)" checkbox: the section's
60
- // background image (and the first slide's images) load with priority, and the
61
- // normalizer centres its content vertically.
62
- is_hero: t.boolean().optional(),
63
- padding: t.object({
64
- bottom: t.enum(["none", "sm", "md", "lg", "xl"]),
65
- top: t.enum(["none", "sm", "md", "lg", "xl"])
66
- }),
67
- responsive_columns: t.object({
68
- desktop: t.union([t.literal(1), t.literal(2), t.literal(3), t.literal(4)]),
69
- mobile: t.union([t.literal(1), t.literal(2)]),
70
- tablet: t.union([t.literal(1), t.literal(2), t.literal(3)])
71
- }),
72
- // With `slider: true` and a non-empty `slides` list the renderer shows a carousel
73
- // of those slides and ignores the top-level `column_blocks` and `background`.
74
- slider: t.boolean().optional(),
75
- slides: t.array(y).optional(),
76
- timeframe: t.number().optional(),
77
- vertical_alignment: t.enum(["start", "center", "end", "stretch"]).optional()
78
- }), _ = {
79
- button: t.object({
80
- position: t.enum(["left", "center", "right"]).optional(),
81
- size: t.enum(["default", "sm", "lg", "full"]).optional(),
82
- text: t.string(),
83
- url: t.string(),
84
- variant: t.enum(["default", "outline", "secondary", "ghost", "link"]).optional()
85
- }),
86
- cart: t.object({}),
87
- checkout: t.object({}),
88
- featured_product: t.object({
89
- imagePosition: t.enum(["left", "right"]).default("left"),
90
- productId: t.string().min(1),
91
- showBackground: t.boolean().default(!1)
92
- }),
93
- form: t.object({
94
- fields: t.array(
95
- t.object({
96
- // Mirrors FormFieldSchema in apps/nextblock/lib/blocks/blockRegistry.ts.
97
- field_type: t.enum(["text", "email", "tel", "url", "number", "textarea", "select", "radio", "checkbox"]),
98
- is_required: t.boolean(),
99
- label: t.string(),
100
- options: t.array(t.object({ label: t.string(), value: t.string() })).optional(),
101
- placeholder: t.string().optional(),
102
- temp_id: t.string()
103
- })
104
- ),
105
- // Opaque handle into form_endpoints, which holds the destination server-side.
106
- form_key: t.string().optional(),
107
- // Legacy. Migration 27 moved every address out of block content; kept optional so
108
- // an older payload still validates, and stripped before the block reaches a browser.
109
- recipient_email: t.string().email().optional(),
110
- submit_button_text: t.string(),
111
- success_message: t.string()
112
- }),
113
- heading: t.object({
114
- level: t.union([t.literal(1), t.literal(2), t.literal(3), t.literal(4), t.literal(5), t.literal(6)]),
115
- textAlign: t.enum(["left", "center", "right", "justify"]).optional(),
116
- // Mirrors TextColorSchema in apps/nextblock/lib/blocks/blockRegistry.ts —
117
- // a theme token, or a literal CSS colour from the block editor's picker.
118
- // libs/* cannot import from the app, so the union is restated here.
119
- textColor: t.union([
120
- t.enum(["foreground", "primary", "secondary", "accent", "muted", "destructive", "background"]),
121
- t.string().regex(
122
- /^(#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|rgba?\([^)]+\)|hsla?\([^)]+\))$/i,
123
- "Must be a hex, rgb(a) or hsl(a) colour"
124
- )
125
- ]).optional().describe("Prefer a theme token so the heading adapts to dark mode; use a CSS colour only when the brand requires an exact value"),
126
- text_content: t.string()
127
- }),
128
- image: t.object({
129
- alt_text: t.string().optional(),
130
- caption: t.string().optional(),
131
- external_url: t.string().nullable().optional(),
132
- height: t.number().nullable().optional(),
133
- media_id: t.string().nullable().optional(),
134
- object_key: t.string().nullable().optional(),
135
- width: t.number().nullable().optional()
136
- }),
137
- posts_grid: t.object({
138
- columns: t.number().min(1).max(6),
139
- postsPerPage: t.number().min(1).max(50),
140
- showPagination: t.boolean(),
141
- title: t.string().optional()
142
- }),
143
- product_details: t.object({}),
144
- product_grid: t.object({
145
- categoryId: t.string().optional(),
146
- categoryIds: t.array(t.string()).max(20).optional(),
147
- // 0 = unlimited (every match on one page).
148
- limit: t.number().min(0).max(48).default(6),
149
- productIds: t.array(t.string()).max(24).optional(),
150
- showPagination: t.boolean().default(!1),
151
- title: t.string().optional(),
152
- type: t.enum(["latest", "category", "manual"]).default("latest")
153
- }),
154
- section: h,
155
- testimonial: t.object({
156
- author_name: t.string().min(1),
157
- author_title: t.string().optional(),
158
- image_url: t.string().url().optional().or(t.literal("")),
159
- quote: t.string().min(1)
160
- }),
161
- text: t.object({
162
- html_content: t.string()
163
- }),
164
- video_embed: t.object({
165
- autoplay: t.boolean().optional(),
166
- controls: t.boolean().optional(),
167
- title: t.string().optional(),
168
- url: t.string()
169
- })
1
+ import { z as e } from "./zod-config.es.js";
2
+ //#region src/lib/block-content-schemas.ts
3
+ var t = [
4
+ "text",
5
+ "heading",
6
+ "image",
7
+ "button",
8
+ "posts_grid",
9
+ "video_embed",
10
+ "section",
11
+ "form",
12
+ "testimonial",
13
+ "product_grid",
14
+ "featured_product",
15
+ "cart",
16
+ "checkout",
17
+ "product_details"
18
+ ], n = e.enum(t), r = e.object({
19
+ direction: e.string().optional(),
20
+ stops: e.array(e.object({
21
+ color: e.string(),
22
+ position: e.number()
23
+ })),
24
+ type: e.enum(["linear", "radial"])
25
+ }), i = e.object({
26
+ gradient: r.optional(),
27
+ image: e.object({
28
+ alt_text: e.string().optional(),
29
+ blur_data_url: e.string().optional(),
30
+ external_url: e.string().optional(),
31
+ height: e.number().optional(),
32
+ media_id: e.string().optional(),
33
+ object_key: e.string().optional(),
34
+ overlay: e.object({
35
+ gradient: r,
36
+ type: e.literal("gradient")
37
+ }).optional(),
38
+ position: e.enum([
39
+ "center",
40
+ "top",
41
+ "bottom",
42
+ "left",
43
+ "right"
44
+ ]),
45
+ quality: e.number().nullable().optional(),
46
+ size: e.enum(["cover", "contain"]),
47
+ width: e.number().optional()
48
+ }).optional(),
49
+ min_height: e.string().optional(),
50
+ solid_color: e.string().optional(),
51
+ theme: e.enum([
52
+ "primary",
53
+ "secondary",
54
+ "muted",
55
+ "accent",
56
+ "destructive"
57
+ ]).optional(),
58
+ type: e.enum([
59
+ "none",
60
+ "theme",
61
+ "solid",
62
+ "gradient",
63
+ "image"
64
+ ])
65
+ }), a = e.string().regex(/^[a-z][a-z0-9-]*$/), o = e.object({
66
+ block_type: e.union([n, a]),
67
+ content: e.record(e.string(), e.any()),
68
+ temp_id: e.string().optional()
69
+ }), s = e.object({
70
+ background: i,
71
+ column_blocks: e.array(e.array(o))
72
+ }), c = e.object({
73
+ autoplay: e.boolean().optional(),
74
+ background: i,
75
+ column_blocks: e.array(e.array(o)),
76
+ column_gap: e.enum([
77
+ "none",
78
+ "sm",
79
+ "md",
80
+ "lg",
81
+ "xl"
82
+ ]),
83
+ container_type: e.enum([
84
+ "full-width",
85
+ "container",
86
+ "container-sm",
87
+ "container-lg",
88
+ "container-xl"
89
+ ]),
90
+ is_hero: e.boolean().optional(),
91
+ padding: e.object({
92
+ bottom: e.enum([
93
+ "none",
94
+ "sm",
95
+ "md",
96
+ "lg",
97
+ "xl"
98
+ ]),
99
+ top: e.enum([
100
+ "none",
101
+ "sm",
102
+ "md",
103
+ "lg",
104
+ "xl"
105
+ ])
106
+ }),
107
+ responsive_columns: e.object({
108
+ desktop: e.union([
109
+ e.literal(1),
110
+ e.literal(2),
111
+ e.literal(3),
112
+ e.literal(4)
113
+ ]),
114
+ mobile: e.union([e.literal(1), e.literal(2)]),
115
+ tablet: e.union([
116
+ e.literal(1),
117
+ e.literal(2),
118
+ e.literal(3)
119
+ ])
120
+ }),
121
+ slider: e.boolean().optional(),
122
+ slides: e.array(s).optional(),
123
+ timeframe: e.number().optional(),
124
+ vertical_alignment: e.enum([
125
+ "start",
126
+ "center",
127
+ "end",
128
+ "stretch"
129
+ ]).optional()
130
+ }), l = {
131
+ button: e.object({
132
+ position: e.enum([
133
+ "left",
134
+ "center",
135
+ "right"
136
+ ]).optional(),
137
+ size: e.enum([
138
+ "default",
139
+ "sm",
140
+ "lg",
141
+ "full"
142
+ ]).optional(),
143
+ text: e.string(),
144
+ url: e.string(),
145
+ variant: e.enum([
146
+ "default",
147
+ "outline",
148
+ "secondary",
149
+ "ghost",
150
+ "link"
151
+ ]).optional()
152
+ }),
153
+ cart: e.object({}),
154
+ checkout: e.object({}),
155
+ featured_product: e.object({
156
+ imagePosition: e.enum(["left", "right"]).default("left"),
157
+ productId: e.string().min(1),
158
+ showBackground: e.boolean().default(!1)
159
+ }),
160
+ form: e.object({
161
+ fields: e.array(e.object({
162
+ field_type: e.enum([
163
+ "text",
164
+ "email",
165
+ "tel",
166
+ "url",
167
+ "number",
168
+ "textarea",
169
+ "select",
170
+ "radio",
171
+ "checkbox"
172
+ ]),
173
+ is_required: e.boolean(),
174
+ label: e.string(),
175
+ options: e.array(e.object({
176
+ label: e.string(),
177
+ value: e.string()
178
+ })).optional(),
179
+ placeholder: e.string().optional(),
180
+ temp_id: e.string()
181
+ })),
182
+ form_key: e.string().optional(),
183
+ recipient_email: e.string().email().optional(),
184
+ submit_button_text: e.string(),
185
+ success_message: e.string()
186
+ }),
187
+ heading: e.object({
188
+ level: e.union([
189
+ e.literal(1),
190
+ e.literal(2),
191
+ e.literal(3),
192
+ e.literal(4),
193
+ e.literal(5),
194
+ e.literal(6)
195
+ ]),
196
+ textAlign: e.enum([
197
+ "left",
198
+ "center",
199
+ "right",
200
+ "justify"
201
+ ]).optional(),
202
+ textColor: e.union([e.enum([
203
+ "foreground",
204
+ "primary",
205
+ "secondary",
206
+ "accent",
207
+ "muted",
208
+ "destructive",
209
+ "background"
210
+ ]), e.string().regex(/^(#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|rgba?\([^)]+\)|hsla?\([^)]+\))$/i, "Must be a hex, rgb(a) or hsl(a) colour")]).optional().describe("Prefer a theme token so the heading adapts to dark mode; use a CSS colour only when the brand requires an exact value"),
211
+ text_content: e.string()
212
+ }),
213
+ image: e.object({
214
+ alt_text: e.string().optional(),
215
+ caption: e.string().optional(),
216
+ external_url: e.string().nullable().optional(),
217
+ height: e.number().nullable().optional(),
218
+ media_id: e.string().nullable().optional(),
219
+ object_key: e.string().nullable().optional(),
220
+ width: e.number().nullable().optional()
221
+ }),
222
+ posts_grid: e.object({
223
+ columns: e.number().min(1).max(6),
224
+ postsPerPage: e.number().min(1).max(50),
225
+ showPagination: e.boolean(),
226
+ title: e.string().optional()
227
+ }),
228
+ product_details: e.object({}),
229
+ product_grid: e.object({
230
+ categoryId: e.string().optional(),
231
+ categoryIds: e.array(e.string()).max(20).optional(),
232
+ limit: e.number().min(0).max(48).default(6),
233
+ productIds: e.array(e.string()).max(24).optional(),
234
+ showPagination: e.boolean().default(!1),
235
+ title: e.string().optional(),
236
+ type: e.enum([
237
+ "latest",
238
+ "category",
239
+ "manual"
240
+ ]).default("latest")
241
+ }),
242
+ section: c,
243
+ testimonial: e.object({
244
+ author_name: e.string().min(1),
245
+ author_title: e.string().optional(),
246
+ image_url: e.string().url().optional().or(e.literal("")),
247
+ quote: e.string().min(1)
248
+ }),
249
+ text: e.object({ html_content: e.string() }),
250
+ video_embed: e.object({
251
+ autoplay: e.boolean().optional(),
252
+ controls: e.boolean().optional(),
253
+ title: e.string().optional(),
254
+ url: e.string()
255
+ })
170
256
  };
171
- function v(o) {
172
- return d.includes(o);
257
+ function u(e) {
258
+ return t.includes(e);
173
259
  }
174
- function k(o) {
175
- return typeof o?.validateBlockContent == "function" ? o.validateBlockContent : null;
260
+ function d(e) {
261
+ return typeof e?.validateBlockContent == "function" ? e.validateBlockContent : null;
176
262
  }
177
- function B(o, n, r) {
178
- const l = k(r);
179
- if (l)
180
- return l(o, n);
181
- const i = _[o].safeParse(n);
182
- return i.success ? { errors: [], isValid: !0, warnings: [] } : {
183
- errors: i.error.issues.map((s) => {
184
- const e = s.path.join(".");
185
- return e ? `${e}: ${s.message}` : s.message;
186
- }),
187
- isValid: !1,
188
- warnings: []
189
- };
263
+ function f(e, t, n) {
264
+ let r = d(n);
265
+ if (r) return r(e, t);
266
+ let i = l[e].safeParse(t);
267
+ return i.success ? {
268
+ errors: [],
269
+ isValid: !0,
270
+ warnings: []
271
+ } : {
272
+ errors: i.error.issues.map((e) => {
273
+ let t = e.path.join(".");
274
+ return t ? `${t}: ${e.message}` : e.message;
275
+ }),
276
+ isValid: !1,
277
+ warnings: []
278
+ };
190
279
  }
191
- function j(o) {
192
- return Array.isArray(o.fields) ? o.fields.filter(
193
- (n) => !!n && typeof n == "object" && typeof n.key == "string" && typeof n.type == "string"
194
- ) : [];
280
+ function p(e) {
281
+ return Array.isArray(e.fields) ? e.fields.filter((e) => !!e && typeof e == "object" && typeof e.key == "string" && typeof e.type == "string") : [];
195
282
  }
196
- function x(o) {
197
- return o == null || typeof o == "string" && o.trim() === "" || Array.isArray(o) && o.length === 0;
283
+ function m(e) {
284
+ return e == null || typeof e == "string" && e.trim() === "" || Array.isArray(e) && e.length === 0;
198
285
  }
199
- function S(o, n) {
200
- if (!n || typeof n != "object" || Array.isArray(n))
201
- return {
202
- errors: ["content must be a JSON object of { field_key: value } pairs."],
203
- isValid: !1,
204
- warnings: []
205
- };
206
- const r = j(o), l = new Set(r.map((e) => e.key)), i = [], s = [];
207
- for (const e of Object.keys(n))
208
- l.has(e) || i.push(
209
- `Unknown field "${e}" for custom block "${o.slug}". Known fields: ${[...l].join(", ") || "(none)"}.`
210
- );
211
- for (const e of r) {
212
- const a = n[e.key];
213
- if (x(a)) {
214
- e.required && i.push(`Field "${e.key}" is required.`);
215
- continue;
216
- }
217
- if (e.type === "text" || e.type === "rich-text") {
218
- if (typeof a != "string") {
219
- i.push(`Field "${e.key}" must be a string${e.type === "rich-text" ? " of HTML" : ""}.`);
220
- continue;
221
- }
222
- typeof e.max_length == "number" && a.length > e.max_length && i.push(`Field "${e.key}" exceeds its ${e.max_length}-character limit.`), typeof e.min_length == "number" && a.length < e.min_length && i.push(`Field "${e.key}" is shorter than its ${e.min_length}-character minimum.`);
223
- continue;
224
- }
225
- if (e.type === "image_r2") {
226
- const c = a;
227
- (typeof a != "object" || Array.isArray(a) || typeof c.object_key != "string" || typeof c.url != "string") && i.push(
228
- `Field "${e.key}" must be an uploaded image object with object_key and url (upload it with upload_media first) or null.`
229
- );
230
- continue;
231
- }
232
- if (e.type === "db_relation") {
233
- const c = (u) => typeof u == "string" || typeof u == "number";
234
- e.multiple ? (!Array.isArray(a) || !a.every(c)) && i.push(`Field "${e.key}" must be an array of related record ids.`) : c(a) || i.push(`Field "${e.key}" must be a single related record id.`);
235
- continue;
236
- }
237
- s.push(`Field "${e.key}" has an unrecognised type "${String(e.type)}"; it was not validated.`);
238
- }
239
- return { errors: i, isValid: i.length === 0, warnings: s };
286
+ function h(e, t) {
287
+ if (!t || typeof t != "object" || Array.isArray(t)) return {
288
+ errors: ["content must be a JSON object of { field_key: value } pairs."],
289
+ isValid: !1,
290
+ warnings: []
291
+ };
292
+ let n = p(e), r = new Set(n.map((e) => e.key)), i = [], a = [];
293
+ for (let n of Object.keys(t)) r.has(n) || i.push(`Unknown field "${n}" for custom block "${e.slug}". Known fields: ${[...r].join(", ") || "(none)"}.`);
294
+ for (let e of n) {
295
+ let n = t[e.key];
296
+ if (m(n)) {
297
+ e.required && i.push(`Field "${e.key}" is required.`);
298
+ continue;
299
+ }
300
+ if (e.type === "text" || e.type === "rich-text") {
301
+ if (typeof n != "string") {
302
+ i.push(`Field "${e.key}" must be a string${e.type === "rich-text" ? " of HTML" : ""}.`);
303
+ continue;
304
+ }
305
+ typeof e.max_length == "number" && n.length > e.max_length && i.push(`Field "${e.key}" exceeds its ${e.max_length}-character limit.`), typeof e.min_length == "number" && n.length < e.min_length && i.push(`Field "${e.key}" is shorter than its ${e.min_length}-character minimum.`);
306
+ continue;
307
+ }
308
+ if (e.type === "image_r2") {
309
+ let t = n;
310
+ (typeof n != "object" || Array.isArray(n) || typeof t.object_key != "string" || typeof t.url != "string") && i.push(`Field "${e.key}" must be an uploaded image object with object_key and url (upload it with upload_media first) or null.`);
311
+ continue;
312
+ }
313
+ if (e.type === "db_relation") {
314
+ let t = (e) => typeof e == "string" || typeof e == "number";
315
+ e.multiple ? (!Array.isArray(n) || !n.every(t)) && i.push(`Field "${e.key}" must be an array of related record ids.`) : t(n) || i.push(`Field "${e.key}" must be a single related record id.`);
316
+ continue;
317
+ }
318
+ a.push(`Field "${e.key}" has an unrecognised type "${String(e.type)}"; it was not validated.`);
319
+ }
320
+ return {
321
+ errors: i,
322
+ isValid: i.length === 0,
323
+ warnings: a
324
+ };
240
325
  }
241
- async function A(o) {
242
- const { data: n, error: r } = await o.from("custom_block_definitions").select("slug, name, fields");
243
- if (r)
244
- throw new Error(
245
- `Could not read the custom block definitions: ${typeof r == "object" && r && "message" in r ? String(r.message) : String(r)}`
246
- );
247
- return (Array.isArray(n) ? n : []).filter(
248
- (l) => !!l && typeof l.slug == "string"
249
- );
326
+ async function g(e) {
327
+ let { data: t, error: n } = await e.from("custom_block_definitions").select("slug, name, fields");
328
+ if (n) throw Error(`Could not read the custom block definitions: ${typeof n == "object" && n && "message" in n ? String(n.message) : String(n)}`);
329
+ return (Array.isArray(t) ? t : []).filter((e) => !!e && typeof e.slug == "string");
250
330
  }
251
- export {
252
- d as availableCortexAiBlockTypes,
253
- b as cortexAiBlockTypeSchema,
254
- f as customBlockSlugPatternSchema,
255
- _ as fallbackBlockSchemas,
256
- v as isValidBlockType,
257
- A as loadCustomBlockDefinitions,
258
- j as readCustomBlockFields,
259
- h as sectionBlockFallbackSchema,
260
- B as validateCortexBlockContent,
261
- S as validateCustomBlockInstanceContent
262
- };
331
+ //#endregion
332
+ export { t as availableCortexAiBlockTypes, n as cortexAiBlockTypeSchema, a as customBlockSlugPatternSchema, l as fallbackBlockSchemas, u as isValidBlockType, g as loadCustomBlockDefinitions, p as readCustomBlockFields, c as sectionBlockFallbackSchema, f as validateCortexBlockContent, h as validateCustomBlockInstanceContent };
@@ -0,0 +1 @@
1
+ let e=require("@nextblock-cms/utils/custom-blocks");var t=`id, slug, name, description, fields, layout_schema, is_original`,n=class extends Error{code;status;constructor(e,t){super(e),this.name=`CortexWidgetRegistryInsertError`,this.code=t?.code,this.status=t?.status??500}};function r(e){return JSON.parse(JSON.stringify(e))}function i(e){return e===`23505`?409:e===`42501`?403:500}function a(t){let n=e.customBlockDefinitionCreateSchema.parse({...t,is_original:!0});return{description:n.description,fields:r(n.fields),is_original:!0,layout_schema:r(n.layout_schema),name:n.name,slug:n.slug}}async function o(r,o){let s=a(o),{data:c,error:l}=await r.from(`custom_block_definitions`).insert(s).select(t).single();if(l||!c)throw new n(l?.message??`Failed to insert Cortex custom block definition.`,{code:l?.code,status:i(l?.code)});return e.customBlockDefinitionRowSchema.parse(c)}exports.CORTEX_WIDGET_DEFINITION_SELECT=t,exports.CortexWidgetRegistryInsertError=n,exports.buildCortexWidgetDefinitionInsertPayload=a,exports.insertCortexWidgetDefinition=o;