@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,54 @@
1
+ import { plainTextOf as e } from "./richDocument.js";
2
+ //#region src/history.ts
3
+ var t = (e) => Array.isArray(e) ? e.map(t) : typeof e == "object" && e && !(e instanceof Date) ? Object.fromEntries(Object.keys(e).sort().map((n) => [n, t(e[n])])) : e instanceof Date ? e.toISOString() : e === void 0 ? null : e, n = (e, n, r) => Object.keys(e).filter((e) => JSON.stringify(t(n[e])) !== JSON.stringify(t(r[e]))), r = (e, n) => {
4
+ let r = [...e].sort((e, t) => Number(e.number) - Number(t.number)), i = [], a;
5
+ for (let e of r) {
6
+ let r = (e.values ?? {})[n], o = JSON.stringify(t(r));
7
+ o !== a && (a = o, r != null && r !== "" && i.push({
8
+ value: r,
9
+ revisionId: String(e.id),
10
+ number: Number(e.number),
11
+ createdAt: e.createdAt,
12
+ createdBy: e.createdBy
13
+ }));
14
+ }
15
+ return i.reverse();
16
+ }, i = (e) => e.match(/\s+|[^\s]+/g) ?? [], a = 4e6, o = (e, t) => {
17
+ let n = i(e), r = i(t), o = [], s = (e, t) => {
18
+ if (t === "") return;
19
+ let n = o[o.length - 1];
20
+ n !== void 0 && n.op === e ? o[o.length - 1] = {
21
+ op: e,
22
+ text: n.text + t
23
+ } : o.push({
24
+ op: e,
25
+ text: t
26
+ });
27
+ };
28
+ if (n.length * r.length > a) return s("removed", e), s("added", t), o;
29
+ let c = Array.from({ length: n.length + 1 }, () => Array(r.length + 1).fill(0));
30
+ for (let e = n.length - 1; e >= 0; e--) for (let t = r.length - 1; t >= 0; t--) c[e][t] = n[e] === r[t] ? c[e + 1][t + 1] + 1 : Math.max(c[e + 1][t], c[e][t + 1]);
31
+ let l = 0, u = 0;
32
+ for (; l < n.length && u < r.length;) n[l] === r[u] ? (s("same", n[l]), l++, u++) : c[l + 1][u] >= c[l][u + 1] ? (s("removed", n[l]), l++) : (s("added", r[u]), u++);
33
+ for (; l < n.length;) s("removed", n[l++]);
34
+ for (; u < r.length;) s("added", r[u++]);
35
+ return o;
36
+ }, s = (e) => typeof e == "object" && !!e && e.type === "doc" && Array.isArray(e.blocks), c = (n) => {
37
+ if (n == null) return "";
38
+ if (typeof n == "string") return n;
39
+ if (typeof n == "number" || typeof n == "boolean") return String(n);
40
+ if (n instanceof Date) return n.toISOString();
41
+ if (s(n)) return e(n);
42
+ if (Array.isArray(n)) return n.map(c).join("\n");
43
+ let r = n;
44
+ if (typeof r.componentId == "string" && typeof r.props == "object" && r.props !== null) {
45
+ let e = Object.values(r.props).map(c).filter((e) => e !== "");
46
+ return `${r.componentId}: ${e.join(" · ")}`;
47
+ }
48
+ return JSON.stringify(t(n));
49
+ }, l = (e, t, r) => n(e, t, r).map((e) => ({
50
+ field: e,
51
+ segments: o(c(t[e]), c(r[e]))
52
+ }));
53
+ //#endregion
54
+ export { n as changedFields, o as diffWords, l as fieldDiffs, r as fieldVersions, c as valueText };
@@ -0,0 +1,297 @@
1
+ import { contactLiteralProblem as e } from "./richDocument.js";
2
+ //#region src/htmlImport.ts
3
+ var t = {
4
+ amp: "&",
5
+ lt: "<",
6
+ gt: ">",
7
+ quot: "\"",
8
+ apos: "'",
9
+ nbsp: "\xA0",
10
+ ndash: "–",
11
+ mdash: "—",
12
+ hellip: "…",
13
+ lsquo: "‘",
14
+ rsquo: "’",
15
+ ldquo: "“",
16
+ rdquo: "”",
17
+ copy: "©",
18
+ euro: "€"
19
+ }, n = (e) => e.replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (e, n) => {
20
+ if (n[0] === "#") {
21
+ let t = n[1] === "x" || n[1] === "X" ? Number.parseInt(n.slice(2), 16) : Number.parseInt(n.slice(1), 10);
22
+ return Number.isFinite(t) && t > 0 && t <= 1114111 ? String.fromCodePoint(t) : e;
23
+ }
24
+ return t[n.toLowerCase()] ?? e;
25
+ }), r = (e) => {
26
+ try {
27
+ return decodeURIComponent(e);
28
+ } catch {
29
+ return e;
30
+ }
31
+ }, i = /* @__PURE__ */ new Set([
32
+ "script",
33
+ "style",
34
+ "iframe",
35
+ "object",
36
+ "embed",
37
+ "noscript",
38
+ "template",
39
+ "svg",
40
+ "form",
41
+ "select",
42
+ "textarea",
43
+ "button"
44
+ ]), a = /* @__PURE__ */ new Set([
45
+ "span",
46
+ "div",
47
+ "section",
48
+ "article",
49
+ "main",
50
+ "header",
51
+ "footer",
52
+ "figure",
53
+ "blockquote",
54
+ "u",
55
+ "small",
56
+ "sup",
57
+ "sub",
58
+ "code",
59
+ "pre",
60
+ "thead",
61
+ "tbody",
62
+ "tfoot",
63
+ "font",
64
+ "center"
65
+ ]), o = (e) => {
66
+ let t = {};
67
+ for (let r of e.matchAll(/([a-zA-Z_:][-a-zA-Z0-9_:.]*)\s*(?:=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g)) t[r[1].toLowerCase()] = n(r[2] ?? r[3] ?? r[4] ?? "");
68
+ return t;
69
+ }, s = (e) => {
70
+ let t = [], n = e.replace(/<!--[\s\S]*?-->/g, ""), r = 0;
71
+ for (let e of n.matchAll(/<(\/?)([a-zA-Z][a-zA-Z0-9]*)([^>]*)>/g)) {
72
+ e.index > r && t.push({
73
+ kind: "text",
74
+ text: n.slice(r, e.index)
75
+ });
76
+ let i = e[3] ?? "";
77
+ t.push({
78
+ kind: "tag",
79
+ tag: {
80
+ name: e[2].toLowerCase(),
81
+ closing: e[1] === "/",
82
+ attrs: o(i.replace(/\/\s*$/, "")),
83
+ selfClosing: /\/\s*$/.test(i)
84
+ }
85
+ }), r = e.index + e[0].length;
86
+ }
87
+ return r < n.length && t.push({
88
+ kind: "text",
89
+ text: n.slice(r)
90
+ }), t;
91
+ }, c = (t, o = {}) => {
92
+ let c = 0, l = o.newId ?? (() => `rb_import_${++c}`), u = [], d = [], f = (e, t) => {
93
+ d.some((n) => n.kind === e && n.detail === t) || d.push({
94
+ kind: e,
95
+ detail: t
96
+ });
97
+ }, p = [], m = null, h = [], g = null, _ = null, v = null, y = null, b = !1, x = (e) => {
98
+ let t = n(e.replace(/[ \t\r\n\f]+/g, " "));
99
+ if (t === "" || t === " " && h.length === 0) return;
100
+ let r = h[h.length - 1];
101
+ m !== null && m.target !== null ? r?.type === "link" && r.target === m.target ? h[h.length - 1] = {
102
+ ...r,
103
+ text: r.text + t
104
+ } : h.push({
105
+ type: "link",
106
+ target: m.target,
107
+ text: t
108
+ }) : m?.contact === void 0 ? r?.type === "text" && ((e) => (e ?? []).join() === p.join())(r.marks) ? h[h.length - 1] = {
109
+ ...r,
110
+ text: r.text + t
111
+ } : h.push({
112
+ type: "text",
113
+ text: t,
114
+ ...p.length > 0 ? { marks: [...p] } : {}
115
+ }) : r?.type === "contact" && r.contact === m.contact ? h[h.length - 1] = {
116
+ ...r,
117
+ text: r.text + t
118
+ } : h.push({
119
+ type: "contact",
120
+ contact: m.contact,
121
+ text: t
122
+ });
123
+ }, S = () => {
124
+ let e = [...h], t = e[0];
125
+ t !== void 0 && (e[0] = {
126
+ ...t,
127
+ text: t.text.replace(/^[ \t\r\n\f]+/, "")
128
+ });
129
+ let n = e[e.length - 1];
130
+ return n !== void 0 && (e[e.length - 1] = {
131
+ ...n,
132
+ text: n.text.replace(/[ \t\r\n\f]+$/, "")
133
+ }), e.filter((e) => e.text !== "");
134
+ }, C = () => {
135
+ if (v === null || v.items.length === 0) return;
136
+ let { ordered: e, items: t, levels: n, sublists: r } = v, i = e ? "ordered" : "unordered", a = r.some((e) => e !== i) ? { sublists: r } : {};
137
+ u.push({
138
+ id: l(),
139
+ type: "list",
140
+ ordered: e,
141
+ items: t,
142
+ ...n.some((e) => e > 0) ? {
143
+ levels: n,
144
+ ...a
145
+ } : {}
146
+ });
147
+ }, w = (e = g) => {
148
+ let t = S();
149
+ h = [], t.length !== 0 && (e === "li" && v !== null ? (v.items.push(t), v.levels.push(Math.min(v.depth, 3))) : e === "cell" && y?.row ? y.row.push(t) : e === "h2" || e === "h3" ? u.push({
150
+ id: l(),
151
+ type: "heading",
152
+ level: e === "h2" ? 2 : 3,
153
+ content: t
154
+ }) : u.push({
155
+ id: l(),
156
+ type: "paragraph",
157
+ content: t
158
+ }));
159
+ }, T = (e) => {
160
+ e.split(/\n\s*\n/).forEach((e, t) => {
161
+ t > 0 && w("p"), x(e);
162
+ });
163
+ };
164
+ for (let n of s(t)) {
165
+ if (_ !== null) {
166
+ n.kind === "tag" && n.tag.closing && n.tag.name === _ && (_ = null);
167
+ continue;
168
+ }
169
+ if (n.kind === "text") {
170
+ g === null && v === null && y === null ? T(n.text) : x(n.text);
171
+ continue;
172
+ }
173
+ let { name: t, closing: s, attrs: c } = n.tag;
174
+ if (i.has(t)) f("unsupportedTag", t), !s && !n.tag.selfClosing && (_ = t);
175
+ else switch (t) {
176
+ case "p":
177
+ s ? (w(), g = null) : (w("p"), g = "p");
178
+ break;
179
+ case "h1":
180
+ case "h2":
181
+ case "h3":
182
+ case "h4":
183
+ case "h5":
184
+ case "h6":
185
+ s ? (w(), g = null) : (w("p"), g = t === "h1" || t === "h2" ? "h2" : "h3");
186
+ break;
187
+ case "br":
188
+ x(" ");
189
+ break;
190
+ case "strong":
191
+ case "b":
192
+ case "em":
193
+ case "i":
194
+ case "u": {
195
+ let e = t === "strong" || t === "b" ? "bold" : t === "u" ? "underline" : "italic";
196
+ if (s) {
197
+ let t = p.lastIndexOf(e);
198
+ t >= 0 && p.splice(t, 1);
199
+ } else p.push(e);
200
+ break;
201
+ }
202
+ case "a":
203
+ if (s) {
204
+ m = null;
205
+ break;
206
+ }
207
+ {
208
+ let t = c.href ?? "", n = /^(mailto|tel):(.+)$/i.exec(t.trim());
209
+ if (o.contacts === !0 && n !== null) {
210
+ let t = n[1].toLowerCase() === "mailto" ? "email" : "phone", i = r(n[2].split("?")[0]).trim();
211
+ if (e(t, i) === null) {
212
+ m = {
213
+ target: null,
214
+ contact: {
215
+ channel: t,
216
+ value: i
217
+ }
218
+ };
219
+ break;
220
+ }
221
+ }
222
+ let i = o.resolveLink?.(t) ?? null;
223
+ i === null && t !== "" && f("externalLink", t), m = { target: i };
224
+ }
225
+ break;
226
+ case "img": {
227
+ let e = c.src ?? "", t = o.resolveImage?.(e) ?? null;
228
+ if (t === null) {
229
+ f("image", e), c.alt && x(c.alt);
230
+ break;
231
+ }
232
+ let n = g;
233
+ w(g === "li" || g === "cell" ? g : "p"), u.push({
234
+ id: l(),
235
+ type: "image",
236
+ asset: t,
237
+ ...c.alt ? { caption: c.alt } : {}
238
+ }), g = n;
239
+ break;
240
+ }
241
+ case "ul":
242
+ case "ol":
243
+ if (s) {
244
+ if (v !== null && v.depth > 0) {
245
+ w("li"), v.depth--, g = "li";
246
+ break;
247
+ }
248
+ w(), C(), v = null, g = null;
249
+ } else if (v !== null) {
250
+ w("li"), v.depth++, g = null;
251
+ let e = Math.min(v.depth, 3) - 1;
252
+ for (; v.sublists.length < e;) v.sublists.push(v.sublists[v.sublists.length - 1] ?? (v.ordered ? "ordered" : "unordered"));
253
+ v.sublists.length === e && v.sublists.push(t === "ol" ? "ordered" : "unordered");
254
+ } else w("p"), v = {
255
+ ordered: t === "ol",
256
+ items: [],
257
+ levels: [],
258
+ depth: 0,
259
+ sublists: []
260
+ }, g = null;
261
+ break;
262
+ case "li":
263
+ s ? (w("li"), g = null) : (w(v === null ? "p" : "li"), g = "li");
264
+ break;
265
+ case "table":
266
+ s ? (y !== null && y.rows.length > 0 && u.push({
267
+ id: l(),
268
+ type: "table",
269
+ header: y.header,
270
+ rows: y.rows
271
+ }), y = null) : (w("p"), y = {
272
+ header: !1,
273
+ rows: [],
274
+ row: null
275
+ });
276
+ break;
277
+ case "tr":
278
+ if (y === null) break;
279
+ s ? (y.row && y.row.length > 0 && (y.rows.length === 0 && b && (y.header = !0), y.rows.push(y.row)), y.row = null, b = !1) : y.row = [];
280
+ break;
281
+ case "th":
282
+ case "td":
283
+ s ? (w("cell"), g = null) : (t === "th" && (b = !0), h = [], g = "cell");
284
+ break;
285
+ default: a.has(t) || f("unsupportedTag", t);
286
+ }
287
+ }
288
+ return w(g ?? "p"), C(), {
289
+ document: {
290
+ type: "doc",
291
+ blocks: u
292
+ },
293
+ findings: d
294
+ };
295
+ };
296
+ //#endregion
297
+ export { n as decodeEntities, c as richDocumentFromHtml };
package/dist/index.d.ts CHANGED
@@ -731,7 +731,7 @@ export declare const CMS_QUALITY_EXCEPTIONS_TABLE = "cms_quality_exceptions";
731
731
 
732
732
  export declare const CMS_REDIRECTS_TABLE = "cms_redirects";
733
733
 
734
- /** The system table holding the reference edges of every published variant. */
734
+ /** The system table holding scoped published, draft and revision edges. */
735
735
  export declare const CMS_REFERENCES_TABLE = "cms_references";
736
736
 
737
737
  export declare const CMS_RELEASE_ITEMS_TABLE = "cms_release_items";
@@ -910,12 +910,6 @@ export declare const cmsQualityExceptionsTable: TableLike;
910
910
  /** A former address and the document now answering it. */
911
911
  export declare const cmsRedirectsTable: TableLike;
912
912
 
913
- /**
914
- * One row per reference a published variant makes: the source (type,
915
- * document, variant, scope), where in its values the reference sits (`path`)
916
- * and the target document. Tenant-scoped. Register it in the app's
917
- * `databaseHandle` beside `cmsRevisionsTable`.
918
- */
919
913
  export declare const cmsReferencesTable: TableLike;
920
914
 
921
915
  /** One variant in a release: publish its pinned revision, or unpublish it. */
@@ -3975,6 +3969,16 @@ export declare const rebaseDraftTexts: (...args: Parameters<typeof rebaseDraftTe
3975
3969
  /** After a save: the texts belong to the new revision. In the caller's transaction. */
3976
3970
  declare const rebaseDraftTexts_2: (tx: DataStore, rows: ReadonlyArray<Row>, revisionId: string) => Promise<void>;
3977
3971
 
3972
+ /** Effect form of {@link rebuildReferenceIndex}. */
3973
+ export declare const rebuildReferenceIndex: (...args: Parameters<typeof rebuildReferenceIndex_2>) => Effect<void, never, never>;
3974
+
3975
+ /**
3976
+ * Rebuild draft/history edges after schema application for existing content or
3977
+ * changed reference declarations. Run inside the caller's transaction, with
3978
+ * the same tenant-scoped store used for content writes. Published edges stay.
3979
+ */
3980
+ declare const rebuildReferenceIndex_2: (store: DataStore, types: ReadonlyArray<ContentType>, scope: Pick<CmsScope, "site" | "environment">) => Promise<void>;
3981
+
3978
3982
  /** Effect form of {@link rebuildSearch}. */
3979
3983
  export declare const rebuildSearch: (...args: Parameters<typeof rebuildSearch_2>) => Effect<number, never, never>;
3980
3984