@voltro/cms 0.81.0 → 0.83.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-BK3ZcL2P.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
+ ]), P = (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
+ }), Bn = (e) => [
353
+ S("site", e.site),
354
+ S("environment", e.environment),
355
+ S("locale", e.locale)
356
+ ], Vn = async (e, t, n, r) => {
357
+ if (t.tree === void 0 && t.address === void 0) return;
358
+ let i = await P(e, `${t.name}_published`, x(...Bn(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 P(e, Ln, x(S("contentType", t.name), ...Bn(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 P(e, N, x(S("contentType", t.name), ...Bn(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
+ }, Hn = 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 P(e, N, x(S("contentType", t.name), ...Bn(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
+ }, Un = async (e, t, n, r, i) => {
400
+ let a = i === void 0 ? [] : [S("tenantId", i)], [o] = await P(e, N, x(S("contentType", t), ...Bn(r), S("fromPath", n), ...a));
401
+ return o === void 0 ? null : String(o.documentId);
402
+ }, Wn = async (e, t, n, r) => {
403
+ let i = r.replace(/^\/+|\/+$/g, ""), [a] = await P(e, N, x(S("contentType", t.name), ...Bn(n), S("fromPath", i)));
404
+ return a !== void 0 && (await e.delete(N, String(a.id)), !0);
405
+ }, Gn = async (e, t, n, r, i) => {
406
+ let a = i === void 0 ? [] : [S("tenantId", i)], [o] = await P(e, Ln, x(S("contentType", t), ...Bn(r), S("path", n), ...a));
407
+ return o !== void 0 || await Un(e, t, n, r, i) !== null;
408
+ }, Kn = (e, t, n) => P(e, N, x(S("contentType", t), ...Bn(n))), qn = (...e) => j(() => Hn(...e)), Jn = (...e) => j(() => Gn(...e)), Yn = (...e) => j(() => Kn(...e)), Xn = (...e) => j(() => Vn(...e)), Zn = (...e) => j(() => Un(...e)), Qn = (...e) => j(() => Wn(...e)), $n = "cms_references", er = D($n, {
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"]), tr = (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) => tr(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)) tr(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)) tr(i, a.props[e], `${n}[${t}].props.${e}`, r);
446
+ });
447
+ return;
448
+ }
449
+ default: return;
450
+ }
451
+ }, nr = (e, t) => {
452
+ let n = [];
453
+ for (let [r, i] of Object.entries(e.fields)) tr(i, t[r], r, n);
454
+ return n;
455
+ }, rr = (e, t, n) => ({
456
+ table: $n,
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
+ }), ir = async (e, t, n, r) => {
463
+ for (let i of await e.query(rr(t, n, r))) await e.delete($n, i.id);
464
+ }, ar = async (e, t, n, r) => {
465
+ let i = n.id;
466
+ await ir(e, t, i, r);
467
+ let a = n.tenantId;
468
+ for (let o of nr(t, n)) await e.insert($n, {
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
+ }, or = async (e, t, n) => (await e.query({
481
+ table: $n,
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)), sr = (...e) => j(() => or(...e)), cr = 3600, lr = (e) => (Buffer.isBuffer(e) ? e : Buffer.from(e, "utf8")).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""), ur = (e) => Buffer.from(e.replace(/-/g, "+").replace(/_/g, "/"), "base64"), dr = (e) => e ?? process.env.VOLTRO_SESSION_SECRET ?? null, fr = (e, t, n = {}) => {
494
+ let r = dr(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 ?? cr)
500
+ }, a = lr(JSON.stringify(i));
501
+ return `${a}.${lr(qt("sha256", r).update(a).digest())}`;
502
+ }, pr = (e, t = {}) => {
91
503
  if (!e) return null;
92
- let n = k(t.secret);
504
+ let n = dr(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 = ur(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(ur(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
+ }, mr = (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
+ }, hr = (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
+ }, gr = (e, t) => ({
127
539
  where(n, r, i) {
128
- return M(e, {
540
+ return gr(e, {
129
541
  ...t,
130
- predicates: [...t.predicates, ve(n, r, i)]
542
+ predicates: [...t.predicates, mr(n, r, i)]
131
543
  });
132
544
  },
133
545
  orderBy(n, r = "asc") {
134
- return M(e, {
546
+ return gr(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 gr(e, {
144
556
  ...t,
145
557
  take: n
146
558
  });
147
559
  },
148
560
  offset(n) {
149
- return M(e, {
561
+ return gr(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(hr(t));
156
568
  },
157
569
  async one() {
158
- return (await e.query(j({
570
+ return (await e.query(hr({
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(hr({
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
+ }), _r = (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), or(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 Un(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 Gn(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), gr(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 ? pr(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,177 +732,2562 @@ 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
+ }, vr = (e, t, n) => _r(e, t, n.scope, n.secret), yr = (e) => _r(e.store, e.types, e.scope, e.secret), br = (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
+ }, xr = "cms_changes", Sr = D(xr, {
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
+ ]), Cr = async (e, t, n, r, i, a = {}) => {
756
+ if (t.changeFeed !== !0) return;
757
+ let o = n.tenantId;
758
+ await e.insert(xr, {
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
+ }, wr = (e) => e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : Number(e), Tr = 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: xr,
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: wr(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
+ }, Er = (...e) => j(() => Tr(...e)), Dr = (...e) => j(() => Cr(...e)), Or = "cms_team", F = "cms_team_invitations", kr = D(Or, {
798
+ id: C({ prefix: "ctm" }),
799
+ defaultRole: O().nullable(),
800
+ reviewRequired: T().nullable()
801
+ }).with(A()).unique("cms_team_uq_tenant", ["tenantId"]), Ar = D(F, {
802
+ id: C({ prefix: "cinv" }),
803
+ email: O().sensitive("pii"),
804
+ role: O()
805
+ }).with(A()).unique("cms_team_invitations_uq_email", ["tenantId", "email"]), jr = /^[^\s@]+@[^\s@]+\.[^\s@]+$/, Mr = /^[a-z][a-zA-Z0-9-]{0,39}$/, Nr = (e) => {
806
+ let t = [];
807
+ e.defaultRole !== void 0 && !Mr.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
+ jr.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), Mr.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
+ }, Pr = (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
+ }), Fr = async (e, t) => (await Pr(e, Or, S("tenantId", t)))[0], Ir = async (e, t, n, r) => {
825
+ let i = null;
826
+ if (n.defaultRole !== void 0) {
827
+ let a = await Fr(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(Or, {
832
+ defaultRole: n.defaultRole,
833
+ tenantId: t
834
+ }) : await e.update(Or, 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 Pr(e, F, 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(F, {
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 = Lr(await Fr(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 Rr(e, t, [...i, ...a]);
858
+ }
859
+ return {
860
+ defaultRole: i,
861
+ members: a,
862
+ reviewRequired: o
863
+ };
864
+ }, Lr = (e) => Array.isArray(e?.reviewRequired) ? e.reviewRequired.filter((e) => typeof e == "string") : [], Rr = async (e, t, n) => {
865
+ let r = await Fr(e, t), i = [...new Set(n)].sort();
866
+ r === void 0 ? await e.insert(Or, {
867
+ defaultRole: null,
868
+ reviewRequired: i,
869
+ tenantId: t
870
+ }) : await e.update(Or, String(r.id), { reviewRequired: i });
871
+ }, zr = async (e, t) => Lr(await Fr(e, t)), Br = async (e, t, n, r) => {
872
+ let i = Lr(await Fr(e, t)), a = r ? [...i, n] : i.filter((e) => e !== n);
873
+ return await Rr(e, t, a), [...new Set(a)].sort();
874
+ }, Vr = (e, t, n) => Ir(e, t, n, !1), Hr = (e, t, n) => Ir(e, t, n, !0), Ur = async (e, t) => {
875
+ let n = (await Fr(e, t))?.defaultRole;
876
+ return typeof n == "string" ? n : null;
877
+ }, Wr = async (e, t, n) => {
878
+ let [r] = await Pr(e, F, x(S("tenantId", t), S("email", n.trim().toLowerCase())));
879
+ return r === void 0 ? null : String(r.role);
880
+ }, Gr = async (e, t) => (await Pr(e, F, 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), Kr = async (e, t, n, r) => {
884
+ let i = n.trim().toLowerCase(), [a] = await Pr(e, F, x(S("tenantId", t), S("email", i)));
885
+ return a === void 0 ? (await e.insert(F, {
886
+ email: i,
887
+ role: r,
888
+ tenantId: t
889
+ }), "invited") : a.role === r ? "present" : (await e.update(F, String(a.id), { role: r }), "changed");
890
+ }, qr = async (e, t, n) => {
891
+ let [r] = await Pr(e, F, x(S("tenantId", t), S("email", n.trim().toLowerCase())));
892
+ return r !== void 0 && (await e.delete(F, String(r.id)), !0);
893
+ }, Jr = (...e) => j(() => Hr(...e)), Yr = (...e) => j(() => Wr(...e)), Xr = (...e) => j(() => Kr(...e)), Zr = (...e) => j(() => Vr(...e)), Qr = (...e) => j(() => Ur(...e)), $r = (...e) => j(() => Gr(...e)), ei = (...e) => j(() => Br(...e)), ti = (...e) => j(() => qr(...e)), ni = (...e) => j(() => zr(...e)), ri = "cms_reviews", ii = [
894
+ "requested",
895
+ "approved",
896
+ "changesRequested"
897
+ ], ai = D(ri, {
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(ii),
907
+ sequence: w().default(0),
908
+ actorId: O(),
909
+ note: O().nullable()
910
+ }).with(A()).index("cms_reviews_by_variant", ["contentType", "variantId"]), oi = (e) => [
911
+ S("site", e.site),
912
+ S("environment", e.environment),
913
+ S("locale", e.locale)
914
+ ], si = async (e, t, n, r, i = !1) => {
915
+ let [a] = await e.query({
916
+ table: `${t.name}_drafts`,
917
+ predicate: x(S("id", n), ...oi(r)),
918
+ order: [],
919
+ take: 1,
920
+ skip: void 0,
921
+ projection: void 0,
922
+ ...i ? { lock: "update" } : {}
265
923
  });
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({
924
+ if (a === void 0) throw new y({
925
+ contentType: t.name,
926
+ id: n,
927
+ stage: "draft"
928
+ });
929
+ return a;
930
+ }, ci = (e, t, n, r) => e.query({
931
+ table: ri,
932
+ predicate: x(S("contentType", t.name), S("variantId", n), ...oi(r)),
933
+ order: [{
934
+ column: "sequence",
935
+ direction: "desc"
936
+ }, {
937
+ column: "createdAt",
938
+ direction: "desc"
939
+ }],
940
+ take: void 0,
941
+ skip: void 0,
942
+ projection: void 0
943
+ }), li = async (e, t, n, r, i, a, o) => {
944
+ let [s] = await ci(e, t, String(n.id), r), c = Number(s?.sequence ?? 0) + 1;
945
+ return e.insert(ri, {
946
+ contentType: t.name,
947
+ variantId: n.id,
948
+ documentId: n.documentId,
949
+ site: r.site,
950
+ environment: r.environment,
951
+ locale: r.locale,
952
+ revisionId: n.revisionId,
953
+ action: i,
954
+ sequence: c,
955
+ actorId: a,
956
+ note: o ?? null
957
+ });
958
+ }, ui = (e, t, n) => {
959
+ let [r, i] = e;
960
+ if (r !== void 0 && i !== void 0 && Number(r.sequence ?? 0) === 0 && new Date(r.createdAt).getTime() === new Date(i.createdAt).getTime()) throw new rt({
961
+ contentType: t.name,
962
+ id: n,
963
+ reason: "ambiguousOrder"
964
+ });
965
+ return r;
966
+ }, di = async (e, t, n, r, i) => li(e, t, await si(e, t, n, r, !0), r, "requested", i.actorId, i.note), fi = async (e, t, n, i, a) => {
967
+ let o = await si(e, t, n, i, !0);
968
+ if (o.revisionId !== a) throw new r({
969
+ contentType: t.name,
970
+ id: n,
971
+ expected: a,
972
+ actual: String(o.revisionId)
973
+ });
974
+ let s = ui(await ci(e, t, n, i), t, n);
975
+ if (s === void 0 || s.action !== "requested" || s.revisionId !== a) throw new rt({
976
+ contentType: t.name,
977
+ id: n,
978
+ reason: "notInReview"
979
+ });
980
+ return {
981
+ draft: o,
982
+ request: s
983
+ };
984
+ }, pi = async (e, t, n, r, i) => {
985
+ let { draft: a, request: o } = await fi(e, t, n, r, i.revisionId);
986
+ if (i.allowSelfApproval !== !0 && o.actorId === i.actorId) throw new rt({
987
+ contentType: t.name,
988
+ id: n,
989
+ reason: "selfApproval"
990
+ });
991
+ return li(e, t, a, r, "approved", i.actorId, i.note);
992
+ }, mi = async (e, t, n, r, i) => {
993
+ let { draft: a } = await fi(e, t, n, r, i.revisionId);
994
+ return li(e, t, a, r, "changesRequested", i.actorId, i.note);
995
+ }, hi = async (e, t, n, r) => {
996
+ let i = await si(e, t, n, r), a = ui(await ci(e, t, n, r), t, n);
997
+ if (a === void 0) return {
998
+ state: "none",
999
+ revisionId: null,
1000
+ stale: !1,
1001
+ lastStep: null
1002
+ };
1003
+ let o = a.revisionId !== i.revisionId;
1004
+ return {
1005
+ state: o ? "none" : a.action === "requested" ? "inReview" : a.action === "approved" ? "approved" : "changesRequested",
1006
+ revisionId: a.revisionId,
1007
+ stale: o,
1008
+ lastStep: a
1009
+ };
1010
+ }, gi = async (e, t, n) => {
1011
+ let r = t.review?.required;
1012
+ if (r !== "workspace") return r === !0;
1013
+ let [i] = n === void 0 ? [] : await e.query({
1014
+ table: `${t.name}_drafts`,
1015
+ predicate: S("id", n),
1016
+ order: [],
1017
+ take: 1,
1018
+ skip: void 0,
1019
+ projection: void 0
1020
+ }), a = i?.tenantId;
1021
+ return typeof a == "string" && (await zr(e, a)).includes(t.name);
1022
+ }, _i = async (e, t, n, r, i) => {
1023
+ if (await gi(e, t, n) && (await e.query({
1024
+ table: "cms_reviews",
1025
+ predicate: x(S("contentType", t.name), S("variantId", n), S("revisionId", i), S("action", "approved"), ...oi(r)),
1026
+ order: [],
1027
+ take: 1,
1028
+ skip: void 0,
1029
+ projection: void 0
1030
+ })).length === 0) throw new v({
1031
+ contentType: t.name,
1032
+ id: n,
1033
+ revisionId: i
1034
+ });
1035
+ }, vi = (...e) => j(() => ci(...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, rt), Ci = (...e) => j(() => gi(...e)), wi = (...e) => j(() => _i(...e), v), Ti = "cms_quality_exceptions", Ei = 90, Di = D(Ti, {
1036
+ id: C({ prefix: "cqex" }),
1037
+ site: O().maxLength(64),
1038
+ environment: O().maxLength(64),
1039
+ locale: O().maxLength(64),
1040
+ contentType: O().maxLength(64),
1041
+ variantId: O().maxLength(64),
1042
+ ruleId: O().maxLength(64),
1043
+ reason: O(),
1044
+ status: O().oneOf([
1045
+ "requested",
1046
+ "approved",
1047
+ "rejected",
1048
+ "withdrawn"
1049
+ ]),
1050
+ requestedBy: O(),
1051
+ requestedAt: k(),
1052
+ decidedBy: O().nullable(),
1053
+ decidedAt: k().nullable(),
1054
+ note: O().nullable(),
1055
+ expiresAt: k()
1056
+ }).with(A()).index("cms_quality_exceptions_by_variant", [
1057
+ "contentType",
1058
+ "variantId",
1059
+ "ruleId"
1060
+ ]), Oi = (e, t) => (e.quality ?? []).filter((e) => e.check(t)).map((e) => ({
1061
+ ruleId: e.id,
1062
+ field: e.field,
1063
+ message: e.message,
1064
+ blocking: e.blocking !== !1
1065
+ })), ki = (e) => e instanceof Date ? e : new Date(String(e)), Ai = (e, t) => {
1066
+ let n = ki(e.expiresAt), r = String(e.status);
1067
+ return {
1068
+ id: String(e.id),
1069
+ ruleId: String(e.ruleId),
1070
+ reason: String(e.reason),
1071
+ state: (r === "approved" || r === "requested") && n.getTime() <= t.getTime() ? "expired" : r,
1072
+ requestedBy: String(e.requestedBy),
1073
+ requestedAt: ki(e.requestedAt),
1074
+ decidedBy: typeof e.decidedBy == "string" ? e.decidedBy : null,
1075
+ note: typeof e.note == "string" ? e.note : null,
1076
+ expiresAt: n
1077
+ };
1078
+ }, ji = (e, t, n) => [
1079
+ S("contentType", e.name),
1080
+ S("variantId", t),
1081
+ S("site", n.site),
1082
+ S("environment", n.environment),
1083
+ S("locale", n.locale)
1084
+ ], Mi = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => (await e.query({
1085
+ table: Ti,
1086
+ predicate: x(...ji(t, n, r)),
1087
+ order: [{
1088
+ column: "requestedAt",
1089
+ direction: "desc"
1090
+ }],
1091
+ take: void 0,
1092
+ skip: void 0,
1093
+ projection: void 0
1094
+ })).map((e) => Ai(e, i)), Ni = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1095
+ let o = (t.quality ?? []).find((e) => e.id === i.ruleId);
1096
+ if (o === void 0) return {
1097
+ ok: !1,
1098
+ reason: "unknownRule"
1099
+ };
1100
+ if (o.blocking === !1) return {
1101
+ ok: !1,
1102
+ reason: "notBlocking"
1103
+ };
1104
+ let s = i.reason.trim();
1105
+ if (s === "" || s.length > 500) return {
1106
+ ok: !1,
1107
+ reason: "noReason"
1108
+ };
1109
+ let c = (i.expiresAt.getTime() - a.getTime()) / 864e5;
1110
+ if (!(c > 0) || c > 90) return {
1111
+ ok: !1,
1112
+ reason: "badExpiry"
1113
+ };
1114
+ let [l] = await e.query({
1115
+ table: `${t.name}_drafts`,
1116
+ predicate: x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)),
1117
+ order: [],
1118
+ take: 1,
1119
+ skip: void 0,
1120
+ projection: void 0
1121
+ });
1122
+ if (l === void 0) throw new y({
279
1123
  contentType: t.name,
280
1124
  id: n,
281
1125
  stage: "draft"
282
1126
  });
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),
1127
+ if ((await Mi(e, t, n, r, a)).some((e) => e.ruleId === o.id && (e.state === "requested" || e.state === "approved"))) return {
1128
+ ok: !1,
1129
+ reason: "alreadyOpen"
1130
+ };
1131
+ let u = l.tenantId, d = await e.insert(Ti, {
1132
+ site: r.site,
1133
+ environment: r.environment,
1134
+ locale: r.locale,
1135
+ contentType: t.name,
1136
+ variantId: n,
1137
+ ruleId: o.id,
1138
+ reason: s,
1139
+ status: "requested",
1140
+ requestedBy: i.actorId,
1141
+ requestedAt: a,
1142
+ decidedBy: null,
1143
+ decidedAt: null,
1144
+ note: null,
1145
+ expiresAt: i.expiresAt,
1146
+ ...u == null ? {} : { tenantId: u }
1147
+ });
1148
+ return {
1149
+ ok: !0,
1150
+ id: String(d.id)
1151
+ };
1152
+ }, Pi = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1153
+ let [i] = await e.query({
1154
+ table: Ti,
1155
+ predicate: S("id", t),
1156
+ order: [],
1157
+ take: 1,
1158
+ skip: void 0,
1159
+ projection: void 0
1160
+ });
1161
+ if (i === void 0) return {
1162
+ ok: !1,
1163
+ reason: "notFound"
1164
+ };
1165
+ let a = Ai(i, r), o = n.note !== void 0 && n.note.trim() !== "" ? n.note.trim().slice(0, 500) : null;
1166
+ if (n.decision === "withdraw") return a.state === "requested" && a.requestedBy !== n.actorId ? {
1167
+ ok: !1,
1168
+ reason: "notRequester"
1169
+ } : a.state !== "requested" && a.state !== "approved" ? {
1170
+ ok: !1,
1171
+ reason: "notOpen"
1172
+ } : (await e.update(Ti, t, {
1173
+ status: "withdrawn",
1174
+ decidedBy: n.actorId,
1175
+ decidedAt: r,
1176
+ note: o
1177
+ }), {
1178
+ ok: !0,
1179
+ state: "withdrawn"
1180
+ });
1181
+ if (a.state !== "requested") return {
1182
+ ok: !1,
1183
+ reason: "notOpen"
1184
+ };
1185
+ if (a.requestedBy === n.actorId) return {
1186
+ ok: !1,
1187
+ reason: "selfApproval"
1188
+ };
1189
+ let s = n.decision === "approve" ? "approved" : "rejected";
1190
+ return await e.update(Ti, t, {
1191
+ status: s,
1192
+ decidedBy: n.actorId,
1193
+ decidedAt: r,
1194
+ note: o
1195
+ }), {
1196
+ ok: !0,
1197
+ state: s
1198
+ };
1199
+ }, Fi = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1200
+ let o = Oi(t, i).filter((e) => e.blocking);
1201
+ if (o.length === 0) return [];
1202
+ let s = new Set((await Mi(e, t, n, r, a)).filter((e) => e.state === "approved").map((e) => e.ruleId));
1203
+ return o.filter((e) => !s.has(e.ruleId)).map((e) => ({
1204
+ field: e.field,
1205
+ rule: `quality.${e.ruleId}`,
1206
+ message: e.message
1207
+ }));
1208
+ }, 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, {
1209
+ id: C({ prefix: "cavl" }),
1210
+ contentType: O().maxLength(64),
1211
+ documentId: O().maxLength(64),
1212
+ site: O().maxLength(64),
1213
+ environment: O().maxLength(64),
1214
+ availableUntil: k().nullable(),
1215
+ blocked: Ft().default(!1)
1216
+ }).with(A()).index("cms_availability_by_document", [
1217
+ "documentId",
1218
+ "site",
1219
+ "environment"
1220
+ ]), Hi = (e) => {
1221
+ if (e instanceof Date) return e;
1222
+ if (typeof e == "string" && e !== "") {
1223
+ let t = new Date(e);
1224
+ return Number.isNaN(t.getTime()) ? null : t;
1225
+ }
1226
+ return null;
1227
+ }, Ui = async (e, t, n, r) => {
1228
+ let i = t.availability;
1229
+ if (i === void 0) return;
1230
+ let a = {
1231
+ availableUntil: i.until === void 0 ? null : Hi(n[i.until]),
1232
+ blocked: i.blocked !== void 0 && n[i.blocked] === !0
1233
+ }, [o] = await e.query({
1234
+ table: Bi,
1235
+ predicate: x(S("contentType", t.name), S("documentId", n.documentId), S("site", r.site), S("environment", r.environment)),
291
1236
  order: [],
292
1237
  take: 1,
293
1238
  skip: void 0,
294
1239
  projection: void 0
295
1240
  });
296
- if (a[0] === void 0) throw new d({
1241
+ if (o !== void 0) {
1242
+ await e.update(Bi, o.id, a);
1243
+ return;
1244
+ }
1245
+ let s = n.tenantId;
1246
+ await e.insert(Bi, {
1247
+ contentType: t.name,
1248
+ documentId: n.documentId,
1249
+ site: r.site,
1250
+ environment: r.environment,
1251
+ ...a,
1252
+ ...s == null ? {} : { tenantId: s }
1253
+ });
1254
+ }, Wi = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1255
+ let i = /* @__PURE__ */ new Map(), a = [...new Set(t)];
1256
+ if (a.length === 0) return i;
1257
+ let o = await e.query({
1258
+ table: Bi,
1259
+ predicate: x(Vt("documentId", a), S("site", n.site), S("environment", n.environment)),
1260
+ order: [],
1261
+ take: void 0,
1262
+ skip: void 0,
1263
+ projection: void 0
1264
+ });
1265
+ for (let e of o) {
1266
+ let t = Hi(e.availableUntil);
1267
+ e.blocked === !0 ? i.set(e.documentId, "blocked") : t !== null && t.getTime() <= r.getTime() && i.set(e.documentId, "expired");
1268
+ }
1269
+ return i;
1270
+ }, Gi = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1271
+ let o = nr(t, r);
1272
+ if (o.length === 0) return;
1273
+ let s = await Wi(e, o.map((e) => e.targetDocumentId), i, a);
1274
+ if (s.size !== 0) throw new d({
1275
+ contentType: t.name,
1276
+ id: n,
1277
+ targets: o.filter((e) => s.has(e.targetDocumentId)).map((e) => ({
1278
+ path: e.path,
1279
+ contentType: e.targetType,
1280
+ documentId: e.targetDocumentId,
1281
+ reason: s.get(e.targetDocumentId)
1282
+ }))
1283
+ });
1284
+ }, Ki = [d], qi = (...e) => j(() => Gi(...e), ...Ki), Ji = (...e) => j(() => Wi(...e), ...Ki), Yi = (...e) => j(() => Ui(...e), ...Ki), I = "cms_draft_texts", Xi = D(I, {
1285
+ id: C({ prefix: "cdtx" }),
1286
+ contentType: O().maxLength(64),
1287
+ draftId: O(),
1288
+ field: O(),
1289
+ baseRevision: O(),
1290
+ state: It()
1291
+ }).with(A()).unique("cms_draft_texts_uq_field", [
1292
+ "tenantId",
1293
+ "draftId",
1294
+ "field"
1295
+ ]), 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({
1296
+ table: t,
1297
+ predicate: n,
1298
+ order: [],
1299
+ take: void 0,
1300
+ skip: void 0,
1301
+ projection: void 0
1302
+ }), ea = async (e, t, n) => {
1303
+ let [r] = await $i(e, `${t.name}_drafts`, S("id", n));
1304
+ if (r === void 0) throw new y({
297
1305
  contentType: t.name,
298
1306
  id: n,
299
1307
  stage: "draft"
300
1308
  });
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")),
1309
+ return r;
1310
+ }, ta = (e, t) => $i(e, I, S("draftId", t)), na = async (e, t, n) => {
1311
+ 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 } : {};
1312
+ for (let s of Zi(t)) {
1313
+ let c = a.get(s);
1314
+ if (c?.baseRevision === i) continue;
1315
+ c !== void 0 && await e.delete(I, String(c.id));
1316
+ let l = r[s];
1317
+ await e.insertIgnore(I, {
1318
+ contentType: t.name,
1319
+ draftId: n,
1320
+ field: s,
1321
+ baseRevision: i,
1322
+ state: Qt(typeof l == "string" ? l : "").encode(),
1323
+ ...o
1324
+ }, { conflictColumns: [
1325
+ "tenantId",
1326
+ "draftId",
1327
+ "field"
1328
+ ] });
1329
+ }
1330
+ return ta(e, n);
1331
+ }, ra = async (e, t, n) => {
1332
+ let [r] = await $i(e, I, S("id", t));
1333
+ if (r === void 0) throw new y({
1334
+ contentType: I,
1335
+ id: t,
1336
+ stage: "draft"
1337
+ });
1338
+ let i = r.state instanceof Uint8Array ? r.state : /* @__PURE__ */ new Uint8Array();
1339
+ return await e.update("cms_draft_texts", t, { state: i.length === 0 ? n : en(i, n) }) ?? r;
1340
+ }, ia = async (e, t) => {
1341
+ let n = (await ta(e, String(t.id))).filter((e) => e.baseRevision === t.revisionId);
1342
+ return {
1343
+ values: new Map(n.map((e) => [String(e.field), e.state instanceof Uint8Array && e.state.length > 0 ? $t(e.state) : ""])),
1344
+ rows: n
1345
+ };
1346
+ }, aa = async (e, t, n) => {
1347
+ for (let r of t) await e.update(I, String(r.id), { baseRevision: n });
1348
+ }, 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({
1349
+ table: t,
1350
+ predicate: n,
305
1351
  order: [],
306
1352
  take: void 0,
307
1353
  skip: void 0,
308
1354
  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));
1355
+ }), pa = 500, ma = async (e, t, n, r, ...i) => {
1356
+ let a = [];
1357
+ for (let o = 0; o < r.length; o += pa) a.push(...await fa(e, t, x(Vt(n, r.slice(o, o + pa)), ...i)));
1358
+ return a;
1359
+ }, 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) => {
1360
+ 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();
1361
+ for (let e of s) {
1362
+ let t = String(e.documentId);
1363
+ c.set(t, (c.get(t) ?? /* @__PURE__ */ new Map()).set(String(e.locale), e));
314
1364
  }
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)));
1365
+ 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) => {
1366
+ let n = e.get(i), r = n === void 0 ? void 0 : u.get(String(n.revisionId)), o = a.filter((e) => e !== i).map((i) => {
1367
+ let a = e.get(i);
1368
+ if (a === void 0) return {
1369
+ locale: i,
1370
+ state: "missing",
1371
+ variantId: null,
1372
+ changed: []
1373
+ };
1374
+ let o = String(a.id), s = u.get(String(a.revisionId))?.basedOn;
1375
+ if (typeof s != "string" || n === void 0) return {
1376
+ locale: i,
1377
+ state: "unknown",
1378
+ variantId: o,
1379
+ changed: []
1380
+ };
1381
+ if (s === n.revisionId) return {
1382
+ locale: i,
1383
+ state: "upToDate",
1384
+ variantId: o,
1385
+ changed: []
1386
+ };
1387
+ let c = f.get(s);
1388
+ return {
1389
+ locale: i,
1390
+ state: "outdated",
1391
+ variantId: o,
1392
+ changed: c === void 0 || r === void 0 ? [] : Ze(t.fields, c.values ?? {}, r.values ?? {})
1393
+ };
1394
+ });
1395
+ return {
1396
+ source: n === void 0 ? null : {
1397
+ variantId: String(n.id),
1398
+ revisionId: String(n.revisionId)
1399
+ },
1400
+ targets: o
1401
+ };
1402
+ };
1403
+ return new Map(o.map((e) => [e, p(c.get(e) ?? /* @__PURE__ */ new Map())]));
1404
+ }, _a = (...e) => j(() => ha(...e)), va = (...e) => j(() => ga(...e)), ya = "cms_stewardship", ba = D(ya, {
1405
+ id: C({ prefix: "cstw" }),
1406
+ contentType: O().maxLength(64),
1407
+ documentId: O().maxLength(64),
1408
+ site: O().maxLength(64),
1409
+ environment: O().maxLength(64),
1410
+ owner: O().nullable(),
1411
+ reviewDue: k().nullable(),
1412
+ reviewedAt: k().nullable(),
1413
+ reviewedBy: O().nullable(),
1414
+ reviewedRevision: O().nullable()
1415
+ }).with(A()).index("cms_stewardship_by_document", [
1416
+ "contentType",
1417
+ "documentId",
1418
+ "site",
1419
+ "environment"
1420
+ ]), xa = 864e5, Sa = (e, t, n, r) => e.query({
1421
+ table: t,
1422
+ predicate: n,
1423
+ order: [],
1424
+ take: r,
1425
+ skip: void 0,
1426
+ projection: void 0
1427
+ }), Ca = (e) => {
1428
+ if (e instanceof Date) return e;
1429
+ if (typeof e == "string" || typeof e == "number") {
1430
+ let t = new Date(e);
1431
+ return Number.isNaN(t.getTime()) ? null : t;
1432
+ }
1433
+ return null;
1434
+ }, 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) => {
1435
+ let n = Ca(e?.reviewDue);
1436
+ return {
1437
+ owner: wa(e?.owner),
1438
+ reviewDue: n,
1439
+ reviewedAt: Ca(e?.reviewedAt),
1440
+ reviewedBy: wa(e?.reviewedBy),
1441
+ reviewedRevision: wa(e?.reviewedRevision),
1442
+ review: Ea(n, t)
1443
+ };
1444
+ }, Oa = async (e, t, n, r, i, a) => {
1445
+ let o = await Ta(e, t.name, n, r);
1446
+ if (o !== void 0) return await e.update("cms_stewardship", String(o.id), i) ?? o;
1447
+ let s = a == null ? {} : { tenantId: a };
1448
+ return e.insert(ya, {
1449
+ contentType: t.name,
1450
+ documentId: n,
1451
+ site: r.site,
1452
+ environment: r.environment,
1453
+ owner: null,
1454
+ reviewDue: null,
1455
+ reviewedAt: null,
1456
+ reviewedBy: null,
1457
+ reviewedRevision: null,
1458
+ ...i,
1459
+ ...s
1460
+ });
1461
+ }, ka = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
1462
+ let o = t.lifecycle;
1463
+ if (o === void 0) return;
1464
+ let s = await Ta(e, t.name, n, r);
1465
+ (s === void 0 || s.reviewDue == null) && await Oa(e, t, n, r, { reviewDue: new Date(a.getTime() + o.reviewEveryDays * xa) }, i);
1466
+ }, 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) => {
1467
+ let a = i.now ?? /* @__PURE__ */ new Date();
1468
+ return Da(await Oa(e, t, n, r, {
1469
+ reviewDue: t.lifecycle === void 0 ? null : new Date(a.getTime() + t.lifecycle.reviewEveryDays * xa),
1470
+ reviewedAt: a,
1471
+ reviewedBy: i.by,
1472
+ reviewedRevision: i.revisionId
1473
+ }), a);
1474
+ }, Na = async (e, t, n, r) => {
1475
+ 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();
1476
+ for (let n of t) {
1477
+ let t = /* @__PURE__ */ new Map();
1478
+ for (let i of await Sa(e, `${n.name}_published`, x(...a, E("status", "archived")))) {
1479
+ let e = String(i.documentId), a = String(i.locale);
1480
+ t.set(e, (t.get(e) ?? /* @__PURE__ */ new Set()).add(a));
1481
+ let o = wa(i.title) ?? wa(i.name) ?? wa(i.slug) ?? e;
1482
+ (a === r.sourceLocale || !c.has(`${n.name}:${e}`)) && c.set(`${n.name}:${e}`, o);
326
1483
  }
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;
1484
+ s.set(n.name, t);
1485
+ }
1486
+ 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]));
1487
+ for (let a of t) {
1488
+ 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);
1489
+ for (let [e, n] of t) {
1490
+ let t = Da(u.get(`${a.name}:${e}`), i), s = {
1491
+ contentType: a.name,
1492
+ documentId: e,
1493
+ title: l(a.name, e)
1494
+ };
1495
+ if (t.owner === null && o.push({
1496
+ ...s,
1497
+ kind: "noOwner",
1498
+ locale: null,
1499
+ detail: []
1500
+ }), t.review === "due" && o.push({
1501
+ ...s,
1502
+ kind: "reviewDue",
1503
+ locale: null,
1504
+ detail: []
1505
+ }), n.has(r.sourceLocale)) for (let t of c.get(e)?.targets ?? []) t.state === "missing" && o.push({
1506
+ ...s,
1507
+ kind: "translationMissing",
1508
+ locale: t.locale,
1509
+ detail: []
1510
+ }), t.state === "outdated" && o.push({
1511
+ ...s,
1512
+ kind: "translationOutdated",
1513
+ locale: t.locale,
1514
+ detail: [...t.changed]
1515
+ });
333
1516
  }
334
- default: return t;
335
1517
  }
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));
1518
+ let d = /* @__PURE__ */ new Map();
1519
+ for (let t of await Sa(e, $n, x(...a))) {
1520
+ let e = s.get(String(t.targetType)), n = String(t.sourceType);
1521
+ if (e === void 0 || !s.has(n)) continue;
1522
+ let r = String(t.locale);
1523
+ if (e.get(String(t.targetDocumentId))?.has(r) === !0) continue;
1524
+ let i = String(t.sourceDocumentId), a = `${n}:${i}:${r}`, o = d.get(a) ?? {
1525
+ type: n,
1526
+ doc: i,
1527
+ locale: r,
1528
+ paths: []
1529
+ };
1530
+ o.paths.push(String(t.path)), d.set(a, o);
341
1531
  }
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" }
350
- };
351
- if (!e.path.startsWith(Ae)) return {
352
- status: 404,
353
- body: { error: "not_found" }
354
- };
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" }
359
- };
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" }
1532
+ for (let e of d.values()) o.push({
1533
+ kind: "linksToUnpublished",
1534
+ contentType: e.type,
1535
+ documentId: e.doc,
1536
+ locale: e.locale,
1537
+ title: l(e.type, e.doc),
1538
+ detail: e.paths
1539
+ });
1540
+ return o;
1541
+ }, 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)), L = (e) => `${e.name}_drafts`, za = (e) => `${e.name}_published`, Ba = (e) => ({
1542
+ site: e.site,
1543
+ environment: e.environment,
1544
+ locale: e.locale
1545
+ }), Va = (e) => [
1546
+ S("site", e.site),
1547
+ S("environment", e.environment),
1548
+ S("locale", e.locale)
1549
+ ], Ha = (e, t, n, r) => ({
1550
+ table: e,
1551
+ predicate: r === void 0 ? S("id", t) : x(S("id", t), ...Va(r)),
1552
+ order: [],
1553
+ take: 1,
1554
+ skip: void 0,
1555
+ projection: void 0,
1556
+ ...n === !0 ? { crossTenant: !0 } : {}
1557
+ }), R = async (e, t, n, r) => (await e.query(Ha(t, n, !1, r)))[0], z = (e, t) => {
1558
+ let n = {};
1559
+ for (let r of Object.keys(e.fields)) r in t && (n[r] = t[r]);
1560
+ return n;
1561
+ }, Ua = async (e, t, n, r, i) => {
1562
+ let a = t.tree;
1563
+ if (a === void 0) return;
1564
+ let o = Object.entries(a.inherit ?? {}).filter(([e, t]) => t.locked === !0 && n[e] !== void 0 && n[e] !== null && n[e] !== "");
1565
+ if (o.length > 0) throw new s({
1566
+ contentType: t.name,
1567
+ violations: o.map(([e]) => ({
1568
+ field: e,
1569
+ rule: "locked",
1570
+ message: `${e} is set for the whole site and cannot be changed on a page`
1571
+ }))
1572
+ });
1573
+ let c = n[a.parent];
1574
+ if (typeof c != "string" || c === "") return;
1575
+ let l = (e, n) => {
1576
+ throw new s({
1577
+ contentType: t.name,
1578
+ violations: [{
1579
+ field: a.parent,
1580
+ rule: e,
1581
+ message: n
1582
+ }]
1583
+ });
1584
+ }, u = async (n) => {
1585
+ let r = await e.query({
1586
+ table: L(t),
1587
+ predicate: x(S("documentId", n), S("site", i.site), S("environment", i.environment)),
1588
+ order: [],
1589
+ take: void 0,
1590
+ skip: void 0,
1591
+ projection: void 0
1592
+ });
1593
+ return r.find((e) => e.locale === i.locale) ?? r[0];
1594
+ }, d = /* @__PURE__ */ new Set(), f = c;
1595
+ for (; f !== null && !d.has(f);) {
1596
+ f === r && l("cycle", "the parent is this page or one of its descendants"), d.add(f);
1597
+ let e = await u(f);
1598
+ if (e === void 0) {
1599
+ f === c && l("unknown", `no ${t.name} document '${c}'`);
1600
+ return;
1601
+ }
1602
+ let n = e[a.parent];
1603
+ f = typeof n == "string" && n !== "" ? n : null;
1604
+ }
1605
+ }, Wa = () => {
1606
+ let e = Rt({
1607
+ kind: "typeid",
1608
+ prefix: "cdoc"
1609
+ }, M);
1610
+ if (e === null) throw Error("[voltro cms] the document id scheme did not mint an id.");
1611
+ return e;
1612
+ }, Ga = /* @__PURE__ */ new WeakMap(), Ka = (e) => {
1613
+ let t = Ga.get(e);
1614
+ t === void 0 && (t = In(e).draft.fields.id.idScheme, Ga.set(e, t));
1615
+ let n = t === void 0 ? null : Rt(t, L(e));
1616
+ if (n === null) throw Error(`[voltro cms] '${e.name}': the drafts table's id scheme does not mint ids up front.`);
1617
+ return n;
1618
+ }, qa = (e, t, n, r, i, a, o, s = null) => e.insert(M, {
1619
+ contentType: t.name,
1620
+ documentId: n,
1621
+ number: r,
1622
+ ...Ba(a),
1623
+ values: i,
1624
+ basedOn: s,
1625
+ ...o == null ? {} : { tenantId: o }
1626
+ }), Ja = (e, t, n, r) => e.query({
1627
+ table: M,
1628
+ predicate: x(S("contentType", t.name), S("documentId", n), ...Va(r)),
1629
+ order: [{
1630
+ column: "number",
1631
+ direction: "desc"
1632
+ }],
1633
+ take: void 0,
1634
+ skip: void 0,
1635
+ projection: void 0
1636
+ }), Ya = async (e, t) => {
1637
+ if (typeof t != "string" || t === "") return null;
1638
+ let [n] = await e.query({
1639
+ table: M,
1640
+ predicate: S("id", t),
1641
+ order: [],
1642
+ take: 1,
1643
+ skip: void 0,
1644
+ projection: void 0
1645
+ });
1646
+ return typeof n?.basedOn == "string" ? n.basedOn : null;
1647
+ }, Xa = async (e, t, n, r, i) => {
1648
+ if (i === void 0 || i.values.size === 0) return !1;
1649
+ let [a] = await e.query({
1650
+ table: M,
1651
+ predicate: S("id", n),
1652
+ order: [],
1653
+ take: 1,
1654
+ skip: void 0,
1655
+ projection: void 0
1656
+ });
1657
+ if (a === void 0) return !1;
1658
+ let o = Qi(t, new Set(i.values.keys()));
1659
+ return Ze(t.fields, a.values ?? {}, r).every((e) => o.has(e));
1660
+ }, Za = async (e, t, n, i, a = {}) => {
1661
+ let o = a.collaborative === !0 && typeof n.id == "string" ? await R(e, L(t), n.id, i) : void 0;
1662
+ if (o !== void 0) {
1663
+ let t = new Set((await ta(e, String(o.id))).map((e) => String(e.id)));
1664
+ for (let n of a.texts ?? []) t.has(n.id) && await ra(e, n.id, n.update);
1665
+ }
1666
+ 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, {
1667
+ ...n,
1668
+ ...Object.fromEntries(l)
1669
+ });
1670
+ st(t, u);
1671
+ let d = je(t, u);
1672
+ if (d.length > 0) throw new s({
1673
+ contentType: t.name,
1674
+ violations: [...d]
1675
+ });
1676
+ let f = L(t), p = z(t, u), m = async (n, r) => {
1677
+ await Ua(e, t, p, r, i);
1678
+ let o = await qa(e, t, r, 1, p, i, void 0, a.basedOn ?? null), s = await e.insert(f, {
1679
+ ...p,
1680
+ id: n,
1681
+ documentId: r,
1682
+ ...Ba(i),
1683
+ status: "draft",
1684
+ revisionId: o.id,
1685
+ revision: 1
1686
+ });
1687
+ return await un(e, t, s, i, "draft"), s;
1688
+ }, h = u.id, g = u.documentId;
1689
+ if (h === void 0) {
1690
+ if (g === void 0) return m(Ka(t), Wa());
1691
+ let n = await e.query({
1692
+ table: f,
1693
+ predicate: S("documentId", g),
1694
+ order: [],
1695
+ take: void 0,
1696
+ skip: void 0,
1697
+ projection: void 0
1698
+ });
1699
+ if (n.length === 0) throw new y({
1700
+ contentType: t.name,
1701
+ id: g,
1702
+ stage: "draft"
1703
+ });
1704
+ let r = n.find((e) => e.site === i.site && e.environment === i.environment && e.locale === i.locale);
1705
+ if (r !== void 0) throw new b({
1706
+ contentType: t.name,
1707
+ id: r.id
1708
+ });
1709
+ return m(Ka(t), g);
1710
+ }
1711
+ let _ = await R(e, f, h, i);
1712
+ if (_ !== void 0) {
1713
+ if (a.expectedRevision !== void 0 && _.revisionId !== a.expectedRevision && !await Xa(e, t, a.expectedRevision, _, c)) throw new r({
1714
+ contentType: t.name,
1715
+ id: h,
1716
+ expected: a.expectedRevision,
1717
+ actual: String(_.revisionId)
1718
+ });
1719
+ let n = Number(_.revision) + 1, o = _.documentId;
1720
+ await Ua(e, t, p, o, i);
1721
+ 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, {
1722
+ ...p,
1723
+ status: "draft",
1724
+ revisionId: l.id,
1725
+ revision: n
1726
+ });
1727
+ return c !== void 0 && await aa(e, c.rows, String(l.id)), await un(e, t, u ?? _, i, "draft"), u ?? _;
1728
+ }
1729
+ if ((await e.query(Ha(f, h, !0))).length > 0) throw new b({
1730
+ contentType: t.name,
1731
+ id: h
1732
+ });
1733
+ return m(h, g ?? Wa());
1734
+ }, Qa = async (e, t, n, r, i) => {
1735
+ let a = await R(e, L(t), n, r);
1736
+ if (a === void 0) throw new y({
1737
+ contentType: t.name,
1738
+ id: n,
1739
+ stage: "draft"
1740
+ });
1741
+ let [o] = await e.query({
1742
+ table: M,
1743
+ predicate: x(S("id", i), S("contentType", t.name), S("documentId", a.documentId), ...Va(r)),
1744
+ order: [],
1745
+ take: 1,
1746
+ skip: void 0,
1747
+ projection: void 0
1748
+ });
1749
+ if (o === void 0) throw new y({
1750
+ contentType: t.name,
1751
+ id: i,
1752
+ stage: "revision"
1753
+ });
1754
+ let s = o.values ?? {}, c = { id: n };
1755
+ for (let e of Object.keys(t.fields)) c[e] = e in s ? s[e] : null;
1756
+ return Za(e, t, c, r);
1757
+ }, $a = (e) => {
1758
+ let t = e.revalidate;
1759
+ if (t !== void 0) {
1760
+ for (let n of t.paths ?? []) Xt(n).catch((t) => {
1761
+ console.warn(`[voltro cms] revalidatePath('${n}') for '${e.name}' failed:`, t);
1762
+ });
1763
+ for (let n of t.tags ?? []) Zt(n).catch((t) => {
1764
+ console.warn(`[voltro cms] revalidateTag('${n}') for '${e.name}' failed:`, t);
1765
+ });
1766
+ }
1767
+ }, eo = async (e, t, n, i, a = {}) => {
1768
+ let o = await R(e, L(t), n, i);
1769
+ if (o === void 0) throw new y({
1770
+ contentType: t.name,
1771
+ id: n,
1772
+ stage: "draft"
1773
+ });
1774
+ let s = o.revisionId;
1775
+ if (a.revisionId !== void 0 && a.revisionId !== s) throw new r({
1776
+ contentType: t.name,
1777
+ id: n,
1778
+ expected: a.revisionId,
1779
+ actual: s
1780
+ });
1781
+ return to(e, t, n, i, s);
1782
+ }, to = async (e, t, n, r, i, a = {}) => {
1783
+ let o = await R(e, L(t), n, r);
1784
+ if (o === void 0) throw new y({
1785
+ contentType: t.name,
1786
+ id: n,
1787
+ stage: "draft"
1788
+ });
1789
+ let [c] = await e.query({
1790
+ table: M,
1791
+ predicate: x(S("id", i), S("contentType", t.name), S("documentId", o.documentId), ...Va(r)),
1792
+ order: [],
1793
+ take: 1,
1794
+ skip: void 0,
1795
+ projection: void 0
1796
+ });
1797
+ if (c === void 0) throw new y({
1798
+ contentType: t.name,
1799
+ id: i,
1800
+ stage: "revision"
1801
+ });
1802
+ let l = mt(t, c.values ?? {}), u = await Fi(e, t, n, r, c.values ?? {});
1803
+ if (l.length + u.length > 0) throw new s({
1804
+ contentType: t.name,
1805
+ violations: [...l, ...u]
1806
+ });
1807
+ await _i(e, t, n, r, i), await Gi(e, t, n, c.values ?? {}, r);
1808
+ let d = za(t), f = {
1809
+ ...z(t, c.values ?? {}),
1810
+ documentId: o.documentId,
1811
+ revisionId: i,
1812
+ revision: c.number
1813
+ }, p = await R(e, d, n, r), m;
1814
+ if (p !== void 0) m = await e.update(d, n, {
1815
+ ...f,
1816
+ status: "published"
1817
+ }) ?? p;
1818
+ else {
1819
+ let t = o.tenantId;
1820
+ m = await e.insert(d, {
1821
+ ...f,
1822
+ id: n,
1823
+ ...Ba(r),
1824
+ status: "published",
1825
+ ...t == null ? {} : { tenantId: t }
1826
+ });
1827
+ }
1828
+ return o.revisionId === i && await e.update(L(t), n, { status: "published" }), await ar(e, t, m, r), await Ui(e, t, m, r), await Vn(e, t, r, m.tenantId), await ka(e, t, String(o.documentId), r, m.tenantId), await Cr(e, t, m, r, "published", a), await un(e, t, m, r, "published"), m;
1829
+ }, no = async (e, t, n, r, i = {}) => {
1830
+ let a = await R(e, za(t), n, r);
1831
+ if (a === void 0) throw new y({
1832
+ contentType: t.name,
1833
+ id: n,
1834
+ stage: "published"
1835
+ });
1836
+ await Cr(e, t, a, r, "unpublished", i), await e.delete(za(t), n), await ir(e, t, n, r), await dn(e, t, n, ["published"]), await R(e, L(t), n, r) !== void 0 && await e.update(L(t), n, { status: "draft" });
1837
+ }, ro = async (e, t, n, r) => {
1838
+ let i = await R(e, L(t), n, r), a = await R(e, za(t), n, r);
1839
+ if (i === void 0 && a === void 0) throw new y({
1840
+ contentType: t.name,
1841
+ id: n,
1842
+ stage: "draft"
1843
+ });
1844
+ i !== void 0 && await e.update(L(t), n, { status: "archived" }), a !== void 0 && (await e.update(za(t), n, { status: "archived" }), await ir(e, t, n, r)), await dn(e, t, n, ["draft", "published"]);
1845
+ }, io = [
1846
+ s,
1847
+ b,
1848
+ y,
1849
+ r
1850
+ ], ao = [
1851
+ y,
1852
+ r,
1853
+ v,
1854
+ d,
1855
+ s
1856
+ ], 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)), B = "cms_releases", V = "cms_release_items", mo = [
1857
+ "draft",
1858
+ "scheduled",
1859
+ "published",
1860
+ "failed"
1861
+ ], ho = D(B, {
1862
+ id: C({ prefix: "crel" }),
1863
+ name: O(),
1864
+ site: O().maxLength(64),
1865
+ environment: O().maxLength(64),
1866
+ status: O().oneOf(mo),
1867
+ scheduledAt: k().nullable(),
1868
+ publishedAt: k().nullable(),
1869
+ rollbackOf: O().nullable(),
1870
+ claimToken: O().nullable(),
1871
+ failure: O().nullable()
1872
+ }).with(A()), go = D(V, {
1873
+ id: C({ prefix: "crit" }),
1874
+ releaseId: O(),
1875
+ contentType: O().maxLength(64),
1876
+ variantId: O().maxLength(64),
1877
+ locale: O().maxLength(64),
1878
+ action: O().oneOf(["publish", "unpublish"]),
1879
+ revisionId: O().nullable(),
1880
+ previousRevisionId: O().nullable(),
1881
+ position: w()
1882
+ }).with(A()).unique("cms_release_items_uq_variant", [
1883
+ "tenantId",
1884
+ "releaseId",
1885
+ "contentType",
1886
+ "variantId"
1887
+ ]), H = (e, t, n, r) => e.query({
1888
+ table: t,
1889
+ predicate: n,
1890
+ order: r === void 0 ? [] : [r],
1891
+ take: void 0,
1892
+ skip: void 0,
1893
+ projection: void 0
1894
+ }), _o = async (e, t) => {
1895
+ let [n] = await H(e, B, S("id", t));
1896
+ if (n === void 0) throw new y({
1897
+ contentType: "release",
1898
+ id: t,
1899
+ stage: "draft"
1900
+ });
1901
+ return n;
1902
+ }, vo = (e, t) => ({
1903
+ site: String(e.site),
1904
+ environment: String(e.environment),
1905
+ locale: t
1906
+ }), yo = (e, t) => e.insert(B, {
1907
+ ...t,
1908
+ status: "draft"
1909
+ }), bo = async (e, t, n) => {
1910
+ let r = await _o(e, t);
1911
+ if (r.status !== "draft") throw new l({
1912
+ id: t,
1913
+ status: String(r.status)
1914
+ });
1915
+ let i = vo(r, n.locale), [a] = await H(e, `${n.type.name}_drafts`, x(S("id", n.id), S("site", i.site), S("environment", i.environment), S("locale", i.locale)));
1916
+ if (a === void 0) throw new y({
1917
+ contentType: n.type.name,
1918
+ id: n.id,
1919
+ stage: "draft"
1920
+ });
1921
+ let o = n.action ?? "publish", s = await H(e, V, x(S("releaseId", t), S("contentType", n.type.name), S("variantId", n.id))), c = {
1922
+ action: o,
1923
+ locale: n.locale,
1924
+ revisionId: o === "publish" ? n.revisionId ?? String(a.revisionId) : null
1925
+ }, [u] = s;
1926
+ if (u !== void 0) return await e.update("cms_release_items", String(u.id), c) ?? u;
1927
+ let d = (await H(e, V, S("releaseId", t))).length;
1928
+ return e.insert(V, {
1929
+ releaseId: t,
1930
+ contentType: n.type.name,
1931
+ variantId: n.id,
1932
+ position: d,
1933
+ ...c
1934
+ });
1935
+ }, xo = async (e, t) => {
1936
+ let [n] = await H(e, B, S("id", t));
1937
+ return n === void 0 ? null : String(n.status);
1938
+ }, So = (e, t) => H(e, V, S("releaseId", t), {
1939
+ column: "position",
1940
+ direction: "asc"
1941
+ }), Co = (e, t) => H(e, B, x(S("site", t.site), S("environment", t.environment)), {
1942
+ column: "createdAt",
1943
+ direction: "desc"
1944
+ }), wo = async (e, t, n, r) => {
1945
+ let [i] = await H(e, `${t}_published`, x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)));
1946
+ return i === void 0 ? null : String(i.revisionId);
1947
+ }, To = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
1948
+ let i = await _o(e, n);
1949
+ if (i.status !== "draft" && i.status !== "scheduled") throw new l({
1950
+ id: n,
1951
+ status: String(i.status)
1952
+ });
1953
+ let a = new Map(t.map((e) => [e.name, e]));
1954
+ for (let t of await So(e, n)) {
1955
+ let r = a.get(String(t.contentType));
1956
+ if (r === void 0) throw new y({
1957
+ contentType: String(t.contentType),
1958
+ id: String(t.variantId),
1959
+ stage: "draft"
1960
+ });
1961
+ let o = vo(i, String(t.locale)), s = String(t.variantId), c = await wo(e, r.name, s, o);
1962
+ 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(V, String(t.id), { previousRevisionId: c });
1963
+ }
1964
+ return await e.update("cms_releases", n, {
1965
+ status: "published",
1966
+ publishedAt: r
1967
+ }) ?? i;
1968
+ }, Eo = async (e, t, n) => {
1969
+ let r = await _o(e, t);
1970
+ if (r.status !== "draft") throw new l({
1971
+ id: t,
1972
+ status: String(r.status)
1973
+ });
1974
+ return await e.update("cms_releases", t, {
1975
+ status: "scheduled",
1976
+ scheduledAt: n
1977
+ }) ?? r;
1978
+ }, Do = async (e, t, n = /* @__PURE__ */ new Date()) => {
1979
+ let r = await H(e, B, x(S("status", "scheduled"), Ut("scheduledAt", n))), i = [];
1980
+ for (let a of r) {
1981
+ let r = String(a.id), o = Rt({
1982
+ kind: "typeid",
1983
+ prefix: "claim"
1984
+ }, "cms_releases") ?? `claim_${Date.now()}`;
1985
+ try {
1986
+ 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);
1987
+ } catch (t) {
1988
+ await e.update(B, r, {
1989
+ status: "failed",
1990
+ failure: Oo(t)
1991
+ });
1992
+ }
1993
+ }
1994
+ return i;
1995
+ }, Oo = (e) => {
1996
+ if (e instanceof d) return `ReferenceUnavailable: ${e.contentType} ${e.id} uses ${e.targets.map((e) => `${e.contentType} ${e.documentId} (${e.reason})`).join(", ")}`;
1997
+ if (e instanceof v) return `ReviewRequired: ${e.contentType} ${e.id} revision ${e.revisionId} is not approved`;
1998
+ if (e instanceof y) return `ContentNotFound: ${e.contentType} ${e.id} (${e.stage})`;
1999
+ let t = e?._tag;
2000
+ return typeof t == "string" ? t : e instanceof Error ? e.message : String(e);
2001
+ }, ko = async (e, t) => {
2002
+ let n = await _o(e, t);
2003
+ if (n.status !== "failed") throw new l({
2004
+ id: t,
2005
+ status: String(n.status)
2006
+ });
2007
+ return await e.update("cms_releases", t, {
2008
+ status: "draft",
2009
+ failure: null,
2010
+ claimToken: null,
2011
+ scheduledAt: null
2012
+ }) ?? n;
2013
+ }, Ao = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
2014
+ let i = await _o(e, n);
2015
+ if (i.status !== "published") throw new l({
2016
+ id: n,
2017
+ status: String(i.status)
2018
+ });
2019
+ let a = await e.insert(B, {
2020
+ name: `Rollback of ${String(i.name)}`,
2021
+ site: i.site,
2022
+ environment: i.environment,
2023
+ status: "draft",
2024
+ rollbackOf: n,
2025
+ ...i.tenantId !== void 0 && i.tenantId !== null ? { tenantId: i.tenantId } : {}
2026
+ }), o = String(a.id), s = 0;
2027
+ for (let t of await So(e, n)) {
2028
+ let n = t.previousRevisionId;
2029
+ await e.insert(V, {
2030
+ releaseId: o,
2031
+ contentType: t.contentType,
2032
+ variantId: t.variantId,
2033
+ locale: t.locale,
2034
+ action: n == null ? "unpublish" : "publish",
2035
+ revisionId: n ?? null,
2036
+ position: s++,
2037
+ ...t.tenantId !== void 0 && t.tenantId !== null ? { tenantId: t.tenantId } : {}
2038
+ });
2039
+ }
2040
+ return To(e, t, o, r);
2041
+ }, jo = [
2042
+ y,
2043
+ l,
2044
+ v,
2045
+ d
2046
+ ], 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({
2047
+ table: t,
2048
+ predicate: x(S("site", n), S("environment", r), E("status", "archived"), ...i),
2049
+ order: [{
2050
+ column: "id",
2051
+ direction: "asc"
2052
+ }],
2053
+ take: void 0,
2054
+ skip: void 0,
2055
+ projection: void 0
2056
+ }), 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) => {
2057
+ for (let t of [
2058
+ "title",
2059
+ "name",
2060
+ "slug"
2061
+ ]) if (typeof e[t] == "string" && e[t] !== "") return e[t];
2062
+ return String(e.documentId);
2063
+ }, Go = (e) => `${String(e.documentId)}\u0000${String(e.locale)}`, Ko = async (e, t, n) => {
2064
+ let r = [];
2065
+ for (let i of t) {
2066
+ let t = await Ho(e, `${i.name}_published`, n.site, n.from);
2067
+ if (t.length === 0) continue;
2068
+ 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]));
2069
+ for (let e of t) {
2070
+ let t = a.get(Go(e)), n = o.get(Go(e)), s = {
2071
+ contentType: i.name,
2072
+ documentId: String(e.documentId),
2073
+ locale: String(e.locale),
2074
+ title: Wo(e)
2075
+ };
2076
+ if (n !== void 0 && n.status === "draft") {
2077
+ r.push({
2078
+ ...s,
2079
+ change: "blocked"
2080
+ });
2081
+ continue;
2082
+ }
2083
+ if (t === void 0) {
2084
+ r.push({
2085
+ ...s,
2086
+ change: "new"
2087
+ });
2088
+ continue;
2089
+ }
2090
+ Uo(z(i, e)) !== Uo(z(i, t)) && r.push({
2091
+ ...s,
2092
+ change: "changed"
2093
+ });
2094
+ }
2095
+ }
2096
+ return r;
2097
+ }, qo = async (e, t, n, r, i) => {
2098
+ if (r.length === 0) return {
2099
+ ok: !1,
2100
+ reason: "nothingSelected",
2101
+ items: []
2102
+ };
2103
+ 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}`));
2104
+ if (s.length > 0) return {
2105
+ ok: !1,
2106
+ reason: "notInPlan",
2107
+ items: s
2108
+ };
2109
+ let c = r.filter((e) => o.get(`${e.contentType}\u0000${e.documentId}\u0000${e.locale}`).change === "blocked");
2110
+ if (c.length > 0) return {
2111
+ ok: !1,
2112
+ reason: "blocked",
2113
+ items: c
2114
+ };
2115
+ let l = new Map(t.map((e) => [e.name, e])), u = await yo(e, {
2116
+ name: i.name,
2117
+ site: n.site,
2118
+ environment: n.to
2119
+ }), d = String(u.id);
2120
+ for (let t of r) {
2121
+ 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 = {
2122
+ site: n.site,
2123
+ environment: n.to,
2124
+ locale: t.locale
2125
+ }, [o] = await Ho(e, `${r.name}_drafts`, n.site, n.to, [S("documentId", t.documentId), S("locale", t.locale)]), s = z(r, i), c = await Za(e, r, o === void 0 ? {
2126
+ ...s,
2127
+ documentId: t.documentId
2128
+ } : {
2129
+ ...s,
2130
+ id: o.id
2131
+ }, a);
2132
+ await bo(e, d, {
2133
+ type: r,
2134
+ id: String(c.id),
2135
+ locale: t.locale,
2136
+ revisionId: String(c.revisionId)
2137
+ });
2138
+ }
2139
+ return await To(e, t, d), {
2140
+ ok: !0,
2141
+ releaseId: d,
2142
+ promoted: r.length
2143
+ };
2144
+ }, Jo = [
2145
+ s,
2146
+ b,
2147
+ y,
2148
+ r,
2149
+ l,
2150
+ v,
2151
+ d
2152
+ ], Yo = (...e) => j(() => Ko(...e), ...Jo), Xo = (...e) => j(() => qo(...e), ...Jo), Zo = async (e, t, n) => {
2153
+ let r = {}, i = /* @__PURE__ */ new Set();
2154
+ for (let a of t) {
2155
+ let t = await e.query({
2156
+ table: `${a.name}_drafts`,
2157
+ predicate: x(S("site", n), E("status", "archived")),
2158
+ order: [],
2159
+ take: void 0,
2160
+ skip: void 0,
2161
+ projection: void 0,
2162
+ groupBy: ["environment"],
2163
+ aggregations: [{
2164
+ op: "column",
2165
+ column: "environment",
2166
+ alias: "environment"
2167
+ }, {
2168
+ op: "count-distinct",
2169
+ column: "documentId",
2170
+ alias: "documents"
2171
+ }]
2172
+ });
2173
+ if (t.length > 1) {
2174
+ let [t] = await e.query({
2175
+ table: `${a.name}_drafts`,
2176
+ predicate: x(S("site", n), E("status", "archived")),
2177
+ order: [],
2178
+ take: void 0,
2179
+ skip: void 0,
2180
+ projection: void 0,
2181
+ aggregations: [{
2182
+ op: "count-distinct",
2183
+ column: "documentId",
2184
+ alias: "documents"
2185
+ }]
2186
+ });
2187
+ r[a.name] = Number(t?.documents ?? 0);
2188
+ } else r[a.name] = Number(t[0]?.documents ?? 0);
2189
+ for (let e of t) i.add(String(e.environment));
2190
+ }
2191
+ return {
2192
+ documents: Object.values(r).reduce((e, t) => e + t, 0),
2193
+ documentsByType: r,
2194
+ environments: [...i].sort()
2195
+ };
2196
+ }, Qo = (...e) => j(() => Zo(...e)), U = "cms_experiments", $o = "cms_experiment_events", es = D(U, {
2197
+ id: C({ prefix: "cexp" }),
2198
+ site: O().maxLength(64),
2199
+ environment: O().maxLength(64),
2200
+ locale: O().maxLength(64),
2201
+ contentType: O().maxLength(64),
2202
+ documentId: O().maxLength(64),
2203
+ name: O(),
2204
+ status: O().oneOf(["running", "stopped"]),
2205
+ share: w(),
2206
+ overrides: T(),
2207
+ goal: O(),
2208
+ hypothesis: O().nullable(),
2209
+ guardrailMaxDrop: w().nullable(),
2210
+ startedAt: k(),
2211
+ stoppedAt: k().nullable(),
2212
+ revisionId: O().maxLength(64).nullable(),
2213
+ adoptedReleaseId: O().maxLength(64).nullable(),
2214
+ adoptedRevisionId: O().maxLength(64).nullable()
2215
+ }).with(A()).index("cms_experiments_by_page", [
2216
+ "contentType",
2217
+ "documentId",
2218
+ "status"
2219
+ ]), ts = D($o, {
2220
+ id: C({ prefix: "cexe" }),
2221
+ experimentId: O(),
2222
+ variant: O().oneOf(["A", "B"]),
2223
+ kind: O().oneOf(["exposure", "conversion"]),
2224
+ reader: O(),
2225
+ revisionId: O().maxLength(64).nullable(),
2226
+ at: k()
2227
+ }).with(A()).unique("cms_experiment_events_once", [
2228
+ "experimentId",
2229
+ "reader",
2230
+ "kind"
2231
+ ]), ns = (e) => e instanceof Date ? e : new Date(String(e)), rs = (e) => typeof e == "string" && e !== "" ? e : null, is = (e) => ({
2232
+ id: String(e.id),
2233
+ name: String(e.name),
2234
+ contentType: String(e.contentType),
2235
+ documentId: String(e.documentId),
2236
+ locale: String(e.locale),
2237
+ status: e.status === "running" ? "running" : "stopped",
2238
+ share: Number(e.share),
2239
+ overrides: e.overrides ?? {},
2240
+ goal: String(e.goal),
2241
+ hypothesis: typeof e.hypothesis == "string" ? e.hypothesis : null,
2242
+ guardrailMaxDrop: typeof e.guardrailMaxDrop == "number" ? e.guardrailMaxDrop : null,
2243
+ startedAt: ns(e.startedAt),
2244
+ stoppedAt: e.stoppedAt === null || e.stoppedAt === void 0 ? null : ns(e.stoppedAt),
2245
+ revisionId: rs(e.revisionId),
2246
+ adoptedReleaseId: rs(e.adoptedReleaseId),
2247
+ adoptedRevisionId: rs(e.adoptedRevisionId)
2248
+ }), as = (e) => {
2249
+ let t = 2166136261;
2250
+ for (let n = 0; n < e.length; n++) t ^= e.charCodeAt(n), t = Math.imul(t, 16777619) >>> 0;
2251
+ return t >>> 0;
2252
+ }, os = (e, t, n) => as(`${e}:${t}`) % 100 < n ? "B" : "A", ss = (e, t, n) => n === "A" ? e : {
2253
+ ...e,
2254
+ ...t.overrides
2255
+ }, 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()) => {
2256
+ if (!Number.isInteger(r.share) || r.share < 1 || r.share > 99) return {
2257
+ ok: !1,
2258
+ reason: "badShare"
2259
+ };
2260
+ if (r.hypothesis.trim() === "" || r.hypothesis.length > 500) return {
2261
+ ok: !1,
2262
+ reason: "noHypothesis"
2263
+ };
2264
+ let a = r.guardrailMaxDrop ?? null;
2265
+ if (a !== null && (!Number.isInteger(a) || a < 1 || a > 50)) return {
2266
+ ok: !1,
2267
+ reason: "badGuardrail"
2268
+ };
2269
+ let o = Object.keys(r.overrides);
2270
+ if (o.length === 0) return {
2271
+ ok: !1,
2272
+ reason: "noOverrides"
2273
+ };
2274
+ let s = new Set(cs(t)), c = o.filter((e) => !s.has(e));
2275
+ if (c.length > 0) return {
2276
+ ok: !1,
2277
+ reason: "unknownField",
2278
+ fields: c
2279
+ };
2280
+ let l = [
2281
+ S("site", n.site),
2282
+ S("environment", n.environment),
2283
+ S("locale", n.locale),
2284
+ S("documentId", r.documentId)
2285
+ ], [u] = await e.query({
2286
+ table: `${t.name}_published`,
2287
+ predicate: x(...l),
2288
+ order: [],
2289
+ take: 1,
2290
+ skip: void 0,
2291
+ projection: void 0
2292
+ });
2293
+ if (u === void 0) return {
2294
+ ok: !1,
2295
+ reason: "notLive"
2296
+ };
2297
+ if (await ds(e, t, n, r.documentId) !== null) return {
2298
+ ok: !1,
2299
+ reason: "alreadyRunning"
2300
+ };
2301
+ let d = u.tenantId, f = await e.insert(U, {
2302
+ site: n.site,
2303
+ environment: n.environment,
2304
+ locale: n.locale,
2305
+ contentType: t.name,
2306
+ documentId: r.documentId,
2307
+ name: r.name,
2308
+ status: "running",
2309
+ share: r.share,
2310
+ overrides: { ...r.overrides },
2311
+ goal: r.goal,
2312
+ hypothesis: r.hypothesis.trim(),
2313
+ guardrailMaxDrop: a,
2314
+ startedAt: i,
2315
+ stoppedAt: null,
2316
+ revisionId: rs(u.revisionId),
2317
+ ...d == null ? {} : { tenantId: d }
2318
+ });
2319
+ return {
2320
+ ok: !0,
2321
+ id: String(f.id)
2322
+ };
2323
+ }, us = async (e, t, n = /* @__PURE__ */ new Date()) => {
2324
+ let [r] = await e.query({
2325
+ table: U,
2326
+ predicate: x(S("id", t), S("status", "running")),
2327
+ order: [],
2328
+ take: 1,
2329
+ skip: void 0,
2330
+ projection: void 0
2331
+ });
2332
+ return r !== void 0 && (await e.update(U, t, {
2333
+ status: "stopped",
2334
+ stoppedAt: n
2335
+ }), !0);
2336
+ }, ds = async (e, t, n, r) => {
2337
+ let [i] = await e.query({
2338
+ table: U,
2339
+ predicate: x(S("contentType", t.name), S("documentId", r), S("status", "running"), S("site", n.site), S("environment", n.environment), S("locale", n.locale)),
2340
+ order: [],
2341
+ take: 1,
2342
+ skip: void 0,
2343
+ projection: void 0
2344
+ });
2345
+ return i === void 0 ? null : is(i);
2346
+ }, fs = async (e, t) => {
2347
+ let [n] = await e.query({
2348
+ table: U,
2349
+ predicate: S("id", t),
2350
+ order: [],
2351
+ take: 1,
2352
+ skip: void 0,
2353
+ projection: void 0
2354
+ });
2355
+ return n === void 0 ? null : is(n);
2356
+ }, ps = async (e) => (await e.query({
2357
+ table: U,
2358
+ predicate: void 0,
2359
+ order: [{
2360
+ column: "startedAt",
2361
+ direction: "desc"
2362
+ }],
2363
+ take: 200,
2364
+ skip: void 0,
2365
+ projection: void 0
2366
+ })).map(is), ms = async (e, t, n, r, i = /* @__PURE__ */ new Date()) => {
2367
+ if (t.status !== "running" || n === "") return !1;
2368
+ let a = as(`${t.id}|${n}`).toString(36) + as(`${n}|${t.id}`).toString(36);
2369
+ if (r === "conversion") {
2370
+ let [n] = await e.query({
2371
+ table: $o,
2372
+ predicate: x(S("experimentId", t.id), S("reader", a), S("kind", "exposure")),
2373
+ order: [],
2374
+ take: 1,
2375
+ skip: void 0,
2376
+ projection: void 0
2377
+ });
2378
+ if (n === void 0) return !1;
2379
+ }
2380
+ let [o] = await e.query({
2381
+ table: U,
2382
+ predicate: S("id", t.id),
2383
+ order: [],
2384
+ take: 1,
2385
+ skip: void 0,
2386
+ projection: void 0
2387
+ }), s = o?.tenantId, [c] = o === void 0 ? [] : await e.query({
2388
+ table: `${t.contentType}_published`,
2389
+ predicate: x(S("documentId", t.documentId), S("site", String(o.site)), S("environment", String(o.environment)), S("locale", t.locale)),
2390
+ order: [],
2391
+ take: 1,
2392
+ skip: void 0,
2393
+ projection: void 0
2394
+ });
2395
+ return (await e.insertIgnoreWithOutcome($o, {
2396
+ experimentId: t.id,
2397
+ variant: os(t.id, n, t.share),
2398
+ kind: r,
2399
+ reader: a,
2400
+ revisionId: rs(c?.revisionId),
2401
+ at: i,
2402
+ ...s == null ? {} : { tenantId: s }
2403
+ }, { conflictColumns: [
2404
+ "experimentId",
2405
+ "reader",
2406
+ "kind"
2407
+ ] })).outcome === "inserted";
2408
+ }, hs = 100, gs = (e) => {
2409
+ 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);
2410
+ return e >= 0 ? (1 + n) / 2 : (1 - n) / 2;
2411
+ }, _s = async (e, t) => {
2412
+ let n = await e.query({
2413
+ table: $o,
2414
+ predicate: S("experimentId", t),
2415
+ order: [],
2416
+ take: void 0,
2417
+ skip: void 0,
2418
+ projection: void 0,
2419
+ groupBy: ["variant", "kind"],
2420
+ aggregations: [
2421
+ {
2422
+ op: "column",
2423
+ column: "variant",
2424
+ alias: "variant"
2425
+ },
2426
+ {
2427
+ op: "column",
2428
+ column: "kind",
2429
+ alias: "kind"
2430
+ },
2431
+ {
2432
+ op: "count",
2433
+ alias: "n"
2434
+ }
2435
+ ]
2436
+ }), r = (e, t) => Number(n.find((n) => n.variant === e && n.kind === t)?.n ?? 0), i = (e) => {
2437
+ let t = r(e, "exposure"), n = r(e, "conversion");
2438
+ return {
2439
+ readers: t,
2440
+ conversions: n,
2441
+ rate: t === 0 ? 0 : n / t
2442
+ };
2443
+ }, a = i("A"), o = i("B"), [s] = await e.query({
2444
+ table: U,
2445
+ predicate: S("id", t),
2446
+ order: [],
2447
+ take: 1,
2448
+ skip: void 0,
2449
+ projection: void 0
2450
+ }), 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;
2451
+ if (a.readers > 0 && o.readers > 0) {
2452
+ let e = (a.conversions + o.conversions) / (a.readers + o.readers), t = Math.sqrt(e * (1 - e) * (1 / a.readers + 1 / o.readers));
2453
+ u = t === 0 ? 1 : 2 * (1 - gs(Math.abs(o.rate - a.rate) / t));
2454
+ }
2455
+ return {
2456
+ A: a,
2457
+ B: o,
2458
+ lift: a.rate === 0 ? null : (o.rate - a.rate) / a.rate,
2459
+ pValue: u,
2460
+ conclusive: a.readers >= 100 && o.readers >= 100 && u !== null && u < .05,
2461
+ guardrail: {
2462
+ maxDrop: c,
2463
+ breached: l
2464
+ }
2465
+ };
2466
+ }, vs = async (e, t, n, r = /* @__PURE__ */ new Date()) => {
2467
+ let [i] = await e.query({
2468
+ table: U,
2469
+ predicate: S("id", n),
2470
+ order: [],
2471
+ take: 1,
2472
+ skip: void 0,
2473
+ projection: void 0
2474
+ });
2475
+ if (i === void 0 || i.contentType !== t.name) return {
2476
+ ok: !1,
2477
+ reason: "notFound"
2478
+ };
2479
+ let a = is(i);
2480
+ if (a.adoptedReleaseId !== null) return {
2481
+ ok: !1,
2482
+ reason: "alreadyAdopted"
2483
+ };
2484
+ let o = {
2485
+ site: String(i.site),
2486
+ environment: String(i.environment),
2487
+ locale: a.locale
2488
+ }, [s] = await e.query({
2489
+ table: `${t.name}_drafts`,
2490
+ predicate: x(S("documentId", a.documentId), S("site", o.site), S("environment", o.environment), S("locale", o.locale)),
2491
+ order: [],
2492
+ take: 1,
2493
+ skip: void 0,
2494
+ projection: void 0
2495
+ });
2496
+ if (s === void 0) return {
2497
+ ok: !1,
2498
+ reason: "noDraft"
2499
+ };
2500
+ a.status === "running" && await us(e, n, r);
2501
+ let c = await Za(e, t, {
2502
+ ...s,
2503
+ ...a.overrides
2504
+ }, o, { expectedRevision: String(s.revisionId) }), l = await yo(e, {
2505
+ name: `Adopt B: ${a.name}`.slice(0, 120),
2506
+ site: o.site,
2507
+ environment: o.environment
2508
+ }), u = String(l.id), d = String(c.revisionId);
2509
+ return await bo(e, u, {
2510
+ type: t,
2511
+ id: String(c.id),
2512
+ locale: o.locale,
2513
+ action: "publish",
2514
+ revisionId: d
2515
+ }), await e.update(U, n, {
2516
+ adoptedReleaseId: u,
2517
+ adoptedRevisionId: d
2518
+ }), {
2519
+ ok: !0,
2520
+ releaseId: u,
2521
+ revisionId: d
2522
+ };
2523
+ }, ys = async (e, t) => {
2524
+ let n = await fs(e, t);
2525
+ if (n === null) return null;
2526
+ let r = (await e.query({
2527
+ table: $o,
2528
+ predicate: x(S("experimentId", t), S("kind", "exposure")),
2529
+ order: [],
2530
+ take: void 0,
2531
+ skip: void 0,
2532
+ projection: void 0,
2533
+ groupBy: ["revisionId", "variant"],
2534
+ aggregations: [
2535
+ {
2536
+ op: "column",
2537
+ column: "revisionId",
2538
+ alias: "revisionId"
2539
+ },
2540
+ {
2541
+ op: "column",
2542
+ column: "variant",
2543
+ alias: "variant"
2544
+ },
2545
+ {
2546
+ op: "count",
2547
+ alias: "n"
2548
+ }
2549
+ ]
2550
+ })).map((e) => ({
2551
+ revisionId: rs(e.revisionId),
2552
+ variant: e.variant === "B" ? "B" : "A",
2553
+ readers: Number(e.n)
2554
+ })).sort((e, t) => String(e.revisionId).localeCompare(String(t.revisionId)) || e.variant.localeCompare(t.variant)), i = n.adoptedReleaseId === null || n.adoptedRevisionId === null ? null : {
2555
+ releaseId: n.adoptedReleaseId,
2556
+ revisionId: n.adoptedRevisionId,
2557
+ releaseStatus: await xo(e, n.adoptedReleaseId) ?? "gone"
2558
+ };
2559
+ return {
2560
+ startedOn: n.revisionId,
2561
+ overrides: n.overrides,
2562
+ delivered: r,
2563
+ adopted: i
2564
+ };
2565
+ }, bs = [
2566
+ s,
2567
+ b,
2568
+ y,
2569
+ r,
2570
+ l
2571
+ ], 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)), W = class extends Error {
2572
+ reason;
2573
+ _tag = "BlueprintInvalid";
2574
+ constructor(e) {
2575
+ super(`blueprint not usable: ${e}`), this.reason = e;
2576
+ }
2577
+ }, As = "$entry", js = (e) => ({ [As]: e }), Ms = (e) => {
2578
+ if (typeof e != "object" || !e || Array.isArray(e)) return;
2579
+ let t = Object.keys(e), n = e[As];
2580
+ return t.length === 1 && typeof n == "string" ? n : void 0;
2581
+ }, Ns = (e, t) => {
2582
+ let n = Ms(e);
2583
+ if (n !== void 0) t.add(n);
2584
+ else if (Array.isArray(e)) for (let n of e) Ns(n, t);
2585
+ else if (typeof e == "object" && e) for (let n of Object.values(e)) Ns(n, t);
2586
+ return t;
2587
+ }, Ps = (e, t) => {
2588
+ let n = Ms(e);
2589
+ 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);
2590
+ }, Fs = (e) => {
2591
+ let t = e.team === void 0 ? [] : Nr(e.team);
2592
+ if (t.length > 0) throw new W(t.join("; "));
2593
+ let n = /* @__PURE__ */ new Map();
2594
+ for (let t of e.entries) {
2595
+ if (n.has(t.key)) throw new W(`the key '${t.key}' is used twice`);
2596
+ n.set(t.key, t);
2597
+ }
2598
+ let r = new Map(e.entries.map((e) => [e.key, Ns([e.values, e.translations ?? {}], /* @__PURE__ */ new Set())]));
2599
+ for (let [e, t] of r) for (let r of t) if (!n.has(r)) throw new W(`'${e}' references '${r}', which is no entry`);
2600
+ let i = [], a = /* @__PURE__ */ new Map(), o = (e, t) => {
2601
+ if (a.get(e) !== "done") {
2602
+ if (a.get(e) === "visiting") throw new W(`the entries reference each other in a circle: ${[...t, e].join(" → ")}`);
2603
+ a.set(e, "visiting");
2604
+ for (let n of r.get(e) ?? []) o(n, [...t, e]);
2605
+ a.set(e, "done"), i.push(n.get(e));
2606
+ }
2607
+ };
2608
+ for (let t of e.entries) o(t.key, []);
2609
+ return {
2610
+ ...e,
2611
+ entries: i
2612
+ };
2613
+ }, Is = (e, t) => {
2614
+ let n = e.find((e) => e.name === t.type);
2615
+ if (n === void 0) throw new W(`'${t.key}' is of type '${t.type}', which this app does not have`);
2616
+ if (t.match !== void 0 && n.fields[t.match] === void 0) throw new W(`'${t.key}' matches on '${t.match}', which ${n.name} does not have`);
2617
+ return n;
2618
+ }, Ls = (e, t, n, r) => {
2619
+ let i = {};
2620
+ if (t.template !== void 0) {
2621
+ let n = re(e, t.template);
2622
+ if (n === null) throw new W(`'${t.key}' is built from the template '${t.template}', which ${e.name} does not have`);
2623
+ i = n;
2624
+ }
2625
+ let a = n === r ? {} : t.translations?.[n] ?? {};
2626
+ return {
2627
+ ...i,
2628
+ ...t.values,
2629
+ ...a
2630
+ };
2631
+ }, Rs = (e, t) => {
2632
+ if (typeof t.title == "string" && t.title !== "") return t.title;
2633
+ let n = e.match === void 0 ? void 0 : t[e.match];
2634
+ return typeof n == "string" && n !== "" ? n : e.key;
2635
+ }, zs = (e, t, n, r) => e.query({
2636
+ table: `${t.name}_drafts`,
2637
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", n.locale), ...r === null ? [] : [r]),
2638
+ order: [{
2639
+ column: "id",
2640
+ direction: "asc"
2641
+ }],
2642
+ take: 1,
2643
+ skip: void 0,
2644
+ projection: void 0
2645
+ }), Bs = async (e, t, n, r, i, a) => {
2646
+ if (a !== null) {
2647
+ let [n] = await zs(e, t, r, S("documentId", a));
2648
+ if (n !== void 0) return n;
2649
+ }
2650
+ let o = n.match === void 0 ? void 0 : i[n.match];
2651
+ if (n.match !== void 0 && (o == null || o === "")) return null;
2652
+ let [s] = await zs(e, t, r, n.match === void 0 ? null : S(n.match, o));
2653
+ return s ?? null;
2654
+ }, Vs = (e, t) => [e.locale, ...Object.keys(t.translations ?? {}).filter((t) => t !== e.locale)], Hs = async (e, t, n, r, i) => {
2655
+ let a = /* @__PURE__ */ new Map(), o = [], s = 0;
2656
+ for (let c of n.entries) {
2657
+ let l = Is(t, c), u = null, d = !1, f = !1;
2658
+ for (let t of Vs(n, c)) {
2659
+ if (f) break;
2660
+ let p = {
2661
+ site: r.site,
2662
+ environment: r.environment,
2663
+ locale: t
2664
+ }, m = Ls(l, c, t, n.locale), h = Ue(l, Ps(m, a)), g = await Bs(e, l, c, p, h, u);
2665
+ if (g !== null) {
2666
+ f = t === n.locale, u ??= String(g.documentId), o.push({
2667
+ key: c.key,
2668
+ type: l.name,
2669
+ locale: t,
2670
+ label: Rs(c, g),
2671
+ action: "present",
2672
+ documentId: String(g.documentId),
2673
+ variantId: String(g.id),
2674
+ outcome: null
2675
+ });
2676
+ continue;
2677
+ }
2678
+ let _ = Rs(c, h);
2679
+ u === null && !d && s++, d = !0;
2680
+ let ee = c.publish === !1 ? "draft" : l.review?.required === !0 || l.review?.required === "workspace" && (n.team?.reviewRequired ?? []).includes(l.name) ? "review" : "live";
2681
+ if (!i) {
2682
+ let e = ee;
2683
+ o.push({
2684
+ key: c.key,
2685
+ type: l.name,
2686
+ locale: t,
2687
+ label: _,
2688
+ action: "create",
2689
+ documentId: u,
2690
+ variantId: null,
2691
+ outcome: e
2692
+ });
2693
+ continue;
2694
+ }
2695
+ let te = await Za(e, l, {
2696
+ ...h,
2697
+ ...u === null ? {} : { documentId: u }
2698
+ }, p), ne = ee === "live" && await gi(e, l, String(te.id)) ? "review" : ee;
2699
+ ne === "live" && await eo(e, l, String(te.id), p), u ??= String(te.documentId), o.push({
2700
+ key: c.key,
2701
+ type: l.name,
2702
+ locale: t,
2703
+ label: _,
2704
+ action: "create",
2705
+ documentId: String(te.documentId),
2706
+ variantId: String(te.id),
2707
+ outcome: ne
2708
+ });
2709
+ }
2710
+ u !== null && a.set(c.key, u);
2711
+ }
2712
+ return {
2713
+ blueprint: n.id,
2714
+ steps: o,
2715
+ documents: s
2716
+ };
2717
+ }, Us = (e, t, n, r) => Hs(e, t, n, r, !1), Ws = (e, t, n, r) => Hs(e, t, n, r, !0), Gs = [
2718
+ W,
2719
+ b,
2720
+ y,
2721
+ s,
2722
+ d,
2723
+ v,
2724
+ r
2725
+ ], Ks = (...e) => j(() => Ws(...e), ...Gs), qs = (...e) => j(() => Us(...e), ...Gs), Js = (e, t, n, r) => e.query({
2726
+ table: t,
2727
+ predicate: x(S("site", n), S("environment", r), E("status", "archived")),
2728
+ order: [{
2729
+ column: "id",
2730
+ direction: "asc"
2731
+ }],
2732
+ take: void 0,
2733
+ skip: void 0,
2734
+ projection: void 0
2735
+ }), Ys = async (e, t, n) => {
2736
+ if (n.from === n.to) return {
2737
+ ok: !1,
2738
+ reason: "sameEnvironment",
2739
+ variants: 0
2740
+ };
2741
+ let r = 0;
2742
+ for (let i of t) r += (await Js(e, `${i.name}_drafts`, n.site, n.to)).length;
2743
+ if (r > 0) return {
2744
+ ok: !1,
2745
+ reason: "targetNotEmpty",
2746
+ variants: r
2747
+ };
2748
+ let i = 0, a = 0;
2749
+ for (let r of t) {
2750
+ 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();
2751
+ for (let c of t) {
2752
+ let t = {
2753
+ site: n.site,
2754
+ environment: n.to,
2755
+ locale: String(c.locale)
2756
+ }, l = String(c.documentId), u = c.tenantId, d = Ka(r), f = o.get(String(c.id)), p = z(r, c), m = 0, h;
2757
+ f !== void 0 && (h = await qa(e, r, l, ++m, z(r, f), t, u));
2758
+ 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 };
2759
+ if (await un(e, r, await e.insert(`${r.name}_drafts`, {
2760
+ ...p,
2761
+ id: d,
2762
+ documentId: l,
2763
+ ...Ba(t),
2764
+ status: c.status,
2765
+ revisionId: g.id,
2766
+ revision: g.number,
2767
+ ..._
2768
+ }), t, "draft"), i++, f !== void 0 && h !== void 0) {
2769
+ let n = await e.insert(`${r.name}_published`, {
2770
+ ...z(r, f),
2771
+ id: d,
2772
+ documentId: l,
2773
+ ...Ba(t),
2774
+ status: "published",
2775
+ revisionId: h.id,
2776
+ revision: h.number,
2777
+ ..._
2778
+ });
2779
+ await ar(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++;
2780
+ }
2781
+ }
2782
+ for (let t of s) {
2783
+ let [i, a] = t.split("\0");
2784
+ await Vn(e, r, {
2785
+ site: n.site,
2786
+ environment: n.to,
2787
+ locale: i
2788
+ }, a === "" ? void 0 : a);
2789
+ }
2790
+ }
2791
+ return {
2792
+ ok: !0,
2793
+ variants: i,
2794
+ published: a
2795
+ };
2796
+ }, 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) => {
2797
+ for (let t of [
2798
+ "title",
2799
+ "name",
2800
+ "slug"
2801
+ ]) if (typeof e[t] == "string" && e[t] !== "") return e[t];
2802
+ return String(e.documentId);
2803
+ }, Qs = async (e, t, n) => {
2804
+ let r = [];
2805
+ for (let i of t) {
2806
+ 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 = [];
2807
+ for (let [e, t] of c) {
2808
+ let n = l.get(e);
2809
+ n !== void 0 && Xs(z(i, t)) !== Xs(z(i, n)) && u.push({
2810
+ documentId: String(t.documentId),
2811
+ locale: String(t.locale),
2812
+ title: Zs(n)
2813
+ });
2814
+ }
2815
+ r.push({
2816
+ contentType: i.name,
2817
+ onlyInFrom: [...a].filter((e) => !o.has(e)).length,
2818
+ onlyInTo: [...o].filter((e) => !a.has(e)).length,
2819
+ differing: u
2820
+ });
2821
+ }
2822
+ return r;
2823
+ }, $s = (...e) => j(() => Qs(...e)), ec = (...e) => j(() => Ys(...e)), tc = async (e, t, n, r) => (await e.query({
2824
+ table: t,
2825
+ predicate: x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)),
2826
+ order: [],
2827
+ take: 1,
2828
+ skip: void 0,
2829
+ projection: void 0
2830
+ }))[0], nc = (e, t) => {
2831
+ for (let t of [
2832
+ "title",
2833
+ "name",
2834
+ "slug"
2835
+ ]) {
2836
+ let n = e?.[t];
2837
+ if (typeof n == "string" && n !== "") return n;
2838
+ }
2839
+ return t;
2840
+ }, rc = (e) => e.targets.map((e) => `${e.path}: ${e.reason}`), ic = async (e, t, n, r, i) => {
2841
+ let a = (e, t = {}) => ({
2842
+ ...i,
2843
+ documentId: null,
2844
+ title: i.id,
2845
+ revisionId: null,
2846
+ disposition: "blocked",
2847
+ reason: e,
2848
+ detail: [],
2849
+ ...t
2850
+ });
2851
+ if (t === void 0) return a("unknownType");
2852
+ let o = {
2853
+ ...n,
2854
+ locale: i.locale
2855
+ }, c = await tc(e, `${t.name}_drafts`, i.id, o);
2856
+ if (c === void 0) return a("notFound");
2857
+ let l = {
2858
+ documentId: String(c.documentId),
2859
+ title: nc(c, i.id)
2860
+ }, u = (e, t = null) => ({
2861
+ ...i,
2862
+ ...l,
2863
+ revisionId: t,
2864
+ disposition: e,
2865
+ reason: null,
2866
+ detail: []
2867
+ });
2868
+ if (r.kind === "unpublish") return await tc(e, `${t.name}_published`, i.id, o) === void 0 ? a("notPublished", l) : u("ready");
2869
+ if (r.kind === "setOwner") return u((await Aa(e, t, l.documentId, n)).owner === r.owner ? "unchanged" : "ready");
2870
+ if (r.kind === "setField") {
2871
+ let e = t.fields[r.field];
2872
+ if (e === void 0 || e.derived !== void 0 || e.kind === "richText" || e.kind === "components") return a("invalid", {
2873
+ ...l,
2874
+ detail: [`${r.field}: not a field this can set`]
2875
+ });
2876
+ let n = String(c.revisionId);
2877
+ if (JSON.stringify(c[r.field] ?? null) === JSON.stringify(r.value ?? null)) return u("unchanged", n);
2878
+ try {
2879
+ st(t, Ue(t, z(t, {
2880
+ ...c,
2881
+ [r.field]: r.value
2882
+ })));
2883
+ } catch (e) {
2884
+ if (e instanceof s) return a("invalid", {
2885
+ ...l,
2886
+ revisionId: n,
2887
+ detail: e.violations.map((e) => `${e.field}: ${e.message}`)
2888
+ });
2889
+ throw e;
2890
+ }
2891
+ return u("ready", n);
2892
+ }
2893
+ let f = String(c.revisionId);
2894
+ if ((await tc(e, `${t.name}_published`, i.id, o))?.revisionId === f) return u("unchanged", f);
2895
+ try {
2896
+ let [n] = await e.query({
2897
+ table: M,
2898
+ predicate: S("id", f),
2899
+ order: [],
2900
+ take: 1,
2901
+ skip: void 0,
2902
+ projection: void 0
2903
+ }), r = n?.values ?? {}, s = mt(t, r);
2904
+ if (s.length > 0) return a("incomplete", {
2905
+ ...l,
2906
+ revisionId: f,
2907
+ detail: s.map((e) => e.field)
2908
+ });
2909
+ await _i(e, t, i.id, o, f), await Gi(e, t, i.id, r, o);
2910
+ } catch (e) {
2911
+ if (e instanceof v) return a("reviewRequired", {
2912
+ ...l,
2913
+ revisionId: f
2914
+ });
2915
+ if (e instanceof d) return a("referenceUnavailable", {
2916
+ ...l,
2917
+ revisionId: f,
2918
+ detail: rc(e)
2919
+ });
2920
+ throw e;
2921
+ }
2922
+ return u("ready", f);
2923
+ }, ac = async (e, t, n, r, i) => {
2924
+ let a = new Map(t.map((e) => [e.name, e])), o = [];
2925
+ for (let t of i) o.push(await ic(e, a.get(t.type), n, r, t));
2926
+ return o;
2927
+ }, oc = async (e, t, n, i, a) => {
2928
+ let o = new Map(t.map((e) => [e.name, e])), c = [], l = /* @__PURE__ */ new Set();
2929
+ for (let t of a) {
2930
+ let a = {
2931
+ type: t.type,
2932
+ id: t.id,
2933
+ locale: t.locale,
2934
+ title: t.title
2935
+ };
2936
+ if (t.disposition !== "ready") {
2937
+ c.push({
2938
+ ...a,
2939
+ outcome: t.disposition === "unchanged" ? "unchanged" : "failed",
2940
+ reason: t.reason,
2941
+ detail: t.detail
2942
+ });
2943
+ continue;
2944
+ }
2945
+ let u = o.get(t.type), f = {
2946
+ ...n,
2947
+ locale: t.locale
2948
+ };
2949
+ try {
2950
+ if (u === void 0) throw new y({
2951
+ contentType: t.type,
2952
+ id: t.id,
2953
+ stage: "draft"
2954
+ });
2955
+ if (i.kind === "publish") await e.transactional((e) => to(e, u, t.id, f, t.revisionId ?? "")), l.add(u);
2956
+ else if (i.kind === "unpublish") await e.transactional((e) => no(e, u, t.id, f)), l.add(u);
2957
+ else if (i.kind === "setField") await e.transactional(async (e) => {
2958
+ let n = await tc(e, `${u.name}_drafts`, t.id, f);
2959
+ if (n === void 0) throw new y({
2960
+ contentType: t.type,
2961
+ id: t.id,
2962
+ stage: "draft"
2963
+ });
2964
+ await Za(e, u, {
2965
+ ...z(u, n),
2966
+ id: t.id,
2967
+ [i.field]: i.value
2968
+ }, f, t.revisionId === null ? {} : { expectedRevision: t.revisionId });
2969
+ });
2970
+ else {
2971
+ if (t.documentId === null) throw new y({
2972
+ contentType: t.type,
2973
+ id: t.id,
2974
+ stage: "draft"
2975
+ });
2976
+ await ja(e, u, t.documentId, n, i.owner);
2977
+ }
2978
+ c.push({
2979
+ ...a,
2980
+ outcome: "done",
2981
+ reason: null,
2982
+ detail: []
2983
+ });
2984
+ } catch (e) {
2985
+ 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)] : [];
2986
+ c.push({
2987
+ ...a,
2988
+ outcome: "failed",
2989
+ reason: t,
2990
+ detail: n
2991
+ });
2992
+ }
2993
+ }
2994
+ for (let e of l) $a(e);
2995
+ return c;
2996
+ }, sc = [
2997
+ b,
2998
+ y,
2999
+ s,
3000
+ d,
3001
+ v,
3002
+ r
3003
+ ], cc = (...e) => j(() => ac(...e), ...sc), lc = (...e) => j(() => oc(...e), ...sc), uc = async (e, t, n, r) => {
3004
+ let i = await e.query({
3005
+ table: `${t.name}_drafts`,
3006
+ predicate: x(S("site", n.site), S("environment", n.environment), S("locale", n.locale), E("status", "archived")),
3007
+ order: [{
3008
+ column: "createdAt",
3009
+ direction: "asc"
3010
+ }],
3011
+ take: void 0,
3012
+ skip: void 0,
3013
+ projection: void 0
3014
+ }), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
3015
+ for (let e of i) {
3016
+ let t = e[r.field];
3017
+ if (typeof t != "string" || t === "") continue;
3018
+ a.has(t) || a.set(t, r.fingerprint(t).catch(() => null));
3019
+ let n = await a.get(t);
3020
+ if (n === null) continue;
3021
+ let i = o.get(n) ?? [];
3022
+ i.push({
3023
+ id: String(e.id),
3024
+ documentId: String(e.documentId),
3025
+ title: String(e[r.titleField ?? "title"] ?? ""),
3026
+ status: String(e.status)
3027
+ }), o.set(n, i);
3028
+ }
3029
+ return [...o].filter(([, e]) => e.length > 1).map(([e, t]) => ({
3030
+ fingerprint: e,
3031
+ documents: t
3032
+ }));
3033
+ }, dc = async (e, t, n, r) => {
3034
+ if (r.copyId === r.keepId) return {
3035
+ ok: !1,
3036
+ reason: "notDuplicate"
3037
+ };
3038
+ let i = async (r) => {
3039
+ let [i] = await e.query({
3040
+ table: `${t.name}_drafts`,
3041
+ predicate: x(S("id", r), S("site", n.site), S("environment", n.environment), S("locale", n.locale)),
3042
+ order: [],
3043
+ take: 1,
3044
+ skip: void 0,
3045
+ projection: void 0
3046
+ });
3047
+ if (i === void 0) throw new y({
3048
+ contentType: t.name,
3049
+ id: r,
3050
+ stage: "draft"
3051
+ });
3052
+ return i;
3053
+ }, [a, o] = [await i(r.copyId), await i(r.keepId)], [s, c] = [a[r.field], o[r.field]];
3054
+ if (typeof s != "string" || typeof c != "string") return {
3055
+ ok: !1,
3056
+ reason: "notDuplicate"
3057
+ };
3058
+ let [l, u] = [await r.fingerprint(s), await r.fingerprint(c)];
3059
+ if (l === null || l !== u) return {
3060
+ ok: !1,
3061
+ reason: "notDuplicate"
3062
+ };
3063
+ let d = await or(e, {
3064
+ type: t.name,
3065
+ documentId: String(a.documentId)
3066
+ }, n);
3067
+ return d.length > 0 ? {
3068
+ ok: !1,
3069
+ reason: "inUse",
3070
+ usedBy: d
3071
+ } : (await ro(e, t, r.copyId, n), { ok: !0 });
3072
+ }, fc = (...e) => j(() => uc(...e)), pc = (...e) => j(() => dc(...e), y), G = "cms_preview_shares", mc = 30, hc = D(G, {
3073
+ id: C({ prefix: "cshr" }),
3074
+ contentType: O().maxLength(64),
3075
+ variantId: O().maxLength(64),
3076
+ documentId: O().maxLength(64),
3077
+ site: O().maxLength(64),
3078
+ environment: O().maxLength(64),
3079
+ locale: O().maxLength(64),
3080
+ revisionId: O().nullable(),
3081
+ tokenHash: O().unique(),
3082
+ label: O().nullable(),
3083
+ expiresAt: k(),
3084
+ revokedAt: k().nullable()
3085
+ }).with(A()), gc = (e) => Kt("sha256").update(e, "utf8").digest("hex"), _c = async (e, t, n, r = !1) => (await e.query({
3086
+ table: t,
3087
+ predicate: n,
3088
+ order: [],
3089
+ take: 1,
3090
+ skip: void 0,
3091
+ projection: void 0,
3092
+ ...r ? { crossTenant: !0 } : {}
3093
+ }))[0], vc = async (e, t, n, r, i) => {
3094
+ let a = i.now ?? /* @__PURE__ */ new Date();
3095
+ if (i.expiresAt.getTime() <= a.getTime()) throw new kt({ reason: "expiryInPast" });
3096
+ if (i.expiresAt.getTime() > a.getTime() + 2592e6) throw new kt({ reason: "expiryTooFar" });
3097
+ let o = await _c(e, `${t.name}_drafts`, x(S("id", n), S("site", r.site), S("environment", r.environment), S("locale", r.locale)));
3098
+ if (o === void 0) throw new y({
3099
+ contentType: t.name,
3100
+ id: n,
3101
+ stage: "draft"
3102
+ });
3103
+ let s = Jt(32).toString("base64url");
3104
+ return {
3105
+ share: await e.insert(G, {
3106
+ contentType: t.name,
3107
+ variantId: n,
3108
+ documentId: o.documentId,
3109
+ site: r.site,
3110
+ environment: r.environment,
3111
+ locale: r.locale,
3112
+ revisionId: i.revision === "pinned" ? o.revisionId : null,
3113
+ tokenHash: gc(s),
3114
+ label: i.label ?? null,
3115
+ expiresAt: i.expiresAt,
3116
+ revokedAt: null
3117
+ }),
3118
+ token: s
3119
+ };
3120
+ }, yc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3121
+ let r = await _c(e, G, S("tokenHash", gc(t)), !0);
3122
+ if (r === void 0) return {
3123
+ ok: !1,
3124
+ reason: "unknown"
3125
+ };
3126
+ if (r.revokedAt !== null && r.revokedAt !== void 0) return {
3127
+ ok: !1,
3128
+ reason: "revoked"
3129
+ };
3130
+ if (new Date(r.expiresAt).getTime() <= n.getTime()) return {
3131
+ ok: !1,
3132
+ reason: "expired"
3133
+ };
3134
+ let i = r.tenantId, a = (e, t) => x(S(e, t), S("tenantId", i)), o = r.revisionId;
3135
+ if (o === null) {
3136
+ let t = await _c(e, `${String(r.contentType)}_drafts`, a("id", r.variantId), !0);
3137
+ if (t === void 0) return {
3138
+ ok: !1,
3139
+ reason: "unknown"
3140
+ };
3141
+ o = t.revisionId;
3142
+ }
3143
+ let s = await _c(e, M, x(a("id", o), S("documentId", r.documentId), S("contentType", r.contentType)), !0);
3144
+ return s === void 0 ? {
3145
+ ok: !1,
3146
+ reason: "unknown"
3147
+ } : {
3148
+ ok: !0,
3149
+ share: r,
3150
+ contentType: r.contentType,
3151
+ locale: r.locale,
3152
+ revisionId: o,
3153
+ revision: s.number,
3154
+ values: s.values ?? {}
3155
+ };
3156
+ }, bc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3157
+ let r = await _c(e, G, S("id", t));
3158
+ if (r === void 0) throw new y({
3159
+ contentType: G,
3160
+ id: t,
3161
+ stage: "share"
3162
+ });
3163
+ (r.revokedAt === null || r.revokedAt === void 0) && await e.update(G, t, { revokedAt: n });
3164
+ }, xc = (e, t, n) => e.query({
3165
+ table: G,
3166
+ predicate: x(S("contentType", t.name), S("documentId", n)),
3167
+ order: [{
3168
+ column: "createdAt",
3169
+ direction: "desc"
3170
+ }],
3171
+ take: void 0,
3172
+ skip: void 0,
3173
+ projection: void 0
3174
+ }), 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) => {
3175
+ let a = Dc(t), o = await e.query({
3176
+ table: a,
3177
+ predicate: x(S("id", n), ...Object.entries(Ba(i)).map(([e, t]) => S(e, t))),
3178
+ order: [],
3179
+ take: 1,
3180
+ skip: void 0,
3181
+ projection: void 0
3182
+ });
3183
+ if (o[0] === void 0) throw new y({
3184
+ contentType: t.name,
3185
+ id: n,
3186
+ stage: "draft"
3187
+ });
3188
+ return await e.update(a, n, r) ?? o[0];
3189
+ }, jc = (e, t) => ({
3190
+ table: Dc(e),
3191
+ predicate: x(Ut("publishAt", t), S("status", "draft")),
3192
+ order: [],
3193
+ take: void 0,
3194
+ skip: void 0,
3195
+ projection: void 0
3196
+ }), Mc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3197
+ let r = await e.query(jc(t, n)), i = [];
3198
+ for (let n of r) {
3199
+ let r = n.id;
3200
+ if (typeof r != "string") continue;
3201
+ let a = {
3202
+ site: String(n.site),
3203
+ environment: String(n.environment),
3204
+ locale: String(n.locale)
3205
+ };
3206
+ try {
3207
+ await e.transactional(async (e) => {
3208
+ await eo(e, t, r, a), await e.update(Dc(t), r, { publishAt: null });
3209
+ });
3210
+ } catch (e) {
3211
+ if (e instanceof v || e instanceof d) continue;
3212
+ throw e;
3213
+ }
3214
+ i.push(r);
3215
+ }
3216
+ return i.length > 0 && $a(t), i;
3217
+ }, Nc = async (e, t, n = /* @__PURE__ */ new Date()) => {
3218
+ let r = await e.query({
3219
+ table: Dc(t),
3220
+ predicate: Ut("unpublishAt", n),
3221
+ order: [],
3222
+ take: void 0,
3223
+ skip: void 0,
3224
+ projection: void 0
3225
+ }), i = [];
3226
+ for (let n of r) {
3227
+ let r = n.id;
3228
+ if (typeof r != "string") continue;
3229
+ let a = {
3230
+ site: String(n.site),
3231
+ environment: String(n.environment),
3232
+ locale: String(n.locale)
3233
+ };
3234
+ await e.transactional(async (e) => {
3235
+ let n = !0;
3236
+ try {
3237
+ await no(e, t, r, a);
3238
+ } catch (e) {
3239
+ if (!(e instanceof y)) throw e;
3240
+ n = !1;
3241
+ }
3242
+ return await e.update(Dc(t), r, { unpublishAt: null }), n;
3243
+ }) && i.push(r);
3244
+ }
3245
+ return i.length > 0 && $a(t), i;
3246
+ }, 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) => {
3247
+ if (t == null) return t;
3248
+ switch (e.kind) {
3249
+ case "media": return typeof t == "string" ? await n(t) ?? t : t;
3250
+ case "array": {
3251
+ let r = e.element;
3252
+ return r === void 0 || !Array.isArray(t) ? t : Promise.all(t.map((e) => zc(r, e, n)));
3253
+ }
3254
+ case "struct": {
3255
+ let r = e.struct;
3256
+ if (r === void 0 || typeof t != "object" || Array.isArray(t)) return t;
3257
+ let i = t, a = { ...i };
3258
+ for (let [e, t] of Object.entries(r)) e in i && (a[e] = await zc(t, i[e], n));
3259
+ return a;
3260
+ }
3261
+ default: return t;
3262
+ }
3263
+ }, Bc = async (e, t, n) => {
3264
+ let r = { ...t };
3265
+ for (let [i, a] of Object.entries(e.fields)) {
3266
+ let e = a;
3267
+ (e.kind === "media" || e.kind === "array" || e.kind === "struct") && i in t && (r[i] = await zc(e, t[i], n));
3268
+ }
3269
+ return r;
3270
+ }, 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) => {
3271
+ let t = e.authorization;
3272
+ return t && t.toLowerCase().startsWith("bearer ") ? t.slice(7).trim() : e["x-api-key"];
3273
+ }, qc = async (e, t) => {
3274
+ if (e.method.toUpperCase() !== "GET") return {
3275
+ status: 405,
3276
+ body: { error: "method_not_allowed" }
3277
+ };
3278
+ if (!e.path.startsWith(Gc)) return {
3279
+ status: 404,
3280
+ body: { error: "not_found" }
3281
+ };
3282
+ let n = Kc(e.headers), r = n ? t.apiKeys.find((e) => e.key === n) : void 0;
3283
+ if (!r) return {
3284
+ status: 401,
3285
+ body: { error: "unauthorized" }
3286
+ };
3287
+ let i = e.path.slice(8).split("/").filter((e) => e.length > 0), a = i[0];
3288
+ if (!a || !t.types.some((e) => e.name === a)) return {
3289
+ status: 404,
3290
+ body: { error: "unknown_content_type" }
364
3291
  };
365
3292
  if (!(r.types === void 0 || r.types.includes("*") || r.types.includes(a))) return {
366
3293
  status: 403,
@@ -388,6 +3315,633 @@ var w = [
388
3315
  status: 200,
389
3316
  body: await t.cms.contentType(a).limit(l).all()
390
3317
  };
391
- };
3318
+ }, K = "cms_publish_series", Jc = D(K, {
3319
+ id: C({ prefix: "cser" }),
3320
+ contentType: O().maxLength(64),
3321
+ draftId: O(),
3322
+ rule: T(),
3323
+ armed: w().default(-1),
3324
+ state: O().oneOf(["running", "done"]).default("running")
3325
+ }).with(A()).unique("cms_publish_series_uq_draft", ["tenantId", "draftId"]), Yc = (e, t, n) => e.query({
3326
+ table: t,
3327
+ predicate: n,
3328
+ order: [],
3329
+ take: void 0,
3330
+ skip: void 0,
3331
+ projection: void 0
3332
+ }), Xc = (e) => `${e.name}_drafts`, Zc = (e) => {
3333
+ let t = e.rule;
3334
+ return {
3335
+ id: String(e.id),
3336
+ rule: t,
3337
+ occurrences: fe(t),
3338
+ armed: Number(e.armed),
3339
+ state: e.state === "done" ? "done" : "running"
3340
+ };
3341
+ }, Qc = async (e, t) => {
3342
+ let [n] = await Yc(e, K, S("draftId", t));
3343
+ return n === void 0 ? null : Zc(n);
3344
+ }, $c = async (e, t, n, r, i, a) => {
3345
+ let o = r.findIndex((e, t) => t > i && e.endsAt.getTime() > a.getTime());
3346
+ if (o === -1) return -1;
3347
+ let s = r[o];
3348
+ return await e.update(Xc(t), n, {
3349
+ publishAt: s.startsAt,
3350
+ unpublishAt: s.endsAt
3351
+ }), o;
3352
+ }, el = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
3353
+ let o = nt(i);
3354
+ if (o.length > 0) throw new s({
3355
+ contentType: t.name,
3356
+ violations: o.map((e) => ({
3357
+ field: "repeat",
3358
+ rule: "recurrence",
3359
+ message: e
3360
+ }))
3361
+ });
3362
+ let [c] = await Yc(e, Xc(t), x(S("id", n), ...Object.entries(Ba(r)).map(([e, t]) => S(e, t))));
3363
+ if (c === void 0) throw new y({
3364
+ contentType: t.name,
3365
+ id: n,
3366
+ stage: "draft"
3367
+ });
3368
+ let l = await $c(e, t, n, fe(i), -1, a);
3369
+ if (l === -1) throw new s({
3370
+ contentType: t.name,
3371
+ violations: [{
3372
+ field: "repeat",
3373
+ rule: "recurrence",
3374
+ message: "every occurrence of this series is over"
3375
+ }]
3376
+ });
3377
+ for (let t of await Yc(e, K, S("draftId", n))) await e.delete(K, String(t.id));
3378
+ let u = c.tenantId !== void 0 && c.tenantId !== null ? { tenantId: c.tenantId } : {};
3379
+ return Zc(await e.insert(K, {
3380
+ contentType: t.name,
3381
+ draftId: n,
3382
+ rule: i,
3383
+ armed: l,
3384
+ state: "running",
3385
+ ...u
3386
+ }));
3387
+ }, tl = async (e, t, n) => {
3388
+ let r = await Yc(e, K, S("draftId", n));
3389
+ if (r.length === 0) return !1;
3390
+ for (let t of r) await e.delete(K, String(t.id));
3391
+ let [i] = await Yc(e, Xc(t), S("id", n));
3392
+ return i !== void 0 && await e.update(Xc(t), n, {
3393
+ publishAt: null,
3394
+ unpublishAt: null
3395
+ }), !0;
3396
+ }, nl = async (e, t, n = /* @__PURE__ */ new Date()) => {
3397
+ let r = [];
3398
+ for (let i of await Yc(e, K, x(S("contentType", t.name), S("state", "running")))) {
3399
+ let a = String(i.draftId);
3400
+ await e.transactional(async (e) => {
3401
+ let [o] = await Yc(e, Xc(t), S("id", a));
3402
+ if (o === void 0) {
3403
+ await e.delete(K, String(i.id));
3404
+ return;
3405
+ }
3406
+ let s = (e) => e != null;
3407
+ if (s(o.publishAt) || s(o.unpublishAt)) return;
3408
+ let c = await $c(e, t, a, fe(i.rule), Number(i.armed), n);
3409
+ await e.update(K, String(i.id), c === -1 ? { state: "done" } : { armed: c }), c !== -1 && r.push(a);
3410
+ });
3411
+ }
3412
+ return r;
3413
+ }, 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), q = "cms_extensions", J = "cms_extension_data", Y = "cms_extension_secrets", cl = D(q, {
3414
+ id: C({ prefix: "cext" }),
3415
+ extensionId: O(),
3416
+ manifest: T(),
3417
+ granted: T(),
3418
+ pending: T().nullable(),
3419
+ previous: T().nullable()
3420
+ }).with(A()).unique("cms_extensions_uq_extension", ["tenantId", "extensionId"]), ll = D(J, {
3421
+ id: C({ prefix: "cexd" }),
3422
+ extensionId: O(),
3423
+ key: O(),
3424
+ value: T()
3425
+ }).with(A()).unique("cms_extension_data_uq_key", [
3426
+ "tenantId",
3427
+ "extensionId",
3428
+ "key"
3429
+ ]), ul = D(Y, {
3430
+ id: C({ prefix: "cexs" }),
3431
+ extensionId: O(),
3432
+ name: O(),
3433
+ value: O().encrypted().serverOnly()
3434
+ }).with(A()).unique("cms_extension_secrets_uq_name", [
3435
+ "tenantId",
3436
+ "extensionId",
3437
+ "name"
3438
+ ]), X = (e, t, n) => e.query({
3439
+ table: t,
3440
+ predicate: n,
3441
+ order: [{
3442
+ column: "id",
3443
+ direction: "asc"
3444
+ }],
3445
+ take: void 0,
3446
+ skip: void 0,
3447
+ projection: void 0
3448
+ }), Z = async (e, t) => (await X(e, q, S("extensionId", t)))[0], Q = (e) => {
3449
+ let t = e.granted, n = e.pending, r = e.previous;
3450
+ return {
3451
+ extensionId: String(e.extensionId),
3452
+ manifest: e.manifest,
3453
+ granted: t,
3454
+ pending: n == null ? null : {
3455
+ manifest: n,
3456
+ adds: yt(t, n.capabilities)
3457
+ },
3458
+ previous: r == null ? null : r.manifest
3459
+ };
3460
+ }, dl = async (e) => (await X(e, q, void 0)).map(Q).sort((e, t) => e.extensionId < t.extensionId ? -1 : 1), fl = async (e, t) => {
3461
+ let n = await Z(e, t);
3462
+ return n === void 0 ? null : Q(n);
3463
+ }, pl = async (e, t, n) => {
3464
+ let r = dt(t);
3465
+ if (r.length > 0) return {
3466
+ ok: !1,
3467
+ reason: "invalidManifest",
3468
+ problems: r
3469
+ };
3470
+ let i = yt(n, t.capabilities);
3471
+ return i.length > 0 ? {
3472
+ ok: !1,
3473
+ reason: "consentIncomplete",
3474
+ missing: i
3475
+ } : await Z(e, t.id) === void 0 ? {
3476
+ ok: !0,
3477
+ installed: Q(await e.insert(q, {
3478
+ extensionId: t.id,
3479
+ manifest: t,
3480
+ granted: [...t.capabilities],
3481
+ pending: null,
3482
+ previous: null
3483
+ }))
3484
+ } : {
3485
+ ok: !1,
3486
+ reason: "alreadyInstalled"
3487
+ };
3488
+ }, ml = async (e, t) => {
3489
+ let n = dt(t);
3490
+ if (n.length > 0) return {
3491
+ ok: !1,
3492
+ reason: "invalidManifest",
3493
+ problems: n
3494
+ };
3495
+ let r = await Z(e, t.id);
3496
+ if (r === void 0) return {
3497
+ ok: !1,
3498
+ reason: "notInstalled"
3499
+ };
3500
+ let i = Q(r);
3501
+ if (Qe(t.version, i.manifest.version) <= 0) return {
3502
+ ok: !1,
3503
+ reason: "notNewer"
3504
+ };
3505
+ let a = yt(i.granted, t.capabilities).length === 0 ? {
3506
+ manifest: t,
3507
+ granted: [...t.capabilities],
3508
+ pending: null,
3509
+ previous: {
3510
+ manifest: i.manifest,
3511
+ granted: i.granted
3512
+ }
3513
+ } : { pending: t }, o = await e.update(q, String(r.id), a);
3514
+ return o === null ? {
3515
+ ok: !1,
3516
+ reason: "notInstalled"
3517
+ } : {
3518
+ ok: !0,
3519
+ installed: Q(o)
3520
+ };
3521
+ }, hl = async (e, t, n) => {
3522
+ let r = await Z(e, t);
3523
+ if (r === void 0) return {
3524
+ ok: !1,
3525
+ reason: "notInstalled"
3526
+ };
3527
+ let { pending: i } = Q(r);
3528
+ if (i === null) return {
3529
+ ok: !1,
3530
+ reason: "nothingPending"
3531
+ };
3532
+ let a = yt(n, i.adds);
3533
+ if (a.length > 0) return {
3534
+ ok: !1,
3535
+ reason: "consentIncomplete",
3536
+ missing: a
3537
+ };
3538
+ let o = Q(r), s = await e.update(q, String(r.id), {
3539
+ manifest: i.manifest,
3540
+ granted: [...i.manifest.capabilities],
3541
+ pending: null,
3542
+ previous: {
3543
+ manifest: o.manifest,
3544
+ granted: o.granted
3545
+ }
3546
+ });
3547
+ return s === null ? {
3548
+ ok: !1,
3549
+ reason: "notInstalled"
3550
+ } : {
3551
+ ok: !0,
3552
+ installed: Q(s)
3553
+ };
3554
+ }, gl = async (e, t) => {
3555
+ let n = await Z(e, t);
3556
+ if (n === void 0) return {
3557
+ ok: !1,
3558
+ reason: "notInstalled"
3559
+ };
3560
+ let r = n.previous;
3561
+ if (r == null) return {
3562
+ ok: !1,
3563
+ reason: "nothingToRollBack"
3564
+ };
3565
+ let i = await e.update(q, String(n.id), {
3566
+ manifest: r.manifest,
3567
+ granted: [...r.granted],
3568
+ pending: null,
3569
+ previous: null
3570
+ });
3571
+ return i === null ? {
3572
+ ok: !1,
3573
+ reason: "notInstalled"
3574
+ } : {
3575
+ ok: !0,
3576
+ installed: Q(i)
3577
+ };
3578
+ }, _l = async (e, t) => {
3579
+ let n = await Z(e, t);
3580
+ if (n === void 0) return {
3581
+ ok: !1,
3582
+ reason: "notInstalled"
3583
+ };
3584
+ let r = await e.update(q, String(n.id), {
3585
+ granted: [],
3586
+ pending: null
3587
+ });
3588
+ return r === null ? {
3589
+ ok: !1,
3590
+ reason: "notInstalled"
3591
+ } : {
3592
+ ok: !0,
3593
+ installed: Q(r)
3594
+ };
3595
+ }, vl = async (e, t, n) => {
3596
+ let r = await Z(e, t);
3597
+ if (r === void 0) return {
3598
+ ok: !1,
3599
+ reason: "notInstalled"
3600
+ };
3601
+ let { manifest: i } = Q(r), a = yt(n, i.capabilities);
3602
+ if (a.length > 0) return {
3603
+ ok: !1,
3604
+ reason: "consentIncomplete",
3605
+ missing: a
3606
+ };
3607
+ let o = await e.update(q, String(r.id), { granted: [...i.capabilities] });
3608
+ return o === null ? {
3609
+ ok: !1,
3610
+ reason: "notInstalled"
3611
+ } : {
3612
+ ok: !0,
3613
+ installed: Q(o)
3614
+ };
3615
+ }, yl = "voltro:settings", bl = async (e, t) => {
3616
+ let n = await fl(e, t);
3617
+ if (n === null) return null;
3618
+ let [r] = await X(e, J, x(S("extensionId", t), S("key", yl))), i = r?.value;
3619
+ return it(n.manifest, typeof i == "object" && i ? i : {});
3620
+ }, xl = async (e, t, n) => {
3621
+ let r = await fl(e, t);
3622
+ if (r === null) return {
3623
+ ok: !1,
3624
+ reason: "notInstalled"
3625
+ };
3626
+ let i = Be(r.manifest, n);
3627
+ if (i.length > 0) return {
3628
+ ok: !1,
3629
+ reason: "invalid",
3630
+ problems: i
3631
+ };
3632
+ let a = {
3633
+ ...await bl(e, t),
3634
+ ...n
3635
+ }, [o] = await X(e, J, x(S("extensionId", t), S("key", yl)));
3636
+ return o === void 0 ? await e.insert(J, {
3637
+ extensionId: t,
3638
+ key: yl,
3639
+ value: a
3640
+ }) : await e.update(J, String(o.id), { value: a }), {
3641
+ ok: !0,
3642
+ settings: it(r.manifest, a)
3643
+ };
3644
+ }, Sl = async (e, t) => {
3645
+ let n = await Z(e, t);
3646
+ if (n === void 0) return {
3647
+ ok: !1,
3648
+ reason: "notInstalled"
3649
+ };
3650
+ let r = await X(e, J, S("extensionId", t));
3651
+ for (let t of r) await e.delete(J, String(t.id));
3652
+ for (let n of await X(e, Y, S("extensionId", t))) await e.delete(Y, String(n.id));
3653
+ return await e.delete(q, String(n.id)), {
3654
+ ok: !0,
3655
+ data: r.map((e) => ({
3656
+ key: String(e.key),
3657
+ value: e.value
3658
+ }))
3659
+ };
3660
+ }, Cl = async (e, t, n, r) => {
3661
+ let i = await fl(e, t);
3662
+ if (i === null) return {
3663
+ ok: !1,
3664
+ reason: "notInstalled"
3665
+ };
3666
+ if (![...i.manifest.capabilities, ...i.pending?.manifest.capabilities ?? []].includes(`secret:${n}`)) return {
3667
+ ok: !1,
3668
+ reason: "notAsked"
3669
+ };
3670
+ let [a] = await X(e, Y, x(S("extensionId", t), S("name", n)));
3671
+ return r === null ? a !== void 0 && await e.delete(Y, String(a.id)) : a === void 0 ? await e.insert(Y, {
3672
+ extensionId: t,
3673
+ name: n,
3674
+ value: r
3675
+ }) : await e.update(Y, String(a.id), { value: r }), { ok: !0 };
3676
+ }, wl = async (e, t, n) => {
3677
+ let [r] = await X(e, Y, x(S("extensionId", t), S("name", n)));
3678
+ return typeof r?.value == "string" ? r.value : void 0;
3679
+ }, Tl = (e, t, n) => {
3680
+ let r = t.extensionId, i = (e) => {
3681
+ if (!t.granted.includes(e)) throw new ct({
3682
+ extensionId: r,
3683
+ capability: e
3684
+ });
3685
+ }, a = async (t) => (await X(e, J, x(S("extensionId", r), S("key", t))))[0];
3686
+ return {
3687
+ extensionId: r,
3688
+ readContent: (e, t) => (i("content:read"), n.readContent(e, t)),
3689
+ listContent: (e) => (i("content:read"), n.listContent(e)),
3690
+ countContent: (e) => (i("content:read"), n.countContent(e)),
3691
+ readRevision: (e) => (i("content:read"), n.readRevision(e)),
3692
+ writeContent: (e, t, r) => (i("content:write"), n.writeContent(e, t, r)),
3693
+ fetch: (e, t) => {
3694
+ let a = URL.canParse(e) ? new URL(e) : null;
3695
+ if (a === null || a.protocol !== "https:" || a.port !== "") throw new ct({
3696
+ extensionId: r,
3697
+ capability: `egress:${e}`
3698
+ });
3699
+ return i(`egress:${a.hostname}`), n.fetch(a.href, t);
3700
+ },
3701
+ secret: (e) => (i(`secret:${e}`), n.secret(e)),
3702
+ settings: async () => await bl(e, r) ?? {},
3703
+ data: {
3704
+ get: async (e) => (await a(e))?.value,
3705
+ set: async (t, n) => {
3706
+ if (t === yl) throw new ct({
3707
+ extensionId: r,
3708
+ capability: "settings:write"
3709
+ });
3710
+ let i = await a(t);
3711
+ i === void 0 ? await e.insert(J, {
3712
+ extensionId: r,
3713
+ key: t,
3714
+ value: n
3715
+ }) : await e.update(J, String(i.id), { value: n });
3716
+ }
3717
+ }
3718
+ };
3719
+ }, 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", $ = "cms_ai_settings", Bl = [
3720
+ "suggested",
3721
+ "failed",
3722
+ "applied",
3723
+ "discarded"
3724
+ ], Vl = D(zl, {
3725
+ id: C({ prefix: "caio" }),
3726
+ operation: O(),
3727
+ version: O(),
3728
+ provider: O(),
3729
+ model: O(),
3730
+ contentType: O().maxLength(64),
3731
+ variantId: O().maxLength(64),
3732
+ revisionId: O().nullable(),
3733
+ field: O().nullable(),
3734
+ promptHash: O(),
3735
+ inputTokens: w().nullable(),
3736
+ outputTokens: w().nullable(),
3737
+ outcome: O().oneOf([...Bl]),
3738
+ error: O().nullable(),
3739
+ actor: O().nullable()
3740
+ }).with(A()), Hl = D($, {
3741
+ id: C({ prefix: "cais" }),
3742
+ provider: O(),
3743
+ model: O(),
3744
+ apiKey: O().encrypted().serverOnly().nullable(),
3745
+ monthlyTokens: w().nullable()
3746
+ }).with(A()).unique("cms_ai_settings_uq_tenant", ["tenantId"]), Ul = (e) => Kt("sha256").update(e).digest("hex"), Wl = async (e, t) => {
3747
+ let n = await e.insert(zl, {
3748
+ operation: t.operation,
3749
+ version: t.version,
3750
+ provider: t.provider,
3751
+ model: t.model,
3752
+ contentType: t.contentType,
3753
+ variantId: t.variantId,
3754
+ revisionId: t.revisionId ?? null,
3755
+ field: t.field ?? null,
3756
+ promptHash: Ul(t.prompt),
3757
+ inputTokens: t.usage?.inputTokens ?? null,
3758
+ outputTokens: t.usage?.outputTokens ?? null,
3759
+ outcome: t.outcome,
3760
+ error: t.error ?? null,
3761
+ actor: t.actor ?? null
3762
+ });
3763
+ return String(n.id);
3764
+ }, Gl = async (e, t, n) => {
3765
+ let [r] = await e.query({
3766
+ table: zl,
3767
+ predicate: S("id", t),
3768
+ order: [],
3769
+ take: 1,
3770
+ skip: void 0,
3771
+ projection: void 0
3772
+ });
3773
+ return r === void 0 || r.outcome !== "suggested" ? !1 : (await e.update(zl, t, { outcome: n }), !0);
3774
+ }, Kl = (e) => ({
3775
+ id: String(e.id),
3776
+ operation: String(e.operation),
3777
+ version: String(e.version),
3778
+ provider: String(e.provider),
3779
+ model: String(e.model),
3780
+ field: typeof e.field == "string" ? e.field : null,
3781
+ revisionId: typeof e.revisionId == "string" ? e.revisionId : null,
3782
+ outcome: e.outcome,
3783
+ inputTokens: typeof e.inputTokens == "number" ? e.inputTokens : null,
3784
+ outputTokens: typeof e.outputTokens == "number" ? e.outputTokens : null,
3785
+ at: e.createdAt instanceof Date ? e.createdAt.getTime() : new Date(String(e.createdAt ?? 0)).getTime()
3786
+ }), ql = async (e, t, n) => (await e.query({
3787
+ table: zl,
3788
+ predicate: x(S("contentType", t), S("variantId", n)),
3789
+ order: [{
3790
+ column: "createdAt",
3791
+ direction: "desc"
3792
+ }, {
3793
+ column: "id",
3794
+ direction: "desc"
3795
+ }],
3796
+ take: 200,
3797
+ skip: void 0,
3798
+ projection: void 0
3799
+ })).map(Kl), Jl = async (e, t) => {
3800
+ let [n] = await e.query({
3801
+ table: $,
3802
+ predicate: S("tenantId", t),
3803
+ order: [],
3804
+ take: 1,
3805
+ skip: void 0,
3806
+ projection: void 0
3807
+ });
3808
+ return n === void 0 ? null : {
3809
+ provider: typeof n.provider == "string" && n.provider !== "" ? n.provider : null,
3810
+ model: typeof n.model == "string" && n.model !== "" ? n.model : null,
3811
+ apiKey: typeof n.apiKey == "string" && n.apiKey !== "" ? n.apiKey : null,
3812
+ monthlyTokens: typeof n.monthlyTokens == "number" ? n.monthlyTokens : null
3813
+ };
3814
+ }, Yl = (e = /* @__PURE__ */ new Date()) => new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), 1)), Xl = async (e, t, n = Yl()) => (await e.query({
3815
+ table: zl,
3816
+ predicate: x(S("tenantId", t), Bt("createdAt", n)),
3817
+ order: [],
3818
+ take: void 0,
3819
+ skip: void 0,
3820
+ projection: ["inputTokens", "outputTokens"]
3821
+ })).reduce((e, t) => e + (Number(t.inputTokens) || 0) + (Number(t.outputTokens) || 0), 0), Zl = async (e, t, n = /* @__PURE__ */ new Date()) => {
3822
+ let r = (await Jl(e, t))?.monthlyTokens ?? null;
3823
+ return r === null ? null : Math.max(0, r - await Xl(e, t, Yl(n)));
3824
+ }, Ql = async (e, t, n) => {
3825
+ let [r] = await e.query({
3826
+ table: $,
3827
+ predicate: S("tenantId", t),
3828
+ order: [],
3829
+ take: 1,
3830
+ skip: void 0,
3831
+ projection: void 0
3832
+ }), i = n === null ? {
3833
+ provider: "",
3834
+ model: "",
3835
+ apiKey: null
3836
+ } : {
3837
+ provider: n.provider,
3838
+ model: n.model,
3839
+ ...n.apiKey === void 0 ? {} : { apiKey: n.apiKey }
3840
+ };
3841
+ if (r === void 0) {
3842
+ n !== null && await e.insert($, {
3843
+ apiKey: null,
3844
+ monthlyTokens: null,
3845
+ ...i,
3846
+ tenantId: t
3847
+ });
3848
+ return;
3849
+ }
3850
+ if (n === null && typeof r.monthlyTokens != "number") {
3851
+ await e.delete($, String(r.id));
3852
+ return;
3853
+ }
3854
+ await e.update($, String(r.id), i);
3855
+ }, $l = async (e, t, n) => {
3856
+ let [r] = await e.query({
3857
+ table: $,
3858
+ predicate: S("tenantId", t),
3859
+ order: [],
3860
+ take: 1,
3861
+ skip: void 0,
3862
+ projection: void 0
3863
+ });
3864
+ if (r === void 0) {
3865
+ n !== null && await e.insert($, {
3866
+ provider: "",
3867
+ model: "",
3868
+ apiKey: null,
3869
+ monthlyTokens: n,
3870
+ tenantId: t
3871
+ });
3872
+ return;
3873
+ }
3874
+ if (n === null && r.provider === "") {
3875
+ await e.delete($, String(r.id));
3876
+ return;
3877
+ }
3878
+ await e.update($, String(r.id), { monthlyTokens: n });
3879
+ }, 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)), cu = "cms_glossary", lu = D(cu, {
3880
+ id: C({ prefix: "cgl" }),
3881
+ term: O(),
3882
+ termKey: O().maxLength(100),
3883
+ locale: O().maxLength(64),
3884
+ translation: O().nullable(),
3885
+ forbidden: T().nullable(),
3886
+ note: O().nullable()
3887
+ }).with(A()).unique("cms_glossary_uq_term", [
3888
+ "tenantId",
3889
+ "termKey",
3890
+ "locale"
3891
+ ]), uu = (e) => e.trim().toLowerCase(), du = (e) => ({
3892
+ id: String(e.id),
3893
+ term: String(e.term),
3894
+ locale: String(e.locale),
3895
+ translation: typeof e.translation == "string" ? e.translation : null,
3896
+ forbidden: Array.isArray(e.forbidden) ? e.forbidden.filter((e) => typeof e == "string") : [],
3897
+ note: typeof e.note == "string" ? e.note : null
3898
+ }), fu = (e) => {
3899
+ let t = [], n = e.term.trim();
3900
+ 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;
3901
+ }, pu = async (e, t, n) => {
3902
+ let r = {
3903
+ term: n.term.trim(),
3904
+ locale: n.locale,
3905
+ translation: n.translation === void 0 || n.translation === null || n.translation.trim() === "" ? null : n.translation.trim(),
3906
+ forbidden: [...new Set((n.forbidden ?? []).map((e) => e.trim()).filter((e) => e !== ""))],
3907
+ note: n.note === void 0 || n.note === null || n.note.trim() === "" ? null : n.note.trim()
3908
+ }, [i] = await e.query({
3909
+ table: cu,
3910
+ predicate: x(S("tenantId", t), S("termKey", uu(n.term)), S("locale", n.locale)),
3911
+ order: [],
3912
+ take: 1,
3913
+ skip: void 0,
3914
+ projection: void 0
3915
+ });
3916
+ return i === void 0 ? (await e.insert(cu, {
3917
+ ...r,
3918
+ termKey: uu(n.term),
3919
+ tenantId: t
3920
+ }), "added") : (await e.update(cu, String(i.id), r), "replaced");
3921
+ }, mu = async (e, t, n) => {
3922
+ let [r] = await e.query({
3923
+ table: cu,
3924
+ predicate: x(S("tenantId", t), S("id", n)),
3925
+ order: [],
3926
+ take: 1,
3927
+ skip: void 0,
3928
+ projection: void 0
3929
+ });
3930
+ return r !== void 0 && (await e.delete(cu, n), !0);
3931
+ }, hu = async (e, t, n) => (await e.query({
3932
+ table: cu,
3933
+ predicate: n === void 0 ? S("tenantId", t) : x(S("tenantId", t), S("locale", n)),
3934
+ order: [{
3935
+ column: "termKey",
3936
+ direction: "asc"
3937
+ }],
3938
+ take: void 0,
3939
+ skip: void 0,
3940
+ projection: void 0
3941
+ })).map(du), gu = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), _u = (e, t) => RegExp(`(^|[^\\p{L}\\p{N}])${gu(t.trim())}($|[^\\p{L}\\p{N}])`, "iu").test(e), vu = (e, t) => t.filter((t) => _u(e, t.term)), yu = (e, t) => t.flatMap((t) => t.forbidden.filter((t) => _u(e, t)).map((e) => ({
3942
+ term: t.term,
3943
+ found: e,
3944
+ use: t.translation
3945
+ }))), bu = (...e) => j(() => hu(...e)), xu = (...e) => j(() => mu(...e)), Su = (...e) => j(() => pu(...e));
392
3946
  //#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 };
3947
+ export { Bl as AI_OUTCOMES, W as BlueprintInvalid, zl as CMS_AI_OPERATIONS_TABLE, $ as CMS_AI_SETTINGS_TABLE, Bi as CMS_AVAILABILITY_TABLE, xr as CMS_CHANGES_TABLE, I as CMS_DRAFT_TEXTS_TABLE, U as CMS_EXPERIMENTS_TABLE, $o as CMS_EXPERIMENT_EVENTS_TABLE, q as CMS_EXTENSIONS_TABLE, J as CMS_EXTENSION_DATA_TABLE, Y as CMS_EXTENSION_SECRETS_TABLE, cu as CMS_GLOSSARY_TABLE, Ln as CMS_PATHS_TABLE, G as CMS_PREVIEW_SHARES_TABLE, K as CMS_PUBLISH_SERIES_TABLE, Ti as CMS_QUALITY_EXCEPTIONS_TABLE, N as CMS_REDIRECTS_TABLE, $n as CMS_REFERENCES_TABLE, B as CMS_RELEASES_TABLE, V as CMS_RELEASE_ITEMS_TABLE, ri as CMS_REVIEWS_TABLE, M as CMS_REVISIONS_TABLE, xn as CMS_SCOPE_COLUMNS, tn as CMS_SEARCH_TABLE, ya as CMS_STEWARDSHIP_TABLE, F as CMS_TEAM_INVITATIONS_TABLE, Or 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, ii 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, qn 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, Jr 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, Sr as cmsChangesTable, vr as cmsContext, Xi as cmsDraftTextsTable, ts as cmsExperimentEventsTable, es as cmsExperimentsTable, ll as cmsExtensionDataTable, ul as cmsExtensionSecretsTable, cl as cmsExtensionsTable, lu as cmsGlossaryTable, Rn as cmsPathsTable, hc as cmsPreviewSharesTable, Jc as cmsPublishSeriesTable, Di as cmsQualityExceptionsTable, zn as cmsRedirectsTable, er as cmsReferencesTable, go as cmsReleaseItemsTable, ho as cmsReleasesTable, ai as cmsReviewsTable, Fn as cmsRevisionsTable, rn as cmsSearchTable, ba as cmsStewardshipTable, Ar as cmsTeamInvitationsTable, kr 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, yr 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, bu as glossary, fu as glossaryInputProblems, yu as glossaryProblems, e as grantedPurposes, Jn 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, Xr as inviteToTeam, Yr as invitedRole, Ie as isExtensionCapability, c as isKnownZone, Ve as languagesOf, Cs as listExperiments, Pt as listNumberedAt, wc as listPreviewShares, Yn 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, Zr as planBlueprintTeam, cc as planBulk, Yo as planPromotion, fr 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, Er as readChanges, la as readDraftTexts, Je as readEditorMessage, Pe as readPreviewMessage, ua as rebaseDraftTexts, yn as rebuildSearch, Fa as recertify, au as recordAiOperation, Dr as recordChange, o as recordEdit, ws as recordExperimentEvent, Xn as recordPaths, nt as recurrenceProblems, Zn as redirectTarget, Ot as redoEdit, nr as referencesOf, Pl as regrantExtension, Fo as releaseStatusOf, xu as removeGlossaryTerm, Qn 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, Su as setGlossaryTerm, Ia as setOwner, ei 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, Qr as teamDefaultRole, $r as teamInvitations, Nr as teamProblems, gt as templateOf, re as templateValues, je as templateViolations, vu 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, br as useCms, sr as usedBy, st as validateContent, Mt as valueText, pr as verifyPreviewToken, Re as visualMessage, ce as widgetFor, ti as withdrawInvitation, ni as workspaceReviewTypes, Yi as writeAvailability, n as zonedInstant };