@voltro/cms 0.85.0 → 0.86.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +666 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -33
  3. package/dist/ContentForm.js +282 -0
  4. package/dist/RichDocumentEditor.js +550 -0
  5. package/dist/RichDocumentView.js +132 -0
  6. package/dist/RichTextSurface.js +135 -0
  7. package/dist/aiCandidates.js +199 -0
  8. package/dist/aiOperations.js +152 -0
  9. package/dist/audiences.js +31 -0
  10. package/dist/availability.js +121 -0
  11. package/dist/blueprint.js +166 -0
  12. package/dist/bulk.js +281 -0
  13. package/dist/cacheIdentity.js +152 -0
  14. package/dist/changes.js +90 -0
  15. package/dist/cmsContext.js +229 -0
  16. package/dist/collections.js +224 -0
  17. package/dist/consent.js +29 -0
  18. package/dist/contentType.js +191 -0
  19. package/dist/contentfulImport.js +162 -0
  20. package/dist/copies.js +89 -0
  21. package/dist/cutover.js +202 -0
  22. package/dist/deliveryChecks.js +138 -0
  23. package/dist/domains.js +145 -0
  24. package/dist/draftTexts.js +164 -0
  25. package/dist/duplicates.js +78 -0
  26. package/dist/edgePurge.js +69 -0
  27. package/dist/editHistory.js +113 -0
  28. package/dist/effectForm.js +11 -0
  29. package/dist/environments.js +109 -0
  30. package/dist/errors.js +67 -0
  31. package/dist/experiments.js +528 -0
  32. package/dist/exposure.js +28 -0
  33. package/dist/extensionManifest.js +81 -0
  34. package/dist/extensions.js +314 -0
  35. package/dist/fieldSchema.js +199 -0
  36. package/dist/formStrings.js +74 -0
  37. package/dist/glossary.js +73 -0
  38. package/dist/history.js +54 -0
  39. package/dist/htmlImport.js +297 -0
  40. package/dist/index.d.ts +11 -7
  41. package/dist/index.js +73 -6082
  42. package/dist/media.js +29 -0
  43. package/dist/metrics.js +46 -0
  44. package/dist/migration.js +193 -0
  45. package/dist/migrationStages.js +13 -0
  46. package/dist/presenceAnchors.js +68 -0
  47. package/dist/preview.js +31 -0
  48. package/dist/promotion.js +107 -0
  49. package/dist/quality.js +188 -0
  50. package/dist/recurrence.js +78 -0
  51. package/dist/redirects.js +99 -0
  52. package/dist/referenceGraph.js +223 -0
  53. package/dist/references.js +173 -0
  54. package/dist/release.js +205 -0
  55. package/dist/rest.js +52 -0
  56. package/dist/review.js +160 -0
  57. package/dist/richDocument.js +491 -0
  58. package/dist/richInline.js +100 -0
  59. package/dist/schedule.js +80 -0
  60. package/dist/search.js +148 -0
  61. package/dist/selectionIntent.js +164 -0
  62. package/dist/seo.js +31 -0
  63. package/dist/series.js +105 -0
  64. package/dist/share.js +112 -0
  65. package/dist/stewardship.js +146 -0
  66. package/dist/taxonomy.js +36 -0
  67. package/dist/team.js +103 -0
  68. package/dist/templates.js +106 -0
  69. package/dist/trackChanges.js +197 -0
  70. package/dist/translation.js +64 -0
  71. package/dist/tree.js +87 -0
  72. package/dist/usage.js +50 -0
  73. package/dist/validation.js +192 -0
  74. package/dist/visualEditing.js +60 -0
  75. package/dist/web.js +33 -2
  76. package/dist/workflow.js +322 -0
  77. package/dist/write.js +394 -0
  78. package/dist/xliff.js +325 -0
  79. package/package.json +5 -5
  80. package/dist/presenceAnchors-4iHAVQB3.js +0 -4367
