@brightsideoy/kama 1.0.0-alpha.2 → 1.0.0-alpha.3

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.
package/dist/index.js CHANGED
@@ -185,13 +185,13 @@ function C(e) {
185
185
  let t = new g();
186
186
  return e.forEach((e) => t.put(e)), [...t.values()];
187
187
  }
188
- function w(e) {
188
+ function ee(e) {
189
189
  return typeof e == "string";
190
190
  }
191
- function T(e) {
191
+ function w(e) {
192
192
  return Object.fromEntries(Object.entries(e).sort(([e], [t]) => e.localeCompare(t)));
193
193
  }
194
- var ee = m(), E = class {
194
+ var T = m(), E = class {
195
195
  static collectMetadata(e, t) {
196
196
  let n = this.getMetadataFromRegistry(e), r = Object.assign(Object.assign({}, n?._internal), t?._internal), i = Object.assign(Object.assign({}, n?.param), t?.param), a = Object.assign(Object.assign(Object.assign(Object.assign({}, Object.keys(r).length > 0 ? { _internal: r } : {}), n), t), Object.keys(i).length > 0 ? { param: i } : {});
197
197
  if (l(e, [
@@ -259,7 +259,7 @@ var ee = m(), E = class {
259
259
  return t ? void 0 : e;
260
260
  }
261
261
  static getMetadataFromInternalRegistry(e) {
262
- return ee.get(e);
262
+ return T.get(e);
263
263
  }
264
264
  static getMetadataFromRegistry(e) {
265
265
  let t = this.getMetadataFromInternalRegistry(e), n = e.meta();
@@ -268,7 +268,7 @@ var ee = m(), E = class {
268
268
  return Object.assign(Object.assign(Object.assign({ _internal: Object.assign(Object.assign({}, o ? { refId: o } : {}), r) }, i), c ? { description: c } : {}), l);
269
269
  }
270
270
  static setMetadataInRegistry(e, t) {
271
- ee.add(e, t);
271
+ T.add(e, t);
272
272
  }
273
273
  };
274
274
  function D(e, t) {
@@ -280,7 +280,7 @@ function D(e, t) {
280
280
  }
281
281
  function te(e) {
282
282
  e.ZodType.prototype.openapi === void 0 && (e.ZodType.prototype.openapi = function(...e) {
283
- let { refId: t, metadata: n, options: r } = O(...e), i = n ?? {}, { param: a } = i, o = s(i, ["param"]), c = E.getMetadataFromRegistry(this) ?? {}, { _internal: u } = c, d = s(c, ["_internal"]), f = Object.assign(Object.assign(Object.assign({}, u), r), t ? { refId: t } : void 0), p = Object.assign(Object.assign(Object.assign({}, d), o), d?.param || a ? { param: Object.assign(Object.assign({}, d?.param), a) } : void 0), m = new this.constructor(this._def);
283
+ let { refId: t, metadata: n, options: r } = ne(...e), i = n ?? {}, { param: a } = i, o = s(i, ["param"]), c = E.getMetadataFromRegistry(this) ?? {}, { _internal: u } = c, d = s(c, ["_internal"]), f = Object.assign(Object.assign(Object.assign({}, u), r), t ? { refId: t } : void 0), p = Object.assign(Object.assign(Object.assign({}, d), o), d?.param || a ? { param: Object.assign(Object.assign({}, d?.param), a) } : void 0), m = new this.constructor(this._def);
284
284
  function h(e) {
285
285
  E.setMetadataInRegistry(e, Object.assign(Object.assign({}, Object.keys(f).length > 0 ? { _internal: f } : void 0), p));
286
286
  }
@@ -306,7 +306,7 @@ function te(e) {
306
306
  }, m;
307
307
  });
308
308
  }
309
- function O(e, t, n) {
309
+ function ne(e, t, n) {
310
310
  return typeof e == "string" ? {
311
311
  refId: e,
312
312
  metadata: t,
@@ -317,10 +317,10 @@ function O(e, t, n) {
317
317
  options: t
318
318
  };
319
319
  }
320
- function k(e) {
320
+ function O(e) {
321
321
  return b(E.getOpenApiMetadata(e) ?? {}, _);
322
322
  }
323
- var A = class {
323
+ var k = class {
324
324
  constructor(e) {
325
325
  this.parents = e, this._definitions = [];
326
326
  }
@@ -367,31 +367,31 @@ var A = class {
367
367
  schemaWithRefId(e, t) {
368
368
  return t.openapi(e);
369
369
  }
370
- }, j = class {
370
+ }, A = class {
371
371
  constructor(e) {
372
372
  this.message = e;
373
373
  }
374
- }, ne = class extends j {
374
+ }, re = class extends A {
375
375
  constructor(e, t) {
376
376
  super(e), this.data = t;
377
377
  }
378
- }, re = class extends j {
378
+ }, ie = class extends A {
379
379
  constructor(e) {
380
380
  super(`Missing parameter data, please specify \`${e.missingField}\` and other OpenAPI parameter props using the \`param\` field of \`schema.openapi\``), this.data = e;
381
381
  }
382
382
  };
383
- function ie(e, t) {
383
+ function ae(e, t) {
384
384
  try {
385
385
  return e();
386
386
  } catch (e) {
387
- throw e instanceof re ? new re(Object.assign(Object.assign({}, e.data), t)) : e;
387
+ throw e instanceof ie ? new ie(Object.assign(Object.assign({}, e.data), t)) : e;
388
388
  }
389
389
  }
390
- var ae = class extends j {
390
+ var oe = class extends A {
391
391
  constructor(e) {
392
392
  super("Unknown zod object type, please specify `type` and other OpenAPI props using `schema.openapi`."), this.data = e;
393
393
  }
394
- }, oe = class {
394
+ }, se = class {
395
395
  transform(e, t, n) {
396
396
  let r = e.def.element, i = (e.def.checks?.find((e) => e._zod.def.check === "min_length"))?._zod.def.minimum, a = (e.def.checks?.find((e) => e._zod.def.check === "max_length"))?._zod.def.maximum;
397
397
  return Object.assign(Object.assign({}, t("array")), {
@@ -400,11 +400,11 @@ var ae = class extends j {
400
400
  maxItems: a
401
401
  });
402
402
  }
403
- }, se = class {
403
+ }, ce = class {
404
404
  transform(e) {
405
405
  return Object.assign(Object.assign({}, e("string")), { pattern: "^\\d+$" });
406
406
  }
407
- }, ce = class {
407
+ }, le = class {
408
408
  transform(e, t, n, r, i) {
409
409
  let a = e.def.options.filter(u), o = a.map(r);
410
410
  if (t) return { oneOf: n(o, t) };
@@ -429,7 +429,7 @@ var ae = class extends j {
429
429
  getDiscriminatorValues(e, t) {
430
430
  if (l(e, "ZodObject")) {
431
431
  let n = e.def.shape?.[t];
432
- return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(w) : l(n, "ZodLiteral") ? n.def.values.filter(w) : [] : [];
432
+ return n ? l(n, "ZodEnum") ? Object.values(n._zod.def.entries).filter(ee) : l(n, "ZodLiteral") ? n.def.values.filter(ee) : [] : [];
433
433
  }
434
434
  if (l(e, "ZodDiscriminatedUnion")) {
435
435
  let n = e.def.options.filter(u);
@@ -438,7 +438,7 @@ var ae = class extends j {
438
438
  return [];
439
439
  }
440
440
  };
441
- function le(e) {
441
+ function j(e) {
442
442
  let t = Object.keys(e).filter((t) => typeof e[e[t]] != "number").map((t) => e[t]), n = t.filter((e) => typeof e == "number").length;
443
443
  return {
444
444
  values: t,
@@ -447,8 +447,8 @@ function le(e) {
447
447
  }
448
448
  var ue = class {
449
449
  transform(e, t, n) {
450
- let { type: r, values: i } = le(e._zod.def.entries);
451
- if (r === "mixed") throw new j("Enum has mixed string and number values, please specify the OpenAPI type manually");
450
+ let { type: r, values: i } = j(e._zod.def.entries);
451
+ if (r === "mixed") throw new A("Enum has mixed string and number values, please specify the OpenAPI type manually");
452
452
  return Object.assign(Object.assign({}, n(r === "numeric" ? "integer" : "string")), { enum: t ? [...i, null] : i });
453
453
  }
454
454
  }, de = class {
@@ -463,7 +463,7 @@ var ue = class {
463
463
  }
464
464
  }, fe = class {
465
465
  constructor() {
466
- this.bigIntTransformer = new se();
466
+ this.bigIntTransformer = new ce();
467
467
  }
468
468
  transform(e, t) {
469
469
  let n = typeof e.def.values[0];
@@ -499,7 +499,7 @@ var ue = class {
499
499
  transform(e, t, n) {
500
500
  let r = e.valueType, i = e.keyType, a = u(r) ? n(r) : {};
501
501
  if (l(i, "ZodEnum")) {
502
- let e = Object.values(i._zod.def.entries).filter(w).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
502
+ let e = Object.values(i._zod.def.entries).filter(ee).reduce((e, t) => Object.assign(Object.assign({}, e), { [t]: a }), {});
503
503
  return Object.assign(Object.assign({}, t("object")), { properties: e });
504
504
  }
505
505
  return Object.assign(Object.assign({}, t("object")), { additionalProperties: a });
@@ -590,7 +590,7 @@ var ve = class {
590
590
  if (l(e, "ZodNumber")) return "[+-]?\\d+(\\.\\d+)?";
591
591
  if (l(e, "ZodBoolean")) return "(true|false)";
592
592
  if (l(e, "ZodEnum")) {
593
- let { values: t } = le(e.def.entries);
593
+ let { values: t } = j(e.def.entries);
594
594
  return `(${t.map((e) => this.escapeRegex(String(e))).join("|")})`;
595
595
  }
596
596
  return ".*";
@@ -600,7 +600,7 @@ var ve = class {
600
600
  }
601
601
  }, we = class {
602
602
  constructor(e, t) {
603
- this.versionSpecifics = e, this.objectTransformer = new me(), this.stringTransformer = new ve(), this.numberTransformer = new pe(), this.bigIntTransformer = new se(), this.dateTransformer = new xe(), this.lazyTransformer = new Se(), this.literalTransformer = new fe(), this.templateLiteralTransformer = new Ce(), this.enumTransformer = new ue(), this.arrayTransformer = new oe(), this.discriminatedUnionTransformer = new ce(), this.intersectionTransformer = new de(), this.recordTransformer = new he(), this.tupleTransformer = new ye(e), this.unionTransformer = new be(t);
603
+ this.versionSpecifics = e, this.objectTransformer = new me(), this.stringTransformer = new ve(), this.numberTransformer = new pe(), this.bigIntTransformer = new ce(), this.dateTransformer = new xe(), this.lazyTransformer = new Se(), this.literalTransformer = new fe(), this.templateLiteralTransformer = new Ce(), this.enumTransformer = new ue(), this.arrayTransformer = new se(), this.discriminatedUnionTransformer = new le(), this.intersectionTransformer = new de(), this.recordTransformer = new he(), this.tupleTransformer = new ye(e), this.unionTransformer = new be(t);
604
604
  }
605
605
  transform(e, t, n, r, i) {
606
606
  if (l(e, "ZodNull")) return this.versionSpecifics.nullType;
@@ -627,7 +627,7 @@ var ve = class {
627
627
  if (l(e, "ZodRecord")) return this.recordTransformer.transform(e, (e) => this.versionSpecifics.mapNullableType(e, t), n);
628
628
  if (l(e, "ZodDate")) return this.dateTransformer.transform((e) => this.versionSpecifics.mapNullableType(e, t));
629
629
  let i = E.getRefId(e);
630
- throw new ae({
630
+ throw new oe({
631
631
  currentSchema: e.def,
632
632
  schemaName: i
633
633
  });
@@ -650,7 +650,7 @@ var ve = class {
650
650
  this.rawComponents.forEach(({ componentType: t, name: n, component: r }) => {
651
651
  e[t] ?? (e[t] = {}), e[t][n] = r;
652
652
  });
653
- let t = e.schemas ?? {}, n = Object.assign(Object.assign({}, t), this.filteredSchemaRefs), r = this.options?.sortComponents === "alphabetically" ? T(n) : n, i = e.parameters ?? {}, a = Object.assign(Object.assign({}, i), this.paramRefs), o = this.options?.sortComponents === "alphabetically" ? T(a) : a;
653
+ let t = e.schemas ?? {}, n = Object.assign(Object.assign({}, t), this.filteredSchemaRefs), r = this.options?.sortComponents === "alphabetically" ? w(n) : n, i = e.parameters ?? {}, a = Object.assign(Object.assign({}, i), this.paramRefs), o = this.options?.sortComponents === "alphabetically" ? w(a) : a;
654
654
  return Object.assign(Object.assign({}, e), {
655
655
  schemas: r,
656
656
  parameters: o
@@ -700,7 +700,7 @@ var ve = class {
700
700
  getParameterRef(e, t) {
701
701
  let n = E.getOpenApiMetadata(e), r = E.getInternalMetadata(e), i = n?.param, a = r?.refId ? this.paramRefs[r.refId] : void 0;
702
702
  if (!(!r?.refId || !a)) {
703
- if (i && a.in !== i.in || t?.in && a.in !== t.in) throw new ne(`Conflicting location for parameter ${a.name}`, {
703
+ if (i && a.in !== i.in || t?.in && a.in !== t.in) throw new re(`Conflicting location for parameter ${a.name}`, {
704
704
  key: "in",
705
705
  values: x([
706
706
  a.in,
@@ -708,7 +708,7 @@ var ve = class {
708
708
  i?.in
709
709
  ])
710
710
  });
711
- if (i && a.name !== i.name || t?.name && a.name !== t?.name) throw new ne("Conflicting names for parameter", {
711
+ if (i && a.name !== i.name || t?.name && a.name !== t?.name) throw new re("Conflicting names for parameter", {
712
712
  key: "name",
713
713
  values: x([
714
714
  a.name,
@@ -731,11 +731,11 @@ var ve = class {
731
731
  });
732
732
  if (i) return i;
733
733
  let a = r?.param;
734
- if (a?.name && a.name !== e) throw new ne("Conflicting names for parameter", {
734
+ if (a?.name && a.name !== e) throw new re("Conflicting names for parameter", {
735
735
  key: "name",
736
736
  values: [e, a.name]
737
737
  });
738
- if (a?.in && a.in !== t) throw new ne(`Conflicting location for parameter ${a.name ?? e}`, {
738
+ if (a?.in && a.in !== t) throw new re(`Conflicting location for parameter ${a.name ?? e}`, {
739
739
  key: "in",
740
740
  values: [t, a.in]
741
741
  });
@@ -745,7 +745,7 @@ var ve = class {
745
745
  });
746
746
  });
747
747
  }
748
- if (n?.in && n.in !== t) throw new ne(`Conflicting location for parameter ${n.name}`, {
748
+ if (n?.in && n.in !== t) throw new re(`Conflicting location for parameter ${n.name}`, {
749
749
  key: "in",
750
750
  values: [t, n.in]
751
751
  });
@@ -760,8 +760,8 @@ var ve = class {
760
760
  }
761
761
  generateParameter(e, t) {
762
762
  let n = E.getOpenApiMetadata(e)?.param, r = t?.name ?? n?.name, i = t?.in ?? n?.in;
763
- if (!r) throw new re({ missingField: "name" });
764
- if (!i) throw new re({
763
+ if (!r) throw new ie({ missingField: "name" });
764
+ if (!i) throw new ie({
765
765
  missingField: "in",
766
766
  paramName: r
767
767
  });
@@ -817,7 +817,7 @@ var ve = class {
817
817
  }
818
818
  getParameters(e) {
819
819
  if (!e) return [];
820
- let { headers: t } = e, n = this.cleanParameter(e.query), r = this.cleanParameter(e.params), i = this.cleanParameter(e.cookies), a = ie(() => n ? this.generateInlineParameters(n, "query") : [], { location: "query" }), o = ie(() => r ? this.generateInlineParameters(r, "path") : [], { location: "path" }), s = ie(() => i ? this.generateInlineParameters(i, "cookie") : [], { location: "cookie" }), c = ie(() => {
820
+ let { headers: t } = e, n = this.cleanParameter(e.query), r = this.cleanParameter(e.params), i = this.cleanParameter(e.cookies), a = ae(() => n ? this.generateInlineParameters(n, "query") : [], { location: "query" }), o = ae(() => r ? this.generateInlineParameters(r, "path") : [], { location: "path" }), s = ae(() => i ? this.generateInlineParameters(i, "cookie") : [], { location: "cookie" }), c = ae(() => {
821
821
  if (Array.isArray(t)) return t.flatMap((e) => this.generateInlineParameters(e, "header"));
822
822
  let e = this.cleanParameter(t);
823
823
  return e ? this.generateInlineParameters(e, "header") : [];
@@ -844,7 +844,7 @@ var ve = class {
844
844
  "path",
845
845
  "request",
846
846
  "responses"
847
- ]), o = v(i, (e) => this.getResponse(e)), c = ie(() => this.getParameters(r), { route: `${t} ${n}` }), l = this.getRequestBody(r?.body);
847
+ ]), o = v(i, (e) => this.getResponse(e)), c = ae(() => this.getParameters(r), { route: `${t} ${n}` }), l = this.getRequestBody(r?.body);
848
848
  return { [t]: Object.assign(Object.assign(Object.assign(Object.assign({}, a), c.length > 0 ? { parameters: [...a.parameters || [], ...c] } : {}), l ? { requestBody: l } : {}), { responses: o }) };
849
849
  }
850
850
  generateSingleRoute(e) {
@@ -16567,7 +16567,7 @@ var $y = class t extends e {
16567
16567
  defaultHook;
16568
16568
  #e;
16569
16569
  constructor(e) {
16570
- super(e), this.openAPIRegistry = new A(), this.defaultHook = e?.defaultHook;
16570
+ super(e), this.openAPIRegistry = new k(), this.defaultHook = e?.defaultHook;
16571
16571
  }
16572
16572
  #t() {
16573
16573
  if (this.defaultHook) return this.defaultHook;
@@ -16682,8 +16682,8 @@ var $y = class t extends e {
16682
16682
  path: Me(r, n._basePath.replaceAll(/:([^\/]+)/g, "{$1}"), e.webhook.path)
16683
16683
  });
16684
16684
  return;
16685
- case "schema": return this.openAPIRegistry.register(k(e.schema)._internal?.refId, e.schema);
16686
- case "parameter": return this.openAPIRegistry.registerParameter(k(e.schema)._internal?.refId, e.schema);
16685
+ case "schema": return this.openAPIRegistry.register(O(e.schema)._internal?.refId, e.schema);
16686
+ case "parameter": return this.openAPIRegistry.registerParameter(O(e.schema)._internal?.refId, e.schema);
16687
16687
  default: throw Error(`Unknown registry type: ${e}`);
16688
16688
  }
16689
16689
  }), this) : this;
@@ -20030,6 +20030,13 @@ var Tb = /* @__PURE__ */ o({
20030
20030
  public: !0,
20031
20031
  rules: {}
20032
20032
  },
20033
+ channelRoot: {
20034
+ label: "Channel Root",
20035
+ type: "link",
20036
+ public: !0,
20037
+ allowedLinkTypes: ["node"],
20038
+ rules: {}
20039
+ },
20033
20040
  currency: {
20034
20041
  label: "Default Currency",
20035
20042
  type: "select",
@@ -20159,6 +20166,13 @@ var Tb = /* @__PURE__ */ o({
20159
20166
  public: !0,
20160
20167
  rules: {}
20161
20168
  },
20169
+ channelRoot: {
20170
+ label: "Channel Root",
20171
+ type: "link",
20172
+ public: !0,
20173
+ allowedLinkTypes: ["node"],
20174
+ rules: {}
20175
+ },
20162
20176
  currency: {
20163
20177
  label: "Default Currency",
20164
20178
  type: "select",
@@ -20282,6 +20296,13 @@ var Tb = /* @__PURE__ */ o({
20282
20296
  dbType: "json",
20283
20297
  public: !0,
20284
20298
  rules: {}
20299
+ },
20300
+ channelRoot: {
20301
+ label: "Channel Root",
20302
+ type: "link",
20303
+ public: !0,
20304
+ allowedLinkTypes: ["node"],
20305
+ rules: {}
20285
20306
  }
20286
20307
  }
20287
20308
  },
@@ -20424,6 +20445,13 @@ var Tb = /* @__PURE__ */ o({
20424
20445
  public: !0,
20425
20446
  rules: {}
20426
20447
  },
20448
+ channelRoot: {
20449
+ label: "Channel Root",
20450
+ type: "link",
20451
+ public: !0,
20452
+ allowedLinkTypes: ["node"],
20453
+ rules: {}
20454
+ },
20427
20455
  favicon: {
20428
20456
  label: "Favicon",
20429
20457
  type: "image",
@@ -21330,6 +21358,12 @@ var Tb = /* @__PURE__ */ o({
21330
21358
  multiple: !0,
21331
21359
  dbType: "json",
21332
21360
  public: !0
21361
+ },
21362
+ channelRoot: {
21363
+ label: "Channel Root",
21364
+ type: "link",
21365
+ public: !0,
21366
+ allowedLinkTypes: ["node"]
21333
21367
  }
21334
21368
  }
21335
21369
  },
@@ -21775,7 +21809,7 @@ var Tb = /* @__PURE__ */ o({
21775
21809
  userTemplate: null
21776
21810
  }, Db = Eb, Ob = {
21777
21811
  content_schemas: "\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n type TEXT UNIQUE NOT NULL,\n schemaJson TEXT NOT NULL,\n isSystem INTEGER DEFAULT 1,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
21778
- users: "\n id TEXT PRIMARY KEY,\n email TEXT UNIQUE NOT NULL,\n name TEXT NOT NULL,\n globalRole TEXT DEFAULT 'editor',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
21812
+ users: "\n id TEXT PRIMARY KEY,\n email UNIQUE NOT NULL,\n name TEXT NOT NULL,\n globalRole TEXT DEFAULT 'editor',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n ",
21779
21813
  user_accounts: "\n id TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n provider TEXT NOT NULL,\n providerAccountId TEXT NOT NULL,\n passwordHash TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE,\n UNIQUE(provider, providerAccountId)\n ",
21780
21814
  sessions: "\n id TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n expiresAt TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE\n ",
21781
21815
  channels: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT UNIQUE NOT NULL,\n label TEXT NOT NULL,\n channelType TEXT,\n domain TEXT,\n baseUrl TEXT,\n defaultLanguage TEXT,\n isHidden INTEGER NOT NULL DEFAULT 0,\n dataJson TEXT,\n createdById TEXT,\n updatedById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL,\n FOREIGN KEY (updatedById) REFERENCES users(id) ON DELETE SET NULL\n ",
@@ -21789,8 +21823,9 @@ var Tb = /* @__PURE__ */ o({
21789
21823
  assets: "\n id TEXT PRIMARY KEY,\n filename TEXT NOT NULL,\n mimeType TEXT NOT NULL,\n sizeBytes INTEGER NOT NULL,\n storageKeyPrivate TEXT,\n cdnUrl TEXT,\n parentAssetId TEXT,\n cropCoordinatesJson TEXT,\n isSystemVariant INTEGER DEFAULT 0,\n dataJson TEXT DEFAULT '{}',\n createdById TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n deletedAt TEXT,\n FOREIGN KEY (parentAssetId) REFERENCES assets(id) ON DELETE SET NULL,\n FOREIGN KEY (createdById) REFERENCES users(id) ON DELETE SET NULL\n ",
21790
21824
  node_assets: "\n nodeId INTEGER NOT NULL,\n assetId TEXT NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (nodeId, assetId, fieldKey),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (assetId) REFERENCES assets(id) ON DELETE CASCADE\n ",
21791
21825
  taxonomy_terms: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n taxonomy TEXT NOT NULL,\n key TEXT NOT NULL,\n label TEXT NOT NULL,\n parentId INTEGER,\n sortOrder INTEGER DEFAULT 0,\n dataJson TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (parentId) REFERENCES taxonomy_terms(id) ON DELETE CASCADE,\n UNIQUE(taxonomy, key)\n ",
21792
- node_terms: "\n nodeId INTEGER NOT NULL,\n termId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (nodeId, termId, fieldKey),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (termId) REFERENCES taxonomy_terms(id) ON DELETE CASCADE\n "
21793
- }, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);".split(".");
21826
+ node_terms: "\n nodeId INTEGER NOT NULL,\n termId INTEGER NOT NULL,\n fieldKey TEXT NOT NULL,\n sortOrder INTEGER DEFAULT 0,\n PRIMARY KEY (nodeId, termId, fieldKey),\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (termId) REFERENCES taxonomy_terms(id) ON DELETE CASCADE\n ",
21827
+ node_routes: "\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n channelId INTEGER NOT NULL,\n nodeId INTEGER,\n treeId INTEGER,\n isCanonical INTEGER DEFAULT 1,\n redirectUrl TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (channelId) REFERENCES channels(id) ON DELETE CASCADE,\n FOREIGN KEY (nodeId) REFERENCES content_nodes(id) ON DELETE CASCADE,\n FOREIGN KEY (treeId) REFERENCES trees(id) ON DELETE CASCADE,\n UNIQUE(path, channelId)\n "
21828
+ }, kb = /* @__PURE__ */ "CREATE INDEX IF NOT EXISTS idx_tree_nodes_tree_parent ON tree_nodes(treeId, parentId);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_contentId ON tree_nodes(contentId);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug_status ON content_nodes(slug, status);.CREATE INDEX IF NOT EXISTS idx_content_blocks_node ON content_blocks(contentId, isDraft);.CREATE INDEX IF NOT EXISTS idx_node_assets_nodeId ON node_assets(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_assets_assetId ON node_assets(assetId);.CREATE INDEX IF NOT EXISTS idx_content_schemas_type ON content_schemas(type);.CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(userId);.CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(expiresAt);.CREATE INDEX IF NOT EXISTS idx_channels_visibility ON channels(isHidden);.CREATE INDEX IF NOT EXISTS idx_trees_visibility ON trees(isHidden);.CREATE INDEX IF NOT EXISTS idx_content_nodes_visibility ON content_nodes(isHidden, status);.CREATE INDEX IF NOT EXISTS idx_content_nodes_slug ON content_nodes(slug);.CREATE INDEX IF NOT EXISTS idx_content_nodes_type ON content_nodes(contentType);.CREATE INDEX IF NOT EXISTS idx_content_nodes_deleted_updated ON content_nodes(deletedAt, updatedAt DESC);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_hierarchy ON tree_nodes(treeId, parentId, sortOrder);.CREATE INDEX IF NOT EXISTS idx_tree_nodes_content ON tree_nodes(contentId, treeId);.CREATE INDEX IF NOT EXISTS idx_content_blocks_content ON content_blocks(contentId, isDraft, region, sortOrder);.CREATE INDEX IF NOT EXISTS idx_node_channels_channel ON node_channels(channelId, nodeId);.CREATE INDEX IF NOT EXISTS idx_node_channels_node ON node_channels(nodeId, channelId);.CREATE INDEX IF NOT EXISTS idx_node_assets_node_asset ON node_assets(nodeId, assetId);.CREATE INDEX IF NOT EXISTS idx_node_assets_asset_node ON node_assets(assetId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_revisions_version ON node_revisions(nodeId, version);.CREATE INDEX IF NOT EXISTS idx_assets_system_created ON assets(isSystemVariant, createdAt DESC);.CREATE INDEX IF NOT EXISTS idx_assets_system_mime ON assets(isSystemVariant, mimeType);.CREATE INDEX IF NOT EXISTS idx_assets_deleted ON assets(deletedAt);.CREATE INDEX IF NOT EXISTS idx_assets_parent ON assets(parentAssetId);.CREATE INDEX IF NOT EXISTS idx_taxonomy_terms_tax ON taxonomy_terms(taxonomy);.CREATE INDEX IF NOT EXISTS idx_node_terms_node ON node_terms(nodeId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term ON node_terms(termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_node_term ON node_terms(nodeId, termId);.CREATE INDEX IF NOT EXISTS idx_node_terms_term_node ON node_terms(termId, nodeId);.CREATE UNIQUE INDEX IF NOT EXISTS idx_node_routes_lookup ON node_routes(path, channelId);.CREATE INDEX IF NOT EXISTS idx_node_routes_node ON node_routes(nodeId);".split(".");
21794
21829
  function Ab(e) {
21795
21830
  let t = /* @__PURE__ */ new Set();
21796
21831
  function n(e) {
@@ -22025,18 +22060,18 @@ var Fb = { hasSubscribers: !1 }, Ib = Fb, Lb = Fb, Rb = typeof performance == "o
22025
22060
  return this.#i;
22026
22061
  }
22027
22062
  constructor(t) {
22028
- let { max: n = 0, ttl: r, ttlResolution: i = 1, ttlAutopurge: a, updateAgeOnGet: o, updateAgeOnHas: s, allowStale: c, dispose: l, onInsert: u, disposeAfter: d, noDisposeOnSet: f, noUpdateTTL: p, maxSize: m = 0, maxEntrySize: h = 0, sizeCalculation: g, fetchMethod: _, memoMethod: v, noDeleteOnFetchRejection: y, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: x, allowStaleOnFetchAbort: S, ignoreFetchAbort: C, backgroundFetchSize: w = 1, perf: T } = t;
22029
- if (this.backgroundFetchSize = w, T !== void 0 && typeof T?.now != "function") throw TypeError("perf option must have a now() method if specified");
22030
- if (this.#s = T ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
22031
- let ee = n ? Gb(n) : Array;
22032
- if (!ee) throw Error("invalid max value: " + n);
22063
+ let { max: n = 0, ttl: r, ttlResolution: i = 1, ttlAutopurge: a, updateAgeOnGet: o, updateAgeOnHas: s, allowStale: c, dispose: l, onInsert: u, disposeAfter: d, noDisposeOnSet: f, noUpdateTTL: p, maxSize: m = 0, maxEntrySize: h = 0, sizeCalculation: g, fetchMethod: _, memoMethod: v, noDeleteOnFetchRejection: y, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: x, allowStaleOnFetchAbort: S, ignoreFetchAbort: C, backgroundFetchSize: ee = 1, perf: w } = t;
22064
+ if (this.backgroundFetchSize = ee, w !== void 0 && typeof w?.now != "function") throw TypeError("perf option must have a now() method if specified");
22065
+ if (this.#s = w ?? Rb, n !== 0 && !Wb(n)) throw TypeError("max option must be a nonnegative integer");
22066
+ let T = n ? Gb(n) : Array;
22067
+ if (!T) throw Error("invalid max value: " + n);
22033
22068
  if (this.#e = n, this.#t = m, this.maxEntrySize = h || this.#t, this.sizeCalculation = g, this.sizeCalculation) {
22034
22069
  if (!this.#t && !this.maxEntrySize) throw TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
22035
22070
  if (typeof this.sizeCalculation != "function") throw TypeError("sizeCalculation set to non-function");
22036
22071
  }
22037
22072
  if (v !== void 0 && typeof v != "function") throw TypeError("memoMethod must be a function if defined");
22038
22073
  if (this.#o = v, _ !== void 0 && typeof _ != "function") throw TypeError("fetchMethod must be a function if specified");
22039
- if (this.#a = _, this.#w = !!_, this.#u = /* @__PURE__ */ new Map(), this.#d = Array.from({ length: n }).fill(void 0), this.#f = Array.from({ length: n }).fill(void 0), this.#p = new ee(n), this.#m = new ee(n), this.#h = 0, this.#g = 0, this.#_ = qb.create(n), this.#c = 0, this.#l = 0, typeof l == "function" && (this.#n = l), typeof u == "function" && (this.#r = u), typeof d == "function" ? (this.#i = d, this.#v = []) : (this.#i = void 0, this.#v = void 0), this.#C = !!this.#n, this.#E = !!this.#r, this.#T = !!this.#i, this.noDisposeOnSet = !!f, this.noUpdateTTL = !!p, this.noDeleteOnFetchRejection = !!y, this.allowStaleOnFetchRejection = !!x, this.allowStaleOnFetchAbort = !!S, this.ignoreFetchAbort = !!C, this.maxEntrySize !== 0) {
22074
+ if (this.#a = _, this.#w = !!_, this.#u = /* @__PURE__ */ new Map(), this.#d = Array.from({ length: n }).fill(void 0), this.#f = Array.from({ length: n }).fill(void 0), this.#p = new T(n), this.#m = new T(n), this.#h = 0, this.#g = 0, this.#_ = qb.create(n), this.#c = 0, this.#l = 0, typeof l == "function" && (this.#n = l), typeof u == "function" && (this.#r = u), typeof d == "function" ? (this.#i = d, this.#v = []) : (this.#i = void 0, this.#v = void 0), this.#C = !!this.#n, this.#E = !!this.#r, this.#T = !!this.#i, this.noDisposeOnSet = !!f, this.noUpdateTTL = !!p, this.noDeleteOnFetchRejection = !!y, this.allowStaleOnFetchRejection = !!x, this.allowStaleOnFetchAbort = !!S, this.ignoreFetchAbort = !!C, this.maxEntrySize !== 0) {
22040
22075
  if (this.#t !== 0 && !Wb(this.#t)) throw TypeError("maxSize must be a positive integer if specified");
22041
22076
  if (!Wb(this.maxEntrySize)) throw TypeError("maxEntrySize must be a positive integer if specified");
22042
22077
  this.#M();
@@ -22782,7 +22817,7 @@ function ax(e) {
22782
22817
  assetRefs: [],
22783
22818
  termRefs: []
22784
22819
  };
22785
- let t = [], n = [], r = (e) => e ? typeof e == "string" && e.startsWith("ast_") ? e : typeof e == "object" && typeof e.id == "string" && e.id.startsWith("ast_") ? e.id : null : null, i = (e) => {
22820
+ let t = [], n = [], r = (e) => e ? typeof e == "string" && e.startsWith("ast_") && !e.includes(" ") ? e : typeof e == "object" && typeof e.id == "string" && e.id.startsWith("ast_") ? e.id : null : null, i = (e) => {
22786
22821
  if (!e) return null;
22787
22822
  if (typeof e == "string" && e.startsWith("trm_")) {
22788
22823
  let t = Number(e.replace("trm_", ""));
@@ -22797,17 +22832,29 @@ function ax(e) {
22797
22832
  if (!e || typeof e != "object") return e;
22798
22833
  if (Array.isArray(e)) return e.map((e, s) => {
22799
22834
  let c = r(e);
22800
- if (c && (t.push({
22801
- assetId: c,
22802
- fieldKey: o,
22803
- sortOrder: s
22804
- }), typeof e == "object" && e && e.variants && typeof e.variants == "object")) for (let [n, i] of Object.entries(e.variants)) {
22805
- let e = r(i);
22806
- e && t.push({
22807
- assetId: e,
22808
- fieldKey: `${o}[${s}].variants.${n}`,
22835
+ if (c) {
22836
+ if (t.push({
22837
+ assetId: c,
22838
+ fieldKey: o,
22809
22839
  sortOrder: s
22810
- });
22840
+ }), typeof e == "object" && e && e.variants && typeof e.variants == "object") for (let [n, i] of Object.entries(e.variants)) {
22841
+ let e = r(i);
22842
+ e && t.push({
22843
+ assetId: e,
22844
+ fieldKey: `${o}[${s}].variants.${n}`,
22845
+ sortOrder: s
22846
+ });
22847
+ }
22848
+ } else if (typeof e == "string") {
22849
+ let n = e.match(/ast_[a-zA-Z0-9-]+/g);
22850
+ if (n) {
22851
+ let e = Array.from(new Set(n));
22852
+ for (let n of e) n !== c && t.push({
22853
+ assetId: n,
22854
+ fieldKey: o,
22855
+ sortOrder: s
22856
+ });
22857
+ }
22811
22858
  }
22812
22859
  let l = i(e);
22813
22860
  return l ? (n.push({
@@ -22843,11 +22890,39 @@ function ax(e) {
22843
22890
  filename: l.filename || void 0,
22844
22891
  mimeType: l.mimeType || void 0
22845
22892
  } : d;
22846
- } else f ? (n.push({
22893
+ } else if (f) n.push({
22847
22894
  termId: f,
22848
22895
  fieldKey: u,
22849
22896
  sortOrder: 0
22850
- }), s[c] = `trm_${f}`) : s[c] = Array.isArray(l) || l && typeof l == "object" ? a(l, u) : l;
22897
+ }), s[c] = `trm_${f}`;
22898
+ else if (Array.isArray(l)) s[c] = a(l, u);
22899
+ else if (l && typeof l == "object") s[c] = a(l, u);
22900
+ else {
22901
+ if (typeof l == "string") {
22902
+ let e = l.match(/ast_[a-zA-Z0-9-]+/g);
22903
+ if (e) {
22904
+ let n = Array.from(new Set(e));
22905
+ for (let e of n) t.push({
22906
+ assetId: e,
22907
+ fieldKey: u,
22908
+ sortOrder: 0
22909
+ });
22910
+ }
22911
+ let r = l.match(/trm_\d+/g);
22912
+ if (r) {
22913
+ let e = Array.from(new Set(r));
22914
+ for (let t of e) {
22915
+ let e = Number(t.replace("trm_", ""));
22916
+ isNaN(e) || n.push({
22917
+ termId: e,
22918
+ fieldKey: u,
22919
+ sortOrder: 0
22920
+ });
22921
+ }
22922
+ }
22923
+ }
22924
+ s[c] = l;
22925
+ }
22851
22926
  }
22852
22927
  return s;
22853
22928
  };
@@ -22859,18 +22934,20 @@ function ax(e) {
22859
22934
  }
22860
22935
  async function ox(e, t, n) {
22861
22936
  if (await e.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(t), n.length === 0) return;
22862
- let r = /* @__PURE__ */ new Set();
22863
- for (let i of n) {
22864
- let n = `${t}:${i.assetId}:${i.fieldKey}`;
22865
- r.has(n) || (r.add(n), await e.prepare("\n INSERT OR IGNORE INTO node_assets (nodeId, assetId, fieldKey, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(t, i.assetId, i.fieldKey, i.sortOrder));
22937
+ let r = [...new Set(n.map((e) => e.assetId))], i = r.map(() => "?").join(","), a = await e.prepare(`SELECT id FROM assets WHERE id IN (${i})`).all(...r), o = Array.isArray(a) ? a : a?.results || [], s = new Set(o.map((e) => e.id)), c = /* @__PURE__ */ new Set();
22938
+ for (let r of n) {
22939
+ if (!s.has(r.assetId)) continue;
22940
+ let n = `${t}:${r.assetId}:${r.fieldKey}`;
22941
+ c.has(n) || (c.add(n), await e.prepare("\n INSERT OR IGNORE INTO node_assets (nodeId, assetId, fieldKey, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(t, r.assetId, r.fieldKey, r.sortOrder));
22866
22942
  }
22867
22943
  }
22868
22944
  async function sx(e, t, n) {
22869
22945
  if (await e.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(t), n.length === 0) return;
22870
- let r = /* @__PURE__ */ new Set();
22871
- for (let i of n) {
22872
- let n = `${t}:${i.termId}:${i.fieldKey}`;
22873
- r.has(n) || (r.add(n), await e.prepare("\n INSERT OR IGNORE INTO node_terms (nodeId, termId, fieldKey, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(t, i.termId, i.fieldKey, i.sortOrder));
22946
+ let r = [...new Set(n.map((e) => e.termId))], i = r.map(() => "?").join(","), a = await e.prepare(`SELECT id FROM taxonomy_terms WHERE id IN (${i})`).all(...r), o = Array.isArray(a) ? a : a?.results || [], s = new Set(o.map((e) => e.id)), c = /* @__PURE__ */ new Set();
22947
+ for (let r of n) {
22948
+ if (!s.has(r.termId)) continue;
22949
+ let n = `${t}:${r.termId}:${r.fieldKey}`;
22950
+ c.has(n) || (c.add(n), await e.prepare("\n INSERT OR IGNORE INTO node_terms (nodeId, termId, fieldKey, sortOrder)\n VALUES (?, ?, ?, ?)\n ").run(t, r.termId, r.fieldKey, r.sortOrder));
22874
22951
  }
22875
22952
  }
22876
22953
  //#endregion
@@ -23261,8 +23338,122 @@ var fx = class {
23261
23338
  console.warn("⚠️ [CacheWarmer] Tree-wide warming failed:", e);
23262
23339
  }
23263
23340
  }
23264
- }, px = new e();
23265
- async function mx(e, t, n = []) {
23341
+ };
23342
+ //#endregion
23343
+ //#region server/utils/route-generator.ts
23344
+ async function px(e) {
23345
+ try {
23346
+ console.log("[Route Generator] Rebuilding enterprise routing table...");
23347
+ let t = await e.prepare("SELECT id, key, dataJson FROM channels").all(), n = Array.isArray(t) ? t : t?.results || [], r = /* @__PURE__ */ new Map();
23348
+ for (let e of n) if (e.dataJson) try {
23349
+ let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
23350
+ typeof t == "string" && (t = JSON.parse(t));
23351
+ let n = t?.channelRoot;
23352
+ if (typeof n == "string") try {
23353
+ n = JSON.parse(n);
23354
+ } catch {}
23355
+ let i = n?.nodeId ?? n?.id ?? t?.channelRootNodeId ?? t?.homeNodeId;
23356
+ i != null && !isNaN(Number(i)) && r.set(Number(e.id), Number(i));
23357
+ } catch (t) {
23358
+ console.error(`[Route Generator] Failed to parse channel ${e.id} dataJson:`, t);
23359
+ }
23360
+ let i = await e.prepare("SELECT id, slug FROM content_nodes WHERE (deletedAt IS NULL OR deletedAt = '')").all(), a = Array.isArray(i) ? i : i?.results || [], o = /* @__PURE__ */ new Map();
23361
+ for (let e of a) e.slug && o.set(Number(e.id), String(e.slug).replace(/^\/+|\/+$/g, ""));
23362
+ let s = await e.prepare("SELECT channelId, treeId FROM channel_trees").all(), c = Array.isArray(s) ? s : s?.results || [], l = await e.prepare("SELECT treeId, contentId, parentId, sortOrder FROM tree_nodes ORDER BY sortOrder ASC").all(), u = Array.isArray(l) ? l : l?.results || [], d = await e.prepare("SELECT nodeId, channelId FROM node_channels").all(), f = Array.isArray(d) ? d : d?.results || [], p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set();
23363
+ for (let e of n) {
23364
+ let t = Number(e.id), n = r.get(t), i = c.filter((e) => Number(e.channelId) === t).map((e) => Number(e.treeId)), a = f.filter((e) => Number(e.channelId) === t).map((e) => Number(e.nodeId));
23365
+ if (n && o.has(n)) {
23366
+ p.set(`/:${t}`, {
23367
+ path: "/",
23368
+ channelId: t,
23369
+ nodeId: n,
23370
+ treeId: null,
23371
+ isCanonical: 1,
23372
+ redirectUrl: null
23373
+ }), m.add(`${t}:${n}`);
23374
+ let e = o.get(n);
23375
+ e && e !== "index" && p.set(`/${e}:${t}`, {
23376
+ path: `/${e}`,
23377
+ channelId: t,
23378
+ nodeId: n,
23379
+ treeId: null,
23380
+ isCanonical: 0,
23381
+ redirectUrl: "/"
23382
+ });
23383
+ }
23384
+ for (let e of i) {
23385
+ let r = u.filter((t) => Number(t.treeId) === e), i = /* @__PURE__ */ new Map();
23386
+ for (let e of r) {
23387
+ let t = e.parentId ? Number(e.parentId) : null;
23388
+ i.has(t) || i.set(t, []), i.get(t).push(e);
23389
+ }
23390
+ let a = (r, s) => {
23391
+ let c = i.get(r) || [];
23392
+ for (let r of c) {
23393
+ let i = Number(r.contentId), c = o.get(i);
23394
+ if (!c) continue;
23395
+ let l = n !== void 0 && i === n, u = [...s];
23396
+ !l && c !== "index" && u.push(c);
23397
+ let d = l || u.length === 0 ? "/" : "/" + u.join("/"), f = `${d}:${t}`;
23398
+ if (!p.has(f) || l) {
23399
+ let n = `${t}:${i}`, r = l ? 1 : +!m.has(n);
23400
+ r && m.add(n), p.set(f, {
23401
+ path: d,
23402
+ channelId: t,
23403
+ nodeId: i,
23404
+ treeId: e,
23405
+ isCanonical: r,
23406
+ redirectUrl: null
23407
+ });
23408
+ }
23409
+ a(i, l ? [] : u);
23410
+ }
23411
+ };
23412
+ a(null, []);
23413
+ }
23414
+ for (let e of a) {
23415
+ let r = o.get(e);
23416
+ if (!r) continue;
23417
+ let i = `${t}:${e}`;
23418
+ if (!m.has(i)) {
23419
+ let a = n !== void 0 && e === n ? "/" : `/${r}`, o = `${a}:${t}`;
23420
+ p.has(o) || (p.set(o, {
23421
+ path: a,
23422
+ channelId: t,
23423
+ nodeId: e,
23424
+ treeId: null,
23425
+ isCanonical: 1,
23426
+ redirectUrl: null
23427
+ }), m.add(i));
23428
+ }
23429
+ }
23430
+ }
23431
+ await e.prepare("DELETE FROM node_routes").run();
23432
+ let h = Array.from(p.values());
23433
+ if (h.length === 0) return;
23434
+ for (let t = 0; t < h.length; t += 50) {
23435
+ let n = h.slice(t, t + 50), r = n.map(() => "(?, ?, ?, ?, ?, ?)").join(","), i = n.flatMap((e) => [
23436
+ e.path,
23437
+ e.channelId,
23438
+ e.nodeId,
23439
+ e.treeId,
23440
+ e.isCanonical,
23441
+ e.redirectUrl ?? null
23442
+ ]);
23443
+ await e.prepare(`
23444
+ INSERT INTO node_routes (path, channelId, nodeId, treeId, isCanonical, redirectUrl)
23445
+ VALUES ${r}
23446
+ `).run(...i);
23447
+ }
23448
+ console.log(`[Route Generator] Successfully built ${h.length} enterprise routes.`);
23449
+ } catch (e) {
23450
+ console.error("[Route Generator] Fatal error rebuilding routes:", e);
23451
+ }
23452
+ }
23453
+ //#endregion
23454
+ //#region server/routes/admin/nodes.ts
23455
+ var mx = new e();
23456
+ async function hx(e, t, n = []) {
23266
23457
  let r = e.prepare(t);
23267
23458
  if (typeof r.bind == "function") {
23268
23459
  let e = await r.bind(...n).all();
@@ -23274,23 +23465,23 @@ async function mx(e, t, n = []) {
23274
23465
  }
23275
23466
  return [];
23276
23467
  }
23277
- async function hx(e, t, n = []) {
23468
+ async function gx(e, t, n = []) {
23278
23469
  let r = e.prepare(t);
23279
23470
  if (typeof r.bind == "function") return r.bind(...n).run();
23280
23471
  if (typeof r.run == "function") return r.run(...n);
23281
23472
  }
23282
- function gx(e) {
23473
+ function _x(e) {
23283
23474
  return !e || !e.trim() ? null : e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "") || null;
23284
23475
  }
23285
- function _x(e) {
23476
+ function vx(e) {
23286
23477
  return +(e === !0 || e === 1 || e === "1" || e === "true");
23287
23478
  }
23288
- function vx(e) {
23479
+ function yx(e) {
23289
23480
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
23290
23481
  let t = Number(e);
23291
23482
  return isNaN(t) ? null : t;
23292
23483
  }
23293
- function yx(e) {
23484
+ function bx(e) {
23294
23485
  let t = { ...e };
23295
23486
  delete t.language, delete t.defaultLanguage;
23296
23487
  for (let e of [
@@ -23303,6 +23494,8 @@ function yx(e) {
23303
23494
  "contentType",
23304
23495
  "title",
23305
23496
  "slug",
23497
+ "path",
23498
+ "routePath",
23306
23499
  "hidden",
23307
23500
  "is_hidden",
23308
23501
  "isHidden",
@@ -23319,34 +23512,28 @@ function yx(e) {
23319
23512
  ]) delete t[e];
23320
23513
  return t;
23321
23514
  }
23322
- function bx(e, t = /* @__PURE__ */ new Set()) {
23323
- return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => bx(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => bx(e, t)), t) : t;
23515
+ function xx(e, t = /* @__PURE__ */ new Set()) {
23516
+ return e ? typeof e == "string" ? (e.startsWith("ast_") && t.add(e), t) : Array.isArray(e) ? (e.forEach((e) => xx(e, t)), t) : (typeof e == "object" && Object.values(e).forEach((e) => xx(e, t)), t) : t;
23324
23517
  }
23325
- function xx(e, t) {
23518
+ function Sx(e, t) {
23326
23519
  if (!e) return !0;
23327
- let n = t.title !== void 0 && t.title?.trim() !== e.title?.trim(), r = t.slug !== void 0 && t.slug !== e.slug, i = t.isHidden !== void 0 && _x(t.isHidden) !== _x(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, s = t.sanitizedFields || {}, c = s.menuTitle !== void 0 && s.menuTitle !== o.menuTitle;
23520
+ let n = t.title !== void 0 && t.title?.trim() !== e.title?.trim(), r = t.slug !== void 0 && t.slug !== e.slug, i = t.isHidden !== void 0 && vx(t.isHidden) !== vx(e.isHidden), a = t.status !== void 0 && t.status !== e.status, o = typeof e.draftDataJson == "string" ? JSON.parse(e.draftDataJson || "{}") : e.draftDataJson || {}, s = t.sanitizedFields || {}, c = s.menuTitle !== void 0 && s.menuTitle !== o.menuTitle;
23328
23521
  return n || r || i || a || c;
23329
23522
  }
23330
- async function Sx(e, t, n) {
23523
+ async function Cx(e, t, n) {
23331
23524
  for (let r of n) {
23332
- let n = (await mx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
23333
- if (!n || (await mx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0) continue;
23334
- let i = [n];
23335
- if (!n.isSystemVariant) {
23336
- let t = await mx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets\n WHERE parentAssetId = ? OR (isSystemVariant = 1 AND filename LIKE ?)\n ", [n.id, `crop_%${String(n.filename || "").replace(/\.[^/.]+$/, "")}%`]), r = t.map((e) => e.id);
23337
- if (r.length > 0 && (await mx(e, `SELECT DISTINCT assetId FROM node_assets WHERE assetId IN (${r.map(() => "?").join(",")})`, r)).length > 0) continue;
23338
- i = [n, ...t];
23339
- }
23340
- for (let e of i) if (e.storageKeyPrivate) try {
23341
- await t.delete(e.storageKeyPrivate);
23342
- } catch (t) {
23343
- console.warn(`[Asset Cleanup] Failed to delete ${e.storageKeyPrivate}:`, t);
23525
+ let n = (await hx(e, "\n SELECT id, storageKeyPrivate, isSystemVariant, parentAssetId, filename\n FROM assets WHERE id = ?\n ", [r]))[0];
23526
+ if (n && n.isSystemVariant && !((await hx(e, "SELECT 1 FROM node_assets WHERE assetId = ? LIMIT 1", [n.id])).length > 0)) {
23527
+ if (n.storageKeyPrivate) try {
23528
+ await t.delete(n.storageKeyPrivate);
23529
+ } catch (e) {
23530
+ console.warn(`[Asset Cleanup] Failed to delete crop ${n.storageKeyPrivate}:`, e);
23531
+ }
23532
+ await gx(e, "DELETE FROM node_assets WHERE assetId = ?", [n.id]), await gx(e, "DELETE FROM assets WHERE id = ?", [n.id]);
23344
23533
  }
23345
- let a = i.map((e) => e.id), o = a.map(() => "?").join(",");
23346
- await hx(e, `DELETE FROM node_assets WHERE assetId IN (${o})`, a), await hx(e, `DELETE FROM assets WHERE id IN (${o})`, a);
23347
23534
  }
23348
23535
  }
23349
- async function Cx(e, t, n) {
23536
+ async function wx(e, t, n) {
23350
23537
  let r = {}, i = null;
23351
23538
  if (t) {
23352
23539
  let a = await e.prepare("\n WITH RECURSIVE ancestor_path(id, parentId, draftDataJson, dataJson, level) AS (\n SELECT t.contentId as id, t.parentId, c.draftDataJson, c.dataJson, 0\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId as id, t.parentId, c.draftDataJson, c.dataJson, ap.level + 1\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT draftDataJson, dataJson FROM ancestor_path ORDER BY level ASC\n ").all(t, n, n), o = Array.isArray(a) ? a : a?.results || [];
@@ -23371,56 +23558,65 @@ async function Cx(e, t, n) {
23371
23558
  inheritedFields: r
23372
23559
  };
23373
23560
  }
23374
- px.get("/", async (e) => {
23561
+ mx.get("/", async (e) => {
23375
23562
  let t = e.get("db"), n = e.req.query("id"), r = e.req.query("type"), i = e.req.query("q") || e.req.query("search"), a = e.req.query("channelId"), o = e.req.query("trashed") === "true", s = e.req.query("assetId"), c = e.req.query("sort") || "updatedAt", l = (e.req.query("order") || "DESC").toUpperCase() === "ASC" ? "ASC" : "DESC", u = e.req.query("limit"), d = e.req.query("offset"), f = Math.max(1, Math.min(100, parseInt(u || "50", 10))), p = Math.max(0, parseInt(d || "0", 10));
23376
23563
  if (n) {
23377
23564
  let r = Number(n);
23378
23565
  if (isNaN(r)) return e.json({ error: "Invalid Node ID" }, 400);
23379
23566
  let i = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(r);
23380
23567
  if (!i) return e.json({ error: "Node not found" }, 404);
23381
- let a = i.status === "draft" || !!i.hasUnpublishedChanges, o = {
23568
+ let o = null;
23569
+ if (a && a !== "all") {
23570
+ let e = await t.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(r, Number(a));
23571
+ e && (o = e.path);
23572
+ } else {
23573
+ let e = await t.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND isCanonical = 1 LIMIT 1").get(r);
23574
+ e && (o = e.path);
23575
+ }
23576
+ let s = i.status === "draft" || !!i.hasUnpublishedChanges, c = {
23382
23577
  id: i.id,
23383
23578
  title: i.title,
23384
23579
  slug: i.slug,
23580
+ path: o,
23385
23581
  language: i.language || null,
23386
23582
  nodeType: i.contentType,
23387
23583
  contentType: i.contentType,
23388
23584
  isHidden: !!i.isHidden,
23389
23585
  status: i.status || "draft",
23390
23586
  publishedAt: i.publishedAt || null,
23391
- hasUnpublishedChanges: a,
23587
+ hasUnpublishedChanges: s,
23392
23588
  deletedAt: i.deletedAt || null,
23393
23589
  createdById: i.createdById || null,
23394
23590
  updatedById: i.updatedById || null,
23395
23591
  createdAt: i.createdAt,
23396
23592
  updatedAt: i.updatedAt
23397
- }, s = i.draftDataJson || i.dataJson;
23398
- if (s) try {
23399
- let n = typeof s == "string" ? JSON.parse(s) : s, a = await t.prepare("SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), c = dx(e.env?.BUNDLED_DEFINITIONS).nodes?.[i.contentType] || {}, l = n.layoutId || null;
23593
+ }, l = i.draftDataJson || i.dataJson;
23594
+ if (l) try {
23595
+ let n = typeof l == "string" ? JSON.parse(l) : l, a = await t.prepare("SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? LIMIT 1").get(r), o = dx(e.env?.BUNDLED_DEFINITIONS).nodes?.[i.contentType] || {}, s = n.layoutId || null;
23400
23596
  if (a) {
23401
- let { resolvedLayoutId: e, inheritedFields: r } = await Cx(t, a.parentId, a.treeId);
23402
- (l === "inherit" || !l) && (l = e);
23597
+ let { resolvedLayoutId: e, inheritedFields: r } = await wx(t, a.parentId, a.treeId);
23598
+ (s === "inherit" || !s) && (s = e);
23403
23599
  for (let [e, t] of Object.entries(r)) e !== "layoutId" && e !== "subpageLayoutId" && (n[e] === void 0 || n[e] === null || n[e] === "") && t !== void 0 && (n[e] = t);
23404
23600
  }
23405
- l && l !== "inherit" && !((e) => {
23406
- if (!c || Object.keys(c).length === 0 || e === c.defaultLayout) return !0;
23601
+ s && s !== "inherit" && !((e) => {
23602
+ if (!o || Object.keys(o).length === 0 || e === o.defaultLayout) return !0;
23407
23603
  let t = null, n = (e) => {
23408
23604
  e && (Array.isArray(e) ? e.forEach((e) => {
23409
23605
  e.layoutId && (t = e.layoutId);
23410
23606
  }) : e.layoutId && (t = e.layoutId));
23411
23607
  };
23412
- if (n(c.fields), !t && c.tabs && Object.values(c.tabs).forEach((e) => n(e.fields)), !t) return !1;
23608
+ if (n(o.fields), !t && o.tabs && Object.values(o.tabs).forEach((e) => n(e.fields)), !t) return !1;
23413
23609
  let r = t.allowedLayouts;
23414
23610
  return r ? typeof r == "string" ? r === e : !Array.isArray(r) || r.length === 0 || r.includes(e) : !0;
23415
- })(l) && (l = null), (l === "inherit" || !l) && (l = c.defaultLayout || null);
23416
- let u = await ux(t, yx(n));
23417
- Object.assign(o, u), o.resolvedLayoutId = l;
23611
+ })(s) && (s = null), (s === "inherit" || !s) && (s = o.defaultLayout || null);
23612
+ let u = await ux(t, bx(n));
23613
+ Object.assign(c, u), c.resolvedLayoutId = s;
23418
23614
  } catch {}
23419
- let c = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
23420
- o.channels = (Array.isArray(c) ? c : c?.results || []).map((e) => e.channelId);
23421
- let l = await t.prepare("SELECT treeId, parentId, sortOrder FROM tree_nodes WHERE contentId = ?").all(r);
23422
- o.trees = Array.isArray(l) ? l : l?.results || [];
23423
- let u = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), d = Array.isArray(u) ? u : u?.results || [], f = await Promise.all(d.map(async (e) => {
23615
+ let u = await t.prepare("SELECT channelId FROM node_channels WHERE nodeId = ?").all(r);
23616
+ c.channels = (Array.isArray(u) ? u : u?.results || []).map((e) => e.channelId);
23617
+ let d = await t.prepare("SELECT treeId, parentId, sortOrder FROM tree_nodes WHERE contentId = ?").all(r);
23618
+ c.trees = Array.isArray(d) ? d : d?.results || [];
23619
+ let f = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = 1 ORDER BY sortOrder ASC").all(r), p = Array.isArray(f) ? f : f?.results || [], m = await Promise.all(p.map(async (e) => {
23424
23620
  let n = {};
23425
23621
  try {
23426
23622
  n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson || "{}") : e.dataJson || {}, n && typeof n == "object" && (n = await ux(t, n));
@@ -23437,8 +23633,8 @@ px.get("/", async (e) => {
23437
23633
  };
23438
23634
  }));
23439
23635
  return e.json({
23440
- node: o,
23441
- blocks: f
23636
+ node: c,
23637
+ blocks: m
23442
23638
  });
23443
23639
  }
23444
23640
  let m = [], h = [o ? "(cn.deletedAt IS NOT NULL AND cn.deletedAt != '')" : "(cn.deletedAt IS NULL OR cn.deletedAt = '')"];
@@ -23466,34 +23662,42 @@ px.get("/", async (e) => {
23466
23662
  WITH filtered_nodes AS (
23467
23663
  SELECT cn.* FROM content_nodes cn ${g} ORDER BY ${y} ${l} LIMIT ? OFFSET ?
23468
23664
  )
23469
- SELECT fn.*, COUNT(na.assetId) as assetCount
23665
+ SELECT fn.*,
23666
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'image/%' THEN COALESCE(a.parentAssetId, a.id) END) as imageCount,
23667
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'video/%' OR a.mimeType LIKE 'audio/%' THEN COALESCE(a.parentAssetId, a.id) END) as videoCount,
23668
+ COUNT(DISTINCT CASE WHEN a.mimeType LIKE 'application/pdf%' OR a.mimeType LIKE 'application/msword%' OR a.mimeType LIKE 'application/vnd%' OR a.mimeType LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as documentCount,
23669
+ COUNT(DISTINCT CASE WHEN a.id IS NOT NULL AND a.mimeType NOT LIKE 'image/%' AND a.mimeType NOT LIKE 'video/%' AND a.mimeType NOT LIKE 'audio/%' AND a.mimeType NOT LIKE 'application/pdf%' AND a.mimeType NOT LIKE 'application/msword%' AND a.mimeType NOT LIKE 'application/vnd%' AND a.mimeType NOT LIKE 'text/%' THEN COALESCE(a.parentAssetId, a.id) END) as otherCount,
23670
+ COUNT(DISTINCT COALESCE(a.parentAssetId, a.id)) as assetCount,
23671
+ (SELECT path FROM node_routes nr WHERE nr.nodeId = fn.id AND isCanonical = 1 LIMIT 1) as routePath
23470
23672
  FROM filtered_nodes fn
23471
23673
  LEFT JOIN node_assets na ON fn.id = na.nodeId
23674
+ LEFT JOIN assets a ON na.assetId = a.id
23472
23675
  GROUP BY fn.id ORDER BY ${y.replace("cn.", "fn.")} ${l}
23473
23676
  `, S = [
23474
23677
  ...m,
23475
23678
  f,
23476
23679
  p
23477
- ], C = await t.prepare(x).all(...S), w = Array.isArray(C) ? C : C?.results || [], T = w.map((e) => e.id), ee = {}, E = {};
23478
- if (T.length > 0) {
23479
- let e = T.map(() => "?").join(","), n = await t.prepare(`
23680
+ ], C = await t.prepare(x).all(...S), ee = Array.isArray(C) ? C : C?.results || [], w = ee.map((e) => e.id), T = {}, E = {};
23681
+ if (w.length > 0) {
23682
+ let e = w.map(() => "?").join(","), n = await t.prepare(`
23480
23683
  SELECT nc.nodeId, c.label FROM node_channels nc JOIN channels c ON nc.channelId = c.id WHERE nc.nodeId IN (${e})
23481
- `).all(...T);
23684
+ `).all(...w);
23482
23685
  (Array.isArray(n) ? n : n?.results || []).forEach((e) => {
23483
- ee[e.nodeId] || (ee[e.nodeId] = []), ee[e.nodeId].push(e.label);
23686
+ T[e.nodeId] || (T[e.nodeId] = []), T[e.nodeId].push(e.label);
23484
23687
  });
23485
23688
  let r = await t.prepare(`
23486
23689
  SELECT tn.contentId as nodeId, t.label FROM tree_nodes tn JOIN trees t ON tn.treeId = t.id WHERE tn.contentId IN (${e})
23487
- `).all(...T);
23690
+ `).all(...w);
23488
23691
  (Array.isArray(r) ? r : r?.results || []).forEach((e) => {
23489
23692
  E[e.nodeId] || (E[e.nodeId] = []), E[e.nodeId].includes(e.label) || E[e.nodeId].push(e.label);
23490
23693
  });
23491
23694
  }
23492
- let D = await Promise.all(w.map(async (e) => {
23695
+ let D = await Promise.all(ee.map(async (e) => {
23493
23696
  let n = e.status === "draft" || !!e.hasUnpublishedChanges, r = {
23494
23697
  id: e.id,
23495
23698
  title: e.title,
23496
23699
  slug: e.slug,
23700
+ path: e.routePath || null,
23497
23701
  language: e.language || null,
23498
23702
  contentType: e.contentType,
23499
23703
  nodeType: e.contentType,
@@ -23506,12 +23710,16 @@ px.get("/", async (e) => {
23506
23710
  updatedById: e.updatedById || null,
23507
23711
  createdAt: e.createdAt,
23508
23712
  updatedAt: e.updatedAt,
23509
- channelNames: ee[e.id] || [],
23713
+ channelNames: T[e.id] || [],
23510
23714
  treeNames: E[e.id] || [],
23511
- assetCount: e.assetCount || 0
23715
+ assetCount: e.assetCount || 0,
23716
+ imageCount: e.imageCount || 0,
23717
+ videoCount: e.videoCount || 0,
23718
+ documentCount: e.documentCount || 0,
23719
+ otherCount: e.otherCount || 0
23512
23720
  }, i = e.draftDataJson || e.dataJson;
23513
23721
  if (i) try {
23514
- let e = typeof i == "string" ? JSON.parse(i) : i, n = await ux(t, yx(e));
23722
+ let e = typeof i == "string" ? JSON.parse(i) : i, n = await ux(t, bx(e));
23515
23723
  Object.assign(r, n);
23516
23724
  } catch {}
23517
23725
  return r;
@@ -23523,10 +23731,10 @@ px.get("/", async (e) => {
23523
23731
  offset: p,
23524
23732
  limit: f
23525
23733
  });
23526
- }), px.post("/", async (e) => {
23527
- let t = e.get("db"), n = await e.req.json(), r = n.node || n.activeNode || n, i = r.id || n.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { title: o, slug: s, language: c, nodeType: l, contentType: u, isHidden: d, hidden: f, is_hidden: p, blocks: m, channels: h, trees: g, ..._ } = r, { cleanedData: v, assetRefs: y, termRefs: b } = ax(yx(_)), x = _x(d === void 0 ? f === void 0 ? p : f : d), S = l || u || "page", C = e.get("user")?.id || null, w = typeof c == "string" && c.trim() !== "" ? c.trim() : null, T = g && Array.isArray(g) && g.length > 0 ? g[0] : null, ee = T ? T.treeId || T.id : null, E = null;
23528
- if (ee) {
23529
- let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(ee) || -1, String(ee));
23734
+ }), mx.post("/", async (e) => {
23735
+ let t = e.get("db"), n = await e.req.json(), r = n.node || n.activeNode || n, i = r.id || n.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { title: o, slug: s, language: c, nodeType: l, contentType: u, isHidden: d, hidden: f, is_hidden: p, blocks: m, channels: h, trees: g, ..._ } = r, { cleanedData: v, assetRefs: y, termRefs: b } = ax(bx(_)), x = vx(d === void 0 ? f === void 0 ? p : f : d), S = l || u || "page", C = e.get("user")?.id || null, ee = typeof c == "string" && c.trim() !== "" ? c.trim() : null, w = g && Array.isArray(g) && g.length > 0 ? g[0] : null, T = w ? w.treeId || w.id : null, E = null;
23736
+ if (T) {
23737
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(T) || -1, String(T));
23530
23738
  if (e?.dataJson) try {
23531
23739
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
23532
23740
  E = t.defaultLanguage?.trim() || t.language?.trim() || null;
@@ -23545,13 +23753,13 @@ px.get("/", async (e) => {
23545
23753
  }
23546
23754
  }
23547
23755
  }
23548
- w && E && w === E && (w = null);
23549
- let D = a, te = /* @__PURE__ */ new Set(), O = !1, k = "draft", A = 0, j = s === void 0 ? null : gx(s);
23550
- if (j) {
23756
+ ee && E && ee === E && (ee = null);
23757
+ let D = a, te = /* @__PURE__ */ new Set(), ne = !1, O = "draft", k = 0, A = s === void 0 ? null : _x(s);
23758
+ if (A) {
23551
23759
  let n = [];
23552
23760
  if (g !== void 0 && Array.isArray(g) && g.length > 0) for (let e of g) n.push({
23553
23761
  treeId: Number(e.treeId),
23554
- parentId: vx(e.parentId ?? e._draftParentId ?? null)
23762
+ parentId: yx(e.parentId ?? e._draftParentId ?? null)
23555
23763
  });
23556
23764
  else if (a) {
23557
23765
  let e = await t.prepare("SELECT treeId, parentId FROM tree_nodes WHERE contentId = ?").all(a), r = Array.isArray(e) ? e : e?.results || [];
@@ -23561,32 +23769,32 @@ px.get("/", async (e) => {
23561
23769
  });
23562
23770
  }
23563
23771
  for (let r of n) {
23564
- let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, j] : [
23772
+ let n = r.parentId === null ? "tn.parentId IS NULL" : "tn.parentId = ?", i = r.parentId === null ? [r.treeId, A] : [
23565
23773
  r.treeId,
23566
23774
  r.parentId,
23567
- j
23775
+ A
23568
23776
  ], o = `
23569
23777
  SELECT cn.id FROM tree_nodes tn
23570
23778
  INNER JOIN content_nodes cn ON tn.contentId = cn.id
23571
23779
  WHERE tn.treeId = ? AND ${n} AND cn.slug = ? AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
23572
23780
  `;
23573
23781
  if (a && (o += " AND cn.id != ?", i.push(a)), o += " LIMIT 1", await t.prepare(o).get(...i)) return e.json({
23574
- error: `The slug '${j}' is already in use by another page in this section.`,
23782
+ error: `The slug '${A}' is already in use by another page in this section.`,
23575
23783
  field: "slug"
23576
23784
  }, 409);
23577
23785
  }
23578
23786
  }
23579
23787
  if (a) {
23580
23788
  let e = await t.prepare("SELECT title, slug, language, contentType, isHidden, draftDataJson, dataJson, publishedAt, status, hasUnpublishedChanges FROM content_nodes WHERE id = ?").get(a);
23581
- O = xx(e, {
23789
+ ne = Sx(e, {
23582
23790
  title: o,
23583
- slug: j,
23791
+ slug: A,
23584
23792
  isHidden: x,
23585
23793
  sanitizedFields: v
23586
23794
  });
23587
23795
  let n = e?.draftDataJson || e?.dataJson || "{}";
23588
23796
  try {
23589
- bx(typeof n == "string" ? JSON.parse(n) : n, te);
23797
+ xx(typeof n == "string" ? JSON.parse(n) : n, te);
23590
23798
  } catch {}
23591
23799
  let r = {};
23592
23800
  try {
@@ -23596,7 +23804,7 @@ px.get("/", async (e) => {
23596
23804
  ...r,
23597
23805
  ...v
23598
23806
  }), l = !1;
23599
- if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (l = !0), s !== void 0 && j !== e?.slug && (l = !0), c !== void 0 && w !== e?.language && (l = !0), !l && Object.keys(v).length > 0) {
23807
+ if (o !== void 0 && o.trim() !== (e?.title || "Untitled") && (l = !0), s !== void 0 && A !== e?.slug && (l = !0), c !== void 0 && ee !== e?.language && (l = !0), !l && Object.keys(v).length > 0) {
23600
23808
  for (let e of Object.keys(v)) if (JSON.stringify(v[e]) !== JSON.stringify(r[e])) {
23601
23809
  l = !0;
23602
23810
  break;
@@ -23618,13 +23826,13 @@ px.get("/", async (e) => {
23618
23826
  }
23619
23827
  }
23620
23828
  }
23621
- let u = o === void 0 ? e?.title || "Untitled" : o, d = j ?? e?.slug ?? null, f = S || e?.contentType || "page", p = c === void 0 ? e?.language : w;
23622
- k = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23829
+ let u = o === void 0 ? e?.title || "Untitled" : o, d = A ?? e?.slug ?? null, f = S || e?.contentType || "page", p = c === void 0 ? e?.language : ee;
23830
+ O = e?.status === "published" || e?.publishedAt ? "published" : "draft";
23623
23831
  let h = e?.hasUnpublishedChanges === 1 || e?.hasUnpublishedChanges === !0;
23624
- A = l ? 1 : +!!h, await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(u, d, p, f, x, k, i, A, C, a);
23832
+ k = l ? 1 : +!!h, await t.prepare("\n UPDATE content_nodes \n SET title = ?, slug = ?, language = ?, contentType = ?, isHidden = ?, status = ?, draftDataJson = ?, hasUnpublishedChanges = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(u, d, p, f, x, O, i, k, C, a);
23625
23833
  } else {
23626
- O = !0;
23627
- let e = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(S, o || "Untitled", j, w, x, JSON.stringify(v), C, C);
23834
+ ne = !0;
23835
+ let e = await t.prepare("\n INSERT INTO content_nodes (contentType, title, slug, language, isHidden, status, draftDataJson, dataJson, hasUnpublishedChanges, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, 'draft', ?, NULL, 0, ?, ?)\n ").run(S, o || "Untitled", A, ee, x, JSON.stringify(v), C, C);
23628
23836
  D = Number(e.lastInsertRowid);
23629
23837
  }
23630
23838
  if (h !== void 0 && Array.isArray(h) && D) {
@@ -23637,10 +23845,10 @@ px.get("/", async (e) => {
23637
23845
  }
23638
23846
  if (g !== void 0 && Array.isArray(g) && g.length > 0 && D) for (let e of g) {
23639
23847
  if (!e || !e.treeId) continue;
23640
- let n = Number(e.treeId) || e.treeId, r = vx(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT contentId, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, D);
23641
- a ? ((a.parentId !== r || a.sortOrder !== i) && (O = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE treeId = ? AND contentId = ?").run(r, i, n, D)) : (O = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, D, r, i));
23848
+ let n = Number(e.treeId) || e.treeId, r = yx(e.parentId ?? e._draftParentId ?? null), i = typeof e.sortOrder == "number" ? e.sortOrder : 0, a = await t.prepare("SELECT contentId, parentId, sortOrder FROM tree_nodes WHERE treeId = ? AND contentId = ?").get(n, D);
23849
+ a ? ((a.parentId !== r || a.sortOrder !== i) && (ne = !0), await t.prepare("UPDATE tree_nodes SET parentId = ?, sortOrder = ? WHERE treeId = ? AND contentId = ?").run(r, i, n, D)) : (ne = !0, await t.prepare("INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder) VALUES (?, ?, ?, ?)").run(n, D, r, i));
23642
23850
  }
23643
- let ne = [], re = [];
23851
+ let re = [], ie = [];
23644
23852
  if (m !== void 0 && Array.isArray(m) && D) {
23645
23853
  await t.prepare("DELETE FROM content_blocks WHERE contentId = ? AND isDraft = 1").run(D);
23646
23854
  let e = [], n = [];
@@ -23650,10 +23858,10 @@ px.get("/", async (e) => {
23650
23858
  blockId: o,
23651
23859
  _instanceId: o
23652
23860
  });
23653
- c.forEach((e) => ne.push({
23861
+ c.forEach((e) => re.push({
23654
23862
  ...e,
23655
23863
  fieldKey: `blocks[${t}].${e.fieldKey}`
23656
- })), l.forEach((e) => re.push({
23864
+ })), l.forEach((e) => ie.push({
23657
23865
  ...e,
23658
23866
  fieldKey: `blocks[${t}].${e.fieldKey}`
23659
23867
  }));
@@ -23663,22 +23871,22 @@ px.get("/", async (e) => {
23663
23871
  e.length > 0 && await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...n);
23664
23872
  }
23665
23873
  if (D) {
23666
- let n = [...y, ...ne], r = [...b, ...re];
23874
+ let n = [...y, ...re], r = [...b, ...ie];
23667
23875
  await ox(t, D, n), await sx(t, D, r);
23668
23876
  let i = new Set(n.map((e) => e.assetId)), a = new Set([...te].filter((e) => !i.has(e)));
23669
23877
  if (a.size > 0) {
23670
23878
  let { storage: n } = ix(e.env);
23671
- await Sx(t, n, a);
23879
+ await Cx(t, n, a);
23672
23880
  }
23673
23881
  }
23674
- return await $b(e).clear(), e.json({
23882
+ return await $b(e).clear(), ne && await px(t), e.json({
23675
23883
  success: !0,
23676
23884
  id: D,
23677
- status: k,
23678
- hasUnpublishedChanges: A === 1 || k === "draft",
23679
- isStructuralChange: O
23885
+ status: O,
23886
+ hasUnpublishedChanges: k === 1 || O === "draft",
23887
+ isStructuralChange: ne
23680
23888
  });
23681
- }), px.post("/publish", async (e) => {
23889
+ }), mx.post("/publish", async (e) => {
23682
23890
  let t = e.get("db"), n = await e.req.json(), r = n.id || n.nodeId;
23683
23891
  if (!r || isNaN(Number(r))) return e.json({ error: "Node ID required for publishing" }, 400);
23684
23892
  let i = Number(r), a = e.get("user")?.id || null, o = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(i);
@@ -23711,7 +23919,7 @@ px.get("/", async (e) => {
23711
23919
  },
23712
23920
  blocks: v
23713
23921
  };
23714
- return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, y, JSON.stringify(b), a), await $b(e).clear(), new fx(e.env).purgeNode(e, t, i, h), e.json({
23922
+ return await t.prepare("INSERT INTO node_revisions (nodeId, version, snapshotJson, createdById) VALUES (?, ?, ?, ?)").run(i, y, JSON.stringify(b), a), await $b(e).clear(), new fx(e.env).purgeNode(e, t, i, h), h && await px(t), e.json({
23715
23923
  success: !0,
23716
23924
  id: i,
23717
23925
  status: "published",
@@ -23720,29 +23928,29 @@ px.get("/", async (e) => {
23720
23928
  hasUnpublishedChanges: !1,
23721
23929
  isStructuralChange: h
23722
23930
  });
23723
- }), px.delete("/", async (e) => {
23931
+ }), mx.delete("/", async (e) => {
23724
23932
  let t = e.get("db"), n = e.req.query("id");
23725
23933
  if (!n) return e.json({ error: "Node ID required" }, 400);
23726
23934
  let r = Number(n);
23727
- return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), e.json({
23935
+ return await t.prepare("UPDATE content_nodes SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), await px(t), e.json({
23728
23936
  success: !0,
23729
23937
  deletedNodeId: r
23730
23938
  });
23731
- }), px.post("/restore", async (e) => {
23939
+ }), mx.post("/restore", async (e) => {
23732
23940
  let t = e.get("db"), n = await e.req.json(), r = Number(n.id);
23733
- return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), e.json({
23941
+ return r ? await t.prepare("SELECT id FROM content_nodes WHERE id = ?").get(r) ? (await t.prepare("UPDATE content_nodes SET deletedAt = NULL WHERE id = ?").run(r), await $b(e).clear(), new fx(e.env).purgeNode(e, t, r, !0), await px(t), e.json({
23734
23942
  success: !0,
23735
23943
  restoredNodeId: r
23736
23944
  })) : e.json({ error: "Node not found" }, 404) : e.json({ error: "Node ID required" }, 400);
23737
- }), px.delete("/purge", async (e) => {
23945
+ }), mx.delete("/purge", async (e) => {
23738
23946
  let t = e.get("db"), n = e.req.query("id");
23739
23947
  if (!n) return e.json({ error: "Node ID required" }, 400);
23740
23948
  let r = Number(n);
23741
- return new fx(e.env).purgeNode(e, t, r, !0), await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), e.json({
23949
+ return new fx(e.env).purgeNode(e, t, r, !0), await t.prepare("DELETE FROM node_channels WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ?").run(r), await t.prepare("DELETE FROM content_blocks WHERE contentId = ?").run(r), await t.prepare("DELETE FROM node_revisions WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_assets WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM node_terms WHERE nodeId = ?").run(r), await t.prepare("DELETE FROM content_nodes WHERE id = ?").run(r), await $b(e).clear(), await px(t), e.json({
23742
23950
  success: !0,
23743
23951
  purgedNodeId: r
23744
23952
  });
23745
- }), px.get("/:id/revisions", async (e) => {
23953
+ }), mx.get("/:id/revisions", async (e) => {
23746
23954
  let t = e.get("db"), n = Number(e.req.param("id"));
23747
23955
  if (isNaN(n)) return e.json({ error: "Invalid Node ID" }, 400);
23748
23956
  let r = await t.prepare("\n SELECT version, createdById, snapshotJson \n FROM node_revisions \n WHERE nodeId = ? \n ORDER BY version DESC\n ").all(n), i = (Array.isArray(r) ? r : r?.results || []).map((e) => {
@@ -23758,7 +23966,7 @@ px.get("/", async (e) => {
23758
23966
  };
23759
23967
  });
23760
23968
  return e.json({ revisions: i });
23761
- }), px.get("/:id/revisions/:version", async (e) => {
23969
+ }), mx.get("/:id/revisions/:version", async (e) => {
23762
23970
  let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
23763
23971
  if (!i) return e.json({ error: "Snapshot not found" }, 404);
23764
23972
  let a = {};
@@ -23768,7 +23976,7 @@ px.get("/", async (e) => {
23768
23976
  return e.json({ error: "Corrupt snapshot data" }, 500);
23769
23977
  }
23770
23978
  return e.json({ snapshot: a });
23771
- }), px.post("/:id/revisions/:version/restore", async (e) => {
23979
+ }), mx.post("/:id/revisions/:version/restore", async (e) => {
23772
23980
  let t = e.get("db"), n = Number(e.req.param("id")), r = Number(e.req.param("version")), i = e.get("user")?.id || null, a = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(n, r);
23773
23981
  if (!a) return e.json({ error: "Snapshot not found" }, 404);
23774
23982
  let o = {};
@@ -23782,15 +23990,15 @@ px.get("/", async (e) => {
23782
23990
  for (let t of o.blocks) e.push("(?, ?, ?, ?, ?, 1)"), r.push(n, t.sortOrder, t.elementType, t.dataJson, t.region || "content");
23783
23991
  await t.prepare(`INSERT INTO content_blocks (contentId, sortOrder, elementType, dataJson, region, isDraft) VALUES ${e.join(", ")}`).run(...r);
23784
23992
  }
23785
- return await $b(e).clear(), e.json({
23993
+ return await $b(e).clear(), await px(t), e.json({
23786
23994
  success: !0,
23787
23995
  restoredVersion: r
23788
23996
  });
23789
23997
  });
23790
23998
  //#endregion
23791
23999
  //#region server/routes/admin/trees.ts
23792
- var wx = new e();
23793
- function Tx(e, t = null) {
24000
+ var Tx = new e();
24001
+ function Ex(e, t = null) {
23794
24002
  let n = [];
23795
24003
  for (let r = 0; r < e.length; r++) {
23796
24004
  let i = e[r];
@@ -23802,19 +24010,19 @@ function Tx(e, t = null) {
23802
24010
  id: o,
23803
24011
  parentId: t,
23804
24012
  sortOrder: r
23805
- }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...Tx(i.children, o)));
24013
+ }), i.children && Array.isArray(i.children) && i.children.length > 0 && n.push(...Ex(i.children, o)));
23806
24014
  }
23807
24015
  return n;
23808
24016
  }
23809
- function Ex(e) {
24017
+ function Dx(e) {
23810
24018
  if (e == null || e === "null" || e === "" || typeof e == "string" && e.startsWith("draft-")) return null;
23811
24019
  let t = Number(e);
23812
24020
  return isNaN(t) ? null : t;
23813
24021
  }
23814
- function Dx(e) {
24022
+ function Ox(e) {
23815
24023
  return +(e === !0 || e === 1 || e === "1" || e === "true");
23816
24024
  }
23817
- wx.get("/tree.json", async (e) => {
24025
+ Tx.get("/tree.json", async (e) => {
23818
24026
  try {
23819
24027
  let t = e.get("db"), n = e.req.query("treeId") || "main-nav", r = e.req.query("preview") === "true", i = 1;
23820
24028
  if (isNaN(Number(n))) {
@@ -23867,7 +24075,7 @@ wx.get("/tree.json", async (e) => {
23867
24075
  } catch (t) {
23868
24076
  return console.error("[CMS Tree API] GET Error:", t), e.json({ error: t.message || "Failed to fetch tree" }, 500);
23869
24077
  }
23870
- }), wx.post("/tree.json", async (e) => {
24078
+ }), Tx.post("/tree.json", async (e) => {
23871
24079
  try {
23872
24080
  let t = e.get("db"), n = await e.req.json(), r = n.treeId ? String(n.treeId).trim() : "main-nav", i = $b(e), a = new fx(e.env), o = 1;
23873
24081
  if (isNaN(Number(r))) {
@@ -23879,7 +24087,7 @@ wx.get("/tree.json", async (e) => {
23879
24087
  }
23880
24088
  } else o = Number(r);
23881
24089
  if (n.tree && Array.isArray(n.tree)) {
23882
- let r = Tx(n.tree, null);
24090
+ let r = Ex(n.tree, null);
23883
24091
  if (r.length > 0) for (let e = 0; e < r.length; e += 50) {
23884
24092
  let n = r.slice(e, e + 50), i = n.map((e) => e.id), a = i.map(() => "?").join(","), s = "UPDATE tree_nodes SET \n";
23885
24093
  s += "parentId = CASE contentId \n", n.forEach(() => {
@@ -23894,14 +24102,14 @@ wx.get("/tree.json", async (e) => {
23894
24102
  c.push(e.id, e.sortOrder);
23895
24103
  }), c.push(...i), c.push(o), await t.prepare(s).run(...c);
23896
24104
  }
23897
- return await i.clear(), r.length > 0 && a.purgeNode(e, t, r[0].id, !0), e.json({
24105
+ return await i.clear(), r.length > 0 && a.purgeNode(e, t, r[0].id, !0), await px(t), e.json({
23898
24106
  success: !0,
23899
24107
  reorderedCount: r.length
23900
24108
  });
23901
24109
  }
23902
- let { action: s, title: c, nodeType: l, parentId: u, contentId: d, nodeData: f = {}, pageData: p = {} } = n, m = Object.keys(f).length > 0 ? { ...f } : { ...p }, h = Dx(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
24110
+ let { action: s, title: c, nodeType: l, parentId: u, contentId: d, nodeData: f = {}, pageData: p = {} } = n, m = Object.keys(f).length > 0 ? { ...f } : { ...p }, h = Ox(n.isHidden === void 0 ? m.isHidden === void 0 ? m.hidden : m.isHidden : n.isHidden);
23903
24111
  delete m._isTreeDraft, delete m._draftParentId, delete m.isNew, delete m.nodeType, delete m.contentType, delete m.title, delete m.slug, delete m.hidden, delete m.is_hidden, delete m.isHidden, delete m.status;
23904
- let g = Ex(u), _ = e.get("user")?.id || null;
24112
+ let g = Dx(u), _ = e.get("user")?.id || null;
23905
24113
  if (s === "create") {
23906
24114
  let r = m.slug || n.slug || c, a = r ? String(r).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") : null;
23907
24115
  if (a) {
@@ -23956,7 +24164,7 @@ wx.get("/tree.json", async (e) => {
23956
24164
  let e = x.map(() => "(?, ?)").join(", "), n = x.flatMap((e) => [f, e]);
23957
24165
  await t.prepare(`INSERT OR IGNORE INTO node_channels (nodeId, channelId) VALUES ${e}`).run(...n);
23958
24166
  }
23959
- return await i.clear(), e.json({
24167
+ return await i.clear(), await px(t), e.json({
23960
24168
  success: !0,
23961
24169
  id: f,
23962
24170
  treeNodeId: f,
@@ -23993,14 +24201,14 @@ wx.get("/tree.json", async (e) => {
23993
24201
  field: "slug"
23994
24202
  }, 409);
23995
24203
  }
23996
- return await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d), await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(o, d, g), await i.clear(), a.purgeNode(e, t, d, !0), e.json({
24204
+ return await t.prepare("DELETE FROM tree_nodes WHERE treeId = ? AND contentId = ?").run(o, d), await t.prepare("\n INSERT INTO tree_nodes (treeId, contentId, parentId, sortOrder)\n VALUES (?, ?, ?, 0)\n ").run(o, d, g), await i.clear(), a.purgeNode(e, t, d, !0), await px(t), e.json({
23997
24205
  success: !0,
23998
24206
  treeNodeId: d
23999
24207
  });
24000
24208
  }
24001
24209
  if (s === "detach") {
24002
24210
  let r = n.contentId || n.id || n.treeNodeId;
24003
- return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE contentId = ? AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, o, r, o), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ? AND treeId = ?").run(r, o), await i.clear(), a.purgeNode(e, t, r, !0), e.json({ success: !0 })) : e.json({ error: "contentId required for detach" }, 400);
24211
+ return r ? (await t.prepare("\n UPDATE tree_nodes \n SET parentId = (SELECT parentId FROM tree_nodes WHERE contentId = ? AND treeId = ?) \n WHERE parentId = ? AND treeId = ?\n ").run(r, o, r, o), await t.prepare("DELETE FROM tree_nodes WHERE contentId = ? AND treeId = ?").run(r, o), await i.clear(), a.purgeNode(e, t, r, !0), await px(t), e.json({ success: !0 })) : e.json({ error: "contentId required for detach" }, 400);
24004
24212
  }
24005
24213
  return e.json({ error: "Invalid payload or action" }, 400);
24006
24214
  } catch (t) {
@@ -24009,7 +24217,7 @@ wx.get("/tree.json", async (e) => {
24009
24217
  details: t.message
24010
24218
  }, 500);
24011
24219
  }
24012
- }), wx.get("/trees.json", async (e) => {
24220
+ }), Tx.get("/trees.json", async (e) => {
24013
24221
  try {
24014
24222
  let t = e.get("db"), n = await t.prepare("SELECT * FROM trees ORDER BY LOWER(label) ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId FROM channel_trees").all(), a = (Array.isArray(i) ? i : i?.results || []).reduce((e, t) => {
24015
24223
  let n = Number(t.treeId), r = Number(t.channelId);
@@ -24039,7 +24247,7 @@ wx.get("/tree.json", async (e) => {
24039
24247
  } catch {
24040
24248
  return e.json([]);
24041
24249
  }
24042
- }), wx.post("/trees.json", async (e) => {
24250
+ }), Tx.post("/trees.json", async (e) => {
24043
24251
  try {
24044
24252
  let t = e.get("db"), n = await e.req.json(), r = n.id, i = r != null && r !== "" && !isNaN(Number(r)) ? Number(r) : null, a = `tree-${Date.now().toString(36)}`, o = (n.key || n.slug || a).toLowerCase().replace(/[^a-z0-9_-]/g, "-"), s = n.label?.trim() || o, c = n.treeType !== void 0 && n.treeType !== null ? n.treeType : n.type ?? "site", l = n.channelId !== void 0 && n.channelId !== null && Number(n.channelId) || null, u = +(n.isHidden === !0 || n.isHidden === 1 || n.isHidden === "true"), d = e.get("user")?.id || null, f = { ...n };
24045
24253
  if (delete f.id, delete f.key, delete f.label, delete f.treeType, delete f.type, delete f.channelId, delete f.channels, delete f.isHidden, delete f.createdById, delete f.updatedById, delete f.createdAt, delete f.updatedAt, await t.prepare("SELECT id FROM trees WHERE key = ? AND id != ? LIMIT 1").get(o, i ?? -1)) return e.json({
@@ -24064,7 +24272,7 @@ wx.get("/tree.json", async (e) => {
24064
24272
  await t.prepare(`INSERT OR IGNORE INTO channel_trees (channelId, treeId, key) VALUES ${n}`).run(...r);
24065
24273
  }
24066
24274
  }
24067
- return await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24275
+ return await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), await px(t), e.json({
24068
24276
  success: !0,
24069
24277
  id: p,
24070
24278
  key: o,
@@ -24078,12 +24286,12 @@ wx.get("/tree.json", async (e) => {
24078
24286
  } catch (t) {
24079
24287
  return console.error("[API Trees] Error saving tree:", t), e.json({ error: t.message || "Failed to save tree" }, 500);
24080
24288
  }
24081
- }), wx.delete("/trees.json", async (e) => {
24289
+ }), Tx.delete("/trees.json", async (e) => {
24082
24290
  let t = e.get("db"), n = e.req.query("id");
24083
24291
  if (!n) return e.json({ error: "Tree ID required" }, 400);
24084
24292
  let r = Number(n);
24085
24293
  try {
24086
- return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24294
+ return await t.prepare("DELETE FROM trees WHERE id = ?").run(r), await t.prepare("DELETE FROM channel_trees WHERE treeId = ?").run(r), await t.prepare("DELETE FROM tree_nodes WHERE treeId = ?").run(r), await $b(e).clear(), new fx(e.env).purgeGlobalCache(e, t), await px(t), e.json({
24087
24295
  success: !0,
24088
24296
  deletedTreeId: r
24089
24297
  });
@@ -24093,8 +24301,8 @@ wx.get("/tree.json", async (e) => {
24093
24301
  });
24094
24302
  //#endregion
24095
24303
  //#region server/routes/admin/channels.ts
24096
- var Ox = new e();
24097
- Ox.get("/", async (e) => {
24304
+ var kx = new e();
24305
+ kx.get("/", async (e) => {
24098
24306
  try {
24099
24307
  let t = e.get("db"), n = await t.prepare("SELECT * FROM channels ORDER BY id ASC").all(), r = Array.isArray(n) ? n : n?.results || [], i = await t.prepare("SELECT channelId, treeId, key, metaJson FROM channel_trees").all(), a = ((Array.isArray(i) ? i : i?.results || []) || []).reduce((e, t) => {
24100
24308
  e[t.channelId] || (e[t.channelId] = []);
@@ -24160,26 +24368,26 @@ Ox.get("/", async (e) => {
24160
24368
  error: t.message
24161
24369
  }, 500);
24162
24370
  }
24163
- }), Ox.post("/", async (e) => {
24371
+ }), kx.post("/", async (e) => {
24164
24372
  try {
24165
- let t = e.get("db"), n = await e.req.json(), r = n.channel || n.data || n, i = r.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { key: o, label: s, channelType: c = "website", domain: l = "localhost", baseUrl: u = "http://localhost:4321", defaultLanguage: d, default_language: f, language: p, isHidden: m, hidden: h, trees: g = [], createdById: _ = null, updatedById: v = null, id: y, createdAt: b, updatedAt: x, ...S } = r, C = o?.trim() || "main", w = s?.trim() || "Untitled Channel", T = d || f || p || "";
24166
- typeof T == "object" && T && (T = T.value || T.id || ""), T = String(T).trim();
24167
- let ee = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}), te = e.get("user")?.id || v || _ || null;
24373
+ let t = e.get("db"), n = await e.req.json(), r = n.channel || n.data || n, i = r.id, a = i != null && i !== "" && !isNaN(Number(i)) ? Number(i) : null, { key: o, label: s, channelType: c = "website", domain: l = "localhost", baseUrl: u = "http://localhost:4321", defaultLanguage: d, default_language: f, language: p, isHidden: m, hidden: h, trees: g = [], createdById: _ = null, updatedById: v = null, id: y, createdAt: b, updatedAt: x, ...S } = r, C = o?.trim() || "main", ee = s?.trim() || "Untitled Channel", w = d || f || p || "";
24374
+ typeof w == "object" && w && (w = w.value || w.id || ""), w = String(w).trim();
24375
+ let T = m === !0 || m === "true" || m === 1 || h === !0 || h === "true" || h === 1, E = Array.isArray(g) ? g : [], D = JSON.stringify(S || {}), te = e.get("user")?.id || v || _ || null;
24168
24376
  if (await t.prepare("SELECT id FROM channels WHERE key = ? AND id != ? LIMIT 1").get(C, a ?? -1)) return e.json({
24169
24377
  error: `Channel API key "${C}" is already in use.`,
24170
24378
  field: "key"
24171
24379
  }, 409);
24172
- let O = a;
24173
- if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, w, c, l, u, T, +!!ee, D, te, a);
24380
+ let ne = a;
24381
+ if (a) await t.prepare("\n UPDATE channels \n SET key = ?, label = ?, channelType = ?, domain = ?, baseUrl = ?, defaultLanguage = ?, \n isHidden = ?, dataJson = ?, updatedById = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ").run(C, ee, c, l, u, w, +!!T, D, te, a);
24174
24382
  else {
24175
- let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ").run(C, w, c, l, u, T, +!!ee, D, te, te);
24176
- O = Number(e.lastInsertRowid);
24177
- }
24178
- await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(O);
24179
- let k = E.filter((e) => e && e.treeId && e.key);
24180
- if (k.length > 0) {
24181
- let e = k.map(() => "(?, ?, ?, ?)").join(", "), n = k.flatMap((e) => [
24182
- O,
24383
+ let e = await t.prepare("\n INSERT INTO channels (key, label, channelType, domain, baseUrl, defaultLanguage, isHidden, dataJson, createdById, updatedById)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ").run(C, ee, c, l, u, w, +!!T, D, te, te);
24384
+ ne = Number(e.lastInsertRowid);
24385
+ }
24386
+ await t.prepare("DELETE FROM channel_trees WHERE channelId = ?").run(ne);
24387
+ let O = E.filter((e) => e && e.treeId && e.key);
24388
+ if (O.length > 0) {
24389
+ let e = O.map(() => "(?, ?, ?, ?)").join(", "), n = O.flatMap((e) => [
24390
+ ne,
24183
24391
  Number(e.treeId) || e.treeId,
24184
24392
  String(e.key).trim(),
24185
24393
  JSON.stringify(e.meta || {})
@@ -24189,10 +24397,10 @@ Ox.get("/", async (e) => {
24189
24397
  VALUES ${e}
24190
24398
  `).run(...n);
24191
24399
  }
24192
- let A = $b(e);
24193
- return await A.delete(`channel:${C}`), await A.delete(`channel:${O}`), await A.clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24400
+ let k = $b(e);
24401
+ return await k.delete(`channel:${C}`), await k.delete(`channel:${ne}`), await k.clear(), new fx(e.env).purgeGlobalCache(e, t), e.json({
24194
24402
  success: !0,
24195
- id: O
24403
+ id: ne
24196
24404
  });
24197
24405
  } catch (t) {
24198
24406
  return console.error("[API Channels] Error saving channel:", t), e.json({
@@ -24200,7 +24408,7 @@ Ox.get("/", async (e) => {
24200
24408
  details: t.message
24201
24409
  }, 500);
24202
24410
  }
24203
- }), Ox.delete("/", async (e) => {
24411
+ }), kx.delete("/", async (e) => {
24204
24412
  let t = e.get("db"), n = e.req.query("id");
24205
24413
  if (!n) return e.json({ error: "Channel ID required" }, 400);
24206
24414
  let r = Number(n);
@@ -24220,15 +24428,15 @@ Ox.get("/", async (e) => {
24220
24428
  });
24221
24429
  //#endregion
24222
24430
  //#region server/routes/admin/taxonomies.ts
24223
- var kx = new e();
24224
- function Ax(e) {
24431
+ var Ax = new e();
24432
+ function jx(e) {
24225
24433
  return e.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/[\s-]+/g, "-").replace(/^-+|-+$/g, "");
24226
24434
  }
24227
- function jx(e) {
24435
+ function Mx(e) {
24228
24436
  let t = (e || "").trim().toLowerCase(), n = dx()?.taxonomies || {};
24229
24437
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
24230
24438
  }
24231
- async function Mx(e, t, n = []) {
24439
+ async function Nx(e, t, n = []) {
24232
24440
  let r = e.prepare(t);
24233
24441
  if (typeof r.bind == "function") {
24234
24442
  let e = await r.bind(...n).all();
@@ -24240,10 +24448,10 @@ async function Mx(e, t, n = []) {
24240
24448
  }
24241
24449
  return [];
24242
24450
  }
24243
- kx.get("/:taxonomy", async (e) => {
24244
- let t = e.get("db"), n = jx(e.req.param("taxonomy"));
24451
+ Ax.get("/:taxonomy", async (e) => {
24452
+ let t = e.get("db"), n = Mx(e.req.param("taxonomy"));
24245
24453
  try {
24246
- let r = (await Mx(t, "\n SELECT id, taxonomy, key, label, parentId, sortOrder, dataJson, createdAt, updatedAt\n FROM taxonomy_terms\n WHERE taxonomy = ?\n ORDER BY sortOrder ASC, label ASC\n ", [n])).map((e) => ({
24454
+ let r = (await Nx(t, "\n SELECT id, taxonomy, key, label, parentId, sortOrder, dataJson, createdAt, updatedAt\n FROM taxonomy_terms\n WHERE taxonomy = ?\n ORDER BY sortOrder ASC, label ASC\n ", [n])).map((e) => ({
24247
24455
  ...e,
24248
24456
  data: e.dataJson ? JSON.parse(e.dataJson) : {}
24249
24457
  }));
@@ -24254,12 +24462,12 @@ kx.get("/:taxonomy", async (e) => {
24254
24462
  } catch (t) {
24255
24463
  return console.error("[Taxonomy API] Error fetching terms:", t), e.json({ error: "Failed to fetch taxonomy terms" }, 500);
24256
24464
  }
24257
- }), kx.post("/:taxonomy", async (e) => {
24258
- let t = e.get("db"), n = jx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
24465
+ }), Ax.post("/:taxonomy", async (e) => {
24466
+ let t = e.get("db"), n = Mx(e.req.param("taxonomy")), r = await e.req.json(), i = r.label?.trim();
24259
24467
  if (!i) return e.json({ error: "Label is required" }, 400);
24260
- let a = r.key?.trim() || Ax(i), o = r.parentId ? Number(r.parentId) : null, s = r.sortOrder ? Number(r.sortOrder) : 0, c = r.data ? JSON.stringify(r.data) : "{}";
24468
+ let a = r.key?.trim() || jx(i), o = r.parentId ? Number(r.parentId) : null, s = r.sortOrder ? Number(r.sortOrder) : 0, c = r.data ? JSON.stringify(r.data) : "{}";
24261
24469
  try {
24262
- if ((await Mx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, a])).length > 0) return e.json({ error: `A term with the key '${a}' already exists in this taxonomy.` }, 409);
24470
+ if ((await Nx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, a])).length > 0) return e.json({ error: `A term with the key '${a}' already exists in this taxonomy.` }, 409);
24263
24471
  let r = t.prepare("\n INSERT INTO taxonomy_terms (taxonomy, key, label, parentId, sortOrder, dataJson)\n VALUES (?, ?, ?, ?, ?, ?)\n "), l;
24264
24472
  return l = typeof r.bind == "function" ? await r.bind(n, a, i, o, s, c).run() : await r.run(n, a, i, o, s, c), e.json({
24265
24473
  success: !0,
@@ -24268,12 +24476,12 @@ kx.get("/:taxonomy", async (e) => {
24268
24476
  } catch (t) {
24269
24477
  return console.error("[Taxonomy API] Error creating term:", t), e.json({ error: "Failed to create taxonomy term" }, 500);
24270
24478
  }
24271
- }), kx.put("/:taxonomy/:id", async (e) => {
24272
- let t = e.get("db"), n = jx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24479
+ }), Ax.put("/:taxonomy/:id", async (e) => {
24480
+ let t = e.get("db"), n = Mx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24273
24481
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
24274
24482
  let i = await e.req.json();
24275
24483
  try {
24276
- let a = await Mx(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
24484
+ let a = await Nx(t, "SELECT * FROM taxonomy_terms WHERE id = ? AND taxonomy = ?", [r, n]);
24277
24485
  if (a.length === 0) return e.json({ error: "Term not found" }, 404);
24278
24486
  let o = a[0], s = i.label === void 0 ? o.label : i.label.trim(), c = i.key === void 0 ? o.key : i.key.trim(), l = i.parentId === void 0 ? o.parentId : i.parentId ? Number(i.parentId) : null, u = i.sortOrder === void 0 ? o.sortOrder : Number(i.sortOrder), d = o.dataJson;
24279
24487
  if (i.data) {
@@ -24283,14 +24491,14 @@ kx.get("/:taxonomy", async (e) => {
24283
24491
  ...i.data
24284
24492
  });
24285
24493
  }
24286
- if (c !== o.key && (await Mx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, c])).length > 0) return e.json({ error: `A term with the key '${c}' already exists in this taxonomy.` }, 409);
24494
+ if (c !== o.key && (await Nx(t, "SELECT id FROM taxonomy_terms WHERE taxonomy = ? AND key = ?", [n, c])).length > 0) return e.json({ error: `A term with the key '${c}' already exists in this taxonomy.` }, 409);
24287
24495
  let f = t.prepare("\n UPDATE taxonomy_terms \n SET label = ?, key = ?, parentId = ?, sortOrder = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP\n WHERE id = ?\n ");
24288
24496
  return typeof f.bind == "function" ? await f.bind(s, c, l, u, d, r).run() : await f.run(s, c, l, u, d, r), e.json({ success: !0 });
24289
24497
  } catch (t) {
24290
24498
  return console.error("[Taxonomy API] Error updating term:", t), e.json({ error: "Failed to update taxonomy term" }, 500);
24291
24499
  }
24292
- }), kx.delete("/:taxonomy/:id", async (e) => {
24293
- let t = e.get("db"), n = jx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24500
+ }), Ax.delete("/:taxonomy/:id", async (e) => {
24501
+ let t = e.get("db"), n = Mx(e.req.param("taxonomy")), r = Number(e.req.param("id"));
24294
24502
  if (isNaN(r)) return e.json({ error: "Invalid term ID" }, 400);
24295
24503
  try {
24296
24504
  let i = t.prepare("DELETE FROM taxonomy_terms WHERE id = ? AND taxonomy = ?");
@@ -24301,20 +24509,20 @@ kx.get("/:taxonomy", async (e) => {
24301
24509
  });
24302
24510
  //#endregion
24303
24511
  //#region server/schema/engine.ts
24304
- var Nx = null, Px = null;
24512
+ var Px = null, Fx = null;
24305
24513
  if (typeof process < "u" && process?.versions?.node) try {
24306
24514
  let e = i(import.meta.url);
24307
- Nx = e("node:fs"), Px = e("node:path");
24515
+ Px = e("node:fs"), Fx = e("node:path");
24308
24516
  } catch {}
24309
- function Fx(e, t = "") {
24517
+ function Ix(e, t = "") {
24310
24518
  let n = e.split(/[\\/]/).pop() || "";
24311
24519
  return t && n.endsWith(t) ? n.slice(0, -t.length) : n;
24312
24520
  }
24313
- function Ix(e) {
24521
+ function Lx(e) {
24314
24522
  let t = e.match(/\.[^.\\/]+$/);
24315
24523
  return t ? t[0] : "";
24316
24524
  }
24317
- var Lx = {
24525
+ var Rx = {
24318
24526
  nodes: {},
24319
24527
  trees: {},
24320
24528
  blocks: {},
@@ -24324,10 +24532,10 @@ var Lx = {
24324
24532
  nodeLayouts: {},
24325
24533
  blockLayouts: {}
24326
24534
  };
24327
- function Rx(e) {
24535
+ function zx(e) {
24328
24536
  return e ? typeof e == "string" ? e.trim() : Array.isArray(e) ? e.includes("*") ? "*" : e : "*" : "*";
24329
24537
  }
24330
- function zx(e = {}, t = {}) {
24538
+ function Bx(e = {}, t = {}) {
24331
24539
  let n = {
24332
24540
  ...e,
24333
24541
  ...t,
@@ -24339,62 +24547,62 @@ function zx(e = {}, t = {}) {
24339
24547
  };
24340
24548
  return t.required === !0 || String(t.required).toLowerCase() === "true" || t.rules?.required === !0 || String(t.rules?.required).toLowerCase() === "true" || t.required === void 0 && (e.required === !0 || String(e.required).toLowerCase() === "true" || e.rules?.required === !0 || String(e.rules?.required).toLowerCase() === "true") ? (n.required = !0, n.rules.required = !0) : (t.required === !1 || t.rules?.required === !1) && (n.required = !1, n.rules.required = !1), n;
24341
24549
  }
24342
- function Bx(e) {
24550
+ function Vx(e) {
24343
24551
  if (!e || typeof e != "object") return e;
24344
- if (Array.isArray(e)) return e.map(Bx);
24552
+ if (Array.isArray(e)) return e.map(Vx);
24345
24553
  let t = {};
24346
24554
  for (let [n, r] of Object.entries(e)) if (n === "<<" || n === "<<:") {
24347
- let e = Bx(r);
24555
+ let e = Vx(r);
24348
24556
  if (typeof e == "object" && e) {
24349
24557
  if (Array.isArray(e)) for (let n of e) Object.assign(t, n);
24350
24558
  else Object.assign(t, e);
24351
24559
  }
24352
- } else t[n] = Bx(r);
24560
+ } else t[n] = Vx(r);
24353
24561
  return t;
24354
24562
  }
24355
- function Vx(e, t) {
24356
- return e ? Bx(n.parseDocument(e, { customTags: [{
24563
+ function Hx(e, t) {
24564
+ return e ? Vx(n.parseDocument(e, { customTags: [{
24357
24565
  tag: "!include",
24358
24566
  resolve(e) {
24359
- let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = Fx(n);
24567
+ let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim(), r = Ix(n);
24360
24568
  if (!r) return n;
24361
24569
  if (t && t.fieldSets) {
24362
24570
  let e = Object.keys(t.fieldSets).find((e) => e.endsWith("/" + r) || e === r);
24363
- if (e) return Vx(t.fieldSets[e], t);
24571
+ if (e) return Hx(t.fieldSets[e], t);
24364
24572
  }
24365
24573
  return n;
24366
24574
  }
24367
24575
  }] }).toJS() || {}) : {};
24368
24576
  }
24369
- function Hx(e, t = /* @__PURE__ */ new Set()) {
24370
- if (!Nx || !Px) return {};
24371
- let r = Px.resolve(e);
24372
- if (t.has(r) || (t.add(r), !Nx.existsSync(r))) return {};
24373
- let i = Nx.readFileSync(r, "utf-8");
24374
- return Bx(n.parseDocument(i, { customTags: [{
24577
+ function Ux(e, t = /* @__PURE__ */ new Set()) {
24578
+ if (!Px || !Fx) return {};
24579
+ let r = Fx.resolve(e);
24580
+ if (t.has(r) || (t.add(r), !Px.existsSync(r))) return {};
24581
+ let i = Px.readFileSync(r, "utf-8");
24582
+ return Vx(n.parseDocument(i, { customTags: [{
24375
24583
  tag: "!include",
24376
24584
  resolve(e) {
24377
24585
  let n = (typeof e == "string" ? e : String(e?.strValue || e?.value || "")).trim();
24378
- return n ? Hx(Px.resolve(Px.dirname(r), n), new Set(t)) : {};
24586
+ return n ? Ux(Fx.resolve(Fx.dirname(r), n), new Set(t)) : {};
24379
24587
  }
24380
24588
  }] }).toJS() || {});
24381
24589
  }
24382
- function Ux() {
24383
- if (!Nx || !Px || typeof process > "u" || !process?.versions?.node) return null;
24590
+ function Wx() {
24591
+ if (!Px || !Fx || typeof process > "u" || !process?.versions?.node) return null;
24384
24592
  try {
24385
24593
  let e = process.cwd(), t = "", n = [
24386
- Px.resolve(e, "content/definitions"),
24387
- Px.resolve(e, "content"),
24388
- Px.resolve(e, "definitions"),
24389
- Px.resolve(e, "kama-worker/content/definitions")
24594
+ Fx.resolve(e, "content/definitions"),
24595
+ Fx.resolve(e, "content"),
24596
+ Fx.resolve(e, "definitions"),
24597
+ Fx.resolve(e, "kama-worker/content/definitions")
24390
24598
  ];
24391
24599
  try {
24392
24600
  if (import.meta.url) {
24393
- let e = Px.dirname(r(import.meta.url));
24394
- n.push(Px.resolve(e, "../../content/definitions")), n.push(Px.resolve(e, "../content/definitions"));
24601
+ let e = Fx.dirname(r(import.meta.url));
24602
+ n.push(Fx.resolve(e, "../../content/definitions")), n.push(Fx.resolve(e, "../content/definitions"));
24395
24603
  }
24396
24604
  } catch {}
24397
- for (let e of n) if (Nx.existsSync(e)) {
24605
+ for (let e of n) if (Px.existsSync(e)) {
24398
24606
  t = e;
24399
24607
  break;
24400
24608
  }
@@ -24402,19 +24610,19 @@ function Ux() {
24402
24610
  let i = (e) => {
24403
24611
  let n = "";
24404
24612
  for (let r of e) {
24405
- let e = Px.join(t, r);
24406
- if (Nx.existsSync(e)) {
24613
+ let e = Fx.join(t, r);
24614
+ if (Px.existsSync(e)) {
24407
24615
  n = e;
24408
24616
  break;
24409
24617
  }
24410
24618
  }
24411
24619
  if (!n) return {};
24412
- let r = {}, i = Nx.readdirSync(n);
24620
+ let r = {}, i = Px.readdirSync(n);
24413
24621
  for (let e of i) {
24414
24622
  if (!e.endsWith(".yaml") && !e.endsWith(".yml")) continue;
24415
- let t = Px.join(n, e), i = Fx(e, Ix(e));
24623
+ let t = Fx.join(n, e), i = Ix(e, Lx(e));
24416
24624
  try {
24417
- r[i] = Hx(t);
24625
+ r[i] = Ux(t);
24418
24626
  } catch (t) {
24419
24627
  console.error(`❌ Error parsing ${e}:`, t.message);
24420
24628
  }
@@ -24443,59 +24651,59 @@ function Ux() {
24443
24651
  return console.error("❌ Exception inside readLocalFsBundle:", e), null;
24444
24652
  }
24445
24653
  }
24446
- var Wx = null, Gx = null;
24447
- function Kx(e) {
24448
- if (!e) Wx = null, Gx = null;
24449
- else if (Wx && Gx === e) return Wx;
24450
- let t = qx(e);
24451
- return Wx = t, Gx = e, t;
24452
- }
24654
+ var Gx = null, Kx = null;
24453
24655
  function qx(e) {
24656
+ if (!e) Gx = null, Kx = null;
24657
+ else if (Gx && Kx === e) return Gx;
24658
+ let t = Jx(e);
24659
+ return Gx = t, Kx = e, t;
24660
+ }
24661
+ function Jx(e) {
24454
24662
  if (e) {
24455
24663
  let t = {
24456
24664
  nodes: {
24457
24665
  ...e.nodes || e.rawNodes || {},
24458
- ...Lx.nodes
24666
+ ...Rx.nodes
24459
24667
  },
24460
24668
  trees: {
24461
24669
  ...e.trees || e.rawTrees || {},
24462
- ...Lx.trees
24670
+ ...Rx.trees
24463
24671
  },
24464
24672
  channels: {
24465
24673
  ...e.channels || e.rawChannels || {},
24466
- ...Lx.channels
24674
+ ...Rx.channels
24467
24675
  },
24468
24676
  taxonomies: {
24469
24677
  ...e.taxonomies || e.rawTaxonomies || {},
24470
- ...Lx.taxonomies
24678
+ ...Rx.taxonomies
24471
24679
  },
24472
24680
  blocks: {
24473
24681
  ...e.blocks || e.rawBlocks || {},
24474
- ...Lx.blocks
24682
+ ...Rx.blocks
24475
24683
  },
24476
24684
  nodeLayouts: {
24477
24685
  ...e.nodeLayouts || e.rawNodeLayouts || {},
24478
- ...Lx.nodeLayouts
24686
+ ...Rx.nodeLayouts
24479
24687
  },
24480
24688
  blockLayouts: {
24481
24689
  ...e.blockLayouts || e.rawBlockLayouts || {},
24482
- ...Lx.blockLayouts
24690
+ ...Rx.blockLayouts
24483
24691
  },
24484
24692
  fieldSets: {
24485
24693
  ...e.fieldSets || e.rawFieldSets || {},
24486
- ...Lx.fieldSets
24694
+ ...Rx.fieldSets
24487
24695
  }
24488
24696
  };
24489
24697
  if (typeof Object.values(t.nodes)[0] == "string") {
24490
24698
  let e = (e) => {
24491
24699
  let n = {};
24492
24700
  for (let [r, i] of Object.entries(e || {})) {
24493
- let e = Fx(r, Ix(r));
24494
- n[e] = Vx(i, t);
24701
+ let e = Ix(r, Lx(r));
24702
+ n[e] = Hx(i, t);
24495
24703
  }
24496
24704
  return n;
24497
24705
  };
24498
- return Jx({
24706
+ return Yx({
24499
24707
  rawNodes: e(t.nodes),
24500
24708
  rawTrees: e(t.trees),
24501
24709
  rawChannels: e(t.channels),
@@ -24506,12 +24714,12 @@ function qx(e) {
24506
24714
  rawFieldSets: e(t.fieldSets)
24507
24715
  });
24508
24716
  }
24509
- return Jx(t);
24717
+ return Yx(t);
24510
24718
  }
24511
- let t = Ux();
24512
- return t && Object.keys(t.rawNodes || {}).length > 0 ? Jx(t) : Jx(null);
24719
+ let t = Wx();
24720
+ return t && Object.keys(t.rawNodes || {}).length > 0 ? Yx(t) : Yx(null);
24513
24721
  }
24514
- function Jx(e) {
24722
+ function Yx(e) {
24515
24723
  if (!e) return {
24516
24724
  nodes: {},
24517
24725
  trees: {},
@@ -24526,16 +24734,16 @@ function Jx(e) {
24526
24734
  channelTemplate: null,
24527
24735
  userTemplate: null
24528
24736
  };
24529
- let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, w = Object.keys(n).length > 0 ? n : y, T = Object.keys(r).length > 0 ? r : i, ee = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, te = Object.keys(u).length > 0 ? u : S, O = m?.fields || {}, k = {
24737
+ let { rawNodes: t = {}, rawTrees: n = {}, rawChannels: r = {}, channels: i = {}, rawTaxonomies: a = {}, taxonomies: o = {}, rawBlocks: s = {}, rawElements: c = {}, rawNodeLayouts: l = {}, rawBlockLayouts: u = {}, rawLayouts: d = {}, rawFieldSets: f = {}, rawTemplates: p = {}, nodeTemplate: m = null, treeTemplate: h = null, channelTemplate: g = null, userTemplate: _ = null, nodes: v = {}, trees: y = {}, blocks: b = {}, nodeLayouts: x = {}, blockLayouts: S = {} } = e, C = Object.keys(t).length > 0 ? t : v, ee = Object.keys(n).length > 0 ? n : y, w = Object.keys(r).length > 0 ? r : i, T = Object.keys(a).length > 0 ? a : o, E = Object.keys(s).length > 0 ? s : Object.keys(c).length > 0 ? c : b, D = Object.keys(l).length > 0 ? l : Object.keys(d).length > 0 ? d : x, te = Object.keys(u).length > 0 ? u : S, ne = m?.fields || {}, O = {
24530
24738
  ...p,
24531
24739
  ...f
24532
- }, A = (e, t = "settings", n, r) => {
24740
+ }, k = (e, t = "settings", n, r) => {
24533
24741
  let i = {};
24534
24742
  if (!e) return i;
24535
24743
  let a = (e) => {
24536
- let a = k[e] || k[`${e}-base`] || {};
24744
+ let a = O[e] || O[`${e}-base`] || {};
24537
24745
  r && typeof a == "object" && a && (r.inTree === void 0 && a.inTree !== void 0 && (r.inTree = a.inTree), r.inVault === void 0 && a.inVault !== void 0 && (r.inVault = a.inVault), r.hasCanvas === void 0 && a.hasCanvas !== void 0 && (r.hasCanvas = a.hasCanvas));
24538
- let o = a.fields || a, s = A(o, t, n, r);
24746
+ let o = a.fields || a, s = k(o, t, n, r);
24539
24747
  if (a.tab && n) {
24540
24748
  let t = a.tab.id || e, r = a.tab.label || a.label || t;
24541
24749
  n[t] || (n[t] = {
@@ -24543,11 +24751,11 @@ function Jx(e) {
24543
24751
  fields: {}
24544
24752
  }), Object.entries(s).forEach(([e, r]) => {
24545
24753
  let i = n[t].fields[e] || {};
24546
- n[t].fields[e] = zx(i, r);
24754
+ n[t].fields[e] = Bx(i, r);
24547
24755
  });
24548
24756
  } else Object.entries(s).forEach(([e, t]) => {
24549
24757
  let n = i[e] || {};
24550
- i[e] = zx(n, t);
24758
+ i[e] = Bx(n, t);
24551
24759
  });
24552
24760
  };
24553
24761
  return !Array.isArray(e) && typeof e == "object" && e ? (Object.entries(e).forEach(([e, t]) => {
@@ -24556,15 +24764,15 @@ function Jx(e) {
24556
24764
  a(String(t));
24557
24765
  return;
24558
24766
  }
24559
- let n = i[e] || O[e] || {};
24560
- i[e] = zx(n, typeof t == "object" && t ? t : { label: String(t) });
24767
+ let n = i[e] || ne[e] || {};
24768
+ i[e] = Bx(n, typeof t == "object" && t ? t : { label: String(t) });
24561
24769
  }), i) : (Array.isArray(e) && e.forEach((e) => {
24562
24770
  if (typeof e == "string") {
24563
24771
  if (e.includes("/") || e.endsWith(".yaml") || e.endsWith(".yml")) return;
24564
24772
  if (e.startsWith("fieldSet:")) a(e.replace("fieldSet:", "").trim());
24565
24773
  else {
24566
- let t = i[e] || O[e] || {};
24567
- i[e] = zx(t, {
24774
+ let t = i[e] || ne[e] || {};
24775
+ i[e] = Bx(t, {
24568
24776
  type: "text",
24569
24777
  label: e
24570
24778
  });
@@ -24572,26 +24780,26 @@ function Jx(e) {
24572
24780
  } else typeof e == "object" && e && Object.entries(e).forEach(([e, t]) => {
24573
24781
  if (e === "fieldSet") a(String(t));
24574
24782
  else if (e !== "<<" && e !== "<<:") {
24575
- let n = i[e] || O[e] || {};
24576
- i[e] = zx(n, typeof t == "object" && t ? t : {});
24783
+ let n = i[e] || ne[e] || {};
24784
+ i[e] = Bx(n, typeof t == "object" && t ? t : {});
24577
24785
  }
24578
24786
  });
24579
24787
  }), i);
24580
- }, j = (e, t) => {
24788
+ }, A = (e, t) => {
24581
24789
  let n = {};
24582
24790
  return !e || typeof e != "object" ? n : Array.isArray(e) ? (e.forEach((e) => {
24583
24791
  if (typeof e == "object" && e.fieldSet) {
24584
- let r = String(e.fieldSet), i = k[r] || k[`${r}-base`] || {};
24792
+ let r = String(e.fieldSet), i = O[r] || O[`${r}-base`] || {};
24585
24793
  t && (t.inTree === void 0 && i.inTree !== void 0 && (t.inTree = i.inTree), t.inVault === void 0 && i.inVault !== void 0 && (t.inVault = i.inVault), t.hasCanvas === void 0 && i.hasCanvas !== void 0 && (t.hasCanvas = i.hasCanvas));
24586
24794
  let a = i.tab?.id || r, o = i.tab?.label || i.label || a;
24587
24795
  n[a] || (n[a] = {
24588
24796
  label: o,
24589
24797
  fields: {}
24590
24798
  });
24591
- let s = A(i.fields || i, a, n, t);
24799
+ let s = k(i.fields || i, a, n, t);
24592
24800
  Object.entries(s).forEach(([e, t]) => {
24593
24801
  let r = n[a].fields[e] || {};
24594
- n[a].fields[e] = zx(r, t);
24802
+ n[a].fields[e] = Bx(r, t);
24595
24803
  });
24596
24804
  }
24597
24805
  }), n) : (Object.entries(e).forEach(([e, r]) => {
@@ -24603,21 +24811,21 @@ function Jx(e) {
24603
24811
  label: i,
24604
24812
  fields: {}
24605
24813
  });
24606
- let s = A(o, e, n, t);
24814
+ let s = k(o, e, n, t);
24607
24815
  Object.entries(s).forEach(([t, r]) => {
24608
24816
  if (t === "<<" || t === "<<:" || t === "label") return;
24609
24817
  let i = n[e].fields[t] || {};
24610
- n[e].fields[t] = zx(i, r);
24818
+ n[e].fields[t] = Bx(i, r);
24611
24819
  });
24612
24820
  }), n);
24613
- }, ne = {};
24821
+ }, re = {};
24614
24822
  Object.entries(C).forEach(([e, t]) => {
24615
24823
  m && (t.inTree === void 0 && m.inTree !== void 0 && (t.inTree = m.inTree), t.inVault === void 0 && m.inVault !== void 0 && (t.inVault = m.inVault), t.hasCanvas === void 0 && m.hasCanvas !== void 0 && (t.hasCanvas = m.hasCanvas));
24616
- let n = j(t.tabs, t), r = A(t.fields || [], "settings", n, t);
24824
+ let n = A(t.tabs, t), r = k(t.fields || [], "settings", n, t);
24617
24825
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24618
- let i = k[e] || k[`${e}-base`] || {};
24826
+ let i = O[e] || O[`${e}-base`] || {};
24619
24827
  t.inTree === void 0 && i.inTree !== void 0 && (t.inTree = i.inTree), t.inVault === void 0 && i.inVault !== void 0 && (t.inVault = i.inVault), t.hasCanvas === void 0 && i.hasCanvas !== void 0 && (t.hasCanvas = i.hasCanvas);
24620
- let a = i.fields || i, o = A(a, "settings", n, t);
24828
+ let a = i.fields || i, o = k(a, "settings", n, t);
24621
24829
  if (i.tab) {
24622
24830
  let t = i.tab.id || e, r = i.tab.label || i.label || t;
24623
24831
  n[t] || (n[t] = {
@@ -24625,21 +24833,21 @@ function Jx(e) {
24625
24833
  fields: {}
24626
24834
  }), Object.entries(o).forEach(([e, r]) => {
24627
24835
  let i = n[t].fields[e] || {};
24628
- n[t].fields[e] = zx(i, r);
24836
+ n[t].fields[e] = Bx(i, r);
24629
24837
  });
24630
24838
  } else Object.entries(o).forEach(([e, t]) => {
24631
- let n = r[e] || O[e] || {};
24632
- r[e] = zx(n, t);
24839
+ let n = r[e] || ne[e] || {};
24840
+ r[e] = Bx(n, t);
24633
24841
  });
24634
24842
  }), Object.values(n).forEach((e) => {
24635
24843
  Object.entries(e.fields).forEach(([e, t]) => {
24636
24844
  let n = r[e] || {};
24637
- r[e] = zx(n, t);
24845
+ r[e] = Bx(n, t);
24638
24846
  });
24639
24847
  }), Object.keys(n).length === 0 && Object.keys(r).length > 0 && (n.settings = {
24640
24848
  label: t.label || "Settings",
24641
24849
  fields: r
24642
- }), ne[e] = {
24850
+ }), re[e] = {
24643
24851
  ...t,
24644
24852
  id: t.id || e,
24645
24853
  label: t.label || e,
@@ -24647,25 +24855,25 @@ function Jx(e) {
24647
24855
  inVault: t.inVault !== !1,
24648
24856
  hasCanvas: t.hasCanvas === !0,
24649
24857
  defaultLayout: t.defaultLayout,
24650
- allowedBlocks: Rx(t.allowedBlocks),
24651
- disallowedBlocks: t.disallowedBlocks ? Rx(t.disallowedBlocks) : void 0,
24858
+ allowedBlocks: zx(t.allowedBlocks),
24859
+ disallowedBlocks: t.disallowedBlocks ? zx(t.disallowedBlocks) : void 0,
24652
24860
  tabs: n,
24653
24861
  fields: r
24654
24862
  };
24655
24863
  });
24656
- let re = {};
24657
- Object.entries(w).forEach(([e, t]) => {
24658
- let n = j(t.tabs), r = A(t.fields || [], "settings", n);
24864
+ let ie = {};
24865
+ Object.entries(ee).forEach(([e, t]) => {
24866
+ let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24659
24867
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24660
- let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
24868
+ let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
24661
24869
  Object.entries(a).forEach(([e, t]) => {
24662
- r[e] = zx(r[e] || {}, t);
24870
+ r[e] = Bx(r[e] || {}, t);
24663
24871
  });
24664
24872
  }), Object.values(n).forEach((e) => {
24665
24873
  Object.entries(e.fields).forEach(([e, t]) => {
24666
- r[e] = zx(r[e] || {}, t);
24874
+ r[e] = Bx(r[e] || {}, t);
24667
24875
  });
24668
- }), re[e] = {
24876
+ }), ie[e] = {
24669
24877
  ...t,
24670
24878
  id: t.id || e,
24671
24879
  label: t.label || e,
@@ -24673,19 +24881,19 @@ function Jx(e) {
24673
24881
  fields: r
24674
24882
  };
24675
24883
  });
24676
- let ie = {};
24677
- Object.entries(T).forEach(([e, t]) => {
24678
- let n = j(t.tabs), r = A(t.fields || [], "settings", n);
24884
+ let ae = {};
24885
+ Object.entries(w).forEach(([e, t]) => {
24886
+ let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24679
24887
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24680
- let t = k[e] || {}, n = t.fields || t, i = A(n);
24888
+ let t = O[e] || {}, n = t.fields || t, i = k(n);
24681
24889
  Object.entries(i).forEach(([e, t]) => {
24682
- r[e] = zx(r[e] || {}, t);
24890
+ r[e] = Bx(r[e] || {}, t);
24683
24891
  });
24684
24892
  }), Object.values(n).forEach((e) => {
24685
24893
  Object.entries(e.fields).forEach(([e, t]) => {
24686
- r[e] = zx(r[e] || {}, t);
24894
+ r[e] = Bx(r[e] || {}, t);
24687
24895
  });
24688
- }), ie[e] = {
24896
+ }), ae[e] = {
24689
24897
  ...t,
24690
24898
  id: t.id || e,
24691
24899
  label: t.label || e,
@@ -24694,19 +24902,19 @@ function Jx(e) {
24694
24902
  fields: r
24695
24903
  };
24696
24904
  });
24697
- let ae = {};
24698
- Object.entries(ee).forEach(([e, t]) => {
24699
- let n = j(t.tabs), r = A(t.fields || [], "settings", n);
24905
+ let oe = {};
24906
+ Object.entries(T).forEach(([e, t]) => {
24907
+ let n = A(t.tabs), r = k(t.fields || [], "settings", n);
24700
24908
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24701
- let t = k[e] || {}, i = t.fields || t, a = A(i, "settings", n);
24909
+ let t = O[e] || {}, i = t.fields || t, a = k(i, "settings", n);
24702
24910
  Object.entries(a).forEach(([e, t]) => {
24703
- r[e] = zx(r[e] || {}, t);
24911
+ r[e] = Bx(r[e] || {}, t);
24704
24912
  });
24705
24913
  }), Object.values(n).forEach((e) => {
24706
24914
  Object.entries(e.fields).forEach(([e, t]) => {
24707
- r[e] = zx(r[e] || {}, t);
24915
+ r[e] = Bx(r[e] || {}, t);
24708
24916
  });
24709
- }), ae[e] = {
24917
+ }), oe[e] = {
24710
24918
  ...t,
24711
24919
  id: t.id || e,
24712
24920
  label: t.label || e,
@@ -24715,15 +24923,15 @@ function Jx(e) {
24715
24923
  fields: r
24716
24924
  };
24717
24925
  });
24718
- let oe = {};
24926
+ let se = {};
24719
24927
  Object.entries(E).forEach(([e, t]) => {
24720
- let n = A(t.fields || []);
24928
+ let n = k(t.fields || []);
24721
24929
  Array.isArray(t.fieldSets) && t.fieldSets.forEach((e) => {
24722
- let t = k[e] || {}, r = t.fields || t, i = A(r);
24930
+ let t = O[e] || {}, r = t.fields || t, i = k(r);
24723
24931
  Object.entries(i).forEach(([e, t]) => {
24724
- n[e] = zx(n[e] || {}, t);
24932
+ n[e] = Bx(n[e] || {}, t);
24725
24933
  });
24726
- }), oe[e] = {
24934
+ }), se[e] = {
24727
24935
  ...t,
24728
24936
  id: t.id || e,
24729
24937
  label: t.label || e,
@@ -24731,17 +24939,17 @@ function Jx(e) {
24731
24939
  fields: n
24732
24940
  };
24733
24941
  });
24734
- let se = {};
24942
+ let ce = {};
24735
24943
  Object.entries(D).forEach(([e, t]) => {
24736
- let n = j(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { content: { label: "Content" } };
24944
+ let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { content: { label: "Content" } };
24737
24945
  Object.entries(a).forEach(([e, t]) => {
24738
24946
  i[e] = {
24739
24947
  ...t,
24740
24948
  label: t.label || e,
24741
- allowedBlocks: Rx(t.allowedBlocks),
24742
- disallowedBlocks: t.disallowedBlocks ? Rx(t.disallowedBlocks) : void 0
24949
+ allowedBlocks: zx(t.allowedBlocks),
24950
+ disallowedBlocks: t.disallowedBlocks ? zx(t.disallowedBlocks) : void 0
24743
24951
  };
24744
- }), se[e] = {
24952
+ }), ce[e] = {
24745
24953
  ...t,
24746
24954
  id: t.id || e,
24747
24955
  label: t.label || e,
@@ -24754,17 +24962,17 @@ function Jx(e) {
24754
24962
  tabs: n
24755
24963
  };
24756
24964
  });
24757
- let ce = {};
24965
+ let le = {};
24758
24966
  Object.entries(te).forEach(([e, t]) => {
24759
- let n = j(t.tabs), r = A(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
24967
+ let n = A(t.tabs), r = k(t.fields || [], "settings", n), i = {}, a = t.regions || { main: { label: "Main Content" } };
24760
24968
  Object.entries(a).forEach(([e, t]) => {
24761
24969
  i[e] = {
24762
24970
  ...t,
24763
24971
  label: t.label || e,
24764
- allowedBlocks: Rx(t.allowedBlocks),
24765
- disallowedBlocks: t.disallowedBlocks ? Rx(t.disallowedBlocks) : void 0
24972
+ allowedBlocks: zx(t.allowedBlocks),
24973
+ disallowedBlocks: t.disallowedBlocks ? zx(t.disallowedBlocks) : void 0
24766
24974
  };
24767
- }), ce[e] = {
24975
+ }), le[e] = {
24768
24976
  ...t,
24769
24977
  id: t.id || e,
24770
24978
  label: t.label || e,
@@ -24777,21 +24985,21 @@ function Jx(e) {
24777
24985
  tabs: n
24778
24986
  };
24779
24987
  });
24780
- let le = g?.fields || {};
24988
+ let j = g?.fields || {};
24781
24989
  Array.isArray(g?.fieldSets) && g?.fieldSets.forEach((e) => {
24782
- let t = k[e] || {}, n = t.fields || t, r = A(n);
24990
+ let t = O[e] || {}, n = t.fields || t, r = k(n);
24783
24991
  Object.entries(r).forEach(([e, t]) => {
24784
- le[e] = zx(le[e] || {}, t);
24992
+ j[e] = Bx(j[e] || {}, t);
24785
24993
  });
24786
24994
  });
24787
24995
  let ue = g ? {
24788
24996
  ...g,
24789
- fields: le
24997
+ fields: j
24790
24998
  } : null, de = _?.fields || {};
24791
24999
  Array.isArray(_?.fieldSets) && _?.fieldSets.forEach((e) => {
24792
- let t = k[e] || {}, n = t.fields || t, r = A(n);
25000
+ let t = O[e] || {}, n = t.fields || t, r = k(n);
24793
25001
  Object.entries(r).forEach(([e, t]) => {
24794
- de[e] = zx(de[e] || {}, t);
25002
+ de[e] = Bx(de[e] || {}, t);
24795
25003
  });
24796
25004
  });
24797
25005
  let fe = _ ? {
@@ -24799,14 +25007,14 @@ function Jx(e) {
24799
25007
  fields: de
24800
25008
  } : null;
24801
25009
  return {
24802
- nodes: ne,
24803
- trees: re,
24804
- channels: ie,
24805
- taxonomies: ae,
24806
- blocks: oe,
24807
- nodeLayouts: se,
24808
- blockLayouts: ce,
24809
- fieldSets: k,
25010
+ nodes: re,
25011
+ trees: ie,
25012
+ channels: ae,
25013
+ taxonomies: oe,
25014
+ blocks: se,
25015
+ nodeLayouts: ce,
25016
+ blockLayouts: le,
25017
+ fieldSets: O,
24810
25018
  nodeTemplate: m || null,
24811
25019
  treeTemplate: h || null,
24812
25020
  channelTemplate: ue,
@@ -24815,11 +25023,11 @@ function Jx(e) {
24815
25023
  }
24816
25024
  //#endregion
24817
25025
  //#region server/routes/admin/schemas.ts
24818
- var Yx = new e(), Xx = (e) => {
25026
+ var Xx = new e(), Zx = (e) => {
24819
25027
  try {
24820
25028
  let t = e.env?.BUNDLED_DEFINITIONS;
24821
25029
  (!t || Object.keys(t).length === 0) && (t = Db || Eb || Tb);
24822
- let n = Kx(t);
25030
+ let n = qx(t);
24823
25031
  return e.json(n, 200, { "Cache-Control": "no-cache, no-store, must-revalidate" });
24824
25032
  } catch (t) {
24825
25033
  return console.error("[CMS API] Error loading schemas:", t), e.json({
@@ -24828,10 +25036,10 @@ var Yx = new e(), Xx = (e) => {
24828
25036
  }, 500);
24829
25037
  }
24830
25038
  };
24831
- Yx.get("/", Xx), Yx.get("/schemas.json", Xx);
25039
+ Xx.get("/", Zx), Xx.get("/schemas.json", Zx);
24832
25040
  //#endregion
24833
25041
  //#region server/routes/admin/validation.ts
24834
- var Zx = new e(), Qx = {
25042
+ var Qx = new e(), $x = {
24835
25043
  node: "content_nodes",
24836
25044
  nodes: "content_nodes",
24837
25045
  content_node: "content_nodes",
@@ -24843,7 +25051,7 @@ var Zx = new e(), Qx = {
24843
25051
  user: "users",
24844
25052
  users: "users",
24845
25053
  user_account: "user_accounts"
24846
- }, $x = {
25054
+ }, eS = {
24847
25055
  content_nodes: [
24848
25056
  "id",
24849
25057
  "title",
@@ -24900,11 +25108,11 @@ var Zx = new e(), Qx = {
24900
25108
  "createdAt"
24901
25109
  ]
24902
25110
  };
24903
- Zx.post("/validate-unique", async (e) => {
25111
+ Qx.post("/validate-unique", async (e) => {
24904
25112
  try {
24905
25113
  let t = e.get("db"), { entityType: n, field: r, value: i, excludeId: a } = await e.req.json();
24906
25114
  if (!r || i == null || String(i).trim() === "") return e.json({ isUnique: !0 });
24907
- let o = Qx[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = ($x[o] || $x.content_nodes).includes(s), l = -1;
25115
+ let o = $x[n] || "content_nodes", s = r.replace(/[^a-zA-Z0-9_]/g, ""), c = (eS[o] || eS.content_nodes).includes(s), l = -1;
24908
25116
  if (a != null && String(a).trim() !== "") {
24909
25117
  let e = Number(a);
24910
25118
  l = isNaN(e) ? String(a) : e;
@@ -24916,11 +25124,11 @@ Zx.post("/validate-unique", async (e) => {
24916
25124
  } catch (t) {
24917
25125
  return console.error("[API Validation] Error validating global uniqueness:", t), e.json({ error: "Failed to validate uniqueness" }, 500);
24918
25126
  }
24919
- }), Zx.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
25127
+ }), Qx.post("/validate-unique-sibling", async (e) => e.json({ isUnique: !0 }));
24920
25128
  //#endregion
24921
25129
  //#region server/routes/admin/stats.ts
24922
- var eS = new e();
24923
- eS.get("/", async (e) => {
25130
+ var tS = new e();
25131
+ tS.get("/", async (e) => {
24924
25132
  try {
24925
25133
  let t = e.get("db"), n = await t.prepare("\n SELECT \n COUNT(*) as total,\n SUM(CASE WHEN isHidden = 0 THEN 1 ELSE 0 END) as published,\n SUM(CASE WHEN isHidden = 1 THEN 1 ELSE 0 END) as hidden\n FROM content_nodes\n WHERE deletedAt IS NULL OR deletedAt = ''\n ").get(), r = Number(n?.total) || 0, i = Number(n?.published) || 0, a = Number(n?.hidden) || 0, o = await t.prepare("\n SELECT \n (SELECT COUNT(*) FROM channels) as totalChannels,\n (SELECT COUNT(*) FROM trees) as totalTrees,\n (SELECT COUNT(*) FROM users) as totalUsers\n ").get(), s = await t.prepare("\n SELECT contentType as type, COUNT(*) as count \n FROM content_nodes \n WHERE deletedAt IS NULL OR deletedAt = ''\n GROUP BY contentType \n ORDER BY count DESC\n ").all(), c = Array.isArray(s) ? s : s?.results || [], l = await t.prepare("\n SELECT id, title, slug, contentType, isHidden, status, updatedAt \n FROM content_nodes \n WHERE deletedAt IS NULL OR deletedAt = ''\n ORDER BY updatedAt DESC \n LIMIT 5\n ").all(), u = (Array.isArray(l) ? l : l?.results || []).map((e) => ({
24926
25134
  ...e,
@@ -24965,8 +25173,8 @@ eS.get("/", async (e) => {
24965
25173
  });
24966
25174
  //#endregion
24967
25175
  //#region server/routes/admin/assets.ts
24968
- var tS = new e();
24969
- async function nS(e, t, n = []) {
25176
+ var nS = new e();
25177
+ async function rS(e, t, n = []) {
24970
25178
  let r = e.prepare(t);
24971
25179
  if (typeof r.bind == "function") {
24972
25180
  let e = await r.bind(...n).all();
@@ -24978,16 +25186,16 @@ async function nS(e, t, n = []) {
24978
25186
  }
24979
25187
  return [];
24980
25188
  }
24981
- async function rS(e, t, n = []) {
25189
+ async function iS(e, t, n = []) {
24982
25190
  let r = e.prepare(t);
24983
25191
  if (typeof r.bind == "function") return await r.bind(...n).run();
24984
25192
  if (typeof r.run == "function") return await r.run(...n);
24985
25193
  }
24986
- function iS(e, t, n) {
25194
+ function aS(e, t, n) {
24987
25195
  let r = e || (t ? `/media/${t}` : "");
24988
25196
  return r && n && r.startsWith(`https://${n}/`) && !r.includes("/media/") && (r = r.replace(`https://${n}/`, `https://${n}/media/`)), r;
24989
25197
  }
24990
- tS.get("/", async (e) => {
25198
+ nS.get("/", async (e) => {
24991
25199
  try {
24992
25200
  let t = wb(e), { search: n = "", type: r = "all", page: i = "1", limit: a = "24", sort: o = "createdAt", order: s = "DESC", nodeId: c, channelId: l, trashed: u } = e.req.query(), d = Math.max(1, parseInt(i, 10) || 1), f = Math.max(1, Math.min(100, parseInt(a, 10) || 24)), p = (d - 1) * f, m = {
24993
25201
  createdAt: "a.createdAt",
@@ -24997,7 +25205,7 @@ tS.get("/", async (e) => {
24997
25205
  sizeBytes: "a.sizeBytes"
24998
25206
  }[o] || "a.createdAt", h = s.toUpperCase() === "ASC" ? "ASC" : "DESC", g = [], _ = ["(a.isSystemVariant = 0 OR a.isSystemVariant IS NULL)", u === "true" || u === "1" ? "(a.deletedAt IS NOT NULL AND a.deletedAt != '')" : "(a.deletedAt IS NULL OR a.deletedAt = '')"];
24999
25207
  if (c) {
25000
- let e = await nS(t, "SELECT a.id, a.filename, a.isSystemVariant FROM node_assets na JOIN assets a ON na.assetId = a.id WHERE na.nodeId = ?", [Number(c)]);
25208
+ let e = await rS(t, "SELECT a.id, a.filename, a.isSystemVariant FROM node_assets na JOIN assets a ON na.assetId = a.id WHERE na.nodeId = ?", [Number(c)]);
25001
25209
  if (e.length === 0) _.push("1 = 0");
25002
25210
  else {
25003
25211
  let t = e.map((e) => e.isSystemVariant ? `(a.id = '${e.id}' OR a.id IN (SELECT parentAssetId FROM assets WHERE id = '${e.id}'))` : `a.id = '${e.id}'`).join(" OR ");
@@ -25011,10 +25219,10 @@ tS.get("/", async (e) => {
25011
25219
  n && n.trim() !== "" && (_.push("a.filename LIKE ?"), g.push(`%${n.trim()}%`)), r && r !== "all" && (r === "image" ? (_.push("a.mimeType LIKE ?"), g.push("image/%")) : r === "document" ? (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("application/pdf%", "application/msword%", "application/vnd%")) : r === "video" && (_.push("(a.mimeType LIKE ? OR a.mimeType LIKE ?)"), g.push("video/%", "audio/%")));
25012
25220
  let v = `SELECT a.id, a.filename, a.mimeType, a.sizeBytes, a.cdnUrl, a.storageKeyPrivate, a.createdAt, a.updatedAt, a.deletedAt, a.dataJson FROM assets a ${` WHERE ${_.join(" AND ")}`} ORDER BY ${m} ${h} LIMIT ? OFFSET ?`;
25013
25221
  g.push(f, p);
25014
- let y = await nS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25222
+ let y = await rS(t, v, g), b = y.map((e) => e.id), x = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
25015
25223
  if (b.length > 0) {
25016
25224
  let e = b.map(() => "?").join(",");
25017
- (await nS(t, `
25225
+ (await rS(t, `
25018
25226
  SELECT master.id AS assetId, COUNT(DISTINCT na.nodeId) AS count
25019
25227
  FROM assets master
25020
25228
  INNER JOIN node_assets na ON (
@@ -25022,7 +25230,7 @@ tS.get("/", async (e) => {
25022
25230
  EXISTS (SELECT 1 FROM assets crop WHERE crop.id = na.assetId AND crop.isSystemVariant = 1 AND crop.parentAssetId = master.id)
25023
25231
  )
25024
25232
  WHERE master.id IN (${e})
25025
- GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await nS(t, `
25233
+ GROUP BY master.id`, b)).forEach((e) => x.set(String(e.assetId), e.count || 0)), (await rS(t, `
25026
25234
  SELECT parentAssetId, COUNT(id) AS count
25027
25235
  FROM assets
25028
25236
  WHERE isSystemVariant = 1 AND parentAssetId IN (${e})
@@ -25040,7 +25248,7 @@ tS.get("/", async (e) => {
25040
25248
  ...JSON.parse(t.dataJson || "{}")
25041
25249
  };
25042
25250
  } catch {}
25043
- let r = iS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25251
+ let r = aS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25044
25252
  return {
25045
25253
  id: t.id,
25046
25254
  filename: t.filename || "Untitled Asset",
@@ -25065,7 +25273,7 @@ tS.get("/", async (e) => {
25065
25273
  details: t.message || String(t)
25066
25274
  }, 500);
25067
25275
  }
25068
- }), tS.post("/upload", async (e) => {
25276
+ }), nS.post("/upload", async (e) => {
25069
25277
  try {
25070
25278
  let t = wb(e), { storage: n } = ix(e.env), r = await e.req.parseBody(), i = r.file, a = r.isVariant === "true" || r.isVariant === "1" || r.temporary === "true", o = r.replaceAssetId, s = typeof o == "string" && o.trim().length > 0 ? o.trim() : null, c = r.parentAssetId || r.parentAsset, l = typeof c == "string" && c.trim().length > 0 ? c.trim() : null;
25071
25279
  if (!i || !(i instanceof File)) return e.json({ error: "No file uploaded" }, 400);
@@ -25080,14 +25288,14 @@ tS.get("/", async (e) => {
25080
25288
  }
25081
25289
  let p = crypto.randomUUID().replace(/-/g, "").slice(0, 12), m = (/* @__PURE__ */ new Date()).toISOString().slice(0, 7).replace("-", "/"), h = a || i.name.startsWith("crop_"), g = h ? `kama/cache/${m}/${p}` : `kama/uploads/${m}/${p}`, _ = await n.upload(i, g), v = typeof _ == "string" ? _ : _?.key || _?.storageKeyPrivate || _?.storageKey || `${g}/${p}_${i.name}`;
25082
25290
  if (!v) throw Error("Storage provider failed to return a valid storage key");
25083
- let y = e.env.CDN_DOMAIN, b = v.replace(/^\//, ""), x = y ? `https://${y}/media/${b}` : `/media/${b}`, S = i.type || "application/octet-stream", C = i.size || 0, w = e.get("userId"), T = typeof w == "string" && w.trim().length > 0 ? w : null;
25084
- T && (await nS(t, "SELECT id FROM users WHERE id = ?", [T])).length === 0 && (T = null);
25085
- let ee = new fx(e.env);
25291
+ let y = e.env.CDN_DOMAIN, b = v.replace(/^\//, ""), x = y ? `https://${y}/media/${b}` : `/media/${b}`, S = i.type || "application/octet-stream", C = i.size || 0, ee = e.get("userId"), w = typeof ee == "string" && ee.trim().length > 0 ? ee : null;
25292
+ w && (await rS(t, "SELECT id FROM users WHERE id = ?", [w])).length === 0 && (w = null);
25293
+ let T = new fx(e.env);
25086
25294
  if (s) {
25087
- let r = await nS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25295
+ let r = await rS(t, "SELECT storageKeyPrivate, isSystemVariant, parentAssetId FROM assets WHERE id = ?", [s]);
25088
25296
  if (r.length > 0) {
25089
25297
  let a = r[0];
25090
- if (await rS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25298
+ if (await iS(t, "UPDATE assets SET filename = ?, mimeType = ?, sizeBytes = ?, storageKeyPrivate = ?, cdnUrl = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25091
25299
  i.name,
25092
25300
  S,
25093
25301
  C,
@@ -25099,7 +25307,7 @@ tS.get("/", async (e) => {
25099
25307
  } catch (e) {
25100
25308
  console.warn("Failed to cleanup old asset", e);
25101
25309
  }
25102
- ee.purgeAsset(e, t, s);
25310
+ T.purgeAsset(e, t, s);
25103
25311
  let o = `${x}?v=${Date.now()}`;
25104
25312
  return e.json({
25105
25313
  id: s,
@@ -25116,22 +25324,22 @@ tS.get("/", async (e) => {
25116
25324
  }
25117
25325
  }
25118
25326
  let E = `ast_${p}`, D = +!!h;
25119
- await rS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25327
+ await iS(t, "INSERT INTO assets (id, filename, mimeType, sizeBytes, storageKeyPrivate, cdnUrl, createdById, isSystemVariant, parentAssetId, cropCoordinatesJson) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
25120
25328
  E,
25121
25329
  i.name,
25122
25330
  S,
25123
25331
  C,
25124
25332
  v,
25125
25333
  x,
25126
- T,
25334
+ w,
25127
25335
  D,
25128
25336
  l,
25129
25337
  d
25130
25338
  ]);
25131
25339
  let te = x;
25132
25340
  if (l) {
25133
- let n = await nS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25134
- n.length > 0 && (te = iS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), ee.purgeAsset(e, t, l);
25341
+ let n = await rS(t, "SELECT cdnUrl, storageKeyPrivate FROM assets WHERE id = ?", [l]);
25342
+ n.length > 0 && (te = aS(n[0].cdnUrl, n[0].storageKeyPrivate, y)), T.purgeAsset(e, t, l);
25135
25343
  }
25136
25344
  return e.json({
25137
25345
  id: E,
@@ -25150,11 +25358,11 @@ tS.get("/", async (e) => {
25150
25358
  details: t.message || String(t)
25151
25359
  }, 500);
25152
25360
  }
25153
- }), tS.get("/:id/details", async (e) => {
25361
+ }), nS.get("/:id/details", async (e) => {
25154
25362
  try {
25155
- let t = wb(e), n = e.req.param("id"), r = await nS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25363
+ let t = wb(e), n = e.req.param("id"), r = await rS(t, "SELECT * FROM assets WHERE id = ?", [n]);
25156
25364
  if (!r || r.length === 0) return e.json({ error: "Asset not found" }, 404);
25157
- let i = r[0], a = await nS(t, "\n SELECT DISTINCT cn.id, cn.title, cn.contentType, cn.slug, na.fieldKey, na.assetId \n FROM node_assets na \n INNER JOIN content_nodes cn ON na.nodeId = cn.id \n LEFT JOIN assets crop ON na.assetId = crop.id \n WHERE na.assetId = ? OR (crop.isSystemVariant = 1 AND crop.parentAssetId = ?)\n ", [n, n]), o = await nS(t, "\n SELECT id, filename, mimeType, sizeBytes, cdnUrl, storageKeyPrivate, parentAssetId, cropCoordinatesJson, createdAt, updatedAt \n FROM assets \n WHERE isSystemVariant = 1 AND parentAssetId = ? \n ORDER BY createdAt DESC\n ", [n]), s = {
25365
+ let i = r[0], a = await rS(t, "\n SELECT DISTINCT cn.id, cn.title, cn.contentType, cn.slug, na.fieldKey, na.assetId \n FROM node_assets na \n INNER JOIN content_nodes cn ON na.nodeId = cn.id \n LEFT JOIN assets crop ON na.assetId = crop.id \n WHERE na.assetId = ? OR (crop.isSystemVariant = 1 AND crop.parentAssetId = ?)\n ", [n, n]), o = await rS(t, "\n SELECT id, filename, mimeType, sizeBytes, cdnUrl, storageKeyPrivate, parentAssetId, cropCoordinatesJson, createdAt, updatedAt \n FROM assets \n WHERE isSystemVariant = 1 AND parentAssetId = ? \n ORDER BY createdAt DESC\n ", [n]), s = {
25158
25366
  title: "",
25159
25367
  alt: "",
25160
25368
  description: ""
@@ -25165,7 +25373,7 @@ tS.get("/", async (e) => {
25165
25373
  ...JSON.parse(i.dataJson || "{}")
25166
25374
  };
25167
25375
  } catch {}
25168
- let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${iS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
25376
+ let c = i.updatedAt ? new Date(i.updatedAt).getTime() : Date.now(), l = `${aS(i.cdnUrl, i.storageKeyPrivate, e.env?.CDN_DOMAIN)}?v=${c}`;
25169
25377
  return e.json({
25170
25378
  id: i.id,
25171
25379
  filename: i.filename,
@@ -25184,7 +25392,7 @@ tS.get("/", async (e) => {
25184
25392
  if (t.cropCoordinatesJson) try {
25185
25393
  n = JSON.parse(t.cropCoordinatesJson);
25186
25394
  } catch {}
25187
- let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = iS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25395
+ let r = t.updatedAt ? new Date(t.updatedAt).getTime() : c, a = aS(t.cdnUrl, t.storageKeyPrivate, e.env?.CDN_DOMAIN);
25188
25396
  return {
25189
25397
  id: t.id,
25190
25398
  filename: t.filename,
@@ -25201,15 +25409,15 @@ tS.get("/", async (e) => {
25201
25409
  } catch {
25202
25410
  return e.json({ error: "Failed to load details" }, 500);
25203
25411
  }
25204
- }), tS.put("/:id", async (e) => {
25412
+ }), nS.put("/:id", async (e) => {
25205
25413
  try {
25206
- let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await nS(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
25414
+ let t = wb(e), n = e.req.param("id"), r = await e.req.json(), i = await rS(t, "SELECT filename, dataJson FROM assets WHERE id = ?", [n]);
25207
25415
  if (!i || i.length === 0) return e.json({ error: "Asset not found" }, 404);
25208
25416
  let a = i[0], o = {};
25209
25417
  try {
25210
25418
  o = JSON.parse(a.dataJson || "{}");
25211
25419
  } catch {}
25212
- return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await rS(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25420
+ return r.title !== void 0 && (o.title = r.title), r.alt !== void 0 && (o.alt = r.alt), r.description !== void 0 && (o.description = r.description), await iS(t, "UPDATE assets SET filename = ?, dataJson = ?, updatedAt = CURRENT_TIMESTAMP WHERE id = ?", [
25213
25421
  r.filename === void 0 ? a.filename : r.filename,
25214
25422
  JSON.stringify(o),
25215
25423
  n
@@ -25217,10 +25425,10 @@ tS.get("/", async (e) => {
25217
25425
  } catch {
25218
25426
  return e.json({ error: "Failed to update asset" }, 500);
25219
25427
  }
25220
- }), tS.delete("/:id", async (e) => {
25428
+ }), nS.delete("/:id", async (e) => {
25221
25429
  try {
25222
- let t = wb(e), n = e.req.param("id"), r = (await nS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
25223
- return r ? (new fx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await rS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await rS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [n, n]), e.json({
25430
+ let t = wb(e), n = e.req.param("id"), r = (await rS(t, "SELECT id, filename, isSystemVariant FROM assets WHERE id = ?", [n]))[0];
25431
+ return r ? (new fx(e.env).purgeAsset(e, t, n), r.isSystemVariant ? await iS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ?", [n]) : await iS(t, "UPDATE assets SET deletedAt = CURRENT_TIMESTAMP WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [n, n]), e.json({
25224
25432
  success: !0,
25225
25433
  id: n,
25226
25434
  trashed: !0
@@ -25231,10 +25439,10 @@ tS.get("/", async (e) => {
25231
25439
  details: t.message || String(t)
25232
25440
  }, 500);
25233
25441
  }
25234
- }), tS.post("/restore", async (e) => {
25442
+ }), nS.post("/restore", async (e) => {
25235
25443
  try {
25236
25444
  let t = wb(e), n = await e.req.json(), r = n.id || n.assetId;
25237
- return r ? (await nS(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0] ? (await rS(t, "UPDATE assets SET deletedAt = NULL WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [r, r]), new fx(e.env).purgeAsset(e, t, r), e.json({
25445
+ return r ? (await rS(t, "SELECT id, filename FROM assets WHERE id = ?", [r]))[0] ? (await iS(t, "UPDATE assets SET deletedAt = NULL WHERE id = ? OR (isSystemVariant = 1 AND parentAssetId = ?)", [r, r]), new fx(e.env).purgeAsset(e, t, r), e.json({
25238
25446
  success: !0,
25239
25447
  id: r,
25240
25448
  restored: !0
@@ -25245,13 +25453,13 @@ tS.get("/", async (e) => {
25245
25453
  details: t.message
25246
25454
  }, 500);
25247
25455
  }
25248
- }), tS.delete("/purge/:id", async (e) => {
25456
+ }), nS.delete("/purge/:id", async (e) => {
25249
25457
  try {
25250
- let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await nS(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
25458
+ let t = wb(e), { storage: n } = ix(e.env), r = e.req.param("id"), i = (await rS(t, "SELECT id, filename, storageKeyPrivate, isSystemVariant FROM assets WHERE id = ?", [r]))[0];
25251
25459
  if (!i) return e.json({ error: "Asset not found" }, 404);
25252
25460
  new fx(e.env).purgeAsset(e, t, r);
25253
25461
  let a = [i];
25254
- i.isSystemVariant || (a = [i, ...await nS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
25462
+ i.isSystemVariant || (a = [i, ...await rS(t, "SELECT id, storageKeyPrivate FROM assets WHERE isSystemVariant = 1 AND parentAssetId = ?", [r])]);
25255
25463
  let o = a.map((e) => e.id);
25256
25464
  if (typeof n.delete == "function") {
25257
25465
  for (let e of a) if (e.storageKeyPrivate) try {
@@ -25261,7 +25469,7 @@ tS.get("/", async (e) => {
25261
25469
  }
25262
25470
  }
25263
25471
  let s = o.map(() => "?").join(",");
25264
- return await rS(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await rS(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
25472
+ return await iS(t, `DELETE FROM node_assets WHERE assetId IN (${s})`, o), await iS(t, `DELETE FROM assets WHERE id IN (${s})`, o), e.json({
25265
25473
  success: !0,
25266
25474
  id: r,
25267
25475
  purged: !0,
@@ -25277,8 +25485,8 @@ tS.get("/", async (e) => {
25277
25485
  });
25278
25486
  //#endregion
25279
25487
  //#region server/routes/public/node.ts
25280
- var aS = new $y();
25281
- function oS() {
25488
+ var oS = new $y();
25489
+ function sS() {
25282
25490
  return {
25283
25491
  fullPath: /* @__PURE__ */ new Map(),
25284
25492
  treeEdges: /* @__PURE__ */ new Map(),
@@ -25286,9 +25494,6 @@ function oS() {
25286
25494
  assetUrls: /* @__PURE__ */ new Map()
25287
25495
  };
25288
25496
  }
25289
- function sS(...e) {
25290
- return e.map((e) => String(e ?? "")).join(":");
25291
- }
25292
25497
  function cS(e, t) {
25293
25498
  let n = Date.now();
25294
25499
  if (e && String(e).trim() !== "") {
@@ -25446,7 +25651,7 @@ function fS(e) {
25446
25651
  }
25447
25652
  return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, fS(t)]));
25448
25653
  }
25449
- async function pS(e, t, n) {
25654
+ async function pS(e, t, n, r) {
25450
25655
  if (typeof t == "string") {
25451
25656
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
25452
25657
  let r = (e, t) => {
@@ -25456,78 +25661,48 @@ async function pS(e, t, n) {
25456
25661
  for (let e of t.matchAll(/(?:#node:|data-node-id\s*=\s*["'])([^"'\s>]+)/gi)) i.add(e[1]);
25457
25662
  for (let e of t.matchAll(/(?:#asset:|data-asset-id\s*=\s*["'])([^"'\s>]+)/gi)) a.add(e[1]);
25458
25663
  if (i.size === 0 && a.size === 0) return t;
25459
- let o = Array.from(i).map(() => "?").join(","), s = i.size > 0 ? await e.prepare(`SELECT id, slug FROM content_nodes WHERE id IN (${o})`).all(...i) : [], c = /* @__PURE__ */ new Map();
25460
- (Array.isArray(s) ? s : s?.results || []).forEach((e) => c.set(String(e.id), String(e.slug || "").replace(/^\/+|\/+$/g, "")));
25461
- let l = Array.from(a).map(() => "?").join(","), u = a.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${l})`).all(...a) : [], d = /* @__PURE__ */ new Map();
25462
- (Array.isArray(u) ? u : u?.results || []).forEach((e) => d.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : "")));
25463
- let f = /* @__PURE__ */ new Map(), p = /<a\s+([^>]+)>/gi;
25464
- return await Promise.all(Array.from(t.matchAll(p)).map(async (t) => {
25465
- let i = t[1], a = r(i, "data-node-id"), o = r(i, "data-tree-id");
25466
- if (!a || !o) return;
25467
- let s = await hS(e, a, o, n);
25468
- if (s?.treeNodeId) {
25469
- let t = await yS(e, String(s.treeNodeId), o, n);
25470
- f.set(`${a}:${o}`, t);
25471
- }
25472
- })), t.replace(p, (e, t) => {
25664
+ let o = /* @__PURE__ */ new Map();
25665
+ if (i.size > 0) {
25666
+ let t = Array.from(i).map(() => "?").join(","), r = await e.prepare(`SELECT nodeId, path FROM node_routes WHERE channelId = ? AND nodeId IN (${t}) AND isCanonical = 1`).all(n, ...i);
25667
+ (Array.isArray(r) ? r : r?.results || []).forEach((e) => o.set(String(e.nodeId), e.path));
25668
+ }
25669
+ let s = Array.from(a).map(() => "?").join(","), c = a.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${s})`).all(...a) : [], l = /* @__PURE__ */ new Map();
25670
+ return (Array.isArray(c) ? c : c?.results || []).forEach((e) => l.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : ""))), t.replace(/<a\s+([^>]+)>/gi, (e, t) => {
25473
25671
  let n = r(t, "data-node-id"), i = r(t, "data-asset-id"), a = r(t, "href") || "";
25474
25672
  if (a.startsWith("mailto:")) return `<a ${t.replace(/\s+target\s*=\s*["'][^"']*["']/i, "")}>`;
25475
- let o = i || a.match(/^#asset:(.+)$/i)?.[1], s = n || a.match(/^#node:(.+)$/i)?.[1];
25476
- if (!s && !o) return e;
25477
- if (o && !s) {
25478
- let n = d.get(o);
25673
+ let s = i || a.match(/^#asset:(.+)$/i)?.[1], c = n || a.match(/^#node:(.+)$/i)?.[1];
25674
+ if (!c && !s) return e;
25675
+ if (s && !c) {
25676
+ let n = l.get(s);
25479
25677
  if (n) {
25480
25678
  let e = t;
25481
- return /href\s*=\s*["'][^"']*["']/i.test(e) ? e = e.replace(/href\s*=\s*["'][^"']*["']/i, `href="${n}"`) : e += ` href="${n}"`, i || (e += ` data-asset-id="${o}"`), `<a ${e}>`;
25679
+ return /href\s*=\s*["'][^"']*["']/i.test(e) ? e = e.replace(/href\s*=\s*["'][^"']*["']/i, `href="${n}"`) : e += ` href="${n}"`, i || (e += ` data-asset-id="${s}"`), `<a ${e}>`;
25482
25680
  }
25483
25681
  return e;
25484
25682
  }
25485
- let l = r(t, "data-tree-id"), u = l ? f.get(`${s}:${l}`) : void 0, p = c.get(s), m = u || (p === void 0 ? "#" : `/${p}`), h = t;
25486
- return /href\s*=\s*["'][^"']*["']/i.test(h) ? h = h.replace(/href\s*=\s*["'][^"']*["']/i, `href="${m || "/"}"`) : h += ` href="${m || "/"}"`, `<a ${h}>`;
25683
+ let u = o.get(c) || "#", d = t;
25684
+ return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
25487
25685
  });
25488
25686
  }
25489
- if (Array.isArray(t)) return Promise.all(t.map((t) => pS(e, t, n)));
25687
+ if (Array.isArray(t)) return Promise.all(t.map((t) => pS(e, t, n, r)));
25490
25688
  if (t && typeof t == "object") {
25491
25689
  if (typeof t.href == "string" && (t.href.startsWith("#node:") || t.href.startsWith("#asset:"))) return {
25492
25690
  ...t,
25493
- href: await mS(e, t, n)
25691
+ href: await mS(e, t, n, r)
25494
25692
  };
25495
- let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await pS(e, r, n)]));
25496
- return Object.fromEntries(r);
25693
+ let i = await Promise.all(Object.entries(t).map(async ([t, i]) => [t, await pS(e, i, n, r)]));
25694
+ return Object.fromEntries(i);
25497
25695
  }
25498
25696
  return t;
25499
25697
  }
25500
- async function mS(e, t, n) {
25501
- let r = t.href.match(/^#node:(.+)$/), i = t.href.match(/^#asset:(.+)$/);
25502
- if (i) return _S(e, i[1], n);
25503
- if (!r) return t.href;
25504
- let a = r[1];
25505
- if (t.treeId) {
25506
- let r = await hS(e, a, String(t.treeId), n);
25507
- if (r?.treeNodeId) {
25508
- let i = await yS(e, String(r.treeNodeId), String(t.treeId), n);
25509
- if (i) return i;
25510
- }
25511
- }
25512
- let o = await gS(e, a, n);
25513
- return o === void 0 ? "#" : `/${o}`;
25514
- }
25515
- async function hS(e, t, n, r) {
25516
- let i = sS(t, n), a = r.treeEdges.get(i);
25517
- if (a) return a;
25518
- let o = e.prepare("SELECT contentId as treeNodeId FROM tree_nodes WHERE contentId = ? AND treeId = ? LIMIT 1").get(t, n);
25519
- return r.treeEdges.set(i, Promise.resolve(o)), o;
25520
- }
25521
- async function gS(e, t, n) {
25522
- let r = String(t), i = n.nodeSlugs.get(r);
25523
- if (i) return i;
25524
- let a = (async () => {
25525
- let n = await e.prepare("SELECT slug FROM content_nodes WHERE id = ?").get(t);
25526
- return n?.slug ? String(n.slug).replace(/^\/+|\/+$/g, "") : void 0;
25527
- })();
25528
- return n.nodeSlugs.set(r, a), a;
25698
+ async function mS(e, t, n, r) {
25699
+ let i = t.href.match(/^#node:(.+)$/), a = t.href.match(/^#asset:(.+)$/);
25700
+ if (a) return hS(e, a[1], r);
25701
+ if (!i) return t.href;
25702
+ let o = i[1];
25703
+ return (await e.prepare("SELECT path FROM node_routes WHERE nodeId = ? AND channelId = ? AND isCanonical = 1 LIMIT 1").get(Number(o), n))?.path || "#";
25529
25704
  }
25530
- async function _S(e, t, n) {
25705
+ async function hS(e, t, n) {
25531
25706
  let r = String(t), i = n.assetUrls.get(r);
25532
25707
  if (i) return i;
25533
25708
  let a = (async () => {
@@ -25536,7 +25711,7 @@ async function _S(e, t, n) {
25536
25711
  })();
25537
25712
  return n.assetUrls.set(r, a), a;
25538
25713
  }
25539
- function vS(e) {
25714
+ function gS(e) {
25540
25715
  let t = e.socialImage;
25541
25716
  if (!t || typeof t != "object") return null;
25542
25717
  let n = (e, t) => {
@@ -25567,24 +25742,7 @@ function vS(e) {
25567
25742
  ])
25568
25743
  };
25569
25744
  }
25570
- async function yS(e, t, n, r) {
25571
- if (!t) return "";
25572
- let i = sS(t, n);
25573
- if (r) {
25574
- let e = r.fullPath.get(i);
25575
- if (e) return e;
25576
- }
25577
- let a = (async () => {
25578
- let r = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, parentId, slug, level) AS (\n SELECT t.contentId, t.parentId, c.slug, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId, t.parentId, c.slug, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT slug FROM ancestor_path ORDER BY level DESC\n ").all(t, n, n), i = Array.isArray(r) ? r : r?.results || [], a = [];
25579
- for (let e of i) {
25580
- let t = (e.slug || "").replace(/^\/+|\/+$/g, "");
25581
- t === "home" || t === "homee" ? i.length === 1 && (a.length = 0) : t && a.push(t);
25582
- }
25583
- return "/" + a.join("/");
25584
- })();
25585
- return r && r.fullPath.set(i, a), a;
25586
- }
25587
- async function bS(e, t, n, r, i) {
25745
+ async function _S(e, t, n, r, i) {
25588
25746
  let a = {}, o = null;
25589
25747
  if (t) {
25590
25748
  let i = await e.prepare("\n WITH RECURSIVE ancestor_path(contentId, title, slug, parentId, level) AS (\n SELECT t.contentId, c.title, c.slug, t.parentId, 0 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.contentId = ? AND t.treeId = ?\n UNION ALL\n SELECT t.contentId, c.title, c.slug, t.parentId, ap.level + 1 FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id INNER JOIN ancestor_path ap ON t.contentId = ap.parentId AND t.treeId = ?\n )\n SELECT c.dataJson, c.draftDataJson FROM ancestor_path ap INNER JOIN content_nodes c ON ap.contentId = c.id ORDER BY ap.level ASC\n ").all(t, n, n), s = Array.isArray(i) ? i : i?.results || [], c = /* @__PURE__ */ new Set([
@@ -25622,200 +25780,151 @@ async function bS(e, t, n, r, i) {
25622
25780
  inheritedFields: a
25623
25781
  };
25624
25782
  }
25625
- function xS(e) {
25783
+ function vS(e) {
25626
25784
  let t = Number(e?.env?.CMS_NODE_CACHE_TTL);
25627
25785
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
25628
25786
  }
25629
- async function SS(e, t, n, r) {
25787
+ async function yS(e, t, n, r) {
25630
25788
  try {
25631
25789
  await e.set(t, n, r);
25632
25790
  } catch (e) {
25633
25791
  console.warn("[CMS Cache] Failed to write node response to cache:", e);
25634
25792
  }
25635
25793
  }
25636
- var CS = X({
25637
- channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
25638
- channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25639
- lang: J().optional().openapi({ description: "Requested language code" }),
25640
- preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
25641
- revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
25642
- treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
25643
- }), wS = X({
25644
- error: J(),
25645
- details: J().optional()
25646
- }).openapi("ErrorResponse"), TS = X({
25647
- channelId: G_([J(), c_()]),
25648
- treeId: J().nullable(),
25649
- language: J().nullable(),
25650
- node: tv(k_()),
25651
- content: tv(z_(k_())),
25652
- regionMeta: tv(X({
25653
- isInherited: g_(),
25654
- inheritedFromId: J().optional(),
25655
- inheritedFromTitle: J().optional()
25656
- }))
25657
- }).openapi("NodeResponse"), ES = eb({
25658
- method: "get",
25659
- path: "/{path+}",
25660
- summary: "Fetch CMS Node Content",
25661
- description: "Retrieves a fully hydrated CMS node along with its content blocks and inherited regions.",
25662
- tags: ["Public Node API"],
25663
- request: {
25664
- params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
25665
- query: CS
25666
- },
25667
- responses: {
25668
- 200: {
25669
- description: "Fully hydrated CMS Node",
25670
- content: { "application/json": { schema: TS } }
25671
- },
25672
- 404: {
25673
- description: "Node or Channel not found",
25674
- content: { "application/json": { schema: wS } }
25675
- },
25676
- 500: {
25677
- description: "Server error during hydration",
25678
- content: { "application/json": { schema: wS } }
25679
- }
25680
- }
25681
- });
25682
- aS.openapi(ES, async (e) => {
25794
+ async function bS(e) {
25683
25795
  try {
25684
- let t = e.get("db"), n = oS(), { path: r } = e.req.valid("param"), i = e.req.valid("query"), a = (r || "index").replace(/^\/+|\/+$/g, ""), o = i.channelId || i.channel || "1", s = i.lang, c = i.preview === "true", l = i.revisionId, u = isNaN(Number(o)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(o) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(o));
25685
- if (!u) return e.json({ error: `Channel '${o}' not found` }, 404);
25686
- let d = u.status === "disabled" || u.status === "inactive" || u.isEnabled === 0 || u.isEnabled === !1;
25687
- if (!c && d) return e.json({ error: `Channel '${u.key || o}' is currently inactive` }, 404);
25688
- let f = u.id, p = u.key || o, m = $b(e), h = dx(e.env?.BUNDLED_DEFINITIONS), g = /^\d+$/.test(a), _ = null, v = null, y = i.treeId, b = a.split("/"), x = b[b.length - 1], S = "/" + a.replace(/^\/+|\/+$/g, ""), C = `
25689
- SELECT cn.*, tn.contentId as treeNodeId, tn.parentId, tn.treeId FROM content_nodes cn
25690
- INNER JOIN tree_nodes tn ON cn.id = tn.contentId
25691
- ${f === null ? "" : "INNER JOIN node_channels nc ON cn.id = nc.nodeId"}
25692
- WHERE cn.slug = ? ${f === null ? "" : "AND nc.channelId = ?"}
25693
- `, w = f === null ? [x] : [x, f], T = await t.prepare(C).all(...w), ee = Array.isArray(T) ? T : T?.results || [];
25694
- if (ee.length > 0) {
25695
- let e = await Promise.all(ee.map(async (e) => ({
25696
- candidate: e,
25697
- calculatedPath: await yS(t, String(e.treeNodeId), String(e.treeId), n)
25698
- }))), r = S.replace(/^\/+|\/+$/g, "");
25699
- for (let { candidate: t, calculatedPath: n } of e) {
25700
- let e = n.replace(/^\/+|\/+$/g, "");
25701
- if (e === r || r === "home" && (e === "" || e === "home")) {
25702
- _ = t, v = t;
25703
- break;
25704
- }
25705
- }
25796
+ let t = e.get("db"), n = sS(), r = new URL(e.req.url), i = r.searchParams.get("channelId") || r.searchParams.get("channel"), a = r.searchParams.get("lang"), o = r.searchParams.get("preview") === "true", s = r.searchParams.get("revisionId"), c = r.searchParams.get("treeId"), l = r.pathname, u = "";
25797
+ l.includes("/node/") ? u = l.substring(l.indexOf("/node/") + 6) : l.endsWith("/node") && (u = "");
25798
+ try {
25799
+ u = decodeURIComponent(u);
25800
+ } catch {}
25801
+ u = u.replace(/^\/+|\/+$/g, "");
25802
+ let d = u === "" || u === "index" ? "/" : `/${u}`, f = i || "1", p = isNaN(Number(f)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(f) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(f));
25803
+ if (!p) return e.json({ error: `Channel '${f}' not found` }, 404);
25804
+ let m = p.status === "disabled" || p.status === "inactive" || p.isEnabled === 0 || p.isEnabled === !1;
25805
+ if (!o && m) return e.json({ error: `Channel '${p.key || f}' is currently inactive` }, 404);
25806
+ let h = p.id, g = p.key || f, _ = await t.prepare("\n SELECT * FROM node_routes WHERE path = ? AND channelId = ? LIMIT 1\n ").get(d, h);
25807
+ if (_?.redirectUrl) return e.json({
25808
+ redirect: _.redirectUrl,
25809
+ isCanonical: !1
25810
+ });
25811
+ let v = null, y = _?.treeId || c || null;
25812
+ if (_?.nodeId) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(_.nodeId);
25813
+ else if (/^\d+$/.test(u)) v = await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(u));
25814
+ else {
25815
+ let e = u.split("/").pop() || u;
25816
+ v = await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(e);
25706
25817
  }
25707
- if (!_ && b.length === 1 && (_ = f === null ? await t.prepare("SELECT * FROM content_nodes WHERE slug = ?").get(x) : await t.prepare("SELECT cn.* FROM content_nodes cn INNER JOIN node_channels nc ON cn.id = nc.nodeId WHERE cn.slug = ? AND nc.channelId = ?").get(x, f)), !_ && g && (_ = f === null ? await t.prepare("SELECT * FROM content_nodes WHERE id = ?").get(Number(a)) : await t.prepare("SELECT cn.* FROM content_nodes cn INNER JOIN node_channels nc ON cn.id = nc.nodeId WHERE cn.id = ? AND nc.channelId = ?").get(Number(a), f)), !_) return e.json({ error: `Node '${a}' not found for Channel '${o}'` }, 404);
25708
- let E = null;
25709
- if (l) {
25710
- let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(_.id, Number(l));
25818
+ if (!v) return e.json({ error: `Node '${u}' not found for Channel '${f}'` }, 404);
25819
+ let b = null;
25820
+ if (s) {
25821
+ let e = await t.prepare("SELECT snapshotJson FROM node_revisions WHERE nodeId = ? AND version = ?").get(v.id, Number(s));
25711
25822
  if (e && e.snapshotJson) try {
25712
- E = JSON.parse(e.snapshotJson), E.node && (E.node.title && (_.title = E.node.title), E.node.slug && (_.slug = E.node.slug));
25823
+ b = JSON.parse(e.snapshotJson), b.node && (b.node.title && (v.title = b.node.title), b.node.slug && (v.slug = b.node.slug));
25713
25824
  } catch (e) {
25714
25825
  console.error("[CMS] Failed to parse snapshotJson", e);
25715
25826
  }
25716
25827
  }
25717
- if (!v) {
25718
- let e = y ? [_.id, y] : [_.id];
25719
- v = await t.prepare(`SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${y ? "AND treeId = ?" : ""} LIMIT 1`).get(...e);
25720
- }
25721
- let D = v?.treeId || y || "main-nav", te = null;
25722
- if (D) {
25723
- let e = await t.prepare("\n SELECT dataJson \n FROM trees \n WHERE id = ? OR key = ? \n LIMIT 1\n ").get(Number(D) || -1, String(D));
25828
+ let x = await t.prepare(`SELECT contentId as treeNodeId, treeId, parentId FROM tree_nodes WHERE contentId = ? ${y ? "AND treeId = ?" : ""} LIMIT 1`).get(v.id, ...y ? [y] : []);
25829
+ !y && x?.treeId && (y = x.treeId), y ||= "main-nav";
25830
+ let S = null;
25831
+ if (y) {
25832
+ let e = await t.prepare("SELECT dataJson FROM trees WHERE id = ? OR key = ? LIMIT 1").get(Number(y) || -1, String(y));
25724
25833
  if (e?.dataJson) try {
25725
25834
  let t = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
25726
- t.defaultLanguage ? te = String(t.defaultLanguage).trim() : t.language && (te = String(t.language).trim());
25835
+ t.defaultLanguage ? S = String(t.defaultLanguage).trim() : t.language && (S = String(t.language).trim());
25727
25836
  } catch {}
25728
25837
  }
25729
- let O = null;
25730
- if (u) {
25731
- if (u.defaultLanguage) O = String(u.defaultLanguage).trim();
25732
- else if (u.dataJson) try {
25733
- let e = typeof u.dataJson == "string" ? JSON.parse(u.dataJson) : u.dataJson;
25734
- e.defaultLanguage ? O = String(e.defaultLanguage).trim() : e.language && (O = String(e.language).trim());
25838
+ let C = null;
25839
+ if (p) {
25840
+ if (p.defaultLanguage) C = String(p.defaultLanguage).trim();
25841
+ else if (p.dataJson) try {
25842
+ let e = typeof p.dataJson == "string" ? JSON.parse(p.dataJson) : p.dataJson;
25843
+ e.defaultLanguage ? C = String(e.defaultLanguage).trim() : e.language && (C = String(e.language).trim());
25735
25844
  } catch {}
25736
25845
  }
25737
- let k = _.language?.trim() || null, A = te || O || s?.trim() || null, j = k || A || null, ne = `node:${f || p}:${j || "default"}:${a}`, re = e.req.header("x-bypass-cache") === "true" || !!l;
25738
- if (!c && !re) {
25739
- let t = await m.get(ne);
25846
+ let ee = v.language?.trim() || null, w = S || C || a?.trim() || null, T = ee || w || null, E = `node:${h || g}:${T || "default"}:${u}`, D = e.req.header("x-bypass-cache") === "true" || !!s, te = $b(e);
25847
+ if (!o && !D) {
25848
+ let t = await te.get(E);
25740
25849
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
25741
25850
  }
25742
- let ie = v?.parentId || null, ae = v?.treeNodeId ? await yS(t, String(v.treeNodeId), String(D), n) : `/${(_.slug || "").replace(/^\/+|\/+$/g, "")}`, oe = {
25743
- id: _.id,
25744
- title: _.title,
25745
- slug: _.slug,
25746
- language: j,
25747
- path: ae === "" ? "/" : ae,
25748
- nodeType: _.contentType,
25749
- createdAt: _.createdAt,
25750
- updatedAt: _.updatedAt
25751
- }, se = _.contentType || "node", ce = h.nodes?.[se] || Object.values(h.nodes || {})[0] || {}, le = { ...ce.fields || {} };
25752
- ce.tabs && Object.values(ce.tabs).forEach((e) => {
25753
- Object.assign(le, e.fields || {});
25851
+ let ne = x?.parentId || null, O = _?.path || (d === "" ? "/" : d), k = {
25852
+ id: v.id,
25853
+ title: v.title,
25854
+ slug: v.slug,
25855
+ language: T,
25856
+ path: O,
25857
+ nodeType: v.contentType,
25858
+ createdAt: v.createdAt,
25859
+ updatedAt: v.updatedAt
25860
+ }, A = dx(e.env?.BUNDLED_DEFINITIONS), re = v.contentType || "node", ie = A.nodes?.[re] || Object.values(A.nodes || {})[0] || {}, ae = { ...ie.fields || {} };
25861
+ ie.tabs && Object.values(ie.tabs).forEach((e) => {
25862
+ Object.assign(ae, e.fields || {});
25754
25863
  });
25755
- let ue = {}, de = null, fe = null, pe = !1, me = {}, he = c && _.draftDataJson || _.dataJson;
25756
- if (E && E.node && E.node.dataJson && (he = E.node.dataJson), he) try {
25757
- me = typeof he == "string" ? JSON.parse(he) : he;
25864
+ let oe = {}, se = null, ce = null, le = !1, j = {}, ue = o && v.draftDataJson || v.dataJson;
25865
+ if (b && b.node && b.node.dataJson && (ue = b.node.dataJson), ue) try {
25866
+ j = typeof ue == "string" ? JSON.parse(ue) : ue;
25758
25867
  } catch {}
25759
- me.disabledRegions && (ue = me.disabledRegions), pe = me.hidden === !0 || me.hidden === 1 || me.hidden === "1" || me.hidden === "true", de = me.startShowingAt || null, fe = me.stopShowingAt || null;
25760
- let ge = me.layoutId, _e = ge && ge !== "inherit", { resolvedLayoutId: ve, inheritedFields: ye } = await bS(t, ie, D, c, le), be = _e ? ge : ve || ce.defaultLayout || null;
25761
- for (let [e, t] of Object.entries(ye)) (me[e] === void 0 || me[e] === null || me[e] === "" || me[e] === "inherit") && t !== void 0 && (me[e] = t);
25762
- let xe = await ux(t, dS(me, le));
25763
- xe = fS(xe), xe = await pS(t, xe, n), delete xe.language;
25764
- let Se = vS(xe);
25765
- delete xe.socialImage, delete xe.fbImage, delete xe.xImage, delete xe.whatsappImage, Se && (xe.socialImages = Se), oe.slug = _.slug, oe.title = _.title, Object.assign(oe, xe), oe.layoutId = be;
25766
- let Ce = Number(_.isHidden) === 1 || pe, we = !cS(de, fe), Te = _.status === "draft" || _.status === "new", Ee = _.dataJson && _.dataJson !== "{}" && _.dataJson !== "null";
25767
- if (!c && (Ce || we || Te && !Ee)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25768
- let De = [];
25769
- if (v?.treeNodeId) {
25770
- let e = await t.prepare("\n SELECT t.contentId as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson\n FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC\n ").all(v.treeNodeId, D), n = Array.isArray(e) ? e : e?.results || [], r = oe.path === "/" ? "" : oe.path;
25771
- De = n.map((e) => {
25772
- let t = {}, n = c && e.draftDataJson || e.dataJson;
25868
+ j.disabledRegions && (oe = j.disabledRegions), le = j.hidden === !0 || j.hidden === 1 || j.hidden === "1" || j.hidden === "true", se = j.startShowingAt || null, ce = j.stopShowingAt || null;
25869
+ let de = j.layoutId, fe = de && de !== "inherit", { resolvedLayoutId: pe, inheritedFields: me } = await _S(t, ne, y, o, ae), he = fe ? de : pe || ie.defaultLayout || null;
25870
+ for (let [e, t] of Object.entries(me)) (j[e] === void 0 || j[e] === null || j[e] === "" || j[e] === "inherit") && t !== void 0 && (j[e] = t);
25871
+ let ge = await ux(t, dS(j, ae));
25872
+ ge = fS(ge), ge = await pS(t, ge, h, n), delete ge.language;
25873
+ let _e = gS(ge);
25874
+ delete ge.socialImage, delete ge.fbImage, delete ge.xImage, delete ge.whatsappImage, _e && (ge.socialImages = _e), Object.assign(k, ge), k.id = v.id, k.slug = v.slug, k.title = v.title, k.path = O, k.layoutId = he;
25875
+ let ve = Number(v.isHidden) === 1 || le, ye = !cS(se, ce), be = v.status === "draft" || v.status === "new", xe = v.dataJson && v.dataJson !== "{}" && v.dataJson !== "null";
25876
+ if (!o && (ve || ye || be && !xe)) return e.json({ error: "Node is hidden, offline, or has never been published." }, 404);
25877
+ let Se = [];
25878
+ if (x?.treeNodeId) {
25879
+ let e = await t.prepare("\n SELECT t.contentId as treeNodeId, t.contentId as id, c.title, c.slug, c.language, c.contentType as nodeType, c.isHidden, c.dataJson, c.draftDataJson\n FROM tree_nodes t INNER JOIN content_nodes c ON t.contentId = c.id WHERE t.parentId = ? AND t.treeId = ? ORDER BY t.sortOrder ASC\n ").all(x.treeNodeId, y), n = Array.isArray(e) ? e : e?.results || [], r = k.path || "", i = r === "/" ? "" : r;
25880
+ Se = n.map((e) => {
25881
+ let t = {}, n = o && e.draftDataJson || e.dataJson;
25773
25882
  if (!n) return null;
25774
25883
  try {
25775
25884
  t = (typeof n == "string" ? JSON.parse(n) : n) || {};
25776
25885
  } catch {}
25777
- let i = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = cS(t.startShowingAt, t.stopShowingAt), o = (e.slug || "").replace(/^\/+|\/+$/g, "");
25778
- return !c && (i || !a) ? null : {
25886
+ let r = Number(e.isHidden) === 1 || t.hidden === !0 || t.hidden === 1 || t.hidden === "1", a = cS(t.startShowingAt, t.stopShowingAt), s = (e.slug || "").replace(/^\/+|\/+$/g, "");
25887
+ return !o && (r || !a) ? null : {
25779
25888
  treeNodeId: e.treeNodeId,
25780
25889
  id: e.id,
25781
25890
  title: e.title,
25782
- slug: o,
25783
- language: e.language?.trim() || j || null,
25784
- path: `${r}/${o}`.replace(/\/+/g, "/"),
25891
+ slug: s,
25892
+ language: e.language?.trim() || T || null,
25893
+ path: `${i}/${s}`.replace(/\/+/g, "/"),
25785
25894
  nodeType: e.nodeType
25786
25895
  };
25787
25896
  }).filter(Boolean);
25788
25897
  }
25789
- oe.children = De;
25790
- let Oe = [];
25791
- if (E && E.blocks && Array.isArray(E.blocks)) Oe = E.blocks.map((e) => ({
25898
+ k.children = Se;
25899
+ let Ce = [];
25900
+ if (b && b.blocks && Array.isArray(b.blocks)) Ce = b.blocks.map((e) => ({
25792
25901
  ...e,
25793
25902
  isDraft: 1
25794
25903
  }));
25795
25904
  else {
25796
- let e = +!!c, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(_.id, e);
25797
- Oe = Array.isArray(n) ? n : n?.results || [];
25905
+ let e = +!!o, n = await t.prepare("SELECT * FROM content_blocks WHERE contentId = ? AND isDraft = ? ORDER BY sortOrder ASC").all(v.id, e);
25906
+ Ce = Array.isArray(n) ? n : n?.results || [];
25798
25907
  }
25799
- let ke = {}, Ae = {}, je = await Promise.all(Oe.map(async (e) => {
25908
+ let we = {}, Te = {}, Ee = await Promise.all(Ce.map(async (e) => {
25800
25909
  let r = e.region || "main", i = {};
25801
25910
  try {
25802
25911
  i = (typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson) || {};
25803
25912
  } catch {}
25804
- let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", o = cS(i.startShowingAt, i.stopShowingAt);
25805
- if (!c && (a || !o)) return null;
25806
- let s = e.elementType || e.componentId || "text-block", l = h.blocks?.[s]?.fields || h.elements?.[s]?.fields || h.components?.[s]?.fields || {}, u = String(i.blockId || i._instanceId || i.id || e.blockId || e.id), d = dS(i, l);
25807
- return d = await ux(t, d), d = fS(d), d = await pS(t, d, n), d.blockId = u, {
25913
+ let a = i.hidden === !0 || i.hidden === 1 || i.hidden === "1" || i.hidden === "true", s = cS(i.startShowingAt, i.stopShowingAt);
25914
+ if (!o && (a || !s)) return null;
25915
+ let c = e.elementType || e.componentId || "text-block", l = A.blocks?.[c]?.fields || A.elements?.[c]?.fields || A.components?.[c]?.fields || {}, u = String(i.blockId || i._instanceId || i.id || e.blockId || e.id), d = dS(i, l);
25916
+ return d = await ux(t, d), d = fS(d), d = await pS(t, d, h, n), d.blockId = u, {
25808
25917
  region: r,
25809
25918
  block: {
25810
25919
  instanceId: e.id,
25811
25920
  blockId: u,
25812
- componentId: s,
25921
+ componentId: c,
25813
25922
  data: d
25814
25923
  }
25815
25924
  };
25816
25925
  }));
25817
- for (let e of je) e && (ke[e.region] || (ke[e.region] = [], Ae[e.region] = { isInherited: !1 }), ke[e.region].push(e.block));
25818
- let Me = {
25926
+ for (let e of Ee) e && (we[e.region] || (we[e.region] = [], Te[e.region] = { isInherited: !1 }), we[e.region].push(e.block));
25927
+ let De = {
25819
25928
  header: {
25820
25929
  label: "Header",
25821
25930
  inherit: "parent"
@@ -25824,44 +25933,91 @@ aS.openapi(ES, async (e) => {
25824
25933
  label: "Footer",
25825
25934
  inherit: "parent"
25826
25935
  },
25827
- ...(be ? h.nodeLayouts?.[be] || h.layouts?.[be] : null)?.regions || { main: { label: "Content" } }
25936
+ ...(he ? A.nodeLayouts?.[he] || A.layouts?.[he] : null)?.regions || { main: { label: "Content" } }
25828
25937
  };
25829
- for (let [e, r] of Object.entries(Me)) {
25830
- let i = ke[e] && ke[e].length > 0, a = !!ue[e];
25831
- if (ke[e] || (ke[e] = [], Ae[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && ie) {
25832
- let r = await uS(t, ie, String(D), e, h, c, n);
25833
- if (r.blocks.length > 0 && (ke[e] = r.blocks, Ae[e] = {
25938
+ for (let [e, r] of Object.entries(De)) {
25939
+ let i = we[e] && we[e].length > 0, a = !!oe[e];
25940
+ if (we[e] || (we[e] = [], Te[e] = { isInherited: !1 }), (r?.inherit === "parent" || r?.inherit === !0 || r?.inherit === "true" || e === "header" || e === "footer") && !i && !a && ne) {
25941
+ let r = await uS(t, ne, String(y), e, A, o, n);
25942
+ if (r.blocks.length > 0 && (we[e] = r.blocks, Te[e] = {
25834
25943
  isInherited: !0,
25835
25944
  inheritedFromId: r.inheritedFromId,
25836
25945
  inheritedFromTitle: r.inheritedFromTitle
25837
- }, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (ke[t] = n, Ae[t] = {
25946
+ }, r.subRegions)) for (let [t, n] of Object.entries(r.subRegions)) t !== e && (we[t] = n, Te[t] = {
25838
25947
  isInherited: !0,
25839
25948
  inheritedFromId: r.inheritedFromId,
25840
25949
  inheritedFromTitle: r.inheritedFromTitle
25841
25950
  });
25842
25951
  }
25843
25952
  }
25844
- await Promise.all(Object.keys(ke).map((e) => lS(t, ke[e], f, j)));
25845
- let Ne = {
25846
- channelId: f || p,
25847
- treeId: D,
25848
- language: j,
25849
- node: oe,
25850
- content: ke,
25851
- regionMeta: Ae
25953
+ await Promise.all(Object.keys(we).map((e) => lS(t, we[e], h, T)));
25954
+ let Oe = {
25955
+ channelId: h || g,
25956
+ treeId: y,
25957
+ language: T,
25958
+ node: k,
25959
+ content: we,
25960
+ regionMeta: Te
25852
25961
  };
25853
- return !c && !re && (e.header("X-Cache", "MISS"), await SS(m, ne, Ne, xS(e))), e.json(Ne, 200);
25962
+ return !o && !D && (e.header("X-Cache", "MISS"), await yS(te, E, Oe, vS(e))), e.json(Oe, 200);
25854
25963
  } catch (t) {
25855
25964
  return console.error("[CMS Public API] Error fetching node by path:", t), e.json({
25856
25965
  error: "Failed to fetch JSON payload",
25857
25966
  ...e.env?.ENVIRONMENT === "development" ? { details: t.message } : {}
25858
25967
  }, 500);
25859
25968
  }
25969
+ }
25970
+ var xS = X({
25971
+ channelId: J().optional().openapi({ description: "The ID or key of the channel" }),
25972
+ channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25973
+ lang: J().optional().openapi({ description: "Requested language code" }),
25974
+ preview: lv(["true", "false"]).optional().openapi({ description: "Request unpublished draft data" }),
25975
+ revisionId: J().optional().openapi({ description: "Historical revision version to load" }),
25976
+ treeId: J().optional().openapi({ description: "The ID of the tree to resolve paths against" })
25977
+ }), SS = X({
25978
+ error: J(),
25979
+ details: J().optional()
25980
+ }).openapi("ErrorResponse"), CS = X({
25981
+ channelId: G_([J(), c_()]),
25982
+ treeId: J().nullable(),
25983
+ language: J().nullable(),
25984
+ node: tv(k_()),
25985
+ content: tv(z_(k_())),
25986
+ regionMeta: tv(X({
25987
+ isInherited: g_(),
25988
+ inheritedFromId: J().optional(),
25989
+ inheritedFromTitle: J().optional()
25990
+ }))
25991
+ }).openapi("NodeResponse"), wS = eb({
25992
+ method: "get",
25993
+ path: "/{path}",
25994
+ summary: "Fetch CMS Node Content",
25995
+ description: "Retrieves a fully hydrated CMS node along with its content blocks and inherited regions using $O(1)$ routing table lookups.",
25996
+ tags: ["Public Node API"],
25997
+ request: {
25998
+ params: X({ path: J().optional().openapi({ description: "The full URL path or slug of the requested node" }) }),
25999
+ query: xS
26000
+ },
26001
+ responses: {
26002
+ 200: {
26003
+ description: "Fully hydrated CMS Node",
26004
+ content: { "application/json": { schema: CS } }
26005
+ },
26006
+ 404: {
26007
+ description: "Node or Channel not found",
26008
+ content: { "application/json": { schema: SS } }
26009
+ },
26010
+ 500: {
26011
+ description: "Server error during hydration",
26012
+ content: { "application/json": { schema: SS } }
26013
+ }
26014
+ }
25860
26015
  });
26016
+ oS.openapi(wS, bS), oS.get("*", bS);
25861
26017
  //#endregion
25862
26018
  //#region server/routes/public/tree.ts
25863
- var DS = new $y();
25864
- function OS(e, t) {
26019
+ var TS = new $y();
26020
+ function ES(e, t) {
25865
26021
  let n = /* @__PURE__ */ new Date();
25866
26022
  if (e && String(e).trim() !== "") {
25867
26023
  let t = new Date(e);
@@ -25873,22 +26029,22 @@ function OS(e, t) {
25873
26029
  }
25874
26030
  return !0;
25875
26031
  }
25876
- async function kS(e, t, n, r) {
26032
+ async function DS(e, t, n, r) {
25877
26033
  try {
25878
26034
  await e.set(t, n, r);
25879
26035
  } catch (e) {
25880
26036
  console.warn("[CMS Cache] Failed to write tree response to cache:", e);
25881
26037
  }
25882
26038
  }
25883
- var AS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), jS = X({
26039
+ var OS = X({ treeParam: J().openapi({ description: "The ID or key of the requested tree (e.g., \"main-nav\")" }) }), kS = X({
25884
26040
  channelId: J().optional().openapi({ description: "Channel ID to resolve context-aware routing" }),
25885
26041
  channel: J().optional().openapi({ description: "Legacy alias for channelId" }),
25886
26042
  lang: J().optional().openapi({ description: "Requested language code for tree nodes" }),
25887
26043
  preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" })
25888
- }), MS = X({
26044
+ }), AS = X({
25889
26045
  error: J(),
25890
26046
  details: J().optional()
25891
- }).openapi("ErrorResponse"), NS = qv(() => X({
26047
+ }).openapi("ErrorResponse"), jS = qv(() => X({
25892
26048
  id: G_([J(), c_()]),
25893
26049
  treeNodeId: G_([J(), c_()]),
25894
26050
  parentId: G_([J(), c_()]).nullable(),
@@ -25901,129 +26057,129 @@ var AS = X({ treeParam: J().openapi({ description: "The ID or key of the request
25901
26057
  summary: J(),
25902
26058
  url: J().optional(),
25903
26059
  target: J().optional(),
25904
- children: z_(NS).optional()
25905
- })).openapi("TreeItem"), PS = X({
26060
+ children: z_(jS).optional()
26061
+ })).openapi("TreeItem"), MS = X({
25906
26062
  treeId: G_([c_(), J()]),
25907
26063
  key: J(),
25908
26064
  channelId: J(),
25909
26065
  language: J().nullable(),
25910
26066
  label: J(),
25911
- items: z_(NS)
25912
- }).catchall(k_()).openapi("TreeResponse"), FS = eb({
26067
+ items: z_(jS)
26068
+ }).catchall(k_()).openapi("TreeResponse"), NS = eb({
25913
26069
  method: "get",
25914
26070
  path: "/{treeParam}",
25915
26071
  summary: "Fetch CMS Navigation Tree",
25916
- description: "Retrieves a fully hydrated, recursive navigation tree structure. Resolves paths, external links, and respects publishing date windows.",
26072
+ description: "Retrieves a fully hydrated, recursive navigation tree structure. Uses $O(1)$ pre-computed routing table paths.",
25917
26073
  tags: ["Public Tree API"],
25918
26074
  request: {
25919
- params: AS,
25920
- query: jS
26075
+ params: OS,
26076
+ query: kS
25921
26077
  },
25922
26078
  responses: {
25923
26079
  200: {
25924
26080
  description: "Fully hydrated CMS Tree payload",
25925
- content: { "application/json": { schema: PS } }
26081
+ content: { "application/json": { schema: MS } }
25926
26082
  },
25927
26083
  404: {
25928
26084
  description: "Tree or Channel not found / inactive",
25929
- content: { "application/json": { schema: MS } }
26085
+ content: { "application/json": { schema: AS } }
25930
26086
  },
25931
26087
  500: {
25932
26088
  description: "Server error during hydration",
25933
- content: { "application/json": { schema: MS } }
26089
+ content: { "application/json": { schema: AS } }
25934
26090
  }
25935
26091
  }
25936
26092
  });
25937
- DS.openapi(FS, async (e) => {
26093
+ TS.openapi(NS, async (e) => {
25938
26094
  try {
25939
- let t = e.get("db"), { treeParam: n } = e.req.valid("param"), r = e.req.valid("query"), i = r.channelId || r.channel || "default", a = r.lang, o = r.preview === "true", s = null;
26095
+ let t = e.get("db"), { treeParam: n } = e.req.valid("param"), r = e.req.valid("query"), i = r.channelId || r.channel || "default", a = r.lang, o = r.preview === "true", s = null, c = -1;
25940
26096
  if (i && i !== "default" && i !== "all") {
25941
26097
  let n = isNaN(Number(i)) ? await t.prepare("SELECT * FROM channels WHERE key = ?").get(i) : await t.prepare("SELECT * FROM channels WHERE id = ?").get(Number(i));
25942
26098
  if (n) {
25943
- n.defaultLanguage && (s = n.defaultLanguage.trim());
26099
+ c = Number(n.id), n.defaultLanguage && (s = n.defaultLanguage.trim());
25944
26100
  let t = n.status === "disabled" || n.status === "inactive" || n.isEnabled === 0 || n.isEnabled === !1;
25945
26101
  if (!o && t) return e.json({ error: `Channel '${n.key || i}' is currently inactive` }, 404);
25946
26102
  }
25947
26103
  }
25948
- let c = !isNaN(Number(n)), l = c ? await t.prepare("SELECT * FROM trees WHERE id = ?").get(Number(n)) : await t.prepare("SELECT * FROM trees WHERE key = ?").get(n);
25949
- if (l && Number(l.isHidden) === 1 && !o) return e.json({ error: `Tree '${n}' is hidden` }, 404);
25950
- let u = null;
25951
- if (l) {
25952
- if (l.defaultLanguage) u = String(l.defaultLanguage).trim();
25953
- else if (l.dataJson) try {
25954
- let e = typeof l.dataJson == "string" ? JSON.parse(l.dataJson) : l.dataJson;
25955
- e.defaultLanguage && (u = String(e.defaultLanguage).trim());
26104
+ let l = !isNaN(Number(n)), u = l ? await t.prepare("SELECT * FROM trees WHERE id = ?").get(Number(n)) : await t.prepare("SELECT * FROM trees WHERE key = ?").get(n);
26105
+ if (u && Number(u.isHidden) === 1 && !o) return e.json({ error: `Tree '${n}' is hidden` }, 404);
26106
+ let d = null;
26107
+ if (u) {
26108
+ if (u.defaultLanguage) d = String(u.defaultLanguage).trim();
26109
+ else if (u.dataJson) try {
26110
+ let e = typeof u.dataJson == "string" ? JSON.parse(u.dataJson) : u.dataJson;
26111
+ e.defaultLanguage && (d = String(e.defaultLanguage).trim());
25956
26112
  } catch {}
25957
26113
  }
25958
- let d = u || s || a?.trim() || null, f = $b(e), p = `tree:${i}:${n}:${d || "default"}`, m = e.req.header("x-bypass-cache") === "true";
25959
- if (!o && !m) {
25960
- let t = await f.get(p);
26114
+ let f = d || s || a?.trim() || null, p = $b(e), m = `tree:${i}:${n}:${f || "default"}`, h = e.req.header("x-bypass-cache") === "true";
26115
+ if (!o && !h) {
26116
+ let t = await p.get(m);
25961
26117
  if (t) return e.header("X-Cache", "HIT"), e.json(t, 200);
25962
26118
  }
25963
- let h = l?.id || (c ? Number(n) : null), g = {};
25964
- if (l && l.dataJson) try {
25965
- let t = typeof l.dataJson == "string" ? JSON.parse(l.dataJson) : l.dataJson, r = e.env?.BUNDLED_DEFINITIONS, i = dx(r), a = (i.trees?.[l.treeType || n] || i.trees?.site || {}).fields || {};
25966
- for (let [e, n] of Object.entries(t)) a[e]?.public === !0 && (g[e] = n);
26119
+ let g = u?.id || (l ? Number(n) : null), _ = {};
26120
+ if (u && u.dataJson) try {
26121
+ let t = typeof u.dataJson == "string" ? JSON.parse(u.dataJson) : u.dataJson, r = e.env?.BUNDLED_DEFINITIONS, i = dx(r), a = (i.trees?.[u.treeType || n] || i.trees?.site || {}).fields || {};
26122
+ for (let [e, n] of Object.entries(t)) a[e]?.public === !0 && (_[e] = n);
25967
26123
  } catch (e) {
25968
26124
  console.warn("[CMS Public Tree API] Failed to parse tree dataJson", e);
25969
26125
  }
25970
- let _ = [];
25971
- if (h !== null) {
25972
- let e = await t.prepare("\n SELECT \n t.contentId as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.dataJson,\n c.draftDataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(h);
25973
- _ = Array.isArray(e) ? e : e?.results || [];
25974
- }
25975
- if ((!_ || _.length === 0) && !l) return e.json({ error: `Tree '${n}' not found` }, 404);
25976
- let v = /* @__PURE__ */ new Map();
25977
- for (let e of _) {
25978
- let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = v.get(n);
25979
- r ? r.push(e) : v.set(n, [e]);
26126
+ let v = [];
26127
+ if (g !== null) {
26128
+ let e = await t.prepare("\n SELECT \n t.contentId as treeNodeId,\n t.treeId,\n t.contentId as id,\n t.parentId,\n t.sortOrder,\n c.title,\n c.slug,\n c.language,\n c.contentType as nodeType,\n c.isHidden,\n c.status,\n c.dataJson,\n c.draftDataJson,\n (\n SELECT path \n FROM node_routes \n WHERE nodeId = c.id AND channelId = ? \n ORDER BY CASE WHEN treeId = t.treeId THEN 0 ELSE 1 END ASC \n LIMIT 1\n ) as materializedPath\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE t.treeId = ? AND (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(c, g);
26129
+ v = Array.isArray(e) ? e : e?.results || [];
25980
26130
  }
26131
+ if ((!v || v.length === 0) && !u) return e.json({ error: `Tree '${n}' not found` }, 404);
25981
26132
  let y = /* @__PURE__ */ new Map();
25982
- for (let e of _) {
26133
+ for (let e of v) {
26134
+ let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = y.get(n);
26135
+ r ? r.push(e) : y.set(n, [e]);
26136
+ }
26137
+ let b = /* @__PURE__ */ new Map();
26138
+ for (let e of v) {
25983
26139
  let t = String(e.id), n = o && e.draftDataJson ? e.draftDataJson : e.dataJson;
25984
26140
  if (!n) {
25985
- y.set(t, {});
26141
+ b.set(t, {});
25986
26142
  continue;
25987
26143
  }
25988
26144
  try {
25989
26145
  let e = typeof n == "string" ? JSON.parse(n) : n;
25990
- y.set(t, e && typeof e == "object" ? e : {});
26146
+ b.set(t, e && typeof e == "object" ? e : {});
25991
26147
  } catch {
25992
- y.set(t, {});
26148
+ b.set(t, {});
25993
26149
  }
25994
26150
  }
25995
- function b(e = null, t = "") {
26151
+ function x(e = null, t = "") {
25996
26152
  let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e);
25997
- return (v.get(n) || []).map((e) => {
25998
- let n = y.get(String(e.id)) || {}, r = {};
26153
+ return (y.get(n) || []).map((e) => {
26154
+ let n = b.get(String(e.id)) || {}, r = {};
25999
26155
  for (let [e, t] of Object.entries(n)) e !== "_isTreeDraft" && e !== "_draftParentId" && e !== "isNew" && e !== "hidden" && e !== "is_hidden" && e !== "isHidden" && e !== "status" && (r[e] = t);
26000
- let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = OS(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = (!e.parentId || e.parentId === "null" || e.parentId === "") && (c === "home" || c === "homee") ? "/" : `${t}/${c}`.replace(/\/+/g, "/"), u = e.language && String(e.language).trim() !== "" ? e.language.trim() : d, f = {
26156
+ let i = !o && (e.status === "draft" || e.status === "new"), a = Number(e.isHidden) === 1 || i || n.hidden === !0 || n.hidden === 1 || n.hidden === "1" || n.hidden === "true", s = ES(n.startShowingAt, n.stopShowingAt), c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = !e.parentId || e.parentId === "null" || e.parentId === "", u = e.materializedPath || (l ? `/${c}` : `${t}/${c}`.replace(/\/+/g, "/")), d = e.language && String(e.language).trim() !== "" ? e.language.trim() : f, p = {
26001
26157
  id: e.id,
26002
26158
  treeNodeId: e.id,
26003
26159
  parentId: e.parentId || null,
26004
26160
  title: e.title,
26005
26161
  slug: c,
26006
- language: u,
26007
- path: l,
26162
+ language: d,
26163
+ path: u,
26008
26164
  nodeType: e.nodeType,
26009
26165
  hidden: a || !s ? 1 : 0,
26010
26166
  summary: r.summary || ""
26011
26167
  };
26012
- e.nodeType === "external-link" && (r.url && (f.url = r.url), r.target && (f.target = r.target));
26013
- let p = l === "/" ? "" : l;
26014
- return f.children = b(e.id, p), f;
26168
+ e.nodeType === "external-link" && (r.url && (p.url = r.url), r.target && (p.target = r.target));
26169
+ let m = u === "/" ? "" : u;
26170
+ return p.children = x(e.id, m), p;
26015
26171
  }).filter((e) => o || !e.hidden);
26016
26172
  }
26017
- let x = {
26018
- treeId: l?.id || h,
26019
- key: l?.key || n,
26173
+ let S = {
26174
+ treeId: u?.id || g,
26175
+ key: u?.key || n,
26020
26176
  channelId: String(i),
26021
- language: d,
26022
- label: l?.label || n,
26023
- ...g,
26024
- items: b(null)
26177
+ language: f,
26178
+ label: u?.label || n,
26179
+ ..._,
26180
+ items: x(null)
26025
26181
  };
26026
- return !o && !m && (e.header("X-Cache", "MISS"), await kS(f, p, x, 300)), e.json(x, 200);
26182
+ return !o && !h && (e.header("X-Cache", "MISS"), await DS(p, m, S, 300)), e.json(S, 200);
26027
26183
  } catch (t) {
26028
26184
  return console.error("[CMS Public Tree API] Error:", t), e.json({
26029
26185
  error: "Failed to fetch public tree",
@@ -26033,19 +26189,19 @@ DS.openapi(FS, async (e) => {
26033
26189
  });
26034
26190
  //#endregion
26035
26191
  //#region server/routes/public/channel.ts
26036
- var IS = new $y();
26037
- function LS(e) {
26192
+ var PS = new $y();
26193
+ function FS(e) {
26038
26194
  let t = Number(e?.env?.CMS_CHANNEL_CACHE_TTL);
26039
26195
  return Number.isFinite(t) && t >= 60 ? Math.floor(t) : 300;
26040
26196
  }
26041
- async function RS(e, t, n, r) {
26197
+ async function IS(e, t, n, r) {
26042
26198
  try {
26043
26199
  await e.set(t, n, r);
26044
26200
  } catch (e) {
26045
26201
  console.warn("[CMS Cache] Failed to write channel response to cache:", e);
26046
26202
  }
26047
26203
  }
26048
- function zS(e, t) {
26204
+ function LS(e, t) {
26049
26205
  let n = {}, r = (e) => {
26050
26206
  if (!e || typeof e != "string") return;
26051
26207
  let n = t?.fieldSets?.[e] || t?.fieldsets?.[e] || t?.definitions?.[e] || t?.channels?.[e] || t?.[e];
@@ -26056,7 +26212,7 @@ function zS(e, t) {
26056
26212
  if (e?.fieldSets && Array.isArray(e.fieldSets) && e.fieldSets.forEach((e) => r(e)), e?.fields && i(e.fields), e?.tabs && typeof e.tabs == "object") for (let t of Object.values(e.tabs)) t?.fields && i(t.fields);
26057
26213
  return n;
26058
26214
  }
26059
- function BS(e, t = {}) {
26215
+ function RS(e, t = {}) {
26060
26216
  let n = {}, r = Object.keys(t).length > 0;
26061
26217
  for (let [i, a] of Object.entries(e)) {
26062
26218
  if (i.endsWith("_meta") || [
@@ -26075,14 +26231,14 @@ function BS(e, t = {}) {
26075
26231
  }
26076
26232
  return n;
26077
26233
  }
26078
- function VS(e) {
26079
- if (Array.isArray(e)) return e.map(VS);
26234
+ function zS(e) {
26235
+ if (Array.isArray(e)) return e.map(zS);
26080
26236
  if (!e || typeof e != "object") return e;
26081
26237
  if (typeof e.id == "string" && e.id.startsWith("ast_") && typeof e.url == "string") {
26082
26238
  let t = e.metadataOverrides || {}, n = e.variants && typeof e.variants == "object" ? e.variants : {}, r = Object.entries(n).find(([, t]) => t?.id === e.id)?.[0], i = r ? {
26083
26239
  ...t,
26084
26240
  ...t.crops?.[r] || {}
26085
- } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, VS({
26241
+ } : t, a = Object.fromEntries(Object.entries(n).filter(([, t]) => t?.id !== e.id).map(([t, n]) => [t, zS({
26086
26242
  ...n,
26087
26243
  title: n?.title ?? e.title ?? "",
26088
26244
  alt: n?.alt ?? e.alt ?? "",
@@ -26096,77 +26252,80 @@ function VS(e) {
26096
26252
  ...Object.keys(a).length > 0 ? { variants: a } : {}
26097
26253
  };
26098
26254
  }
26099
- return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, VS(t)]));
26255
+ return Object.fromEntries(Object.entries(e).map(([e, t]) => [e, zS(t)]));
26100
26256
  }
26101
- async function HS(e, t) {
26257
+ async function BS(e, t, n) {
26102
26258
  if (typeof t == "string") {
26103
26259
  if (!t.includes("#node:") && !t.includes("data-node-id") && !t.includes("#asset:") && !t.includes("data-asset-id")) return t;
26104
- let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
26105
- for (let e of t.matchAll(/(?:#node:|data-node-id\s*=\s*["'])([^"'\s>]+)/gi)) n.add(e[1]);
26106
- for (let e of t.matchAll(/(?:#asset:|data-asset-id\s*=\s*["'])([^"'\s>]+)/gi)) r.add(e[1]);
26107
- if (n.size === 0 && r.size === 0) return t;
26108
- let i = Array.from(n).map(() => "?").join(","), a = n.size > 0 ? await e.prepare(`SELECT id, slug FROM content_nodes WHERE id IN (${i})`).all(...n) : [], o = /* @__PURE__ */ new Map();
26109
- (Array.isArray(a) ? a : a?.results || []).forEach((e) => o.set(String(e.id), String(e.slug || "").replace(/^\/+|\/+$/g, "")));
26110
- let s = Array.from(r).map(() => "?").join(","), c = r.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${s})`).all(...r) : [], l = /* @__PURE__ */ new Map();
26111
- return (Array.isArray(c) ? c : c?.results || []).forEach((e) => l.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : ""))), t.replace(/<a\s+([^>]+)>/gi, (e, t) => {
26260
+ let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
26261
+ for (let e of t.matchAll(/(?:#node:|data-node-id\s*=\s*["'])([^"'\s>]+)/gi)) r.add(e[1]);
26262
+ for (let e of t.matchAll(/(?:#asset:|data-asset-id\s*=\s*["'])([^"'\s>]+)/gi)) i.add(e[1]);
26263
+ if (r.size === 0 && i.size === 0) return t;
26264
+ let a = /* @__PURE__ */ new Map();
26265
+ if (r.size > 0) {
26266
+ let t = Array.from(r).map(() => "?").join(","), i = await e.prepare(`SELECT nodeId, path FROM node_routes WHERE channelId = ? AND nodeId IN (${t}) AND isCanonical = 1`).all(n, ...r);
26267
+ (Array.isArray(i) ? i : i?.results || []).forEach((e) => a.set(String(e.nodeId), e.path));
26268
+ }
26269
+ let o = Array.from(i).map(() => "?").join(","), s = i.size > 0 ? await e.prepare(`SELECT id, cdnUrl, storageKeyPrivate FROM assets WHERE id IN (${o})`).all(...i) : [], c = /* @__PURE__ */ new Map();
26270
+ return (Array.isArray(s) ? s : s?.results || []).forEach((e) => c.set(String(e.id), e.cdnUrl || (e.storageKeyPrivate ? `/media/${e.storageKeyPrivate}` : ""))), t.replace(/<a\s+([^>]+)>/gi, (e, t) => {
26112
26271
  let n = (e, t) => {
26113
26272
  let n = e.match(RegExp(`\\b${t}\\s*=\\s*(["'])(.*?)\\1`, "i"));
26114
26273
  return n ? n[2] : void 0;
26115
- }, r = n(t, "data-node-id"), i = n(t, "data-asset-id"), a = n(t, "href") || "";
26116
- if (a.startsWith("mailto:")) return `<a ${t.replace(/\s+target\s*=\s*["'][^"']*["']/i, "")}>`;
26117
- let s = i || a.match(/^#asset:(.+)$/i)?.[1], c = r || a.match(/^#node:(.+)$/i)?.[1];
26118
- if (!c && !s) return e;
26119
- if (s && !c) {
26120
- let n = l.get(s);
26274
+ }, r = n(t, "data-node-id"), i = n(t, "data-asset-id"), o = n(t, "href") || "";
26275
+ if (o.startsWith("mailto:")) return `<a ${t.replace(/\s+target\s*=\s*["'][^"']*["']/i, "")}>`;
26276
+ let s = i || o.match(/^#asset:(.+)$/i)?.[1], l = r || o.match(/^#node:(.+)$/i)?.[1];
26277
+ if (!l && !s) return e;
26278
+ if (s && !l) {
26279
+ let n = c.get(s);
26121
26280
  if (n) {
26122
26281
  let e = t;
26123
26282
  return /href\s*=\s*["'][^"']*["']/i.test(e) ? e = e.replace(/href\s*=\s*["'][^"']*["']/i, `href="${n}"`) : e += ` href="${n}"`, `<a ${e}>`;
26124
26283
  }
26125
26284
  return e;
26126
26285
  }
26127
- let u = o.get(c), d = u === void 0 ? "#" : `/${u}`, f = t;
26128
- return /href\s*=\s*["'][^"']*["']/i.test(f) ? f = f.replace(/href\s*=\s*["'][^"']*["']/i, `href="${d || "/"}"`) : f += ` href="${d || "/"}"`, `<a ${f}>`;
26286
+ let u = a.get(l) || "#", d = t;
26287
+ return /href\s*=\s*["'][^"']*["']/i.test(d) ? d = d.replace(/href\s*=\s*["'][^"']*["']/i, `href="${u}"`) : d += ` href="${u}"`, `<a ${d}>`;
26129
26288
  });
26130
26289
  }
26131
- if (Array.isArray(t)) return Promise.all(t.map((t) => HS(e, t)));
26290
+ if (Array.isArray(t)) return Promise.all(t.map((t) => BS(e, t, n)));
26132
26291
  if (t && typeof t == "object") {
26133
- let n = await Promise.all(Object.entries(t).map(async ([t, n]) => [t, await HS(e, n)]));
26134
- return Object.fromEntries(n);
26292
+ let r = await Promise.all(Object.entries(t).map(async ([t, r]) => [t, await BS(e, r, n)]));
26293
+ return Object.fromEntries(r);
26135
26294
  }
26136
26295
  return t;
26137
26296
  }
26138
- var US = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), WS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), GS = X({
26297
+ var VS = X({ channelParam: J().openapi({ description: "The ID or key (slug) of the requested channel" }) }), HS = X({ preview: lv(["true", "false"]).optional().openapi({ description: "Set to true to retrieve unpublished draft data" }) }), US = X({
26139
26298
  error: J(),
26140
26299
  details: J().optional()
26141
- }).openapi("ErrorResponse"), KS = X({
26300
+ }).openapi("ErrorResponse"), WS = X({
26142
26301
  id: G_([c_(), J()]),
26143
26302
  key: J()
26144
- }).catchall(k_()).openapi("ChannelResponse"), qS = eb({
26303
+ }).catchall(k_()).openapi("ChannelResponse"), GS = eb({
26145
26304
  method: "get",
26146
26305
  path: "/{channelParam}",
26147
26306
  summary: "Fetch CMS Channel Settings",
26148
26307
  description: "Retrieves the fully hydrated, public-facing settings and payload for a specific CMS channel.",
26149
26308
  tags: ["Public Channel API"],
26150
26309
  request: {
26151
- params: US,
26152
- query: WS
26310
+ params: VS,
26311
+ query: HS
26153
26312
  },
26154
26313
  responses: {
26155
26314
  200: {
26156
26315
  description: "Fully hydrated CMS Channel payload",
26157
- content: { "application/json": { schema: KS } }
26316
+ content: { "application/json": { schema: WS } }
26158
26317
  },
26159
26318
  404: {
26160
26319
  description: "Channel not found or inactive",
26161
- content: { "application/json": { schema: GS } }
26320
+ content: { "application/json": { schema: US } }
26162
26321
  },
26163
26322
  500: {
26164
26323
  description: "Server error during hydration",
26165
- content: { "application/json": { schema: GS } }
26324
+ content: { "application/json": { schema: US } }
26166
26325
  }
26167
26326
  }
26168
26327
  });
26169
- IS.openapi(qS, async (e) => {
26328
+ PS.openapi(GS, async (e) => {
26170
26329
  try {
26171
26330
  let t = e.get("db"), { channelParam: n } = e.req.valid("param"), { preview: r } = e.req.valid("query"), i = r === "true", a = e.req.header("x-bypass-cache") === "true", o = `channel:${n}:${i ? "preview" : "live"}`, s = $b(e);
26172
26331
  if (!i && !a) {
@@ -26177,23 +26336,23 @@ IS.openapi(qS, async (e) => {
26177
26336
  if (!c) return e.json({ error: `Channel '${n}' not found` }, 404);
26178
26337
  let l = c.status === "disabled" || c.status === "inactive" || c.isEnabled === 0 || c.isEnabled === !1;
26179
26338
  if (!i && l) return e.json({ error: `Channel '${c.key || n}' is currently inactive` }, 404);
26180
- let u = e.env?.BUNDLED_DEFINITIONS, d = dx(u), f = c.channelType || c.key || "website", p = zS(d.channels?.[f] || d.channels?.[c.key] || d.channels?.website || d.definitions?.["channel-base"] || {}, d), m = {}, h = i && c.draftDataJson || c.dataJson;
26181
- if (h) try {
26182
- m = typeof h == "string" ? JSON.parse(h) : h;
26339
+ let u = Number(c.id), d = e.env?.BUNDLED_DEFINITIONS, f = dx(d), p = c.channelType || c.key || "website", m = LS(f.channels?.[p] || f.channels?.[c.key] || f.channels?.website || f.definitions?.["channel-base"] || {}, f), h = {}, g = i && c.draftDataJson || c.dataJson;
26340
+ if (g) try {
26341
+ h = typeof g == "string" ? JSON.parse(g) : g;
26183
26342
  } catch (e) {
26184
26343
  console.warn("[CMS Public Channel API] Failed to parse channel dataJson:", e);
26185
26344
  }
26186
- let g = BS({
26187
- ...m,
26345
+ let _ = RS({
26346
+ ...h,
26188
26347
  ...c
26189
- }, p);
26190
- g = await ux(t, g), g = VS(g), g = await HS(t, g);
26191
- let _ = {
26348
+ }, m);
26349
+ _ = await ux(t, _), _ = zS(_), _ = await BS(t, _, u);
26350
+ let v = {
26192
26351
  id: c.id,
26193
26352
  key: c.key,
26194
- ...g
26353
+ ..._
26195
26354
  };
26196
- return !i && !a && (e.header("X-Cache", "MISS"), await RS(s, o, _, LS(e))), e.json(_, 200);
26355
+ return !i && !a && (e.header("X-Cache", "MISS"), await IS(s, o, v, FS(e))), e.json(v, 200);
26197
26356
  } catch (t) {
26198
26357
  return console.error("[CMS Public Channel API] Error:", t), e.json({
26199
26358
  error: "Failed to fetch public channel",
@@ -26203,8 +26362,8 @@ IS.openapi(qS, async (e) => {
26203
26362
  });
26204
26363
  //#endregion
26205
26364
  //#region server/routes/public/assets.ts
26206
- var JS = new $y();
26207
- function YS(e, t) {
26365
+ var KS = new $y();
26366
+ function qS(e, t) {
26208
26367
  if (t === "webp") return "image/webp";
26209
26368
  if (t === "avif") return "image/avif";
26210
26369
  if (t === "jpeg" || t === "jpg") return "image/jpeg";
@@ -26213,7 +26372,7 @@ function YS(e, t) {
26213
26372
  let n = e.toLowerCase();
26214
26373
  return n.endsWith(".jpg") || n.endsWith(".jpeg") ? "image/jpeg" : n.endsWith(".png") ? "image/png" : n.endsWith(".webp") ? "image/webp" : n.endsWith(".gif") ? "image/gif" : n.endsWith(".svg") ? "image/svg+xml" : n.endsWith(".pdf") ? "application/pdf" : n.endsWith(".mp4") ? "video/mp4" : "application/octet-stream";
26215
26374
  }
26216
- var XS = eb({
26375
+ var JS = eb({
26217
26376
  method: "get",
26218
26377
  path: "/*",
26219
26378
  summary: "Serve & Optimize Media Assets",
@@ -26270,7 +26429,7 @@ var XS = eb({
26270
26429
  }
26271
26430
  }
26272
26431
  });
26273
- JS.openapi(XS, async (e) => {
26432
+ KS.openapi(JS, async (e) => {
26274
26433
  try {
26275
26434
  let t = e.req.path.replace(/^\/media\//, "").replace(/^\//, "");
26276
26435
  if (!t) return e.text("Asset key missing", 400);
@@ -26290,7 +26449,7 @@ JS.openapi(XS, async (e) => {
26290
26449
  if (!m) return e.text(`Asset not found: ${t}`, 404);
26291
26450
  if (!o) {
26292
26451
  let n = e.body(m, 200, {
26293
- "Content-Type": YS(t),
26452
+ "Content-Type": qS(t),
26294
26453
  "Cache-Control": "public, max-age=31536000, immutable"
26295
26454
  });
26296
26455
  return l && d && e.executionCtx?.waitUntil && e.executionCtx.waitUntil(l.put(d, n.clone())), n;
@@ -26304,7 +26463,7 @@ JS.openapi(XS, async (e) => {
26304
26463
  key: t,
26305
26464
  env: e.env,
26306
26465
  req: e.req.raw
26307
- }), _ = YS(t, c), v = e.body(g, 200, {
26466
+ }), _ = qS(t, c), v = e.body(g, 200, {
26308
26467
  "Content-Type": _,
26309
26468
  "Cache-Control": "public, max-age=31536000, immutable"
26310
26469
  });
@@ -26315,8 +26474,8 @@ JS.openapi(XS, async (e) => {
26315
26474
  });
26316
26475
  //#endregion
26317
26476
  //#region server/routes/public/paths.ts
26318
- var ZS = new $y();
26319
- function QS(e, t) {
26477
+ var YS = new $y();
26478
+ function XS(e, t) {
26320
26479
  let n = /* @__PURE__ */ new Date();
26321
26480
  if (e && String(e).trim() !== "") {
26322
26481
  let t = new Date(e);
@@ -26328,73 +26487,73 @@ function QS(e, t) {
26328
26487
  }
26329
26488
  return !0;
26330
26489
  }
26331
- var $S = z_(J()).openapi("PathsResponse"), eC = X({
26490
+ var ZS = X({
26491
+ channelId: J().optional().openapi({ description: "Optional channel ID/key to filter and resolve root paths for" }),
26492
+ channel: J().optional().openapi({ description: "Legacy alias for channelId" })
26493
+ }), QS = z_(J()).openapi("PathsResponse"), $S = X({
26332
26494
  error: J(),
26333
26495
  details: J().optional()
26334
- }).openapi("ErrorResponse"), tC = eb({
26496
+ }).openapi("ErrorResponse"), eC = eb({
26335
26497
  method: "get",
26336
26498
  path: "/",
26337
26499
  summary: "Fetch All Public Paths",
26338
- description: "Retrieves a deduplicated array of all active, published node paths across all trees. Intended primarily for Static Site Generation (SSG) crawlers and sitemaps.",
26500
+ description: "Retrieves a deduplicated array of all active, published node paths leveraging the $O(1)$ node_routes table. Includes both tree-bound and standalone pages.",
26339
26501
  tags: ["Public Paths API"],
26502
+ request: { query: ZS },
26340
26503
  responses: {
26341
26504
  200: {
26342
26505
  description: "Array of valid public URL paths",
26343
- content: { "application/json": { schema: $S } }
26506
+ content: { "application/json": { schema: QS } }
26344
26507
  },
26345
26508
  500: {
26346
26509
  description: "Server error fetching paths",
26347
- content: { "application/json": { schema: eC } }
26510
+ content: { "application/json": { schema: $S } }
26348
26511
  }
26349
26512
  }
26350
26513
  });
26351
- ZS.openapi(tC, async (e) => {
26514
+ YS.openapi(eC, async (e) => {
26352
26515
  try {
26353
- let t = await e.get("db").prepare("\n SELECT\n t.id as treeNodeId,\n t.parentId,\n c.slug,\n c.contentType as nodeType,\n c.status,\n c.dataJson\n FROM tree_nodes t\n INNER JOIN content_nodes c ON t.contentId = c.id\n WHERE (c.deletedAt IS NULL OR c.deletedAt = '')\n ORDER BY t.sortOrder ASC\n ").all(), n = Array.isArray(t) ? t : t?.results || [], r = [], i = /* @__PURE__ */ new Map();
26354
- for (let e of n) {
26355
- let t = !e.parentId || e.parentId === "null" || e.parentId === "" ? null : e.parentId, n = t === null ? "__ROOT__" : String(t), r = i.get(n);
26356
- r ? r.push(e) : i.set(n, [e]);
26357
- }
26358
- let a = /* @__PURE__ */ new Map();
26359
- for (let e of n) {
26360
- let t = String(e.treeNodeId);
26361
- if (!e.dataJson) {
26362
- a.set(t, {});
26363
- continue;
26364
- }
26365
- try {
26516
+ let t = e.get("db"), n = e.req.valid("query"), r = n.channelId || n.channel, i = "", a = [];
26517
+ if (r && r !== "all") {
26518
+ let e = isNaN(Number(r)) ? await t.prepare("SELECT id FROM channels WHERE key = ?").get(r) : await t.prepare("SELECT id FROM channels WHERE id = ?").get(Number(r));
26519
+ e && (i = "AND nr.channelId = ?", a.push(Number(e.id)));
26520
+ }
26521
+ let o = await t.prepare(`
26522
+ SELECT
26523
+ nr.path,
26524
+ cn.contentType as nodeType,
26525
+ cn.dataJson
26526
+ FROM node_routes nr
26527
+ INNER JOIN content_nodes cn ON nr.nodeId = cn.id
26528
+ WHERE nr.isCanonical = 1
26529
+ AND (cn.status = 'published' OR cn.status = 'active')
26530
+ AND (cn.deletedAt IS NULL OR cn.deletedAt = '')
26531
+ ${i}
26532
+ ORDER BY nr.path ASC
26533
+ `).all(...a), s = Array.isArray(o) ? o : o?.results || [], c = [];
26534
+ for (let e of s) {
26535
+ if (e.nodeType === "external-link" || !e.path) continue;
26536
+ let t = !0;
26537
+ if (e.dataJson) try {
26366
26538
  let n = typeof e.dataJson == "string" ? JSON.parse(e.dataJson) : e.dataJson;
26367
- a.set(t, n && typeof n == "object" ? n : {});
26368
- } catch {
26369
- a.set(t, {});
26370
- }
26371
- }
26372
- function o(e = null, t = "") {
26373
- let n = e == null || e === "" || e === "null" ? "__ROOT__" : String(e), s = i.get(n) || [];
26374
- for (let e of s) {
26375
- let n = a.get(String(e.treeNodeId)) || {}, i = e.status === "published" || e.status === "active", s = QS(n.startShowingAt, n.stopShowingAt);
26376
- if (!i || !s) continue;
26377
- let c = (e.slug || "").replace(/^\/+|\/+$/g, ""), l = c === "home" || c === "homee" ? "/" : `${t}/${c}`.replace(/\/+/g, "/");
26378
- e.nodeType !== "external-link" && r.push(l);
26379
- let u = l === "/" ? "" : l;
26380
- o(e.treeNodeId, u);
26381
- }
26539
+ t = XS(n?.startShowingAt, n?.stopShowingAt);
26540
+ } catch {}
26541
+ t && c.push(e.path);
26382
26542
  }
26383
- o(null);
26384
- let s = [...new Set(r)];
26385
- return e.json(s, 200);
26543
+ let l = [...new Set(c)];
26544
+ return e.json(l, 200);
26386
26545
  } catch (t) {
26387
26546
  return console.error("[CMS Paths API] Error:", t), e.json({ error: "Failed to fetch paths" }, 500);
26388
26547
  }
26389
26548
  });
26390
26549
  //#endregion
26391
26550
  //#region server/routes/public/taxonomies.ts
26392
- var nC = new $y();
26393
- function rC(e) {
26551
+ var tC = new $y();
26552
+ function nC(e) {
26394
26553
  let t = (e || "").trim().toLowerCase(), n = dx()?.taxonomies || {};
26395
26554
  return n[t] ? t : n[`${t}s`] ? `${t}s` : t.endsWith("s") && n[t.slice(0, -1)] ? t.slice(0, -1) : t;
26396
26555
  }
26397
- var iC = X({
26556
+ var rC = X({
26398
26557
  id: c_(),
26399
26558
  taxonomy: J(),
26400
26559
  key: J(),
@@ -26404,14 +26563,14 @@ var iC = X({
26404
26563
  data: tv(k_()),
26405
26564
  createdAt: J(),
26406
26565
  updatedAt: J()
26407
- }), aC = X({
26566
+ }), iC = X({
26408
26567
  taxonomy: J(),
26409
- items: z_(iC),
26568
+ items: z_(rC),
26410
26569
  total: c_()
26411
- }).openapi("TaxonomyResponse"), oC = X({
26570
+ }).openapi("TaxonomyResponse"), aC = X({
26412
26571
  error: J(),
26413
26572
  details: J().optional()
26414
- }).openapi("ErrorResponse"), sC = eb({
26573
+ }).openapi("ErrorResponse"), oC = eb({
26415
26574
  method: "get",
26416
26575
  path: "/{taxonomy}",
26417
26576
  summary: "Fetch Public Taxonomy Terms",
@@ -26421,17 +26580,17 @@ var iC = X({
26421
26580
  responses: {
26422
26581
  200: {
26423
26582
  description: "List of taxonomy terms",
26424
- content: { "application/json": { schema: aC } }
26583
+ content: { "application/json": { schema: iC } }
26425
26584
  },
26426
26585
  500: {
26427
26586
  description: "Server error",
26428
- content: { "application/json": { schema: oC } }
26587
+ content: { "application/json": { schema: aC } }
26429
26588
  }
26430
26589
  }
26431
26590
  });
26432
- nC.openapi(sC, async (e) => {
26591
+ tC.openapi(oC, async (e) => {
26433
26592
  try {
26434
- let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = rC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
26593
+ let t = e.get("db"), n = $b(e), r = e.req.valid("param").taxonomy, i = nC(r), a = `taxonomy:public:${i}`, o = e.req.header("x-bypass-cache") === "true";
26435
26594
  if (!o) {
26436
26595
  let t = await n.get(a);
26437
26596
  if (t) return e.header("X-Cache", "HIT"), e.json(t);
@@ -26467,7 +26626,7 @@ nC.openapi(sC, async (e) => {
26467
26626
  });
26468
26627
  //#endregion
26469
26628
  //#region server/index.ts
26470
- var $ = new $y(), cC = !1;
26629
+ var $ = new $y(), sC = !1;
26471
26630
  $.use("*", t()), $.use("/media/*", t({
26472
26631
  origin: "*",
26473
26632
  allowMethods: [
@@ -26488,13 +26647,13 @@ $.use("*", t()), $.use("/media/*", t({
26488
26647
  let n = new URL(e.req.url), r = (e.req.header("host") || n.hostname).split(":")[0];
26489
26648
  e.set("currentDomain", r);
26490
26649
  let i = wb(e);
26491
- if (e.set("db", i), !cC) try {
26492
- await Mb(i), cC = !0;
26650
+ if (e.set("db", i), !sC) try {
26651
+ await Mb(i), sC = !0;
26493
26652
  } catch (e) {
26494
26653
  console.error("❌ [CMS Server] Failed to initialize system tables on cold start:", e);
26495
26654
  }
26496
26655
  await t();
26497
- }), $.route("/media", JS), $.use("/media/*", Pb()), $.route("/api/cms/nodes", px), $.route("/api/cms/nodes.json", px), $.route("/api/cms/formcsv", px), $.route("/api/cms/formcsv.json", px), $.route("/api/cms/stats", eS), $.route("/api/cms/stats.json", eS), $.route("/api/cms", wx), $.route("/api/cms/trees.json", wx), $.route("/api/cms/channels", Ox), $.route("/api/cms/channels.json", Ox), $.route("/api/cms/taxonomies", kx), $.route("/api/cms/taxonomies.json", kx), $.route("/api/cms/schemas", Yx), $.route("/api/cms/schemas.json", Yx), $.route("/api/cms", Zx), $.route("/api/admin/assets", tS), $.route("/api/v1/node", aS), $.route("/api/v1/tree", DS), $.route("/api/v1/channel", IS), $.route("/api/v1/all-paths", ZS), $.route("/api/v1/taxonomies", nC), $.doc("/api/openapi.json", {
26656
+ }), $.route("/media", KS), $.use("/media/*", Pb()), $.route("/api/cms/nodes", mx), $.route("/api/cms/nodes.json", mx), $.route("/api/cms/formcsv", mx), $.route("/api/cms/formcsv.json", mx), $.route("/api/cms/stats", tS), $.route("/api/cms/stats.json", tS), $.route("/api/cms", Tx), $.route("/api/cms/trees.json", Tx), $.route("/api/cms/channels", kx), $.route("/api/cms/channels.json", kx), $.route("/api/cms/taxonomies", Ax), $.route("/api/cms/taxonomies.json", Ax), $.route("/api/cms/schemas", Xx), $.route("/api/cms/schemas.json", Xx), $.route("/api/cms", Qx), $.route("/api/admin/assets", nS), $.route("/api/v1/node", oS), $.route("/api/v1/tree", TS), $.route("/api/v1/channel", PS), $.route("/api/v1/all-paths", YS), $.route("/api/v1/taxonomies", tC), $.doc("/api/openapi.json", {
26498
26657
  openapi: "3.0.0",
26499
26658
  info: {
26500
26659
  title: "KAMA Engine Public API",
@@ -26513,4 +26672,4 @@ $.use("*", t()), $.use("/media/*", t({
26513
26672
  return t();
26514
26673
  });
26515
26674
  //#endregion
26516
- export { $ as app, $ as default, Kx as compileDefinitions, qx as getCmsDefinitions };
26675
+ export { $ as app, $ as default, qx as compileDefinitions, Jx as getCmsDefinitions };