@voltro/cms 0.81.0 → 0.82.0

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
@@ -1,37 +1,206 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as ee, u as te } from "./ContentForm-DUW_rb_m.js";
2
- import { and as f, boolean as p, date as m, eq as h, gt as ne, gte as re, id as g, integer as _, json as ie, lt as ae, lte as v, neq as y, table as oe, text as b, timestamp as x } from "@voltro/database";
3
- import { tenant as se } from "@voltro/plugin-multitenancy/mixin";
4
- import { createHmac as S, timingSafeEqual as ce } from "node:crypto";
5
- import { Effect as C } from "effect";
6
- import { revalidatePath as le, revalidateTag as ue } from "@voltro/runtime";
7
- //#region src/contentType.ts
8
- var w = [
1
+ import { $ as e, $t as t, A as n, At as r, B as i, Bt as a, C as o, Ct as s, D as c, Dt as l, E as u, Et as d, F as f, Ft as p, G as m, Gt as h, H as g, Ht as _, I as ee, It as te, J as ne, Jt as re, K as ie, Kt as ae, L as oe, Lt as se, M as ce, Mt as le, N as ue, Nt as de, O as fe, Ot as v, P as pe, Pt as me, Q as he, Qt as ge, R as _e, Rt as ve, S as ye, St as y, T as be, Tt as xe, U as Se, Ut as Ce, V as we, Vt as Te, W as Ee, Wt as De, X as Oe, Xt as ke, Y as Ae, Yt as je, Z as Me, Zt as Ne, _ as Pe, _t as Fe, a as Ie, at as Le, b as Re, bt as ze, c as Be, ct as Ve, d as He, dt as Ue, en as We, et as Ge, f as Ke, ft as qe, g as Je, gt as Ye, h as Xe, ht as Ze, i as Qe, it as $e, j as et, jt as tt, k as nt, kt as rt, l as it, lt as at, m as ot, mt as st, n as ct, nn as lt, nt as ut, o as dt, ot as ft, p as pt, pt as mt, q as ht, qt as gt, r as _t, rt as vt, s as yt, st as bt, t as xt, tn as St, tt as Ct, u as wt, ut as Tt, v as Et, vt as Dt, w as Ot, wt as kt, x as At, xt as b, y as jt, yt as Mt, z as Nt, zt as Pt } from "./extensionManifest-ghuSj4ND.js";
2
+ import { and as x, boolean as Ft, crdtText as It, date as Lt, eq as S, generateId as Rt, gt as zt, gte as Bt, id as C, inSet as Vt, integer as w, json as T, lt as Ht, lte as Ut, neq as E, real as Wt, table as D, text as O, timestamp as k } from "@voltro/database";
3
+ import { tenant as A } from "@voltro/plugin-multitenancy/mixin";
4
+ import { Effect as Gt } from "effect";
5
+ import { createHash as Kt, createHmac as qt, randomBytes as Jt, timingSafeEqual as Yt } from "node:crypto";
6
+ import { revalidatePath as Xt, revalidateTag as Zt } from "@voltro/runtime";
7
+ import { crdtText as Qt, decodeCrdtText as $t, mergeCrdtStates as en } from "@voltro/local-first";
8
+ //#region src/effectForm.ts
9
+ var j = (e, ...t) => {
10
+ let n = (e) => t.some((t) => e instanceof t);
11
+ return Gt.tryPromise({
12
+ try: e,
13
+ catch: (e) => e
14
+ }).pipe(Gt.catchAll((e) => n(e) ? Gt.fail(e) : Gt.die(e)));
15
+ }, tn = "cms_search", nn = "cms_search_text", rn = D(tn, {
16
+ id: C({ prefix: "csrch" }),
17
+ site: O().maxLength(64),
18
+ environment: O().maxLength(64),
19
+ locale: O().maxLength(64),
20
+ contentType: O().maxLength(64),
21
+ documentId: O().maxLength(64),
22
+ variantId: O().maxLength(64),
23
+ stage: O().oneOf(["draft", "published"]),
24
+ title: O(),
25
+ body: O()
26
+ }).with(A()).index("cms_search_by_variant", ["variantId", "stage"]).fullTextIndex(nn, ["title", "body"], {
27
+ config: "simple",
28
+ weights: {
29
+ title: "A",
30
+ body: "B"
31
+ }
32
+ }), an = (e, t, n) => {
33
+ if (t[n.title]?.kind !== "string") throw Error(`defineContentType('${e}'): search.title '${n.title}' is not a string field of this content type.`);
34
+ }, on = (e) => typeof e == "object" && !!e && e.type === "doc" && Array.isArray(e.blocks), sn = (e, t) => {
35
+ if (t == null) return [];
36
+ switch (e.kind) {
37
+ case "string": return typeof t == "string" && t !== "" ? [t] : [];
38
+ case "richText": {
39
+ let e = Te(t);
40
+ return on(e) ? [Ce(e)] : [];
41
+ }
42
+ case "array": return Array.isArray(t) && e.element !== void 0 ? t.flatMap((t) => sn(e.element, t)) : [];
43
+ case "struct": return typeof t == "object" && e.struct !== void 0 ? Object.entries(e.struct).flatMap(([e, n]) => sn(n, t[e])) : [];
44
+ case "components": return Array.isArray(t) ? t.flatMap((t) => {
45
+ let n = t, r = e.components?.find((e) => e.id === n.componentId);
46
+ if (r === void 0 || typeof n.props != "object" || n.props === null) return [];
47
+ let i = n.props;
48
+ return Object.entries(r.props).flatMap(([e, t]) => sn(t, i[e]));
49
+ }) : [];
50
+ default: return [];
51
+ }
52
+ }, cn = (e, t) => {
53
+ let n = e.search?.title ?? "";
54
+ return {
55
+ title: typeof t[n] == "string" ? t[n] : "",
56
+ body: Object.entries(e.fields).filter(([t]) => t !== n && !e.derivedFields.includes(t)).flatMap(([e, n]) => sn(n, t[e])).join("\n")
57
+ };
58
+ }, ln = async (e, t, n) => (await e.query({
59
+ table: tn,
60
+ predicate: x(S("variantId", t), S("stage", n)),
61
+ order: [],
62
+ take: 1,
63
+ skip: void 0,
64
+ projection: void 0
65
+ }))[0], un = async (e, t, n, r, i) => {
66
+ if (t.search === void 0) return;
67
+ let a = cn(t, n), o = String(n.id), s = await ln(e, o, i);
68
+ if (s !== void 0) {
69
+ await e.update(tn, String(s.id), a);
70
+ return;
71
+ }
72
+ let c = n.tenantId;
73
+ await e.insert(tn, {
74
+ site: r.site,
75
+ environment: r.environment,
76
+ locale: r.locale,
77
+ contentType: t.name,
78
+ documentId: String(n.documentId),
79
+ variantId: o,
80
+ stage: i,
81
+ ...a,
82
+ ...c == null ? {} : { tenantId: c }
83
+ });
84
+ }, dn = async (e, t, n, r) => {
85
+ if (t.search !== void 0) for (let t of r) {
86
+ let r = await ln(e, n, t);
87
+ r !== void 0 && await e.delete(tn, String(r.id));
88
+ }
89
+ }, fn = async (e, t) => {
90
+ if (t.search === void 0) return 0;
91
+ let n = 0;
92
+ for (let r of ["draft", "published"]) {
93
+ let i = await e.query({
94
+ table: `${t.name}_${r === "draft" ? "drafts" : "published"}`,
95
+ predicate: void 0,
96
+ order: [],
97
+ take: void 0,
98
+ skip: void 0,
99
+ projection: void 0
100
+ });
101
+ for (let a of i) {
102
+ let i = {
103
+ site: String(a.site),
104
+ environment: String(a.environment),
105
+ locale: String(a.locale)
106
+ };
107
+ a.status === "archived" ? await dn(e, t, String(a.id), [r]) : (await un(e, t, a, i, r), n += 1);
108
+ }
109
+ }
110
+ return n;
111
+ }, pn = (e) => e.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter((e) => e !== ""), mn = 160, hn = (e, t) => {
112
+ let n = pn(t), r = [...e.matchAll(/[\p{L}\p{N}]+/gu)].find((e) => n.some((t) => e[0].toLowerCase().startsWith(t))), i = r === void 0 ? 0 : Math.max(0, (r.index ?? 0) - mn / 3), a = i === 0 ? 0 : e.slice(i).search(/\s/) + i + 1, o = Math.min(e.length, a + mn), s = o < e.length ? e.slice(a, o).replace(/\s+\S*$/, "") : e.slice(a, o), c = `${a > 0 ? "…" : ""}${s.replace(/\s+/g, " ")}${a + s.length < e.length ? "…" : ""}`;
113
+ return {
114
+ text: c,
115
+ marks: [...c.matchAll(/[\p{L}\p{N}]+/gu)].filter((e) => n.some((t) => e[0].toLowerCase().startsWith(t))).map((e) => [e.index ?? 0, (e.index ?? 0) + e[0].length])
116
+ };
117
+ }, gn = async (e, t, n, r) => {
118
+ let i = n.trim();
119
+ if (pn(i).length === 0) return [];
120
+ let a = Math.max(1, Math.min(100, Math.floor(r.limit ?? 20))), o = r.types ?? [];
121
+ return (await e.query({
122
+ table: tn,
123
+ predicate: x(S("site", t.site), S("environment", t.environment), S("stage", r.stage), ...r.locale === void 0 ? [] : [S("locale", r.locale)], ...o.length > 0 ? [Vt("contentType", o)] : [], ...Object.entries(r.filter ?? {}).map(([e, t]) => S(e, t))),
124
+ order: [{
125
+ column: "id",
126
+ direction: "asc"
127
+ }],
128
+ take: a,
129
+ skip: void 0,
130
+ projection: void 0,
131
+ fullTextSearch: {
132
+ indexName: nn,
133
+ query: i,
134
+ columns: ["title", "body"],
135
+ config: "simple",
136
+ weights: {
137
+ title: "A",
138
+ body: "B"
139
+ },
140
+ rank: {
141
+ alias: "rank",
142
+ order: !0
143
+ },
144
+ prefix: !0
145
+ }
146
+ })).map((e) => ({
147
+ contentType: String(e.contentType),
148
+ documentId: String(e.documentId),
149
+ variantId: String(e.variantId),
150
+ locale: String(e.locale),
151
+ title: String(e.title),
152
+ snippet: hn(String(e.body ?? ""), i),
153
+ rank: Number(e.rank ?? 0)
154
+ }));
155
+ }, _n = (...e) => j(() => dn(...e)), vn = (...e) => j(() => un(...e)), yn = (...e) => j(() => fn(...e)), bn = (...e) => j(() => gn(...e)), xn = [
156
+ "site",
157
+ "environment",
158
+ "locale"
159
+ ], Sn = [
9
160
  "draft",
10
161
  "published",
11
162
  "archived"
12
- ], T = [
163
+ ], Cn = [
13
164
  "id",
14
165
  "status",
15
166
  "publishAt",
167
+ "unpublishAt",
168
+ "revisionId",
169
+ "revision",
170
+ "documentId",
171
+ "site",
172
+ "environment",
173
+ "locale",
16
174
  "tenantId",
17
175
  "createdAt",
18
176
  "updatedAt",
19
177
  "createdBy",
20
178
  "updatedBy"
21
- ], de = (e) => {
179
+ ], wn = (e) => {
22
180
  let t = {}, n = [], r = [];
23
181
  for (let [i, a] of Object.entries(e.fields)) {
24
- if (T.includes(i)) throw Error(`defineContentType('${e.name}'): field '${i}' collides with a reserved lifecycle column (${T.join(", ")}). Rename it.`);
182
+ if (Cn.includes(i)) throw Error(`defineContentType('${e.name}'): field '${i}' collides with a reserved lifecycle column (${Cn.join(", ")}). Rename it.`);
25
183
  let o = a;
26
184
  if (o.unique && o.kind !== "string") throw Error(`defineContentType('${e.name}'): field '${i}' is marked unique() but is a '${o.kind}' field — per-tenant uniqueness is only supported on string fields (a slug). Remove unique() or make it a Schema.String.`);
27
185
  t[i] = o, o.derived && n.push(i), o.unique && r.push(i);
28
186
  }
29
187
  if (e.list) {
30
- let n = /* @__PURE__ */ new Set([...Object.keys(t), ...T]);
188
+ let n = /* @__PURE__ */ new Set([...Object.keys(t), ...Cn]);
31
189
  for (let t of e.list.columns) if (!n.has(t)) throw Error(`defineContentType('${e.name}'): list.columns entry '${t}' is not a declared field (or lifecycle column) of this content type.`);
32
190
  let r = e.list.defaultSort?.field;
33
191
  if (r !== void 0 && !n.has(r)) throw Error(`defineContentType('${e.name}'): list.defaultSort.field '${r}' is not a declared field (or lifecycle column) of this content type.`);
34
192
  }
193
+ if (e.tree && En(e.name, t, e.tree), e.address !== void 0) {
194
+ if (e.tree) throw Error(`defineContentType('${e.name}'): address is for a type outside a tree — a tree type is addressed by its tree.`);
195
+ if (t[e.address]?.kind !== "string") throw Error(`defineContentType('${e.name}'): address '${e.address}' must be a declared string field.`);
196
+ }
197
+ if (e.availability && Dn(e.name, t, e.availability), e.templates && ae(e.name, t, e.templates), e.search && an(e.name, t, e.search), e.quality && Tn(e.name, t, e.quality), e.taxonomy) {
198
+ let n = t[e.taxonomy.field];
199
+ if (n?.kind !== "array" || n.element?.kind !== "string") throw Error(`defineContentType('${e.name}'): taxonomy field '${e.taxonomy.field}' must be a declared Schema.Array(Schema.String) field.`);
200
+ let r = me(e.taxonomy);
201
+ if (r !== null) throw Error(`defineContentType('${e.name}'): taxonomy ${r}.`);
202
+ }
203
+ if (e.lifecycle && !(Number.isInteger(e.lifecycle.reviewEveryDays) && e.lifecycle.reviewEveryDays > 0)) throw Error(`defineContentType('${e.name}'): lifecycle.reviewEveryDays must be a positive whole number of days.`);
35
204
  return {
36
205
  name: e.name,
37
206
  displayName: e.displayName,
@@ -40,63 +209,306 @@ var w = [
40
209
  ...e.list ? { list: e.list } : {},
41
210
  ...e.idPrefix ? { idPrefix: e.idPrefix } : {},
42
211
  ...e.revalidate ? { revalidate: e.revalidate } : {},
212
+ ...e.tree ? { tree: e.tree } : {},
213
+ ...e.address === void 0 ? {} : { address: e.address },
214
+ ...e.review ? { review: e.review } : {},
215
+ ...e.availability ? { availability: e.availability } : {},
216
+ ...e.lifecycle ? { lifecycle: e.lifecycle } : {},
217
+ ...e.templates ? { templates: e.templates } : {},
218
+ ...e.changeFeed === !0 ? { changeFeed: !0 } : {},
219
+ ...e.search ? { search: e.search } : {},
220
+ ...e.quality && e.quality.length > 0 ? { quality: e.quality } : {},
221
+ ...e.taxonomy ? { taxonomy: e.taxonomy } : {},
43
222
  derivedFields: n,
44
223
  uniqueFields: r
45
224
  };
46
- }, fe = (e) => {
225
+ }, Tn = (e, t, n) => {
226
+ let r = /* @__PURE__ */ new Set();
227
+ for (let i of n) {
228
+ if (!/^[A-Za-z][A-Za-z0-9.-]{0,63}$/.test(i.id)) throw Error(`defineContentType('${e}'): quality rule id '${i.id}' must be letters, digits, '.' or '-', at most 64.`);
229
+ if (r.has(i.id)) throw Error(`defineContentType('${e}'): quality rule '${i.id}' is declared twice.`);
230
+ if (r.add(i.id), t[i.field] === void 0) throw Error(`defineContentType('${e}'): quality rule '${i.id}' names '${i.field}', which is no field of this type.`);
231
+ }
232
+ }, En = (e, t, n) => {
233
+ let r = (t) => {
234
+ throw Error(`defineContentType('${e}'): tree ${t}`);
235
+ }, i = t[n.parent];
236
+ i === void 0 ? r(`parent '${n.parent}' is not a declared field.`) : (i.kind !== "reference" || i.referenceType !== e || !i.isOptional) && r(`parent '${n.parent}' must be Schema.Reference('${e}').optional() — roots have no parent.`);
237
+ let a = t[n.segment];
238
+ (a === void 0 || a.kind !== "string") && r(`segment '${n.segment}' must be a declared string field.`), n.order !== void 0 && t[n.order]?.kind !== "number" && r(`order '${n.order}' must be a declared number field.`);
239
+ for (let e of Object.keys(n.inherit ?? {})) (t[e] === void 0 || !t[e].isOptional) && r(`inherit '${e}' must be a declared optional field — a page that sets nothing inherits.`);
240
+ }, Dn = (e, t, n) => {
241
+ let r = n.until === void 0 ? void 0 : t[n.until];
242
+ if (n.until !== void 0 && (r === void 0 || r.kind !== "date" && r.kind !== "datetime")) throw Error(`defineContentType('${e}'): availability.until '${n.until}' must be a declared date or datetime field.`);
243
+ let i = n.blocked === void 0 ? void 0 : t[n.blocked];
244
+ if (n.blocked !== void 0 && (i === void 0 || i.kind !== "boolean")) throw Error(`defineContentType('${e}'): availability.blocked '${n.blocked}' must be a declared boolean field.`);
245
+ }, On = (e) => {
47
246
  switch (e.kind) {
48
- case "string": return e.isOptional ? b().nullable() : b();
49
- case "number": return e.isOptional ? _().nullable() : _();
50
- case "boolean": return e.isOptional ? p().nullable() : p();
51
- case "date": return e.isOptional ? m().nullable() : m();
52
- case "datetime": return e.isOptional ? x().nullable() : x();
247
+ case "string": return e.isOptional ? O().nullable() : O();
248
+ case "number": return e.fraction === !0 ? e.isOptional ? Wt().nullable() : Wt() : e.isOptional ? w().nullable() : w();
249
+ case "boolean": return e.isOptional ? Ft().nullable() : Ft();
250
+ case "date": return e.isOptional ? Lt().nullable() : Lt();
251
+ case "datetime": return e.isOptional ? k().nullable() : k();
53
252
  case "literal": {
54
- let t = e.literals ?? [], n = t.length > 0 ? b().oneOf(t) : b();
253
+ let t = e.literals ?? [], n = t.length > 0 ? O().oneOf(t) : O();
55
254
  return e.isOptional ? n.nullable() : n;
56
255
  }
57
256
  case "richText":
58
257
  case "array":
59
- case "struct": {
60
- let t = ie();
258
+ case "struct":
259
+ case "components": {
260
+ let t = T();
61
261
  return e.isOptional ? t.nullable() : t;
62
262
  }
63
263
  case "media":
64
- case "reference": return e.isOptional ? b().nullable() : b();
264
+ case "reference": return e.isOptional ? O().nullable() : O();
65
265
  }
66
- }, pe = (e) => {
266
+ }, kn = (e) => {
67
267
  let t = {};
68
- for (let [n, r] of Object.entries(e.fields)) t[n] = fe(r);
268
+ for (let [n, r] of Object.entries(e.fields)) t[n] = On(r);
69
269
  return t;
70
- }, me = (e) => e.idPrefix, E = (e, t) => {
71
- let n = me(e), r = n ? g({ prefix: n }) : g(), i = oe(`${e.name}_${t}`, {
270
+ }, An = (e) => e.idPrefix, jn = (e, t) => {
271
+ let n = An(e), r = n ? C({ prefix: n }) : C(), i = D(`${e.name}_${t}`, {
72
272
  id: r,
73
- status: b().oneOf(w),
74
- ...t === "drafts" ? { publishAt: x().nullable() } : {},
75
- ...pe(e)
76
- }).with(se());
77
- return e.uniqueFields.reduce((e, t) => e.unique(`uq_${t}`, ["tenantId", t]), i);
78
- }, he = (e) => ({
79
- draft: E(e, "drafts"),
80
- published: E(e, "published")
81
- }), ge = 3600, D = (e) => (Buffer.isBuffer(e) ? e : Buffer.from(e, "utf8")).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), O = (e) => Buffer.from(e.replace(/-/g, "+").replace(/_/g, "/"), "base64"), k = (e) => e ?? process.env.VOLTRO_SESSION_SECRET ?? null, _e = (e, t, n = {}) => {
82
- let r = k(n.secret);
273
+ status: O().oneOf(Sn),
274
+ ...t === "drafts" ? {
275
+ publishAt: k().nullable(),
276
+ unpublishAt: k().nullable()
277
+ } : {},
278
+ revisionId: O().default(""),
279
+ revision: w().default(0),
280
+ documentId: O().maxLength(64).backfill((e) => String(e.id)),
281
+ site: O().maxLength(64).default(""),
282
+ environment: O().maxLength(64).default(""),
283
+ locale: O().maxLength(64).default(""),
284
+ ...kn(e)
285
+ }).with(A()).unique(Pn(e, `${e.name}_${t}_variant_key`, "the document variant key"), [
286
+ "tenantId",
287
+ ...xn,
288
+ "documentId"
289
+ ]);
290
+ return e.uniqueFields.reduce((n, r) => n.unique(Nn(e, t, r), [
291
+ "tenantId",
292
+ ...xn,
293
+ r
294
+ ]), i);
295
+ }, Mn = 63, Nn = (e, t, n) => Pn(e, `${e.name}_${t}_uq_${n}`, `the unique constraint for field '${n}'`), Pn = (e, t, n) => {
296
+ if (t.length > Mn) throw Error(`contentTypeToEntities('${e.name}'): ${n} would be named '${t}' (${t.length} chars), past the ${Mn}-byte identifier limit. Shorten the content type name or the field name.`);
297
+ return t;
298
+ }, M = "cms_revisions", Fn = D(M, {
299
+ id: C({ prefix: "crev" }),
300
+ contentType: O().maxLength(64),
301
+ documentId: O().maxLength(64),
302
+ number: w(),
303
+ site: O().maxLength(64).default(""),
304
+ environment: O().maxLength(64).default(""),
305
+ locale: O().maxLength(64).default(""),
306
+ values: T(),
307
+ basedOn: O().nullable()
308
+ }).with(A()).unique("cms_revisions_uq_variant_number", [
309
+ "tenantId",
310
+ "contentType",
311
+ "documentId",
312
+ ...xn,
313
+ "number"
314
+ ]), In = (e) => ({
315
+ draft: jn(e, "drafts"),
316
+ published: jn(e, "published")
317
+ }), Ln = "cms_paths", N = "cms_redirects", Rn = D(Ln, {
318
+ id: C({ prefix: "cpth" }),
319
+ contentType: O().maxLength(64),
320
+ documentId: O().maxLength(64),
321
+ site: O().maxLength(64),
322
+ environment: O().maxLength(64),
323
+ locale: O().maxLength(64),
324
+ path: O()
325
+ }).with(A()).index("cms_paths_by_document", [
326
+ "contentType",
327
+ "documentId",
328
+ "site",
329
+ "environment",
330
+ "locale"
331
+ ]), zn = D(N, {
332
+ id: C({ prefix: "crdr" }),
333
+ contentType: O().maxLength(64),
334
+ site: O().maxLength(64),
335
+ environment: O().maxLength(64),
336
+ locale: O().maxLength(64),
337
+ fromPath: O(),
338
+ documentId: O().maxLength(64)
339
+ }).with(A()).index("cms_redirects_by_path", [
340
+ "contentType",
341
+ "site",
342
+ "environment",
343
+ "locale",
344
+ "fromPath"
345
+ ]), Bn = (e, t, n) => e.query({
346
+ table: t,
347
+ predicate: n,
348
+ order: [],
349
+ take: void 0,
350
+ skip: void 0,
351
+ projection: void 0
352
+ }), Vn = (e) => [
353
+ S("site", e.site),
354
+ S("environment", e.environment),
355
+ S("locale", e.locale)
356
+ ], Hn = async (e, t, n, r) => {
357
+ if (t.tree === void 0 && t.address === void 0) return;
358
+ let i = await Bn(e, `${t.name}_published`, x(...Vn(n), E("status", "archived"))), a = t.address, o = t.tree === void 0 ? { nodes: i.filter((e) => typeof e[a] == "string" && e[a] !== "").map((e) => ({
359
+ documentId: String(e.documentId),
360
+ path: String(e[a])
361
+ })) } : tt(i.map((e) => ({
362
+ row: e,
363
+ locale: n.locale,
364
+ fallback: !1
365
+ })), t.tree), s = new Map((await Bn(e, Ln, x(S("contentType", t.name), ...Vn(n)))).map((e) => [String(e.documentId), e])), c = r == null ? {} : { tenantId: r };
366
+ for (let r of o.nodes) {
367
+ let i = s.get(r.documentId);
368
+ if (i === void 0) {
369
+ await e.insert(Ln, {
370
+ contentType: t.name,
371
+ documentId: r.documentId,
372
+ ...n,
373
+ path: r.path,
374
+ ...c
375
+ });
376
+ continue;
377
+ }
378
+ if (i.path === r.path) continue;
379
+ let a = String(i.path), [o] = await Bn(e, N, x(S("contentType", t.name), ...Vn(n), S("fromPath", a)));
380
+ o === void 0 ? await e.insert(N, {
381
+ contentType: t.name,
382
+ ...n,
383
+ fromPath: a,
384
+ documentId: r.documentId,
385
+ ...c
386
+ }) : await e.update(N, String(o.id), { documentId: r.documentId }), await e.update(Ln, String(i.id), { path: r.path });
387
+ }
388
+ }, Un = async (e, t, n, r, i, a) => {
389
+ let o = r.replace(/^\/+|\/+$/g, "");
390
+ if (o === "") return;
391
+ let s = a == null ? {} : { tenantId: a }, [c] = await Bn(e, N, x(S("contentType", t.name), ...Vn(n), S("fromPath", o)));
392
+ c === void 0 ? await e.insert(N, {
393
+ contentType: t.name,
394
+ ...n,
395
+ fromPath: o,
396
+ documentId: i,
397
+ ...s
398
+ }) : await e.update(N, String(c.id), { documentId: i });
399
+ }, Wn = async (e, t, n, r, i) => {
400
+ let a = i === void 0 ? [] : [S("tenantId", i)], [o] = await Bn(e, N, x(S("contentType", t), ...Vn(r), S("fromPath", n), ...a));
401
+ return o === void 0 ? null : String(o.documentId);
402
+ }, Gn = async (e, t, n, r) => {
403
+ let i = r.replace(/^\/+|\/+$/g, ""), [a] = await Bn(e, N, x(S("contentType", t.name), ...Vn(n), S("fromPath", i)));
404
+ return a !== void 0 && (await e.delete(N, String(a.id)), !0);
405
+ }, Kn = async (e, t, n, r, i) => {
406
+ let a = i === void 0 ? [] : [S("tenantId", i)], [o] = await Bn(e, Ln, x(S("contentType", t), ...Vn(r), S("path", n), ...a));
407
+ return o !== void 0 || await Wn(e, t, n, r, i) !== null;
408
+ }, qn = (e, t, n) => Bn(e, N, x(S("contentType", t), ...Vn(n))), Jn = (...e) => j(() => Un(...e)), Yn = (...e) => j(() => Kn(...e)), Xn = (...e) => j(() => qn(...e)), Zn = (...e) => j(() => Hn(...e)), Qn = (...e) => j(() => Wn(...e)), $n = (...e) => j(() => Gn(...e)), er = "cms_references", tr = D(er, {
409
+ id: C({ prefix: "cref" }),
410
+ sourceType: O().maxLength(64),
411
+ sourceDocumentId: O().maxLength(64),
412
+ sourceVariantId: O().maxLength(64),
413
+ site: O().maxLength(64),
414
+ environment: O().maxLength(64),
415
+ locale: O().maxLength(64),
416
+ path: O(),
417
+ targetType: O().maxLength(64),
418
+ targetDocumentId: O().maxLength(64)
419
+ }).with(A()).index("cms_references_by_target", ["targetType", "targetDocumentId"]), nr = (e, t, n, r) => {
420
+ if (t != null) switch (e.kind) {
421
+ case "reference":
422
+ typeof t == "string" && t !== "" && e.referenceType !== void 0 && r.push({
423
+ path: n,
424
+ targetType: e.referenceType,
425
+ targetDocumentId: t
426
+ });
427
+ return;
428
+ case "array":
429
+ e.element !== void 0 && Array.isArray(t) && t.forEach((t, i) => nr(e.element, t, `${n}[${i}]`, r));
430
+ return;
431
+ case "struct":
432
+ if (e.struct !== void 0 && typeof t == "object") for (let [i, a] of Object.entries(e.struct)) nr(a, t[i], `${n}.${i}`, r);
433
+ return;
434
+ case "richText": {
435
+ let i = e.richText ?? {};
436
+ if (De(n, t, i).length > 0) return;
437
+ r.push(...h(n, t, i));
438
+ return;
439
+ }
440
+ case "components": {
441
+ if (!Array.isArray(t)) return;
442
+ let i = new Map((e.components ?? []).map((e) => [e.id, e]));
443
+ t.forEach((e, t) => {
444
+ let a = e, o = i.get(String(a.componentId));
445
+ if (o !== void 0 && typeof a.props == "object" && a.props !== null) for (let [e, i] of Object.entries(o.props)) nr(i, a.props[e], `${n}[${t}].props.${e}`, r);
446
+ });
447
+ return;
448
+ }
449
+ default: return;
450
+ }
451
+ }, rr = (e, t) => {
452
+ let n = [];
453
+ for (let [r, i] of Object.entries(e.fields)) nr(i, t[r], r, n);
454
+ return n;
455
+ }, ir = (e, t, n) => ({
456
+ table: er,
457
+ predicate: x(S("sourceType", e.name), S("sourceVariantId", t), S("site", n.site), S("environment", n.environment), S("locale", n.locale)),
458
+ order: [],
459
+ take: void 0,
460
+ skip: void 0,
461
+ projection: void 0
462
+ }), ar = async (e, t, n, r) => {
463
+ for (let i of await e.query(ir(t, n, r))) await e.delete(er, i.id);
464
+ }, or = async (e, t, n, r) => {
465
+ let i = n.id;
466
+ await ar(e, t, i, r);
467
+ let a = n.tenantId;
468
+ for (let o of rr(t, n)) await e.insert(er, {
469
+ sourceType: t.name,
470
+ sourceDocumentId: n.documentId,
471
+ sourceVariantId: i,
472
+ site: r.site,
473
+ environment: r.environment,
474
+ locale: r.locale,
475
+ path: o.path,
476
+ targetType: o.targetType,
477
+ targetDocumentId: o.targetDocumentId,
478
+ ...a == null ? {} : { tenantId: a }
479
+ });
480
+ }, sr = async (e, t, n) => (await e.query({
481
+ table: er,
482
+ predicate: x(S("targetType", t.type), S("targetDocumentId", t.documentId), S("site", n.site), S("environment", n.environment)),
483
+ order: [],
484
+ take: void 0,
485
+ skip: void 0,
486
+ projection: void 0
487
+ })).map((e) => ({
488
+ sourceType: e.sourceType,
489
+ sourceDocumentId: e.sourceDocumentId,
490
+ sourceVariantId: e.sourceVariantId,
491
+ locale: e.locale,
492
+ path: e.path
493
+ })).sort((e, t) => e.sourceType.localeCompare(t.sourceType) || e.sourceDocumentId.localeCompare(t.sourceDocumentId) || e.locale.localeCompare(t.locale) || e.path.localeCompare(t.path)), cr = (...e) => j(() => sr(...e)), lr = 3600, ur = (e) => (Buffer.isBuffer(e) ? e : Buffer.from(e, "utf8")).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), dr = (e) => Buffer.from(e.replace(/-/g, "+").replace(/_/g, "/"), "base64"), fr = (e) => e ?? process.env.VOLTRO_SESSION_SECRET ?? null, pr = (e, t, n = {}) => {
494
+ let r = fr(n.secret);
83
495
  if (r === null) throw Error("cms previewToken requires a signing secret — set VOLTRO_SESSION_SECRET or pass { secret }. Refusing to sign with a hardcoded default (it would ship in the bundle and be forgeable).");
84
496
  let i = {
85
497
  t: e,
86
498
  i: t,
87
- exp: Math.floor(Date.now() / 1e3) + (n.ttlSeconds ?? ge)
88
- }, a = D(JSON.stringify(i));
89
- return `${a}.${D(S("sha256", r).update(a).digest())}`;
90
- }, A = (e, t = {}) => {
499
+ exp: Math.floor(Date.now() / 1e3) + (n.ttlSeconds ?? lr)
500
+ }, a = ur(JSON.stringify(i));
501
+ return `${a}.${ur(qt("sha256", r).update(a).digest())}`;
502
+ }, mr = (e, t = {}) => {
91
503
  if (!e) return null;
92
- let n = k(t.secret);
504
+ let n = fr(t.secret);
93
505
  if (n === null) return null;
94
506
  let r = e.indexOf(".");
95
507
  if (r <= 0 || r === e.length - 1) return null;
96
- let i = e.slice(0, r), a = e.slice(r + 1), o = S("sha256", n).update(i).digest(), s = O(a);
97
- if (s.length !== o.length || !ce(s, o)) return null;
508
+ let i = e.slice(0, r), a = e.slice(r + 1), o = qt("sha256", n).update(i).digest(), s = dr(a);
509
+ if (s.length !== o.length || !Yt(s, o)) return null;
98
510
  try {
99
- let e = JSON.parse(O(i).toString("utf8"));
511
+ let e = JSON.parse(dr(i).toString("utf8"));
100
512
  return typeof e.t != "string" || typeof e.i != "string" || typeof e.exp != "number" || e.exp < Math.floor(Date.now() / 1e3) ? null : {
101
513
  type: e.t,
102
514
  id: e.i
@@ -104,17 +516,17 @@ var w = [
104
516
  } catch {
105
517
  return null;
106
518
  }
107
- }, ve = (e, t, n) => {
519
+ }, hr = (e, t, n) => {
108
520
  switch (t) {
109
- case "=": return h(e, n);
110
- case "!=": return y(e, n);
111
- case "<": return ae(e, n);
112
- case "<=": return v(e, n);
113
- case ">": return ne(e, n);
114
- case ">=": return re(e, n);
115
- }
116
- }, j = (e) => {
117
- let t = e.excludeArchived ? [...e.predicates, y("status", "archived")] : e.predicates, n = t.length === 0 ? void 0 : t.length === 1 ? t[0] : f(...t);
521
+ case "=": return S(e, n);
522
+ case "!=": return E(e, n);
523
+ case "<": return Ht(e, n);
524
+ case "<=": return Ut(e, n);
525
+ case ">": return zt(e, n);
526
+ case ">=": return Bt(e, n);
527
+ }
528
+ }, gr = (e) => {
529
+ let t = e.excludeArchived ? [...e.predicates, E("status", "archived")] : e.predicates, n = t.length === 0 ? void 0 : t.length === 1 ? t[0] : x(...t);
118
530
  return {
119
531
  table: e.table,
120
532
  predicate: n,
@@ -123,15 +535,15 @@ var w = [
123
535
  skip: e.skip,
124
536
  projection: void 0
125
537
  };
126
- }, M = (e, t) => ({
538
+ }, _r = (e, t) => ({
127
539
  where(n, r, i) {
128
- return M(e, {
540
+ return _r(e, {
129
541
  ...t,
130
- predicates: [...t.predicates, ve(n, r, i)]
542
+ predicates: [...t.predicates, hr(n, r, i)]
131
543
  });
132
544
  },
133
545
  orderBy(n, r = "asc") {
134
- return M(e, {
546
+ return _r(e, {
135
547
  ...t,
136
548
  order: [...t.order, {
137
549
  column: n,
@@ -140,49 +552,179 @@ var w = [
140
552
  });
141
553
  },
142
554
  limit(n) {
143
- return M(e, {
555
+ return _r(e, {
144
556
  ...t,
145
557
  take: n
146
558
  });
147
559
  },
148
560
  offset(n) {
149
- return M(e, {
561
+ return _r(e, {
150
562
  ...t,
151
563
  skip: n
152
564
  });
153
565
  },
154
566
  async all() {
155
- return e.query(j(t));
567
+ return e.query(gr(t));
156
568
  },
157
569
  async one() {
158
- return (await e.query(j({
570
+ return (await e.query(gr({
159
571
  ...t,
160
572
  take: 1
161
573
  })))[0] ?? null;
574
+ },
575
+ async page(n, r) {
576
+ let i = Math.max(1, Math.floor(n)), a = r === void 0 ? t.predicates : [...t.predicates, zt("id", r)], o = await e.query(gr({
577
+ ...t,
578
+ predicates: a,
579
+ order: [{
580
+ column: "id",
581
+ direction: "asc"
582
+ }],
583
+ take: i + 1,
584
+ skip: void 0
585
+ })), s = o.slice(0, i);
586
+ return {
587
+ items: s,
588
+ next: o.length > i ? String(s[s.length - 1]?.id) : null
589
+ };
162
590
  }
163
- }), N = (e, t, n) => {
164
- let r = new Map(t.map((e) => [e.name, e])), i = (e) => {
165
- let t = r.get(e);
591
+ }), vr = (e, t, n, r) => {
592
+ let i = [
593
+ S("site", n.site),
594
+ S("environment", n.environment),
595
+ S("locale", n.locale)
596
+ ], a = new Map(t.map((e) => [e.name, e])), o = (e) => {
597
+ let t = a.get(e);
166
598
  if (!t) throw Error(`cms.contentType('${e}'): unknown content type. Register it via defineContentType and pass it to cmsContext / createCmsClient.`);
167
599
  return t;
168
- };
169
- return {
600
+ }, s = async (t, r, i) => (await e.query({
601
+ table: `${t}_published`,
602
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", r), E("status", "archived"), ...Object.entries(i).map(([e, t]) => S(e, t))),
603
+ order: [],
604
+ take: 1,
605
+ skip: void 0,
606
+ projection: void 0
607
+ }))[0] ?? null, c = (t, r, i) => e.query({
608
+ table: `${t}_published`,
609
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", r), E("status", "archived"), ...Object.entries(i).map(([e, t]) => S(e, t))),
610
+ order: [],
611
+ take: void 0,
612
+ skip: void 0,
613
+ projection: void 0
614
+ }), l = async (e, t, n) => {
615
+ let r = o(e).tree;
616
+ if (r === void 0) throw Error(`cms.tree('${e}'): the content type declares no tree. Add tree: { parent, segment } to it.`);
617
+ let i = [];
618
+ for (let r of /* @__PURE__ */ new Set([t, ...n.fallback ?? []])) for (let a of await c(e, r, n.filter ?? {})) i.push({
619
+ row: a,
620
+ locale: r,
621
+ fallback: r !== t
622
+ });
623
+ return tt(i, r);
624
+ }, u = {
625
+ async usedBy(t, r) {
626
+ return o(t), sr(e, {
627
+ type: t,
628
+ documentId: r
629
+ }, n);
630
+ },
631
+ async tree(e, t = {}) {
632
+ return l(e, n.locale, t);
633
+ },
634
+ async route(t, r, i = {}) {
635
+ let a = await l(t, n.locale, i), o = a.nodes.find((e) => e.path === r);
636
+ if (o !== void 0) return {
637
+ node: o,
638
+ tree: a,
639
+ via: "path"
640
+ };
641
+ for (let e of i.fallback ?? []) {
642
+ if (e === n.locale) continue;
643
+ let o = (await l(t, e, {
644
+ ...i,
645
+ fallback: []
646
+ })).nodes.find((e) => e.path === r);
647
+ if (o === void 0) continue;
648
+ let s = a.nodes.find((e) => e.documentId === o.documentId);
649
+ return s === void 0 ? null : {
650
+ node: s,
651
+ tree: a,
652
+ via: "fallback"
653
+ };
654
+ }
655
+ let s = i.filter?.tenantId;
656
+ for (let o of /* @__PURE__ */ new Set([n.locale, ...i.fallback ?? []])) {
657
+ let i = await Wn(e, t, r, {
658
+ ...n,
659
+ locale: o
660
+ }, s), c = i === null ? void 0 : a.nodes.find((e) => e.documentId === i);
661
+ if (c !== void 0) return {
662
+ node: c,
663
+ tree: a,
664
+ via: "redirect"
665
+ };
666
+ }
667
+ return null;
668
+ },
669
+ async gone(t, r, i = {}) {
670
+ if (await u.route(t, r, i) !== null) return !1;
671
+ let a = i.filter?.tenantId;
672
+ for (let o of /* @__PURE__ */ new Set([n.locale, ...i.fallback ?? []])) if (await Kn(e, t, r, {
673
+ ...n,
674
+ locale: o
675
+ }, a)) return !0;
676
+ return !1;
677
+ },
678
+ async resolve(e, t) {
679
+ o(e);
680
+ let r = t.filter ?? {}, i = {
681
+ ...r,
682
+ [t.key.field]: t.key.value
683
+ }, a = n.locale, c = await s(e, a, i);
684
+ if (c !== null) return {
685
+ row: c,
686
+ locale: a,
687
+ requestedLocale: a,
688
+ fallback: !1
689
+ };
690
+ for (let n of t.fallback ?? []) {
691
+ if (n === a) continue;
692
+ let t = await s(e, n, i);
693
+ if (t === null) continue;
694
+ let o = await s(e, a, {
695
+ ...r,
696
+ documentId: t.documentId
697
+ });
698
+ return o === null ? {
699
+ row: t,
700
+ locale: n,
701
+ requestedLocale: a,
702
+ fallback: !0
703
+ } : {
704
+ row: o,
705
+ locale: a,
706
+ requestedLocale: a,
707
+ fallback: !1
708
+ };
709
+ }
710
+ return null;
711
+ },
170
712
  contentType(t) {
171
- return i(t), M(e, {
713
+ return o(t), _r(e, {
172
714
  table: `${t}_published`,
173
- predicates: [],
715
+ predicates: i,
174
716
  order: [],
175
717
  take: void 0,
176
718
  skip: void 0,
177
719
  excludeArchived: !0
178
720
  });
179
721
  },
180
- async preview(t, r, a) {
181
- i(t);
182
- let o = a ? A(a, n ? { secret: n } : {}) : null, s = o !== null && o.type === t && o.id === r ? `${t}_drafts` : `${t}_published`;
722
+ async preview(t, n, a) {
723
+ o(t);
724
+ let s = a ? mr(a, r ? { secret: r } : {}) : null, c = s !== null && s.type === t && s.id === n ? `${t}_drafts` : `${t}_published`;
183
725
  return (await e.query({
184
- table: s,
185
- predicate: h("id", r),
726
+ table: c,
727
+ predicate: x(S("id", n), ...i),
186
728
  order: [],
187
729
  take: 1,
188
730
  skip: void 0,
@@ -190,204 +732,3199 @@ var w = [
190
732
  }))[0] ?? null;
191
733
  }
192
734
  };
193
- }, P = (e, t, n = {}) => N(e, t, n.secret), F = (e) => N(e.store, e.types, e.secret), ye = (e) => {
194
- if (e.cms === void 0) throw Error("useCms: `ctx.cms` is not set. Build it with cmsContext(store, types) and attach it to your AppContext (or use createCmsClient at build time).");
735
+ return u;
736
+ }, yr = (e, t, n) => vr(e, t, n.scope, n.secret), br = (e) => vr(e.store, e.types, e.scope, e.secret), xr = (e) => {
737
+ if (e.cms === void 0) throw Error("useCms: `ctx.cms` is not set. Build it with cmsContext(store, types, { scope }) and attach it to your AppContext (or use createCmsClient at build time).");
195
738
  return e.cms;
196
- }, I = (e) => `${e.name}_drafts`, L = (e) => `${e.name}_published`, R = (e, t, n) => ({
197
- table: e,
198
- predicate: h("id", t),
199
- order: [],
200
- take: 1,
739
+ }, Sr = "cms_changes", Cr = D(Sr, {
740
+ id: C({ prefix: "cchg" }),
741
+ site: O().maxLength(64),
742
+ environment: O().maxLength(64),
743
+ locale: O().maxLength(64),
744
+ contentType: O().maxLength(64),
745
+ documentId: O().maxLength(64),
746
+ variantId: O().maxLength(64),
747
+ action: O().oneOf(["published", "unpublished"]),
748
+ revision: w().nullable(),
749
+ releaseId: O().nullable(),
750
+ at: k()
751
+ }).with(A()).index("cms_changes_by_place", [
752
+ "site",
753
+ "environment",
754
+ "id"
755
+ ]), wr = async (e, t, n, r, i, a = {}) => {
756
+ if (t.changeFeed !== !0) return;
757
+ let o = n.tenantId;
758
+ await e.insert(Sr, {
759
+ site: r.site,
760
+ environment: r.environment,
761
+ locale: r.locale,
762
+ contentType: t.name,
763
+ documentId: String(n.documentId),
764
+ variantId: String(n.id),
765
+ action: i,
766
+ revision: i === "published" && typeof n.revision == "number" ? n.revision : null,
767
+ releaseId: a.releaseId ?? null,
768
+ at: /* @__PURE__ */ new Date(),
769
+ ...o == null ? {} : { tenantId: o }
770
+ });
771
+ }, Tr = (e) => e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : Number(e), Er = async (e, t, n = {}) => {
772
+ let r = Math.max(1, Math.min(1e3, Math.floor(n.limit ?? 100))), i = new Date((n.now ?? Date.now()) - (n.settleMs ?? 2e3)), a = (await e.query({
773
+ table: Sr,
774
+ predicate: x(S("site", t.site), S("environment", t.environment), Ht("at", i), ...n.after === void 0 ? [] : [zt("id", n.after)], ...Object.entries(n.filter ?? {}).map(([e, t]) => S(e, t))),
775
+ order: [{
776
+ column: "id",
777
+ direction: "asc"
778
+ }],
779
+ take: r,
780
+ skip: void 0,
781
+ projection: void 0
782
+ })).map((e) => ({
783
+ id: String(e.id),
784
+ at: Tr(e.at),
785
+ locale: String(e.locale),
786
+ contentType: String(e.contentType),
787
+ documentId: String(e.documentId),
788
+ variantId: String(e.variantId),
789
+ action: e.action === "unpublished" ? "unpublished" : "published",
790
+ revision: typeof e.revision == "number" ? e.revision : null,
791
+ releaseId: typeof e.releaseId == "string" ? e.releaseId : null
792
+ }));
793
+ return {
794
+ items: a,
795
+ next: a.length > 0 ? a[a.length - 1].id : n.after ?? null
796
+ };
797
+ }, Dr = (...e) => j(() => Er(...e)), Or = (...e) => j(() => wr(...e)), kr = "cms_team", P = "cms_team_invitations", Ar = D(kr, {
798
+ id: C({ prefix: "ctm" }),
799
+ defaultRole: O().nullable(),
800
+ reviewRequired: T().nullable()
801
+ }).with(A()).unique("cms_team_uq_tenant", ["tenantId"]), jr = D(P, {
802
+ id: C({ prefix: "cinv" }),
803
+ email: O().sensitive("pii"),
804
+ role: O()
805
+ }).with(A()).unique("cms_team_invitations_uq_email", ["tenantId", "email"]), Mr = /^[^\s@]+@[^\s@]+\.[^\s@]+$/, Nr = /^[a-z][a-zA-Z0-9-]{0,39}$/, Pr = (e) => {
806
+ let t = [];
807
+ e.defaultRole !== void 0 && !Nr.test(e.defaultRole) && t.push(`default role "${e.defaultRole}" is not a role name`);
808
+ let n = /* @__PURE__ */ new Set();
809
+ for (let r of e.members ?? []) {
810
+ let e = r.email.trim().toLowerCase();
811
+ Mr.test(e) || t.push(`"${r.email}" is not an e-mail address`), n.has(e) && t.push(`"${r.email}" is invited twice`), n.add(e), Nr.test(r.role) || t.push(`role "${r.role}" of ${r.email} is not a role name`);
812
+ }
813
+ return new Set(e.reviewRequired ?? []).size !== (e.reviewRequired ?? []).length && t.push("a type is listed twice for review"), t;
814
+ }, Fr = (e, t, n) => e.query({
815
+ table: t,
816
+ predicate: n,
817
+ order: [{
818
+ column: "id",
819
+ direction: "asc"
820
+ }],
821
+ take: void 0,
201
822
  skip: void 0,
202
- projection: void 0,
203
- ...n === !0 ? { crossTenant: !0 } : {}
204
- }), z = async (e, t, n) => (await e.query(R(t, n)))[0], B = (e, t) => {
205
- let n = {};
206
- for (let r of Object.keys(e.fields)) r in t && (n[r] = t[r]);
207
- return n;
208
- }, V = async (t, n, r) => {
209
- let i = u(n, r);
210
- e(n, i);
211
- let a = I(n), o = B(n, i), s = i.id;
212
- if (s !== void 0) {
213
- let e = await z(t, a, s);
214
- if (e !== void 0) return await t.update(a, s, {
215
- ...o,
216
- status: "draft"
217
- }) ?? e;
218
- if ((await t.query(R(a, s, !0))).length > 0) throw new c({
219
- contentType: n.name,
220
- id: s
221
- });
222
- return t.insert(a, {
223
- ...o,
224
- id: s,
225
- status: "draft"
226
- });
227
- }
228
- return t.insert(a, {
229
- ...o,
230
- status: "draft"
231
- });
232
- }, H = (e) => {
233
- let t = e.revalidate;
234
- if (t !== void 0) {
235
- for (let n of t.paths ?? []) le(n).catch((t) => {
236
- console.warn(`[voltro cms] revalidatePath('${n}') for '${e.name}' failed:`, t);
237
- });
238
- for (let n of t.tags ?? []) ue(n).catch((t) => {
239
- console.warn(`[voltro cms] revalidateTag('${n}') for '${e.name}' failed:`, t);
823
+ projection: void 0
824
+ }), Ir = async (e, t) => (await Fr(e, kr, S("tenantId", t)))[0], Lr = async (e, t, n, r) => {
825
+ let i = null;
826
+ if (n.defaultRole !== void 0) {
827
+ let a = await Ir(e, t), o = typeof a?.defaultRole == "string";
828
+ i = {
829
+ role: o ? String(a.defaultRole) : n.defaultRole,
830
+ action: o ? "kept" : "set"
831
+ }, r && !o && (a === void 0 ? await e.insert(kr, {
832
+ defaultRole: n.defaultRole,
833
+ tenantId: t
834
+ }) : await e.update(kr, String(a.id), { defaultRole: n.defaultRole }));
835
+ }
836
+ let a = [];
837
+ for (let i of n.members ?? []) {
838
+ let n = i.email.trim().toLowerCase(), [o] = await Fr(e, P, x(S("tenantId", t), S("email", n)));
839
+ a.push({
840
+ email: n,
841
+ role: o === void 0 ? i.role : String(o.role),
842
+ action: o === void 0 ? "invite" : "present"
843
+ }), r && o === void 0 && await e.insert(P, {
844
+ email: n,
845
+ role: i.role,
846
+ tenantId: t
240
847
  });
241
848
  }
242
- }, U = async (e, t, n) => {
243
- let r = await e.transactional(async (e) => {
244
- let r = await z(e, I(t), n);
245
- if (r === void 0) throw new d({
246
- contentType: t.name,
247
- id: n,
248
- stage: "draft"
849
+ let o = [];
850
+ if ((n.reviewRequired ?? []).length > 0) {
851
+ let i = Rr(await Ir(e, t));
852
+ for (let e of n.reviewRequired ?? []) o.push({
853
+ type: e,
854
+ action: i.includes(e) ? "present" : "require"
249
855
  });
250
- let i = L(t), a = B(t, r), o = await z(e, i, n), s;
251
- if (o !== void 0) s = await e.update(i, n, {
252
- ...a,
253
- status: "published"
254
- }) ?? o;
255
- else {
256
- let t = r.tenantId;
257
- s = await e.insert(i, {
258
- ...a,
259
- id: n,
260
- status: "published",
261
- ...t == null ? {} : { tenantId: t }
262
- });
263
- }
264
- return await e.update(I(t), n, { status: "published" }), s;
856
+ let a = o.filter((e) => e.action === "require").map((e) => e.type);
857
+ r && a.length > 0 && await zr(e, t, [...i, ...a]);
858
+ }
859
+ return {
860
+ defaultRole: i,
861
+ members: a,
862
+ reviewRequired: o
863
+ };
864
+ }, Rr = (e) => Array.isArray(e?.reviewRequired) ? e.reviewRequired.filter((e) => typeof e == "string") : [], zr = async (e, t, n) => {
865
+ let r = await Ir(e, t), i = [...new Set(n)].sort();
866
+ r === void 0 ? await e.insert(kr, {
867
+ defaultRole: null,
868
+ reviewRequired: i,
869
+ tenantId: t
870
+ }) : await e.update(kr, String(r.id), { reviewRequired: i });
871
+ }, Br = async (e, t) => Rr(await Ir(e, t)), Vr = async (e, t, n, r) => {
872
+ let i = Rr(await Ir(e, t)), a = r ? [...i, n] : i.filter((e) => e !== n);
873
+ return await zr(e, t, a), [...new Set(a)].sort();
874
+ }, Hr = (e, t, n) => Lr(e, t, n, !1), Ur = (e, t, n) => Lr(e, t, n, !0), Wr = async (e, t) => {
875
+ let n = (await Ir(e, t))?.defaultRole;
876
+ return typeof n == "string" ? n : null;
877
+ }, Gr = async (e, t, n) => {
878
+ let [r] = await Fr(e, P, x(S("tenantId", t), S("email", n.trim().toLowerCase())));
879
+ return r === void 0 ? null : String(r.role);
880
+ }, Kr = async (e, t) => (await Fr(e, P, S("tenantId", t))).map((e) => ({
881
+ email: String(e.email),
882
+ role: String(e.role)
883
+ })).sort((e, t) => e.email < t.email ? -1 : 1), qr = async (e, t, n, r) => {
884
+ let i = n.trim().toLowerCase(), [a] = await Fr(e, P, x(S("tenantId", t), S("email", i)));
885
+ return a === void 0 ? (await e.insert(P, {
886
+ email: i,
887
+ role: r,
888
+ tenantId: t
889
+ }), "invited") : a.role === r ? "present" : (await e.update(P, String(a.id), { role: r }), "changed");
890
+ }, Jr = async (e, t, n) => {
891
+ let [r] = await Fr(e, P, x(S("tenantId", t), S("email", n.trim().toLowerCase())));
892
+ return r !== void 0 && (await e.delete(P, String(r.id)), !0);
893
+ }, Yr = (...e) => j(() => Ur(...e)), Xr = (...e) => j(() => Gr(...e)), Zr = (...e) => j(() => qr(...e)), Qr = (...e) => j(() => Hr(...e)), $r = (...e) => j(() => Wr(...e)), ei = (...e) => j(() => Kr(...e)), ti = (...e) => j(() => Vr(...e)), ni = (...e) => j(() => Jr(...e)), ri = (...e) => j(() => Br(...e)), ii = "cms_reviews", ai = [
894
+ "requested",
895
+ "approved",
896
+ "changesRequested"
897
+ ], oi = D(ii, {
898
+ id: C({ prefix: "crvw" }),
899
+ contentType: O().maxLength(64),
900
+ variantId: O().maxLength(64),
901
+ documentId: O().maxLength(64),
902
+ site: O().maxLength(64),
903
+ environment: O().maxLength(64),
904
+ locale: O().maxLength(64),
905
+ revisionId: O(),
906
+ action: O().oneOf(ai),
907
+ actorId: O(),
908
+ note: O().nullable()
909
+ }).with(A()).index("cms_reviews_by_variant", ["contentType", "variantId"]), si = (e) => [
910
+ S("site", e.site),
911
+ S("environment", e.environment),
912
+ S("locale", e.locale)
913
+ ], ci = async (e, t, n, r) => {
914
+ let [i] = await e.query({
915
+ table: `${t.name}_drafts`,
916
+ predicate: x(S("id", n), ...si(r)),
917
+ order: [],
918
+ take: 1,
919
+ skip: void 0,
920
+ projection: void 0
265
921
  });
266
- return H(t), r;
267
- }, W = async (e, t, n) => {
268
- await e.transactional(async (e) => {
269
- if (await z(e, L(t), n) === void 0) throw new d({
270
- contentType: t.name,
271
- id: n,
272
- stage: "published"
273
- });
274
- await e.delete(L(t), n), await z(e, I(t), n) !== void 0 && await e.update(I(t), n, { status: "draft" });
275
- }), H(t);
276
- }, G = async (e, t, n) => e.transactional(async (e) => {
277
- let r = await z(e, I(t), n), i = await z(e, L(t), n);
278
- if (r === void 0 && i === void 0) throw new d({
922
+ if (i === void 0) throw new y({
279
923
  contentType: t.name,
280
924
  id: n,
281
925
  stage: "draft"
282
926
  });
283
- r !== void 0 && await e.update(I(t), n, { status: "archived" }), i !== void 0 && await e.update(L(t), n, { status: "archived" });
284
- }), K = (e, t) => C.tryPromise({
285
- try: e,
286
- catch: (e) => e
287
- }).pipe(C.catchAll((e) => t(e) ? C.fail(e) : C.die(e))), be = (e) => e instanceof t || e instanceof c, q = (e) => e instanceof d, xe = (e, t, n) => K(() => V(e, t, n), be), Se = (e, t, n) => K(() => U(e, t, n), q), Ce = (e, t, n) => K(() => W(e, t, n), q), we = (e, t, n) => K(() => G(e, t, n), q), J = (e) => `${e.name}_drafts`, Y = async (e, t, n, r) => {
288
- let i = J(t), a = await e.query({
289
- table: i,
290
- predicate: h("id", n),
927
+ return i;
928
+ }, li = (e, t, n, r) => e.query({
929
+ table: ii,
930
+ predicate: x(S("contentType", t.name), S("variantId", n), ...si(r)),
931
+ order: [{
932
+ column: "createdAt",
933
+ direction: "desc"
934
+ }],
935
+ take: void 0,
936
+ skip: void 0,
937
+ projection: void 0
938
+ }), ui = async (e, t, n, r, i, a, o) => e.insert(ii, {
939
+ contentType: t.name,
940
+ variantId: n.id,
941
+ documentId: n.documentId,
942
+ site: r.site,
943
+ environment: r.environment,
944
+ locale: r.locale,
945
+ revisionId: n.revisionId,
946
+ action: i,
947
+ actorId: a,
948
+ note: o ?? null
949
+ }), di = async (e, t, n, r, i) => ui(e, t, await ci(e, t, n, r), r, "requested", i.actorId, i.note), fi = async (e, t, n, i, a) => {
950
+ let o = await ci(e, t, n, i);
951
+ if (o.revisionId !== a) throw new r({
952
+ contentType: t.name,
953
+ id: n,
954
+ expected: a,
955
+ actual: String(o.revisionId)
956
+ });
957
+ let [s] = await li(e, t, n, i);
958
+ if (s === void 0 || s.action !== "requested" || s.revisionId !== a) throw new rt({
959
+ contentType: t.name,
960
+ id: n,
961
+ reason: "notInReview"
962
+ });
963
+ return {
964
+ draft: o,
965
+ request: s
966
+ };
967
+ }, pi = async (e, t, n, r, i) => {
968
+ let { draft: a, request: o } = await fi(e, t, n, r, i.revisionId);
969
+ if (i.allowSelfApproval !== !0 && o.actorId === i.actorId) throw new rt({
970
+ contentType: t.name,
971
+ id: n,
972
+ reason: "selfApproval"
973
+ });
974
+ return ui(e, t, a, r, "approved", i.actorId, i.note);
975
+ }, mi = async (e, t, n, r, i) => {
976
+ let { draft: a } = await fi(e, t, n, r, i.revisionId);
977
+ return ui(e, t, a, r, "changesRequested", i.actorId, i.note);
978
+ }, hi = async (e, t, n, r) => {
979
+ let i = await ci(e, t, n, r), [a] = await li(e, t, n, r);
980
+ if (a === void 0) return {
981
+ state: "none",
982
+ revisionId: null,
983
+ stale: !1,
984
+ lastStep: null
985
+ };
986
+ let o = a.revisionId !== i.revisionId;
987
+ return {
988
+ state: o ? "none" : a.action === "requested" ? "inReview" : a.action === "approved" ? "approved" : "changesRequested",
989
+ revisionId: a.revisionId,
990
+ stale: o,
991
+ lastStep: a
992
+ };
993
+ }, gi = async (e, t, n) => {
994
+ let r = t.review?.required;
995
+ if (r !== "workspace") return r === !0;
996
+ let [i] = n === void 0 ? [] : await e.query({
997
+ table: `${t.name}_drafts`,
998
+ predicate: S("id", n),
291
999
  order: [],
292
1000
  take: 1,
293
1001
  skip: void 0,
294
1002
  projection: void 0
295
- });
296
- if (a[0] === void 0) throw new d({
1003
+ }), a = i?.tenantId;
1004
+ return typeof a == "string" && (await Br(e, a)).includes(t.name);
1005
+ }, _i = async (e, t, n, r, i) => {
1006
+ if (await gi(e, t, n) && (await e.query({
1007
+ table: "cms_reviews",
1008
+ predicate: x(S("contentType", t.name), S("variantId", n), S("revisionId", i), S("action", "approved"), ...si(r)),
1009
+ order: [],
1010
+ take: 1,
1011
+ skip: void 0,
1012
+ projection: void 0
1013
+ })).length === 0) throw new v({
297
1014
  contentType: t.name,
298
1015
  id: n,
299
- stage: "draft"
1016
+ revisionId: i
300
1017
  });
301
- return await e.update(i, n, { publishAt: r }) ?? a[0];
302
- }, Te = (e, t) => ({
303
- table: J(e),
304
- predicate: f(v("publishAt", t), h("status", "draft")),
305
- order: [],
1018
+ }, vi = (...e) => j(() => li(...e)), yi = (...e) => j(() => di(...e), y), bi = (...e) => j(() => pi(...e), y, r, rt), xi = (...e) => j(() => mi(...e), y, r, rt), Si = (...e) => j(() => hi(...e), y), Ci = (...e) => j(() => gi(...e)), wi = (...e) => j(() => _i(...e), v), Ti = "cms_quality_exceptions", Ei = 90, Di = D(Ti, {
1019
+ id: C({ prefix: "cqex" }),
1020
+ site: O().maxLength(64),
1021
+ environment: O().maxLength(64),
1022
+ locale: O().maxLength(64),
1023
+ contentType: O().maxLength(64),
1024
+ variantId: O().maxLength(64),
1025
+ ruleId: O().maxLength(64),
1026
+ reason: O(),
1027
+ status: O().oneOf([
1028
+ "requested",
1029
+ "approved",
1030
+ "rejected",
1031
+ "withdrawn"
1032
+ ]),
1033
+ requestedBy: O(),
1034
+ requestedAt: k(),
1035
+ decidedBy: O().nullable(),
1036
+ decidedAt: k().nullable(),
1037
+ note: O().nullable(),
1038
+ expiresAt: k()
1039
+ }).with(A()).index("cms_quality_exceptions_by_variant", [
1040
+ "contentType",
1041
+ "variantId",
1042
+ "ruleId"
1043
+ ]), Oi = (e, t) => (e.quality ?? []).filter((e) => e.check(t)).map((e) => ({
1044
+ ruleId: e.id,
1045
+ field: e.field,
1046
+ message: e.message,
1047
+ blocking: e.blocking !== !1
1048
+ })), ki = (e) => e instanceof Date ? e : new Date(String(e)), Ai = (e, t) => {
1049
+ let n = ki(e.expiresAt), r = String(e.status);
1050
+ return {
1051
+ id: String(e.id),
1052
+ ruleId: String(e.ruleId),
1053
+ reason: String(e.reason),
1054
+ state: (r === "approved" || r === "requested") && n.getTime() <= t.getTime() ? "expired" : r,
1055
+ requestedBy: String(e.requestedBy),
1056
+ requestedAt: ki(e.requestedAt),
1057
+ decidedBy: typeof e.decidedBy == "string" ? e.decidedBy : null,
1058
+ note: typeof e.note == "string" ? e.note : null,
1059
+ expiresAt: n
1060
+ };
1061
+ }, ji = (e, t, n) => [
1062
+ S("contentType", e.name),
1063
+ S("variantId", t),
1064
+ S("site", n.site),
1065
+ S("environment", n.environment),
1066
+ S("locale", n.locale)
1067
+ ], Mi = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => (await e.query({
1068
+ table: Ti,
1069
+ predicate: x(...ji(t, n, r)),
1070
+ order: [{
1071
+ column: "requestedAt",
1072
+ direction: "desc"
1073
+ }],
306
1074
  take: void 0,
307
1075
  skip: void 0,
308
1076
  projection: void 0
309
- }), X = async (e, t, n = /* @__PURE__ */ new Date()) => {
310
- let r = await e.query(Te(t, n)), i = [];
311
- for (let n of r) {
312
- let r = n.id;
313
- typeof r == "string" && (await U(e, t, r), await e.update(J(t), r, { publishAt: null }), i.push(r));
314
- }
315
- return i;
316
- }, Z = (e, t, n, r) => C.tryPromise({
317
- try: () => Y(e, t, n, r),
318
- catch: (e) => e
319
- }).pipe(C.catchAll((e) => e instanceof d ? C.fail(e) : C.die(e))), Ee = (e, t, n = /* @__PURE__ */ new Date()) => C.promise(() => X(e, t, n)), De = (e) => Object.entries(e.fields).filter(([, e]) => e.kind === "media").map(([e]) => e), Q = async (e, t, n) => {
320
- if (t == null) return t;
321
- switch (e.kind) {
322
- case "media": return typeof t == "string" ? await n(t) ?? t : t;
323
- case "array": {
324
- let r = e.element;
325
- return r === void 0 || !Array.isArray(t) ? t : Promise.all(t.map((e) => Q(r, e, n)));
326
- }
327
- case "struct": {
328
- let r = e.struct;
329
- if (r === void 0 || typeof t != "object" || Array.isArray(t)) return t;
330
- let i = t, a = { ...i };
331
- for (let [e, t] of Object.entries(r)) e in i && (a[e] = await Q(t, i[e], n));
332
- return a;
333
- }
334
- default: return t;
335
- }
336
- }, $ = async (e, t, n) => {
337
- let r = { ...t };
338
- for (let [i, a] of Object.entries(e.fields)) {
339
- let e = a;
340
- (e.kind === "media" || e.kind === "array" || e.kind === "struct") && i in t && (r[i] = await Q(e, t[i], n));
341
- }
342
- return r;
343
- }, Oe = async (e, t, n) => Promise.all(t.map((t) => $(e, t, n))), ke = (e) => De(e), Ae = "/v1/cms/", je = (e) => {
344
- let t = e.authorization;
345
- return t && t.toLowerCase().startsWith("bearer ") ? t.slice(7).trim() : e["x-api-key"];
346
- }, Me = async (e, t) => {
347
- if (e.method.toUpperCase() !== "GET") return {
348
- status: 405,
349
- body: { error: "method_not_allowed" }
1077
+ })).map((e) => Ai(e, i)), Ni = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1078
+ let o = (t.quality ?? []).find((e) => e.id === i.ruleId);
1079
+ if (o === void 0) return {
1080
+ ok: !1,
1081
+ reason: "unknownRule"
350
1082
  };
351
- if (!e.path.startsWith(Ae)) return {
352
- status: 404,
353
- body: { error: "not_found" }
1083
+ if (o.blocking === !1) return {
1084
+ ok: !1,
1085
+ reason: "notBlocking"
354
1086
  };
355
- let n = je(e.headers), r = n ? t.apiKeys.find((e) => e.key === n) : void 0;
356
- if (!r) return {
357
- status: 401,
358
- body: { error: "unauthorized" }
1087
+ let s = i.reason.trim();
1088
+ if (s === "" || s.length > 500) return {
1089
+ ok: !1,
1090
+ reason: "noReason"
359
1091
  };
360
- let i = e.path.slice(8).split("/").filter((e) => e.length > 0), a = i[0];
361
- if (!a || !t.types.some((e) => e.name === a)) return {
362
- status: 404,
363
- body: { error: "unknown_content_type" }
1092
+ let c = (i.expiresAt.getTime() - a.getTime()) / 864e5;
1093
+ if (!(c > 0) || c > 90) return {
1094
+ ok: !1,
1095
+ reason: "badExpiry"
364
1096
  };
365
- if (!(r.types === void 0 || r.types.includes("*") || r.types.includes(a))) return {
366
- status: 403,
367
- body: {
368
- error: "forbidden",
369
- type: a
370
- }
1097
+ let [l] = await e.query({
1098
+ table: `${t.name}_drafts`,
1099
+ predicate: x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)),
1100
+ order: [],
1101
+ take: 1,
1102
+ skip: void 0,
1103
+ projection: void 0
1104
+ });
1105
+ if (l === void 0) throw new y({
1106
+ contentType: t.name,
1107
+ id: n,
1108
+ stage: "draft"
1109
+ });
1110
+ if ((await Mi(e, t, n, r, a)).some((e) => e.ruleId === o.id && (e.state === "requested" || e.state === "approved"))) return {
1111
+ ok: !1,
1112
+ reason: "alreadyOpen"
371
1113
  };
372
- if (i.length >= 2) {
373
- let e = i.slice(1).join("/"), n = await t.cms.contentType(a).where("slug", "=", e).one();
374
- return n ? {
375
- status: 200,
376
- body: n
377
- } : {
378
- status: 404,
379
- body: {
380
- error: "not_found",
381
- type: a,
382
- slug: e
383
- }
384
- };
1114
+ let u = l.tenantId, d = await e.insert(Ti, {
1115
+ site: r.site,
1116
+ environment: r.environment,
1117
+ locale: r.locale,
1118
+ contentType: t.name,
1119
+ variantId: n,
1120
+ ruleId: o.id,
1121
+ reason: s,
1122
+ status: "requested",
1123
+ requestedBy: i.actorId,
1124
+ requestedAt: a,
1125
+ decidedBy: null,
1126
+ decidedAt: null,
1127
+ note: null,
1128
+ expiresAt: i.expiresAt,
1129
+ ...u == null ? {} : { tenantId: u }
1130
+ });
1131
+ return {
1132
+ ok: !0,
1133
+ id: String(d.id)
1134
+ };
1135
+ }, Pi = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1136
+ let [i] = await e.query({
1137
+ table: Ti,
1138
+ predicate: S("id", t),
1139
+ order: [],
1140
+ take: 1,
1141
+ skip: void 0,
1142
+ projection: void 0
1143
+ });
1144
+ if (i === void 0) return {
1145
+ ok: !1,
1146
+ reason: "notFound"
1147
+ };
1148
+ let a = Ai(i, r), o = n.note !== void 0 && n.note.trim() !== "" ? n.note.trim().slice(0, 500) : null;
1149
+ if (n.decision === "withdraw") return a.state === "requested" && a.requestedBy !== n.actorId ? {
1150
+ ok: !1,
1151
+ reason: "notRequester"
1152
+ } : a.state !== "requested" && a.state !== "approved" ? {
1153
+ ok: !1,
1154
+ reason: "notOpen"
1155
+ } : (await e.update(Ti, t, {
1156
+ status: "withdrawn",
1157
+ decidedBy: n.actorId,
1158
+ decidedAt: r,
1159
+ note: o
1160
+ }), {
1161
+ ok: !0,
1162
+ state: "withdrawn"
1163
+ });
1164
+ if (a.state !== "requested") return {
1165
+ ok: !1,
1166
+ reason: "notOpen"
1167
+ };
1168
+ if (a.requestedBy === n.actorId) return {
1169
+ ok: !1,
1170
+ reason: "selfApproval"
1171
+ };
1172
+ let s = n.decision === "approve" ? "approved" : "rejected";
1173
+ return await e.update(Ti, t, {
1174
+ status: s,
1175
+ decidedBy: n.actorId,
1176
+ decidedAt: r,
1177
+ note: o
1178
+ }), {
1179
+ ok: !0,
1180
+ state: s
1181
+ };
1182
+ }, Fi = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1183
+ let o = Oi(t, i).filter((e) => e.blocking);
1184
+ if (o.length === 0) return [];
1185
+ let s = new Set((await Mi(e, t, n, r, a)).filter((e) => e.state === "approved").map((e) => e.ruleId));
1186
+ return o.filter((e) => !s.has(e.ruleId)).map((e) => ({
1187
+ field: e.field,
1188
+ rule: `quality.${e.ruleId}`,
1189
+ message: e.message
1190
+ }));
1191
+ }, Ii = (...e) => j(() => Mi(...e)), Li = (...e) => j(() => Ni(...e), y), Ri = (...e) => j(() => Pi(...e)), zi = (...e) => j(() => Fi(...e)), Bi = "cms_availability", Vi = D(Bi, {
1192
+ id: C({ prefix: "cavl" }),
1193
+ contentType: O().maxLength(64),
1194
+ documentId: O().maxLength(64),
1195
+ site: O().maxLength(64),
1196
+ environment: O().maxLength(64),
1197
+ availableUntil: k().nullable(),
1198
+ blocked: Ft().default(!1)
1199
+ }).with(A()).index("cms_availability_by_document", [
1200
+ "documentId",
1201
+ "site",
1202
+ "environment"
1203
+ ]), Hi = (e) => {
1204
+ if (e instanceof Date) return e;
1205
+ if (typeof e == "string" && e !== "") {
1206
+ let t = new Date(e);
1207
+ return Number.isNaN(t.getTime()) ? null : t;
385
1208
  }
386
- let o = t.defaultLimit ?? 20, s = t.maxLimit ?? 100, c = Number(e.query?.limit), l = Number.isFinite(c) && c > 0 ? Math.min(c, s) : o;
1209
+ return null;
1210
+ }, Ui = async (e, t, n, r) => {
1211
+ let i = t.availability;
1212
+ if (i === void 0) return;
1213
+ let a = {
1214
+ availableUntil: i.until === void 0 ? null : Hi(n[i.until]),
1215
+ blocked: i.blocked !== void 0 && n[i.blocked] === !0
1216
+ }, [o] = await e.query({
1217
+ table: Bi,
1218
+ predicate: x(S("contentType", t.name), S("documentId", n.documentId), S("site", r.site), S("environment", r.environment)),
1219
+ order: [],
1220
+ take: 1,
1221
+ skip: void 0,
1222
+ projection: void 0
1223
+ });
1224
+ if (o !== void 0) {
1225
+ await e.update(Bi, o.id, a);
1226
+ return;
1227
+ }
1228
+ let s = n.tenantId;
1229
+ await e.insert(Bi, {
1230
+ contentType: t.name,
1231
+ documentId: n.documentId,
1232
+ site: r.site,
1233
+ environment: r.environment,
1234
+ ...a,
1235
+ ...s == null ? {} : { tenantId: s }
1236
+ });
1237
+ }, Wi = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1238
+ let i = /* @__PURE__ */ new Map(), a = [...new Set(t)];
1239
+ if (a.length === 0) return i;
1240
+ let o = await e.query({
1241
+ table: Bi,
1242
+ predicate: x(Vt("documentId", a), S("site", n.site), S("environment", n.environment)),
1243
+ order: [],
1244
+ take: void 0,
1245
+ skip: void 0,
1246
+ projection: void 0
1247
+ });
1248
+ for (let e of o) {
1249
+ let t = Hi(e.availableUntil);
1250
+ e.blocked === !0 ? i.set(e.documentId, "blocked") : t !== null && t.getTime() <= r.getTime() && i.set(e.documentId, "expired");
1251
+ }
1252
+ return i;
1253
+ }, Gi = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1254
+ let o = rr(t, r);
1255
+ if (o.length === 0) return;
1256
+ let s = await Wi(e, o.map((e) => e.targetDocumentId), i, a);
1257
+ if (s.size !== 0) throw new d({
1258
+ contentType: t.name,
1259
+ id: n,
1260
+ targets: o.filter((e) => s.has(e.targetDocumentId)).map((e) => ({
1261
+ path: e.path,
1262
+ contentType: e.targetType,
1263
+ documentId: e.targetDocumentId,
1264
+ reason: s.get(e.targetDocumentId)
1265
+ }))
1266
+ });
1267
+ }, Ki = [d], qi = (...e) => j(() => Gi(...e), ...Ki), Ji = (...e) => j(() => Wi(...e), ...Ki), Yi = (...e) => j(() => Ui(...e), ...Ki), F = "cms_draft_texts", Xi = D(F, {
1268
+ id: C({ prefix: "cdtx" }),
1269
+ contentType: O().maxLength(64),
1270
+ draftId: O(),
1271
+ field: O(),
1272
+ baseRevision: O(),
1273
+ state: It()
1274
+ }).with(A()).unique("cms_draft_texts_uq_field", [
1275
+ "tenantId",
1276
+ "draftId",
1277
+ "field"
1278
+ ]), Zi = (e) => Object.entries(e.fields).filter(([t, n]) => t !== e.templates?.field && n.kind === "string" && (n.editorHint === "text" || n.editorHint === "textarea") && n.derived === void 0 && n.literals === void 0 && n.unique !== !0).map(([e]) => e), Qi = (e, t) => /* @__PURE__ */ new Set([...t, ...Object.entries(e.fields).filter(([, e]) => e.derived !== void 0 && t.has(e.derived.source)).map(([e]) => e)]), $i = (e, t, n) => e.query({
1279
+ table: t,
1280
+ predicate: n,
1281
+ order: [],
1282
+ take: void 0,
1283
+ skip: void 0,
1284
+ projection: void 0
1285
+ }), ea = async (e, t, n) => {
1286
+ let [r] = await $i(e, `${t.name}_drafts`, S("id", n));
1287
+ if (r === void 0) throw new y({
1288
+ contentType: t.name,
1289
+ id: n,
1290
+ stage: "draft"
1291
+ });
1292
+ return r;
1293
+ }, ta = (e, t) => $i(e, F, S("draftId", t)), na = async (e, t, n) => {
1294
+ let r = await ea(e, t, n), i = String(r.revisionId), a = new Map((await ta(e, n)).map((e) => [String(e.field), e])), o = r.tenantId !== void 0 && r.tenantId !== null ? { tenantId: r.tenantId } : {};
1295
+ for (let s of Zi(t)) {
1296
+ let c = a.get(s);
1297
+ if (c?.baseRevision === i) continue;
1298
+ c !== void 0 && await e.delete(F, String(c.id));
1299
+ let l = r[s];
1300
+ await e.insertIgnore(F, {
1301
+ contentType: t.name,
1302
+ draftId: n,
1303
+ field: s,
1304
+ baseRevision: i,
1305
+ state: Qt(typeof l == "string" ? l : "").encode(),
1306
+ ...o
1307
+ }, { conflictColumns: [
1308
+ "tenantId",
1309
+ "draftId",
1310
+ "field"
1311
+ ] });
1312
+ }
1313
+ return ta(e, n);
1314
+ }, ra = async (e, t, n) => {
1315
+ let [r] = await $i(e, F, S("id", t));
1316
+ if (r === void 0) throw new y({
1317
+ contentType: F,
1318
+ id: t,
1319
+ stage: "draft"
1320
+ });
1321
+ let i = r.state instanceof Uint8Array ? r.state : /* @__PURE__ */ new Uint8Array();
1322
+ return await e.update("cms_draft_texts", t, { state: i.length === 0 ? n : en(i, n) }) ?? r;
1323
+ }, ia = async (e, t) => {
1324
+ let n = (await ta(e, String(t.id))).filter((e) => e.baseRevision === t.revisionId);
387
1325
  return {
388
- status: 200,
389
- body: await t.cms.contentType(a).limit(l).all()
1326
+ values: new Map(n.map((e) => [String(e.field), e.state instanceof Uint8Array && e.state.length > 0 ? $t(e.state) : ""])),
1327
+ rows: n
390
1328
  };
391
- };
1329
+ }, aa = async (e, t, n) => {
1330
+ for (let r of t) await e.update(F, String(r.id), { baseRevision: n });
1331
+ }, oa = [y], sa = (...e) => j(() => ia(...e), ...oa), ca = (...e) => j(() => na(...e), ...oa), la = (...e) => j(() => ta(...e), ...oa), ua = (...e) => j(() => aa(...e), ...oa), da = (...e) => j(() => ra(...e), ...oa), fa = (e, t, n) => e.query({
1332
+ table: t,
1333
+ predicate: n,
1334
+ order: [],
1335
+ take: void 0,
1336
+ skip: void 0,
1337
+ projection: void 0
1338
+ }), pa = 500, ma = async (e, t, n, r, ...i) => {
1339
+ let a = [];
1340
+ for (let o = 0; o < r.length; o += pa) a.push(...await fa(e, t, x(Vt(n, r.slice(o, o + pa)), ...i)));
1341
+ return a;
1342
+ }, ha = async (e, t, n, r, i, a) => (await ga(e, t, [n], r, i, a)).get(n), ga = async (e, t, n, r, i, a) => {
1343
+ let o = [...new Set(n)], s = await ma(e, `${t.name}_drafts`, "documentId", o, S("site", r.site), S("environment", r.environment)), c = /* @__PURE__ */ new Map();
1344
+ for (let e of s) {
1345
+ let t = String(e.documentId);
1346
+ c.set(t, (c.get(t) ?? /* @__PURE__ */ new Map()).set(String(e.locale), e));
1347
+ }
1348
+ let l = await ma(e, M, "id", [...new Set(s.map((e) => String(e.revisionId)))]), u = new Map(l.map((e) => [String(e.id), e])), d = [...new Set(l.map((e) => e.basedOn).filter((e) => typeof e == "string"))], f = new Map((await ma(e, M, "id", d)).map((e) => [String(e.id), e])), p = (e) => {
1349
+ let n = e.get(i), r = n === void 0 ? void 0 : u.get(String(n.revisionId)), o = a.filter((e) => e !== i).map((i) => {
1350
+ let a = e.get(i);
1351
+ if (a === void 0) return {
1352
+ locale: i,
1353
+ state: "missing",
1354
+ variantId: null,
1355
+ changed: []
1356
+ };
1357
+ let o = String(a.id), s = u.get(String(a.revisionId))?.basedOn;
1358
+ if (typeof s != "string" || n === void 0) return {
1359
+ locale: i,
1360
+ state: "unknown",
1361
+ variantId: o,
1362
+ changed: []
1363
+ };
1364
+ if (s === n.revisionId) return {
1365
+ locale: i,
1366
+ state: "upToDate",
1367
+ variantId: o,
1368
+ changed: []
1369
+ };
1370
+ let c = f.get(s);
1371
+ return {
1372
+ locale: i,
1373
+ state: "outdated",
1374
+ variantId: o,
1375
+ changed: c === void 0 || r === void 0 ? [] : Ze(t.fields, c.values ?? {}, r.values ?? {})
1376
+ };
1377
+ });
1378
+ return {
1379
+ source: n === void 0 ? null : {
1380
+ variantId: String(n.id),
1381
+ revisionId: String(n.revisionId)
1382
+ },
1383
+ targets: o
1384
+ };
1385
+ };
1386
+ return new Map(o.map((e) => [e, p(c.get(e) ?? /* @__PURE__ */ new Map())]));
1387
+ }, _a = (...e) => j(() => ha(...e)), va = (...e) => j(() => ga(...e)), ya = "cms_stewardship", ba = D(ya, {
1388
+ id: C({ prefix: "cstw" }),
1389
+ contentType: O().maxLength(64),
1390
+ documentId: O().maxLength(64),
1391
+ site: O().maxLength(64),
1392
+ environment: O().maxLength(64),
1393
+ owner: O().nullable(),
1394
+ reviewDue: k().nullable(),
1395
+ reviewedAt: k().nullable(),
1396
+ reviewedBy: O().nullable(),
1397
+ reviewedRevision: O().nullable()
1398
+ }).with(A()).index("cms_stewardship_by_document", [
1399
+ "contentType",
1400
+ "documentId",
1401
+ "site",
1402
+ "environment"
1403
+ ]), xa = 864e5, Sa = (e, t, n, r) => e.query({
1404
+ table: t,
1405
+ predicate: n,
1406
+ order: [],
1407
+ take: r,
1408
+ skip: void 0,
1409
+ projection: void 0
1410
+ }), Ca = (e) => {
1411
+ if (e instanceof Date) return e;
1412
+ if (typeof e == "string" || typeof e == "number") {
1413
+ let t = new Date(e);
1414
+ return Number.isNaN(t.getTime()) ? null : t;
1415
+ }
1416
+ return null;
1417
+ }, wa = (e) => typeof e == "string" && e !== "" ? e : null, Ta = async (e, t, n, r) => (await Sa(e, ya, x(S("contentType", t), S("documentId", n), S("site", r.site), S("environment", r.environment)), 1))[0], Ea = (e, t) => e === null ? "notRequired" : e.getTime() <= t.getTime() ? "due" : "scheduled", Da = (e, t) => {
1418
+ let n = Ca(e?.reviewDue);
1419
+ return {
1420
+ owner: wa(e?.owner),
1421
+ reviewDue: n,
1422
+ reviewedAt: Ca(e?.reviewedAt),
1423
+ reviewedBy: wa(e?.reviewedBy),
1424
+ reviewedRevision: wa(e?.reviewedRevision),
1425
+ review: Ea(n, t)
1426
+ };
1427
+ }, Oa = async (e, t, n, r, i, a) => {
1428
+ let o = await Ta(e, t.name, n, r);
1429
+ if (o !== void 0) return await e.update("cms_stewardship", String(o.id), i) ?? o;
1430
+ let s = a == null ? {} : { tenantId: a };
1431
+ return e.insert(ya, {
1432
+ contentType: t.name,
1433
+ documentId: n,
1434
+ site: r.site,
1435
+ environment: r.environment,
1436
+ owner: null,
1437
+ reviewDue: null,
1438
+ reviewedAt: null,
1439
+ reviewedBy: null,
1440
+ reviewedRevision: null,
1441
+ ...i,
1442
+ ...s
1443
+ });
1444
+ }, ka = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1445
+ let o = t.lifecycle;
1446
+ if (o === void 0) return;
1447
+ let s = await Ta(e, t.name, n, r);
1448
+ (s === void 0 || s.reviewDue == null) && await Oa(e, t, n, r, { reviewDue: new Date(a.getTime() + o.reviewEveryDays * xa) }, i);
1449
+ }, Aa = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => Da(await Ta(e, t.name, n, r), i), ja = async (e, t, n, r, i) => Da(await Oa(e, t, n, r, { owner: i }), /* @__PURE__ */ new Date()), Ma = async (e, t, n, r, i) => {
1450
+ let a = i.now ?? /* @__PURE__ */ new Date();
1451
+ return Da(await Oa(e, t, n, r, {
1452
+ reviewDue: t.lifecycle === void 0 ? null : new Date(a.getTime() + t.lifecycle.reviewEveryDays * xa),
1453
+ reviewedAt: a,
1454
+ reviewedBy: i.by,
1455
+ reviewedRevision: i.revisionId
1456
+ }), a);
1457
+ }, Na = async (e, t, n, r) => {
1458
+ let i = r.now ?? /* @__PURE__ */ new Date(), a = [S("site", n.site), S("environment", n.environment)], o = [], s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
1459
+ for (let n of t) {
1460
+ let t = /* @__PURE__ */ new Map();
1461
+ for (let i of await Sa(e, `${n.name}_published`, x(...a, E("status", "archived")))) {
1462
+ let e = String(i.documentId), a = String(i.locale);
1463
+ t.set(e, (t.get(e) ?? /* @__PURE__ */ new Set()).add(a));
1464
+ let o = wa(i.title) ?? wa(i.name) ?? wa(i.slug) ?? e;
1465
+ (a === r.sourceLocale || !c.has(`${n.name}:${e}`)) && c.set(`${n.name}:${e}`, o);
1466
+ }
1467
+ s.set(n.name, t);
1468
+ }
1469
+ let l = (e, t) => c.get(`${e}:${t}`) ?? t, u = new Map((await Sa(e, ya, x(...a))).map((e) => [`${String(e.contentType)}:${String(e.documentId)}`, e]));
1470
+ for (let a of t) {
1471
+ let t = s.get(a.name) ?? /* @__PURE__ */ new Map(), c = await ga(e, a, [...t].filter(([, e]) => e.has(r.sourceLocale)).map(([e]) => e), n, r.sourceLocale, r.locales);
1472
+ for (let [e, n] of t) {
1473
+ let t = Da(u.get(`${a.name}:${e}`), i), s = {
1474
+ contentType: a.name,
1475
+ documentId: e,
1476
+ title: l(a.name, e)
1477
+ };
1478
+ if (t.owner === null && o.push({
1479
+ ...s,
1480
+ kind: "noOwner",
1481
+ locale: null,
1482
+ detail: []
1483
+ }), t.review === "due" && o.push({
1484
+ ...s,
1485
+ kind: "reviewDue",
1486
+ locale: null,
1487
+ detail: []
1488
+ }), n.has(r.sourceLocale)) for (let t of c.get(e)?.targets ?? []) t.state === "missing" && o.push({
1489
+ ...s,
1490
+ kind: "translationMissing",
1491
+ locale: t.locale,
1492
+ detail: []
1493
+ }), t.state === "outdated" && o.push({
1494
+ ...s,
1495
+ kind: "translationOutdated",
1496
+ locale: t.locale,
1497
+ detail: [...t.changed]
1498
+ });
1499
+ }
1500
+ }
1501
+ let d = /* @__PURE__ */ new Map();
1502
+ for (let t of await Sa(e, er, x(...a))) {
1503
+ let e = s.get(String(t.targetType)), n = String(t.sourceType);
1504
+ if (e === void 0 || !s.has(n)) continue;
1505
+ let r = String(t.locale);
1506
+ if (e.get(String(t.targetDocumentId))?.has(r) === !0) continue;
1507
+ let i = String(t.sourceDocumentId), a = `${n}:${i}:${r}`, o = d.get(a) ?? {
1508
+ type: n,
1509
+ doc: i,
1510
+ locale: r,
1511
+ paths: []
1512
+ };
1513
+ o.paths.push(String(t.path)), d.set(a, o);
1514
+ }
1515
+ for (let e of d.values()) o.push({
1516
+ kind: "linksToUnpublished",
1517
+ contentType: e.type,
1518
+ documentId: e.doc,
1519
+ locale: e.locale,
1520
+ title: l(e.type, e.doc),
1521
+ detail: e.paths
1522
+ });
1523
+ return o;
1524
+ }, Pa = (...e) => j(() => Na(...e)), Fa = (...e) => j(() => Ma(...e)), Ia = (...e) => j(() => ja(...e)), La = (...e) => j(() => ka(...e)), Ra = (...e) => j(() => Aa(...e)), I = (e) => `${e.name}_drafts`, za = (e) => `${e.name}_published`, Ba = (e) => ({
1525
+ site: e.site,
1526
+ environment: e.environment,
1527
+ locale: e.locale
1528
+ }), Va = (e) => [
1529
+ S("site", e.site),
1530
+ S("environment", e.environment),
1531
+ S("locale", e.locale)
1532
+ ], Ha = (e, t, n, r) => ({
1533
+ table: e,
1534
+ predicate: r === void 0 ? S("id", t) : x(S("id", t), ...Va(r)),
1535
+ order: [],
1536
+ take: 1,
1537
+ skip: void 0,
1538
+ projection: void 0,
1539
+ ...n === !0 ? { crossTenant: !0 } : {}
1540
+ }), L = async (e, t, n, r) => (await e.query(Ha(t, n, !1, r)))[0], R = (e, t) => {
1541
+ let n = {};
1542
+ for (let r of Object.keys(e.fields)) r in t && (n[r] = t[r]);
1543
+ return n;
1544
+ }, Ua = async (e, t, n, r, i) => {
1545
+ let a = t.tree;
1546
+ if (a === void 0) return;
1547
+ let o = Object.entries(a.inherit ?? {}).filter(([e, t]) => t.locked === !0 && n[e] !== void 0 && n[e] !== null && n[e] !== "");
1548
+ if (o.length > 0) throw new s({
1549
+ contentType: t.name,
1550
+ violations: o.map(([e]) => ({
1551
+ field: e,
1552
+ rule: "locked",
1553
+ message: `${e} is set for the whole site and cannot be changed on a page`
1554
+ }))
1555
+ });
1556
+ let c = n[a.parent];
1557
+ if (typeof c != "string" || c === "") return;
1558
+ let l = (e, n) => {
1559
+ throw new s({
1560
+ contentType: t.name,
1561
+ violations: [{
1562
+ field: a.parent,
1563
+ rule: e,
1564
+ message: n
1565
+ }]
1566
+ });
1567
+ }, u = async (n) => {
1568
+ let r = await e.query({
1569
+ table: I(t),
1570
+ predicate: x(S("documentId", n), S("site", i.site), S("environment", i.environment)),
1571
+ order: [],
1572
+ take: void 0,
1573
+ skip: void 0,
1574
+ projection: void 0
1575
+ });
1576
+ return r.find((e) => e.locale === i.locale) ?? r[0];
1577
+ }, d = /* @__PURE__ */ new Set(), f = c;
1578
+ for (; f !== null && !d.has(f);) {
1579
+ f === r && l("cycle", "the parent is this page or one of its descendants"), d.add(f);
1580
+ let e = await u(f);
1581
+ if (e === void 0) {
1582
+ f === c && l("unknown", `no ${t.name} document '${c}'`);
1583
+ return;
1584
+ }
1585
+ let n = e[a.parent];
1586
+ f = typeof n == "string" && n !== "" ? n : null;
1587
+ }
1588
+ }, Wa = () => {
1589
+ let e = Rt({
1590
+ kind: "typeid",
1591
+ prefix: "cdoc"
1592
+ }, M);
1593
+ if (e === null) throw Error("[voltro cms] the document id scheme did not mint an id.");
1594
+ return e;
1595
+ }, Ga = /* @__PURE__ */ new WeakMap(), Ka = (e) => {
1596
+ let t = Ga.get(e);
1597
+ t === void 0 && (t = In(e).draft.fields.id.idScheme, Ga.set(e, t));
1598
+ let n = t === void 0 ? null : Rt(t, I(e));
1599
+ if (n === null) throw Error(`[voltro cms] '${e.name}': the drafts table's id scheme does not mint ids up front.`);
1600
+ return n;
1601
+ }, qa = (e, t, n, r, i, a, o, s = null) => e.insert(M, {
1602
+ contentType: t.name,
1603
+ documentId: n,
1604
+ number: r,
1605
+ ...Ba(a),
1606
+ values: i,
1607
+ basedOn: s,
1608
+ ...o == null ? {} : { tenantId: o }
1609
+ }), Ja = (e, t, n, r) => e.query({
1610
+ table: M,
1611
+ predicate: x(S("contentType", t.name), S("documentId", n), ...Va(r)),
1612
+ order: [{
1613
+ column: "number",
1614
+ direction: "desc"
1615
+ }],
1616
+ take: void 0,
1617
+ skip: void 0,
1618
+ projection: void 0
1619
+ }), Ya = async (e, t) => {
1620
+ if (typeof t != "string" || t === "") return null;
1621
+ let [n] = await e.query({
1622
+ table: M,
1623
+ predicate: S("id", t),
1624
+ order: [],
1625
+ take: 1,
1626
+ skip: void 0,
1627
+ projection: void 0
1628
+ });
1629
+ return typeof n?.basedOn == "string" ? n.basedOn : null;
1630
+ }, Xa = async (e, t, n, r, i) => {
1631
+ if (i === void 0 || i.values.size === 0) return !1;
1632
+ let [a] = await e.query({
1633
+ table: M,
1634
+ predicate: S("id", n),
1635
+ order: [],
1636
+ take: 1,
1637
+ skip: void 0,
1638
+ projection: void 0
1639
+ });
1640
+ if (a === void 0) return !1;
1641
+ let o = Qi(t, new Set(i.values.keys()));
1642
+ return Ze(t.fields, a.values ?? {}, r).every((e) => o.has(e));
1643
+ }, Za = async (e, t, n, i, a = {}) => {
1644
+ let o = a.collaborative === !0 && typeof n.id == "string" ? await L(e, I(t), n.id, i) : void 0;
1645
+ if (o !== void 0) {
1646
+ let t = new Set((await ta(e, String(o.id))).map((e) => String(e.id)));
1647
+ for (let n of a.texts ?? []) t.has(n.id) && await ra(e, n.id, n.update);
1648
+ }
1649
+ let c = o === void 0 ? void 0 : await ia(e, o), l = c === void 0 ? [] : [...c.values].filter(([e, t]) => t !== "" || typeof o?.[e] == "string"), u = Ue(t, {
1650
+ ...n,
1651
+ ...Object.fromEntries(l)
1652
+ });
1653
+ st(t, u);
1654
+ let d = je(t, u);
1655
+ if (d.length > 0) throw new s({
1656
+ contentType: t.name,
1657
+ violations: [...d]
1658
+ });
1659
+ let f = I(t), p = R(t, u), m = async (n, r) => {
1660
+ await Ua(e, t, p, r, i);
1661
+ let o = await qa(e, t, r, 1, p, i, void 0, a.basedOn ?? null), s = await e.insert(f, {
1662
+ ...p,
1663
+ id: n,
1664
+ documentId: r,
1665
+ ...Ba(i),
1666
+ status: "draft",
1667
+ revisionId: o.id,
1668
+ revision: 1
1669
+ });
1670
+ return await un(e, t, s, i, "draft"), s;
1671
+ }, h = u.id, g = u.documentId;
1672
+ if (h === void 0) {
1673
+ if (g === void 0) return m(Ka(t), Wa());
1674
+ let n = await e.query({
1675
+ table: f,
1676
+ predicate: S("documentId", g),
1677
+ order: [],
1678
+ take: void 0,
1679
+ skip: void 0,
1680
+ projection: void 0
1681
+ });
1682
+ if (n.length === 0) throw new y({
1683
+ contentType: t.name,
1684
+ id: g,
1685
+ stage: "draft"
1686
+ });
1687
+ let r = n.find((e) => e.site === i.site && e.environment === i.environment && e.locale === i.locale);
1688
+ if (r !== void 0) throw new b({
1689
+ contentType: t.name,
1690
+ id: r.id
1691
+ });
1692
+ return m(Ka(t), g);
1693
+ }
1694
+ let _ = await L(e, f, h, i);
1695
+ if (_ !== void 0) {
1696
+ if (a.expectedRevision !== void 0 && _.revisionId !== a.expectedRevision && !await Xa(e, t, a.expectedRevision, _, c)) throw new r({
1697
+ contentType: t.name,
1698
+ id: h,
1699
+ expected: a.expectedRevision,
1700
+ actual: String(_.revisionId)
1701
+ });
1702
+ let n = Number(_.revision) + 1, o = _.documentId;
1703
+ await Ua(e, t, p, o, i);
1704
+ let s = a.basedOn ?? await Ya(e, _.revisionId), l = await qa(e, t, o, n, p, i, _.tenantId, s), u = await e.update(f, h, {
1705
+ ...p,
1706
+ status: "draft",
1707
+ revisionId: l.id,
1708
+ revision: n
1709
+ });
1710
+ return c !== void 0 && await aa(e, c.rows, String(l.id)), await un(e, t, u ?? _, i, "draft"), u ?? _;
1711
+ }
1712
+ if ((await e.query(Ha(f, h, !0))).length > 0) throw new b({
1713
+ contentType: t.name,
1714
+ id: h
1715
+ });
1716
+ return m(h, g ?? Wa());
1717
+ }, Qa = async (e, t, n, r, i) => {
1718
+ let a = await L(e, I(t), n, r);
1719
+ if (a === void 0) throw new y({
1720
+ contentType: t.name,
1721
+ id: n,
1722
+ stage: "draft"
1723
+ });
1724
+ let [o] = await e.query({
1725
+ table: M,
1726
+ predicate: x(S("id", i), S("contentType", t.name), S("documentId", a.documentId), ...Va(r)),
1727
+ order: [],
1728
+ take: 1,
1729
+ skip: void 0,
1730
+ projection: void 0
1731
+ });
1732
+ if (o === void 0) throw new y({
1733
+ contentType: t.name,
1734
+ id: i,
1735
+ stage: "revision"
1736
+ });
1737
+ let s = o.values ?? {}, c = { id: n };
1738
+ for (let e of Object.keys(t.fields)) c[e] = e in s ? s[e] : null;
1739
+ return Za(e, t, c, r);
1740
+ }, $a = (e) => {
1741
+ let t = e.revalidate;
1742
+ if (t !== void 0) {
1743
+ for (let n of t.paths ?? []) Xt(n).catch((t) => {
1744
+ console.warn(`[voltro cms] revalidatePath('${n}') for '${e.name}' failed:`, t);
1745
+ });
1746
+ for (let n of t.tags ?? []) Zt(n).catch((t) => {
1747
+ console.warn(`[voltro cms] revalidateTag('${n}') for '${e.name}' failed:`, t);
1748
+ });
1749
+ }
1750
+ }, eo = async (e, t, n, i, a = {}) => {
1751
+ let o = await L(e, I(t), n, i);
1752
+ if (o === void 0) throw new y({
1753
+ contentType: t.name,
1754
+ id: n,
1755
+ stage: "draft"
1756
+ });
1757
+ let s = o.revisionId;
1758
+ if (a.revisionId !== void 0 && a.revisionId !== s) throw new r({
1759
+ contentType: t.name,
1760
+ id: n,
1761
+ expected: a.revisionId,
1762
+ actual: s
1763
+ });
1764
+ return to(e, t, n, i, s);
1765
+ }, to = async (e, t, n, r, i, a = {}) => {
1766
+ let o = await L(e, I(t), n, r);
1767
+ if (o === void 0) throw new y({
1768
+ contentType: t.name,
1769
+ id: n,
1770
+ stage: "draft"
1771
+ });
1772
+ let [c] = await e.query({
1773
+ table: M,
1774
+ predicate: x(S("id", i), S("contentType", t.name), S("documentId", o.documentId), ...Va(r)),
1775
+ order: [],
1776
+ take: 1,
1777
+ skip: void 0,
1778
+ projection: void 0
1779
+ });
1780
+ if (c === void 0) throw new y({
1781
+ contentType: t.name,
1782
+ id: i,
1783
+ stage: "revision"
1784
+ });
1785
+ let l = mt(t, c.values ?? {}), u = await Fi(e, t, n, r, c.values ?? {});
1786
+ if (l.length + u.length > 0) throw new s({
1787
+ contentType: t.name,
1788
+ violations: [...l, ...u]
1789
+ });
1790
+ await _i(e, t, n, r, i), await Gi(e, t, n, c.values ?? {}, r);
1791
+ let d = za(t), f = {
1792
+ ...R(t, c.values ?? {}),
1793
+ documentId: o.documentId,
1794
+ revisionId: i,
1795
+ revision: c.number
1796
+ }, p = await L(e, d, n, r), m;
1797
+ if (p !== void 0) m = await e.update(d, n, {
1798
+ ...f,
1799
+ status: "published"
1800
+ }) ?? p;
1801
+ else {
1802
+ let t = o.tenantId;
1803
+ m = await e.insert(d, {
1804
+ ...f,
1805
+ id: n,
1806
+ ...Ba(r),
1807
+ status: "published",
1808
+ ...t == null ? {} : { tenantId: t }
1809
+ });
1810
+ }
1811
+ return o.revisionId === i && await e.update(I(t), n, { status: "published" }), await or(e, t, m, r), await Ui(e, t, m, r), await Hn(e, t, r, m.tenantId), await ka(e, t, String(o.documentId), r, m.tenantId), await wr(e, t, m, r, "published", a), await un(e, t, m, r, "published"), m;
1812
+ }, no = async (e, t, n, r, i = {}) => {
1813
+ let a = await L(e, za(t), n, r);
1814
+ if (a === void 0) throw new y({
1815
+ contentType: t.name,
1816
+ id: n,
1817
+ stage: "published"
1818
+ });
1819
+ await wr(e, t, a, r, "unpublished", i), await e.delete(za(t), n), await ar(e, t, n, r), await dn(e, t, n, ["published"]), await L(e, I(t), n, r) !== void 0 && await e.update(I(t), n, { status: "draft" });
1820
+ }, ro = async (e, t, n, r) => {
1821
+ let i = await L(e, I(t), n, r), a = await L(e, za(t), n, r);
1822
+ if (i === void 0 && a === void 0) throw new y({
1823
+ contentType: t.name,
1824
+ id: n,
1825
+ stage: "draft"
1826
+ });
1827
+ i !== void 0 && await e.update(I(t), n, { status: "archived" }), a !== void 0 && (await e.update(za(t), n, { status: "archived" }), await ar(e, t, n, r)), await dn(e, t, n, ["draft", "published"]);
1828
+ }, io = [
1829
+ s,
1830
+ b,
1831
+ y,
1832
+ r
1833
+ ], ao = [
1834
+ y,
1835
+ r,
1836
+ v,
1837
+ d,
1838
+ s
1839
+ ], oo = (e, t, n, r, i = {}) => j(() => Za(e, t, n, r, i), ...io), so = (e, t, n, r, i) => j(() => Qa(e, t, n, r, i), s, y), co = (e, t, n, r, i = {}) => j(() => eo(e, t, n, r, i), ...ao), lo = (e, t, n, r, i, a = {}) => j(() => to(e, t, n, r, i, a), ...ao), uo = (e, t, n, r) => j(() => no(e, t, n, r), y), fo = (e, t, n, r) => j(() => ro(e, t, n, r), y), po = (...e) => j(() => Ja(...e)), z = "cms_releases", B = "cms_release_items", mo = [
1840
+ "draft",
1841
+ "scheduled",
1842
+ "published",
1843
+ "failed"
1844
+ ], ho = D(z, {
1845
+ id: C({ prefix: "crel" }),
1846
+ name: O(),
1847
+ site: O().maxLength(64),
1848
+ environment: O().maxLength(64),
1849
+ status: O().oneOf(mo),
1850
+ scheduledAt: k().nullable(),
1851
+ publishedAt: k().nullable(),
1852
+ rollbackOf: O().nullable(),
1853
+ claimToken: O().nullable(),
1854
+ failure: O().nullable()
1855
+ }).with(A()), go = D(B, {
1856
+ id: C({ prefix: "crit" }),
1857
+ releaseId: O(),
1858
+ contentType: O().maxLength(64),
1859
+ variantId: O().maxLength(64),
1860
+ locale: O().maxLength(64),
1861
+ action: O().oneOf(["publish", "unpublish"]),
1862
+ revisionId: O().nullable(),
1863
+ previousRevisionId: O().nullable(),
1864
+ position: w()
1865
+ }).with(A()).unique("cms_release_items_uq_variant", [
1866
+ "tenantId",
1867
+ "releaseId",
1868
+ "contentType",
1869
+ "variantId"
1870
+ ]), V = (e, t, n, r) => e.query({
1871
+ table: t,
1872
+ predicate: n,
1873
+ order: r === void 0 ? [] : [r],
1874
+ take: void 0,
1875
+ skip: void 0,
1876
+ projection: void 0
1877
+ }), _o = async (e, t) => {
1878
+ let [n] = await V(e, z, S("id", t));
1879
+ if (n === void 0) throw new y({
1880
+ contentType: "release",
1881
+ id: t,
1882
+ stage: "draft"
1883
+ });
1884
+ return n;
1885
+ }, vo = (e, t) => ({
1886
+ site: String(e.site),
1887
+ environment: String(e.environment),
1888
+ locale: t
1889
+ }), yo = (e, t) => e.insert(z, {
1890
+ ...t,
1891
+ status: "draft"
1892
+ }), bo = async (e, t, n) => {
1893
+ let r = await _o(e, t);
1894
+ if (r.status !== "draft") throw new l({
1895
+ id: t,
1896
+ status: String(r.status)
1897
+ });
1898
+ let i = vo(r, n.locale), [a] = await V(e, `${n.type.name}_drafts`, x(S("id", n.id), S("site", i.site), S("environment", i.environment), S("locale", i.locale)));
1899
+ if (a === void 0) throw new y({
1900
+ contentType: n.type.name,
1901
+ id: n.id,
1902
+ stage: "draft"
1903
+ });
1904
+ let o = n.action ?? "publish", s = await V(e, B, x(S("releaseId", t), S("contentType", n.type.name), S("variantId", n.id))), c = {
1905
+ action: o,
1906
+ locale: n.locale,
1907
+ revisionId: o === "publish" ? n.revisionId ?? String(a.revisionId) : null
1908
+ }, [u] = s;
1909
+ if (u !== void 0) return await e.update("cms_release_items", String(u.id), c) ?? u;
1910
+ let d = (await V(e, B, S("releaseId", t))).length;
1911
+ return e.insert(B, {
1912
+ releaseId: t,
1913
+ contentType: n.type.name,
1914
+ variantId: n.id,
1915
+ position: d,
1916
+ ...c
1917
+ });
1918
+ }, xo = async (e, t) => {
1919
+ let [n] = await V(e, z, S("id", t));
1920
+ return n === void 0 ? null : String(n.status);
1921
+ }, So = (e, t) => V(e, B, S("releaseId", t), {
1922
+ column: "position",
1923
+ direction: "asc"
1924
+ }), Co = (e, t) => V(e, z, x(S("site", t.site), S("environment", t.environment)), {
1925
+ column: "createdAt",
1926
+ direction: "desc"
1927
+ }), wo = async (e, t, n, r) => {
1928
+ let [i] = await V(e, `${t}_published`, x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)));
1929
+ return i === void 0 ? null : String(i.revisionId);
1930
+ }, To = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1931
+ let i = await _o(e, n);
1932
+ if (i.status !== "draft" && i.status !== "scheduled") throw new l({
1933
+ id: n,
1934
+ status: String(i.status)
1935
+ });
1936
+ let a = new Map(t.map((e) => [e.name, e]));
1937
+ for (let t of await So(e, n)) {
1938
+ let r = a.get(String(t.contentType));
1939
+ if (r === void 0) throw new y({
1940
+ contentType: String(t.contentType),
1941
+ id: String(t.variantId),
1942
+ stage: "draft"
1943
+ });
1944
+ let o = vo(i, String(t.locale)), s = String(t.variantId), c = await wo(e, r.name, s, o);
1945
+ t.action === "publish" ? await to(e, r, s, o, String(t.revisionId), { releaseId: n }) : c !== null && await no(e, r, s, o, { releaseId: n }), await e.update(B, String(t.id), { previousRevisionId: c });
1946
+ }
1947
+ return await e.update("cms_releases", n, {
1948
+ status: "published",
1949
+ publishedAt: r
1950
+ }) ?? i;
1951
+ }, Eo = async (e, t, n) => {
1952
+ let r = await _o(e, t);
1953
+ if (r.status !== "draft") throw new l({
1954
+ id: t,
1955
+ status: String(r.status)
1956
+ });
1957
+ return await e.update("cms_releases", t, {
1958
+ status: "scheduled",
1959
+ scheduledAt: n
1960
+ }) ?? r;
1961
+ }, Do = async (e, t, n = /* @__PURE__ */ new Date()) => {
1962
+ let r = await V(e, z, x(S("status", "scheduled"), Ut("scheduledAt", n))), i = [];
1963
+ for (let a of r) {
1964
+ let r = String(a.id), o = Rt({
1965
+ kind: "typeid",
1966
+ prefix: "claim"
1967
+ }, "cms_releases") ?? `claim_${Date.now()}`;
1968
+ try {
1969
+ await e.transactional(async (e) => await e.updateMany("cms_releases", { claimToken: o }, { where: x(S("id", r), S("status", "scheduled")) }) === 1 && (await To(e, t, r, n), !0)) && i.push(r);
1970
+ } catch (t) {
1971
+ await e.update(z, r, {
1972
+ status: "failed",
1973
+ failure: Oo(t)
1974
+ });
1975
+ }
1976
+ }
1977
+ return i;
1978
+ }, Oo = (e) => {
1979
+ if (e instanceof d) return `ReferenceUnavailable: ${e.contentType} ${e.id} uses ${e.targets.map((e) => `${e.contentType} ${e.documentId} (${e.reason})`).join(", ")}`;
1980
+ if (e instanceof v) return `ReviewRequired: ${e.contentType} ${e.id} revision ${e.revisionId} is not approved`;
1981
+ if (e instanceof y) return `ContentNotFound: ${e.contentType} ${e.id} (${e.stage})`;
1982
+ let t = e?._tag;
1983
+ return typeof t == "string" ? t : e instanceof Error ? e.message : String(e);
1984
+ }, ko = async (e, t) => {
1985
+ let n = await _o(e, t);
1986
+ if (n.status !== "failed") throw new l({
1987
+ id: t,
1988
+ status: String(n.status)
1989
+ });
1990
+ return await e.update("cms_releases", t, {
1991
+ status: "draft",
1992
+ failure: null,
1993
+ claimToken: null,
1994
+ scheduledAt: null
1995
+ }) ?? n;
1996
+ }, Ao = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1997
+ let i = await _o(e, n);
1998
+ if (i.status !== "published") throw new l({
1999
+ id: n,
2000
+ status: String(i.status)
2001
+ });
2002
+ let a = await e.insert(z, {
2003
+ name: `Rollback of ${String(i.name)}`,
2004
+ site: i.site,
2005
+ environment: i.environment,
2006
+ status: "draft",
2007
+ rollbackOf: n,
2008
+ ...i.tenantId !== void 0 && i.tenantId !== null ? { tenantId: i.tenantId } : {}
2009
+ }), o = String(a.id), s = 0;
2010
+ for (let t of await So(e, n)) {
2011
+ let n = t.previousRevisionId;
2012
+ await e.insert(B, {
2013
+ releaseId: o,
2014
+ contentType: t.contentType,
2015
+ variantId: t.variantId,
2016
+ locale: t.locale,
2017
+ action: n == null ? "unpublish" : "publish",
2018
+ revisionId: n ?? null,
2019
+ position: s++,
2020
+ ...t.tenantId !== void 0 && t.tenantId !== null ? { tenantId: t.tenantId } : {}
2021
+ });
2022
+ }
2023
+ return To(e, t, o, r);
2024
+ }, jo = [
2025
+ y,
2026
+ l,
2027
+ v,
2028
+ d
2029
+ ], Mo = (...e) => j(() => yo(...e)), No = (...e) => j(() => bo(...e), y, l), Po = (...e) => j(() => So(...e)), Fo = (...e) => j(() => xo(...e)), Io = (...e) => j(() => Co(...e)), Lo = (...e) => j(() => To(...e), ...jo), Ro = (...e) => j(() => Eo(...e), ...jo), zo = (...e) => j(() => Do(...e)), Bo = (...e) => j(() => Ao(...e), ...jo), Vo = (...e) => j(() => ko(...e), ...jo), Ho = (e, t, n, r, i = []) => e.query({
2030
+ table: t,
2031
+ predicate: x(S("site", n), S("environment", r), E("status", "archived"), ...i),
2032
+ order: [{
2033
+ column: "id",
2034
+ direction: "asc"
2035
+ }],
2036
+ take: void 0,
2037
+ skip: void 0,
2038
+ projection: void 0
2039
+ }), Uo = (e) => JSON.stringify(e, (e, t) => typeof t == "object" && t && !Array.isArray(t) && !(t instanceof Date) ? Object.fromEntries(Object.entries(t).sort(([e], [t]) => e < t ? -1 : 1)) : t), Wo = (e) => {
2040
+ for (let t of [
2041
+ "title",
2042
+ "name",
2043
+ "slug"
2044
+ ]) if (typeof e[t] == "string" && e[t] !== "") return e[t];
2045
+ return String(e.documentId);
2046
+ }, Go = (e) => `${String(e.documentId)}\u0000${String(e.locale)}`, Ko = async (e, t, n) => {
2047
+ let r = [];
2048
+ for (let i of t) {
2049
+ let t = await Ho(e, `${i.name}_published`, n.site, n.from);
2050
+ if (t.length === 0) continue;
2051
+ let a = new Map((await Ho(e, `${i.name}_published`, n.site, n.to)).map((e) => [Go(e), e])), o = new Map((await Ho(e, `${i.name}_drafts`, n.site, n.to)).map((e) => [Go(e), e]));
2052
+ for (let e of t) {
2053
+ let t = a.get(Go(e)), n = o.get(Go(e)), s = {
2054
+ contentType: i.name,
2055
+ documentId: String(e.documentId),
2056
+ locale: String(e.locale),
2057
+ title: Wo(e)
2058
+ };
2059
+ if (n !== void 0 && n.status === "draft") {
2060
+ r.push({
2061
+ ...s,
2062
+ change: "blocked"
2063
+ });
2064
+ continue;
2065
+ }
2066
+ if (t === void 0) {
2067
+ r.push({
2068
+ ...s,
2069
+ change: "new"
2070
+ });
2071
+ continue;
2072
+ }
2073
+ Uo(R(i, e)) !== Uo(R(i, t)) && r.push({
2074
+ ...s,
2075
+ change: "changed"
2076
+ });
2077
+ }
2078
+ }
2079
+ return r;
2080
+ }, qo = async (e, t, n, r, i) => {
2081
+ if (r.length === 0) return {
2082
+ ok: !1,
2083
+ reason: "nothingSelected",
2084
+ items: []
2085
+ };
2086
+ let a = await Ko(e, t, n), o = new Map(a.map((e) => [`${e.contentType}\u0000${e.documentId}\u0000${e.locale}`, e])), s = r.filter((e) => !o.has(`${e.contentType}\u0000${e.documentId}\u0000${e.locale}`));
2087
+ if (s.length > 0) return {
2088
+ ok: !1,
2089
+ reason: "notInPlan",
2090
+ items: s
2091
+ };
2092
+ let c = r.filter((e) => o.get(`${e.contentType}\u0000${e.documentId}\u0000${e.locale}`).change === "blocked");
2093
+ if (c.length > 0) return {
2094
+ ok: !1,
2095
+ reason: "blocked",
2096
+ items: c
2097
+ };
2098
+ let l = new Map(t.map((e) => [e.name, e])), u = await yo(e, {
2099
+ name: i.name,
2100
+ site: n.site,
2101
+ environment: n.to
2102
+ }), d = String(u.id);
2103
+ for (let t of r) {
2104
+ let r = l.get(t.contentType), [i] = await Ho(e, `${r.name}_published`, n.site, n.from, [S("documentId", t.documentId), S("locale", t.locale)]), a = {
2105
+ site: n.site,
2106
+ environment: n.to,
2107
+ locale: t.locale
2108
+ }, [o] = await Ho(e, `${r.name}_drafts`, n.site, n.to, [S("documentId", t.documentId), S("locale", t.locale)]), s = R(r, i), c = await Za(e, r, o === void 0 ? {
2109
+ ...s,
2110
+ documentId: t.documentId
2111
+ } : {
2112
+ ...s,
2113
+ id: o.id
2114
+ }, a);
2115
+ await bo(e, d, {
2116
+ type: r,
2117
+ id: String(c.id),
2118
+ locale: t.locale,
2119
+ revisionId: String(c.revisionId)
2120
+ });
2121
+ }
2122
+ return await To(e, t, d), {
2123
+ ok: !0,
2124
+ releaseId: d,
2125
+ promoted: r.length
2126
+ };
2127
+ }, Jo = [
2128
+ s,
2129
+ b,
2130
+ y,
2131
+ r,
2132
+ l,
2133
+ v,
2134
+ d
2135
+ ], Yo = (...e) => j(() => Ko(...e), ...Jo), Xo = (...e) => j(() => qo(...e), ...Jo), Zo = async (e, t, n) => {
2136
+ let r = {}, i = /* @__PURE__ */ new Set();
2137
+ for (let a of t) {
2138
+ let t = await e.query({
2139
+ table: `${a.name}_drafts`,
2140
+ predicate: x(S("site", n), E("status", "archived")),
2141
+ order: [],
2142
+ take: void 0,
2143
+ skip: void 0,
2144
+ projection: void 0,
2145
+ groupBy: ["environment"],
2146
+ aggregations: [{
2147
+ op: "column",
2148
+ column: "environment",
2149
+ alias: "environment"
2150
+ }, {
2151
+ op: "count-distinct",
2152
+ column: "documentId",
2153
+ alias: "documents"
2154
+ }]
2155
+ });
2156
+ if (t.length > 1) {
2157
+ let [t] = await e.query({
2158
+ table: `${a.name}_drafts`,
2159
+ predicate: x(S("site", n), E("status", "archived")),
2160
+ order: [],
2161
+ take: void 0,
2162
+ skip: void 0,
2163
+ projection: void 0,
2164
+ aggregations: [{
2165
+ op: "count-distinct",
2166
+ column: "documentId",
2167
+ alias: "documents"
2168
+ }]
2169
+ });
2170
+ r[a.name] = Number(t?.documents ?? 0);
2171
+ } else r[a.name] = Number(t[0]?.documents ?? 0);
2172
+ for (let e of t) i.add(String(e.environment));
2173
+ }
2174
+ return {
2175
+ documents: Object.values(r).reduce((e, t) => e + t, 0),
2176
+ documentsByType: r,
2177
+ environments: [...i].sort()
2178
+ };
2179
+ }, Qo = (...e) => j(() => Zo(...e)), H = "cms_experiments", $o = "cms_experiment_events", es = D(H, {
2180
+ id: C({ prefix: "cexp" }),
2181
+ site: O().maxLength(64),
2182
+ environment: O().maxLength(64),
2183
+ locale: O().maxLength(64),
2184
+ contentType: O().maxLength(64),
2185
+ documentId: O().maxLength(64),
2186
+ name: O(),
2187
+ status: O().oneOf(["running", "stopped"]),
2188
+ share: w(),
2189
+ overrides: T(),
2190
+ goal: O(),
2191
+ hypothesis: O().nullable(),
2192
+ guardrailMaxDrop: w().nullable(),
2193
+ startedAt: k(),
2194
+ stoppedAt: k().nullable(),
2195
+ revisionId: O().maxLength(64).nullable(),
2196
+ adoptedReleaseId: O().maxLength(64).nullable(),
2197
+ adoptedRevisionId: O().maxLength(64).nullable()
2198
+ }).with(A()).index("cms_experiments_by_page", [
2199
+ "contentType",
2200
+ "documentId",
2201
+ "status"
2202
+ ]), ts = D($o, {
2203
+ id: C({ prefix: "cexe" }),
2204
+ experimentId: O(),
2205
+ variant: O().oneOf(["A", "B"]),
2206
+ kind: O().oneOf(["exposure", "conversion"]),
2207
+ reader: O(),
2208
+ revisionId: O().maxLength(64).nullable(),
2209
+ at: k()
2210
+ }).with(A()).unique("cms_experiment_events_once", [
2211
+ "experimentId",
2212
+ "reader",
2213
+ "kind"
2214
+ ]), ns = (e) => e instanceof Date ? e : new Date(String(e)), rs = (e) => typeof e == "string" && e !== "" ? e : null, is = (e) => ({
2215
+ id: String(e.id),
2216
+ name: String(e.name),
2217
+ contentType: String(e.contentType),
2218
+ documentId: String(e.documentId),
2219
+ locale: String(e.locale),
2220
+ status: e.status === "running" ? "running" : "stopped",
2221
+ share: Number(e.share),
2222
+ overrides: e.overrides ?? {},
2223
+ goal: String(e.goal),
2224
+ hypothesis: typeof e.hypothesis == "string" ? e.hypothesis : null,
2225
+ guardrailMaxDrop: typeof e.guardrailMaxDrop == "number" ? e.guardrailMaxDrop : null,
2226
+ startedAt: ns(e.startedAt),
2227
+ stoppedAt: e.stoppedAt === null || e.stoppedAt === void 0 ? null : ns(e.stoppedAt),
2228
+ revisionId: rs(e.revisionId),
2229
+ adoptedReleaseId: rs(e.adoptedReleaseId),
2230
+ adoptedRevisionId: rs(e.adoptedRevisionId)
2231
+ }), as = (e) => {
2232
+ let t = 2166136261;
2233
+ for (let n = 0; n < e.length; n++) t ^= e.charCodeAt(n), t = Math.imul(t, 16777619) >>> 0;
2234
+ return t >>> 0;
2235
+ }, os = (e, t, n) => as(`${e}:${t}`) % 100 < n ? "B" : "A", ss = (e, t, n) => n === "A" ? e : {
2236
+ ...e,
2237
+ ...t.overrides
2238
+ }, cs = (e) => Object.entries(e.fields).filter(([t, n]) => n.kind === "string" && !e.derivedFields.includes(t)).map(([e]) => e), ls = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => {
2239
+ if (!Number.isInteger(r.share) || r.share < 1 || r.share > 99) return {
2240
+ ok: !1,
2241
+ reason: "badShare"
2242
+ };
2243
+ if (r.hypothesis.trim() === "" || r.hypothesis.length > 500) return {
2244
+ ok: !1,
2245
+ reason: "noHypothesis"
2246
+ };
2247
+ let a = r.guardrailMaxDrop ?? null;
2248
+ if (a !== null && (!Number.isInteger(a) || a < 1 || a > 50)) return {
2249
+ ok: !1,
2250
+ reason: "badGuardrail"
2251
+ };
2252
+ let o = Object.keys(r.overrides);
2253
+ if (o.length === 0) return {
2254
+ ok: !1,
2255
+ reason: "noOverrides"
2256
+ };
2257
+ let s = new Set(cs(t)), c = o.filter((e) => !s.has(e));
2258
+ if (c.length > 0) return {
2259
+ ok: !1,
2260
+ reason: "unknownField",
2261
+ fields: c
2262
+ };
2263
+ let l = [
2264
+ S("site", n.site),
2265
+ S("environment", n.environment),
2266
+ S("locale", n.locale),
2267
+ S("documentId", r.documentId)
2268
+ ], [u] = await e.query({
2269
+ table: `${t.name}_published`,
2270
+ predicate: x(...l),
2271
+ order: [],
2272
+ take: 1,
2273
+ skip: void 0,
2274
+ projection: void 0
2275
+ });
2276
+ if (u === void 0) return {
2277
+ ok: !1,
2278
+ reason: "notLive"
2279
+ };
2280
+ if (await ds(e, t, n, r.documentId) !== null) return {
2281
+ ok: !1,
2282
+ reason: "alreadyRunning"
2283
+ };
2284
+ let d = u.tenantId, f = await e.insert(H, {
2285
+ site: n.site,
2286
+ environment: n.environment,
2287
+ locale: n.locale,
2288
+ contentType: t.name,
2289
+ documentId: r.documentId,
2290
+ name: r.name,
2291
+ status: "running",
2292
+ share: r.share,
2293
+ overrides: { ...r.overrides },
2294
+ goal: r.goal,
2295
+ hypothesis: r.hypothesis.trim(),
2296
+ guardrailMaxDrop: a,
2297
+ startedAt: i,
2298
+ stoppedAt: null,
2299
+ revisionId: rs(u.revisionId),
2300
+ ...d == null ? {} : { tenantId: d }
2301
+ });
2302
+ return {
2303
+ ok: !0,
2304
+ id: String(f.id)
2305
+ };
2306
+ }, us = async (e, t, n = /* @__PURE__ */ new Date()) => {
2307
+ let [r] = await e.query({
2308
+ table: H,
2309
+ predicate: x(S("id", t), S("status", "running")),
2310
+ order: [],
2311
+ take: 1,
2312
+ skip: void 0,
2313
+ projection: void 0
2314
+ });
2315
+ return r !== void 0 && (await e.update(H, t, {
2316
+ status: "stopped",
2317
+ stoppedAt: n
2318
+ }), !0);
2319
+ }, ds = async (e, t, n, r) => {
2320
+ let [i] = await e.query({
2321
+ table: H,
2322
+ predicate: x(S("contentType", t.name), S("documentId", r), S("status", "running"), S("site", n.site), S("environment", n.environment), S("locale", n.locale)),
2323
+ order: [],
2324
+ take: 1,
2325
+ skip: void 0,
2326
+ projection: void 0
2327
+ });
2328
+ return i === void 0 ? null : is(i);
2329
+ }, fs = async (e, t) => {
2330
+ let [n] = await e.query({
2331
+ table: H,
2332
+ predicate: S("id", t),
2333
+ order: [],
2334
+ take: 1,
2335
+ skip: void 0,
2336
+ projection: void 0
2337
+ });
2338
+ return n === void 0 ? null : is(n);
2339
+ }, ps = async (e) => (await e.query({
2340
+ table: H,
2341
+ predicate: void 0,
2342
+ order: [{
2343
+ column: "startedAt",
2344
+ direction: "desc"
2345
+ }],
2346
+ take: 200,
2347
+ skip: void 0,
2348
+ projection: void 0
2349
+ })).map(is), ms = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => {
2350
+ if (t.status !== "running" || n === "") return !1;
2351
+ let a = as(`${t.id}|${n}`).toString(36) + as(`${n}|${t.id}`).toString(36);
2352
+ if (r === "conversion") {
2353
+ let [n] = await e.query({
2354
+ table: $o,
2355
+ predicate: x(S("experimentId", t.id), S("reader", a), S("kind", "exposure")),
2356
+ order: [],
2357
+ take: 1,
2358
+ skip: void 0,
2359
+ projection: void 0
2360
+ });
2361
+ if (n === void 0) return !1;
2362
+ }
2363
+ let [o] = await e.query({
2364
+ table: H,
2365
+ predicate: S("id", t.id),
2366
+ order: [],
2367
+ take: 1,
2368
+ skip: void 0,
2369
+ projection: void 0
2370
+ }), s = o?.tenantId, [c] = o === void 0 ? [] : await e.query({
2371
+ table: `${t.contentType}_published`,
2372
+ predicate: x(S("documentId", t.documentId), S("site", String(o.site)), S("environment", String(o.environment)), S("locale", t.locale)),
2373
+ order: [],
2374
+ take: 1,
2375
+ skip: void 0,
2376
+ projection: void 0
2377
+ });
2378
+ return (await e.insertIgnoreWithOutcome($o, {
2379
+ experimentId: t.id,
2380
+ variant: os(t.id, n, t.share),
2381
+ kind: r,
2382
+ reader: a,
2383
+ revisionId: rs(c?.revisionId),
2384
+ at: i,
2385
+ ...s == null ? {} : { tenantId: s }
2386
+ }, { conflictColumns: [
2387
+ "experimentId",
2388
+ "reader",
2389
+ "kind"
2390
+ ] })).outcome === "inserted";
2391
+ }, hs = 100, gs = (e) => {
2392
+ let t = 1 / (1 + .3275911 * Math.abs(e) / Math.SQRT2), n = 1 - ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - .284496736) * t + .254829592) * t * Math.exp(-(e * e) / 2);
2393
+ return e >= 0 ? (1 + n) / 2 : (1 - n) / 2;
2394
+ }, _s = async (e, t) => {
2395
+ let n = await e.query({
2396
+ table: $o,
2397
+ predicate: S("experimentId", t),
2398
+ order: [],
2399
+ take: void 0,
2400
+ skip: void 0,
2401
+ projection: void 0,
2402
+ groupBy: ["variant", "kind"],
2403
+ aggregations: [
2404
+ {
2405
+ op: "column",
2406
+ column: "variant",
2407
+ alias: "variant"
2408
+ },
2409
+ {
2410
+ op: "column",
2411
+ column: "kind",
2412
+ alias: "kind"
2413
+ },
2414
+ {
2415
+ op: "count",
2416
+ alias: "n"
2417
+ }
2418
+ ]
2419
+ }), r = (e, t) => Number(n.find((n) => n.variant === e && n.kind === t)?.n ?? 0), i = (e) => {
2420
+ let t = r(e, "exposure"), n = r(e, "conversion");
2421
+ return {
2422
+ readers: t,
2423
+ conversions: n,
2424
+ rate: t === 0 ? 0 : n / t
2425
+ };
2426
+ }, a = i("A"), o = i("B"), [s] = await e.query({
2427
+ table: H,
2428
+ predicate: S("id", t),
2429
+ order: [],
2430
+ take: 1,
2431
+ skip: void 0,
2432
+ projection: void 0
2433
+ }), c = typeof s?.guardrailMaxDrop == "number" ? s.guardrailMaxDrop : null, l = c !== null && a.readers >= 100 && o.readers >= 100 && (a.rate - o.rate) * 100 > c, u = null;
2434
+ if (a.readers > 0 && o.readers > 0) {
2435
+ let e = (a.conversions + o.conversions) / (a.readers + o.readers), t = Math.sqrt(e * (1 - e) * (1 / a.readers + 1 / o.readers));
2436
+ u = t === 0 ? 1 : 2 * (1 - gs(Math.abs(o.rate - a.rate) / t));
2437
+ }
2438
+ return {
2439
+ A: a,
2440
+ B: o,
2441
+ lift: a.rate === 0 ? null : (o.rate - a.rate) / a.rate,
2442
+ pValue: u,
2443
+ conclusive: a.readers >= 100 && o.readers >= 100 && u !== null && u < .05,
2444
+ guardrail: {
2445
+ maxDrop: c,
2446
+ breached: l
2447
+ }
2448
+ };
2449
+ }, vs = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
2450
+ let [i] = await e.query({
2451
+ table: H,
2452
+ predicate: S("id", n),
2453
+ order: [],
2454
+ take: 1,
2455
+ skip: void 0,
2456
+ projection: void 0
2457
+ });
2458
+ if (i === void 0 || i.contentType !== t.name) return {
2459
+ ok: !1,
2460
+ reason: "notFound"
2461
+ };
2462
+ let a = is(i);
2463
+ if (a.adoptedReleaseId !== null) return {
2464
+ ok: !1,
2465
+ reason: "alreadyAdopted"
2466
+ };
2467
+ let o = {
2468
+ site: String(i.site),
2469
+ environment: String(i.environment),
2470
+ locale: a.locale
2471
+ }, [s] = await e.query({
2472
+ table: `${t.name}_drafts`,
2473
+ predicate: x(S("documentId", a.documentId), S("site", o.site), S("environment", o.environment), S("locale", o.locale)),
2474
+ order: [],
2475
+ take: 1,
2476
+ skip: void 0,
2477
+ projection: void 0
2478
+ });
2479
+ if (s === void 0) return {
2480
+ ok: !1,
2481
+ reason: "noDraft"
2482
+ };
2483
+ a.status === "running" && await us(e, n, r);
2484
+ let c = await Za(e, t, {
2485
+ ...s,
2486
+ ...a.overrides
2487
+ }, o, { expectedRevision: String(s.revisionId) }), l = await yo(e, {
2488
+ name: `Adopt B: ${a.name}`.slice(0, 120),
2489
+ site: o.site,
2490
+ environment: o.environment
2491
+ }), u = String(l.id), d = String(c.revisionId);
2492
+ return await bo(e, u, {
2493
+ type: t,
2494
+ id: String(c.id),
2495
+ locale: o.locale,
2496
+ action: "publish",
2497
+ revisionId: d
2498
+ }), await e.update(H, n, {
2499
+ adoptedReleaseId: u,
2500
+ adoptedRevisionId: d
2501
+ }), {
2502
+ ok: !0,
2503
+ releaseId: u,
2504
+ revisionId: d
2505
+ };
2506
+ }, ys = async (e, t) => {
2507
+ let n = await fs(e, t);
2508
+ if (n === null) return null;
2509
+ let r = (await e.query({
2510
+ table: $o,
2511
+ predicate: x(S("experimentId", t), S("kind", "exposure")),
2512
+ order: [],
2513
+ take: void 0,
2514
+ skip: void 0,
2515
+ projection: void 0,
2516
+ groupBy: ["revisionId", "variant"],
2517
+ aggregations: [
2518
+ {
2519
+ op: "column",
2520
+ column: "revisionId",
2521
+ alias: "revisionId"
2522
+ },
2523
+ {
2524
+ op: "column",
2525
+ column: "variant",
2526
+ alias: "variant"
2527
+ },
2528
+ {
2529
+ op: "count",
2530
+ alias: "n"
2531
+ }
2532
+ ]
2533
+ })).map((e) => ({
2534
+ revisionId: rs(e.revisionId),
2535
+ variant: e.variant === "B" ? "B" : "A",
2536
+ readers: Number(e.n)
2537
+ })).sort((e, t) => String(e.revisionId).localeCompare(String(t.revisionId)) || e.variant.localeCompare(t.variant)), i = n.adoptedReleaseId === null || n.adoptedRevisionId === null ? null : {
2538
+ releaseId: n.adoptedReleaseId,
2539
+ revisionId: n.adoptedRevisionId,
2540
+ releaseStatus: await xo(e, n.adoptedReleaseId) ?? "gone"
2541
+ };
2542
+ return {
2543
+ startedOn: n.revisionId,
2544
+ overrides: n.overrides,
2545
+ delivered: r,
2546
+ adopted: i
2547
+ };
2548
+ }, bs = [
2549
+ s,
2550
+ b,
2551
+ y,
2552
+ r,
2553
+ l
2554
+ ], xs = (...e) => j(() => fs(...e)), Ss = (...e) => j(() => _s(...e)), Cs = (...e) => j(() => ps(...e)), ws = (...e) => j(() => ms(...e)), Ts = (...e) => j(() => ds(...e)), Es = (...e) => j(() => ls(...e)), Ds = (...e) => j(() => us(...e)), Os = (...e) => j(() => vs(...e), ...bs), ks = (...e) => j(() => ys(...e)), U = class extends Error {
2555
+ reason;
2556
+ _tag = "BlueprintInvalid";
2557
+ constructor(e) {
2558
+ super(`blueprint not usable: ${e}`), this.reason = e;
2559
+ }
2560
+ }, As = "$entry", js = (e) => ({ [As]: e }), Ms = (e) => {
2561
+ if (typeof e != "object" || !e || Array.isArray(e)) return;
2562
+ let t = Object.keys(e), n = e[As];
2563
+ return t.length === 1 && typeof n == "string" ? n : void 0;
2564
+ }, Ns = (e, t) => {
2565
+ let n = Ms(e);
2566
+ if (n !== void 0) t.add(n);
2567
+ else if (Array.isArray(e)) for (let n of e) Ns(n, t);
2568
+ else if (typeof e == "object" && e) for (let n of Object.values(e)) Ns(n, t);
2569
+ return t;
2570
+ }, Ps = (e, t) => {
2571
+ let n = Ms(e);
2572
+ return n === void 0 ? Array.isArray(e) ? e.map((e) => Ps(e, t)) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).map(([e, n]) => [e, Ps(n, t)])) : e : t.get(n);
2573
+ }, Fs = (e) => {
2574
+ let t = e.team === void 0 ? [] : Pr(e.team);
2575
+ if (t.length > 0) throw new U(t.join("; "));
2576
+ let n = /* @__PURE__ */ new Map();
2577
+ for (let t of e.entries) {
2578
+ if (n.has(t.key)) throw new U(`the key '${t.key}' is used twice`);
2579
+ n.set(t.key, t);
2580
+ }
2581
+ let r = new Map(e.entries.map((e) => [e.key, Ns([e.values, e.translations ?? {}], /* @__PURE__ */ new Set())]));
2582
+ for (let [e, t] of r) for (let r of t) if (!n.has(r)) throw new U(`'${e}' references '${r}', which is no entry`);
2583
+ let i = [], a = /* @__PURE__ */ new Map(), o = (e, t) => {
2584
+ if (a.get(e) !== "done") {
2585
+ if (a.get(e) === "visiting") throw new U(`the entries reference each other in a circle: ${[...t, e].join(" → ")}`);
2586
+ a.set(e, "visiting");
2587
+ for (let n of r.get(e) ?? []) o(n, [...t, e]);
2588
+ a.set(e, "done"), i.push(n.get(e));
2589
+ }
2590
+ };
2591
+ for (let t of e.entries) o(t.key, []);
2592
+ return {
2593
+ ...e,
2594
+ entries: i
2595
+ };
2596
+ }, Is = (e, t) => {
2597
+ let n = e.find((e) => e.name === t.type);
2598
+ if (n === void 0) throw new U(`'${t.key}' is of type '${t.type}', which this app does not have`);
2599
+ if (t.match !== void 0 && n.fields[t.match] === void 0) throw new U(`'${t.key}' matches on '${t.match}', which ${n.name} does not have`);
2600
+ return n;
2601
+ }, Ls = (e, t, n, r) => {
2602
+ let i = {};
2603
+ if (t.template !== void 0) {
2604
+ let n = re(e, t.template);
2605
+ if (n === null) throw new U(`'${t.key}' is built from the template '${t.template}', which ${e.name} does not have`);
2606
+ i = n;
2607
+ }
2608
+ let a = n === r ? {} : t.translations?.[n] ?? {};
2609
+ return {
2610
+ ...i,
2611
+ ...t.values,
2612
+ ...a
2613
+ };
2614
+ }, Rs = (e, t) => {
2615
+ if (typeof t.title == "string" && t.title !== "") return t.title;
2616
+ let n = e.match === void 0 ? void 0 : t[e.match];
2617
+ return typeof n == "string" && n !== "" ? n : e.key;
2618
+ }, zs = (e, t, n, r) => e.query({
2619
+ table: `${t.name}_drafts`,
2620
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", n.locale), ...r === null ? [] : [r]),
2621
+ order: [{
2622
+ column: "id",
2623
+ direction: "asc"
2624
+ }],
2625
+ take: 1,
2626
+ skip: void 0,
2627
+ projection: void 0
2628
+ }), Bs = async (e, t, n, r, i, a) => {
2629
+ if (a !== null) {
2630
+ let [n] = await zs(e, t, r, S("documentId", a));
2631
+ if (n !== void 0) return n;
2632
+ }
2633
+ let o = n.match === void 0 ? void 0 : i[n.match];
2634
+ if (n.match !== void 0 && (o == null || o === "")) return null;
2635
+ let [s] = await zs(e, t, r, n.match === void 0 ? null : S(n.match, o));
2636
+ return s ?? null;
2637
+ }, Vs = (e, t) => [e.locale, ...Object.keys(t.translations ?? {}).filter((t) => t !== e.locale)], Hs = async (e, t, n, r, i) => {
2638
+ let a = /* @__PURE__ */ new Map(), o = [], s = 0;
2639
+ for (let c of n.entries) {
2640
+ let l = Is(t, c), u = null, d = !1, f = !1;
2641
+ for (let t of Vs(n, c)) {
2642
+ if (f) break;
2643
+ let p = {
2644
+ site: r.site,
2645
+ environment: r.environment,
2646
+ locale: t
2647
+ }, m = Ls(l, c, t, n.locale), h = Ue(l, Ps(m, a)), g = await Bs(e, l, c, p, h, u);
2648
+ if (g !== null) {
2649
+ f = t === n.locale, u ??= String(g.documentId), o.push({
2650
+ key: c.key,
2651
+ type: l.name,
2652
+ locale: t,
2653
+ label: Rs(c, g),
2654
+ action: "present",
2655
+ documentId: String(g.documentId),
2656
+ variantId: String(g.id),
2657
+ outcome: null
2658
+ });
2659
+ continue;
2660
+ }
2661
+ let _ = Rs(c, h);
2662
+ u === null && !d && s++, d = !0;
2663
+ let ee = c.publish === !1 ? "draft" : l.review?.required === !0 || l.review?.required === "workspace" && (n.team?.reviewRequired ?? []).includes(l.name) ? "review" : "live";
2664
+ if (!i) {
2665
+ let e = ee;
2666
+ o.push({
2667
+ key: c.key,
2668
+ type: l.name,
2669
+ locale: t,
2670
+ label: _,
2671
+ action: "create",
2672
+ documentId: u,
2673
+ variantId: null,
2674
+ outcome: e
2675
+ });
2676
+ continue;
2677
+ }
2678
+ let te = await Za(e, l, {
2679
+ ...h,
2680
+ ...u === null ? {} : { documentId: u }
2681
+ }, p), ne = ee === "live" && await gi(e, l, String(te.id)) ? "review" : ee;
2682
+ ne === "live" && await eo(e, l, String(te.id), p), u ??= String(te.documentId), o.push({
2683
+ key: c.key,
2684
+ type: l.name,
2685
+ locale: t,
2686
+ label: _,
2687
+ action: "create",
2688
+ documentId: String(te.documentId),
2689
+ variantId: String(te.id),
2690
+ outcome: ne
2691
+ });
2692
+ }
2693
+ u !== null && a.set(c.key, u);
2694
+ }
2695
+ return {
2696
+ blueprint: n.id,
2697
+ steps: o,
2698
+ documents: s
2699
+ };
2700
+ }, Us = (e, t, n, r) => Hs(e, t, n, r, !1), Ws = (e, t, n, r) => Hs(e, t, n, r, !0), Gs = [
2701
+ U,
2702
+ b,
2703
+ y,
2704
+ s,
2705
+ d,
2706
+ v,
2707
+ r
2708
+ ], Ks = (...e) => j(() => Ws(...e), ...Gs), qs = (...e) => j(() => Us(...e), ...Gs), Js = (e, t, n, r) => e.query({
2709
+ table: t,
2710
+ predicate: x(S("site", n), S("environment", r), E("status", "archived")),
2711
+ order: [{
2712
+ column: "id",
2713
+ direction: "asc"
2714
+ }],
2715
+ take: void 0,
2716
+ skip: void 0,
2717
+ projection: void 0
2718
+ }), Ys = async (e, t, n) => {
2719
+ if (n.from === n.to) return {
2720
+ ok: !1,
2721
+ reason: "sameEnvironment",
2722
+ variants: 0
2723
+ };
2724
+ let r = 0;
2725
+ for (let i of t) r += (await Js(e, `${i.name}_drafts`, n.site, n.to)).length;
2726
+ if (r > 0) return {
2727
+ ok: !1,
2728
+ reason: "targetNotEmpty",
2729
+ variants: r
2730
+ };
2731
+ let i = 0, a = 0;
2732
+ for (let r of t) {
2733
+ let t = await Js(e, `${r.name}_drafts`, n.site, n.from), o = new Map((await Js(e, `${r.name}_published`, n.site, n.from)).map((e) => [String(e.id), e])), s = /* @__PURE__ */ new Set();
2734
+ for (let c of t) {
2735
+ let t = {
2736
+ site: n.site,
2737
+ environment: n.to,
2738
+ locale: String(c.locale)
2739
+ }, l = String(c.documentId), u = c.tenantId, d = Ka(r), f = o.get(String(c.id)), p = R(r, c), m = 0, h;
2740
+ f !== void 0 && (h = await qa(e, r, l, ++m, R(r, f), t, u));
2741
+ let g = f !== void 0 && f.revisionId === c.revisionId && h !== void 0 ? h : await qa(e, r, l, ++m, p, t, u), _ = u == null ? {} : { tenantId: u };
2742
+ if (await un(e, r, await e.insert(`${r.name}_drafts`, {
2743
+ ...p,
2744
+ id: d,
2745
+ documentId: l,
2746
+ ...Ba(t),
2747
+ status: c.status,
2748
+ revisionId: g.id,
2749
+ revision: g.number,
2750
+ ..._
2751
+ }), t, "draft"), i++, f !== void 0 && h !== void 0) {
2752
+ let n = await e.insert(`${r.name}_published`, {
2753
+ ...R(r, f),
2754
+ id: d,
2755
+ documentId: l,
2756
+ ...Ba(t),
2757
+ status: "published",
2758
+ revisionId: h.id,
2759
+ revision: h.number,
2760
+ ..._
2761
+ });
2762
+ await or(e, r, n, t), await Ui(e, r, n, t), await un(e, r, n, t, "published"), s.add(`${t.locale}\u0000${String(u ?? "")}`), a++;
2763
+ }
2764
+ }
2765
+ for (let t of s) {
2766
+ let [i, a] = t.split("\0");
2767
+ await Hn(e, r, {
2768
+ site: n.site,
2769
+ environment: n.to,
2770
+ locale: i
2771
+ }, a === "" ? void 0 : a);
2772
+ }
2773
+ }
2774
+ return {
2775
+ ok: !0,
2776
+ variants: i,
2777
+ published: a
2778
+ };
2779
+ }, Xs = (e) => JSON.stringify(e, (e, t) => typeof t == "object" && t && !Array.isArray(t) && !(t instanceof Date) ? Object.fromEntries(Object.entries(t).sort(([e], [t]) => e < t ? -1 : 1)) : t), Zs = (e) => {
2780
+ for (let t of [
2781
+ "title",
2782
+ "name",
2783
+ "slug"
2784
+ ]) if (typeof e[t] == "string" && e[t] !== "") return e[t];
2785
+ return String(e.documentId);
2786
+ }, Qs = async (e, t, n) => {
2787
+ let r = [];
2788
+ for (let i of t) {
2789
+ let t = async (t) => new Set((await Js(e, `${i.name}_drafts`, n.site, t)).map((e) => String(e.documentId))), [a, o] = [await t(n.from), await t(n.to)], s = async (t) => new Map((await Js(e, `${i.name}_published`, n.site, t)).map((e) => [`${String(e.documentId)}\u0000${String(e.locale)}`, e])), [c, l] = [await s(n.from), await s(n.to)], u = [];
2790
+ for (let [e, t] of c) {
2791
+ let n = l.get(e);
2792
+ n !== void 0 && Xs(R(i, t)) !== Xs(R(i, n)) && u.push({
2793
+ documentId: String(t.documentId),
2794
+ locale: String(t.locale),
2795
+ title: Zs(n)
2796
+ });
2797
+ }
2798
+ r.push({
2799
+ contentType: i.name,
2800
+ onlyInFrom: [...a].filter((e) => !o.has(e)).length,
2801
+ onlyInTo: [...o].filter((e) => !a.has(e)).length,
2802
+ differing: u
2803
+ });
2804
+ }
2805
+ return r;
2806
+ }, $s = (...e) => j(() => Qs(...e)), ec = (...e) => j(() => Ys(...e)), tc = async (e, t, n, r) => (await e.query({
2807
+ table: t,
2808
+ predicate: x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)),
2809
+ order: [],
2810
+ take: 1,
2811
+ skip: void 0,
2812
+ projection: void 0
2813
+ }))[0], nc = (e, t) => {
2814
+ for (let t of [
2815
+ "title",
2816
+ "name",
2817
+ "slug"
2818
+ ]) {
2819
+ let n = e?.[t];
2820
+ if (typeof n == "string" && n !== "") return n;
2821
+ }
2822
+ return t;
2823
+ }, rc = (e) => e.targets.map((e) => `${e.path}: ${e.reason}`), ic = async (e, t, n, r, i) => {
2824
+ let a = (e, t = {}) => ({
2825
+ ...i,
2826
+ documentId: null,
2827
+ title: i.id,
2828
+ revisionId: null,
2829
+ disposition: "blocked",
2830
+ reason: e,
2831
+ detail: [],
2832
+ ...t
2833
+ });
2834
+ if (t === void 0) return a("unknownType");
2835
+ let o = {
2836
+ ...n,
2837
+ locale: i.locale
2838
+ }, c = await tc(e, `${t.name}_drafts`, i.id, o);
2839
+ if (c === void 0) return a("notFound");
2840
+ let l = {
2841
+ documentId: String(c.documentId),
2842
+ title: nc(c, i.id)
2843
+ }, u = (e, t = null) => ({
2844
+ ...i,
2845
+ ...l,
2846
+ revisionId: t,
2847
+ disposition: e,
2848
+ reason: null,
2849
+ detail: []
2850
+ });
2851
+ if (r.kind === "unpublish") return await tc(e, `${t.name}_published`, i.id, o) === void 0 ? a("notPublished", l) : u("ready");
2852
+ if (r.kind === "setOwner") return u((await Aa(e, t, l.documentId, n)).owner === r.owner ? "unchanged" : "ready");
2853
+ if (r.kind === "setField") {
2854
+ let e = t.fields[r.field];
2855
+ if (e === void 0 || e.derived !== void 0 || e.kind === "richText" || e.kind === "components") return a("invalid", {
2856
+ ...l,
2857
+ detail: [`${r.field}: not a field this can set`]
2858
+ });
2859
+ let n = String(c.revisionId);
2860
+ if (JSON.stringify(c[r.field] ?? null) === JSON.stringify(r.value ?? null)) return u("unchanged", n);
2861
+ try {
2862
+ st(t, Ue(t, R(t, {
2863
+ ...c,
2864
+ [r.field]: r.value
2865
+ })));
2866
+ } catch (e) {
2867
+ if (e instanceof s) return a("invalid", {
2868
+ ...l,
2869
+ revisionId: n,
2870
+ detail: e.violations.map((e) => `${e.field}: ${e.message}`)
2871
+ });
2872
+ throw e;
2873
+ }
2874
+ return u("ready", n);
2875
+ }
2876
+ let f = String(c.revisionId);
2877
+ if ((await tc(e, `${t.name}_published`, i.id, o))?.revisionId === f) return u("unchanged", f);
2878
+ try {
2879
+ let [n] = await e.query({
2880
+ table: M,
2881
+ predicate: S("id", f),
2882
+ order: [],
2883
+ take: 1,
2884
+ skip: void 0,
2885
+ projection: void 0
2886
+ }), r = n?.values ?? {}, s = mt(t, r);
2887
+ if (s.length > 0) return a("incomplete", {
2888
+ ...l,
2889
+ revisionId: f,
2890
+ detail: s.map((e) => e.field)
2891
+ });
2892
+ await _i(e, t, i.id, o, f), await Gi(e, t, i.id, r, o);
2893
+ } catch (e) {
2894
+ if (e instanceof v) return a("reviewRequired", {
2895
+ ...l,
2896
+ revisionId: f
2897
+ });
2898
+ if (e instanceof d) return a("referenceUnavailable", {
2899
+ ...l,
2900
+ revisionId: f,
2901
+ detail: rc(e)
2902
+ });
2903
+ throw e;
2904
+ }
2905
+ return u("ready", f);
2906
+ }, ac = async (e, t, n, r, i) => {
2907
+ let a = new Map(t.map((e) => [e.name, e])), o = [];
2908
+ for (let t of i) o.push(await ic(e, a.get(t.type), n, r, t));
2909
+ return o;
2910
+ }, oc = async (e, t, n, i, a) => {
2911
+ let o = new Map(t.map((e) => [e.name, e])), c = [], l = /* @__PURE__ */ new Set();
2912
+ for (let t of a) {
2913
+ let a = {
2914
+ type: t.type,
2915
+ id: t.id,
2916
+ locale: t.locale,
2917
+ title: t.title
2918
+ };
2919
+ if (t.disposition !== "ready") {
2920
+ c.push({
2921
+ ...a,
2922
+ outcome: t.disposition === "unchanged" ? "unchanged" : "failed",
2923
+ reason: t.reason,
2924
+ detail: t.detail
2925
+ });
2926
+ continue;
2927
+ }
2928
+ let u = o.get(t.type), f = {
2929
+ ...n,
2930
+ locale: t.locale
2931
+ };
2932
+ try {
2933
+ if (u === void 0) throw new y({
2934
+ contentType: t.type,
2935
+ id: t.id,
2936
+ stage: "draft"
2937
+ });
2938
+ if (i.kind === "publish") await e.transactional((e) => to(e, u, t.id, f, t.revisionId ?? "")), l.add(u);
2939
+ else if (i.kind === "unpublish") await e.transactional((e) => no(e, u, t.id, f)), l.add(u);
2940
+ else if (i.kind === "setField") await e.transactional(async (e) => {
2941
+ let n = await tc(e, `${u.name}_drafts`, t.id, f);
2942
+ if (n === void 0) throw new y({
2943
+ contentType: t.type,
2944
+ id: t.id,
2945
+ stage: "draft"
2946
+ });
2947
+ await Za(e, u, {
2948
+ ...R(u, n),
2949
+ id: t.id,
2950
+ [i.field]: i.value
2951
+ }, f, t.revisionId === null ? {} : { expectedRevision: t.revisionId });
2952
+ });
2953
+ else {
2954
+ if (t.documentId === null) throw new y({
2955
+ contentType: t.type,
2956
+ id: t.id,
2957
+ stage: "draft"
2958
+ });
2959
+ await ja(e, u, t.documentId, n, i.owner);
2960
+ }
2961
+ c.push({
2962
+ ...a,
2963
+ outcome: "done",
2964
+ reason: null,
2965
+ detail: []
2966
+ });
2967
+ } catch (e) {
2968
+ let t = e instanceof v ? "reviewRequired" : e instanceof r ? "revisionMoved" : e instanceof s ? "incomplete" : e instanceof d ? "referenceUnavailable" : e instanceof y ? e.stage === "published" ? "notPublished" : "notFound" : "failed", n = e instanceof d ? rc(e) : e instanceof s ? e.violations.map((e) => e.field) : t === "failed" ? [e instanceof Error ? e.message : String(e)] : [];
2969
+ c.push({
2970
+ ...a,
2971
+ outcome: "failed",
2972
+ reason: t,
2973
+ detail: n
2974
+ });
2975
+ }
2976
+ }
2977
+ for (let e of l) $a(e);
2978
+ return c;
2979
+ }, sc = [
2980
+ b,
2981
+ y,
2982
+ s,
2983
+ d,
2984
+ v,
2985
+ r
2986
+ ], cc = (...e) => j(() => ac(...e), ...sc), lc = (...e) => j(() => oc(...e), ...sc), uc = async (e, t, n, r) => {
2987
+ let i = await e.query({
2988
+ table: `${t.name}_drafts`,
2989
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", n.locale), E("status", "archived")),
2990
+ order: [{
2991
+ column: "createdAt",
2992
+ direction: "asc"
2993
+ }],
2994
+ take: void 0,
2995
+ skip: void 0,
2996
+ projection: void 0
2997
+ }), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
2998
+ for (let e of i) {
2999
+ let t = e[r.field];
3000
+ if (typeof t != "string" || t === "") continue;
3001
+ a.has(t) || a.set(t, r.fingerprint(t).catch(() => null));
3002
+ let n = await a.get(t);
3003
+ if (n === null) continue;
3004
+ let i = o.get(n) ?? [];
3005
+ i.push({
3006
+ id: String(e.id),
3007
+ documentId: String(e.documentId),
3008
+ title: String(e[r.titleField ?? "title"] ?? ""),
3009
+ status: String(e.status)
3010
+ }), o.set(n, i);
3011
+ }
3012
+ return [...o].filter(([, e]) => e.length > 1).map(([e, t]) => ({
3013
+ fingerprint: e,
3014
+ documents: t
3015
+ }));
3016
+ }, dc = async (e, t, n, r) => {
3017
+ if (r.copyId === r.keepId) return {
3018
+ ok: !1,
3019
+ reason: "notDuplicate"
3020
+ };
3021
+ let i = async (r) => {
3022
+ let [i] = await e.query({
3023
+ table: `${t.name}_drafts`,
3024
+ predicate: x(S("id", r), S("site", n.site), S("environment", n.environment), S("locale", n.locale)),
3025
+ order: [],
3026
+ take: 1,
3027
+ skip: void 0,
3028
+ projection: void 0
3029
+ });
3030
+ if (i === void 0) throw new y({
3031
+ contentType: t.name,
3032
+ id: r,
3033
+ stage: "draft"
3034
+ });
3035
+ return i;
3036
+ }, [a, o] = [await i(r.copyId), await i(r.keepId)], [s, c] = [a[r.field], o[r.field]];
3037
+ if (typeof s != "string" || typeof c != "string") return {
3038
+ ok: !1,
3039
+ reason: "notDuplicate"
3040
+ };
3041
+ let [l, u] = [await r.fingerprint(s), await r.fingerprint(c)];
3042
+ if (l === null || l !== u) return {
3043
+ ok: !1,
3044
+ reason: "notDuplicate"
3045
+ };
3046
+ let d = await sr(e, {
3047
+ type: t.name,
3048
+ documentId: String(a.documentId)
3049
+ }, n);
3050
+ return d.length > 0 ? {
3051
+ ok: !1,
3052
+ reason: "inUse",
3053
+ usedBy: d
3054
+ } : (await ro(e, t, r.copyId, n), { ok: !0 });
3055
+ }, fc = (...e) => j(() => uc(...e)), pc = (...e) => j(() => dc(...e), y), W = "cms_preview_shares", mc = 30, hc = D(W, {
3056
+ id: C({ prefix: "cshr" }),
3057
+ contentType: O().maxLength(64),
3058
+ variantId: O().maxLength(64),
3059
+ documentId: O().maxLength(64),
3060
+ site: O().maxLength(64),
3061
+ environment: O().maxLength(64),
3062
+ locale: O().maxLength(64),
3063
+ revisionId: O().nullable(),
3064
+ tokenHash: O().unique(),
3065
+ label: O().nullable(),
3066
+ expiresAt: k(),
3067
+ revokedAt: k().nullable()
3068
+ }).with(A()), gc = (e) => Kt("sha256").update(e, "utf8").digest("hex"), _c = async (e, t, n, r = !1) => (await e.query({
3069
+ table: t,
3070
+ predicate: n,
3071
+ order: [],
3072
+ take: 1,
3073
+ skip: void 0,
3074
+ projection: void 0,
3075
+ ...r ? { crossTenant: !0 } : {}
3076
+ }))[0], vc = async (e, t, n, r, i) => {
3077
+ let a = i.now ?? /* @__PURE__ */ new Date();
3078
+ if (i.expiresAt.getTime() <= a.getTime()) throw new kt({ reason: "expiryInPast" });
3079
+ if (i.expiresAt.getTime() > a.getTime() + 2592e6) throw new kt({ reason: "expiryTooFar" });
3080
+ let o = await _c(e, `${t.name}_drafts`, x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)));
3081
+ if (o === void 0) throw new y({
3082
+ contentType: t.name,
3083
+ id: n,
3084
+ stage: "draft"
3085
+ });
3086
+ let s = Jt(32).toString("base64url");
3087
+ return {
3088
+ share: await e.insert(W, {
3089
+ contentType: t.name,
3090
+ variantId: n,
3091
+ documentId: o.documentId,
3092
+ site: r.site,
3093
+ environment: r.environment,
3094
+ locale: r.locale,
3095
+ revisionId: i.revision === "pinned" ? o.revisionId : null,
3096
+ tokenHash: gc(s),
3097
+ label: i.label ?? null,
3098
+ expiresAt: i.expiresAt,
3099
+ revokedAt: null
3100
+ }),
3101
+ token: s
3102
+ };
3103
+ }, yc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3104
+ let r = await _c(e, W, S("tokenHash", gc(t)), !0);
3105
+ if (r === void 0) return {
3106
+ ok: !1,
3107
+ reason: "unknown"
3108
+ };
3109
+ if (r.revokedAt !== null && r.revokedAt !== void 0) return {
3110
+ ok: !1,
3111
+ reason: "revoked"
3112
+ };
3113
+ if (new Date(r.expiresAt).getTime() <= n.getTime()) return {
3114
+ ok: !1,
3115
+ reason: "expired"
3116
+ };
3117
+ let i = r.tenantId, a = (e, t) => x(S(e, t), S("tenantId", i)), o = r.revisionId;
3118
+ if (o === null) {
3119
+ let t = await _c(e, `${String(r.contentType)}_drafts`, a("id", r.variantId), !0);
3120
+ if (t === void 0) return {
3121
+ ok: !1,
3122
+ reason: "unknown"
3123
+ };
3124
+ o = t.revisionId;
3125
+ }
3126
+ let s = await _c(e, M, x(a("id", o), S("documentId", r.documentId), S("contentType", r.contentType)), !0);
3127
+ return s === void 0 ? {
3128
+ ok: !1,
3129
+ reason: "unknown"
3130
+ } : {
3131
+ ok: !0,
3132
+ share: r,
3133
+ contentType: r.contentType,
3134
+ locale: r.locale,
3135
+ revisionId: o,
3136
+ revision: s.number,
3137
+ values: s.values ?? {}
3138
+ };
3139
+ }, bc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3140
+ let r = await _c(e, W, S("id", t));
3141
+ if (r === void 0) throw new y({
3142
+ contentType: W,
3143
+ id: t,
3144
+ stage: "share"
3145
+ });
3146
+ (r.revokedAt === null || r.revokedAt === void 0) && await e.update(W, t, { revokedAt: n });
3147
+ }, xc = (e, t, n) => e.query({
3148
+ table: W,
3149
+ predicate: x(S("contentType", t.name), S("documentId", n)),
3150
+ order: [{
3151
+ column: "createdAt",
3152
+ direction: "desc"
3153
+ }],
3154
+ take: void 0,
3155
+ skip: void 0,
3156
+ projection: void 0
3157
+ }), Sc = [y, kt], Cc = (...e) => j(() => vc(...e), ...Sc), wc = (...e) => j(() => xc(...e), ...Sc), Tc = (...e) => j(() => yc(...e), ...Sc), Ec = (...e) => j(() => bc(...e), ...Sc), Dc = (e) => `${e.name}_drafts`, Oc = async (e, t, n, r, i) => Ac(e, t, n, { publishAt: r }, i), kc = async (e, t, n, r, i) => Ac(e, t, n, { unpublishAt: r }, i), Ac = async (e, t, n, r, i) => {
3158
+ let a = Dc(t), o = await e.query({
3159
+ table: a,
3160
+ predicate: x(S("id", n), ...Object.entries(Ba(i)).map(([e, t]) => S(e, t))),
3161
+ order: [],
3162
+ take: 1,
3163
+ skip: void 0,
3164
+ projection: void 0
3165
+ });
3166
+ if (o[0] === void 0) throw new y({
3167
+ contentType: t.name,
3168
+ id: n,
3169
+ stage: "draft"
3170
+ });
3171
+ return await e.update(a, n, r) ?? o[0];
3172
+ }, jc = (e, t) => ({
3173
+ table: Dc(e),
3174
+ predicate: x(Ut("publishAt", t), S("status", "draft")),
3175
+ order: [],
3176
+ take: void 0,
3177
+ skip: void 0,
3178
+ projection: void 0
3179
+ }), Mc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3180
+ let r = await e.query(jc(t, n)), i = [];
3181
+ for (let n of r) {
3182
+ let r = n.id;
3183
+ if (typeof r != "string") continue;
3184
+ let a = {
3185
+ site: String(n.site),
3186
+ environment: String(n.environment),
3187
+ locale: String(n.locale)
3188
+ };
3189
+ try {
3190
+ await e.transactional(async (e) => {
3191
+ await eo(e, t, r, a), await e.update(Dc(t), r, { publishAt: null });
3192
+ });
3193
+ } catch (e) {
3194
+ if (e instanceof v || e instanceof d) continue;
3195
+ throw e;
3196
+ }
3197
+ i.push(r);
3198
+ }
3199
+ return i.length > 0 && $a(t), i;
3200
+ }, Nc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3201
+ let r = await e.query({
3202
+ table: Dc(t),
3203
+ predicate: Ut("unpublishAt", n),
3204
+ order: [],
3205
+ take: void 0,
3206
+ skip: void 0,
3207
+ projection: void 0
3208
+ }), i = [];
3209
+ for (let n of r) {
3210
+ let r = n.id;
3211
+ if (typeof r != "string") continue;
3212
+ let a = {
3213
+ site: String(n.site),
3214
+ environment: String(n.environment),
3215
+ locale: String(n.locale)
3216
+ };
3217
+ await e.transactional(async (e) => {
3218
+ let n = !0;
3219
+ try {
3220
+ await no(e, t, r, a);
3221
+ } catch (e) {
3222
+ if (!(e instanceof y)) throw e;
3223
+ n = !1;
3224
+ }
3225
+ return await e.update(Dc(t), r, { unpublishAt: null }), n;
3226
+ }) && i.push(r);
3227
+ }
3228
+ return i.length > 0 && $a(t), i;
3229
+ }, Pc = (...e) => j(() => Oc(...e), y), Fc = (...e) => j(() => kc(...e), y), Ic = (...e) => j(() => Mc(...e)), Lc = (...e) => j(() => Nc(...e)), Rc = (e) => Object.entries(e.fields).filter(([, e]) => e.kind === "media").map(([e]) => e), zc = async (e, t, n) => {
3230
+ if (t == null) return t;
3231
+ switch (e.kind) {
3232
+ case "media": return typeof t == "string" ? await n(t) ?? t : t;
3233
+ case "array": {
3234
+ let r = e.element;
3235
+ return r === void 0 || !Array.isArray(t) ? t : Promise.all(t.map((e) => zc(r, e, n)));
3236
+ }
3237
+ case "struct": {
3238
+ let r = e.struct;
3239
+ if (r === void 0 || typeof t != "object" || Array.isArray(t)) return t;
3240
+ let i = t, a = { ...i };
3241
+ for (let [e, t] of Object.entries(r)) e in i && (a[e] = await zc(t, i[e], n));
3242
+ return a;
3243
+ }
3244
+ default: return t;
3245
+ }
3246
+ }, Bc = async (e, t, n) => {
3247
+ let r = { ...t };
3248
+ for (let [i, a] of Object.entries(e.fields)) {
3249
+ let e = a;
3250
+ (e.kind === "media" || e.kind === "array" || e.kind === "struct") && i in t && (r[i] = await zc(e, t[i], n));
3251
+ }
3252
+ return r;
3253
+ }, Vc = async (e, t, n) => Promise.all(t.map((t) => Bc(e, t, n))), Hc = (e) => Rc(e), Uc = (...e) => j(() => Bc(...e)), Wc = (...e) => j(() => Vc(...e)), Gc = "/v1/cms/", Kc = (e) => {
3254
+ let t = e.authorization;
3255
+ return t && t.toLowerCase().startsWith("bearer ") ? t.slice(7).trim() : e["x-api-key"];
3256
+ }, qc = async (e, t) => {
3257
+ if (e.method.toUpperCase() !== "GET") return {
3258
+ status: 405,
3259
+ body: { error: "method_not_allowed" }
3260
+ };
3261
+ if (!e.path.startsWith(Gc)) return {
3262
+ status: 404,
3263
+ body: { error: "not_found" }
3264
+ };
3265
+ let n = Kc(e.headers), r = n ? t.apiKeys.find((e) => e.key === n) : void 0;
3266
+ if (!r) return {
3267
+ status: 401,
3268
+ body: { error: "unauthorized" }
3269
+ };
3270
+ let i = e.path.slice(8).split("/").filter((e) => e.length > 0), a = i[0];
3271
+ if (!a || !t.types.some((e) => e.name === a)) return {
3272
+ status: 404,
3273
+ body: { error: "unknown_content_type" }
3274
+ };
3275
+ if (!(r.types === void 0 || r.types.includes("*") || r.types.includes(a))) return {
3276
+ status: 403,
3277
+ body: {
3278
+ error: "forbidden",
3279
+ type: a
3280
+ }
3281
+ };
3282
+ if (i.length >= 2) {
3283
+ let e = i.slice(1).join("/"), n = await t.cms.contentType(a).where("slug", "=", e).one();
3284
+ return n ? {
3285
+ status: 200,
3286
+ body: n
3287
+ } : {
3288
+ status: 404,
3289
+ body: {
3290
+ error: "not_found",
3291
+ type: a,
3292
+ slug: e
3293
+ }
3294
+ };
3295
+ }
3296
+ let o = t.defaultLimit ?? 20, s = t.maxLimit ?? 100, c = Number(e.query?.limit), l = Number.isFinite(c) && c > 0 ? Math.min(c, s) : o;
3297
+ return {
3298
+ status: 200,
3299
+ body: await t.cms.contentType(a).limit(l).all()
3300
+ };
3301
+ }, G = "cms_publish_series", Jc = D(G, {
3302
+ id: C({ prefix: "cser" }),
3303
+ contentType: O().maxLength(64),
3304
+ draftId: O(),
3305
+ rule: T(),
3306
+ armed: w().default(-1),
3307
+ state: O().oneOf(["running", "done"]).default("running")
3308
+ }).with(A()).unique("cms_publish_series_uq_draft", ["tenantId", "draftId"]), Yc = (e, t, n) => e.query({
3309
+ table: t,
3310
+ predicate: n,
3311
+ order: [],
3312
+ take: void 0,
3313
+ skip: void 0,
3314
+ projection: void 0
3315
+ }), Xc = (e) => `${e.name}_drafts`, Zc = (e) => {
3316
+ let t = e.rule;
3317
+ return {
3318
+ id: String(e.id),
3319
+ rule: t,
3320
+ occurrences: fe(t),
3321
+ armed: Number(e.armed),
3322
+ state: e.state === "done" ? "done" : "running"
3323
+ };
3324
+ }, Qc = async (e, t) => {
3325
+ let [n] = await Yc(e, G, S("draftId", t));
3326
+ return n === void 0 ? null : Zc(n);
3327
+ }, $c = async (e, t, n, r, i, a) => {
3328
+ let o = r.findIndex((e, t) => t > i && e.endsAt.getTime() > a.getTime());
3329
+ if (o === -1) return -1;
3330
+ let s = r[o];
3331
+ return await e.update(Xc(t), n, {
3332
+ publishAt: s.startsAt,
3333
+ unpublishAt: s.endsAt
3334
+ }), o;
3335
+ }, el = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
3336
+ let o = nt(i);
3337
+ if (o.length > 0) throw new s({
3338
+ contentType: t.name,
3339
+ violations: o.map((e) => ({
3340
+ field: "repeat",
3341
+ rule: "recurrence",
3342
+ message: e
3343
+ }))
3344
+ });
3345
+ let [c] = await Yc(e, Xc(t), x(S("id", n), ...Object.entries(Ba(r)).map(([e, t]) => S(e, t))));
3346
+ if (c === void 0) throw new y({
3347
+ contentType: t.name,
3348
+ id: n,
3349
+ stage: "draft"
3350
+ });
3351
+ let l = await $c(e, t, n, fe(i), -1, a);
3352
+ if (l === -1) throw new s({
3353
+ contentType: t.name,
3354
+ violations: [{
3355
+ field: "repeat",
3356
+ rule: "recurrence",
3357
+ message: "every occurrence of this series is over"
3358
+ }]
3359
+ });
3360
+ for (let t of await Yc(e, G, S("draftId", n))) await e.delete(G, String(t.id));
3361
+ let u = c.tenantId !== void 0 && c.tenantId !== null ? { tenantId: c.tenantId } : {};
3362
+ return Zc(await e.insert(G, {
3363
+ contentType: t.name,
3364
+ draftId: n,
3365
+ rule: i,
3366
+ armed: l,
3367
+ state: "running",
3368
+ ...u
3369
+ }));
3370
+ }, tl = async (e, t, n) => {
3371
+ let r = await Yc(e, G, S("draftId", n));
3372
+ if (r.length === 0) return !1;
3373
+ for (let t of r) await e.delete(G, String(t.id));
3374
+ let [i] = await Yc(e, Xc(t), S("id", n));
3375
+ return i !== void 0 && await e.update(Xc(t), n, {
3376
+ publishAt: null,
3377
+ unpublishAt: null
3378
+ }), !0;
3379
+ }, nl = async (e, t, n = /* @__PURE__ */ new Date()) => {
3380
+ let r = [];
3381
+ for (let i of await Yc(e, G, x(S("contentType", t.name), S("state", "running")))) {
3382
+ let a = String(i.draftId);
3383
+ await e.transactional(async (e) => {
3384
+ let [o] = await Yc(e, Xc(t), S("id", a));
3385
+ if (o === void 0) {
3386
+ await e.delete(G, String(i.id));
3387
+ return;
3388
+ }
3389
+ let s = (e) => e != null;
3390
+ if (s(o.publishAt) || s(o.unpublishAt)) return;
3391
+ let c = await $c(e, t, a, fe(i.rule), Number(i.armed), n);
3392
+ await e.update(G, String(i.id), c === -1 ? { state: "done" } : { armed: c }), c !== -1 && r.push(a);
3393
+ });
3394
+ }
3395
+ return r;
3396
+ }, rl = [y, s], il = (...e) => j(() => nl(...e), ...rl), al = (...e) => j(() => tl(...e), ...rl), ol = (...e) => j(() => el(...e), ...rl), sl = (...e) => j(() => Qc(...e), ...rl), K = "cms_extensions", q = "cms_extension_data", J = "cms_extension_secrets", cl = D(K, {
3397
+ id: C({ prefix: "cext" }),
3398
+ extensionId: O(),
3399
+ manifest: T(),
3400
+ granted: T(),
3401
+ pending: T().nullable(),
3402
+ previous: T().nullable()
3403
+ }).with(A()).unique("cms_extensions_uq_extension", ["tenantId", "extensionId"]), ll = D(q, {
3404
+ id: C({ prefix: "cexd" }),
3405
+ extensionId: O(),
3406
+ key: O(),
3407
+ value: T()
3408
+ }).with(A()).unique("cms_extension_data_uq_key", [
3409
+ "tenantId",
3410
+ "extensionId",
3411
+ "key"
3412
+ ]), ul = D(J, {
3413
+ id: C({ prefix: "cexs" }),
3414
+ extensionId: O(),
3415
+ name: O(),
3416
+ value: O().encrypted().serverOnly()
3417
+ }).with(A()).unique("cms_extension_secrets_uq_name", [
3418
+ "tenantId",
3419
+ "extensionId",
3420
+ "name"
3421
+ ]), Y = (e, t, n) => e.query({
3422
+ table: t,
3423
+ predicate: n,
3424
+ order: [{
3425
+ column: "id",
3426
+ direction: "asc"
3427
+ }],
3428
+ take: void 0,
3429
+ skip: void 0,
3430
+ projection: void 0
3431
+ }), X = async (e, t) => (await Y(e, K, S("extensionId", t)))[0], Z = (e) => {
3432
+ let t = e.granted, n = e.pending, r = e.previous;
3433
+ return {
3434
+ extensionId: String(e.extensionId),
3435
+ manifest: e.manifest,
3436
+ granted: t,
3437
+ pending: n == null ? null : {
3438
+ manifest: n,
3439
+ adds: yt(t, n.capabilities)
3440
+ },
3441
+ previous: r == null ? null : r.manifest
3442
+ };
3443
+ }, dl = async (e) => (await Y(e, K, void 0)).map(Z).sort((e, t) => e.extensionId < t.extensionId ? -1 : 1), fl = async (e, t) => {
3444
+ let n = await X(e, t);
3445
+ return n === void 0 ? null : Z(n);
3446
+ }, pl = async (e, t, n) => {
3447
+ let r = dt(t);
3448
+ if (r.length > 0) return {
3449
+ ok: !1,
3450
+ reason: "invalidManifest",
3451
+ problems: r
3452
+ };
3453
+ let i = yt(n, t.capabilities);
3454
+ return i.length > 0 ? {
3455
+ ok: !1,
3456
+ reason: "consentIncomplete",
3457
+ missing: i
3458
+ } : await X(e, t.id) === void 0 ? {
3459
+ ok: !0,
3460
+ installed: Z(await e.insert(K, {
3461
+ extensionId: t.id,
3462
+ manifest: t,
3463
+ granted: [...t.capabilities],
3464
+ pending: null,
3465
+ previous: null
3466
+ }))
3467
+ } : {
3468
+ ok: !1,
3469
+ reason: "alreadyInstalled"
3470
+ };
3471
+ }, ml = async (e, t) => {
3472
+ let n = dt(t);
3473
+ if (n.length > 0) return {
3474
+ ok: !1,
3475
+ reason: "invalidManifest",
3476
+ problems: n
3477
+ };
3478
+ let r = await X(e, t.id);
3479
+ if (r === void 0) return {
3480
+ ok: !1,
3481
+ reason: "notInstalled"
3482
+ };
3483
+ let i = Z(r);
3484
+ if (Qe(t.version, i.manifest.version) <= 0) return {
3485
+ ok: !1,
3486
+ reason: "notNewer"
3487
+ };
3488
+ let a = yt(i.granted, t.capabilities).length === 0 ? {
3489
+ manifest: t,
3490
+ granted: [...t.capabilities],
3491
+ pending: null,
3492
+ previous: {
3493
+ manifest: i.manifest,
3494
+ granted: i.granted
3495
+ }
3496
+ } : { pending: t }, o = await e.update(K, String(r.id), a);
3497
+ return o === null ? {
3498
+ ok: !1,
3499
+ reason: "notInstalled"
3500
+ } : {
3501
+ ok: !0,
3502
+ installed: Z(o)
3503
+ };
3504
+ }, hl = async (e, t, n) => {
3505
+ let r = await X(e, t);
3506
+ if (r === void 0) return {
3507
+ ok: !1,
3508
+ reason: "notInstalled"
3509
+ };
3510
+ let { pending: i } = Z(r);
3511
+ if (i === null) return {
3512
+ ok: !1,
3513
+ reason: "nothingPending"
3514
+ };
3515
+ let a = yt(n, i.adds);
3516
+ if (a.length > 0) return {
3517
+ ok: !1,
3518
+ reason: "consentIncomplete",
3519
+ missing: a
3520
+ };
3521
+ let o = Z(r), s = await e.update(K, String(r.id), {
3522
+ manifest: i.manifest,
3523
+ granted: [...i.manifest.capabilities],
3524
+ pending: null,
3525
+ previous: {
3526
+ manifest: o.manifest,
3527
+ granted: o.granted
3528
+ }
3529
+ });
3530
+ return s === null ? {
3531
+ ok: !1,
3532
+ reason: "notInstalled"
3533
+ } : {
3534
+ ok: !0,
3535
+ installed: Z(s)
3536
+ };
3537
+ }, gl = async (e, t) => {
3538
+ let n = await X(e, t);
3539
+ if (n === void 0) return {
3540
+ ok: !1,
3541
+ reason: "notInstalled"
3542
+ };
3543
+ let r = n.previous;
3544
+ if (r == null) return {
3545
+ ok: !1,
3546
+ reason: "nothingToRollBack"
3547
+ };
3548
+ let i = await e.update(K, String(n.id), {
3549
+ manifest: r.manifest,
3550
+ granted: [...r.granted],
3551
+ pending: null,
3552
+ previous: null
3553
+ });
3554
+ return i === null ? {
3555
+ ok: !1,
3556
+ reason: "notInstalled"
3557
+ } : {
3558
+ ok: !0,
3559
+ installed: Z(i)
3560
+ };
3561
+ }, _l = async (e, t) => {
3562
+ let n = await X(e, t);
3563
+ if (n === void 0) return {
3564
+ ok: !1,
3565
+ reason: "notInstalled"
3566
+ };
3567
+ let r = await e.update(K, String(n.id), {
3568
+ granted: [],
3569
+ pending: null
3570
+ });
3571
+ return r === null ? {
3572
+ ok: !1,
3573
+ reason: "notInstalled"
3574
+ } : {
3575
+ ok: !0,
3576
+ installed: Z(r)
3577
+ };
3578
+ }, vl = async (e, t, n) => {
3579
+ let r = await X(e, t);
3580
+ if (r === void 0) return {
3581
+ ok: !1,
3582
+ reason: "notInstalled"
3583
+ };
3584
+ let { manifest: i } = Z(r), a = yt(n, i.capabilities);
3585
+ if (a.length > 0) return {
3586
+ ok: !1,
3587
+ reason: "consentIncomplete",
3588
+ missing: a
3589
+ };
3590
+ let o = await e.update(K, String(r.id), { granted: [...i.capabilities] });
3591
+ return o === null ? {
3592
+ ok: !1,
3593
+ reason: "notInstalled"
3594
+ } : {
3595
+ ok: !0,
3596
+ installed: Z(o)
3597
+ };
3598
+ }, yl = "voltro:settings", bl = async (e, t) => {
3599
+ let n = await fl(e, t);
3600
+ if (n === null) return null;
3601
+ let [r] = await Y(e, q, x(S("extensionId", t), S("key", yl))), i = r?.value;
3602
+ return it(n.manifest, typeof i == "object" && i ? i : {});
3603
+ }, xl = async (e, t, n) => {
3604
+ let r = await fl(e, t);
3605
+ if (r === null) return {
3606
+ ok: !1,
3607
+ reason: "notInstalled"
3608
+ };
3609
+ let i = Be(r.manifest, n);
3610
+ if (i.length > 0) return {
3611
+ ok: !1,
3612
+ reason: "invalid",
3613
+ problems: i
3614
+ };
3615
+ let a = {
3616
+ ...await bl(e, t),
3617
+ ...n
3618
+ }, [o] = await Y(e, q, x(S("extensionId", t), S("key", yl)));
3619
+ return o === void 0 ? await e.insert(q, {
3620
+ extensionId: t,
3621
+ key: yl,
3622
+ value: a
3623
+ }) : await e.update(q, String(o.id), { value: a }), {
3624
+ ok: !0,
3625
+ settings: it(r.manifest, a)
3626
+ };
3627
+ }, Sl = async (e, t) => {
3628
+ let n = await X(e, t);
3629
+ if (n === void 0) return {
3630
+ ok: !1,
3631
+ reason: "notInstalled"
3632
+ };
3633
+ let r = await Y(e, q, S("extensionId", t));
3634
+ for (let t of r) await e.delete(q, String(t.id));
3635
+ for (let n of await Y(e, J, S("extensionId", t))) await e.delete(J, String(n.id));
3636
+ return await e.delete(K, String(n.id)), {
3637
+ ok: !0,
3638
+ data: r.map((e) => ({
3639
+ key: String(e.key),
3640
+ value: e.value
3641
+ }))
3642
+ };
3643
+ }, Cl = async (e, t, n, r) => {
3644
+ let i = await fl(e, t);
3645
+ if (i === null) return {
3646
+ ok: !1,
3647
+ reason: "notInstalled"
3648
+ };
3649
+ if (![...i.manifest.capabilities, ...i.pending?.manifest.capabilities ?? []].includes(`secret:${n}`)) return {
3650
+ ok: !1,
3651
+ reason: "notAsked"
3652
+ };
3653
+ let [a] = await Y(e, J, x(S("extensionId", t), S("name", n)));
3654
+ return r === null ? a !== void 0 && await e.delete(J, String(a.id)) : a === void 0 ? await e.insert(J, {
3655
+ extensionId: t,
3656
+ name: n,
3657
+ value: r
3658
+ }) : await e.update(J, String(a.id), { value: r }), { ok: !0 };
3659
+ }, wl = async (e, t, n) => {
3660
+ let [r] = await Y(e, J, x(S("extensionId", t), S("name", n)));
3661
+ return typeof r?.value == "string" ? r.value : void 0;
3662
+ }, Tl = (e, t, n) => {
3663
+ let r = t.extensionId, i = (e) => {
3664
+ if (!t.granted.includes(e)) throw new ct({
3665
+ extensionId: r,
3666
+ capability: e
3667
+ });
3668
+ }, a = async (t) => (await Y(e, q, x(S("extensionId", r), S("key", t))))[0];
3669
+ return {
3670
+ extensionId: r,
3671
+ readContent: (e, t) => (i("content:read"), n.readContent(e, t)),
3672
+ listContent: (e) => (i("content:read"), n.listContent(e)),
3673
+ countContent: (e) => (i("content:read"), n.countContent(e)),
3674
+ readRevision: (e) => (i("content:read"), n.readRevision(e)),
3675
+ writeContent: (e, t, r) => (i("content:write"), n.writeContent(e, t, r)),
3676
+ fetch: (e, t) => {
3677
+ let a = URL.canParse(e) ? new URL(e) : null;
3678
+ if (a === null || a.protocol !== "https:" || a.port !== "") throw new ct({
3679
+ extensionId: r,
3680
+ capability: `egress:${e}`
3681
+ });
3682
+ return i(`egress:${a.hostname}`), n.fetch(a.href, t);
3683
+ },
3684
+ secret: (e) => (i(`secret:${e}`), n.secret(e)),
3685
+ settings: async () => await bl(e, r) ?? {},
3686
+ data: {
3687
+ get: async (e) => (await a(e))?.value,
3688
+ set: async (t, n) => {
3689
+ if (t === yl) throw new ct({
3690
+ extensionId: r,
3691
+ capability: "settings:write"
3692
+ });
3693
+ let i = await a(t);
3694
+ i === void 0 ? await e.insert(q, {
3695
+ extensionId: r,
3696
+ key: t,
3697
+ value: n
3698
+ }) : await e.update(q, String(i.id), { value: n });
3699
+ }
3700
+ }
3701
+ };
3702
+ }, El = (...e) => j(() => Cl(...e)), Dl = (...e) => j(() => hl(...e)), Ol = (...e) => j(() => wl(...e)), kl = (...e) => j(() => bl(...e)), Al = (...e) => j(() => xl(...e)), jl = (...e) => j(() => pl(...e)), Ml = (...e) => j(() => fl(...e)), Nl = (...e) => j(() => dl(...e)), Pl = (...e) => j(() => vl(...e)), Fl = (...e) => j(() => _l(...e)), Il = (...e) => j(() => gl(...e)), Ll = (...e) => j(() => Sl(...e)), Rl = (...e) => j(() => ml(...e)), zl = "cms_ai_operations", Q = "cms_ai_settings", Bl = [
3703
+ "suggested",
3704
+ "failed",
3705
+ "applied",
3706
+ "discarded"
3707
+ ], Vl = D(zl, {
3708
+ id: C({ prefix: "caio" }),
3709
+ operation: O(),
3710
+ version: O(),
3711
+ provider: O(),
3712
+ model: O(),
3713
+ contentType: O().maxLength(64),
3714
+ variantId: O().maxLength(64),
3715
+ revisionId: O().nullable(),
3716
+ field: O().nullable(),
3717
+ promptHash: O(),
3718
+ inputTokens: w().nullable(),
3719
+ outputTokens: w().nullable(),
3720
+ outcome: O().oneOf([...Bl]),
3721
+ error: O().nullable(),
3722
+ actor: O().nullable()
3723
+ }).with(A()), Hl = D(Q, {
3724
+ id: C({ prefix: "cais" }),
3725
+ provider: O(),
3726
+ model: O(),
3727
+ apiKey: O().encrypted().serverOnly().nullable(),
3728
+ monthlyTokens: w().nullable()
3729
+ }).with(A()).unique("cms_ai_settings_uq_tenant", ["tenantId"]), Ul = (e) => Kt("sha256").update(e).digest("hex"), Wl = async (e, t) => {
3730
+ let n = await e.insert(zl, {
3731
+ operation: t.operation,
3732
+ version: t.version,
3733
+ provider: t.provider,
3734
+ model: t.model,
3735
+ contentType: t.contentType,
3736
+ variantId: t.variantId,
3737
+ revisionId: t.revisionId ?? null,
3738
+ field: t.field ?? null,
3739
+ promptHash: Ul(t.prompt),
3740
+ inputTokens: t.usage?.inputTokens ?? null,
3741
+ outputTokens: t.usage?.outputTokens ?? null,
3742
+ outcome: t.outcome,
3743
+ error: t.error ?? null,
3744
+ actor: t.actor ?? null
3745
+ });
3746
+ return String(n.id);
3747
+ }, Gl = async (e, t, n) => {
3748
+ let [r] = await e.query({
3749
+ table: zl,
3750
+ predicate: S("id", t),
3751
+ order: [],
3752
+ take: 1,
3753
+ skip: void 0,
3754
+ projection: void 0
3755
+ });
3756
+ return r === void 0 || r.outcome !== "suggested" ? !1 : (await e.update(zl, t, { outcome: n }), !0);
3757
+ }, Kl = (e) => ({
3758
+ id: String(e.id),
3759
+ operation: String(e.operation),
3760
+ version: String(e.version),
3761
+ provider: String(e.provider),
3762
+ model: String(e.model),
3763
+ field: typeof e.field == "string" ? e.field : null,
3764
+ revisionId: typeof e.revisionId == "string" ? e.revisionId : null,
3765
+ outcome: e.outcome,
3766
+ inputTokens: typeof e.inputTokens == "number" ? e.inputTokens : null,
3767
+ outputTokens: typeof e.outputTokens == "number" ? e.outputTokens : null,
3768
+ at: e.createdAt instanceof Date ? e.createdAt.getTime() : new Date(String(e.createdAt ?? 0)).getTime()
3769
+ }), ql = async (e, t, n) => (await e.query({
3770
+ table: zl,
3771
+ predicate: x(S("contentType", t), S("variantId", n)),
3772
+ order: [{
3773
+ column: "createdAt",
3774
+ direction: "desc"
3775
+ }, {
3776
+ column: "id",
3777
+ direction: "desc"
3778
+ }],
3779
+ take: 200,
3780
+ skip: void 0,
3781
+ projection: void 0
3782
+ })).map(Kl), Jl = async (e, t) => {
3783
+ let [n] = await e.query({
3784
+ table: Q,
3785
+ predicate: S("tenantId", t),
3786
+ order: [],
3787
+ take: 1,
3788
+ skip: void 0,
3789
+ projection: void 0
3790
+ });
3791
+ return n === void 0 ? null : {
3792
+ provider: typeof n.provider == "string" && n.provider !== "" ? n.provider : null,
3793
+ model: typeof n.model == "string" && n.model !== "" ? n.model : null,
3794
+ apiKey: typeof n.apiKey == "string" && n.apiKey !== "" ? n.apiKey : null,
3795
+ monthlyTokens: typeof n.monthlyTokens == "number" ? n.monthlyTokens : null
3796
+ };
3797
+ }, Yl = (e = /* @__PURE__ */ new Date()) => new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), 1)), Xl = async (e, t, n = Yl()) => (await e.query({
3798
+ table: zl,
3799
+ predicate: x(S("tenantId", t), Bt("createdAt", n)),
3800
+ order: [],
3801
+ take: void 0,
3802
+ skip: void 0,
3803
+ projection: ["inputTokens", "outputTokens"]
3804
+ })).reduce((e, t) => e + (Number(t.inputTokens) || 0) + (Number(t.outputTokens) || 0), 0), Zl = async (e, t, n = /* @__PURE__ */ new Date()) => {
3805
+ let r = (await Jl(e, t))?.monthlyTokens ?? null;
3806
+ return r === null ? null : Math.max(0, r - await Xl(e, t, Yl(n)));
3807
+ }, Ql = async (e, t, n) => {
3808
+ let [r] = await e.query({
3809
+ table: Q,
3810
+ predicate: S("tenantId", t),
3811
+ order: [],
3812
+ take: 1,
3813
+ skip: void 0,
3814
+ projection: void 0
3815
+ }), i = n === null ? {
3816
+ provider: "",
3817
+ model: "",
3818
+ apiKey: null
3819
+ } : {
3820
+ provider: n.provider,
3821
+ model: n.model,
3822
+ ...n.apiKey === void 0 ? {} : { apiKey: n.apiKey }
3823
+ };
3824
+ if (r === void 0) {
3825
+ n !== null && await e.insert(Q, {
3826
+ apiKey: null,
3827
+ monthlyTokens: null,
3828
+ ...i,
3829
+ tenantId: t
3830
+ });
3831
+ return;
3832
+ }
3833
+ if (n === null && typeof r.monthlyTokens != "number") {
3834
+ await e.delete(Q, String(r.id));
3835
+ return;
3836
+ }
3837
+ await e.update(Q, String(r.id), i);
3838
+ }, $l = async (e, t, n) => {
3839
+ let [r] = await e.query({
3840
+ table: Q,
3841
+ predicate: S("tenantId", t),
3842
+ order: [],
3843
+ take: 1,
3844
+ skip: void 0,
3845
+ projection: void 0
3846
+ });
3847
+ if (r === void 0) {
3848
+ n !== null && await e.insert(Q, {
3849
+ provider: "",
3850
+ model: "",
3851
+ apiKey: null,
3852
+ monthlyTokens: n,
3853
+ tenantId: t
3854
+ });
3855
+ return;
3856
+ }
3857
+ if (n === null && r.provider === "") {
3858
+ await e.delete(Q, String(r.id));
3859
+ return;
3860
+ }
3861
+ await e.update(Q, String(r.id), { monthlyTokens: n });
3862
+ }, eu = (...e) => j(() => Zl(...e)), tu = (...e) => j(() => ql(...e)), nu = (...e) => j(() => Jl(...e)), ru = (...e) => j(() => Xl(...e)), iu = (...e) => j(() => $l(...e)), au = (...e) => j(() => Wl(...e)), ou = (...e) => j(() => Ql(...e)), su = (...e) => j(() => Gl(...e)), $ = "cms_glossary", cu = D($, {
3863
+ id: C({ prefix: "cgl" }),
3864
+ term: O(),
3865
+ termKey: O().maxLength(100),
3866
+ locale: O().maxLength(64),
3867
+ translation: O().nullable(),
3868
+ forbidden: T().nullable(),
3869
+ note: O().nullable()
3870
+ }).with(A()).unique("cms_glossary_uq_term", [
3871
+ "tenantId",
3872
+ "termKey",
3873
+ "locale"
3874
+ ]), lu = (e) => e.trim().toLowerCase(), uu = (e) => ({
3875
+ id: String(e.id),
3876
+ term: String(e.term),
3877
+ locale: String(e.locale),
3878
+ translation: typeof e.translation == "string" ? e.translation : null,
3879
+ forbidden: Array.isArray(e.forbidden) ? e.forbidden.filter((e) => typeof e == "string") : [],
3880
+ note: typeof e.note == "string" ? e.note : null
3881
+ }), du = (e) => {
3882
+ let t = [], n = e.term.trim();
3883
+ return (n === "" || n.length > 100) && t.push("a term has 1 to 100 characters"), /^[a-z]{2}(-[A-Z]{2})?$/.test(e.locale) || t.push(`"${e.locale}" is not a language`), (e.translation ?? "").length > 100 && t.push("a translation has at most 100 characters"), ((e.forbidden ?? []).length > 20 || (e.forbidden ?? []).some((e) => e.trim() === "" || e.length > 100)) && t.push("at most 20 forbidden translations of 1 to 100 characters"), t;
3884
+ }, fu = async (e, t, n) => {
3885
+ let r = {
3886
+ term: n.term.trim(),
3887
+ locale: n.locale,
3888
+ translation: n.translation === void 0 || n.translation === null || n.translation.trim() === "" ? null : n.translation.trim(),
3889
+ forbidden: [...new Set((n.forbidden ?? []).map((e) => e.trim()).filter((e) => e !== ""))],
3890
+ note: n.note === void 0 || n.note === null || n.note.trim() === "" ? null : n.note.trim()
3891
+ }, [i] = await e.query({
3892
+ table: $,
3893
+ predicate: x(S("tenantId", t), S("termKey", lu(n.term)), S("locale", n.locale)),
3894
+ order: [],
3895
+ take: 1,
3896
+ skip: void 0,
3897
+ projection: void 0
3898
+ });
3899
+ return i === void 0 ? (await e.insert($, {
3900
+ ...r,
3901
+ termKey: lu(n.term),
3902
+ tenantId: t
3903
+ }), "added") : (await e.update($, String(i.id), r), "replaced");
3904
+ }, pu = async (e, t, n) => {
3905
+ let [r] = await e.query({
3906
+ table: $,
3907
+ predicate: x(S("tenantId", t), S("id", n)),
3908
+ order: [],
3909
+ take: 1,
3910
+ skip: void 0,
3911
+ projection: void 0
3912
+ });
3913
+ return r !== void 0 && (await e.delete($, n), !0);
3914
+ }, mu = async (e, t, n) => (await e.query({
3915
+ table: $,
3916
+ predicate: n === void 0 ? S("tenantId", t) : x(S("tenantId", t), S("locale", n)),
3917
+ order: [{
3918
+ column: "termKey",
3919
+ direction: "asc"
3920
+ }],
3921
+ take: void 0,
3922
+ skip: void 0,
3923
+ projection: void 0
3924
+ })).map(uu), hu = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), gu = (e, t) => RegExp(`(^|[^\\p{L}\\p{N}])${hu(t.trim())}($|[^\\p{L}\\p{N}])`, "iu").test(e), _u = (e, t) => t.filter((t) => gu(e, t.term)), vu = (e, t) => t.flatMap((t) => t.forbidden.filter((t) => gu(e, t)).map((e) => ({
3925
+ term: t.term,
3926
+ found: e,
3927
+ use: t.translation
3928
+ }))), yu = (...e) => j(() => mu(...e)), bu = (...e) => j(() => pu(...e)), xu = (...e) => j(() => fu(...e));
392
3929
  //#endregion
393
- export { w as CONTENT_STATUSES, ee as ContentForm, c as ContentIdConflict, d as ContentNotFound, t as ContentValidationFailed, a as Schema, u as applyDerivations, G as archive, we as archiveEffect, P as cmsContext, he as contentTypeToEntities, i as contentViolations, F as createCmsClient, de as defineContentType, te as derivedFrom, Me as handleCmsRest, n as maxLength, ke as mediaFields, r as pattern, _e as previewToken, U as publish, X as publishDue, Ee as publishDueEffect, Se as publishEffect, $ as resolveMedia, Oe as resolveMediaAll, V as saveDraft, xe as saveDraftEffect, Y as schedulePublish, Z as schedulePublishEffect, l as slugify, o as unique, W as unpublish, Ce as unpublishEffect, ye as useCms, e as validateContent, A as verifyPreviewToken, s as widgetFor };
3930
+ export { Bl as AI_OUTCOMES, U as BlueprintInvalid, zl as CMS_AI_OPERATIONS_TABLE, Q as CMS_AI_SETTINGS_TABLE, Bi as CMS_AVAILABILITY_TABLE, Sr as CMS_CHANGES_TABLE, F as CMS_DRAFT_TEXTS_TABLE, H as CMS_EXPERIMENTS_TABLE, $o as CMS_EXPERIMENT_EVENTS_TABLE, K as CMS_EXTENSIONS_TABLE, q as CMS_EXTENSION_DATA_TABLE, J as CMS_EXTENSION_SECRETS_TABLE, $ as CMS_GLOSSARY_TABLE, Ln as CMS_PATHS_TABLE, W as CMS_PREVIEW_SHARES_TABLE, G as CMS_PUBLISH_SERIES_TABLE, Ti as CMS_QUALITY_EXCEPTIONS_TABLE, N as CMS_REDIRECTS_TABLE, er as CMS_REFERENCES_TABLE, z as CMS_RELEASES_TABLE, B as CMS_RELEASE_ITEMS_TABLE, ii as CMS_REVIEWS_TABLE, M as CMS_REVISIONS_TABLE, xn as CMS_SCOPE_COLUMNS, tn as CMS_SEARCH_TABLE, ya as CMS_STEWARDSHIP_TABLE, P as CMS_TEAM_INVITATIONS_TABLE, kr as CMS_TEAM_TABLE, g as CONTENT_FORM_STRINGS, Sn as CONTENT_STATUSES, et as ContentForm, ze as ContentGone, b as ContentIdConflict, y as ContentNotFound, s as ContentValidationFailed, At as EMPTY_EDIT_HISTORY, xt as EXTENSION_SLOTS, ct as ExtensionAccessDenied, _t as ExtensionManifestSchema, Ei as MAX_EXCEPTION_DAYS, te as MAX_LIST_LEVEL, u as MAX_OCCURRENCES, mc as MAX_PREVIEW_SHARE_DAYS, hs as MIN_READERS, kt as PreviewShareRejected, xe as QuotaExceeded, mo as RELEASE_STATUSES, ai as REVIEW_ACTIONS, d as ReferenceUnavailable, l as ReleaseNotEditable, v as ReviewRequired, rt as ReviewStepRefused, r as RevisionMismatch, ue as RichDocumentEditor, wt as RichDocumentView, pe as RichTextSurface, ke as Schema, He as VISUAL_EDITING_PROTOCOL, Ee as XliffInvalid, Jn as addRedirect, No as addToRelease, Os as adoptWinner, il as advanceSeries, eu as aiBudgetLeft, tu as aiOperationsFor, nu as aiSettings, ru as aiTokensUsed, Ct as alternatesOf, Ks as applyBlueprint, Yr as applyBlueprintTeam, Ue as applyDerivations, m as applyTranslation, ss as applyVariant, bi as approveReview, fo as archive, wi as assertApproved, qi as assertReferencesAvailable, os as assignVariant, El as bindExtensionSecret, js as blueprintRef, tt as buildTree, al as cancelSeries, Ze as changedFields, ae as checkTemplates, Vl as cmsAiOperationsTable, Hl as cmsAiSettingsTable, Vi as cmsAvailabilityTable, Cr as cmsChangesTable, yr as cmsContext, Xi as cmsDraftTextsTable, ts as cmsExperimentEventsTable, es as cmsExperimentsTable, ll as cmsExtensionDataTable, ul as cmsExtensionSecretsTable, cl as cmsExtensionsTable, cu as cmsGlossaryTable, Rn as cmsPathsTable, hc as cmsPreviewSharesTable, Jc as cmsPublishSeriesTable, Di as cmsQualityExceptionsTable, zn as cmsRedirectsTable, tr as cmsReferencesTable, go as cmsReleaseItemsTable, ho as cmsReleasesTable, oi as cmsReviewsTable, Fn as cmsRevisionsTable, rn as cmsSearchTable, ba as cmsStewardshipTable, jr as cmsTeamInvitationsTable, Ar as cmsTeamTable, Zi as collaborativeFields, $s as compareEnvironments, Qe as compareVersions, Dl as consentToUpgrade, Se as contentFormStrings, Pa as contentHealth, In as contentTypeToEntities, Qo as contentUsage, qe as contentViolations, ec as copyEnvironment, br as createCmsClient, Cc as createPreviewShare, Mo as createRelease, Ri as decideQualityException, Le as decodeEntities, bt as defineAudience, Fs as defineBlueprint, Ne as defineComponent, wn as defineContentType, ge as derivedFrom, ye as describeEdit, Oo as describeFailure, Ye as diffWords, _n as dropFromSearch, fc as duplicateGroups, Me as effectiveExposure, se as emptyRichDocument, xs as experimentById, cs as experimentFields, ks as experimentLineage, Ss as experimentResults, Tl as extensionSandbox, Ol as extensionSecret, kl as extensionSettings, Fe as fieldDiffs, Dt as fieldVersions, Ke as formPartOf, he as gateConsent, yu as glossary, du as glossaryInputProblems, vu as glossaryProblems, e as grantedPurposes, Yn as hadAddress, qc as handleCmsRest, f as hasMark, vn as indexForSearch, le as inheritedValue, ee as inlineFromDom, oe as inlineHtml, ve as inlineMarkupOf, _e as inlineText, jl as installExtension, Ml as installedExtension, Nl as installedExtensions, Zr as inviteToTeam, Xr as invitedRole, Ie as isExtensionCapability, c as isKnownZone, Ve as languagesOf, Cs as listExperiments, Pt as listNumberedAt, wc as listPreviewShares, Xn as listRedirects, Po as listReleaseItems, Io as listReleases, po as listRevisions, sa as liveDraftTexts, dt as manifestProblems, ie as matchUnits, at as matchesAudience, t as maxLength, Hc as mediaFields, Nt as mergeInline, Yl as monthStart, pt as moveEntry, Qi as movedTogether, a as newBlockId, yt as newCapabilities, ot as newVisualNonce, Te as normalizeRichDocument, de as normalizeTerms, fe as occurrencesOf, ca as openDraftTexts, _ as parseInlineMarkup, Xe as parseSourcePath, ht as parseXliff, We as pattern, Tt as pickVariant, Ce as plainTextOf, qs as planBlueprint, Qr as planBlueprintTeam, cc as planBulk, Yo as planPromotion, pr as previewToken, Xo as promote, Ul as promptHash, co as publish, Ic as publishDue, zo as publishDueReleases, Lo as publishRelease, lo as publishRevision, mt as publishViolations, Ge as purposesUsedBy, Ii as qualityExceptions, Oi as qualityFindings, zi as qualityViolations, Dr as readChanges, la as readDraftTexts, Je as readEditorMessage, Pe as readPreviewMessage, ua as rebaseDraftTexts, yn as rebuildSearch, Fa as recertify, au as recordAiOperation, Or as recordChange, o as recordEdit, ws as recordExperimentEvent, Zn as recordPaths, nt as recurrenceProblems, Qn as redirectTarget, Ot as redoEdit, rr as referencesOf, Pl as regrantExtension, Fo as releaseStatusOf, bu as removeGlossaryTerm, $n as removeRedirect, i as replaceText, xi as requestChanges, Li as requestQualityException, yi as requestReview, Uc as resolveMedia, Wc as resolveMediaAll, Tc as resolvePreviewShare, so as restoreRevision, pc as retireDuplicate, Vo as retryRelease, $a as revalidateContent, vi as reviewLog, Ci as reviewRequiredFor, Si as reviewStatus, Fl as revokeExtension, Ec as revokePreviewShare, $e as richDocumentFromContentful, ft as richDocumentFromHtml, De as richDocumentProblems, h as richDocumentReferences, Il as rollbackExtension, Bo as rollbackRelease, lc as runBulk, Ts as runningExperiment, oo as saveDraft, Pc as schedulePublish, Ro as scheduleRelease, ol as scheduleSeries, Fc as scheduleUnpublish, bn as searchContent, cn as searchTextOf, sl as seriesOf, iu as setAiBudget, ou as setAiSettings, Al as setExtensionSettings, xu as setGlossaryTerm, Ia as setOwner, ti as setReviewRequired, Be as settingsProblems, it as settingsWithDefaults, su as settleAiOperation, ut as sitemapUrls, vt as sitemapXml, St as slugify, hn as snippetOf, Et as sourceAttributes, jt as sourcePathOf, Es as startExperiment, La as startStewardship, Ra as stewardshipOf, Ds as stopExperiment, p as taxonomyValue, $r as teamDefaultRole, ei as teamInvitations, Pr as teamProblems, gt as templateOf, re as templateValues, je as templateViolations, _u as termsIn, ne as toXliff, we as toggleMark, _a as translationStatus, va as translationStatuses, Ae as translationUnits, da as typeDraftText, Ji as unavailableAmong, be as undoEdit, Ll as uninstallExtension, lt as unique, Oe as unitsHash, uo as unpublish, Lc as unpublishDue, Rl as upgradeExtension, xr as useCms, cr as usedBy, st as validateContent, Mt as valueText, mr as verifyPreviewToken, Re as visualMessage, ce as widgetFor, ni as withdrawInvitation, ri as workspaceReviewTypes, Yi as writeAvailability, n as zonedInstant };