@@ -0,0 +1,205 @@
1
+ import { asTyped as e } from "./effectForm.js";
2
+ import { ContentNotFound as t, ReferenceUnavailable as n, ReleaseNotEditable as r, ReviewRequired as i } from "./errors.js";
3
+ import { publishRevision as a, unpublish as o } from "./write.js";
4
+ import { and as s, eq as c, generateId as l, id as u, integer as d, json as f, lte as p, table as m, text as h, timestamp as g } from "@voltro/database";
5
+ import { tenant as _ } from "@voltro/plugin-multitenancy/mixin";
6
+ //#region src/release.ts
7
+ var v = "cms_releases", y = "cms_release_items", b = [
8
+ "draft",
9
+ "scheduled",
10
+ "published",
11
+ "failed"
12
+ ], x = m(v, {
13
+ id: u({ prefix: "crel" }),
14
+ name: h(),
15
+ site: h().maxLength(64),
16
+ environment: h().maxLength(64),
17
+ status: h().oneOf(b),
18
+ scheduledAt: g().nullable(),
19
+ publishedAt: g().nullable(),
20
+ rollbackOf: h().nullable(),
21
+ claimToken: h().nullable(),
22
+ failure: h().nullable()
23
+ }).with(_()), S = m(y, {
24
+ id: u({ prefix: "crit" }),
25
+ releaseId: h(),
26
+ contentType: h().maxLength(64),
27
+ variantId: h().maxLength(64),
28
+ locale: h().maxLength(64),
29
+ action: h().oneOf(["publish", "unpublish"]),
30
+ revisionId: h().nullable(),
31
+ previousRevisionId: h().nullable(),
32
+ position: d(),
33
+ inherited: f().nullable()
34
+ }).with(_()).unique("cms_release_items_uq_variant", [
35
+ "tenantId",
36
+ "releaseId",
37
+ "contentType",
38
+ "variantId"
39
+ ]), C = (e, t, n, r) => e.query({
40
+ table: t,
41
+ predicate: n,
42
+ order: r === void 0 ? [] : [r],
43
+ take: void 0,
44
+ skip: void 0,
45
+ projection: void 0
46
+ }), w = async (e, n) => {
47
+ let [r] = await C(e, v, c("id", n));
48
+ if (r === void 0) throw new t({
49
+ contentType: "release",
50
+ id: n,
51
+ stage: "draft"
52
+ });
53
+ return r;
54
+ }, T = (e, t) => ({
55
+ site: String(e.site),
56
+ environment: String(e.environment),
57
+ locale: t
58
+ }), E = (e, t) => e.insert(v, {
59
+ ...t,
60
+ status: "draft"
61
+ }), D = async (e, n, i) => {
62
+ let a = await w(e, n);
63
+ if (a.status !== "draft") throw new r({
64
+ id: n,
65
+ status: String(a.status)
66
+ });
67
+ let o = T(a, i.locale), [l] = await C(e, `${i.type.name}_drafts`, s(c("id", i.id), c("site", o.site), c("environment", o.environment), c("locale", o.locale)));
68
+ if (l === void 0) throw new t({
69
+ contentType: i.type.name,
70
+ id: i.id,
71
+ stage: "draft"
72
+ });
73
+ let u = i.action ?? "publish", d = await C(e, y, s(c("releaseId", n), c("contentType", i.type.name), c("variantId", i.id))), f = {
74
+ action: u,
75
+ locale: i.locale,
76
+ revisionId: u === "publish" ? i.revisionId ?? String(l.revisionId) : null
77
+ }, [p] = d;
78
+ if (p !== void 0) return await e.update("cms_release_items", String(p.id), f) ?? p;
79
+ let m = (await C(e, y, c("releaseId", n))).length;
80
+ return e.insert(y, {
81
+ releaseId: n,
82
+ contentType: i.type.name,
83
+ variantId: i.id,
84
+ position: m,
85
+ ...f
86
+ });
87
+ }, O = async (e, t) => {
88
+ let [n] = await C(e, v, c("id", t));
89
+ return n === void 0 ? null : String(n.status);
90
+ }, k = (e, t) => C(e, y, c("releaseId", t), {
91
+ column: "position",
92
+ direction: "asc"
93
+ }), A = (e, t) => C(e, v, s(c("site", t.site), c("environment", t.environment)), {
94
+ column: "createdAt",
95
+ direction: "desc"
96
+ }), j = async (e, t, n, r) => {
97
+ let [i] = await C(e, `${t}_published`, s(c("id", n), c("site", r.site), c("environment", r.environment), c("locale", r.locale)));
98
+ return i === void 0 ? null : String(i.revisionId);
99
+ }, M = async (e, n, i, s = /* @__PURE__ */ new Date(), c = {}) => {
100
+ let l = await w(e, i);
101
+ if (l.status !== "draft" && l.status !== "scheduled") throw new r({
102
+ id: i,
103
+ status: String(l.status)
104
+ });
105
+ let u = new Map(n.map((e) => [e.name, e]));
106
+ for (let n of await k(e, i)) {
107
+ let r = u.get(String(n.contentType));
108
+ if (r === void 0) throw new t({
109
+ contentType: String(n.contentType),
110
+ id: String(n.variantId),
111
+ stage: "draft"
112
+ });
113
+ let s = T(l, String(n.locale)), c = String(n.variantId), d = await j(e, r.name, c, s);
114
+ n.action === "publish" ? await a(e, r, c, s, String(n.revisionId), { releaseId: i }) : d !== null && await o(e, r, c, s, { releaseId: i }), await e.update(y, String(n.id), { previousRevisionId: d });
115
+ }
116
+ let d = await e.update("cms_releases", i, {
117
+ status: "published",
118
+ publishedAt: s
119
+ }) ?? l;
120
+ for (let t of c.afterPublish ?? []) await t(e, d, s);
121
+ return d;
122
+ }, N = async (e, t, n) => {
123
+ let i = await w(e, t);
124
+ if (i.status !== "draft") throw new r({
125
+ id: t,
126
+ status: String(i.status)
127
+ });
128
+ return await e.update("cms_releases", t, {
129
+ status: "scheduled",
130
+ scheduledAt: n
131
+ }) ?? i;
132
+ }, P = async (e, t, n = /* @__PURE__ */ new Date(), r = {}) => {
133
+ let i = await C(e, v, s(c("status", "scheduled"), p("scheduledAt", n))), a = [];
134
+ for (let o of i) {
135
+ let i = String(o.id), u = l({
136
+ kind: "typeid",
137
+ prefix: "claim"
138
+ }, "cms_releases") ?? `claim_${Date.now()}`;
139
+ try {
140
+ await e.transactional(async (e) => await e.updateMany("cms_releases", { claimToken: u }, { where: s(c("id", i), c("status", "scheduled")) }) === 1 && (await M(e, t, i, n, r), !0)) && a.push(i);
141
+ } catch (t) {
142
+ await e.update(v, i, {
143
+ status: "failed",
144
+ failure: F(t)
145
+ });
146
+ }
147
+ }
148
+ return a;
149
+ }, F = (e) => {
150
+ if (e instanceof n) return `ReferenceUnavailable: ${e.contentType} ${e.id} uses ${e.targets.map((e) => `${e.contentType} ${e.documentId} (${e.reason})`).join(", ")}`;
151
+ if (e instanceof i) return `ReviewRequired: ${e.contentType} ${e.id} revision ${e.revisionId} is not approved`;
152
+ if (e instanceof t) return `ContentNotFound: ${e.contentType} ${e.id} (${e.stage})`;
153
+ let r = e?._tag;
154
+ return typeof r == "string" ? r : e instanceof Error ? e.message : String(e);
155
+ }, I = async (e, t) => {
156
+ let n = await w(e, t);
157
+ if (n.status !== "failed") throw new r({
158
+ id: t,
159
+ status: String(n.status)
160
+ });
161
+ return await e.update("cms_releases", t, {
162
+ status: "draft",
163
+ failure: null,
164
+ claimToken: null,
165
+ scheduledAt: null
166
+ }) ?? n;
167
+ }, L = async (e, t, n, i = /* @__PURE__ */ new Date(), a = {}) => {
168
+ let o = await w(e, n);
169
+ if (o.status !== "published") throw new r({
170
+ id: n,
171
+ status: String(o.status)
172
+ });
173
+ let s = await e.insert(v, {
174
+ name: `Rollback of ${String(o.name)}`,
175
+ site: o.site,
176
+ environment: o.environment,
177
+ status: "draft",
178
+ rollbackOf: n,
179
+ ...o.tenantId !== void 0 && o.tenantId !== null ? { tenantId: o.tenantId } : {}
180
+ }), c = String(s.id), l = 0;
181
+ for (let t of await k(e, n)) {
182
+ let n = t.previousRevisionId;
183
+ await e.insert(y, {
184
+ releaseId: c,
185
+ contentType: t.contentType,
186
+ variantId: t.variantId,
187
+ locale: t.locale,
188
+ action: n == null ? "unpublish" : "publish",
189
+ revisionId: n ?? null,
190
+ position: l++,
191
+ ...t.tenantId !== void 0 && t.tenantId !== null ? { tenantId: t.tenantId } : {}
192
+ });
193
+ }
194
+ return M(e, t, c, i, a);
195
+ }, R = [
196
+ t,
197
+ r,
198
+ i,
199
+ n
200
+ ], z = (...t) => e(() => E(...t)), B = (...n) => e(() => D(...n), t, r), V = async (e, t, n, r) => {
201
+ let [i] = await C(e, y, s(c("releaseId", t), c("variantId", n)));
202
+ return i !== void 0 && (await e.update(y, String(i.id), { inherited: r }), !0);
203
+ }, H = (...t) => e(() => V(...t)), U = (...t) => e(() => k(...t)), W = (...t) => e(() => O(...t)), G = (...t) => e(() => A(...t)), K = (...t) => e(() => M(...t), ...R), q = (...t) => e(() => N(...t), ...R), J = (...t) => e(() => P(...t)), Y = (...t) => e(() => L(...t), ...R), X = (...t) => e(() => I(...t), ...R);
204
+ //#endregion
205
+ export { v as CMS_RELEASES_TABLE, y as CMS_RELEASE_ITEMS_TABLE, b as RELEASE_STATUSES, D as addToRelease, B as addToReleaseEffect, S as cmsReleaseItemsTable, x as cmsReleasesTable, E as createRelease, z as createReleaseEffect, F as describeFailure, k as listReleaseItems, U as listReleaseItemsEffect, A as listReleases, G as listReleasesEffect, V as pinReleaseInheritance, H as pinReleaseInheritanceEffect, P as publishDueReleases, J as publishDueReleasesEffect, M as publishRelease, K as publishReleaseEffect, O as releaseStatusOf, W as releaseStatusOfEffect, I as retryRelease, X as retryReleaseEffect, L as rollbackRelease, Y as rollbackReleaseEffect, N as scheduleRelease, q as scheduleReleaseEffect };
package/dist/rest.js ADDED
@@ -0,0 +1,52 @@
1
+ //#region src/rest.ts
2
+ var e = (e) => {
3
+ let t = e.authorization;
4
+ return t && t.toLowerCase().startsWith("bearer ") ? t.slice(7).trim() : e["x-api-key"];
5
+ }, t = async (t, n) => {
6
+ if (t.method.toUpperCase() !== "GET") return {
7
+ status: 405,
8
+ body: { error: "method_not_allowed" }
9
+ };
10
+ if (!t.path.startsWith("/v1/cms/")) return {
11
+ status: 404,
12
+ body: { error: "not_found" }
13
+ };
14
+ let r = e(t.headers), i = r ? n.apiKeys.find((e) => e.key === r) : void 0;
15
+ if (!i) return {
16
+ status: 401,
17
+ body: { error: "unauthorized" }
18
+ };
19
+ let a = t.path.slice(8).split("/").filter((e) => e.length > 0), o = a[0];
20
+ if (!o || !n.types.some((e) => e.name === o)) return {
21
+ status: 404,
22
+ body: { error: "unknown_content_type" }
23
+ };
24
+ if (!(i.types === void 0 || i.types.includes("*") || i.types.includes(o))) return {
25
+ status: 403,
26
+ body: {
27
+ error: "forbidden",
28
+ type: o
29
+ }
30
+ };
31
+ if (a.length >= 2) {
32
+ let e = a.slice(1).join("/"), t = await n.cms.contentType(o).where("slug", "=", e).one();
33
+ return t ? {
34
+ status: 200,
35
+ body: t
36
+ } : {
37
+ status: 404,
38
+ body: {
39
+ error: "not_found",
40
+ type: o,
41
+ slug: e
42
+ }
43
+ };
44
+ }
45
+ let s = n.defaultLimit ?? 20, c = n.maxLimit ?? 100, l = Number(t.query?.limit), u = Number.isFinite(l) && l > 0 ? Math.min(l, c) : s;
46
+ return {
47
+ status: 200,
48
+ body: await n.cms.contentType(o).limit(u).all()
49
+ };
50
+ };
51
+ //#endregion
52
+ export { t as handleCmsRest };
package/dist/review.js ADDED
@@ -0,0 +1,160 @@
1
+ import { asTyped as e } from "./effectForm.js";
2
+ import { ContentNotFound as t, ReviewRequired as n, ReviewStepRefused as r, RevisionMismatch as i } from "./errors.js";
3
+ import { approvedByWorkflow as a } from "./workflow.js";
4
+ import { workspaceReviewTypes as o } from "./team.js";
5
+ import { and as s, eq as c, id as l, integer as u, table as d, text as f } from "@voltro/database";
6
+ import { tenant as p } from "@voltro/plugin-multitenancy/mixin";
7
+ //#region src/review.ts
8
+ var m = "cms_reviews", h = [
9
+ "requested",
10
+ "approved",
11
+ "changesRequested"
12
+ ], g = d(m, {
13
+ id: l({ prefix: "crvw" }),
14
+ contentType: f().maxLength(64),
15
+ variantId: f().maxLength(64),
16
+ documentId: f().maxLength(64),
17
+ site: f().maxLength(64),
18
+ environment: f().maxLength(64),
19
+ locale: f().maxLength(64),
20
+ revisionId: f(),
21
+ action: f().oneOf(h),
22
+ sequence: u().default(0),
23
+ actorId: f(),
24
+ note: f().nullable()
25
+ }).with(p()).index("cms_reviews_by_variant", ["contentType", "variantId"]), _ = (e) => [
26
+ c("site", e.site),
27
+ c("environment", e.environment),
28
+ c("locale", e.locale)
29
+ ], v = async (e, n, r, i, a = !1) => {
30
+ let [o] = await e.query({
31
+ table: `${n.name}_drafts`,
32
+ predicate: s(c("id", r), ..._(i)),
33
+ order: [],
34
+ take: 1,
35
+ skip: void 0,
36
+ projection: void 0,
37
+ ...a ? { lock: "update" } : {}
38
+ });
39
+ if (o === void 0) throw new t({
40
+ contentType: n.name,
41
+ id: r,
42
+ stage: "draft"
43
+ });
44
+ return o;
45
+ }, y = (e, t, n, r) => e.query({
46
+ table: m,
47
+ predicate: s(c("contentType", t.name), c("variantId", n), ..._(r)),
48
+ order: [{
49
+ column: "sequence",
50
+ direction: "desc"
51
+ }, {
52
+ column: "createdAt",
53
+ direction: "desc"
54
+ }],
55
+ take: void 0,
56
+ skip: void 0,
57
+ projection: void 0
58
+ }), b = async (e, t, n, r, i, a, o) => {
59
+ let [s] = await y(e, t, String(n.id), r), c = Number(s?.sequence ?? 0) + 1;
60
+ return e.insert(m, {
61
+ contentType: t.name,
62
+ variantId: n.id,
63
+ documentId: n.documentId,
64
+ site: r.site,
65
+ environment: r.environment,
66
+ locale: r.locale,
67
+ revisionId: n.revisionId,
68
+ action: i,
69
+ sequence: c,
70
+ actorId: a,
71
+ note: o ?? null
72
+ });
73
+ }, x = (e, t, n) => {
74
+ let [i, a] = e;
75
+ if (i !== void 0 && a !== void 0 && Number(i.sequence ?? 0) === 0 && new Date(i.createdAt).getTime() === new Date(a.createdAt).getTime()) throw new r({
76
+ contentType: t.name,
77
+ id: n,
78
+ reason: "ambiguousOrder"
79
+ });
80
+ return i;
81
+ }, S = async (e, t, n, r, i) => b(e, t, await v(e, t, n, r, !0), r, "requested", i.actorId, i.note), C = async (e, t, n, a, o) => {
82
+ let s = await v(e, t, n, a, !0);
83
+ if (s.revisionId !== o) throw new i({
84
+ contentType: t.name,
85
+ id: n,
86
+ expected: o,
87
+ actual: String(s.revisionId)
88
+ });
89
+ let c = x(await y(e, t, n, a), t, n);
90
+ if (c === void 0 || c.action !== "requested" || c.revisionId !== o) throw new r({
91
+ contentType: t.name,
92
+ id: n,
93
+ reason: "notInReview"
94
+ });
95
+ return {
96
+ draft: s,
97
+ request: c
98
+ };
99
+ }, w = async (e, t, n, i, a) => {
100
+ let { draft: o, request: s } = await C(e, t, n, i, a.revisionId);
101
+ if (a.allowSelfApproval !== !0 && s.actorId === a.actorId) throw new r({
102
+ contentType: t.name,
103
+ id: n,
104
+ reason: "selfApproval"
105
+ });
106
+ return b(e, t, o, i, "approved", a.actorId, a.note);
107
+ }, T = async (e, t, n, r, i) => {
108
+ let { draft: a } = await C(e, t, n, r, i.revisionId);
109
+ return b(e, t, a, r, "changesRequested", i.actorId, i.note);
110
+ }, E = async (e, t, n, r) => {
111
+ let i = await v(e, t, n, r), a = x(await y(e, t, n, r), t, n);
112
+ if (a === void 0) return {
113
+ state: "none",
114
+ revisionId: null,
115
+ stale: !1,
116
+ lastStep: null
117
+ };
118
+ let o = a.revisionId !== i.revisionId;
119
+ return {
120
+ state: o ? "none" : a.action === "requested" ? "inReview" : a.action === "approved" ? "approved" : "changesRequested",
121
+ revisionId: a.revisionId,
122
+ stale: o,
123
+ lastStep: a
124
+ };
125
+ }, D = async (e, t, n) => {
126
+ let r = t.review?.required;
127
+ if (r !== "workspace") return r === !0;
128
+ let [i] = n === void 0 ? [] : await e.query({
129
+ table: `${t.name}_drafts`,
130
+ predicate: c("id", n),
131
+ order: [],
132
+ take: 1,
133
+ skip: void 0,
134
+ projection: void 0
135
+ }), a = i?.tenantId;
136
+ return typeof a == "string" && (await o(e, a)).includes(t.name);
137
+ }, O = async (e, t, r, i, o) => {
138
+ if (await D(e, t, r)) {
139
+ if (t.review?.workflow !== void 0) {
140
+ if (!await a(e, t, r, o)) throw new n({
141
+ contentType: t.name,
142
+ id: r,
143
+ revisionId: o
144
+ });
145
+ } else if ((await e.query({
146
+ table: "cms_reviews",
147
+ predicate: s(c("contentType", t.name), c("variantId", r), c("revisionId", o), c("action", "approved"), ..._(i)),
148
+ order: [],
149
+ take: 1,
150
+ skip: void 0,
151
+ projection: void 0
152
+ })).length === 0) throw new n({
153
+ contentType: t.name,
154
+ id: r,
155
+ revisionId: o
156
+ });
157
+ }
158
+ }, k = (...t) => e(() => y(...t)), A = (...n) => e(() => S(...n), t), j = (...n) => e(() => w(...n), t, i, r), M = (...n) => e(() => T(...n), t, i, r), N = (...n) => e(() => E(...n), t, r), P = (...t) => e(() => D(...t)), F = (...t) => e(() => O(...t), n);
159
+ //#endregion
160
+ export { m as CMS_REVIEWS_TABLE, h as REVIEW_ACTIONS, w as approveReview, j as approveReviewEffect, O as assertApproved, F as assertApprovedEffect, g as cmsReviewsTable, T as requestChanges, M as requestChangesEffect, S as requestReview, A as requestReviewEffect, y as reviewLog, k as reviewLogEffect, D as reviewRequiredFor, P as reviewRequiredForEffect, E as reviewStatus, N as reviewStatusEffect };