@nextblock-cms/cortex 0.13.3 → 0.13.6

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.
@@ -1,9 +1,10 @@
1
- import { tool as T } from "ai";
2
- import { createCortexDatabaseAgentTools as Vt } from "./ai-global-agent-db-tools.es.js";
3
- import { createCortexCustomBlockTools as Ht } from "./ai-global-agent-custom-block-tools.es.js";
1
+ import { tool as S } from "ai";
2
+ import { createCortexDatabaseAgentTools as an } from "./ai-global-agent-db-tools.es.js";
3
+ import { createCortexCustomBlockTools as sn } from "./ai-global-agent-custom-block-tools.es.js";
4
+ import { editorDocumentFromHtml as pt } from "./editor-document-from-html.es.js";
4
5
  import "./zod-config.es.js";
5
6
  import { z as i } from "zod";
6
- const M = [
7
+ const K = [
7
8
  "text",
8
9
  "heading",
9
10
  "image",
@@ -18,7 +19,7 @@ const M = [
18
19
  "cart",
19
20
  "checkout",
20
21
  "product_details"
21
- ], Wt = 1e4, Jt = {
22
+ ], ln = 1e4, cn = {
22
23
  arabic: "ar",
23
24
  chinese: "zh",
24
25
  dutch: "nl",
@@ -33,40 +34,40 @@ const M = [
33
34
  portuguese: "pt",
34
35
  russian: "ru",
35
36
  spanish: "es"
36
- }, ot = i.string().trim().min(1).max(2048).refine(
37
+ }, mt = i.string().trim().min(1).max(2048).refine(
37
38
  (e) => e.startsWith("/") || e.startsWith("#") || e.startsWith("http://") || e.startsWith("https://") || e.startsWith("mailto:") || e.startsWith("tel:"),
38
39
  "URL must be a relative path, hash link, http(s) URL, mailto URL, or tel URL."
39
- ), Ke = i.strictObject({
40
+ ), Xe = i.strictObject({
40
41
  label: i.string().trim().min(1).max(120),
41
42
  target: i.enum(["_self", "_blank"]).optional(),
42
- url: ot
43
- }), it = Ke.extend({
44
- children: i.array(Ke).max(20).optional()
45
- }), Yt = i.strictObject({
43
+ url: mt
44
+ }), gt = Xe.extend({
45
+ children: i.array(Xe).max(20).optional()
46
+ }), un = i.strictObject({
46
47
  label: i.string().trim().min(1).max(120).optional(),
47
- url: ot.optional()
48
+ url: mt.optional()
48
49
  }).refine((e) => !!(e.label || e.url), {
49
50
  message: "Navigation item match requires label or url."
50
- }), se = i.strictObject({
51
- items: i.array(it).min(1).max(30),
51
+ }), de = i.strictObject({
52
+ items: i.array(gt).min(1).max(30),
52
53
  languageCode: i.string().trim().min(2).max(80).default("en").describe('Locale code or language name, for example "en", "fr", "English", or "French".'),
53
- match: Yt.optional().describe('For mode "update", identifies the existing navigation item to update.'),
54
+ match: un.optional().describe('For mode "update", identifies the existing navigation item to update.'),
54
55
  mode: i.enum(["append", "replace", "update"]).default("append")
55
- }), le = i.strictObject({
56
+ }), pe = i.strictObject({
56
57
  copyright: i.record(i.string().trim().min(2).max(12), i.string().trim().min(1).max(500)).optional(),
57
58
  languageCode: i.string().trim().min(2).max(80).default("en").describe('Locale code or language name, for example "en", "fr", "English", or "French".'),
58
- links: i.array(it).min(1).max(30).optional()
59
- }), Pe = i.strictObject({
59
+ links: i.array(gt).min(1).max(30).optional()
60
+ }), je = i.strictObject({
60
61
  limit: i.number().int().min(1).max(8).default(4),
61
62
  query: i.string().trim().min(2).max(300)
62
- }), at = i.object({
63
+ }), ft = i.object({
63
64
  currency: i.string().trim().min(3).max(3).optional().describe(
64
65
  "Optional currency code for currency-specific monetary reports (e.g., USD, CAD). Do not set this for plain order-status counts unless the user asks for a currency."
65
66
  ),
66
67
  query: i.string().describe("The analytical question about orders, products, or revenue."),
67
68
  reportType: i.enum(["revenue", "orders", "products", "general"]).optional().default("general").describe("The focus area of the statistical report."),
68
69
  timeRange: i.enum(["today", "this_month", "last_7_days", "last_30_days", "last_month", "last_90_days", "all_time"]).optional().default("all_time").describe("The time period for the report. Use all_time for current order-status counts unless the user names a specific period.")
69
- }), st = i.strictObject({
70
+ }), ht = i.strictObject({
70
71
  contentType: i.enum(["page", "post", "product"]),
71
72
  currentEditor: i.strictObject({
72
73
  blockId: i.union([i.number().int().positive(), i.string().trim().min(1).max(120)]).nullable().optional(),
@@ -78,11 +79,13 @@ const M = [
78
79
  slug: i.string().trim().min(1).max(300).nullable().optional(),
79
80
  title: i.string().trim().min(1).max(300).nullable().optional(),
80
81
  translationGroupId: i.string().trim().min(1).max(120).nullable().optional()
81
- }), lt = i.strictObject({
82
+ }), yt = i.strictObject({
82
83
  includeBlockContent: i.boolean().default(!1),
83
84
  includeBlocks: i.boolean().default(!0)
84
- }), ce = i.strictObject({
85
+ }), me = i.strictObject({
85
86
  fields: i.strictObject({
87
+ // Accepts an HTML string as well as an editor document — see
88
+ // validateProductDescriptionJson.
86
89
  description_json: i.unknown().optional(),
87
90
  excerpt: i.string().max(2e3).nullable().optional(),
88
91
  feature_image_id: i.string().trim().min(1).max(2048).nullable().optional(),
@@ -96,32 +99,36 @@ const M = [
96
99
  subtitle: i.string().max(300).nullable().optional(),
97
100
  title: i.string().trim().min(1).max(300).optional()
98
101
  }).partial()
99
- }), ue = i.strictObject({
102
+ }), ge = i.strictObject({
100
103
  blockId: i.number().int().positive(),
101
- blockType: i.enum(M).optional(),
104
+ blockType: i.enum(K).optional(),
102
105
  content: i.record(i.string(), i.unknown())
103
- }), de = i.strictObject({
106
+ }), fe = i.strictObject({
104
107
  blockIndex: i.number().int().min(0),
105
- blockType: i.enum(M).optional(),
108
+ blockType: i.enum(K).optional(),
106
109
  columnIndex: i.number().int().min(0),
107
110
  content: i.record(i.string(), i.unknown()),
108
111
  parentBlockId: i.number().int().positive()
109
- }), Xt = i.enum(["page", "post", "product"]), W = i.strictObject({
110
- contentType: Xt.optional(),
112
+ }), dn = i.enum(["page", "post", "product"]), H = i.strictObject({
113
+ contentType: dn.optional(),
111
114
  entityId: i.union([i.number().int().positive(), i.string().trim().min(1).max(120)]).optional(),
112
115
  slug: i.string().trim().min(1).max(300).optional(),
113
116
  title: i.string().trim().min(1).max(300).optional()
114
- }), pe = i.strictObject({
115
- blockType: i.enum(M),
117
+ }), Q = i.strictObject({
118
+ blockType: i.enum(K),
116
119
  content: i.record(i.string(), i.unknown()),
117
120
  order: i.number().int().min(0).optional()
118
- }), me = W.extend({
121
+ }), he = H.extend({
122
+ images: i.array(i.string().trim().min(1).max(2048)).min(1).max(12).describe(
123
+ "External https image URLs (imported into the media library automatically) and/or existing media library ids. The first entry is the feature image (pages/posts) or the main product image (products)."
124
+ )
125
+ }), ye = H.extend({
119
126
  anchorBlockId: i.number().int().positive().optional(),
120
- anchorBlockType: i.enum(M).optional(),
121
- block: pe,
127
+ anchorBlockType: i.enum(K).optional(),
128
+ block: Q,
122
129
  position: i.enum(["before", "after", "start", "end"]).default("end")
123
- }), ge = i.strictObject({
124
- blocks: i.array(pe).max(20).optional(),
130
+ }), _e = i.strictObject({
131
+ blocks: i.array(Q).max(20).optional(),
125
132
  contactEmail: i.string().email().optional(),
126
133
  feature_image_id: i.string().trim().min(1).max(2048).nullable().optional(),
127
134
  languageCode: i.string().trim().min(2).max(80).optional(),
@@ -131,8 +138,8 @@ const M = [
131
138
  status: i.enum(["draft", "published", "archived"]).default("draft"),
132
139
  title: i.string().trim().min(1).max(300),
133
140
  translationGroupId: i.string().trim().min(1).max(120).optional()
134
- }), fe = i.strictObject({
135
- blocks: i.array(pe).max(20).optional(),
141
+ }), be = i.strictObject({
142
+ blocks: i.array(Q).max(20).optional(),
136
143
  excerpt: i.string().max(2e3).nullable().optional(),
137
144
  feature_image_id: i.string().trim().min(1).max(2048).nullable().optional(),
138
145
  label: i.string().max(120).nullable().optional(),
@@ -145,10 +152,24 @@ const M = [
145
152
  subtitle: i.string().max(300).nullable().optional(),
146
153
  title: i.string().trim().min(1).max(300),
147
154
  translationGroupId: i.string().trim().min(1).max(120).optional()
148
- }), he = i.strictObject({
155
+ }), ke = i.strictObject({
156
+ // Products render "Product Description Blocks" exactly like pages/posts render
157
+ // their blocks (blocks.product_id). This is the richest body and takes
158
+ // precedence over description_html on the public product page.
159
+ blocks: i.array(Q).max(20).optional().describe(
160
+ "Content blocks for the product description area, same block vocabulary as create_cms_page. Rendered on the public product page in place of the plain description."
161
+ ),
162
+ // Fallback body input. A plain string is something every model can produce
163
+ // under a strict tool schema, unlike the untyped description_json below.
164
+ description_html: i.string().max(6e4).optional().describe(
165
+ "The product body as an HTML fragment (headings, paragraphs, lists, bold/italic/links). Converted to the editor document automatically. Prefer this over description_json."
166
+ ),
149
167
  description_json: i.unknown().optional(),
150
168
  freemius_plan_id: i.string().optional(),
151
169
  freemius_product_id: i.string().optional(),
170
+ images: i.array(i.string().trim().min(1).max(2048)).max(12).optional().describe(
171
+ "Product images, in order: the first becomes the main product image and the rest the gallery. Each entry is either an external https image URL (imported into the media library automatically) or an existing media library id."
172
+ ),
152
173
  is_taxable: i.boolean().default(!0),
153
174
  languageCode: i.string().trim().min(2).max(80).optional(),
154
175
  meta_description: i.string().max(500).nullable().optional(),
@@ -169,51 +190,53 @@ const M = [
169
190
  trial_requires_payment_method: i.boolean().default(!1),
170
191
  translationGroupId: i.string().trim().min(1).max(120).optional(),
171
192
  upc: i.string().max(120).nullable().optional()
172
- }), _e = W.extend({
193
+ }), we = H.extend({
173
194
  currencyCode: i.string().trim().min(3).max(3).optional(),
174
195
  endsAt: i.string().max(80).nullable().optional(),
175
196
  field: i.string().trim().min(1).max(120),
176
197
  startsAt: i.string().max(80).nullable().optional(),
177
198
  value: i.unknown()
178
- }), ct = W, ye = W, ut = i.discriminatedUnion("tool", [
179
- i.strictObject({ input: ge, tool: i.literal("create_cms_page") }),
180
- i.strictObject({ input: fe, tool: i.literal("create_cms_post") }),
181
- i.strictObject({ input: he, tool: i.literal("create_cms_product") }),
182
- i.strictObject({ input: ye, tool: i.literal("delete_cms_item") }),
183
- i.strictObject({ input: _e, tool: i.literal("update_cms_item_field") }),
184
- i.strictObject({ input: ue, tool: i.literal("update_content_block") }),
185
- i.strictObject({ input: me, tool: i.literal("insert_content_block") }),
186
- i.strictObject({ input: ce, tool: i.literal("update_current_cms_fields") }),
187
- i.strictObject({ input: le, tool: i.literal("update_footer") }),
188
- i.strictObject({ input: se, tool: i.literal("update_navigation_bar") }),
189
- i.strictObject({ input: de, tool: i.literal("update_section_column_block") })
190
- ]), Qt = i.union([
191
- ge.extend({ tool: i.literal("create_cms_page") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
192
- fe.extend({ tool: i.literal("create_cms_post") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
193
- he.extend({ tool: i.literal("create_cms_product") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
194
- ye.extend({ tool: i.literal("delete_cms_item") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
195
- _e.extend({ tool: i.literal("update_cms_item_field") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
196
- ue.extend({ tool: i.literal("update_content_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
197
- me.extend({ tool: i.literal("insert_content_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
198
- ce.extend({ tool: i.literal("update_current_cms_fields") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
199
- le.extend({ tool: i.literal("update_footer") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
200
- se.extend({ tool: i.literal("update_navigation_bar") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
201
- de.extend({ tool: i.literal("update_section_column_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e }))
202
- ]), Zt = i.string().transform((e, t) => {
203
- const n = on(e);
199
+ }), _t = H, Ie = H, bt = i.discriminatedUnion("tool", [
200
+ i.strictObject({ input: _e, tool: i.literal("create_cms_page") }),
201
+ i.strictObject({ input: be, tool: i.literal("create_cms_post") }),
202
+ i.strictObject({ input: ke, tool: i.literal("create_cms_product") }),
203
+ i.strictObject({ input: Ie, tool: i.literal("delete_cms_item") }),
204
+ i.strictObject({ input: we, tool: i.literal("update_cms_item_field") }),
205
+ i.strictObject({ input: ge, tool: i.literal("update_content_block") }),
206
+ i.strictObject({ input: ye, tool: i.literal("insert_content_block") }),
207
+ i.strictObject({ input: me, tool: i.literal("update_current_cms_fields") }),
208
+ i.strictObject({ input: pe, tool: i.literal("update_footer") }),
209
+ i.strictObject({ input: de, tool: i.literal("update_navigation_bar") }),
210
+ i.strictObject({ input: fe, tool: i.literal("update_section_column_block") }),
211
+ i.strictObject({ input: he, tool: i.literal("set_content_images") })
212
+ ]), pn = i.union([
213
+ _e.extend({ tool: i.literal("create_cms_page") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
214
+ be.extend({ tool: i.literal("create_cms_post") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
215
+ ke.extend({ tool: i.literal("create_cms_product") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
216
+ Ie.extend({ tool: i.literal("delete_cms_item") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
217
+ we.extend({ tool: i.literal("update_cms_item_field") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
218
+ ge.extend({ tool: i.literal("update_content_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
219
+ ye.extend({ tool: i.literal("insert_content_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
220
+ me.extend({ tool: i.literal("update_current_cms_fields") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
221
+ pe.extend({ tool: i.literal("update_footer") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
222
+ de.extend({ tool: i.literal("update_navigation_bar") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
223
+ fe.extend({ tool: i.literal("update_section_column_block") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e })),
224
+ he.extend({ tool: i.literal("set_content_images") }).transform(({ tool: e, ...t }) => ({ input: t, tool: e }))
225
+ ]), mn = i.string().transform((e, t) => {
226
+ const n = _n(e);
204
227
  return n.success ? n.action : (t.addIssue({
205
228
  code: "custom",
206
229
  message: n.message
207
230
  }), i.NEVER);
208
- }), en = i.union([
209
- ut,
210
- Qt,
211
- Zt
212
- ]), dt = i.strictObject({
213
- actions: i.array(en).min(1).max(8),
231
+ }), gn = i.union([
232
+ bt,
233
+ pn,
234
+ mn
235
+ ]), kt = i.strictObject({
236
+ actions: i.array(gn).min(1).max(8),
214
237
  summary: i.string().trim().min(1).max(500).optional()
215
238
  });
216
- function tn(e) {
239
+ function fn(e) {
217
240
  const t = [];
218
241
  let n = "", r = 0, o = null, a = !1;
219
242
  for (const s of e) {
@@ -241,7 +264,7 @@ function tn(e) {
241
264
  }
242
265
  return n.trim() && t.push(n.trim()), t;
243
266
  }
244
- function Ve(e) {
267
+ function Qe(e) {
245
268
  let t = "";
246
269
  for (let n = 0; n < e.length; n++) {
247
270
  const r = e[n];
@@ -268,24 +291,24 @@ function Ve(e) {
268
291
  }
269
292
  return t.replace(/\bTrue\b/g, "true").replace(/\bFalse\b/g, "false").replace(/\bNone\b/g, "null");
270
293
  }
271
- function nn(e) {
294
+ function hn(e) {
272
295
  const t = e.trim();
273
- return t.startsWith("'") && t.endsWith("'") || t.startsWith('"') && t.endsWith('"') || t.startsWith("[") || t.startsWith("{") ? JSON.parse(Ve(t)) : /^-?\d+(?:\.\d+)?$/.test(t) ? Number(t) : t === "true" || t === "True" ? !0 : t === "false" || t === "False" ? !1 : t === "null" || t === "None" ? null : t;
296
+ return t.startsWith("'") && t.endsWith("'") || t.startsWith('"') && t.endsWith('"') || t.startsWith("[") || t.startsWith("{") ? JSON.parse(Qe(t)) : /^-?\d+(?:\.\d+)?$/.test(t) ? Number(t) : t === "true" || t === "True" ? !0 : t === "false" || t === "False" ? !1 : t === "null" || t === "None" ? null : t;
274
297
  }
275
- function rn(e) {
298
+ function yn(e) {
276
299
  const t = {};
277
- for (const n of tn(e)) {
300
+ for (const n of fn(e)) {
278
301
  const r = n.indexOf("=");
279
302
  if (r <= 0)
280
303
  throw new Error(`Expected key=value argument, received "${n}".`);
281
304
  const o = n.slice(0, r).trim();
282
305
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(o))
283
306
  throw new Error(`Invalid argument name "${o}".`);
284
- t[o] = nn(n.slice(r + 1));
307
+ t[o] = hn(n.slice(r + 1));
285
308
  }
286
309
  return t;
287
310
  }
288
- function on(e) {
311
+ function _n(e) {
289
312
  const n = e.trim().match(/^([a-z_]+)\(([\s\S]*)\)$/);
290
313
  if (!n)
291
314
  return {
@@ -295,14 +318,14 @@ function on(e) {
295
318
  const r = n[1];
296
319
  let o;
297
320
  try {
298
- o = rn(n[2]);
321
+ o = yn(n[2]);
299
322
  } catch (l) {
300
323
  return {
301
324
  message: l instanceof Error ? l.message : "Could not parse action-plan command arguments.",
302
325
  success: !1
303
326
  };
304
327
  }
305
- const a = { input: o, tool: r }, s = ut.safeParse(a);
328
+ const a = { input: o, tool: r }, s = bt.safeParse(a);
306
329
  return s.success ? {
307
330
  action: s.data,
308
331
  success: !0
@@ -311,21 +334,21 @@ function on(e) {
311
334
  success: !1
312
335
  };
313
336
  }
314
- function an(e) {
337
+ function bn(e) {
315
338
  return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/\s+/g, " ").trim();
316
339
  }
317
- function Q(e, t) {
340
+ function ne(e, t) {
318
341
  return t.some((n) => e.includes(n));
319
342
  }
320
- function Dr(e) {
321
- const t = an(e), n = Q(t, ["add ", "insert ", "put ", "create "]), r = Q(t, [
343
+ function so(e) {
344
+ const t = bn(e), n = ne(t, ["add ", "insert ", "put ", "create "]), r = ne(t, [
322
345
  "title",
323
346
  "heading",
324
347
  "description",
325
348
  "intro",
326
349
  "copy",
327
350
  "paragraph"
328
- ]), o = t.includes("form") && Q(t, ["above", "before"]), a = t.includes("contact page") || t.includes("contact pages") || t.includes("contact us") || t.includes("contactez-nous"), s = t.includes("english") && Q(t, ["french", "francais", "francaise"]);
351
+ ]), o = t.includes("form") && ne(t, ["above", "before"]), a = t.includes("contact page") || t.includes("contact pages") || t.includes("contact us") || t.includes("contactez-nous"), s = t.includes("english") && ne(t, ["french", "francais", "francaise"]);
329
352
  return !n || !r || !o || !a || !s ? null : {
330
353
  actions: [
331
354
  {
@@ -362,12 +385,12 @@ function Dr(e) {
362
385
  summary: "Add visible title and description copy above the forms on the English and French Contact pages."
363
386
  };
364
387
  }
365
- const sn = i.enum(M), He = i.object({
388
+ const kn = i.enum(K), Ze = i.object({
366
389
  direction: i.string().optional(),
367
390
  stops: i.array(i.object({ color: i.string(), position: i.number() })),
368
391
  type: i.enum(["linear", "radial"])
369
- }), ln = i.object({
370
- gradient: He.optional(),
392
+ }), wn = i.object({
393
+ gradient: Ze.optional(),
371
394
  image: i.object({
372
395
  alt_text: i.string().optional(),
373
396
  blur_data_url: i.string().optional(),
@@ -376,7 +399,7 @@ const sn = i.enum(M), He = i.object({
376
399
  media_id: i.string().optional(),
377
400
  object_key: i.string().optional(),
378
401
  overlay: i.object({
379
- gradient: He,
402
+ gradient: Ze,
380
403
  type: i.literal("gradient")
381
404
  }).optional(),
382
405
  position: i.enum(["center", "top", "bottom", "left", "right"]),
@@ -388,13 +411,13 @@ const sn = i.enum(M), He = i.object({
388
411
  solid_color: i.string().optional(),
389
412
  theme: i.enum(["primary", "secondary", "muted", "accent", "destructive"]).optional(),
390
413
  type: i.enum(["none", "theme", "solid", "gradient", "image"])
391
- }), cn = i.object({
392
- block_type: sn,
414
+ }), In = i.object({
415
+ block_type: kn,
393
416
  content: i.record(i.string(), i.any()),
394
417
  temp_id: i.string().optional()
395
- }), un = i.object({
396
- background: ln,
397
- column_blocks: i.array(i.array(cn)),
418
+ }), Tn = i.object({
419
+ background: wn,
420
+ column_blocks: i.array(i.array(In)),
398
421
  column_gap: i.enum(["none", "sm", "md", "lg", "xl"]),
399
422
  container_type: i.enum(["full-width", "container", "container-sm", "container-lg", "container-xl"]),
400
423
  padding: i.object({
@@ -407,7 +430,7 @@ const sn = i.enum(M), He = i.object({
407
430
  tablet: i.union([i.literal(1), i.literal(2), i.literal(3)])
408
431
  }),
409
432
  vertical_alignment: i.enum(["start", "center", "end", "stretch"]).optional()
410
- }), dn = {
433
+ }), xn = {
411
434
  button: i.object({
412
435
  position: i.enum(["left", "center", "right"]).optional(),
413
436
  size: i.enum(["default", "sm", "lg", "full"]).optional(),
@@ -465,7 +488,7 @@ const sn = i.enum(M), He = i.object({
465
488
  title: i.string().optional(),
466
489
  type: i.enum(["latest", "category"]).default("latest")
467
490
  }),
468
- section: un,
491
+ section: Tn,
469
492
  testimonial: i.object({
470
493
  author_name: i.string().min(1),
471
494
  author_title: i.string().optional(),
@@ -482,17 +505,17 @@ const sn = i.enum(M), He = i.object({
482
505
  url: i.string()
483
506
  })
484
507
  };
485
- function pn(e) {
486
- return M.includes(e);
508
+ function Cn(e) {
509
+ return K.includes(e);
487
510
  }
488
- function mn(e) {
511
+ function Sn(e) {
489
512
  return typeof e?.validateBlockContent == "function" ? e.validateBlockContent : null;
490
513
  }
491
- function gn(e, t, n) {
492
- const r = mn(n);
514
+ function vn(e, t, n) {
515
+ const r = Sn(n);
493
516
  if (r)
494
517
  return r(e, t);
495
- const o = dn[e].safeParse(t);
518
+ const o = xn[e].safeParse(t);
496
519
  return o.success ? { errors: [], isValid: !0, warnings: [] } : {
497
520
  errors: o.error.issues.map((a) => {
498
521
  const s = a.path.join(".");
@@ -502,13 +525,13 @@ function gn(e, t, n) {
502
525
  warnings: []
503
526
  };
504
527
  }
505
- function fn() {
528
+ function et() {
506
529
  return i.object({
507
530
  content: i.array(i.any()).optional(),
508
531
  type: i.literal("doc")
509
532
  });
510
533
  }
511
- function Ne() {
534
+ function Le() {
512
535
  try {
513
536
  const { revalidatePath: e } = require("next/cache");
514
537
  return e;
@@ -516,12 +539,12 @@ function Ne() {
516
539
  return null;
517
540
  }
518
541
  }
519
- function I(e) {
542
+ function C(e) {
520
543
  if (!e?.supabase)
521
544
  throw new Error("A Supabase service client is required to execute Cortex AI global tools.");
522
545
  return e.supabase;
523
546
  }
524
- function hn(e, t, n) {
547
+ function En(e, t, n) {
525
548
  let r;
526
549
  const o = new Promise((a) => {
527
550
  r = setTimeout(() => a(n()), t);
@@ -533,38 +556,38 @@ function hn(e, t, n) {
533
556
  o
534
557
  ]);
535
558
  }
536
- function D(e) {
537
- const t = st.safeParse(e?.pageContext);
559
+ function V(e) {
560
+ const t = ht.safeParse(e?.pageContext);
538
561
  if (!t.success)
539
562
  throw new Error(
540
563
  "No current CMS page context is available. Open a page, post, or product edit screen before using this editing tool."
541
564
  );
542
565
  return t.data;
543
566
  }
544
- function Ue(e) {
567
+ function Be(e) {
545
568
  const t = typeof e.entityId == "number" ? e.entityId : Number.parseInt(e.entityId, 10);
546
569
  if (!Number.isInteger(t) || t <= 0)
547
570
  throw new Error(`Current ${e.contentType} id must be a positive integer.`);
548
571
  return t;
549
572
  }
550
- function _n(e) {
573
+ function wt(e) {
551
574
  const t = String(e.entityId || "").trim();
552
575
  if (!t)
553
576
  throw new Error(`Current ${e.contentType} id is missing.`);
554
577
  return t;
555
578
  }
556
- function be(e) {
557
- return e.contentType === "product" ? _n(e) : Ue(e);
579
+ function Te(e) {
580
+ return e.contentType === "product" ? wt(e) : Be(e);
558
581
  }
559
- const yn = /^https?:\/\//i, bn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
560
- async function J(e, t, n) {
582
+ const $n = /^https?:\/\//i, An = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
583
+ async function Z(e, t, n) {
561
584
  if (typeof e != "string")
562
585
  return null;
563
586
  const r = e.trim();
564
587
  if (!r)
565
588
  return null;
566
- if (!yn.test(r)) {
567
- if (bn.test(r))
589
+ if (!$n.test(r)) {
590
+ if (An.test(r))
568
591
  return r;
569
592
  throw new Error(
570
593
  `"${r}" is not a usable image reference — provide an https:// image URL or a media library id.`
@@ -580,54 +603,106 @@ async function J(e, t, n) {
580
603
  throw new Error(`I could not import the image from that URL: ${a.error}`);
581
604
  return a.id;
582
605
  }
583
- function pt(e) {
606
+ async function It(e, t, n) {
607
+ const r = [];
608
+ for (let o = 0; o < e.length; o += 1) {
609
+ const a = await Z(
610
+ e[o],
611
+ t,
612
+ `${n} image ${o + 1}`
613
+ );
614
+ a && r.push(a);
615
+ }
616
+ return r;
617
+ }
618
+ async function Pn(e) {
619
+ const t = [...new Set(e.mediaIds)], { error: n } = await e.supabase.from("product_media").delete().eq("product_id", e.productId);
620
+ if (n)
621
+ throw new Error(
622
+ `Could not clear the product's existing images: ${_(n)}`
623
+ );
624
+ if (t.length > 0) {
625
+ const { error: r } = await e.supabase.from("product_media").insert(
626
+ t.map((o, a) => ({
627
+ media_id: o,
628
+ product_id: e.productId,
629
+ sort_order: a
630
+ }))
631
+ );
632
+ if (r)
633
+ throw new Error(`Could not save the product images: ${_(r)}`);
634
+ }
635
+ return t;
636
+ }
637
+ async function xe(e) {
638
+ if (!e.productId)
639
+ return !1;
640
+ const { data: t, error: n } = await e.supabase.from("product_drafts").select("id, blocks, meta").eq("product_id", e.productId).maybeSingle();
641
+ if (n || !t)
642
+ return !1;
643
+ const r = e.patch({
644
+ blocks: Array.isArray(t.blocks) ? z(t.blocks) : [],
645
+ meta: $(t.meta) ? z(t.meta) : {}
646
+ }), o = { updated_at: (/* @__PURE__ */ new Date()).toISOString() };
647
+ if (r.blocks && (o.blocks = r.blocks), r.meta && (o.meta = r.meta), Object.keys(o).length === 1)
648
+ return !1;
649
+ const { error: a } = await e.supabase.from("product_drafts").update(o).eq("id", t.id);
650
+ if (a)
651
+ throw new Error(
652
+ `The product was updated, but its open draft could not be kept in sync: ${_(
653
+ a
654
+ )}. Publishing that draft would undo this change — publish or discard it in the product editor first.`
655
+ );
656
+ return !0;
657
+ }
658
+ function Tt(e) {
584
659
  return typeof e == "string" ? e.trim().replace(/^\/+|\/+$/g, "") : "";
585
660
  }
586
- function kn(e, t) {
587
- const n = pt(t ?? e.slug);
661
+ function Nn(e, t) {
662
+ const n = Tt(t ?? e.slug);
588
663
  return n ? e.contentType === "page" ? n === "home" ? "/" : `/${n}` : e.contentType === "post" ? `/article/${n}` : `/product/${n}` : null;
589
664
  }
590
- function wn(e) {
665
+ function Un(e) {
591
666
  const t = String(e.entityId);
592
667
  return e.contentType === "page" ? `/cms/pages/${t}/edit` : e.contentType === "post" ? `/cms/posts/${t}/edit` : `/cms/products/${t}/edit`;
593
668
  }
594
- function N(e, t, n) {
595
- const r = e?.revalidatePath ?? Ne();
669
+ function U(e, t, n) {
670
+ const r = e?.revalidatePath ?? Le();
596
671
  if (!r)
597
672
  return;
598
- r(wn(t));
599
- const o = kn(t, n);
673
+ r(Un(t));
674
+ const o = Nn(t, n);
600
675
  o && r(o), t.contentType === "page" && o !== "/" && r("/"), t.contentType === "product" && r("/cms/products");
601
676
  }
602
- function mt(e) {
603
- const t = e?.revalidatePath ?? Ne();
677
+ function xt(e) {
678
+ const t = e?.revalidatePath ?? Le();
604
679
  t && (t("/", "layout"), t("/cms/navigation"));
605
680
  }
606
- function h(e) {
681
+ function _(e) {
607
682
  return e ? typeof e == "object" && "message" in e ? String(e.message || "Unknown database error.") : String(e) : "Unknown database error.";
608
683
  }
609
- async function In() {
684
+ async function On() {
610
685
  return import("./ai-global-agent-ecommerce.es.js");
611
686
  }
612
- function Te(e) {
613
- return e === null || typeof e != "object" ? JSON.stringify(e) : Array.isArray(e) ? `[${e.map((t) => Te(t)).join(",")}]` : `{${Object.keys(e).filter((t) => t !== "temp_id").sort().map((t) => `${JSON.stringify(t)}:${Te(e[t])}`).join(",")}}`;
687
+ function Ee(e) {
688
+ return e === null || typeof e != "object" ? JSON.stringify(e) : Array.isArray(e) ? `[${e.map((t) => Ee(t)).join(",")}]` : `{${Object.keys(e).filter((t) => t !== "temp_id").sort().map((t) => `${JSON.stringify(t)}:${Ee(e[t])}`).join(",")}}`;
614
689
  }
615
- function Tn(e) {
690
+ function Fn(e) {
616
691
  let t = 2166136261;
617
- const n = Te(e);
692
+ const n = Ee(e);
618
693
  for (let r = 0; r < n.length; r++)
619
694
  t ^= n.charCodeAt(r), t = Math.imul(t, 16777619);
620
695
  return (t >>> 0).toString(16).padStart(8, "0");
621
696
  }
622
- function xe(e) {
697
+ function $e(e) {
623
698
  return e.replace(/\s+/g, " ").trim().toUpperCase();
624
699
  }
625
- function xn(e, t, n) {
626
- return `${xe(`CONFIRM ${e} ${t}`)} #${Tn(n)}`;
700
+ function jn(e, t, n) {
701
+ return `${$e(`CONFIRM ${e} ${t}`)} #${Fn(n)}`;
627
702
  }
628
- function gt(e) {
703
+ function Ct(e) {
629
704
  return {
630
- confirmationPhrase: xn(
705
+ confirmationPhrase: jn(
631
706
  e.action,
632
707
  e.subject,
633
708
  e.payload
@@ -638,58 +713,63 @@ function gt(e) {
638
713
  success: !0
639
714
  };
640
715
  }
641
- function U(e, t) {
716
+ function O(e, t) {
642
717
  const n = e[t];
643
718
  return typeof n == "string" && n.trim() ? n.trim() : null;
644
719
  }
645
- function Z(e, t) {
720
+ function M(e, t) {
646
721
  const n = Number(e[t]);
647
722
  return Number.isFinite(n) ? n : null;
648
723
  }
649
- function F(e, t, n = `${t}s`) {
724
+ function N(e, t, n = `${t}s`) {
650
725
  return `${e} ${e === 1 ? t : n}`;
651
726
  }
652
- function Cn(e, t) {
653
- const n = U(t, "summary");
727
+ function Ln(e, t) {
728
+ const n = O(t, "summary");
654
729
  if (n)
655
730
  return n;
656
- const r = U(t, "title"), o = U(t, "slug"), a = U(t, "status"), s = U(t, "contentType"), l = U(t, "field"), u = U(t, "mode"), d = U(t, "languageCode"), c = Z(t, "blockCount"), p = Z(t, "itemCount"), g = Z(t, "affectedCount");
731
+ const r = O(t, "title"), o = O(t, "slug"), a = O(t, "status"), s = O(t, "contentType"), l = O(t, "field"), u = O(t, "mode"), d = O(t, "languageCode"), c = M(t, "blockCount"), m = M(t, "itemCount"), h = M(t, "affectedCount");
657
732
  if (e === "create_cms_page" || e === "create_cms_post")
658
- return `Create ${a || "draft"} ${e === "create_cms_page" ? "page" : "post"} "${r || o || "Untitled"}"${o ? ` at slug "${o}"` : ""}${c !== null ? ` with ${F(c, "content block")}` : ""}.`;
659
- if (e === "create_cms_product")
660
- return `Create ${a || "draft"} product "${r || o || "Untitled"}"${o ? ` at slug "${o}"` : ""}.`;
733
+ return `Create ${a || "draft"} ${e === "create_cms_page" ? "page" : "post"} "${r || o || "Untitled"}"${o ? ` at slug "${o}"` : ""}${c !== null ? ` with ${N(c, "content block")}` : ""}.`;
734
+ if (e === "create_cms_product") {
735
+ const p = M(t, "imageCount"), g = M(t, "blockCount"), f = [
736
+ p ? N(p, "image") : null,
737
+ g ? N(g, "description block") : M(t, "descriptionLength") ? "a full description" : null
738
+ ].filter(Boolean);
739
+ return `Create ${a || "draft"} product "${r || o || "Untitled"}"${o ? ` at slug "${o}"` : ""}${f.length ? ` with ${f.join(" and ")}` : ""}.`;
740
+ }
661
741
  if (e === "update_cms_item_field")
662
742
  return `Update ${l || "one field"} on the ${s || "CMS item"} "${r || o || "selected item"}".`;
663
743
  if (e === "update_navigation_bar")
664
- return `${u === "append" ? "Add" : u === "update" ? "Update" : "Replace"} ${p !== null ? F(p, "navigation item") : "navigation items"} in the ${d || "selected"} header navigation.`;
744
+ return `${u === "append" ? "Add" : u === "update" ? "Update" : "Replace"} ${m !== null ? N(m, "navigation item") : "navigation items"} in the ${d || "selected"} header navigation.`;
665
745
  if (e === "update_footer") {
666
- const m = Z(t, "linkCount");
667
- return `Update the ${d || "selected"} footer${m !== null ? ` with ${F(m, "link")}` : ""}.`;
746
+ const p = M(t, "linkCount");
747
+ return `Update the ${d || "selected"} footer${p !== null ? ` with ${N(p, "link")}` : ""}.`;
668
748
  }
669
- return e === "update_content_block" ? `Update the selected ${U(t, "blockType") || "content"} block.` : e === "insert_content_block" ? `Insert ${U(t, "blockType") || "content"} block on the ${s || "CMS item"} "${r || o || "selected item"}".` : e === "update_section_column_block" ? `Update the selected nested ${U(t, "nestedBlockType") || "section"} block.` : e === "delete_cms_item" || e === "prepare_delete_cms_item" ? `Delete ${g !== null ? F(g, s || "CMS item") : `the selected ${s || "CMS item"}`}${r || o ? ` for "${r || o}"` : ""}.` : "Complete the requested CMS change.";
749
+ return e === "update_content_block" ? `Update the selected ${O(t, "blockType") || "content"} block.` : e === "insert_content_block" ? `Insert ${O(t, "blockType") || "content"} block on the ${s || "CMS item"} "${r || o || "selected item"}".` : e === "update_section_column_block" ? `Update the selected nested ${O(t, "nestedBlockType") || "section"} block.` : e === "delete_cms_item" || e === "prepare_delete_cms_item" ? `Delete ${h !== null ? N(h, s || "CMS item") : `the selected ${s || "CMS item"}`}${r || o ? ` for "${r || o}"` : ""}.` : "Complete the requested CMS change.";
670
750
  }
671
751
  function P(e) {
672
752
  if (e.context?.skipConfirmation)
673
753
  return null;
674
- const t = gt(e), n = xe(e.context?.latestUserMessage || ""), r = xe(t.confirmationPhrase);
754
+ const t = Ct(e), n = $e(e.context?.latestUserMessage || ""), r = $e(t.confirmationPhrase);
675
755
  return n.includes(r) ? null : t;
676
756
  }
677
- function Fe(e) {
757
+ function Re(e) {
678
758
  const t = e?.actorUserId;
679
759
  if (!t)
680
760
  throw new Error("A confirmed CMS mutation requires an authenticated admin actor.");
681
761
  return t;
682
762
  }
683
- function Oe() {
763
+ function qe() {
684
764
  return globalThis.crypto?.randomUUID?.() || `id-${Date.now()}-${Math.random().toString(36).slice(2)}`;
685
765
  }
686
- function Y(e) {
766
+ function R(e) {
687
767
  return e.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 300);
688
768
  }
689
- function je(e) {
769
+ function Me(e) {
690
770
  return (e || "USD").trim().toUpperCase();
691
771
  }
692
- const vn = /* @__PURE__ */ new Set([
772
+ const Bn = /* @__PURE__ */ new Set([
693
773
  "BIF",
694
774
  "CLP",
695
775
  "DJF",
@@ -707,128 +787,131 @@ const vn = /* @__PURE__ */ new Set([
707
787
  "XOF",
708
788
  "XPF"
709
789
  ]);
710
- function Sn(e) {
711
- return vn.has(je(e)) ? 0 : 2;
790
+ function Rn(e) {
791
+ return Bn.has(Me(e)) ? 0 : 2;
712
792
  }
713
- function ft(e, t) {
714
- return Math.round(e * 10 ** Sn(t));
793
+ function St(e, t) {
794
+ return Math.round(e * 10 ** Rn(t));
715
795
  }
716
- function En(e, t) {
796
+ function qn(e, t) {
717
797
  return !e || typeof e != "object" || Array.isArray(e) ? {} : Object.entries(e).reduce(
718
798
  (n, [r, o]) => {
719
799
  if (typeof o == "number" && Number.isFinite(o) && o >= 0) {
720
- const a = je(r || t);
721
- n[a] = ft(o, a);
800
+ const a = Me(r || t);
801
+ n[a] = St(o, a);
722
802
  }
723
803
  return n;
724
804
  },
725
805
  {}
726
806
  );
727
807
  }
728
- function X(e, t) {
729
- if (!A(e))
808
+ function ee(e, t) {
809
+ if (!$(e))
730
810
  throw new Error(`${t} content must be a JSON object.`);
731
811
  return JSON.parse(JSON.stringify(e));
732
812
  }
733
- function H(e) {
813
+ function z(e) {
734
814
  return JSON.parse(JSON.stringify(e));
735
815
  }
736
- function A(e) {
816
+ function $(e) {
737
817
  return !!(e && typeof e == "object" && !Array.isArray(e));
738
818
  }
739
- function Ce(e, t) {
740
- const n = H(e);
819
+ function Ae(e, t) {
820
+ const n = z(e);
741
821
  for (const [r, o] of Object.entries(t))
742
822
  if (o !== void 0) {
743
- if (A(o) && A(n[r])) {
744
- n[r] = Ce(n[r], o);
823
+ if ($(o) && $(n[r])) {
824
+ n[r] = Ae(n[r], o);
745
825
  continue;
746
826
  }
747
- n[r] = H(o);
827
+ n[r] = z(o);
748
828
  }
749
829
  return n;
750
830
  }
751
- function ht(e, t) {
752
- if (t.contentType === "product")
753
- throw new Error("Products do not have page/post content blocks in this editor context.");
754
- const n = Ue(t);
831
+ function vt(e, t) {
832
+ if (t.contentType === "product") {
833
+ if (String(e.product_id ?? "") !== String(wt(t)))
834
+ throw new Error(`Block ${e.id} does not belong to the current product being edited.`);
835
+ return;
836
+ }
837
+ const n = Be(t);
755
838
  if ((t.contentType === "page" ? Number(e.page_id) : Number(e.post_id)) !== n)
756
839
  throw new Error(
757
840
  `Block ${e.id} does not belong to the current ${t.contentType} being edited.`
758
841
  );
759
842
  }
760
- function re(e, t) {
843
+ function ae(e, t) {
761
844
  const n = typeof e == "string" ? e : "";
762
- if (!pn(n))
845
+ if (!Cn(n))
763
846
  throw new Error(`${t} has unsupported block type "${n || "unknown"}".`);
764
847
  return n;
765
848
  }
766
- function _t(e, t, n) {
849
+ function Et(e, t, n) {
767
850
  if (e && e !== t)
768
851
  throw new Error(
769
852
  `${n} is a "${t}" block. Refusing to update it as "${e}".`
770
853
  );
771
854
  }
772
- function L(e, t, n, r) {
773
- const o = gn(e, t, r);
855
+ function D(e, t, n, r) {
856
+ const o = vn(e, t, r);
774
857
  if (!o.isValid)
775
858
  throw new Error(
776
859
  `${n} content is invalid for block type "${e}": ${o.errors.join("; ")}`
777
860
  );
778
861
  }
779
- function yt(e) {
862
+ function $t(e) {
780
863
  return e === "section";
781
864
  }
782
- function $n(e) {
865
+ function Mn(e) {
783
866
  return typeof e.html_content == "string" ? "text" : typeof e.text == "string" && typeof e.url == "string" ? "button" : typeof e.text_content == "string" ? "heading" : "media_id" in e || "object_key" in e || "external_url" in e ? "image" : typeof e.quote == "string" && typeof e.author_name == "string" ? "testimonial" : typeof e.url == "string" && ("controls" in e || "autoplay" in e || "title" in e) ? "video_embed" : Array.isArray(e.fields) || typeof e.recipient_email == "string" ? "form" : "postsPerPage" in e || "showPagination" in e ? "posts_grid" : typeof e.productId == "string" ? "featured_product" : "limit" in e && "type" in e ? "product_grid" : null;
784
867
  }
785
- function oe(e) {
868
+ function se(e) {
786
869
  return `ai-${e}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
787
870
  }
788
- function ve(e, t, n) {
789
- if (!A(e))
871
+ function Pe(e, t, n) {
872
+ if (!$(e))
790
873
  throw new Error(`${t} must be a JSON object.`);
791
- const r = e.block_type ?? e.blockType, o = re(r, t);
792
- if (yt(o))
874
+ const r = e.block_type ?? e.blockType, o = ae(r, t);
875
+ if ($t(o))
793
876
  throw new Error(`${t} cannot be a nested ${o} block.`);
794
- const a = It(
877
+ const a = Ut(
795
878
  o,
796
- X(e.content, t),
879
+ ee(e.content, t),
797
880
  t,
798
881
  n
799
- ), s = e.temp_id ?? e.tempId, l = typeof s == "string" && s.trim() ? s : oe(o);
882
+ ), s = e.temp_id ?? e.tempId, l = typeof s == "string" && s.trim() ? s : se(o);
800
883
  return {
801
884
  block_type: o,
802
885
  content: a,
803
886
  temp_id: l
804
887
  };
805
888
  }
806
- function An(e, t) {
889
+ function Dn(e, t) {
807
890
  const n = [];
808
- if ("append_block" in e && n.push(ve(e.append_block, "Nested block to append", t)), "append_blocks" in e) {
891
+ if ("append_block" in e && n.push(Pe(e.append_block, "Nested block to append", t)), "append_blocks" in e) {
809
892
  const r = e.append_blocks;
810
893
  if (!Array.isArray(r))
811
894
  throw new Error("append_blocks must be an array of nested block objects.");
812
895
  r.forEach((o, a) => {
813
- n.push(ve(o, `Nested block to append ${a}`, t));
896
+ n.push(Pe(o, `Nested block to append ${a}`, t));
814
897
  });
815
898
  }
816
899
  return n;
817
900
  }
818
- function Pn(e, t) {
901
+ function zn(e, t) {
819
902
  if ("append_block" in e || "append_blocks" in e || "background" in e || "column_blocks" in e || "column_gap" in e || "container_type" in e || "padding" in e || "responsive_columns" in e || "vertical_alignment" in e)
820
903
  return null;
821
- const n = $n(e);
904
+ const n = Mn(e);
822
905
  if (!n)
823
906
  return null;
824
- const r = X(e, `Nested ${n} block`);
825
- return L(n, r, `Nested ${n} block`, t), {
907
+ const r = ee(e, `Nested ${n} block`);
908
+ return D(n, r, `Nested ${n} block`, t), {
826
909
  block_type: n,
827
910
  content: r,
828
- temp_id: oe(n)
911
+ temp_id: se(n)
829
912
  };
830
913
  }
831
- function Nn(e, t) {
914
+ function Gn(e, t) {
832
915
  const n = e.append_column_index ?? e.column_index;
833
916
  if (n === void 0)
834
917
  return 0;
@@ -840,14 +923,14 @@ function Nn(e, t) {
840
923
  );
841
924
  return n;
842
925
  }
843
- function Un(e, t, n, r) {
844
- if (!yt(e))
845
- return Ce(t, n);
846
- const o = { ...n }, a = An(o, r), s = Pn(o, r);
926
+ function Kn(e, t, n, r) {
927
+ if (!$t(e))
928
+ return Ae(t, n);
929
+ const o = { ...n }, a = Dn(o, r), s = zn(o, r);
847
930
  s && a.push(s), delete o.append_block, delete o.append_blocks, delete o.append_column_index, delete o.column_index;
848
- const l = Ce(t, o);
931
+ const l = Ae(t, o);
849
932
  if (a.length > 0) {
850
- const u = Array.isArray(t.column_blocks) ? H(t.column_blocks) : [], d = Nn(n, u.length), c = u.length > 0 ? u : [[]];
933
+ const u = Array.isArray(t.column_blocks) ? z(t.column_blocks) : [], d = Gn(n, u.length), c = u.length > 0 ? u : [[]];
851
934
  for (; c.length <= d; )
852
935
  c.push([]);
853
936
  c[d] = [
@@ -857,7 +940,7 @@ function Un(e, t, n, r) {
857
940
  }
858
941
  return l;
859
942
  }
860
- function Fn(e, t) {
943
+ function Hn(e, t) {
861
944
  return {
862
945
  blockType: e.block_type,
863
946
  content: t ? e.content : void 0,
@@ -868,28 +951,28 @@ function Fn(e, t) {
868
951
  postId: e.post_id
869
952
  };
870
953
  }
871
- function R(e) {
954
+ function G(e) {
872
955
  return typeof e == "string" ? e.trim().toLowerCase() : "";
873
956
  }
874
- function We(e) {
957
+ function tt(e) {
875
958
  return typeof e == "string" ? e.trim().toLowerCase() : "";
876
959
  }
877
- function bt(e) {
960
+ function At(e) {
878
961
  return e.reduce((t, n) => t + 1 + (n.children?.length || 0), 0);
879
962
  }
880
- function ne(e) {
963
+ function ie(e) {
881
964
  return typeof e == "string" ? e.trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") : "";
882
965
  }
883
- async function G(e, t) {
884
- const n = t.trim(), r = ne(n), o = Jt[r], { data: a, error: s } = await e.from("languages").select("id, code, name, is_active");
966
+ async function J(e, t) {
967
+ const n = t.trim(), r = ie(n), o = cn[r], { data: a, error: s } = await e.from("languages").select("id, code, name, is_active");
885
968
  if (s)
886
- throw new Error(`Failed to load language "${t}": ${h(s)}`);
969
+ throw new Error(`Failed to load language "${t}": ${_(s)}`);
887
970
  const u = (Array.isArray(a) ? a : []).filter((c) => c.is_active !== !1), d = u.find((c) => {
888
- const p = ne(c.code), g = ne(c.name);
889
- return p === r || p === o || g === r;
971
+ const m = ie(c.code), h = ie(c.name);
972
+ return m === r || m === o || h === r;
890
973
  });
891
974
  if (!d?.id || !d?.code) {
892
- const c = u.map((p) => p.code).filter(Boolean).join(", ");
975
+ const c = u.map((m) => m.code).filter(Boolean).join(", ");
893
976
  throw new Error(
894
977
  `Language "${t}" was not found.${c ? ` Available languages: ${c}.` : ""}`
895
978
  );
@@ -899,15 +982,15 @@ async function G(e, t) {
899
982
  id: Number(d.id)
900
983
  };
901
984
  }
902
- async function ke(e, t) {
985
+ async function Ce(e, t) {
903
986
  if (t)
904
- return G(e, t);
987
+ return J(e, t);
905
988
  const { data: n, error: r } = await e.from("languages").select("id, code, name, is_active, is_default");
906
989
  if (r)
907
- throw new Error(`Failed to load active languages: ${h(r)}`);
990
+ throw new Error(`Failed to load active languages: ${_(r)}`);
908
991
  const o = (Array.isArray(n) ? n : []).filter(
909
992
  (s) => s.is_active !== !1
910
- ), a = o.find((s) => s.is_default) || o.find((s) => ne(s.code) === "en") || o[0];
993
+ ), a = o.find((s) => s.is_default) || o.find((s) => ie(s.code) === "en") || o[0];
911
994
  if (!a?.id || !a?.code)
912
995
  throw new Error("No active CMS language is available for Cortex AI content creation.");
913
996
  return {
@@ -915,25 +998,25 @@ async function ke(e, t) {
915
998
  id: Number(a.id)
916
999
  };
917
1000
  }
918
- async function Je(e) {
1001
+ async function nt(e) {
919
1002
  try {
920
1003
  const { data: t, error: n } = await e.from("currencies").select("code, is_default, is_active").eq("is_active", !0);
921
1004
  if (n)
922
1005
  return "USD";
923
1006
  const r = Array.isArray(t) ? t : [], o = r.find((a) => a.is_default) || r[0];
924
- return je(o?.code || "USD");
1007
+ return Me(o?.code || "USD");
925
1008
  } catch {
926
1009
  return "USD";
927
1010
  }
928
1011
  }
929
- async function On(e) {
1012
+ async function Vn(e) {
930
1013
  const t = e.contentType === "page" ? "pages" : e.contentType === "post" ? "posts" : "products";
931
1014
  let n = "id", r = e.entityId;
932
1015
  if (r === void 0 && e.slug && (n = "slug", r = e.slug), r === void 0 && e.title && (n = "title", r = e.title), r === void 0)
933
1016
  throw new Error(`A ${e.contentType} target requires an id, slug, title, or current edit context.`);
934
1017
  const { data: o, error: a } = await e.supabase.from(t).select("*").eq(n, r);
935
1018
  if (a)
936
- throw new Error(`Failed to resolve ${e.contentType}: ${h(a)}`);
1019
+ throw new Error(`Failed to resolve ${e.contentType}: ${_(a)}`);
937
1020
  const s = Array.isArray(o) ? o : o ? [o] : [];
938
1021
  if (s.length !== 1)
939
1022
  throw new Error(
@@ -941,15 +1024,15 @@ async function On(e) {
941
1024
  );
942
1025
  return s[0];
943
1026
  }
944
- async function we(e, t) {
945
- const n = st.safeParse(t?.pageContext).success ? t?.pageContext : null, r = e.contentType || n?.contentType;
1027
+ async function te(e, t) {
1028
+ const n = ht.safeParse(t?.pageContext).success ? t?.pageContext : null, r = e.contentType || n?.contentType;
946
1029
  if (!r)
947
1030
  throw new Error("Target contentType is required when no current CMS edit context exists.");
948
- const o = e.entityId !== void 0 || !!e.slug || !!e.title, a = e.entityId ?? (o ? void 0 : n?.entityId), s = e.slug ?? (o ? void 0 : n?.slug ?? void 0), l = e.title ?? (o ? void 0 : n?.title ?? void 0), u = await On({
1031
+ const o = e.entityId !== void 0 || !!e.slug || !!e.title, a = e.entityId ?? (o ? void 0 : n?.entityId), s = e.slug ?? (o ? void 0 : n?.slug ?? void 0), l = e.title ?? (o ? void 0 : n?.title ?? void 0), u = await Vn({
949
1032
  contentType: r,
950
1033
  entityId: a,
951
1034
  slug: a === void 0 && s || void 0,
952
- supabase: I(t),
1035
+ supabase: C(t),
953
1036
  title: a === void 0 && !s && l || void 0
954
1037
  });
955
1038
  return {
@@ -957,8 +1040,8 @@ async function we(e, t) {
957
1040
  item: u
958
1041
  };
959
1042
  }
960
- async function ie(e) {
961
- const t = await qn({
1043
+ async function le(e) {
1044
+ const t = await Wn({
962
1045
  item: e.item,
963
1046
  languageId: e.languageId,
964
1047
  menuKey: e.menuKey,
@@ -974,56 +1057,56 @@ async function ie(e) {
974
1057
  url: e.item.url
975
1058
  }, { data: r, error: o } = await e.supabase.from("navigation_items").insert(n).select("id").single();
976
1059
  if (o)
977
- throw new Error(`Failed to insert ${e.menuKey} navigation item: ${h(o)}`);
1060
+ throw new Error(`Failed to insert ${e.menuKey} navigation item: ${_(o)}`);
978
1061
  return Number(r.id);
979
1062
  }
980
- function jn(e) {
1063
+ function Jn(e) {
981
1064
  const t = e.trim();
982
1065
  if (!t.startsWith("/") || t.startsWith("//"))
983
1066
  return null;
984
1067
  const n = t.split("?")[0]?.split("#")[0] || "", r = n === "/" ? "home" : n.replace(/^\/+|\/+$/g, "");
985
1068
  return r && !r.includes("/") ? r : null;
986
1069
  }
987
- async function qn(e) {
988
- const t = jn(e.item.url);
1070
+ async function Wn(e) {
1071
+ const t = Jn(e.item.url);
989
1072
  if (!t)
990
1073
  return null;
991
1074
  const { data: n, error: r } = await e.supabase.from("pages").select("id, slug, translation_group_id, language_id").eq("slug", t).eq("language_id", e.languageId);
992
1075
  if (r)
993
- throw new Error(`Failed to resolve linked page for navigation item: ${h(r)}`);
1076
+ throw new Error(`Failed to resolve linked page for navigation item: ${_(r)}`);
994
1077
  const o = Array.isArray(n) ? n[0] : n;
995
1078
  if (!o?.id)
996
1079
  return null;
997
- let a = Oe();
1080
+ let a = qe();
998
1081
  if (o.translation_group_id) {
999
1082
  const { data: s, error: l } = await e.supabase.from("pages").select("id").eq("translation_group_id", o.translation_group_id);
1000
1083
  if (l)
1001
1084
  throw new Error(
1002
- `Failed to inspect linked page translations for navigation item: ${h(l)}`
1085
+ `Failed to inspect linked page translations for navigation item: ${_(l)}`
1003
1086
  );
1004
1087
  const u = new Set(
1005
- (Array.isArray(s) ? s : []).map((g) => String(g.id)).filter(Boolean)
1088
+ (Array.isArray(s) ? s : []).map((h) => String(h.id)).filter(Boolean)
1006
1089
  ), { data: d, error: c } = await e.supabase.from("navigation_items").select("id, page_id, translation_group_id, menu_key").eq("menu_key", e.menuKey);
1007
1090
  if (c)
1008
1091
  throw new Error(
1009
- `Failed to inspect related navigation translations: ${h(c)}`
1092
+ `Failed to inspect related navigation translations: ${_(c)}`
1010
1093
  );
1011
- const p = (Array.isArray(d) ? d : []).find((g) => g.translation_group_id && u.has(String(g.page_id)));
1012
- p?.translation_group_id && (a = p.translation_group_id);
1094
+ const m = (Array.isArray(d) ? d : []).find((h) => h.translation_group_id && u.has(String(h.page_id)));
1095
+ m?.translation_group_id && (a = m.translation_group_id);
1013
1096
  }
1014
1097
  return {
1015
1098
  navigationTranslationGroupId: a,
1016
1099
  pageId: Number(o.id)
1017
1100
  };
1018
1101
  }
1019
- async function kt(e) {
1020
- const t = await G(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, parent_id").eq("menu_key", e.menuKey).eq("language_id", t.id);
1102
+ async function Pt(e) {
1103
+ const t = await J(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, parent_id").eq("menu_key", e.menuKey).eq("language_id", t.id);
1021
1104
  if (r)
1022
1105
  throw new Error(
1023
- `Failed to inspect existing ${e.menuKey} navigation items: ${h(r)}`
1106
+ `Failed to inspect existing ${e.menuKey} navigation items: ${_(r)}`
1024
1107
  );
1025
- const o = Array.isArray(n) ? n : [], a = o.filter((d) => d.parent_id == null).length, s = bt(e.items);
1026
- wt({
1108
+ const o = Array.isArray(n) ? n : [], a = o.filter((d) => d.parent_id == null).length, s = At(e.items);
1109
+ Nt({
1027
1110
  existingItemCount: o.length,
1028
1111
  existingTopLevelCount: a,
1029
1112
  languageCode: t.code,
@@ -1032,10 +1115,10 @@ async function kt(e) {
1032
1115
  });
1033
1116
  const { error: l } = await e.supabase.from("navigation_items").delete().eq("menu_key", e.menuKey).eq("language_id", t.id);
1034
1117
  if (l)
1035
- throw new Error(`Failed to clear ${e.menuKey} navigation items: ${h(l)}`);
1118
+ throw new Error(`Failed to clear ${e.menuKey} navigation items: ${_(l)}`);
1036
1119
  let u = 0;
1037
1120
  for (const [d, c] of e.items.entries()) {
1038
- const p = await ie({
1121
+ const m = await le({
1039
1122
  item: c,
1040
1123
  languageId: t.id,
1041
1124
  menuKey: e.menuKey,
@@ -1043,13 +1126,13 @@ async function kt(e) {
1043
1126
  supabase: e.supabase
1044
1127
  });
1045
1128
  u++;
1046
- for (const [g, m] of (c.children ?? []).entries())
1047
- await ie({
1048
- item: m,
1129
+ for (const [h, p] of (c.children ?? []).entries())
1130
+ await le({
1131
+ item: p,
1049
1132
  languageId: t.id,
1050
1133
  menuKey: e.menuKey,
1051
- order: g,
1052
- parentId: p,
1134
+ order: h,
1135
+ parentId: m,
1053
1136
  supabase: e.supabase
1054
1137
  }), u++;
1055
1138
  }
@@ -1061,38 +1144,38 @@ async function kt(e) {
1061
1144
  updatedCount: 0
1062
1145
  };
1063
1146
  }
1064
- function wt(e) {
1147
+ function Nt(e) {
1065
1148
  if (!(e.existingItemCount === 0 || e.replacementItemCount >= e.existingItemCount))
1066
1149
  throw new Error(
1067
1150
  `Refusing destructive ${e.menuKey} navigation replacement for ${e.languageCode}: existing menu has ${e.existingItemCount} items (${e.existingTopLevelCount} top-level), but the replacement only contains ${e.replacementItemCount}. Use mode "update" for renaming or changing a single link, or provide the full menu.`
1068
1151
  );
1069
1152
  }
1070
- async function Bn(e) {
1071
- const t = await G(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, parent_id").eq("menu_key", e.menuKey).eq("language_id", t.id);
1153
+ async function Yn(e) {
1154
+ const t = await J(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, parent_id").eq("menu_key", e.menuKey).eq("language_id", t.id);
1072
1155
  if (r)
1073
1156
  throw new Error(
1074
- `Failed to inspect existing ${e.menuKey} navigation items: ${h(r)}`
1157
+ `Failed to inspect existing ${e.menuKey} navigation items: ${_(r)}`
1075
1158
  );
1076
1159
  const o = Array.isArray(n) ? n : [];
1077
- wt({
1160
+ Nt({
1078
1161
  existingItemCount: o.length,
1079
1162
  existingTopLevelCount: o.filter((a) => a.parent_id == null).length,
1080
1163
  languageCode: t.code,
1081
1164
  menuKey: e.menuKey,
1082
- replacementItemCount: bt(e.items)
1165
+ replacementItemCount: At(e.items)
1083
1166
  });
1084
1167
  }
1085
- async function Ln(e) {
1168
+ async function Xn(e) {
1086
1169
  if (e.items.length !== 1)
1087
1170
  throw new Error('mode "update" requires exactly one navigation item.');
1088
- const t = await G(e.supabase, e.languageCode), n = e.items[0], r = R(e.match?.url) || R(n.url), o = We(e.match?.label), { data: a, error: s } = await e.supabase.from("navigation_items").select("id, label, url, parent_id, order").eq("menu_key", e.menuKey).eq("language_id", t.id);
1171
+ const t = await J(e.supabase, e.languageCode), n = e.items[0], r = G(e.match?.url) || G(n.url), o = tt(e.match?.label), { data: a, error: s } = await e.supabase.from("navigation_items").select("id, label, url, parent_id, order").eq("menu_key", e.menuKey).eq("language_id", t.id);
1089
1172
  if (s)
1090
1173
  throw new Error(
1091
- `Failed to load existing ${e.menuKey} navigation items: ${h(s)}`
1174
+ `Failed to load existing ${e.menuKey} navigation items: ${_(s)}`
1092
1175
  );
1093
1176
  const u = (Array.isArray(a) ? a : []).find((c) => {
1094
- const p = R(c.url), g = We(c.label);
1095
- return !!(r && p === r || o && g === o);
1177
+ const m = G(c.url), h = tt(c.label);
1178
+ return !!(r && m === r || o && h === o);
1096
1179
  });
1097
1180
  if (!u?.id)
1098
1181
  throw new Error(
@@ -1103,7 +1186,7 @@ async function Ln(e) {
1103
1186
  url: n.url
1104
1187
  }).eq("id", u.id);
1105
1188
  if (d)
1106
- throw new Error(`Failed to update ${e.menuKey} navigation item: ${h(d)}`);
1189
+ throw new Error(`Failed to update ${e.menuKey} navigation item: ${_(d)}`);
1107
1190
  return {
1108
1191
  insertedCount: 0,
1109
1192
  languageCode: t.code,
@@ -1112,46 +1195,46 @@ async function Ln(e) {
1112
1195
  updatedCount: 1
1113
1196
  };
1114
1197
  }
1115
- async function Rn(e) {
1116
- const t = await G(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, url, parent_id, order").eq("menu_key", e.menuKey).eq("language_id", t.id);
1198
+ async function Qn(e) {
1199
+ const t = await J(e.supabase, e.languageCode), { data: n, error: r } = await e.supabase.from("navigation_items").select("id, url, parent_id, order").eq("menu_key", e.menuKey).eq("language_id", t.id);
1117
1200
  if (r)
1118
1201
  throw new Error(
1119
- `Failed to load existing ${e.menuKey} navigation items: ${h(r)}`
1202
+ `Failed to load existing ${e.menuKey} navigation items: ${_(r)}`
1120
1203
  );
1121
1204
  let o = 0, a = 0;
1122
1205
  const s = Array.isArray(n) ? n : [], l = new Set(
1123
- s.map((c) => R(c.url)).filter(Boolean)
1206
+ s.map((c) => G(c.url)).filter(Boolean)
1124
1207
  ), u = s.filter((c) => c.parent_id == null).map((c) => Number(c.order)).filter(Number.isFinite);
1125
1208
  let d = u.length > 0 ? Math.max(...u) + 1 : s.length;
1126
1209
  for (const c of e.items) {
1127
- const p = R(c.url);
1128
- if (p && l.has(p)) {
1210
+ const m = G(c.url);
1211
+ if (m && l.has(m)) {
1129
1212
  a++;
1130
1213
  continue;
1131
1214
  }
1132
- const g = await ie({
1215
+ const h = await le({
1133
1216
  item: c,
1134
1217
  languageId: t.id,
1135
1218
  menuKey: e.menuKey,
1136
1219
  order: d,
1137
1220
  supabase: e.supabase
1138
1221
  });
1139
- o++, d++, p && l.add(p);
1140
- let m = 0;
1141
- for (const f of c.children ?? []) {
1142
- const _ = R(f.url);
1143
- if (_ && l.has(_)) {
1222
+ o++, d++, m && l.add(m);
1223
+ let p = 0;
1224
+ for (const g of c.children ?? []) {
1225
+ const f = G(g.url);
1226
+ if (f && l.has(f)) {
1144
1227
  a++;
1145
1228
  continue;
1146
1229
  }
1147
- await ie({
1148
- item: f,
1230
+ await le({
1231
+ item: g,
1149
1232
  languageId: t.id,
1150
1233
  menuKey: e.menuKey,
1151
- order: m,
1152
- parentId: g,
1234
+ order: p,
1235
+ parentId: h,
1153
1236
  supabase: e.supabase
1154
- }), o++, m++, _ && l.add(_);
1237
+ }), o++, p++, f && l.add(f);
1155
1238
  }
1156
1239
  }
1157
1240
  return {
@@ -1162,76 +1245,76 @@ async function Rn(e) {
1162
1245
  updatedCount: 0
1163
1246
  };
1164
1247
  }
1165
- function x(e) {
1248
+ function v(e) {
1166
1249
  return typeof e == "string" && e.trim() ? e.trim() : "";
1167
1250
  }
1168
- function Mn(e) {
1251
+ function Zn(e) {
1169
1252
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1170
1253
  }
1171
- function Dn(e) {
1172
- const t = x(e.field_type ?? e.fieldType ?? e.type ?? e.input_type).toLowerCase().replace(/\s+/g, "_"), n = x(e.label ?? e.name ?? e.placeholder).toLowerCase();
1254
+ function er(e) {
1255
+ const t = v(e.field_type ?? e.fieldType ?? e.type ?? e.input_type).toLowerCase().replace(/\s+/g, "_"), n = v(e.label ?? e.name ?? e.placeholder).toLowerCase();
1173
1256
  return ["email", "textarea", "select", "radio", "checkbox", "text"].includes(t) ? t : n.includes("email") ? "email" : n.includes("message") || n.includes("comment") || n.includes("details") ? "textarea" : "text";
1174
1257
  }
1175
- function Gn(e) {
1258
+ function tr(e) {
1176
1259
  return (Array.isArray(e) && e.length > 0 ? e : [
1177
1260
  { field_type: "text", is_required: !0, label: "Name", placeholder: "Your name" },
1178
1261
  { field_type: "email", is_required: !0, label: "Email", placeholder: "you@example.com" },
1179
1262
  { field_type: "textarea", is_required: !0, label: "Message", placeholder: "How can we help?" }
1180
1263
  ]).map((n, r) => {
1181
- const o = A(n) ? n : {}, a = x(o.label ?? o.name) || (r === 0 ? "Name" : r === 1 ? "Email" : "Message"), s = Dn({ ...o, label: a }), l = o.is_required ?? o.isRequired ?? o.required;
1264
+ const o = $(n) ? n : {}, a = v(o.label ?? o.name) || (r === 0 ? "Name" : r === 1 ? "Email" : "Message"), s = er({ ...o, label: a }), l = o.is_required ?? o.isRequired ?? o.required;
1182
1265
  return {
1183
1266
  field_type: s,
1184
1267
  is_required: typeof l == "boolean" ? l : !0,
1185
1268
  label: a,
1186
1269
  options: Array.isArray(o.options) ? o.options : void 0,
1187
- placeholder: x(o.placeholder) || void 0,
1188
- temp_id: x(o.temp_id ?? o.tempId ?? o.id) || `field-${r + 1}`
1270
+ placeholder: v(o.placeholder) || void 0,
1271
+ temp_id: v(o.temp_id ?? o.tempId ?? o.id) || `field-${r + 1}`
1189
1272
  };
1190
1273
  });
1191
1274
  }
1192
- const zn = /* @__PURE__ */ new Set(["none", "sm", "md", "lg", "xl"]), Ye = /* @__PURE__ */ new Set(["none", "sm", "md", "lg", "xl"]), Kn = /* @__PURE__ */ new Set([
1275
+ const nr = /* @__PURE__ */ new Set(["none", "sm", "md", "lg", "xl"]), rt = /* @__PURE__ */ new Set(["none", "sm", "md", "lg", "xl"]), rr = /* @__PURE__ */ new Set([
1193
1276
  "full-width",
1194
1277
  "container",
1195
1278
  "container-sm",
1196
1279
  "container-lg",
1197
1280
  "container-xl"
1198
- ]), Vn = /* @__PURE__ */ new Set(["start", "center", "end", "stretch"]), Hn = /* @__PURE__ */ new Set(["none", "theme", "solid", "gradient", "image"]), Wn = /* @__PURE__ */ new Set(["primary", "secondary", "muted", "accent", "destructive"]), Jn = /* @__PURE__ */ new Set(["center", "top", "bottom", "left", "right"]);
1199
- function Yn(e) {
1281
+ ]), or = /* @__PURE__ */ new Set(["start", "center", "end", "stretch"]), ir = /* @__PURE__ */ new Set(["none", "theme", "solid", "gradient", "image"]), ar = /* @__PURE__ */ new Set(["primary", "secondary", "muted", "accent", "destructive"]), sr = /* @__PURE__ */ new Set(["center", "top", "bottom", "left", "right"]);
1282
+ function lr(e) {
1200
1283
  return typeof e == "string" && /^https?:\/\//i.test(e.trim());
1201
1284
  }
1202
- function q(e, t, n) {
1285
+ function B(e, t, n) {
1203
1286
  return typeof e == "string" && t.has(e) ? e : n;
1204
1287
  }
1205
- function Xn(e) {
1288
+ function cr(e) {
1206
1289
  return Number.isFinite(e) ? Math.min(4, Math.max(1, Math.round(e))) : 1;
1207
1290
  }
1208
- function Qn(e) {
1291
+ function ur(e) {
1209
1292
  const t = [
1210
1293
  { color: "#1e3a8a", position: 0 },
1211
1294
  { color: "#3b82f6", position: 100 }
1212
1295
  ];
1213
- if (!A(e))
1296
+ if (!$(e))
1214
1297
  return { direction: "to bottom right", stops: t, type: "linear" };
1215
1298
  const n = e.type === "radial" ? "radial" : "linear", r = Array.isArray(e.stops) && e.stops.length >= 2 ? e.stops : t;
1216
1299
  return { direction: typeof e.direction == "string" && e.direction.trim() ? e.direction : n === "radial" ? "circle at center" : "to bottom right", stops: r, type: n };
1217
1300
  }
1218
- function Zn(e) {
1219
- if (!A(e))
1301
+ function dr(e) {
1302
+ if (!$(e))
1220
1303
  return { type: "none" };
1221
- const t = q(e.type, Hn, "none"), n = typeof e.min_height == "string" && e.min_height.trim() ? { min_height: e.min_height } : {};
1304
+ const t = B(e.type, ir, "none"), n = typeof e.min_height == "string" && e.min_height.trim() ? { min_height: e.min_height } : {};
1222
1305
  if (t === "theme")
1223
- return { theme: q(e.theme, Wn, "muted"), type: t, ...n };
1306
+ return { theme: B(e.theme, ar, "muted"), type: t, ...n };
1224
1307
  if (t === "solid")
1225
1308
  return typeof e.solid_color == "string" && e.solid_color.trim() ? { solid_color: e.solid_color, type: t, ...n } : { type: "none" };
1226
1309
  if (t === "gradient")
1227
- return { gradient: Qn(e.gradient), type: t, ...n };
1310
+ return { gradient: ur(e.gradient), type: t, ...n };
1228
1311
  if (t === "image") {
1229
- const r = A(e.image) ? e.image : null, o = r && Yn(r.external_url) ? r.external_url.trim() : null, a = !!(r && typeof r.media_id == "string" && r.media_id.trim() && typeof r.object_key == "string" && r.object_key.trim());
1312
+ const r = $(e.image) ? e.image : null, o = r && lr(r.external_url) ? r.external_url.trim() : null, a = !!(r && typeof r.media_id == "string" && r.media_id.trim() && typeof r.object_key == "string" && r.object_key.trim());
1230
1313
  return r && (o || a) ? {
1231
1314
  image: {
1232
1315
  ...r,
1233
1316
  ...o ? { external_url: o } : {},
1234
- position: q(r.position, Jn, "center"),
1317
+ position: B(r.position, sr, "center"),
1235
1318
  size: r.size === "contain" ? "contain" : "cover"
1236
1319
  },
1237
1320
  type: t,
@@ -1240,47 +1323,47 @@ function Zn(e) {
1240
1323
  }
1241
1324
  return { type: "none", ...n };
1242
1325
  }
1243
- function er(e, t, n) {
1326
+ function pr(e, t, n) {
1244
1327
  const r = e.is_hero === !0;
1245
1328
  let o = Array.isArray(e.column_blocks) ? e.column_blocks : [];
1246
- o.length > 0 && o.every((_) => A(_) && !Array.isArray(_)) && (o = [o]);
1247
- const a = o.map((_, k) => (Array.isArray(_) ? _ : []).map(
1248
- (E, y) => ve(E, `${t} column ${k} block ${y}`, n)
1249
- )), s = a.length > 0 ? a : [[]], l = Xn(s.length), u = A(e.responsive_columns) ? e.responsive_columns : {}, d = Number(u.tablet), c = Number(u.mobile), p = Number.isFinite(d) ? Math.min(3, Math.max(1, Math.min(l, d))) : Math.min(3, l), g = Number.isFinite(c) ? Math.min(2, Math.max(1, c)) : 1, m = A(e.padding) ? e.padding : {}, f = {
1329
+ o.length > 0 && o.every((f) => $(f) && !Array.isArray(f)) && (o = [o]);
1330
+ const a = o.map((f, k) => (Array.isArray(f) ? f : []).map(
1331
+ (w, b) => Pe(w, `${t} column ${k} block ${b}`, n)
1332
+ )), s = a.length > 0 ? a : [[]], l = cr(s.length), u = $(e.responsive_columns) ? e.responsive_columns : {}, d = Number(u.tablet), c = Number(u.mobile), m = Number.isFinite(d) ? Math.min(3, Math.max(1, Math.min(l, d))) : Math.min(3, l), h = Number.isFinite(c) ? Math.min(2, Math.max(1, c)) : 1, p = $(e.padding) ? e.padding : {}, g = {
1250
1333
  ...e,
1251
- background: Zn(e.background),
1334
+ background: dr(e.background),
1252
1335
  column_blocks: s,
1253
- column_gap: q(e.column_gap, zn, "lg"),
1254
- container_type: q(e.container_type, Kn, "container"),
1336
+ column_gap: B(e.column_gap, nr, "lg"),
1337
+ container_type: B(e.container_type, rr, "container"),
1255
1338
  padding: {
1256
- bottom: q(m.bottom, Ye, "xl"),
1257
- top: q(m.top, Ye, "xl")
1339
+ bottom: B(p.bottom, rt, "xl"),
1340
+ top: B(p.top, rt, "xl")
1258
1341
  },
1259
- responsive_columns: { desktop: l, mobile: g, tablet: p },
1260
- vertical_alignment: q(
1342
+ responsive_columns: { desktop: l, mobile: h, tablet: m },
1343
+ vertical_alignment: B(
1261
1344
  e.vertical_alignment,
1262
- Vn,
1345
+ or,
1263
1346
  r ? "center" : "start"
1264
1347
  )
1265
1348
  };
1266
- return f.slider === !0 && !(Array.isArray(f.slides) && f.slides.length > 0) && (f.slider = !1), f;
1349
+ return g.slider === !0 && !(Array.isArray(g.slides) && g.slides.length > 0) && (g.slider = !1), g;
1267
1350
  }
1268
- function It(e, t, n, r) {
1351
+ function Ut(e, t, n, r) {
1269
1352
  if (e === "section") {
1270
- const a = er(t, n, r);
1271
- return L(e, a, n, r), a;
1353
+ const a = pr(t, n, r);
1354
+ return D(e, a, n, r), a;
1272
1355
  }
1273
- const o = H(t);
1274
- if (e === "heading" && (o.text_content = x(o.text_content) || x(o.text) || x(o.title) || x(o.heading) || "Untitled", o.level = typeof o.level == "number" ? o.level : 1), e === "text") {
1275
- const a = x(o.html_content) || x(o.html) || x(o.content) || x(o.text);
1276
- a && (o.html_content = /<\/?[a-z][\s\S]*>/i.test(a) ? a : `<p>${Mn(a)}</p>`);
1356
+ const o = z(t);
1357
+ if (e === "heading" && (o.text_content = v(o.text_content) || v(o.text) || v(o.title) || v(o.heading) || "Untitled", o.level = typeof o.level == "number" ? o.level : 1), e === "text") {
1358
+ const a = v(o.html_content) || v(o.html) || v(o.content) || v(o.text);
1359
+ a && (o.html_content = /<\/?[a-z][\s\S]*>/i.test(a) ? a : `<p>${Zn(a)}</p>`);
1277
1360
  }
1278
- return e === "button" && (o.text = x(o.text) || x(o.label) || x(o.title) || "Learn More", o.url = x(o.url) || x(o.href) || x(o.link) || "#"), e === "form" && (o.fields = Gn(o.fields), o.submit_button_text = x(o.submit_button_text ?? o.submitButtonText ?? o.button_text) || "Send Message", o.success_message = x(o.success_message ?? o.successMessage) || "Thanks for reaching out. We will reply as soon as possible."), L(e, o, n, r), o;
1361
+ return e === "button" && (o.text = v(o.text) || v(o.label) || v(o.title) || "Learn More", o.url = v(o.url) || v(o.href) || v(o.link) || "#"), e === "form" && (o.fields = tr(o.fields), o.submit_button_text = v(o.submit_button_text ?? o.submitButtonText ?? o.button_text) || "Send Message", o.success_message = v(o.success_message ?? o.successMessage) || "Thanks for reaching out. We will reply as soon as possible."), D(e, o, n, r), o;
1279
1362
  }
1280
- function ae(e, t, n) {
1281
- const r = It(
1363
+ function ce(e, t, n) {
1364
+ const r = Ut(
1282
1365
  e.blockType,
1283
- X(e.content, `Block ${t}`),
1366
+ ee(e.content, `Block ${t}`),
1284
1367
  `Block ${t}`,
1285
1368
  n
1286
1369
  );
@@ -1290,9 +1373,9 @@ function ae(e, t, n) {
1290
1373
  order: e.order ?? t
1291
1374
  };
1292
1375
  }
1293
- function tr(e, t = "Contact Us", n) {
1376
+ function mr(e, t = "Contact Us", n) {
1294
1377
  return [
1295
- ae(
1378
+ ce(
1296
1379
  {
1297
1380
  blockType: "section",
1298
1381
  content: {
@@ -1307,14 +1390,14 @@ function tr(e, t = "Contact Us", n) {
1307
1390
  textAlign: "center",
1308
1391
  text_content: t
1309
1392
  },
1310
- temp_id: oe("heading")
1393
+ temp_id: se("heading")
1311
1394
  },
1312
1395
  {
1313
1396
  block_type: "text",
1314
1397
  content: {
1315
1398
  html_content: "<p>Have a question, project, or support request? Send us a note and we will get back to you soon.</p>"
1316
1399
  },
1317
- temp_id: oe("text")
1400
+ temp_id: se("text")
1318
1401
  }
1319
1402
  ]
1320
1403
  ],
@@ -1328,7 +1411,7 @@ function tr(e, t = "Contact Us", n) {
1328
1411
  0,
1329
1412
  n
1330
1413
  ),
1331
- ae(
1414
+ ce(
1332
1415
  {
1333
1416
  blockType: "form",
1334
1417
  content: {
@@ -1365,13 +1448,13 @@ function tr(e, t = "Contact Us", n) {
1365
1448
  )
1366
1449
  ];
1367
1450
  }
1368
- function qe(e, t, n, r) {
1369
- return (!e || e.length === 0) && t ? tr(t, n, r) : (e || []).map((o, a) => ae(o, a, r));
1451
+ function Se(e, t, n, r) {
1452
+ return (!e || e.length === 0) && t ? mr(t, n, r) : (e || []).map((o, a) => ce(o, a, r));
1370
1453
  }
1371
- async function Be(e) {
1454
+ async function De(e) {
1372
1455
  const t = e.contentType === "page" ? "pages" : e.contentType === "post" ? "posts" : "products", { data: n, error: r } = await e.supabase.from(t).select("id, title, slug, language_id").eq("slug", e.slug).eq("language_id", e.languageId);
1373
1456
  if (r)
1374
- throw new Error(`Failed to check ${e.contentType} slug uniqueness: ${h(r)}`);
1457
+ throw new Error(`Failed to check ${e.contentType} slug uniqueness: ${_(r)}`);
1375
1458
  const o = Array.isArray(n) ? n : [];
1376
1459
  return o.length > 0 ? {
1377
1460
  duplicate: !0,
@@ -1381,7 +1464,7 @@ async function Be(e) {
1381
1464
  message: `A ${e.contentType} with slug "${e.slug}" already exists for this language.`
1382
1465
  } : null;
1383
1466
  }
1384
- async function Le(e) {
1467
+ async function ze(e) {
1385
1468
  if (!e.suppliedTranslationGroupId)
1386
1469
  return {
1387
1470
  translationGroupId: void 0
@@ -1389,7 +1472,7 @@ async function Le(e) {
1389
1472
  const t = e.contentType === "page" ? "pages" : e.contentType === "post" ? "posts" : "products", { data: n, error: r } = await e.supabase.from(t).select("id, title, slug, language_id, translation_group_id").eq("translation_group_id", e.suppliedTranslationGroupId);
1390
1473
  if (r)
1391
1474
  throw new Error(
1392
- `Failed to inspect ${e.contentType} translation group: ${h(r)}`
1475
+ `Failed to inspect ${e.contentType} translation group: ${_(r)}`
1393
1476
  );
1394
1477
  const o = Array.isArray(n) ? n : [];
1395
1478
  if (o.length === 0)
@@ -1417,7 +1500,7 @@ async function Le(e) {
1417
1500
  translationGroupId: e.suppliedTranslationGroupId
1418
1501
  };
1419
1502
  }
1420
- async function Tt(e) {
1503
+ async function Ge(e) {
1421
1504
  if (e.blocks.length === 0)
1422
1505
  return [];
1423
1506
  const t = e.blocks.map((o, a) => ({
@@ -1426,25 +1509,26 @@ async function Tt(e) {
1426
1509
  language_id: e.languageId,
1427
1510
  order: o.order ?? a,
1428
1511
  page_id: e.contentType === "page" ? e.itemId : null,
1429
- post_id: e.contentType === "post" ? e.itemId : null
1512
+ post_id: e.contentType === "post" ? e.itemId : null,
1513
+ product_id: e.contentType === "product" ? e.itemId : null
1430
1514
  })), { data: n, error: r } = await e.supabase.from("blocks").insert(t).select("*");
1431
1515
  if (r)
1432
- throw new Error(`Failed to insert ${e.contentType} blocks: ${h(r)}`);
1433
- return Ie(e.blocks, e.supabase), Array.isArray(n) ? n : [];
1516
+ throw new Error(`Failed to insert ${e.contentType} blocks: ${_(r)}`);
1517
+ return ve(e.blocks, e.supabase), Array.isArray(n) ? n : [];
1434
1518
  }
1435
- async function xt(e) {
1436
- const t = e.contentType === "page" ? "pages" : "posts";
1519
+ async function Ke(e) {
1520
+ const t = e.contentType === "page" ? "pages" : e.contentType === "post" ? "posts" : "products";
1437
1521
  await e.supabase.from(t).delete().eq("id", e.itemId);
1438
1522
  }
1439
- function Re(e, t) {
1523
+ function He(e, t) {
1440
1524
  return e === "page" ? `/cms/pages/${t}/edit` : e === "post" ? `/cms/posts/${t}/edit` : `/cms/products/${t}/edit`;
1441
1525
  }
1442
- function Xe(e) {
1526
+ function ot(e) {
1443
1527
  return e === "page" ? "/cms/pages" : e === "post" ? "/cms/posts" : "/cms/products";
1444
1528
  }
1445
- async function Ct(e, t) {
1446
- const n = se.parse(e), r = I(t);
1447
- n.mode === "replace" && await Bn({
1529
+ async function Ot(e, t) {
1530
+ const n = de.parse(e), r = C(t);
1531
+ n.mode === "replace" && await Yn({
1448
1532
  items: n.items,
1449
1533
  languageCode: n.languageCode,
1450
1534
  menuKey: "HEADER",
@@ -1464,35 +1548,35 @@ async function Ct(e, t) {
1464
1548
  });
1465
1549
  if (o)
1466
1550
  return o;
1467
- const a = n.mode === "update" ? await Ln({
1551
+ const a = n.mode === "update" ? await Xn({
1468
1552
  items: n.items,
1469
1553
  languageCode: n.languageCode,
1470
1554
  match: n.match,
1471
1555
  menuKey: "HEADER",
1472
1556
  supabase: r
1473
- }) : n.mode === "append" ? await Rn({
1557
+ }) : n.mode === "append" ? await Qn({
1474
1558
  items: n.items,
1475
1559
  languageCode: n.languageCode,
1476
1560
  menuKey: "HEADER",
1477
1561
  supabase: r
1478
- }) : await kt({
1562
+ }) : await Pt({
1479
1563
  items: n.items,
1480
1564
  languageCode: n.languageCode,
1481
1565
  menuKey: "HEADER",
1482
1566
  supabase: r
1483
1567
  });
1484
- return mt(t), {
1568
+ return xt(t), {
1485
1569
  ...a,
1486
1570
  mutationExecuted: !0,
1487
1571
  mode: n.mode,
1488
1572
  success: !0
1489
1573
  };
1490
1574
  }
1491
- async function vt(e, t) {
1492
- const n = le.parse(e);
1575
+ async function Ft(e, t) {
1576
+ const n = pe.parse(e);
1493
1577
  if (!n.links?.length && !n.copyright)
1494
1578
  throw new Error("update_footer requires links or copyright.");
1495
- const r = I(t), o = P({
1579
+ const r = C(t), o = P({
1496
1580
  action: "UPDATE FOOTER",
1497
1581
  context: t,
1498
1582
  payload: { input: n, tool: "update_footer" },
@@ -1507,7 +1591,7 @@ async function vt(e, t) {
1507
1591
  if (o)
1508
1592
  return o;
1509
1593
  let a = null;
1510
- if (n.links?.length && (a = await kt({
1594
+ if (n.links?.length && (a = await Pt({
1511
1595
  items: n.links,
1512
1596
  languageCode: n.languageCode,
1513
1597
  menuKey: "FOOTER",
@@ -1518,38 +1602,38 @@ async function vt(e, t) {
1518
1602
  value: n.copyright
1519
1603
  });
1520
1604
  if (s)
1521
- throw new Error(`Failed to update footer copyright: ${h(s)}`);
1605
+ throw new Error(`Failed to update footer copyright: ${_(s)}`);
1522
1606
  }
1523
- return mt(t), {
1607
+ return xt(t), {
1524
1608
  copyrightUpdated: !!n.copyright,
1525
1609
  footerNavigation: a,
1526
1610
  mutationExecuted: !0,
1527
1611
  success: !0
1528
1612
  };
1529
1613
  }
1530
- function St(e) {
1614
+ function jt(e) {
1531
1615
  return typeof e == "string" ? e.toLowerCase() : "";
1532
1616
  }
1533
- function nr(e, t) {
1534
- const n = t.map(St).join(" ");
1617
+ function gr(e, t) {
1618
+ const n = t.map(jt).join(" ");
1535
1619
  return e.reduce((r, o) => r + (n.includes(o) ? 1 : 0), 0);
1536
1620
  }
1537
- function Qe(e, t) {
1621
+ function it(e, t) {
1538
1622
  return (e.find(
1539
- (n) => t.some((r) => St(n).includes(r))
1623
+ (n) => t.some((r) => jt(n).includes(r))
1540
1624
  ) || e.find((n) => n.trim().length > 0) || "No excerpt available.").slice(0, 500);
1541
1625
  }
1542
- async function rr(e, t) {
1543
- const n = Pe.parse(e), r = I(t), o = n.query.toLowerCase().split(/\s+/).map((c) => c.trim()).filter(Boolean), [a, s] = await Promise.all([
1626
+ async function fr(e, t) {
1627
+ const n = je.parse(e), r = C(t), o = n.query.toLowerCase().split(/\s+/).map((c) => c.trim()).filter(Boolean), [a, s] = await Promise.all([
1544
1628
  r.from("posts").select("id, title, slug, excerpt, subtitle, meta_description, status, updated_at").eq("status", "published").limit(100),
1545
1629
  r.from("pages").select("id, title, slug, meta_description, status, updated_at").eq("status", "published").limit(100)
1546
1630
  ]);
1547
1631
  if (a.error)
1548
- throw new Error(`Failed to search documentation posts: ${h(a.error)}`);
1632
+ throw new Error(`Failed to search documentation posts: ${_(a.error)}`);
1549
1633
  if (s.error)
1550
- throw new Error(`Failed to search documentation pages: ${h(s.error)}`);
1634
+ throw new Error(`Failed to search documentation pages: ${_(s.error)}`);
1551
1635
  const l = (a.data ?? []).map((c) => ({
1552
- excerpt: Qe(
1636
+ excerpt: it(
1553
1637
  [c.excerpt, c.subtitle, c.meta_description, c.slug].filter(Boolean),
1554
1638
  o
1555
1639
  ),
@@ -1557,14 +1641,14 @@ async function rr(e, t) {
1557
1641
  title: c.title,
1558
1642
  url: `/article/${c.slug}`
1559
1643
  })), u = (s.data ?? []).map((c) => ({
1560
- excerpt: Qe([c.meta_description, c.slug].filter(Boolean), o),
1644
+ excerpt: it([c.meta_description, c.slug].filter(Boolean), o),
1561
1645
  source: "page",
1562
1646
  title: c.title,
1563
1647
  url: c.slug === "home" ? "/" : `/${c.slug}`
1564
1648
  })), d = [...l, ...u].map((c) => ({
1565
1649
  ...c,
1566
- score: nr(o, [c.title, c.excerpt, c.url])
1567
- })).filter((c) => c.score > 0).sort((c, p) => p.score - c.score).slice(0, n.limit).map((c) => ({
1650
+ score: gr(o, [c.title, c.excerpt, c.url])
1651
+ })).filter((c) => c.score > 0).sort((c, m) => m.score - c.score).slice(0, n.limit).map((c) => ({
1568
1652
  excerpt: c.excerpt,
1569
1653
  source: c.source,
1570
1654
  title: c.title,
@@ -1576,10 +1660,10 @@ async function rr(e, t) {
1576
1660
  success: !0
1577
1661
  };
1578
1662
  }
1579
- async function or(e, t, n = Wt) {
1580
- const r = Pe.safeParse(e), o = r.success ? r.data.query : "";
1581
- return hn(
1582
- rr(e, t),
1663
+ async function hr(e, t, n = ln) {
1664
+ const r = je.safeParse(e), o = r.success ? r.data.query : "";
1665
+ return En(
1666
+ fr(e, t),
1583
1667
  n,
1584
1668
  () => ({
1585
1669
  message: "Documentation search took too long to respond. Please try again or ask a more specific question.",
@@ -1590,7 +1674,7 @@ async function or(e, t, n = Wt) {
1590
1674
  })
1591
1675
  );
1592
1676
  }
1593
- const ir = [
1677
+ const yr = [
1594
1678
  "pending",
1595
1679
  "trial",
1596
1680
  "paid",
@@ -1598,7 +1682,7 @@ const ir = [
1598
1682
  "cancelled",
1599
1683
  "refunded",
1600
1684
  "failed"
1601
- ], ar = {
1685
+ ], _r = {
1602
1686
  awaiting: "pending",
1603
1687
  canceled: "cancelled",
1604
1688
  cancelled: "cancelled",
@@ -1615,34 +1699,34 @@ const ir = [
1615
1699
  trial: "trial",
1616
1700
  trials: "trial"
1617
1701
  };
1618
- function sr(e) {
1702
+ function br(e) {
1619
1703
  return String(e ?? "unknown").trim().toLowerCase() || "unknown";
1620
1704
  }
1621
- function Ze(e) {
1705
+ function at(e) {
1622
1706
  const t = Object.fromEntries(
1623
- ir.map((n) => [n, 0])
1707
+ yr.map((n) => [n, 0])
1624
1708
  );
1625
1709
  for (const n of e) {
1626
- const r = sr(n.status);
1710
+ const r = br(n.status);
1627
1711
  t[r] = (t[r] ?? 0) + 1;
1628
1712
  }
1629
1713
  return t;
1630
1714
  }
1631
- function lr(e) {
1715
+ function kr(e) {
1632
1716
  const n = e.toLowerCase().replace(/[^a-z0-9_]+/g, " ").split(/\s+/).filter(Boolean);
1633
1717
  for (const r of n) {
1634
- const o = ar[r];
1718
+ const o = _r[r];
1635
1719
  if (o)
1636
1720
  return o;
1637
1721
  }
1638
1722
  return null;
1639
1723
  }
1640
- function V(e) {
1724
+ function X(e) {
1641
1725
  const t = Number(e);
1642
1726
  return Number.isFinite(t) ? t : 0;
1643
1727
  }
1644
- async function cr(e, t) {
1645
- const n = at.parse(e), r = I(t), o = /* @__PURE__ */ new Date();
1728
+ async function wr(e, t) {
1729
+ const n = ft.parse(e), r = C(t), o = /* @__PURE__ */ new Date();
1646
1730
  let a = null, s = null;
1647
1731
  switch (n.timeRange) {
1648
1732
  case "today":
@@ -1667,9 +1751,9 @@ async function cr(e, t) {
1667
1751
  a = null;
1668
1752
  break;
1669
1753
  }
1670
- const l = n.currency?.toUpperCase(), u = lr(n.query), d = r.from("orders").select("id, status, total, currency, created_at, paid_at");
1754
+ const l = n.currency?.toUpperCase(), u = kr(n.query), d = r.from("orders").select("id, status, total, currency, created_at, paid_at");
1671
1755
  l && d.eq("currency", l), a && d.gte("created_at", a.toISOString()), s && d.lte("created_at", s.toISOString());
1672
- const p = n.reportType === "products" || n.reportType === "revenue" || n.reportType === "general" ? r.from("order_items").select(`
1756
+ const m = n.reportType === "products" || n.reportType === "revenue" || n.reportType === "general" ? r.from("order_items").select(`
1673
1757
  quantity,
1674
1758
  price_at_purchase,
1675
1759
  products!inner (
@@ -1684,83 +1768,83 @@ async function cr(e, t) {
1684
1768
  currency
1685
1769
  )
1686
1770
  `).eq("orders.status", "paid") : null;
1687
- p && (l && p.eq("orders.currency", l), a && p.gte("orders.paid_at", a.toISOString()), s && p.lte("orders.paid_at", s.toISOString()));
1688
- const m = n.timeRange !== "all_time" && (n.reportType === "orders" || u) ? r.from("orders").select("id, status, currency") : null;
1689
- m && l && m.eq("currency", l);
1771
+ m && (l && m.eq("orders.currency", l), a && m.gte("orders.paid_at", a.toISOString()), s && m.lte("orders.paid_at", s.toISOString()));
1772
+ const p = n.timeRange !== "all_time" && (n.reportType === "orders" || u) ? r.from("orders").select("id, status, currency") : null;
1773
+ p && l && p.eq("currency", l);
1690
1774
  const [
1691
- { data: f, error: _ },
1692
- { data: k, error: w },
1693
- E
1775
+ { data: g, error: f },
1776
+ { data: k, error: y },
1777
+ w
1694
1778
  ] = await Promise.all([
1695
1779
  d,
1696
- p ?? Promise.resolve({ data: [], error: null }),
1697
- m ?? Promise.resolve({ data: null, error: null })
1780
+ m ?? Promise.resolve({ data: [], error: null }),
1781
+ p ?? Promise.resolve({ data: null, error: null })
1698
1782
  ]);
1699
- if (_)
1700
- throw new Error(`Failed to fetch ecommerce stats: ${h(_)}`);
1701
- if (w)
1702
- throw new Error(`Failed to fetch ecommerce stats: ${h(w)}`);
1703
- if (E.error)
1704
- throw new Error(`Failed to fetch ecommerce stats: ${h(E.error)}`);
1705
- const y = Array.isArray(f) ? f : [], C = Array.isArray(k) ? k : [], v = Ze(y), S = Array.isArray(E.data) ? E.data : null, j = S ? Ze(S) : null, B = {};
1706
- for (const b of C) {
1707
- const $ = Array.isArray(b.orders) ? b.orders[0] : b.orders, O = String($?.currency || l || "unknown").toUpperCase();
1708
- B[O] = (B[O] ?? 0) + V(b.quantity) * V(b.price_at_purchase) / 100;
1783
+ if (f)
1784
+ throw new Error(`Failed to fetch ecommerce stats: ${_(f)}`);
1785
+ if (y)
1786
+ throw new Error(`Failed to fetch ecommerce stats: ${_(y)}`);
1787
+ if (w.error)
1788
+ throw new Error(`Failed to fetch ecommerce stats: ${_(w.error)}`);
1789
+ const b = Array.isArray(g) ? g : [], I = Array.isArray(k) ? k : [], x = at(b), E = Array.isArray(w.data) ? w.data : null, L = E ? at(E) : null, q = {};
1790
+ for (const T of I) {
1791
+ const A = Array.isArray(T.orders) ? T.orders[0] : T.orders, j = String(A?.currency || l || "unknown").toUpperCase();
1792
+ q[j] = (q[j] ?? 0) + X(T.quantity) * X(T.price_at_purchase) / 100;
1709
1793
  }
1710
- const z = {
1794
+ const W = {
1711
1795
  currency: l ?? null,
1712
1796
  currencyFiltered: !!l,
1713
- orderStatusCounts: v,
1714
- paidOrderCount: v.paid ?? 0,
1797
+ orderStatusCounts: x,
1798
+ paidOrderCount: x.paid ?? 0,
1715
1799
  query: n.query,
1716
1800
  reportType: n.reportType,
1717
- revenueByCurrency: B,
1801
+ revenueByCurrency: q,
1718
1802
  timeRange: n.timeRange,
1719
- totalOrders: y.length,
1720
- totalRevenue: Object.values(B).reduce(
1721
- (b, $) => b + $,
1803
+ totalOrders: b.length,
1804
+ totalRevenue: Object.values(q).reduce(
1805
+ (T, A) => T + A,
1722
1806
  0
1723
1807
  )
1724
1808
  };
1725
- if (j && (z.allTimeOrderStatusCounts = j), u && (z.matchingOrderStatus = {
1726
- allTimeCount: j?.[u] ?? v[u] ?? 0,
1727
- count: v[u] ?? 0,
1809
+ if (L && (W.allTimeOrderStatusCounts = L), u && (W.matchingOrderStatus = {
1810
+ allTimeCount: L?.[u] ?? x[u] ?? 0,
1811
+ count: x[u] ?? 0,
1728
1812
  status: u,
1729
1813
  timeRange: n.timeRange
1730
1814
  }), n.reportType === "products" || n.reportType === "revenue" || n.reportType === "general") {
1731
- const b = {};
1732
- for (const $ of C) {
1733
- const O = Array.isArray($.products) ? $.products[0] : $.products;
1734
- if (!O?.id)
1815
+ const T = {};
1816
+ for (const A of I) {
1817
+ const j = Array.isArray(A.products) ? A.products[0] : A.products;
1818
+ if (!j?.id)
1735
1819
  continue;
1736
- const K = O.id;
1737
- b[K] || (b[K] = {
1738
- id: K,
1820
+ const Y = j.id;
1821
+ T[Y] || (T[Y] = {
1822
+ id: Y,
1739
1823
  quantity: 0,
1740
1824
  revenue: 0,
1741
- title: O.title,
1742
- type: O.product_type
1743
- }), b[K].quantity += V($.quantity), b[K].revenue += V($.quantity) * V($.price_at_purchase) / 100;
1825
+ title: j.title,
1826
+ type: j.product_type
1827
+ }), T[Y].quantity += X(A.quantity), T[Y].revenue += X(A.quantity) * X(A.price_at_purchase) / 100;
1744
1828
  }
1745
- z.topProducts = Object.values(b).sort(($, O) => O.revenue - $.revenue).slice(0, 10);
1829
+ W.topProducts = Object.values(T).sort((A, j) => j.revenue - A.revenue).slice(0, 10);
1746
1830
  }
1747
1831
  return {
1748
- report: z,
1832
+ report: W,
1749
1833
  success: !0
1750
1834
  };
1751
1835
  }
1752
- async function ur(e, t) {
1753
- const n = lt.parse(e), r = I(t), o = D(t), a = be(o), s = o.contentType === "page" ? "pages" : o.contentType === "post" ? "posts" : "products", { data: l, error: u } = await r.from(s).select("*").eq("id", a).single();
1836
+ async function Ir(e, t) {
1837
+ const n = yt.parse(e), r = C(t), o = V(t), a = Te(o), s = o.contentType === "page" ? "pages" : o.contentType === "post" ? "posts" : "products", { data: l, error: u } = await r.from(s).select("*").eq("id", a).single();
1754
1838
  if (u || !l)
1755
1839
  throw new Error(
1756
- `Failed to read current ${o.contentType}: ${h(u)}`
1840
+ `Failed to read current ${o.contentType}: ${_(u)}`
1757
1841
  );
1758
1842
  let d = [];
1759
- if (n.includeBlocks && o.contentType !== "product") {
1760
- const c = o.contentType === "page" ? "page_id" : "post_id", { data: p, error: g } = await r.from("blocks").select("id, page_id, post_id, language_id, block_type, content, order").eq(c, a);
1761
- if (g)
1762
- throw new Error(`Failed to read current ${o.contentType} blocks: ${h(g)}`);
1763
- d = (Array.isArray(p) ? p : []).slice().sort((m, f) => Number(m.order) - Number(f.order)).map((m) => Fn(m, n.includeBlockContent));
1843
+ if (n.includeBlocks) {
1844
+ const c = o.contentType === "page" ? "page_id" : o.contentType === "post" ? "post_id" : "product_id", { data: m, error: h } = await r.from("blocks").select("id, page_id, post_id, product_id, language_id, block_type, content, order").eq(c, a);
1845
+ if (h)
1846
+ throw new Error(`Failed to read current ${o.contentType} blocks: ${_(h)}`);
1847
+ d = (Array.isArray(m) ? m : []).slice().sort((p, g) => Number(p.order) - Number(g.order)).map((p) => Hn(p, n.includeBlockContent));
1764
1848
  }
1765
1849
  return {
1766
1850
  blocks: d,
@@ -1769,7 +1853,7 @@ async function ur(e, t) {
1769
1853
  success: !0
1770
1854
  };
1771
1855
  }
1772
- const Et = /* @__PURE__ */ new Set([
1856
+ const Lt = /* @__PURE__ */ new Set([
1773
1857
  "feature_image_id",
1774
1858
  "language_id",
1775
1859
  "meta_description",
@@ -1777,7 +1861,7 @@ const Et = /* @__PURE__ */ new Set([
1777
1861
  "slug",
1778
1862
  "status",
1779
1863
  "title"
1780
- ]), $t = /* @__PURE__ */ new Set([
1864
+ ]), Bt = /* @__PURE__ */ new Set([
1781
1865
  "excerpt",
1782
1866
  "feature_image_id",
1783
1867
  "label",
@@ -1789,7 +1873,7 @@ const Et = /* @__PURE__ */ new Set([
1789
1873
  "status",
1790
1874
  "subtitle",
1791
1875
  "title"
1792
- ]), dr = /* @__PURE__ */ new Set([
1876
+ ]), Tr = /* @__PURE__ */ new Set([
1793
1877
  "description_json",
1794
1878
  "language_id",
1795
1879
  "meta_description",
@@ -1798,7 +1882,7 @@ const Et = /* @__PURE__ */ new Set([
1798
1882
  "slug",
1799
1883
  "status",
1800
1884
  "title"
1801
- ]), pr = /* @__PURE__ */ new Set([
1885
+ ]), xr = /* @__PURE__ */ new Set([
1802
1886
  "excerpt",
1803
1887
  "feature_image_id",
1804
1888
  "label",
@@ -1808,13 +1892,13 @@ const Et = /* @__PURE__ */ new Set([
1808
1892
  "short_description",
1809
1893
  "subtitle"
1810
1894
  ]);
1811
- function mr(e) {
1812
- return e === "page" ? Et : e === "post" ? $t : dr;
1895
+ function Cr(e) {
1896
+ return e === "page" ? Lt : e === "post" ? Bt : Tr;
1813
1897
  }
1814
- function At(e, t) {
1815
- return pr.has(e) && t === "" ? null : t;
1898
+ function Rt(e, t) {
1899
+ return xr.has(e) && t === "" ? null : t;
1816
1900
  }
1817
- function Se(e, t) {
1901
+ function Ne(e, t) {
1818
1902
  if (typeof t != "string")
1819
1903
  return;
1820
1904
  const n = e === "product" ? ["active", "archived", "draft"] : ["archived", "draft", "published"];
@@ -1823,20 +1907,20 @@ function Se(e, t) {
1823
1907
  `Status "${t}" is not valid for ${e}. Allowed statuses: ${n.join(", ")}.`
1824
1908
  );
1825
1909
  }
1826
- function gr(e, t) {
1827
- const n = mr(t.contentType), r = {};
1910
+ function Sr(e, t) {
1911
+ const n = Cr(t.contentType), r = {};
1828
1912
  for (const [o, a] of Object.entries(e))
1829
1913
  if (a !== void 0) {
1830
1914
  if (!n.has(o))
1831
1915
  throw new Error(
1832
1916
  `Field "${o}" cannot be updated for ${t.contentType} content.`
1833
1917
  );
1834
- o === "status" && Se(t.contentType, a), r[o] = At(o, a);
1918
+ o === "status" && Ne(t.contentType, a), r[o] = Rt(o, a);
1835
1919
  }
1836
1920
  return r;
1837
1921
  }
1838
- async function Pt(e, t) {
1839
- const n = ce.parse(e), r = I(t), o = D(t), a = be(o), s = gr(n.fields, o), l = Object.keys(s);
1922
+ async function qt(e, t) {
1923
+ const n = me.parse(e), r = C(t), o = V(t), a = Te(o), s = Sr(n.fields, o), l = Object.keys(s);
1840
1924
  if (l.length === 0)
1841
1925
  throw new Error("update_current_cms_fields requires at least one supported field.");
1842
1926
  const u = P({
@@ -1859,20 +1943,20 @@ async function Pt(e, t) {
1859
1943
  });
1860
1944
  if (u)
1861
1945
  return u;
1862
- typeof s.feature_image_id == "string" && (s.feature_image_id = await J(
1946
+ typeof s.feature_image_id == "string" && (s.feature_image_id = await Z(
1863
1947
  s.feature_image_id,
1864
1948
  t,
1865
1949
  typeof o.title == "string" ? o.title : void 0
1866
1950
  ));
1867
- const d = o.contentType === "page" ? "pages" : o.contentType === "post" ? "posts" : "products", { data: c, error: p } = await r.from(d).update({
1951
+ const d = o.contentType === "page" ? "pages" : o.contentType === "post" ? "posts" : "products", { data: c, error: m } = await r.from(d).update({
1868
1952
  ...s,
1869
1953
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
1870
1954
  }).eq("id", a).select("id, language_id, slug, status, title").single();
1871
- if (p || !c)
1955
+ if (m || !c)
1872
1956
  throw new Error(
1873
- `Failed to update current ${o.contentType}: ${h(p)}`
1957
+ `Failed to update current ${o.contentType}: ${_(m)}`
1874
1958
  );
1875
- return N(t, o, c.slug), {
1959
+ return U(t, o, c.slug), {
1876
1960
  contentType: o.contentType,
1877
1961
  entityId: a,
1878
1962
  mutationExecuted: !0,
@@ -1881,20 +1965,20 @@ async function Pt(e, t) {
1881
1965
  updatedFields: l
1882
1966
  };
1883
1967
  }
1884
- async function Nt(e, t) {
1885
- const n = ue.parse(e), r = I(t), o = D(t), { data: a, error: s } = await r.from("blocks").select("id, page_id, post_id, language_id, block_type, content, order").eq("id", n.blockId).single();
1968
+ async function Mt(e, t) {
1969
+ const n = ge.parse(e), r = C(t), o = V(t), { data: a, error: s } = await r.from("blocks").select("id, page_id, post_id, product_id, language_id, block_type, content, order").eq("id", n.blockId).single();
1886
1970
  if (s || !a)
1887
- throw new Error(`Failed to read block ${n.blockId}: ${h(s)}`);
1888
- ht(a, o);
1889
- const l = re(a.block_type, `Block ${n.blockId}`);
1890
- _t(n.blockType, l, `Block ${n.blockId}`);
1891
- const u = X(a.content, `Block ${n.blockId}`), d = Un(
1971
+ throw new Error(`Failed to read block ${n.blockId}: ${_(s)}`);
1972
+ vt(a, o);
1973
+ const l = ae(a.block_type, `Block ${n.blockId}`);
1974
+ Et(n.blockType, l, `Block ${n.blockId}`);
1975
+ const u = ee(a.content, `Block ${n.blockId}`), d = Kn(
1892
1976
  l,
1893
1977
  u,
1894
1978
  n.content,
1895
1979
  t
1896
1980
  );
1897
- L(l, d, `Block ${n.blockId}`, t);
1981
+ D(l, d, `Block ${n.blockId}`, t);
1898
1982
  const c = P({
1899
1983
  action: "UPDATE CONTENT BLOCK",
1900
1984
  context: t,
@@ -1908,64 +1992,69 @@ async function Nt(e, t) {
1908
1992
  blockId: n.blockId,
1909
1993
  blockType: l,
1910
1994
  contentType: o.contentType,
1911
- entityId: be(o)
1995
+ entityId: Te(o)
1912
1996
  },
1913
1997
  subject: `${l} block ${n.blockId}`
1914
1998
  });
1915
1999
  if (c)
1916
2000
  return c;
1917
- const { data: p, error: g } = await r.from("blocks").update({
2001
+ const { data: m, error: h } = await r.from("blocks").update({
1918
2002
  content: d,
1919
2003
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
1920
2004
  }).eq("id", n.blockId).select("id, block_type, order").single();
1921
- if (g || !p)
1922
- throw new Error(`Failed to update block ${n.blockId}: ${h(g)}`);
1923
- return Ie([{ content: d }], r), N(t, o), {
1924
- blockId: p.id,
1925
- blockType: p.block_type,
2005
+ if (h || !m)
2006
+ throw new Error(`Failed to update block ${n.blockId}: ${_(h)}`);
2007
+ return await xe({
2008
+ patch: ({ blocks: p }) => ({
2009
+ blocks: p.map(
2010
+ (g) => String(g?.id) === String(n.blockId) ? { ...g, content: d } : g
2011
+ )
2012
+ }),
2013
+ productId: a.product_id,
2014
+ supabase: r
2015
+ }), ve([{ content: d }], r), U(t, o), {
2016
+ blockId: m.id,
2017
+ blockType: m.block_type,
1926
2018
  contentUpdated: !0,
1927
2019
  mutationExecuted: !0,
1928
2020
  success: !0
1929
2021
  };
1930
2022
  }
1931
- async function Ut(e, t) {
1932
- const n = me.parse(e), r = I(t), o = await we(n, t);
1933
- if (o.contentType === "product")
1934
- throw new Error("Products do not have page/post content blocks in this editor context.");
1935
- const a = Number(o.item.id), s = o.contentType === "page" ? "page_id" : "post_id", l = async () => {
1936
- const { data: y, error: C } = await r.from("blocks").select("id, page_id, post_id, language_id, block_type, content, order").eq(s, a);
1937
- if (C)
1938
- throw new Error(`Failed to read ${o.contentType} blocks: ${h(C)}`);
1939
- return (Array.isArray(y) ? y : []).sort(
1940
- (v, S) => Number(v.order) - Number(S.order)
2023
+ async function Dt(e, t) {
2024
+ const n = ye.parse(e), r = C(t), o = await te(n, t), a = o.contentType === "product" ? o.item.id : Number(o.item.id), s = o.contentType === "page" ? "page_id" : o.contentType === "post" ? "post_id" : "product_id", l = async () => {
2025
+ const { data: b, error: I } = await r.from("blocks").select("id, page_id, post_id, product_id, language_id, block_type, content, order").eq(s, a);
2026
+ if (I)
2027
+ throw new Error(`Failed to read ${o.contentType} blocks: ${_(I)}`);
2028
+ return (Array.isArray(b) ? b : []).sort(
2029
+ (x, E) => Number(x.order) - Number(E.order)
1941
2030
  );
1942
- }, u = (y) => {
2031
+ }, u = (b) => {
1943
2032
  if (n.position === "start")
1944
2033
  return 0;
1945
2034
  if (n.position === "end") {
1946
- const S = y.map((j) => Number(j.order)).filter(Number.isFinite);
1947
- return S.length > 0 ? Math.max(...S) + 1 : 0;
2035
+ const E = b.map((L) => Number(L.order)).filter(Number.isFinite);
2036
+ return E.length > 0 ? Math.max(...E) + 1 : 0;
1948
2037
  }
1949
- const C = n.anchorBlockId ? y.find((S) => Number(S.id) === n.anchorBlockId) : n.anchorBlockType ? y.find((S) => S.block_type === n.anchorBlockType) : null;
1950
- if (!C)
2038
+ const I = n.anchorBlockId ? b.find((E) => Number(E.id) === n.anchorBlockId) : n.anchorBlockType ? b.find((E) => E.block_type === n.anchorBlockType) : null;
2039
+ if (!I)
1951
2040
  throw new Error(
1952
2041
  n.anchorBlockType ? `Could not find a ${n.anchorBlockType} block to insert ${n.position}.` : `Could not find block ${n.anchorBlockId} to insert ${n.position}.`
1953
2042
  );
1954
- const v = Number(C.order);
1955
- return n.position === "before" ? v : v + 1;
1956
- }, d = ae(n.block, 0, t), c = await l(), p = u(c), g = {
2043
+ const x = Number(I.order);
2044
+ return n.position === "before" ? x : x + 1;
2045
+ }, d = ce(n.block, 0, t), c = await l(), m = u(c), h = {
1957
2046
  contentType: o.contentType,
1958
2047
  entityId: o.item.id,
1959
2048
  languageId: o.item.language_id,
1960
2049
  slug: o.item.slug,
1961
2050
  title: o.item.title,
1962
2051
  translationGroupId: o.item.translation_group_id
1963
- }, m = P({
2052
+ }, p = P({
1964
2053
  action: "INSERT CONTENT BLOCK",
1965
2054
  context: t,
1966
2055
  payload: {
1967
2056
  block: d,
1968
- order: p,
2057
+ order: m,
1969
2058
  target: {
1970
2059
  contentType: o.contentType,
1971
2060
  id: o.item.id,
@@ -1986,45 +2075,66 @@ async function Ut(e, t) {
1986
2075
  },
1987
2076
  subject: `${d.block_type} block on ${o.contentType} ${o.item.id}`
1988
2077
  });
1989
- if (m)
1990
- return m;
1991
- const f = await l(), _ = u(f), k = f.filter((y) => Number(y.order) >= _).sort((y, C) => Number(C.order) - Number(y.order));
1992
- for (const y of k) {
1993
- const { error: C } = await r.from("blocks").update({
1994
- order: Number(y.order) + 1,
2078
+ if (p)
2079
+ return p;
2080
+ const g = await l(), f = u(g), k = g.filter((b) => Number(b.order) >= f).sort((b, I) => Number(I.order) - Number(b.order));
2081
+ for (const b of k) {
2082
+ const { error: I } = await r.from("blocks").update({
2083
+ order: Number(b.order) + 1,
1995
2084
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
1996
- }).eq("id", y.id);
1997
- if (C)
1998
- throw new Error(`Failed to shift block ${y.id}: ${h(C)}`);
2085
+ }).eq("id", b.id);
2086
+ if (I)
2087
+ throw new Error(`Failed to shift block ${b.id}: ${_(I)}`);
1999
2088
  }
2000
- const { data: w, error: E } = await r.from("blocks").insert({
2089
+ const { data: y, error: w } = await r.from("blocks").insert({
2001
2090
  block_type: d.block_type,
2002
2091
  content: d.content,
2003
2092
  language_id: o.item.language_id,
2004
- order: _,
2093
+ order: f,
2005
2094
  page_id: o.contentType === "page" ? a : null,
2006
- post_id: o.contentType === "post" ? a : null
2095
+ post_id: o.contentType === "post" ? a : null,
2096
+ product_id: o.contentType === "product" ? a : null
2007
2097
  }).select("id, block_type, order").single();
2008
- if (E || !w)
2009
- throw new Error(`Failed to insert content block: ${h(E)}`);
2010
- return Ie([d], r), N(t, g), {
2011
- blockId: w.id,
2012
- blockType: w.block_type,
2098
+ if (w || !y)
2099
+ throw new Error(`Failed to insert content block: ${_(w)}`);
2100
+ return o.contentType === "product" && await xe({
2101
+ patch: ({ blocks: b }) => ({
2102
+ blocks: [
2103
+ ...b.map(
2104
+ (I) => Number(I?.order) >= f ? { ...I, order: Number(I.order) + 1 } : I
2105
+ ),
2106
+ {
2107
+ block_type: d.block_type,
2108
+ content: d.content,
2109
+ id: y.id,
2110
+ language_id: o.item.language_id,
2111
+ order: f,
2112
+ page_id: null,
2113
+ post_id: null,
2114
+ product_id: a
2115
+ }
2116
+ ].sort((I, x) => Number(I.order) - Number(x.order))
2117
+ }),
2118
+ productId: a,
2119
+ supabase: r
2120
+ }), ve([d], r), U(t, h), {
2121
+ blockId: y.id,
2122
+ blockType: y.block_type,
2013
2123
  contentType: o.contentType,
2014
2124
  entityId: o.item.id,
2015
2125
  mutationExecuted: !0,
2016
- order: w.order,
2126
+ order: y.order,
2017
2127
  success: !0
2018
2128
  };
2019
2129
  }
2020
- async function Ft(e, t) {
2021
- const n = de.parse(e), r = I(t), o = D(t), { data: a, error: s } = await r.from("blocks").select("id, page_id, post_id, language_id, block_type, content, order").eq("id", n.parentBlockId).single();
2130
+ async function zt(e, t) {
2131
+ const n = fe.parse(e), r = C(t), o = V(t), { data: a, error: s } = await r.from("blocks").select("id, page_id, post_id, product_id, language_id, block_type, content, order").eq("id", n.parentBlockId).single();
2022
2132
  if (s || !a)
2023
2133
  throw new Error(
2024
- `Failed to read parent block ${n.parentBlockId}: ${h(s)}`
2134
+ `Failed to read parent block ${n.parentBlockId}: ${_(s)}`
2025
2135
  );
2026
- ht(a, o);
2027
- const l = re(
2136
+ vt(a, o);
2137
+ const l = ae(
2028
2138
  a.block_type,
2029
2139
  `Parent block ${n.parentBlockId}`
2030
2140
  );
@@ -2032,11 +2142,11 @@ async function Ft(e, t) {
2032
2142
  throw new Error(
2033
2143
  `Parent block ${n.parentBlockId} must be a section block, not "${l}".`
2034
2144
  );
2035
- const u = X(
2145
+ const u = ee(
2036
2146
  a.content,
2037
2147
  `Parent block ${n.parentBlockId}`
2038
2148
  );
2039
- L(
2149
+ D(
2040
2150
  l,
2041
2151
  u,
2042
2152
  `Parent block ${n.parentBlockId}`,
@@ -2047,79 +2157,87 @@ async function Ft(e, t) {
2047
2157
  throw new Error(
2048
2158
  `Nested block was not found at column ${n.columnIndex}, index ${n.blockIndex}.`
2049
2159
  );
2050
- const p = re(
2160
+ const m = ae(
2051
2161
  c.block_type,
2052
2162
  `Nested block ${n.columnIndex}:${n.blockIndex}`
2053
2163
  );
2054
- _t(
2164
+ Et(
2055
2165
  n.blockType,
2056
- p,
2166
+ m,
2057
2167
  `Nested block ${n.columnIndex}:${n.blockIndex}`
2058
- ), L(
2059
- p,
2168
+ ), D(
2169
+ m,
2060
2170
  n.content,
2061
2171
  `Nested block ${n.columnIndex}:${n.blockIndex}`,
2062
2172
  t
2063
2173
  );
2064
- const g = u.column_blocks.map(
2065
- (w, E) => E === n.columnIndex ? w.map(
2066
- (y, C) => C === n.blockIndex ? {
2067
- ...y,
2174
+ const h = u.column_blocks.map(
2175
+ (y, w) => w === n.columnIndex ? y.map(
2176
+ (b, I) => I === n.blockIndex ? {
2177
+ ...b,
2068
2178
  content: n.content
2069
- } : y
2070
- ) : w
2071
- ), m = {
2179
+ } : b
2180
+ ) : y
2181
+ ), p = {
2072
2182
  ...u,
2073
- column_blocks: g
2183
+ column_blocks: h
2074
2184
  };
2075
- L(
2185
+ D(
2076
2186
  l,
2077
- m,
2187
+ p,
2078
2188
  `Updated parent block ${n.parentBlockId}`,
2079
2189
  t
2080
2190
  );
2081
- const f = P({
2191
+ const g = P({
2082
2192
  action: "UPDATE NESTED BLOCK",
2083
2193
  context: t,
2084
2194
  payload: {
2085
2195
  blockIndex: n.blockIndex,
2086
2196
  columnIndex: n.columnIndex,
2087
2197
  content: n.content,
2088
- nestedBlockType: p,
2198
+ nestedBlockType: m,
2089
2199
  parentBlockId: n.parentBlockId,
2090
2200
  tool: "update_section_column_block"
2091
2201
  },
2092
2202
  preview: {
2093
2203
  blockIndex: n.blockIndex,
2094
2204
  columnIndex: n.columnIndex,
2095
- nestedBlockType: p,
2205
+ nestedBlockType: m,
2096
2206
  parentBlockId: n.parentBlockId,
2097
2207
  parentBlockType: l
2098
2208
  },
2099
- subject: `${p} nested block ${n.columnIndex}:${n.blockIndex}`
2209
+ subject: `${m} nested block ${n.columnIndex}:${n.blockIndex}`
2100
2210
  });
2101
- if (f)
2102
- return f;
2103
- const { data: _, error: k } = await r.from("blocks").update({
2104
- content: m,
2211
+ if (g)
2212
+ return g;
2213
+ const { data: f, error: k } = await r.from("blocks").update({
2214
+ content: p,
2105
2215
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
2106
2216
  }).eq("id", n.parentBlockId).select("id, block_type").single();
2107
- if (k || !_)
2217
+ if (k || !f)
2108
2218
  throw new Error(
2109
- `Failed to update parent block ${n.parentBlockId}: ${h(k)}`
2219
+ `Failed to update parent block ${n.parentBlockId}: ${_(k)}`
2110
2220
  );
2111
- return N(t, o), {
2221
+ return await xe({
2222
+ patch: ({ blocks: y }) => ({
2223
+ blocks: y.map(
2224
+ (w) => String(w?.id) === String(n.parentBlockId) ? { ...w, content: p } : w
2225
+ )
2226
+ }),
2227
+ productId: a.product_id,
2228
+ supabase: r
2229
+ }), U(t, o), {
2112
2230
  blockIndex: n.blockIndex,
2113
2231
  columnIndex: n.columnIndex,
2114
2232
  mutationExecuted: !0,
2115
- nestedBlockType: p,
2116
- parentBlockId: _.id,
2117
- parentBlockType: _.block_type,
2233
+ nestedBlockType: m,
2234
+ parentBlockId: f.id,
2235
+ parentBlockType: f.block_type,
2118
2236
  success: !0
2119
2237
  };
2120
2238
  }
2121
- async function Me(e, t) {
2122
- const n = ge.parse(e), r = I(t), o = Fe(t), a = await ke(r, n.languageCode), s = Y(n.slug || n.title), l = qe(n.blocks, n.contactEmail, n.title, t), u = await Be({
2239
+ async function Ve(e, t) {
2240
+ const n = _e.parse(e), r = C(t), o = Re(t), a = await Ce(r, n.languageCode), s = R(n.slug || n.title), l = Se(n.blocks, n.contactEmail, n.title, t), u = await De({
2123
2241
  contentType: "page",
2124
2242
  languageId: a.id,
2125
2243
  slug: s,
@@ -2127,7 +2245,7 @@ async function Me(e, t) {
2127
2245
  });
2128
2246
  if (u)
2129
2247
  return u;
2130
- const d = await Le({
2248
+ const d = await ze({
2131
2249
  contentType: "page",
2132
2250
  languageCode: a.code,
2133
2251
  languageId: a.id,
@@ -2149,7 +2267,7 @@ async function Me(e, t) {
2149
2267
  translation_group_id: d.translationGroupId
2150
2268
  },
2151
2269
  tool: "create_cms_page"
2152
- }, p = P({
2270
+ }, m = P({
2153
2271
  action: "CREATE PAGE",
2154
2272
  context: t,
2155
2273
  payload: c,
@@ -2163,49 +2281,49 @@ async function Me(e, t) {
2163
2281
  },
2164
2282
  subject: s
2165
2283
  });
2166
- if (p)
2167
- return p;
2168
- const g = d.translationGroupId || Oe(), m = await J(
2284
+ if (m)
2285
+ return m;
2286
+ const h = d.translationGroupId || qe(), p = await Z(
2169
2287
  c.item.feature_image_id,
2170
2288
  t,
2171
2289
  n.title
2172
- ), { data: f, error: _ } = await r.from("pages").insert({
2290
+ ), { data: g, error: f } = await r.from("pages").insert({
2173
2291
  ...c.item,
2174
2292
  author_id: o,
2175
- feature_image_id: m,
2176
- translation_group_id: g
2293
+ feature_image_id: p,
2294
+ translation_group_id: h
2177
2295
  }).select("id, language_id, slug, status, title, translation_group_id").single();
2178
- if (_ || !f?.id)
2179
- throw new Error(`Failed to create page: ${h(_)}`);
2296
+ if (f || !g?.id)
2297
+ throw new Error(`Failed to create page: ${_(f)}`);
2180
2298
  try {
2181
- await Tt({
2299
+ await Ge({
2182
2300
  blocks: l,
2183
2301
  contentType: "page",
2184
- itemId: Number(f.id),
2302
+ itemId: Number(g.id),
2185
2303
  languageId: a.id,
2186
2304
  supabase: r
2187
2305
  });
2188
2306
  } catch (k) {
2189
- throw await xt({ contentType: "page", itemId: Number(f.id), supabase: r }), k;
2307
+ throw await Ke({ contentType: "page", itemId: Number(g.id), supabase: r }), k;
2190
2308
  }
2191
- return N(
2309
+ return U(
2192
2310
  t,
2193
- { contentType: "page", entityId: Number(f.id), languageId: a.id, slug: s, title: n.title },
2311
+ { contentType: "page", entityId: Number(g.id), languageId: a.id, slug: s, title: n.title },
2194
2312
  s
2195
2313
  ), t?.revalidatePath?.("/cms/pages"), {
2196
2314
  blockCount: l.length,
2197
2315
  contentType: "page",
2198
- editPath: Re("page", f.id),
2199
- entityId: f.id,
2316
+ editPath: He("page", g.id),
2317
+ entityId: g.id,
2200
2318
  mutationExecuted: !0,
2201
2319
  slug: s,
2202
2320
  success: !0,
2203
2321
  title: n.title,
2204
- translationGroupId: f.translation_group_id
2322
+ translationGroupId: g.translation_group_id
2205
2323
  };
2206
2324
  }
2207
- async function De(e, t) {
2208
- const n = fe.parse(e), r = I(t), o = Fe(t), a = await ke(r, n.languageCode), s = Y(n.slug || n.title), l = qe(n.blocks, void 0, void 0, t), u = await Be({
2325
+ async function Je(e, t) {
2326
+ const n = be.parse(e), r = C(t), o = Re(t), a = await Ce(r, n.languageCode), s = R(n.slug || n.title), l = Se(n.blocks, void 0, void 0, t), u = await De({
2209
2327
  contentType: "post",
2210
2328
  languageId: a.id,
2211
2329
  slug: s,
@@ -2213,7 +2331,7 @@ async function De(e, t) {
2213
2331
  });
2214
2332
  if (u)
2215
2333
  return u;
2216
- const d = await Le({
2334
+ const d = await ze({
2217
2335
  contentType: "post",
2218
2336
  languageCode: a.code,
2219
2337
  languageId: a.id,
@@ -2222,7 +2340,7 @@ async function De(e, t) {
2222
2340
  });
2223
2341
  if (d.result)
2224
2342
  return d.result;
2225
- const c = n.published_at && !Number.isNaN(new Date(n.published_at).getTime()) ? new Date(n.published_at).toISOString() : n.published_at ?? null, p = {
2343
+ const c = n.published_at && !Number.isNaN(new Date(n.published_at).getTime()) ? new Date(n.published_at).toISOString() : n.published_at ?? null, m = {
2226
2344
  blocks: l,
2227
2345
  item: {
2228
2346
  excerpt: n.excerpt ?? null,
@@ -2239,10 +2357,10 @@ async function De(e, t) {
2239
2357
  translation_group_id: d.translationGroupId
2240
2358
  },
2241
2359
  tool: "create_cms_post"
2242
- }, g = P({
2360
+ }, h = P({
2243
2361
  action: "CREATE POST",
2244
2362
  context: t,
2245
- payload: p,
2363
+ payload: m,
2246
2364
  preview: {
2247
2365
  blockCount: l.length,
2248
2366
  languageCode: a.code,
@@ -2253,80 +2371,98 @@ async function De(e, t) {
2253
2371
  },
2254
2372
  subject: s
2255
2373
  });
2256
- if (g)
2257
- return g;
2258
- const m = d.translationGroupId || Oe(), f = await J(
2259
- p.item.feature_image_id,
2374
+ if (h)
2375
+ return h;
2376
+ const p = d.translationGroupId || qe(), g = await Z(
2377
+ m.item.feature_image_id,
2260
2378
  t,
2261
2379
  n.title
2262
- ), { data: _, error: k } = await r.from("posts").insert({
2263
- ...p.item,
2380
+ ), { data: f, error: k } = await r.from("posts").insert({
2381
+ ...m.item,
2264
2382
  author_id: o,
2265
- feature_image_id: f,
2266
- translation_group_id: m
2383
+ feature_image_id: g,
2384
+ translation_group_id: p
2267
2385
  }).select("id, language_id, slug, status, title, translation_group_id").single();
2268
- if (k || !_?.id)
2269
- throw new Error(`Failed to create post: ${h(k)}`);
2386
+ if (k || !f?.id)
2387
+ throw new Error(`Failed to create post: ${_(k)}`);
2270
2388
  try {
2271
- await Tt({
2389
+ await Ge({
2272
2390
  blocks: l,
2273
2391
  contentType: "post",
2274
- itemId: Number(_.id),
2392
+ itemId: Number(f.id),
2275
2393
  languageId: a.id,
2276
2394
  supabase: r
2277
2395
  });
2278
- } catch (w) {
2279
- throw await xt({ contentType: "post", itemId: Number(_.id), supabase: r }), w;
2396
+ } catch (y) {
2397
+ throw await Ke({ contentType: "post", itemId: Number(f.id), supabase: r }), y;
2280
2398
  }
2281
- return N(
2399
+ return U(
2282
2400
  t,
2283
- { contentType: "post", entityId: Number(_.id), languageId: a.id, slug: s, title: n.title },
2401
+ { contentType: "post", entityId: Number(f.id), languageId: a.id, slug: s, title: n.title },
2284
2402
  s
2285
2403
  ), t?.revalidatePath?.("/cms/posts"), t?.revalidatePath?.("/articles"), {
2286
2404
  blockCount: l.length,
2287
2405
  contentType: "post",
2288
- editPath: Re("post", _.id),
2289
- entityId: _.id,
2406
+ editPath: He("post", f.id),
2407
+ entityId: f.id,
2290
2408
  mutationExecuted: !0,
2291
2409
  slug: s,
2292
2410
  success: !0,
2293
2411
  title: n.title,
2294
- translationGroupId: _.translation_group_id
2412
+ translationGroupId: f.translation_group_id
2295
2413
  };
2296
2414
  }
2297
- function fr(e, t) {
2298
- return (t || Y(e) || "product").replace(/-/g, "").slice(0, 24).toUpperCase();
2415
+ function vr(e, t) {
2416
+ return (t || R(e) || "product").replace(/-/g, "").slice(0, 24).toUpperCase();
2299
2417
  }
2300
- function Ot(e) {
2301
- if (e === void 0)
2418
+ function Gt(e) {
2419
+ if (e == null)
2302
2420
  return;
2303
- const t = fn().safeParse(e);
2304
- if (!t.success)
2421
+ if (typeof e == "string")
2422
+ return pt(e) ?? void 0;
2423
+ const t = Array.isArray(e) ? { content: e, type: "doc" } : $(e) && e.type !== "doc" && Array.isArray(e.content) ? { ...e, type: "doc" } : e, n = et().safeParse(t);
2424
+ if (!n.success) {
2425
+ if ($(e) && typeof e.type == "string") {
2426
+ const r = et().safeParse({
2427
+ content: [e],
2428
+ type: "doc"
2429
+ });
2430
+ if (r.success)
2431
+ return r.data;
2432
+ }
2305
2433
  throw new Error(
2306
- `Product description_json failed editor document validation: ${t.error.issues.map((n) => n.message).join("; ")}`
2434
+ `Product description_json must be an editor document like { "type": "doc", "content": [ { "type": "paragraph", "content": [ { "type": "text", "text": "..." } ] } ] }, or simply an HTML string. Received: ${n.error.issues.map((r) => r.message).join("; ")}`
2307
2435
  );
2308
- return t.data;
2436
+ }
2437
+ return n.data;
2438
+ }
2439
+ function Er(e) {
2440
+ const t = (o) => !!(o && Array.isArray(o.content) && o.content.length > 0), n = Gt(e.description_json);
2441
+ if (t(n))
2442
+ return n;
2443
+ const r = e.description_html ? pt(e.description_html) : null;
2444
+ return t(r) ? r : void 0;
2309
2445
  }
2310
- async function jt(e, t) {
2311
- const n = he.parse(e), r = I(t), o = await ke(r, n.languageCode), a = Y(n.slug || n.title), s = await Be({
2446
+ async function Kt(e, t) {
2447
+ const n = ke.parse(e), r = C(t), o = await Ce(r, n.languageCode), a = R(n.slug || n.title), s = Se(n.blocks, void 0, void 0, t), l = await De({
2312
2448
  contentType: "product",
2313
2449
  languageId: o.id,
2314
2450
  slug: a,
2315
2451
  supabase: r
2316
2452
  });
2317
- if (s)
2318
- return s;
2319
- const l = await Le({
2453
+ if (l)
2454
+ return l;
2455
+ const u = await ze({
2320
2456
  contentType: "product",
2321
2457
  languageCode: o.code,
2322
2458
  languageId: o.id,
2323
2459
  suppliedTranslationGroupId: n.translationGroupId,
2324
2460
  supabase: r
2325
2461
  });
2326
- if (l.result)
2327
- return l.result;
2328
- const { createProduct: u, productSchema: d } = await In(), p = n.product_type === "digital" && n.payment_provider === "freemius" ? n.trial_period_days : 0, g = d.parse({
2329
- description_json: Ot(n.description_json),
2462
+ if (u.result)
2463
+ return u.result;
2464
+ const { createProduct: d, productSchema: c } = await On(), h = n.product_type === "digital" && n.payment_provider === "freemius" ? n.trial_period_days : 0, p = c.parse({
2465
+ description_json: Er(n),
2330
2466
  freemius_plan_id: n.freemius_plan_id || "",
2331
2467
  freemius_product_id: n.freemius_product_id || "",
2332
2468
  is_taxable: n.is_taxable,
@@ -2341,79 +2477,108 @@ async function jt(e, t) {
2341
2477
  sale_price: n.sale_price ?? null,
2342
2478
  sale_prices: n.sale_prices || {},
2343
2479
  short_description: n.short_description ?? "",
2344
- sku: n.sku || fr(n.title, a),
2480
+ sku: n.sku || vr(n.title, a),
2345
2481
  slug: a,
2346
2482
  status: n.status,
2347
2483
  stock: n.stock,
2348
2484
  title: n.title,
2349
- trial_period_days: p,
2350
- trial_requires_payment_method: p > 0 ? n.trial_requires_payment_method : !1,
2351
- translation_group_id: l.translationGroupId,
2485
+ trial_period_days: h,
2486
+ trial_requires_payment_method: h > 0 ? n.trial_requires_payment_method : !1,
2487
+ translation_group_id: u.translationGroupId,
2352
2488
  upc: n.upc ?? "",
2353
2489
  variation_attributes: [],
2354
2490
  variants: []
2355
- }), m = P({
2491
+ }), g = n.images ?? [], f = P({
2356
2492
  action: "CREATE PRODUCT",
2357
2493
  context: t,
2358
- payload: { item: g, tool: "create_cms_product" },
2494
+ payload: { blocks: s, images: g, item: p, tool: "create_cms_product" },
2359
2495
  preview: {
2496
+ blockCount: s.length,
2497
+ descriptionLength: p.description_json ? JSON.stringify(p.description_json).length : 0,
2498
+ imageCount: g.length,
2360
2499
  languageCode: o.code,
2361
- price: g.price,
2362
- sku: g.sku,
2500
+ price: p.price,
2501
+ sku: p.sku,
2363
2502
  slug: a,
2364
- status: g.status,
2365
- stock: g.stock,
2366
- title: g.title,
2367
- translationGroupId: l.translationGroupId
2503
+ status: p.status,
2504
+ stock: p.stock,
2505
+ title: p.title,
2506
+ translationGroupId: u.translationGroupId
2368
2507
  },
2369
2508
  subject: a
2370
2509
  });
2371
- if (m)
2372
- return m;
2373
- const f = await u(r, g);
2374
- if (!f?.id)
2510
+ if (f)
2511
+ return f;
2512
+ let k = [], y = null;
2513
+ if (g.length > 0)
2514
+ try {
2515
+ if (k = [...new Set(await It(g, t, n.title))], k.length === 0)
2516
+ throw new Error("None of the provided images could be resolved to a media item.");
2517
+ } catch (b) {
2518
+ y = b instanceof Error ? b.message : String(b);
2519
+ }
2520
+ const w = await d(r, {
2521
+ ...p,
2522
+ // First entry is the main product image; the rest become the gallery in order.
2523
+ product_media: k.map((b) => ({ media_id: b }))
2524
+ });
2525
+ if (!w?.id)
2375
2526
  throw new Error("Failed to create product.");
2376
- return N(
2527
+ try {
2528
+ await Ge({
2529
+ blocks: s,
2530
+ contentType: "product",
2531
+ itemId: w.id,
2532
+ languageId: o.id,
2533
+ supabase: r
2534
+ });
2535
+ } catch (b) {
2536
+ throw await Ke({ contentType: "product", itemId: w.id, supabase: r }), b;
2537
+ }
2538
+ return U(
2377
2539
  t,
2378
- { contentType: "product", entityId: f.id, languageId: o.id, slug: a, title: n.title },
2540
+ { contentType: "product", entityId: w.id, languageId: o.id, slug: a, title: n.title },
2379
2541
  a
2380
2542
  ), t?.revalidatePath?.("/cms/products"), {
2543
+ blockCount: s.length,
2381
2544
  contentType: "product",
2382
- editPath: Re("product", f.id),
2383
- entityId: f.id,
2545
+ editPath: He("product", w.id),
2546
+ entityId: w.id,
2547
+ imageCount: k.length,
2548
+ ...y ? { imageError: y } : {},
2384
2549
  mutationExecuted: !0,
2385
2550
  slug: a,
2386
2551
  success: !0,
2387
2552
  title: n.title,
2388
- translationGroupId: f.translation_group_id
2553
+ translationGroupId: w.translation_group_id
2389
2554
  };
2390
2555
  }
2391
- function Ge(e) {
2556
+ function We(e) {
2392
2557
  return e.trim().replace(/[\s-]+/g, "_").toLowerCase();
2393
2558
  }
2394
- function hr(e, t) {
2395
- const n = typeof t == "string" ? Ge(t) : t;
2559
+ function $r(e, t) {
2560
+ const n = typeof t == "string" ? We(t) : t;
2396
2561
  return e === "product" ? n === "public" || n === "publish" || n === "published" ? "active" : n : n === "public" || n === "active" || n === "publish" ? "published" : n;
2397
2562
  }
2398
- function _r(e) {
2399
- const t = Ge(e.field);
2563
+ function Ar(e) {
2564
+ const t = We(e.field);
2400
2565
  return !!(e.startsAt || e.endsAt || t.includes("start") || t.includes("end") || t.includes("schedule") || t.includes("special_date"));
2401
2566
  }
2402
- async function yr(e, t, n) {
2567
+ async function Pr(e, t, n) {
2403
2568
  if (e === "price" || e === "sale_price") {
2404
2569
  if (t == null)
2405
2570
  return { [e]: null };
2406
- const r = await Je(n);
2407
- return { [e]: ft(Number(t), r) };
2571
+ const r = await nt(n);
2572
+ return { [e]: St(Number(t), r) };
2408
2573
  }
2409
2574
  if (e === "prices" || e === "sale_prices") {
2410
- const r = await Je(n);
2411
- return { [e]: En(t, r) };
2575
+ const r = await nt(n);
2576
+ return { [e]: qn(t, r) };
2412
2577
  }
2413
- return e === "description_json" ? { description_json: Ot(t) } : { [e]: t };
2578
+ return e === "description_json" ? { description_json: Gt(t) } : { [e]: t };
2414
2579
  }
2415
- function br(e, t) {
2416
- const n = Ge(e.field), r = n === "status" ? hr(t.contentType, e.value) : e.value, a = {
2580
+ function Nr(e, t) {
2581
+ const n = We(e.field), r = n === "status" ? $r(t.contentType, e.value) : e.value, a = {
2417
2582
  description: "description_json",
2418
2583
  feature_image: "feature_image_id",
2419
2584
  feature_image_id: "feature_image_id",
@@ -2433,12 +2598,12 @@ function br(e, t) {
2433
2598
  type: "product_type"
2434
2599
  }[n] || n;
2435
2600
  if (t.contentType !== "product") {
2436
- if (!(t.contentType === "page" ? Et : $t).has(a))
2601
+ if (!(t.contentType === "page" ? Lt : Bt).has(a))
2437
2602
  throw new Error(`Field "${e.field}" cannot be updated for ${t.contentType}.`);
2438
- return a === "status" && Se(t.contentType, r), {
2603
+ return a === "status" && Ne(t.contentType, r), {
2439
2604
  field: a,
2440
2605
  payload: {
2441
- [a]: At(a, r)
2606
+ [a]: Rt(a, r)
2442
2607
  }
2443
2608
  };
2444
2609
  }
@@ -2467,7 +2632,7 @@ function br(e, t) {
2467
2632
  "upc"
2468
2633
  ])).has(a))
2469
2634
  throw new Error(`Field "${e.field}" cannot be updated for product.`);
2470
- if (a === "status" && Se("product", r), (a === "price" || a === "sale_price") && r !== null && (typeof r != "number" || r < 0))
2635
+ if (a === "status" && Ne("product", r), (a === "price" || a === "sale_price") && r !== null && (typeof r != "number" || r < 0))
2471
2636
  throw new Error(`${a} must be a non-negative number or null.`);
2472
2637
  if (a === "stock" && (!Number.isInteger(r) || Number(r) < 0))
2473
2638
  throw new Error("stock must be a non-negative integer.");
@@ -2482,22 +2647,22 @@ function br(e, t) {
2482
2647
  }
2483
2648
  };
2484
2649
  }
2485
- async function qt(e, t) {
2486
- const n = _e.parse(e);
2487
- if (_r(n))
2650
+ async function Ht(e, t) {
2651
+ const n = we.parse(e);
2652
+ if (Ar(n))
2488
2653
  return {
2489
2654
  message: "Scheduled product specials are not supported by the current product schema yet. I can set or clear sale_price now, but not start/end dates.",
2490
2655
  mutationExecuted: !1,
2491
2656
  success: !1,
2492
2657
  unsupported: !0
2493
2658
  };
2494
- const r = await we(n, t), o = br(n, r), a = o.field;
2659
+ const r = await te(n, t), o = Nr(n, r), a = o.field;
2495
2660
  let s = o.payload;
2496
2661
  if (a === "language_id" && typeof s.language_id == "string") {
2497
- const p = await G(I(t), s.language_id);
2662
+ const m = await J(C(t), s.language_id);
2498
2663
  s = {
2499
2664
  ...s,
2500
- language_id: p.id
2665
+ language_id: m.id
2501
2666
  };
2502
2667
  }
2503
2668
  const l = P({
@@ -2523,47 +2688,47 @@ async function qt(e, t) {
2523
2688
  if (l)
2524
2689
  return l;
2525
2690
  if (r.contentType === "product") {
2526
- const p = I(t), g = await yr(a, s[a], p), { data: m, error: f } = await p.from("products").update({
2527
- ...g,
2691
+ const m = C(t), h = await Pr(a, s[a], m), { data: p, error: g } = await m.from("products").update({
2692
+ ...h,
2528
2693
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
2529
2694
  }).eq("id", r.item.id).select("id, language_id, slug, status, title").single();
2530
- if (f || !m)
2531
- throw new Error(`Failed to update product: ${h(f)}`);
2532
- return N(
2695
+ if (g || !p)
2696
+ throw new Error(`Failed to update product: ${_(g)}`);
2697
+ return U(
2533
2698
  t,
2534
2699
  {
2535
2700
  contentType: "product",
2536
- entityId: String(m.id),
2537
- languageId: m.language_id,
2538
- slug: m.slug,
2539
- title: m.title
2701
+ entityId: String(p.id),
2702
+ languageId: p.language_id,
2703
+ slug: p.slug,
2704
+ title: p.title
2540
2705
  },
2541
- m.slug
2706
+ p.slug
2542
2707
  ), {
2543
2708
  contentType: "product",
2544
- entityId: m.id,
2709
+ entityId: p.id,
2545
2710
  field: a,
2546
2711
  mutationExecuted: !0,
2547
- slug: m.slug,
2712
+ slug: p.slug,
2548
2713
  success: !0,
2549
2714
  updatedFields: [a]
2550
2715
  };
2551
2716
  }
2552
2717
  a === "feature_image_id" && typeof s.feature_image_id == "string" && (s = {
2553
2718
  ...s,
2554
- feature_image_id: await J(
2719
+ feature_image_id: await Z(
2555
2720
  s.feature_image_id,
2556
2721
  t,
2557
2722
  typeof r.item.title == "string" ? r.item.title : void 0
2558
2723
  )
2559
2724
  });
2560
- const u = r.contentType === "page" ? "pages" : "posts", { data: d, error: c } = await I(t).from(u).update({
2725
+ const u = r.contentType === "page" ? "pages" : "posts", { data: d, error: c } = await C(t).from(u).update({
2561
2726
  ...s,
2562
2727
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
2563
2728
  }).eq("id", r.item.id).select("id, language_id, slug, status, title").single();
2564
2729
  if (c || !d)
2565
- throw new Error(`Failed to update ${r.contentType}: ${h(c)}`);
2566
- return N(
2730
+ throw new Error(`Failed to update ${r.contentType}: ${_(c)}`);
2731
+ return U(
2567
2732
  t,
2568
2733
  {
2569
2734
  contentType: r.contentType,
@@ -2583,53 +2748,53 @@ async function qt(e, t) {
2583
2748
  updatedFields: [a]
2584
2749
  };
2585
2750
  }
2586
- async function Bt(e, t) {
2587
- const n = ct.parse(e), r = await we(n, t);
2751
+ async function Vt(e, t) {
2752
+ const n = _t.parse(e), r = await te(n, t);
2588
2753
  if (r.contentType === "product")
2589
2754
  return {
2590
2755
  affectedCount: 1,
2591
- collectionPath: Xe("product"),
2756
+ collectionPath: ot("product"),
2592
2757
  contentType: "product",
2593
2758
  item: r.item,
2594
2759
  navigationLinkCount: 0,
2595
2760
  publicPaths: r.item.slug ? [`/product/${r.item.slug}`] : [],
2596
2761
  targetIds: [r.item.id]
2597
2762
  };
2598
- const o = r.contentType === "page" ? "pages" : "posts", { data: a, error: s } = await I(t).from(o).select("id, slug, title, translation_group_id").eq("translation_group_id", r.item.translation_group_id);
2763
+ const o = r.contentType === "page" ? "pages" : "posts", { data: a, error: s } = await C(t).from(o).select("id, slug, title, translation_group_id").eq("translation_group_id", r.item.translation_group_id);
2599
2764
  if (s)
2600
- throw new Error(`Failed to inspect related ${r.contentType}s: ${h(s)}`);
2765
+ throw new Error(`Failed to inspect related ${r.contentType}s: ${_(s)}`);
2601
2766
  const l = Array.isArray(a) ? a : [], u = l.map(
2602
- (m) => r.contentType === "page" ? m.slug === "home" ? "/" : `/${m.slug}` : `/article/${m.slug}`
2603
- ).filter(Boolean), d = new Set(u), { data: c, error: p } = await I(t).from("navigation_items").select("id, url");
2604
- if (p)
2605
- throw new Error(`Failed to inspect related navigation links: ${h(p)}`);
2606
- const g = (Array.isArray(c) ? c : []).filter(
2607
- (m) => d.has(m.url)
2767
+ (p) => r.contentType === "page" ? p.slug === "home" ? "/" : `/${p.slug}` : `/article/${p.slug}`
2768
+ ).filter(Boolean), d = new Set(u), { data: c, error: m } = await C(t).from("navigation_items").select("id, url");
2769
+ if (m)
2770
+ throw new Error(`Failed to inspect related navigation links: ${_(m)}`);
2771
+ const h = (Array.isArray(c) ? c : []).filter(
2772
+ (p) => d.has(p.url)
2608
2773
  ).length;
2609
2774
  return {
2610
2775
  affectedCount: l.length,
2611
- collectionPath: Xe(r.contentType),
2776
+ collectionPath: ot(r.contentType),
2612
2777
  contentType: r.contentType,
2613
2778
  item: r.item,
2614
- navigationLinkCount: g,
2779
+ navigationLinkCount: h,
2615
2780
  publicPaths: u,
2616
- targetIds: l.map((m) => m.id)
2781
+ targetIds: l.map((p) => p.id)
2617
2782
  };
2618
2783
  }
2619
- function Lt(e) {
2784
+ function Jt(e) {
2620
2785
  const t = e.item.title || e.item.slug || "selected item", n = e.item.slug ? ` (${e.item.slug})` : "";
2621
2786
  if (e.contentType === "product")
2622
2787
  return `Delete product "${t}"${n}.`;
2623
2788
  const r = [
2624
- `${F(e.affectedCount, "language version")}`,
2625
- e.navigationLinkCount > 0 ? `${F(e.navigationLinkCount, "navigation link")}` : null
2789
+ `${N(e.affectedCount, "language version")}`,
2790
+ e.navigationLinkCount > 0 ? `${N(e.navigationLinkCount, "navigation link")}` : null
2626
2791
  ].filter(Boolean);
2627
2792
  return `Delete ${e.contentType} "${t}"${n}, including ${r.join(" and ")}.`;
2628
2793
  }
2629
- async function kr(e, t) {
2630
- const n = await Bt(e, t);
2794
+ async function Ur(e, t) {
2795
+ const n = await Vt(e, t);
2631
2796
  return {
2632
- ...gt({
2797
+ ...Ct({
2633
2798
  action: `DELETE ${n.contentType}`,
2634
2799
  payload: {
2635
2800
  affectedCount: n.affectedCount,
@@ -2644,7 +2809,7 @@ async function kr(e, t) {
2644
2809
  navigationLinkCount: n.navigationLinkCount,
2645
2810
  publicPaths: n.publicPaths,
2646
2811
  slug: n.item.slug,
2647
- summary: Lt(n),
2812
+ summary: Jt(n),
2648
2813
  title: n.item.title
2649
2814
  },
2650
2815
  subject: `${n.item.id} ${n.item.slug || ""}`
@@ -2652,8 +2817,8 @@ async function kr(e, t) {
2652
2817
  preparedDelete: !0
2653
2818
  };
2654
2819
  }
2655
- async function Rt(e, t) {
2656
- const n = ye.parse(e), r = await Bt(n, t), o = P({
2820
+ async function Wt(e, t) {
2821
+ const n = Ie.parse(e), r = await Vt(n, t), o = P({
2657
2822
  action: `DELETE ${r.contentType}`,
2658
2823
  context: t,
2659
2824
  payload: {
@@ -2669,26 +2834,26 @@ async function Rt(e, t) {
2669
2834
  navigationLinkCount: r.navigationLinkCount,
2670
2835
  publicPaths: r.publicPaths,
2671
2836
  slug: r.item.slug,
2672
- summary: Lt(r),
2837
+ summary: Jt(r),
2673
2838
  title: r.item.title
2674
2839
  },
2675
2840
  subject: `${r.item.id} ${r.item.slug || ""}`
2676
2841
  });
2677
2842
  if (o)
2678
2843
  return o;
2679
- const a = I(t);
2844
+ const a = C(t);
2680
2845
  if (r.contentType === "product") {
2681
2846
  const { error: l } = await a.from("products").delete().eq("id", r.item.id);
2682
2847
  if (l)
2683
- throw new Error(`Failed to delete product: ${h(l)}`);
2848
+ throw new Error(`Failed to delete product: ${_(l)}`);
2684
2849
  } else {
2685
2850
  for (const d of r.publicPaths)
2686
2851
  await a.from("navigation_items").delete().eq("url", d);
2687
2852
  const l = r.contentType === "page" ? "pages" : "posts", { error: u } = await a.from(l).delete().eq("translation_group_id", r.item.translation_group_id);
2688
2853
  if (u)
2689
- throw new Error(`Failed to delete ${r.contentType}: ${h(u)}`);
2854
+ throw new Error(`Failed to delete ${r.contentType}: ${_(u)}`);
2690
2855
  }
2691
- const s = t?.revalidatePath ?? Ne();
2856
+ const s = t?.revalidatePath ?? Le();
2692
2857
  return s && (s(r.collectionPath), s("/cms/navigation"), r.publicPaths.forEach((l) => s(l))), {
2693
2858
  affectedCount: r.affectedCount,
2694
2859
  collectionPath: r.collectionPath,
@@ -2698,33 +2863,35 @@ async function Rt(e, t) {
2698
2863
  success: !0
2699
2864
  };
2700
2865
  }
2701
- async function et(e, t) {
2866
+ async function st(e, t) {
2702
2867
  switch (e.tool) {
2703
2868
  case "create_cms_page":
2704
- return Me(e.input, t);
2869
+ return Ve(e.input, t);
2705
2870
  case "create_cms_post":
2706
- return De(e.input, t);
2871
+ return Je(e.input, t);
2707
2872
  case "create_cms_product":
2708
- return jt(e.input, t);
2873
+ return Kt(e.input, t);
2709
2874
  case "delete_cms_item":
2710
- return Rt(e.input, t);
2875
+ return Wt(e.input, t);
2711
2876
  case "update_cms_item_field":
2712
- return qt(e.input, t);
2877
+ return Ht(e.input, t);
2713
2878
  case "update_content_block":
2714
- return Nt(e.input, t);
2879
+ return Mt(e.input, t);
2715
2880
  case "insert_content_block":
2716
- return Ut(e.input, t);
2881
+ return Dt(e.input, t);
2717
2882
  case "update_current_cms_fields":
2718
- return Pt(e.input, t);
2883
+ return qt(e.input, t);
2719
2884
  case "update_footer":
2720
- return vt(e.input, t);
2885
+ return Ft(e.input, t);
2721
2886
  case "update_navigation_bar":
2722
- return Ct(e.input, t);
2887
+ return Ot(e.input, t);
2723
2888
  case "update_section_column_block":
2724
- return Ft(e.input, t);
2889
+ return zt(e.input, t);
2890
+ case "set_content_images":
2891
+ return on(e.input, t);
2725
2892
  }
2726
2893
  }
2727
- function wr(e, t) {
2894
+ function Or(e, t) {
2728
2895
  if (e.tool !== "create_cms_page" && e.tool !== "create_cms_post" && e.tool !== "create_cms_product" || e.input.translationGroupId || !e.input.languageCode)
2729
2896
  return e;
2730
2897
  const n = t[e.tool];
@@ -2736,80 +2903,134 @@ function wr(e, t) {
2736
2903
  }
2737
2904
  } : e;
2738
2905
  }
2739
- async function Ir(e, t) {
2740
- const n = dt.parse(e);
2906
+ function lt(e) {
2907
+ return e === "create_cms_page" ? "page" : e === "create_cms_post" ? "post" : "product";
2908
+ }
2909
+ function Fr(e, t, n) {
2910
+ if (e.tool !== "set_content_images")
2911
+ return e;
2912
+ const r = e.input;
2913
+ if (r.entityId !== void 0)
2914
+ return e;
2915
+ const o = r.slug ? t.get(
2916
+ `${r.contentType || "product"}:${R(r.slug)}`
2917
+ ) : n;
2918
+ return o ? {
2919
+ ...e,
2920
+ input: {
2921
+ ...r,
2922
+ contentType: o.contentType,
2923
+ entityId: o.entityId
2924
+ }
2925
+ } : e;
2926
+ }
2927
+ async function jr(e, t) {
2928
+ const n = kt.parse(e), r = new Set(
2929
+ n.actions.filter(
2930
+ (p) => p.tool === "create_cms_page" || p.tool === "create_cms_post" || p.tool === "create_cms_product"
2931
+ ).map((p) => {
2932
+ const g = p.input;
2933
+ return `${lt(p.tool)}:${R(g.slug || g.title || "")}`;
2934
+ })
2935
+ ), o = (p) => {
2936
+ if (p.tool !== "set_content_images")
2937
+ return !1;
2938
+ const g = p.input;
2939
+ return g.slug ? r.has(
2940
+ `${g.contentType || "product"}:${R(g.slug)}`
2941
+ ) : r.size > 0;
2942
+ };
2741
2943
  if (!t?.skipConfirmation) {
2742
- const d = [];
2743
- for (const g of n.actions) {
2744
- const m = await et(g, {
2944
+ const p = [];
2945
+ for (const k of n.actions) {
2946
+ if (o(k)) {
2947
+ const w = k.input;
2948
+ p.push(
2949
+ `Set ${N(w.images.length, "image")} on the ${w.slug ? `"${w.slug}"` : "new"} item created in this plan.`
2950
+ );
2951
+ continue;
2952
+ }
2953
+ const y = await st(k, {
2745
2954
  ...t,
2746
2955
  latestUserMessage: null
2747
2956
  });
2748
- if (!m || typeof m != "object")
2957
+ if (!y || typeof y != "object")
2749
2958
  return {
2750
- message: `Could not prepare action ${d.length + 1}.`,
2959
+ message: `Could not prepare action ${p.length + 1}.`,
2751
2960
  mutationExecuted: !1,
2752
2961
  success: !1
2753
2962
  };
2754
- if (m.success === !1 || m.unsupported === !0)
2755
- return m;
2756
- m.requiresConfirmation === !0 && m.preview ? d.push(
2757
- Cn(g.tool, m.preview)
2758
- ) : d.push(`Run ${g.tool.replace(/_/g, " ")}.`);
2963
+ if (y.success === !1 || y.unsupported === !0)
2964
+ return y;
2965
+ y.requiresConfirmation === !0 && y.preview ? p.push(
2966
+ Ln(k.tool, y.preview)
2967
+ ) : p.push(`Run ${k.tool.replace(/_/g, " ")}.`);
2759
2968
  }
2760
- const c = n.summary || `Complete ${F(n.actions.length, "CMS action")}.`, p = P({
2969
+ const g = n.summary || `Complete ${N(n.actions.length, "CMS action")}.`, f = P({
2761
2970
  action: "EXECUTE CMS ACTION PLAN",
2762
2971
  context: t,
2763
2972
  payload: { actions: n.actions, tool: "execute_cms_action_plan" },
2764
2973
  preview: {
2765
2974
  actionCount: n.actions.length,
2766
- actionSummaries: d,
2767
- summary: c
2975
+ actionSummaries: p,
2976
+ summary: g
2768
2977
  },
2769
2978
  subject: `${n.actions.length} actions`
2770
2979
  });
2771
- if (p)
2772
- return p;
2980
+ if (f)
2981
+ return f;
2773
2982
  }
2774
- const r = {
2983
+ const a = {
2775
2984
  ...t,
2776
2985
  skipConfirmation: !0
2777
- }, o = [];
2778
- let a = !1, s = null, l = null;
2779
- const u = {};
2780
- for (const [d, c] of n.actions.entries()) {
2781
- const p = wr(c, u), g = await et(p, r);
2782
- if (o.push({ output: g, tool: p.tool }), g && typeof g == "object") {
2783
- const m = g;
2784
- if (m.mutationExecuted === !0 && (a = !0), !s && typeof m.editPath == "string" && (s = m.editPath), typeof m.redirectPath == "string" && (l = m.redirectPath), (p.tool === "create_cms_page" || p.tool === "create_cms_post" || p.tool === "create_cms_product") && typeof m.translationGroupId == "string" && (u[p.tool] = m.translationGroupId), m.success === !1 || m.unsupported === !0)
2986
+ }, s = [];
2987
+ let l = !1, u = null, d = null;
2988
+ const c = {}, m = /* @__PURE__ */ new Map();
2989
+ let h = null;
2990
+ for (const [p, g] of n.actions.entries()) {
2991
+ const f = Fr(
2992
+ Or(g, c),
2993
+ m,
2994
+ h
2995
+ ), k = await st(f, a);
2996
+ if (s.push({ output: k, tool: f.tool }), k && typeof k == "object") {
2997
+ const y = k;
2998
+ if (y.mutationExecuted === !0 && (l = !0), !u && typeof y.editPath == "string" && (u = y.editPath), typeof y.redirectPath == "string" && (d = y.redirectPath), (f.tool === "create_cms_page" || f.tool === "create_cms_post" || f.tool === "create_cms_product") && (typeof y.translationGroupId == "string" && (c[f.tool] = y.translationGroupId), y.entityId !== void 0 && y.entityId !== null)) {
2999
+ const w = lt(f.tool), b = {
3000
+ contentType: w,
3001
+ entityId: y.entityId
3002
+ };
3003
+ h = b, typeof y.slug == "string" && m.set(`${w}:${y.slug}`, b);
3004
+ }
3005
+ if (y.success === !1 || y.unsupported === !0)
2785
3006
  return {
2786
3007
  actionCount: n.actions.length,
2787
- failedActionIndex: d,
2788
- failedTool: p.tool,
2789
- message: typeof m.message == "string" ? m.message : `Action ${d + 1} failed.`,
2790
- mutationExecuted: a,
2791
- results: o,
3008
+ failedActionIndex: p,
3009
+ failedTool: f.tool,
3010
+ message: typeof y.message == "string" ? y.message : `Action ${p + 1} failed.`,
3011
+ mutationExecuted: l,
3012
+ results: s,
2792
3013
  success: !1,
2793
- ...s ? { editPath: s } : {},
2794
- ...l ? { redirectPath: l } : {}
3014
+ ...u ? { editPath: u } : {},
3015
+ ...d ? { redirectPath: d } : {}
2795
3016
  };
2796
3017
  }
2797
3018
  }
2798
3019
  return {
2799
3020
  actionCount: n.actions.length,
2800
- editPath: l ? void 0 : s ?? void 0,
2801
- mutationExecuted: a,
2802
- redirectPath: l ?? void 0,
2803
- results: o,
3021
+ editPath: d ? void 0 : u ?? void 0,
3022
+ mutationExecuted: l,
3023
+ redirectPath: d ?? void 0,
3024
+ results: s,
2804
3025
  success: !0,
2805
3026
  summary: n.summary ?? null
2806
3027
  };
2807
3028
  }
2808
- const Mt = i.strictObject({
3029
+ const Yt = i.strictObject({
2809
3030
  maxChars: i.number().int().min(500).max(2e4).default(8e3).describe("Maximum characters of readable body text to return."),
2810
3031
  url: i.string().trim().min(1).max(2048).refine((e) => /^https?:\/\//i.test(e), "URL must start with http:// or https://.")
2811
- }), Tr = 12e3, tt = 2e6;
2812
- function nt(e) {
3032
+ }), Lr = 12e3, ct = 2e6;
3033
+ function ut(e) {
2813
3034
  const t = e.trim().toLowerCase().replace(/\.$/, "").replace(/^\[|\]$/g, "");
2814
3035
  if (!t || t === "localhost" || t.endsWith(".localhost") || t.endsWith(".local") || t.endsWith(".internal") || t === "metadata.google.internal" || t === "0.0.0.0" || t === "::1" || t.startsWith("fe80:") || t.startsWith("fc") || t.startsWith("fd"))
2815
3036
  return !0;
@@ -2821,21 +3042,166 @@ function nt(e) {
2821
3042
  }
2822
3043
  return !1;
2823
3044
  }
2824
- function ee(e) {
3045
+ function re(e) {
2825
3046
  return e.replace(/<[^>]+>/g, " ").replace(/&nbsp;/gi, " ").replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/&quot;/gi, '"').replace(/&#39;/gi, "'").replace(/\s+/g, " ").trim();
2826
3047
  }
2827
- function xr(e, t) {
2828
- const n = e.replace(/<script\b[\s\S]*?<\/script>/gi, " ").replace(/<style\b[\s\S]*?<\/style>/gi, " ").replace(/<noscript\b[\s\S]*?<\/noscript>/gi, " ").replace(/<svg\b[\s\S]*?<\/svg>/gi, " "), r = e.match(/<title\b[^>]*>([\s\S]*?)<\/title>/i), o = e.match(/<meta[^>]+name=["']description["'][^>]*content=["']([^"']*)["'][^>]*>/i) || e.match(/<meta[^>]+content=["']([^"']*)["'][^>]*name=["']description["'][^>]*>/i), a = [...n.matchAll(/<h([1-3])\b[^>]*>([\s\S]*?)<\/h\1>/gi)].map((u) => ee(u[2])).filter(Boolean).slice(0, 40), s = n.match(/<body\b[^>]*>([\s\S]*?)<\/body>/i), l = ee(s?.[1] ?? n);
3048
+ function Br(e) {
3049
+ return e.trim().replace(/&amp;/gi, "&").replace(/&#38;/g, "&").replace(/&quot;/gi, '"').replace(/&#39;/g, "'");
3050
+ }
3051
+ const Xt = /\.(avif|gif|jpe?g|png|webp)(?:[?#]|$)/i, Qt = /(?:^|[/_-])(?:sprite|icon|favicon|logo|placeholder|pixel|spacer|blank|avatar|badge|flag|loader|spinner|1x1|transparent|watermark|payment|visa|mastercard|paypal|amex|social|share|facebook|twitter|instagram|youtube|pinterest|linkedin)(?:[/_.-]|$)/i;
3052
+ function ue(e, t) {
3053
+ if (typeof e != "string")
3054
+ return null;
3055
+ const n = Br(e);
3056
+ if (!n || n.startsWith("data:"))
3057
+ return null;
3058
+ try {
3059
+ const r = new URL(n, t);
3060
+ return r.protocol !== "http:" && r.protocol !== "https:" ? null : r.toString();
3061
+ } catch {
3062
+ return null;
3063
+ }
3064
+ }
3065
+ function Rr(e) {
3066
+ let t = null;
3067
+ for (const n of e.split(",")) {
3068
+ const r = n.trim().split(/\s+/), o = r[0];
3069
+ if (!o)
3070
+ continue;
3071
+ const a = r[1] || "", s = a.match(/^(\d+(?:\.\d+)?)w$/i), l = a.match(/^(\d+(?:\.\d+)?)x$/i), u = s ? Number(s[1]) : l ? Number(l[1]) * 1e3 : 1;
3072
+ (!t || u > t.weight) && (t = { url: o, weight: u });
3073
+ }
3074
+ return t?.url ?? null;
3075
+ }
3076
+ function F(e, t) {
3077
+ const n = e.match(
3078
+ new RegExp(`\\b${t}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i")
3079
+ );
3080
+ return n ? n[1] ?? n[2] ?? n[3] ?? null : null;
3081
+ }
3082
+ function qr(e, t) {
3083
+ const n = [], r = [], o = (l, u) => {
3084
+ if (typeof l == "string") {
3085
+ const d = ue(l, t);
3086
+ d && u.push(d);
3087
+ return;
3088
+ }
3089
+ if (Array.isArray(l)) {
3090
+ for (const d of l)
3091
+ o(d, u);
3092
+ return;
3093
+ }
3094
+ l && typeof l == "object" && (o(l.url, u), o(l.contentUrl, u));
3095
+ }, a = (l, u) => {
3096
+ if (u > 8 || !l || typeof l != "object")
3097
+ return;
3098
+ if (Array.isArray(l)) {
3099
+ for (const p of l)
3100
+ a(p, u + 1);
3101
+ return;
3102
+ }
3103
+ const d = l, c = d["@type"], h = (Array.isArray(c) ? c : [c]).filter((p) => typeof p == "string").map((p) => p.toLowerCase()).some(
3104
+ (p) => p === "product" || p === "productgroup" || p === "itempage"
3105
+ );
3106
+ "image" in d && o(d.image, h ? n : r);
3107
+ for (const p of Object.values(d))
3108
+ a(p, u + 1);
3109
+ }, s = e.matchAll(
3110
+ /<script\b[^>]*type\s*=\s*["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi
3111
+ );
3112
+ for (const l of s) {
3113
+ const u = (l[1] || "").trim();
3114
+ if (u)
3115
+ try {
3116
+ a(JSON.parse(u), 0);
3117
+ } catch {
3118
+ }
3119
+ }
3120
+ return [...n, ...r];
3121
+ }
3122
+ const Zt = /(?:^|[/_-])(?:thumbnails?|thumbs?|small|mini)(?:[/_.-]|$)/i;
3123
+ function en(e) {
3124
+ try {
3125
+ const { pathname: t } = new URL(e);
3126
+ return decodeURIComponent(t.slice(t.lastIndexOf("/") + 1)).toLowerCase() || null;
3127
+ } catch {
3128
+ return null;
3129
+ }
3130
+ }
3131
+ function Mr(e, t) {
3132
+ const n = /* @__PURE__ */ new Map();
3133
+ for (const r of e.matchAll(/<a\b[^>]*>/gi)) {
3134
+ const o = ue(F(r[0], "href"), t);
3135
+ if (!o || !Xt.test(o) || Zt.test(o) || Qt.test(o))
3136
+ continue;
3137
+ const a = en(o);
3138
+ a && !n.has(a) && n.set(a, o);
3139
+ }
3140
+ return n;
3141
+ }
3142
+ function Dr(e, t) {
3143
+ const n = [...qr(e, t)], r = [
3144
+ /<meta\b[^>]*\b(?:property|name)\s*=\s*["'](?:og:image:secure_url|og:image:url|og:image)["'][^>]*>/gi,
3145
+ /<meta\b[^>]*\b(?:property|name)\s*=\s*["'](?:twitter:image:src|twitter:image)["'][^>]*>/gi,
3146
+ /<meta\b[^>]*\bitemprop\s*=\s*["']image["'][^>]*>/gi,
3147
+ /<link\b[^>]*\brel\s*=\s*["']image_src["'][^>]*>/gi
3148
+ ];
3149
+ for (const c of r)
3150
+ for (const m of e.matchAll(c)) {
3151
+ const h = m[0], p = ue(
3152
+ F(h, "content") || F(h, "href"),
3153
+ t
3154
+ );
3155
+ p && n.push(p);
3156
+ }
3157
+ const o = [];
3158
+ for (const c of e.matchAll(/<img\b[^>]*>/gi)) {
3159
+ const m = c[0], h = F(m, "srcset") || F(m, "data-srcset"), p = [
3160
+ h ? Rr(h) : null,
3161
+ F(m, "src"),
3162
+ F(m, "data-src"),
3163
+ F(m, "data-original"),
3164
+ F(m, "data-lazy-src"),
3165
+ F(m, "data-image")
3166
+ ];
3167
+ let g = null;
3168
+ for (const k of p)
3169
+ if (g = ue(k, t), g)
3170
+ break;
3171
+ if (!g || Qt.test(g))
3172
+ continue;
3173
+ const f = Number(F(m, "width"));
3174
+ Number.isFinite(f) && f > 0 && f < 200 || o.push(g);
3175
+ }
3176
+ const a = (c) => Xt.test(c);
3177
+ n.push(...o.filter(a), ...o.filter((c) => !a(c)));
3178
+ const s = Mr(e, t), l = (c) => {
3179
+ if (!Zt.test(c))
3180
+ return c;
3181
+ const m = en(c);
3182
+ return m && s.get(m) || c;
3183
+ }, u = /* @__PURE__ */ new Set(), d = [];
3184
+ for (const c of n) {
3185
+ const m = l(c);
3186
+ if (!u.has(m) && (u.add(m), d.push(m), d.length >= 12))
3187
+ break;
3188
+ }
3189
+ return { images: d, mainImage: d[0] ?? null };
3190
+ }
3191
+ function zr(e, t, n) {
3192
+ const r = e.replace(/<script\b[\s\S]*?<\/script>/gi, " ").replace(/<style\b[\s\S]*?<\/style>/gi, " ").replace(/<noscript\b[\s\S]*?<\/noscript>/gi, " ").replace(/<svg\b[\s\S]*?<\/svg>/gi, " "), { images: o, mainImage: a } = Dr(e, n), s = e.match(/<title\b[^>]*>([\s\S]*?)<\/title>/i), l = e.match(/<meta[^>]+name=["']description["'][^>]*content=["']([^"']*)["'][^>]*>/i) || e.match(/<meta[^>]+content=["']([^"']*)["'][^>]*name=["']description["'][^>]*>/i), u = [...r.matchAll(/<h([1-3])\b[^>]*>([\s\S]*?)<\/h\1>/gi)].map((m) => re(m[2])).filter(Boolean).slice(0, 40), d = r.match(/<body\b[^>]*>([\s\S]*?)<\/body>/i), c = re(d?.[1] ?? r);
2829
3193
  return {
2830
- description: o ? ee(o[1]) : "",
2831
- headings: a,
2832
- text: l.slice(0, t),
2833
- title: r ? ee(r[1]) : "",
2834
- truncated: l.length > t
3194
+ description: l ? re(l[1]) : "",
3195
+ headings: u,
3196
+ images: o,
3197
+ mainImage: a,
3198
+ text: c.slice(0, t),
3199
+ title: s ? re(s[1]) : "",
3200
+ truncated: c.length > t
2835
3201
  };
2836
3202
  }
2837
- async function Cr(e) {
2838
- const t = Mt.parse(e);
3203
+ async function Gr(e) {
3204
+ const t = Yt.parse(e);
2839
3205
  let n;
2840
3206
  try {
2841
3207
  n = new URL(t.url);
@@ -2844,13 +3210,13 @@ async function Cr(e) {
2844
3210
  }
2845
3211
  if (n.protocol !== "http:" && n.protocol !== "https:")
2846
3212
  return { message: "Only http and https URLs can be fetched.", success: !1, url: t.url };
2847
- if (nt(n.hostname))
3213
+ if (ut(n.hostname))
2848
3214
  return {
2849
3215
  message: "Refusing to fetch a local, private, or internal address.",
2850
3216
  success: !1,
2851
3217
  url: t.url
2852
3218
  };
2853
- const r = new AbortController(), o = setTimeout(() => r.abort(), Tr);
3219
+ const r = new AbortController(), o = setTimeout(() => r.abort(), Lr);
2854
3220
  try {
2855
3221
  const a = await fetch(n.toString(), {
2856
3222
  headers: {
@@ -2869,7 +3235,7 @@ async function Cr(e) {
2869
3235
  };
2870
3236
  const s = a.url || n.toString();
2871
3237
  try {
2872
- if (nt(new URL(s).hostname))
3238
+ if (ut(new URL(s).hostname))
2873
3239
  return {
2874
3240
  message: "The URL redirected to a blocked internal address.",
2875
3241
  success: !1,
@@ -2885,11 +3251,17 @@ async function Cr(e) {
2885
3251
  success: !1,
2886
3252
  url: t.url
2887
3253
  };
2888
- const u = await a.text(), d = u.length > tt ? u.slice(0, tt) : u, c = xr(d, t.maxChars);
3254
+ const u = await a.text(), d = u.length > ct ? u.slice(0, ct) : u, c = zr(d, t.maxChars, s);
2889
3255
  return !c.text && !c.title ? { message: "The URL returned no readable text content.", success: !1, url: t.url } : {
2890
3256
  description: c.description,
2891
3257
  finalUrl: s,
2892
3258
  headings: c.headings,
3259
+ // Ranked best-first (schema.org Product image > og:image > in-body <img>).
3260
+ // `mainImage` is the page's subject image and can be passed straight into
3261
+ // create_cms_product `images` / feature_image_id — it is imported into the
3262
+ // media library automatically.
3263
+ images: c.images,
3264
+ mainImage: c.mainImage,
2893
3265
  success: !0,
2894
3266
  text: c.text,
2895
3267
  title: c.title,
@@ -2898,7 +3270,7 @@ async function Cr(e) {
2898
3270
  };
2899
3271
  } catch (a) {
2900
3272
  return {
2901
- message: a instanceof Error && (a.name === "AbortError" || /abort/i.test(a.message)) ? "Fetching the URL timed out." : `Failed to fetch the URL: ${h(a)}`,
3273
+ message: a instanceof Error && (a.name === "AbortError" || /abort/i.test(a.message)) ? "Fetching the URL timed out." : `Failed to fetch the URL: ${_(a)}`,
2902
3274
  success: !1,
2903
3275
  url: t.url
2904
3276
  };
@@ -2906,12 +3278,12 @@ async function Cr(e) {
2906
3278
  clearTimeout(o);
2907
3279
  }
2908
3280
  }
2909
- const Dt = i.strictObject({
3281
+ const tn = i.strictObject({
2910
3282
  count: i.number().int().min(1).max(15).default(6),
2911
3283
  orientation: i.enum(["landscape", "portrait", "square"]).optional().describe("Preferred image orientation. Use landscape for hero/section backgrounds."),
2912
3284
  query: i.string().trim().min(2).max(200).describe('What the photos should depict, e.g. "herbal supplements".')
2913
- }), vr = 12e3;
2914
- async function ze(e) {
3285
+ }), Kr = 12e3;
3286
+ async function Ye(e) {
2915
3287
  let t = null, n = null;
2916
3288
  if (e)
2917
3289
  try {
@@ -2919,8 +3291,8 @@ async function ze(e) {
2919
3291
  if (!c)
2920
3292
  return null;
2921
3293
  try {
2922
- const p = s(c);
2923
- return typeof p == "string" && p.trim() ? p.trim() : null;
3294
+ const m = s(c);
3295
+ return typeof m == "string" && m.trim() ? m.trim() : null;
2924
3296
  } catch {
2925
3297
  return null;
2926
3298
  }
@@ -2932,10 +3304,10 @@ async function ze(e) {
2932
3304
  const r = [];
2933
3305
  return t && r.push({ apiKey: t, provider: "pexels" }), n && r.push({ apiKey: n, provider: "unsplash" }), r;
2934
3306
  }
2935
- async function Gr(e) {
2936
- return (await ze(e))[0] ?? null;
3307
+ async function lo(e) {
3308
+ return (await Ye(e))[0] ?? null;
2937
3309
  }
2938
- async function Sr(e) {
3310
+ async function Hr(e) {
2939
3311
  if (e)
2940
3312
  try {
2941
3313
  const { CORTEX_AI_UNSPLASH_APP_NAME_SETTING_KEY: t } = await import("./ai-config.es.js"), { data: n } = await e.from("site_settings").select("value").eq("key", t).maybeSingle(), r = n?.value;
@@ -2945,8 +3317,8 @@ async function Sr(e) {
2945
3317
  }
2946
3318
  return process.env.UNSPLASH_APP_NAME?.trim() || null;
2947
3319
  }
2948
- async function rt(e, t) {
2949
- const n = new AbortController(), r = setTimeout(() => n.abort(), vr);
3320
+ async function dt(e, t) {
3321
+ const n = new AbortController(), r = setTimeout(() => n.abort(), Kr);
2950
3322
  try {
2951
3323
  const o = await fetch(e, { headers: t, signal: n.signal });
2952
3324
  if (!o.ok)
@@ -2956,34 +3328,34 @@ async function rt(e, t) {
2956
3328
  clearTimeout(r);
2957
3329
  }
2958
3330
  }
2959
- function te(e) {
3331
+ function oe(e) {
2960
3332
  const t = Number(e);
2961
3333
  return Number.isFinite(t) && t > 0 ? t : null;
2962
3334
  }
2963
- function Ee(e, t) {
2964
- if (!A(e))
3335
+ function Ue(e, t) {
3336
+ if (!$(e))
2965
3337
  return;
2966
3338
  const n = (r) => {
2967
- A(r) && r.provider === "unsplash" && typeof r.downloadLocation == "string" && r.downloadLocation.trim() && t.add(r.downloadLocation.trim());
3339
+ $(r) && r.provider === "unsplash" && typeof r.downloadLocation == "string" && r.downloadLocation.trim() && t.add(r.downloadLocation.trim());
2968
3340
  };
2969
- if (n(e.attribution), A(e.background) && A(e.background.image) && n(e.background.image.attribution), Array.isArray(e.column_blocks)) {
3341
+ if (n(e.attribution), $(e.background) && $(e.background.image) && n(e.background.image.attribution), Array.isArray(e.column_blocks)) {
2970
3342
  for (const r of e.column_blocks)
2971
3343
  if (Array.isArray(r))
2972
3344
  for (const o of r)
2973
- A(o) && Ee(o.content, t);
3345
+ $(o) && Ue(o.content, t);
2974
3346
  }
2975
3347
  if (Array.isArray(e.slides))
2976
3348
  for (const r of e.slides)
2977
- Ee(r, t);
3349
+ Ue(r, t);
2978
3350
  }
2979
- async function Ie(e, t) {
3351
+ async function ve(e, t) {
2980
3352
  try {
2981
3353
  const n = /* @__PURE__ */ new Set();
2982
3354
  for (const a of e)
2983
- Ee(a?.content, n);
3355
+ Ue(a?.content, n);
2984
3356
  if (n.size === 0)
2985
3357
  return;
2986
- const o = (await ze(t)).find((a) => a.provider === "unsplash");
3358
+ const o = (await Ye(t)).find((a) => a.provider === "unsplash");
2987
3359
  if (!o)
2988
3360
  return;
2989
3361
  await Promise.all(
@@ -2997,13 +3369,13 @@ async function Ie(e, t) {
2997
3369
  } catch {
2998
3370
  }
2999
3371
  }
3000
- async function Er(e, t, n) {
3372
+ async function Vr(e, t, n) {
3001
3373
  const r = new URLSearchParams({
3002
3374
  per_page: String(t.count),
3003
3375
  query: t.query
3004
3376
  });
3005
3377
  if (t.orientation && r.set("orientation", t.orientation), e.provider === "pexels") {
3006
- const a = await rt(
3378
+ const a = await dt(
3007
3379
  `https://api.pexels.com/v1/search?${r.toString()}`,
3008
3380
  { Authorization: e.apiKey }
3009
3381
  );
@@ -3013,18 +3385,18 @@ async function Er(e, t, n) {
3013
3385
  alt: typeof s?.alt == "string" && s.alt.trim() ? s.alt.trim() : t.query,
3014
3386
  credit: l ? `Photo by ${l} on Pexels` : "Photo on Pexels",
3015
3387
  downloadLocation: null,
3016
- height: te(s?.height),
3388
+ height: oe(s?.height),
3017
3389
  photographer: l,
3018
3390
  photographerUrl: typeof s?.photographer_url == "string" ? s.photographer_url : null,
3019
3391
  provider: "pexels",
3020
3392
  sourceUrl: typeof s?.url == "string" ? s.url : null,
3021
3393
  thumbnailUrl: s?.src?.medium || s?.src?.large || null,
3022
3394
  url: s?.src?.large2x || s?.src?.large || s?.src?.original || null,
3023
- width: te(s?.width)
3395
+ width: oe(s?.width)
3024
3396
  };
3025
3397
  }).filter((s) => typeof s.url == "string");
3026
3398
  }
3027
- const o = await rt(
3399
+ const o = await dt(
3028
3400
  `https://api.unsplash.com/search/photos?${r.toString()}`,
3029
3401
  { Authorization: `Client-ID ${e.apiKey}` }
3030
3402
  );
@@ -3036,7 +3408,7 @@ async function Er(e, t, n) {
3036
3408
  // Unsplash requires triggering this endpoint when the photo is actually
3037
3409
  // used; carry it so the block-persist path can fire it.
3038
3410
  downloadLocation: typeof a?.links?.download_location == "string" ? a.links.download_location : null,
3039
- height: te(a?.height),
3411
+ height: oe(a?.height),
3040
3412
  photographer: s,
3041
3413
  photographerUrl: typeof a?.user?.links?.html == "string" ? a.user.links.html : null,
3042
3414
  provider: "unsplash",
@@ -3045,24 +3417,24 @@ async function Er(e, t, n) {
3045
3417
  url: a?.urls?.regular || a?.urls?.full || a?.urls?.raw || null,
3046
3418
  // The operator's registered Unsplash app name for the attribution utm_source.
3047
3419
  utmSource: n || null,
3048
- width: te(a?.width)
3420
+ width: oe(a?.width)
3049
3421
  };
3050
3422
  }).filter((a) => typeof a.url == "string");
3051
3423
  }
3052
- async function $r(e, t) {
3053
- const n = Dt.parse(e), r = await ze(t?.supabase);
3424
+ async function Jr(e, t) {
3425
+ const n = tn.parse(e), r = await Ye(t?.supabase);
3054
3426
  if (r.length === 0)
3055
3427
  return {
3056
3428
  message: "No stock photo provider is configured. Add a free Pexels or Unsplash API key in /cms/settings/cortex-ai (or set PEXELS_API_KEY / UNSPLASH_ACCESS_KEY).",
3057
3429
  photos: [],
3058
3430
  success: !1
3059
3431
  };
3060
- const o = r.some((l) => l.provider === "unsplash") ? await Sr(t?.supabase) : null, a = [];
3432
+ const o = r.some((l) => l.provider === "unsplash") ? await Hr(t?.supabase) : null, a = [];
3061
3433
  let s = null;
3062
3434
  for (const l of r) {
3063
3435
  a.push(l.provider);
3064
3436
  try {
3065
- const u = await Er(l, n, o);
3437
+ const u = await Vr(l, n, o);
3066
3438
  if (u.length > 0)
3067
3439
  return {
3068
3440
  attemptedProviders: a,
@@ -3078,13 +3450,13 @@ async function $r(e, t) {
3078
3450
  }
3079
3451
  return {
3080
3452
  attemptedProviders: a,
3081
- message: s ? `Stock photo search failed across ${a.join(", ")}: ${h(s)}` : `No matching stock photos found for "${n.query}".`,
3453
+ message: s ? `Stock photo search failed across ${a.join(", ")}: ${_(s)}` : `No matching stock photos found for "${n.query}".`,
3082
3454
  photos: [],
3083
3455
  success: !1
3084
3456
  };
3085
3457
  }
3086
- const Gt = W.extend({
3087
- blocks: i.array(pe).min(1).max(20),
3458
+ const nn = H.extend({
3459
+ blocks: i.array(Q).min(1).max(20),
3088
3460
  meta: i.strictObject({
3089
3461
  meta_description: i.string().max(500).nullable().optional(),
3090
3462
  meta_title: i.string().max(160).nullable().optional(),
@@ -3092,7 +3464,7 @@ const Gt = W.extend({
3092
3464
  status: i.enum(["draft", "published", "archived"]).optional(),
3093
3465
  title: i.string().trim().min(1).max(300).optional()
3094
3466
  }).partial().optional()
3095
- }), Ar = [
3467
+ }), Wr = [
3096
3468
  "custom_canonical",
3097
3469
  "excerpt",
3098
3470
  "feature_image_id",
@@ -3107,20 +3479,20 @@ const Gt = W.extend({
3107
3479
  "title",
3108
3480
  "translation_group_id"
3109
3481
  ];
3110
- function Pr(e) {
3482
+ function Yr(e) {
3111
3483
  const t = {};
3112
- for (const n of Ar)
3484
+ for (const n of Wr)
3113
3485
  n in e && e[n] !== void 0 && (t[n] = e[n]);
3114
3486
  return t;
3115
3487
  }
3116
- function Nr(e, t) {
3488
+ function Xr(e, t) {
3117
3489
  if (!t)
3118
3490
  return null;
3119
3491
  const n = e === "page" ? t === "home" ? "/" : `/${t}` : `/article/${t}`;
3120
3492
  return `/api/draft/start?path=${encodeURIComponent(n)}`;
3121
3493
  }
3122
- async function Ur(e, t) {
3123
- const n = Gt.parse(e), r = I(t), o = Fe(t), a = await we(n, t);
3494
+ async function Qr(e, t) {
3495
+ const n = nn.parse(e), r = C(t), o = Re(t), a = await te(n, t);
3124
3496
  if (a.contentType === "product")
3125
3497
  throw new Error(
3126
3498
  "rewrite_page_draft supports pages and posts only. Products use description_json, not page blocks."
@@ -3131,26 +3503,26 @@ async function Ur(e, t) {
3131
3503
  const u = Number(a.item.language_id);
3132
3504
  if (!Number.isInteger(u) || u <= 0)
3133
3505
  throw new Error("The target page/post is missing a language id.");
3134
- const c = qe(n.blocks, void 0, void 0, t).map((v, S) => ({
3135
- block_type: v.block_type,
3136
- content: v.content,
3506
+ const c = Se(n.blocks, void 0, void 0, t).map((x, E) => ({
3507
+ block_type: x.block_type,
3508
+ content: x.content,
3137
3509
  language_id: u,
3138
- order: S,
3510
+ order: E,
3139
3511
  page_id: s === "page" ? l : null,
3140
3512
  post_id: s === "post" ? l : null,
3141
3513
  product_id: null
3142
- })), p = Pr(a.item);
3514
+ })), m = Yr(a.item);
3143
3515
  if (n.meta)
3144
- for (const [v, S] of Object.entries(n.meta))
3145
- S !== void 0 && (p[v] = S);
3146
- const g = pt(
3147
- typeof p.slug == "string" ? p.slug : a.item.slug
3148
- ), m = typeof p.title == "string" && p.title.trim() ? p.title : String(a.item.title || g || "Untitled"), f = s === "page" ? `/cms/pages/${l}/edit` : `/cms/posts/${l}/edit`, _ = Nr(s, g), w = P({
3516
+ for (const [x, E] of Object.entries(n.meta))
3517
+ E !== void 0 && (m[x] = E);
3518
+ const h = Tt(
3519
+ typeof m.slug == "string" ? m.slug : a.item.slug
3520
+ ), p = typeof m.title == "string" && m.title.trim() ? m.title : String(a.item.title || h || "Untitled"), g = s === "page" ? `/cms/pages/${l}/edit` : `/cms/posts/${l}/edit`, f = Xr(s, h), y = P({
3149
3521
  action: "REWRITE DRAFT",
3150
3522
  context: t,
3151
3523
  payload: {
3152
3524
  blocks: c,
3153
- meta: p,
3525
+ meta: m,
3154
3526
  parent_id: l,
3155
3527
  parent_type: s,
3156
3528
  tool: "rewrite_page_draft"
@@ -3158,48 +3530,48 @@ async function Ur(e, t) {
3158
3530
  preview: {
3159
3531
  blockCount: c.length,
3160
3532
  contentType: s,
3161
- slug: g,
3162
- summary: `Stage a Live Draft that replaces the ${s} "${m}" with ${F(
3533
+ slug: h,
3534
+ summary: `Stage a Live Draft that replaces the ${s} "${p}" with ${N(
3163
3535
  c.length,
3164
3536
  "new block"
3165
3537
  )}. Nothing goes live until you review the draft and click Publish (which also saves a revision snapshot).`,
3166
- title: m
3538
+ title: p
3167
3539
  },
3168
3540
  subject: `${s}-${l}`
3169
3541
  });
3170
- if (w)
3171
- return w;
3172
- const E = Number(a.item.version) || 1, { error: y } = await r.from("content_drafts").delete().eq("parent_type", s).eq("parent_id", l);
3173
3542
  if (y)
3174
- throw new Error(`Failed to clear the existing draft: ${h(y)}`);
3175
- const { error: C } = await r.from("content_drafts").insert({
3543
+ return y;
3544
+ const w = Number(a.item.version) || 1, { error: b } = await r.from("content_drafts").delete().eq("parent_type", s).eq("parent_id", l);
3545
+ if (b)
3546
+ throw new Error(`Failed to clear the existing draft: ${_(b)}`);
3547
+ const { error: I } = await r.from("content_drafts").insert({
3176
3548
  author_id: o,
3177
- base_version: E,
3549
+ base_version: w,
3178
3550
  blocks: c,
3179
- meta: p,
3551
+ meta: m,
3180
3552
  parent_id: l,
3181
3553
  parent_type: s
3182
3554
  });
3183
- if (C)
3184
- throw new Error(`Failed to save the draft: ${h(C)}`);
3185
- return Ie(c, r), N(
3555
+ if (I)
3556
+ throw new Error(`Failed to save the draft: ${_(I)}`);
3557
+ return ve(c, r), U(
3186
3558
  t,
3187
- { contentType: s, entityId: l, slug: g },
3188
- g
3559
+ { contentType: s, entityId: l, slug: h },
3560
+ h
3189
3561
  ), {
3190
3562
  blockCount: c.length,
3191
3563
  contentType: s,
3192
- draftPreviewPath: _,
3193
- editPath: f,
3564
+ draftPreviewPath: f,
3565
+ editPath: g,
3194
3566
  entityId: l,
3195
3567
  isDraft: !0,
3196
3568
  mutationExecuted: !0,
3197
- slug: g,
3569
+ slug: h,
3198
3570
  success: !0,
3199
- title: m
3571
+ title: p
3200
3572
  };
3201
3573
  }
3202
- const Fr = /* @__PURE__ */ new Set([
3574
+ const Zr = /* @__PURE__ */ new Set([
3203
3575
  "alt_text",
3204
3576
  "author_name",
3205
3577
  "author_title",
@@ -3214,7 +3586,7 @@ const Fr = /* @__PURE__ */ new Set([
3214
3586
  "text_content",
3215
3587
  "title"
3216
3588
  ]);
3217
- function $e(e, t, n) {
3589
+ function Oe(e, t, n) {
3218
3590
  if (!e)
3219
3591
  return e;
3220
3592
  if (Object.prototype.hasOwnProperty.call(t, e))
@@ -3227,357 +3599,375 @@ function $e(e, t, n) {
3227
3599
  a && o.includes(a) && (o = o.split(a).join(s));
3228
3600
  return o;
3229
3601
  }
3230
- function Ae(e, t, n) {
3602
+ function Fe(e, t, n) {
3231
3603
  if (Array.isArray(e))
3232
- return e.map((r) => Ae(r, t, n));
3604
+ return e.map((r) => Fe(r, t, n));
3233
3605
  if (e && typeof e == "object") {
3234
3606
  const r = {};
3235
3607
  for (const [o, a] of Object.entries(e))
3236
- typeof a == "string" && Fr.has(o) ? r[o] = $e(a, t, n) : a && typeof a == "object" ? r[o] = Ae(a, t, n) : r[o] = a;
3608
+ typeof a == "string" && Zr.has(o) ? r[o] = Oe(a, t, n) : a && typeof a == "object" ? r[o] = Fe(a, t, n) : r[o] = a;
3237
3609
  return r;
3238
3610
  }
3239
3611
  return e;
3240
3612
  }
3241
- const zt = i.strictObject({
3613
+ const rn = i.strictObject({
3242
3614
  targetLanguageCode: i.string().trim().min(2).max(80).describe('Target language code or name, e.g. "fr" or "French".'),
3243
3615
  title: i.string().trim().min(1).max(300).optional().describe("Translated page title (defaults to translating the source title)."),
3244
3616
  translations: i.record(i.string(), i.string()).describe(
3245
3617
  'Map of every visible source string to its translation, e.g. { "Explore Our Products": "Explorez nos produits" }. Include headings, paragraph text, button labels, image alt text, captions, and form labels.'
3246
3618
  )
3247
3619
  });
3248
- async function Or(e, t) {
3249
- const n = zt.parse(e), r = D(t);
3620
+ async function eo(e, t) {
3621
+ const n = rn.parse(e), r = V(t);
3250
3622
  if (r.contentType === "product")
3251
3623
  throw new Error("translate_page supports pages and posts only.");
3252
- const o = I(t), a = Ue(r), s = r.contentType === "page" ? "pages" : "posts", l = r.contentType === "page" ? "page_id" : "post_id", { data: u, error: d } = await o.from(s).select("*").eq("id", a).single();
3624
+ const o = C(t), a = Be(r), s = r.contentType === "page" ? "pages" : "posts", l = r.contentType === "page" ? "page_id" : "post_id", { data: u, error: d } = await o.from(s).select("*").eq("id", a).single();
3253
3625
  if (d || !u)
3254
3626
  throw new Error(
3255
- `Could not read the source ${r.contentType} to translate: ${h(d)}`
3627
+ `Could not read the source ${r.contentType} to translate: ${_(d)}`
3256
3628
  );
3257
- const { data: c, error: p } = await o.from("blocks").select("id, block_type, content, order").eq(l, a);
3258
- if (p)
3259
- throw new Error(`Could not read the source blocks: ${h(p)}`);
3260
- const g = (Array.isArray(c) ? c : []).slice().sort((b, $) => Number(b.order) - Number($.order));
3261
- if (g.length === 0)
3629
+ const { data: c, error: m } = await o.from("blocks").select("id, block_type, content, order").eq(l, a);
3630
+ if (m)
3631
+ throw new Error(`Could not read the source blocks: ${_(m)}`);
3632
+ const h = (Array.isArray(c) ? c : []).slice().sort((T, A) => Number(T.order) - Number(A.order));
3633
+ if (h.length === 0)
3262
3634
  throw new Error(`The source ${r.contentType} has no content blocks to translate.`);
3263
- const m = n.translations || {}, f = Object.entries(m).filter(([b]) => !!b).sort((b, $) => $[0].length - b[0].length), _ = g.map((b, $) => ({
3264
- blockType: b.block_type,
3265
- content: Ae(H(b.content), m, f),
3266
- order: $
3267
- })), k = await ke(o, n.targetLanguageCode), w = String(u.title || ""), E = n.title || $e(w, m, f) || w || "Untitled", y = (b) => typeof b == "string" && b.trim() ? $e(b, m, f) : void 0, C = Y(E) || u.slug || "translated-page", v = {
3268
- blocks: _,
3635
+ const p = n.translations || {}, g = Object.entries(p).filter(([T]) => !!T).sort((T, A) => A[0].length - T[0].length), f = h.map((T, A) => ({
3636
+ blockType: T.block_type,
3637
+ content: Fe(z(T.content), p, g),
3638
+ order: A
3639
+ })), k = await Ce(o, n.targetLanguageCode), y = String(u.title || ""), w = n.title || Oe(y, p, g) || y || "Untitled", b = (T) => typeof T == "string" && T.trim() ? Oe(T, p, g) : void 0, I = R(w) || u.slug || "translated-page", x = {
3640
+ blocks: f,
3269
3641
  feature_image_id: u.feature_image_id ?? void 0,
3270
3642
  languageCode: k.code,
3271
- meta_description: y(u.meta_description),
3272
- meta_title: y(u.meta_title),
3273
- slug: C,
3643
+ meta_description: b(u.meta_description),
3644
+ meta_title: b(u.meta_title),
3645
+ slug: I,
3274
3646
  // Publish the translation immediately so it goes live the moment the owner
3275
3647
  // confirms — the localized homepage/page is then reachable and the public
3276
3648
  // language switcher can find it (drafts are filtered out of public lookups).
3277
3649
  status: "published",
3278
- title: E,
3650
+ title: w,
3279
3651
  translationGroupId: u.translation_group_id || void 0
3280
- }, S = r.contentType === "post" ? {
3281
- ...v,
3282
- excerpt: y(u.excerpt),
3283
- label: y(u.label),
3652
+ }, E = r.contentType === "post" ? {
3653
+ ...x,
3654
+ excerpt: b(u.excerpt),
3655
+ label: b(u.label),
3284
3656
  // Inherit the source post's publish date (or "now" if it has none) so a
3285
3657
  // published translation sorts alongside its original in the article list
3286
3658
  // instead of jumping to the top with a null published_at.
3287
3659
  published_at: u.published_at ?? (/* @__PURE__ */ new Date()).toISOString(),
3288
- subtitle: y(u.subtitle)
3289
- } : v, j = P({
3660
+ subtitle: b(u.subtitle)
3661
+ } : x, L = P({
3290
3662
  action: "TRANSLATE",
3291
3663
  context: t,
3292
- payload: { createInput: S, sourceId: u.id, tool: "translate_page" },
3664
+ payload: { createInput: E, sourceId: u.id, tool: "translate_page" },
3293
3665
  preview: {
3294
- blockCount: _.length,
3666
+ blockCount: f.length,
3295
3667
  contentType: r.contentType,
3296
3668
  languageCode: k.code,
3297
- slug: v.slug,
3298
- status: v.status,
3299
- summary: `Publish a ${k.code.toUpperCase()} translation of "${w}" — it goes live immediately, linked to the original ${r.contentType}, at /${v.slug} with ${F(
3300
- _.length,
3669
+ slug: x.slug,
3670
+ status: x.status,
3671
+ summary: `Publish a ${k.code.toUpperCase()} translation of "${y}" — it goes live immediately, linked to the original ${r.contentType}, at /${x.slug} with ${N(
3672
+ f.length,
3301
3673
  "translated block"
3302
3674
  )}.`,
3303
- title: E
3675
+ title: w
3304
3676
  },
3305
3677
  subject: `translate ${r.contentType} ${u.id} to ${k.code}`
3306
3678
  });
3307
- if (j)
3308
- return j;
3309
- const B = { ...t, skipConfirmation: !0 };
3310
- return { ...r.contentType === "post" ? await De(S, B) : await Me(S, B), isTranslation: !0, languageCode: k.code };
3311
- }
3312
- const Kt = i.strictObject({
3313
- images: i.array(i.string().trim().min(1).max(2048)).min(1).max(12)
3314
- });
3315
- async function jr(e, t) {
3316
- const n = Kt.parse(e), r = D(t), o = I(t), a = be(r), s = r.title || r.slug || "current item", l = r.contentType === "product", u = P({
3679
+ if (L)
3680
+ return L;
3681
+ const q = { ...t, skipConfirmation: !0 };
3682
+ return { ...r.contentType === "post" ? await Je(E, q) : await Ve(E, q), isTranslation: !0, languageCode: k.code };
3683
+ }
3684
+ async function on(e, t) {
3685
+ const n = he.parse(e), r = n.entityId !== void 0 || !!n.slug || !!n.title, o = C(t);
3686
+ let a, s;
3687
+ if (r) {
3688
+ const g = await te(
3689
+ {
3690
+ contentType: n.contentType,
3691
+ entityId: n.entityId,
3692
+ slug: n.slug,
3693
+ title: n.title
3694
+ },
3695
+ t
3696
+ ), f = g.item;
3697
+ s = f.id, a = {
3698
+ contentType: g.contentType,
3699
+ entityId: s,
3700
+ slug: typeof f.slug == "string" ? f.slug : "",
3701
+ title: typeof f.title == "string" ? f.title : ""
3702
+ };
3703
+ } else
3704
+ a = V(t), s = Te(a);
3705
+ const l = a.title || a.slug || "current item", u = a.contentType === "product", d = P({
3317
3706
  action: "SET IMAGES",
3318
3707
  context: t,
3319
- payload: { images: n.images, tool: "set_content_images" },
3708
+ payload: {
3709
+ contentType: a.contentType,
3710
+ entityId: String(s),
3711
+ images: n.images,
3712
+ tool: "set_content_images"
3713
+ },
3320
3714
  preview: {
3321
- contentType: r.contentType,
3715
+ contentType: a.contentType,
3322
3716
  imageCount: n.images.length,
3323
- slug: r.slug,
3324
- summary: l ? `Set ${F(
3717
+ slug: a.slug,
3718
+ summary: u ? `Set ${N(
3325
3719
  n.images.length,
3326
3720
  "image"
3327
- )} on product "${s}" (the first becomes the main product image, the rest the gallery).` : `Set the feature image on the ${r.contentType} "${s}".`,
3328
- title: r.title
3721
+ )} on product "${l}" (the first becomes the main product image, the rest the gallery).` : `Set the feature image on the ${a.contentType} "${l}".`,
3722
+ title: a.title
3329
3723
  },
3330
- subject: `set images on ${r.contentType} ${String(a)}`
3724
+ subject: `set images on ${a.contentType} ${String(s)}`
3331
3725
  });
3332
- if (u)
3333
- return u;
3334
- const d = [];
3335
- for (let m = 0; m < n.images.length; m += 1) {
3336
- const f = await J(
3337
- n.images[m],
3338
- t,
3339
- `${s} image ${m + 1}`
3340
- );
3341
- f && d.push(f);
3342
- }
3343
- if (d.length === 0)
3726
+ if (d)
3727
+ return d;
3728
+ const c = await It(n.images, t, l);
3729
+ if (c.length === 0)
3344
3730
  throw new Error("None of the provided images could be resolved to a media item.");
3345
- if (l) {
3346
- const { data: m, error: f } = await o.from("products").select("id, slug, language_id, title").eq("id", a).maybeSingle();
3347
- if (f || !m)
3348
- throw new Error(
3349
- `Could not load the product to set images: ${h(f)}`
3350
- );
3351
- const _ = [...new Set(d)], { error: k } = await o.from("product_media").delete().eq("product_id", a);
3352
- if (k)
3731
+ if (u) {
3732
+ const { data: g, error: f } = await o.from("products").select("id, slug, language_id, title").eq("id", s).maybeSingle();
3733
+ if (f || !g)
3353
3734
  throw new Error(
3354
- `Could not clear the product's existing images: ${h(k)}`
3735
+ `Could not load the product to set images: ${_(f)}`
3355
3736
  );
3356
- const { error: w } = await o.from("product_media").insert(
3357
- _.map((E, y) => ({
3358
- media_id: E,
3359
- product_id: a,
3360
- sort_order: y
3361
- }))
3362
- );
3363
- if (w)
3364
- throw new Error(`Could not save the product images: ${h(w)}`);
3365
- return N(
3737
+ const k = await Pn({
3738
+ mediaIds: c,
3739
+ productId: s,
3740
+ supabase: o
3741
+ });
3742
+ return await xe({
3743
+ patch: ({ meta: y }) => Array.isArray(y.product_media) ? {
3744
+ meta: {
3745
+ ...y,
3746
+ product_media: k.map((w, b) => ({
3747
+ media_id: w,
3748
+ sort_order: b
3749
+ }))
3750
+ }
3751
+ } : {},
3752
+ productId: s,
3753
+ supabase: o
3754
+ }), U(
3366
3755
  t,
3367
3756
  {
3368
3757
  contentType: "product",
3369
- entityId: String(a),
3370
- languageId: m.language_id,
3371
- slug: m.slug,
3372
- title: m.title
3758
+ entityId: String(s),
3759
+ languageId: g.language_id,
3760
+ slug: g.slug,
3761
+ title: g.title
3373
3762
  },
3374
- m.slug
3763
+ g.slug
3375
3764
  ), t?.revalidatePath?.("/cms/products"), {
3376
3765
  contentType: "product",
3377
- entityId: a,
3378
- imageCount: _.length,
3766
+ entityId: s,
3767
+ imageCount: k.length,
3379
3768
  mutationExecuted: !0,
3380
- slug: m.slug,
3769
+ slug: g.slug,
3381
3770
  success: !0
3382
3771
  };
3383
3772
  }
3384
- const c = r.contentType === "page" ? "pages" : "posts", { data: p, error: g } = await o.from(c).update({
3385
- feature_image_id: d[0],
3773
+ const m = a.contentType === "page" ? "pages" : "posts", { data: h, error: p } = await o.from(m).update({
3774
+ feature_image_id: c[0],
3386
3775
  updated_at: (/* @__PURE__ */ new Date()).toISOString()
3387
- }).eq("id", a).select("id, language_id, slug, status, title").single();
3388
- if (g || !p)
3389
- throw new Error(`Failed to set the feature image: ${h(g)}`);
3390
- return N(t, r, p.slug), {
3391
- contentType: r.contentType,
3392
- entityId: a,
3393
- extraImagesIgnored: d.length - 1,
3776
+ }).eq("id", s).select("id, language_id, slug, status, title").single();
3777
+ if (p || !h)
3778
+ throw new Error(`Failed to set the feature image: ${_(p)}`);
3779
+ return U(t, a, h.slug), {
3780
+ contentType: a.contentType,
3781
+ entityId: s,
3782
+ extraImagesIgnored: c.length - 1,
3394
3783
  imageCount: 1,
3395
3784
  mutationExecuted: !0,
3396
- slug: p.slug,
3785
+ slug: h.slug,
3397
3786
  success: !0
3398
3787
  };
3399
3788
  }
3400
- function zr(e) {
3789
+ function co(e) {
3401
3790
  return {
3402
- ...Vt(e),
3403
- ...Ht(e),
3404
- fetch_ecommerce_stats: T({
3791
+ ...an(e),
3792
+ ...sn(e),
3793
+ fetch_ecommerce_stats: S({
3405
3794
  description: "Fetch quantitative ecommerce statistics and reports from the database. Use this to answer questions about revenue, order counts, order status counts such as pending or trial, and top-selling products over a time range. This tool is read-only and does not require confirmation.",
3406
- execute: (t) => cr(t, e),
3407
- inputSchema: at,
3795
+ execute: (t) => wr(t, e),
3796
+ inputSchema: ft,
3408
3797
  strict: !0
3409
3798
  }),
3410
- read_current_cms_item: T({
3799
+ read_current_cms_item: S({
3411
3800
  description: "Read the CMS item currently being edited. Requires pageContext and returns page/post/product metadata plus page/post block summaries or content.",
3412
- execute: (t) => ur(t, e),
3413
- inputSchema: lt,
3801
+ execute: (t) => Ir(t, e),
3802
+ inputSchema: yt,
3414
3803
  strict: !0
3415
3804
  }),
3416
- search_documentation: T({
3805
+ search_documentation: S({
3417
3806
  description: "Search the NextBlock documentation database and return concise source snippets for factual CMS guidance.",
3418
- execute: (t) => or(t, e),
3419
- inputSchema: Pe,
3807
+ execute: (t) => hr(t, e),
3808
+ inputSchema: je,
3420
3809
  strict: !0
3421
3810
  }),
3422
- fetch_url_content: T({
3423
- description: 'Fetch the readable content (title, meta description, headings, and body text) of an external web page so you can base new CMS content on it. Read-only, no confirmation. Use this first whenever the user references an external URL to copy, adapt, or draw inspiration from, e.g. "rewrite my home page based on https://example.com".',
3424
- execute: (t) => Cr(t),
3425
- inputSchema: Mt,
3811
+ fetch_url_content: S({
3812
+ description: "Fetch an external web page and return its title, meta description, headings, body text, AND its images: `mainImage` (the page's subject image schema.org Product image, else og:image, else the best in-body <img>) plus a ranked `images` list, all as absolute URLs. Read-only, no confirmation. Use this first whenever the user references an external URL to copy, adapt, clone, or draw inspiration from. To reuse the source page's image, pass `mainImage` straight into create_cms_product `images` or a page/post `feature_image_id` it is imported into the media library automatically. Never invent an image URL: if `mainImage` is null, the page had none.",
3813
+ execute: (t) => Gr(t),
3814
+ inputSchema: Yt,
3426
3815
  strict: !0
3427
3816
  }),
3428
- search_stock_photos: T({
3817
+ search_stock_photos: S({
3429
3818
  description: "Find relevant, free, high-quality stock photos (Unsplash/Pexels) for page imagery. Returns a list of photos each with a direct image `url`, `width`, `height`, `alt`, and `photographer`. Read-only, zero cost. Use the returned `url` directly as an image block's external_url or a section image background's image.external_url when building or revamping pages, so layouts show real photos instantly. Set orientation \"landscape\" for hero/section backgrounds.",
3430
- execute: (t) => $r(t, e),
3431
- inputSchema: Dt,
3819
+ execute: (t) => Jr(t, e),
3820
+ inputSchema: tn,
3432
3821
  strict: !0
3433
3822
  }),
3434
- rewrite_page_draft: T({
3823
+ rewrite_page_draft: S({
3435
3824
  description: 'Replace ALL blocks of an existing page or post with a brand-new set of blocks, staged as a Live Draft (content_drafts) that the user previews before publishing. Use this for whole-page redesigns/rewrites such as "rewrite my home page with 5 sections". Provide the complete new list of top-level blocks in `blocks` (usually section blocks for a landing/home page, each with nested heading/text/button blocks). Nothing goes live until the user publishes the draft, and publishing auto-creates a revision snapshot so the change is reversible. Mutating: first returns a confirmation phrase; only stages the draft after the user replies with the exact phrase.',
3436
- execute: (t) => Ur(t, e),
3437
- inputSchema: Gt,
3825
+ execute: (t) => Qr(t, e),
3826
+ inputSchema: nn,
3438
3827
  strict: !0
3439
3828
  }),
3440
- translate_page: T({
3829
+ translate_page: S({
3441
3830
  description: 'Translate the CURRENT page or post into another language. This copies the source page\'s entire structure, layout, and images automatically and links the new page to the original as a translation — you ONLY supply the text translations. Provide targetLanguageCode (e.g. "fr") and a `translations` map of every visible source string to its translation (headings, paragraph text, button labels, image alt text, captions, form labels). Do NOT rebuild the layout or call search_stock_photos for a translation. Requires an open page/post. Mutating: first returns a confirmation phrase; only creates the translation after exact confirmation.',
3442
- execute: (t) => Or(t, e),
3443
- inputSchema: zt,
3831
+ execute: (t) => eo(t, e),
3832
+ inputSchema: rn,
3444
3833
  strict: !0
3445
3834
  }),
3446
- set_content_images: T({
3447
- description: "Set the feature image for the CURRENT page or post, or the image gallery for the CURRENT product. Pass `images`: a list of image URLs (e.g. `url` values returned by search_stock_photos) and/or existing media library IDs. External URLs are imported into the media library automatically — NEVER put an image URL directly into feature_image_id. The FIRST image becomes the feature image (pages/posts) or the main product image (products); for a product the remaining images become its gallery in order (this REPLACES the product's current images). Requires an open page/post/product. Mutating: first returns a confirmation phrase; only applies after exact confirmation.",
3448
- execute: (t) => jr(t, e),
3449
- inputSchema: Kt,
3835
+ set_content_images: S({
3836
+ description: "Set the feature image for a page or post, or the image gallery for a product. Pass `images`: a list of image URLs (e.g. `mainImage` from fetch_url_content or `url` values from search_stock_photos) and/or existing media library IDs. External URLs are imported into the media library automatically — NEVER put an image URL directly into feature_image_id. The FIRST image becomes the feature image (pages/posts) or the main product image (products); for a product the remaining images become its gallery in order (this REPLACES the product's current images). Targets the currently open page/post/product by default; to target any other item (for example a product you just created from the dashboard) pass contentType plus slug, entityId, or title — no open editor needed. Mutating: first returns a confirmation phrase; only applies after exact confirmation.",
3837
+ execute: (t) => on(t, e),
3838
+ inputSchema: he,
3450
3839
  strict: !0
3451
3840
  }),
3452
- create_cms_page: T({
3841
+ create_cms_page: S({
3453
3842
  description: "Create a new CMS page with metadata and optional validated page blocks. Mutating: first returns a confirmation phrase; only executes after the user replies with the exact phrase. For translations, pass translationGroupId from the source page/post/product context so the new language is linked to the same backend translation group. For contact pages, provide contactEmail or a form block with recipient_email and fields.",
3454
- execute: (t) => Me(t, e),
3455
- inputSchema: ge,
3843
+ execute: (t) => Ve(t, e),
3844
+ inputSchema: _e,
3456
3845
  strict: !0
3457
3846
  }),
3458
- create_cms_post: T({
3847
+ create_cms_post: S({
3459
3848
  description: "Create a new CMS post with metadata and optional validated post blocks. Mutating: first returns a confirmation phrase; only executes after the user replies with the exact phrase. For translations, pass translationGroupId from the source post context so the new language is linked to the same backend translation group.",
3460
- execute: (t) => De(t, e),
3461
- inputSchema: fe,
3849
+ execute: (t) => Je(t, e),
3850
+ inputSchema: be,
3462
3851
  strict: !0
3463
3852
  }),
3464
- create_cms_product: T({
3465
- description: "Create a new draft-capable product. Defaults missing product fields safely: physical Stripe product, generated SKU, price 0, stock 0, taxable, draft. For translations, pass translationGroupId from the source product context. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3466
- execute: (t) => jt(t, e),
3467
- inputSchema: he,
3853
+ create_cms_product: S({
3854
+ description: "Create a new draft-capable product, complete with its images and its body copy in ONE call. Pass `images` to set the main product image and gallery (external https URLs are imported into the media library automatically — use `mainImage` from fetch_url_content to reuse a source page's photo). Pass `blocks` to build the product's \"Product Description Blocks\" — the SAME block vocabulary and section-based design rules as create_cms_page, rendered on the public product page. This is the richest product body and is what you should produce whenever the user asks to copy or write real product content. Also pass `short_description` for the one-line summary shown on product cards. `description_html` is a plain-HTML fallback body used only when no blocks are supplied. Defaults missing fields safely: physical Stripe product, generated SKU, price 0, stock 0, taxable, draft. `price` is in major units (25 = $25.00). For translations, pass translationGroupId from the source product context. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3855
+ execute: (t) => Kt(t, e),
3856
+ inputSchema: ke,
3468
3857
  strict: !0
3469
3858
  }),
3470
- delete_cms_item: T({
3859
+ delete_cms_item: S({
3471
3860
  description: "Delete a resolved page, post, or product after exact confirmation. Pages/posts delete all translations in the translation group and related navigation links. Mutating: refuses unless the latest user message includes the exact confirmation phrase.",
3472
- execute: (t) => Rt(t, e),
3473
- inputSchema: ye,
3861
+ execute: (t) => Wt(t, e),
3862
+ inputSchema: Ie,
3474
3863
  strict: !0
3475
3864
  }),
3476
- prepare_delete_cms_item: T({
3865
+ prepare_delete_cms_item: S({
3477
3866
  description: "Inspect the page, post, or product that would be deleted and return the exact confirmation phrase. This tool does not mutate data.",
3478
- execute: (t) => kr(t, e),
3479
- inputSchema: ct,
3867
+ execute: (t) => Ur(t, e),
3868
+ inputSchema: _t,
3480
3869
  strict: !0
3481
3870
  }),
3482
- update_footer: T({
3871
+ update_footer: S({
3483
3872
  description: "Replace the public footer links and/or footer copyright settings for a locale. Use links for footer navigation and copyright for locale text templates. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3484
- execute: (t) => vt(t, e),
3485
- inputSchema: le,
3873
+ execute: (t) => Ft(t, e),
3874
+ inputSchema: pe,
3486
3875
  strict: !0
3487
3876
  }),
3488
- update_content_block: T({
3877
+ update_content_block: S({
3489
3878
  description: 'Update the JSON content of an existing top-level page/post block that belongs to the current CMS edit context. Content is merged with the existing block before validation. For section blocks, add nested blocks with content.append_block or content.append_blocks using objects like { block_type: "button", content: { text: "Contact Us", url: "/contact" } }; existing column_blocks and layout fields are preserved. Mutating: first returns a confirmation phrase; only executes after exact confirmation.',
3490
- execute: (t) => Nt(t, e),
3491
- inputSchema: ue,
3879
+ execute: (t) => Mt(t, e),
3880
+ inputSchema: ge,
3492
3881
  strict: !0
3493
3882
  }),
3494
- insert_content_block: T({
3883
+ insert_content_block: S({
3495
3884
  description: 'Insert a new validated top-level page/post block before or after an existing block, or at the start/end. Use this for visible content additions like adding a rich text title and paragraph above a form. For "above the form", use position "before" with anchorBlockType "form" and blockType "text" containing html_content. Mutating: first returns a confirmation phrase; only executes after exact confirmation.',
3496
- execute: (t) => Ut(t, e),
3497
- inputSchema: me,
3885
+ execute: (t) => Dt(t, e),
3886
+ inputSchema: ye,
3498
3887
  strict: !0
3499
3888
  }),
3500
- update_current_cms_fields: T({
3889
+ update_current_cms_fields: S({
3501
3890
  description: "Update validated metadata fields on the current page, post, or product. For products, description_json must be a valid NextBlock editor document JSON object. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3502
- execute: (t) => Pt(t, e),
3503
- inputSchema: ce,
3891
+ execute: (t) => qt(t, e),
3892
+ inputSchema: me,
3504
3893
  strict: !0
3505
3894
  }),
3506
- update_cms_item_field: T({
3895
+ update_cms_item_field: S({
3507
3896
  description: "Update one field on a page, post, or product, resolving by current edit context, id, slug, or exact title. Use this for requests like changing price, stock, title, slug, status, sale_price, or meta fields. Interpret public as published for pages/posts and active for products. Scheduled sale date ranges are not supported and will be refused without mutation. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3508
- execute: (t) => qt(t, e),
3509
- inputSchema: _e,
3897
+ execute: (t) => Ht(t, e),
3898
+ inputSchema: we,
3510
3899
  strict: !0
3511
3900
  }),
3512
- update_navigation_bar: T({
3901
+ update_navigation_bar: S({
3513
3902
  description: 'Update the public header navigation bar for a locale. Use mode "append" when adding links while preserving existing navigation. Use mode "update" when renaming or changing an existing single link. Use mode "replace" only when the user asks to rebuild the complete header and you provide the full menu; destructive partial replacements are refused. Mutating: first returns a confirmation phrase; only executes after exact confirmation.',
3514
- execute: (t) => Ct(t, e),
3515
- inputSchema: se,
3903
+ execute: (t) => Ot(t, e),
3904
+ inputSchema: de,
3516
3905
  strict: !0
3517
3906
  }),
3518
- update_section_column_block: T({
3907
+ update_section_column_block: S({
3519
3908
  description: "Update the content of one existing nested block inside a section block that belongs to the current CMS edit context. This tool must not change the nested block type. To add a new nested block, update the parent section with update_content_block and preserve existing column_blocks. Mutating: first returns a confirmation phrase; only executes after exact confirmation.",
3520
- execute: (t) => Ft(t, e),
3521
- inputSchema: de,
3909
+ execute: (t) => zt(t, e),
3910
+ inputSchema: fe,
3522
3911
  strict: !0
3523
3912
  }),
3524
- execute_cms_action_plan: T({
3913
+ execute_cms_action_plan: S({
3525
3914
  description: "Execute multiple CMS mutations as one confirmed plan. Use this whenever the user asks for more than one change in the same prompt, such as creating a page and adding a navigation link. First returns one combined confirmation preview and Confirm button; after confirmation, runs each action in order and stops on the first failure.",
3526
- execute: (t) => Ir(t, e),
3527
- inputSchema: dt,
3915
+ execute: (t) => jr(t, e),
3916
+ inputSchema: kt,
3528
3917
  strict: !0
3529
3918
  })
3530
3919
  };
3531
3920
  }
3532
3921
  export {
3533
- M as availableCortexAiBlockTypes,
3534
- Dr as buildVisibleContactIntroActionPlan,
3535
- st as cortexAiPageContextSchema,
3536
- ge as createCmsPageInputSchema,
3537
- fe as createCmsPostInputSchema,
3538
- he as createCmsProductInputSchema,
3539
- zr as createCortexGlobalAgentTools,
3540
- ye as deleteCmsItemInputSchema,
3541
- Ir as executeCmsActionPlan,
3542
- dt as executeCmsActionPlanInputSchema,
3543
- Me as executeCreateCmsPage,
3544
- De as executeCreateCmsPost,
3545
- jt as executeCreateCmsProduct,
3546
- Rt as executeDeleteCmsItem,
3547
- cr as executeFetchEcommerceStats,
3548
- Cr as executeFetchUrlContent,
3549
- Ut as executeInsertContentBlock,
3550
- kr as executePrepareDeleteCmsItem,
3551
- ur as executeReadCurrentCmsItem,
3552
- Ur as executeRewritePageDraft,
3553
- rr as executeSearchDocumentation,
3554
- or as executeSearchDocumentationWithTimeout,
3555
- $r as executeSearchStockPhotos,
3556
- jr as executeSetContentImages,
3557
- Or as executeTranslatePage,
3558
- qt as executeUpdateCmsItemField,
3559
- Nt as executeUpdateContentBlock,
3560
- Pt as executeUpdateCurrentCmsFields,
3561
- vt as executeUpdateFooter,
3562
- Ct as executeUpdateNavigationBar,
3563
- Ft as executeUpdateSectionColumnBlock,
3564
- at as fetchEcommerceStatsInputSchema,
3565
- Mt as fetchUrlContentInputSchema,
3566
- me as insertContentBlockInputSchema,
3567
- Ie as maybeTriggerStockPhotoDownloads,
3568
- it as navigationItemInputSchema,
3569
- ct as prepareDeleteCmsItemInputSchema,
3570
- lt as readCurrentCmsItemInputSchema,
3571
- Gr as resolveCortexAiStockPhotoProvider,
3572
- ze as resolveCortexAiStockPhotoProviders,
3573
- Gt as rewritePageDraftInputSchema,
3574
- Pe as searchDocumentationInputSchema,
3575
- Dt as searchStockPhotosInputSchema,
3576
- zt as translatePageInputSchema,
3577
- _e as updateCmsItemFieldInputSchema,
3578
- ue as updateContentBlockInputSchema,
3579
- ce as updateCurrentCmsFieldsInputSchema,
3580
- le as updateFooterInputSchema,
3581
- se as updateNavigationBarInputSchema,
3582
- de as updateSectionColumnBlockInputSchema
3922
+ K as availableCortexAiBlockTypes,
3923
+ so as buildVisibleContactIntroActionPlan,
3924
+ ht as cortexAiPageContextSchema,
3925
+ _e as createCmsPageInputSchema,
3926
+ be as createCmsPostInputSchema,
3927
+ ke as createCmsProductInputSchema,
3928
+ co as createCortexGlobalAgentTools,
3929
+ Ie as deleteCmsItemInputSchema,
3930
+ jr as executeCmsActionPlan,
3931
+ kt as executeCmsActionPlanInputSchema,
3932
+ Ve as executeCreateCmsPage,
3933
+ Je as executeCreateCmsPost,
3934
+ Kt as executeCreateCmsProduct,
3935
+ Wt as executeDeleteCmsItem,
3936
+ wr as executeFetchEcommerceStats,
3937
+ Gr as executeFetchUrlContent,
3938
+ Dt as executeInsertContentBlock,
3939
+ Ur as executePrepareDeleteCmsItem,
3940
+ Ir as executeReadCurrentCmsItem,
3941
+ Qr as executeRewritePageDraft,
3942
+ fr as executeSearchDocumentation,
3943
+ hr as executeSearchDocumentationWithTimeout,
3944
+ Jr as executeSearchStockPhotos,
3945
+ on as executeSetContentImages,
3946
+ eo as executeTranslatePage,
3947
+ Ht as executeUpdateCmsItemField,
3948
+ Mt as executeUpdateContentBlock,
3949
+ qt as executeUpdateCurrentCmsFields,
3950
+ Ft as executeUpdateFooter,
3951
+ Ot as executeUpdateNavigationBar,
3952
+ zt as executeUpdateSectionColumnBlock,
3953
+ ft as fetchEcommerceStatsInputSchema,
3954
+ Yt as fetchUrlContentInputSchema,
3955
+ ye as insertContentBlockInputSchema,
3956
+ ve as maybeTriggerStockPhotoDownloads,
3957
+ gt as navigationItemInputSchema,
3958
+ _t as prepareDeleteCmsItemInputSchema,
3959
+ yt as readCurrentCmsItemInputSchema,
3960
+ lo as resolveCortexAiStockPhotoProvider,
3961
+ Ye as resolveCortexAiStockPhotoProviders,
3962
+ nn as rewritePageDraftInputSchema,
3963
+ je as searchDocumentationInputSchema,
3964
+ tn as searchStockPhotosInputSchema,
3965
+ he as setContentImagesInputSchema,
3966
+ rn as translatePageInputSchema,
3967
+ we as updateCmsItemFieldInputSchema,
3968
+ ge as updateContentBlockInputSchema,
3969
+ me as updateCurrentCmsFieldsInputSchema,
3970
+ pe as updateFooterInputSchema,
3971
+ de as updateNavigationBarInputSchema,
3972
+ fe as updateSectionColumnBlockInputSchema
3583
3973
  };