@voltro/cms 0.85.0 → 0.87.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 (244) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/README.md +138 -0
  3. package/THIRD-PARTY-NOTICES.md +864 -253
  4. package/dist/ContentForm.js +282 -0
  5. package/dist/RichDocumentEditor.js +550 -0
  6. package/dist/RichDocumentView.js +177 -0
  7. package/dist/RichTextSurface.js +135 -0
  8. package/dist/aiCandidates.js +199 -0
  9. package/dist/aiOperations.js +152 -0
  10. package/dist/applicationBuildSnapshotService.js +101 -0
  11. package/dist/assetRenditions.js +102 -0
  12. package/dist/assetRevision.js +46 -0
  13. package/dist/assetUseRights.js +72 -0
  14. package/dist/audiences.js +31 -0
  15. package/dist/availability.js +124 -0
  16. package/dist/blueprint.js +166 -0
  17. package/dist/build.d.ts +3063 -0
  18. package/dist/build.js +37 -0
  19. package/dist/buildApplicationAdmission.js +16 -0
  20. package/dist/buildApplicationCatalog.js +136 -0
  21. package/dist/buildApplicationCatalogTable.js +24 -0
  22. package/dist/buildApplicationRest.js +99 -0
  23. package/dist/buildApplicationUpload.js +111 -0
  24. package/dist/buildSnapshot.js +401 -0
  25. package/dist/buildSnapshotApplicationPin.js +32 -0
  26. package/dist/buildSnapshotRest.js +210 -0
  27. package/dist/buildSnapshotService.js +265 -0
  28. package/dist/buildSnapshotTables.js +25 -0
  29. package/dist/bulk.js +282 -0
  30. package/dist/cacheIdentity.js +152 -0
  31. package/dist/changes.js +307 -0
  32. package/dist/cmsContext.js +229 -0
  33. package/dist/collections.js +224 -0
  34. package/dist/consent.js +29 -0
  35. package/dist/contentLocations.js +53 -0
  36. package/dist/contentProjection.js +83 -0
  37. package/dist/contentRouteIdentity.js +13 -0
  38. package/dist/contentRouteMaterializer.js +97 -0
  39. package/dist/contentRouteTypes.js +39 -0
  40. package/dist/contentSeo.js +189 -0
  41. package/dist/contentTreePath.js +60 -0
  42. package/dist/contentType.js +208 -0
  43. package/dist/contentValues.js +18 -0
  44. package/dist/contentfulImport.js +162 -0
  45. package/dist/copies.js +89 -0
  46. package/dist/cutover.js +202 -0
  47. package/dist/deliveryChecks.js +138 -0
  48. package/dist/domainHost.js +7 -0
  49. package/dist/domains.js +139 -0
  50. package/dist/draftTexts.js +164 -0
  51. package/dist/duplicates.js +78 -0
  52. package/dist/edgePurge.js +69 -0
  53. package/dist/editHistory.js +113 -0
  54. package/dist/effectForm.js +11 -0
  55. package/dist/environmentAliases.js +138 -0
  56. package/dist/environments.js +147 -0
  57. package/dist/errors.js +107 -0
  58. package/dist/experiments.js +528 -0
  59. package/dist/exposure.js +28 -0
  60. package/dist/extensionManifest.js +81 -0
  61. package/dist/extensions.js +314 -0
  62. package/dist/fieldSchema.js +199 -0
  63. package/dist/formStrings.js +74 -0
  64. package/dist/frontendBindings.js +99 -0
  65. package/dist/frontendMedia.js +18 -0
  66. package/dist/glossary.js +73 -0
  67. package/dist/history.js +54 -0
  68. package/dist/htmlImport.js +297 -0
  69. package/dist/index.d.ts +771 -54
  70. package/dist/index.js +89 -6082
  71. package/dist/initializePublicRoutes.js +28 -0
  72. package/dist/liveContentRouteView.js +76 -0
  73. package/dist/media.js +29 -0
  74. package/dist/metrics.js +46 -0
  75. package/dist/migration.js +193 -0
  76. package/dist/migrationStages.js +13 -0
  77. package/dist/nativeOutputDeploymentService.js +205 -0
  78. package/dist/outputActivation.js +234 -0
  79. package/dist/outputActivationOrigin.js +51 -0
  80. package/dist/outputActivationStore.js +411 -0
  81. package/dist/outputActivationTables.js +11 -0
  82. package/dist/outputActivationTarget.js +81 -0
  83. package/dist/outputActivationTargetTable.js +25 -0
  84. package/dist/outputDeployment.js +174 -0
  85. package/dist/outputDeploymentRest.js +168 -0
  86. package/dist/outputDeploymentService.js +241 -0
  87. package/dist/outputRouteGraph.js +177 -0
  88. package/dist/outputSafetyArtifact.js +147 -0
  89. package/dist/outputTargetRest.js +62 -0
  90. package/dist/pathSegmentEncoding.js +4 -0
  91. package/dist/presenceAnchors.js +68 -0
  92. package/dist/preview.js +31 -0
  93. package/dist/privateCmsTransport.js +76 -0
  94. package/dist/privateNativeRouteReservation.js +10 -0
  95. package/dist/promotion.js +116 -0
  96. package/dist/publicBuild.js +90 -0
  97. package/dist/publicBuildRest.js +98 -0
  98. package/dist/publicBuildService.js +63 -0
  99. package/dist/publicOutputHttp.js +129 -0
  100. package/dist/publicOutputService.js +287 -0
  101. package/dist/publicPresentation.js +17 -0
  102. package/dist/publicRouteDispositionAdmission.js +38 -0
  103. package/dist/publicRouteHistoryStore.js +12 -0
  104. package/dist/publicRouteHistoryView.js +34 -0
  105. package/dist/publicRouteIntegrity.js +5 -0
  106. package/dist/publicRouteMutation.js +6 -0
  107. package/dist/publicRouteNamespace.js +134 -0
  108. package/dist/publicRoutePublication.js +36 -0
  109. package/dist/publicRouteRegistry.js +17 -0
  110. package/dist/publicRouteRegistryBinding.js +194 -0
  111. package/dist/publicRouteRegistryDefinition.js +76 -0
  112. package/dist/publicRouteSitePublication.js +40 -0
  113. package/dist/publicRouteTables.js +13 -0
  114. package/dist/publicRouteUrl.js +18 -0
  115. package/dist/publicationSeo.js +52 -0
  116. package/dist/publicationState.js +296 -0
  117. package/dist/quality.js +188 -0
  118. package/dist/reconfigurePublicRoutes.js +41 -0
  119. package/dist/recurrence.js +78 -0
  120. package/dist/redirects.js +130 -0
  121. package/dist/referenceGraph.js +224 -0
  122. package/dist/references.js +173 -0
  123. package/dist/release.js +241 -0
  124. package/dist/renderReadAuthority.js +43 -0
  125. package/dist/renderReadGrant.js +137 -0
  126. package/dist/rest.js +52 -0
  127. package/dist/review.js +160 -0
  128. package/dist/richDocument.js +521 -0
  129. package/dist/richInline.js +100 -0
  130. package/dist/routeDispositionGraph.js +44 -0
  131. package/dist/routeDispositionRest.js +51 -0
  132. package/dist/routeDispositionService.js +73 -0
  133. package/dist/routeDispositionStore.js +289 -0
  134. package/dist/routeDispositionTables.js +5 -0
  135. package/dist/routeDispositions.js +91 -0
  136. package/dist/routeHistoryStorage.js +320 -0
  137. package/dist/routeHistoryStore.js +12 -0
  138. package/dist/schedule.js +80 -0
  139. package/dist/search.js +148 -0
  140. package/dist/selectionIntent.js +164 -0
  141. package/dist/seo.js +31 -0
  142. package/dist/series.js +105 -0
  143. package/dist/share.js +112 -0
  144. package/dist/siteBindings.js +159 -0
  145. package/dist/siteBuildCandidate.js +104 -0
  146. package/dist/siteDelivery.js +115 -0
  147. package/dist/siteState.js +47 -0
  148. package/dist/snapshotAddressGraph.js +55 -0
  149. package/dist/snapshotAddressRead.js +73 -0
  150. package/dist/snapshotAppConsumer.js +71 -0
  151. package/dist/snapshotAppExecution.js +102 -0
  152. package/dist/snapshotApplication.js +75 -0
  153. package/dist/snapshotApprovedRouteDispositions.js +44 -0
  154. package/dist/snapshotAssetAssembly.js +70 -0
  155. package/dist/snapshotAssetAssemblyRest.js +50 -0
  156. package/dist/snapshotBindingRead.js +61 -0
  157. package/dist/snapshotCodeSeo.js +29 -0
  158. package/dist/snapshotComponent.js +34 -0
  159. package/dist/snapshotComponentSource.js +24 -0
  160. package/dist/snapshotConsumer.js +87 -0
  161. package/dist/snapshotContentIdentity.js +10 -0
  162. package/dist/snapshotDefinitions.js +264 -0
  163. package/dist/snapshotDocumentAssembly.js +193 -0
  164. package/dist/snapshotDocumentAssemblyRest.js +84 -0
  165. package/dist/snapshotDocumentProjection.js +202 -0
  166. package/dist/snapshotDocumentTransfer.js +35 -0
  167. package/dist/snapshotDocumentTransferRest.js +80 -0
  168. package/dist/snapshotDomains.js +56 -0
  169. package/dist/snapshotEnvironment.js +31 -0
  170. package/dist/snapshotFieldPlan.js +85 -0
  171. package/dist/snapshotFrontend.js +103 -0
  172. package/dist/snapshotLink.js +8 -0
  173. package/dist/snapshotMedia.js +111 -0
  174. package/dist/snapshotMediaCapture.js +246 -0
  175. package/dist/snapshotMediaFields.js +225 -0
  176. package/dist/snapshotMediaRead.js +185 -0
  177. package/dist/snapshotMediaReader.js +13 -0
  178. package/dist/snapshotObservation.js +16 -0
  179. package/dist/snapshotObservedRouteHistory.js +34 -0
  180. package/dist/snapshotOutputTransfer.js +78 -0
  181. package/dist/snapshotPageLoader.js +7 -0
  182. package/dist/snapshotPageSeo.js +59 -0
  183. package/dist/snapshotPathLocale.js +15 -0
  184. package/dist/snapshotPresentation.js +86 -0
  185. package/dist/snapshotPresentationPolicy.js +12 -0
  186. package/dist/snapshotProjection.js +119 -0
  187. package/dist/snapshotPublicAccess.js +161 -0
  188. package/dist/snapshotPublicRouteHistory.js +40 -0
  189. package/dist/snapshotReadAdmission.js +38 -0
  190. package/dist/snapshotRedirectOutput.js +151 -0
  191. package/dist/snapshotRedirectTargets.js +24 -0
  192. package/dist/snapshotRedirects.js +132 -0
  193. package/dist/snapshotReference.js +8 -0
  194. package/dist/snapshotReferenceAddress.js +10 -0
  195. package/dist/snapshotReferenceGraph.js +79 -0
  196. package/dist/snapshotReferenceRead.js +65 -0
  197. package/dist/snapshotRelease.js +99 -0
  198. package/dist/snapshotRender.js +361 -0
  199. package/dist/snapshotRenderDependencies.js +178 -0
  200. package/dist/snapshotRenditions.js +88 -0
  201. package/dist/snapshotRichDocument.js +62 -0
  202. package/dist/snapshotRoleTransfer.js +106 -0
  203. package/dist/snapshotRoleTransferRest.js +99 -0
  204. package/dist/snapshotRouteAdmission.js +71 -0
  205. package/dist/snapshotRouteDispatch.js +111 -0
  206. package/dist/snapshotRouteDispositionPlan.js +73 -0
  207. package/dist/snapshotRouteRead.js +43 -0
  208. package/dist/snapshotRoutes.js +79 -0
  209. package/dist/snapshotRouting.js +113 -0
  210. package/dist/snapshotSeo.js +179 -0
  211. package/dist/snapshotSeoControls.js +101 -0
  212. package/dist/snapshotSeoDocumentInventory.js +115 -0
  213. package/dist/snapshotSeoDocuments.js +129 -0
  214. package/dist/snapshotSeoMerge.js +85 -0
  215. package/dist/snapshotSeoMetadata.js +137 -0
  216. package/dist/snapshotSeoOutput.js +173 -0
  217. package/dist/snapshotSeoPathSets.js +105 -0
  218. package/dist/snapshotSeoRead.js +88 -0
  219. package/dist/snapshotSite.js +128 -0
  220. package/dist/snapshotSitemapFiles.js +36 -0
  221. package/dist/snapshotTreeDependencies.js +58 -0
  222. package/dist/snapshotTreeLoader.js +10 -0
  223. package/dist/snapshotTreeRead.js +158 -0
  224. package/dist/staticPathSet.js +177 -0
  225. package/dist/staticPathSetRest.js +129 -0
  226. package/dist/staticPathSetService.js +249 -0
  227. package/dist/staticPathSetStore.js +338 -0
  228. package/dist/stewardship.js +146 -0
  229. package/dist/taxonomy.js +36 -0
  230. package/dist/team.js +103 -0
  231. package/dist/templates.js +106 -0
  232. package/dist/trackChanges.js +197 -0
  233. package/dist/translation.js +64 -0
  234. package/dist/tree.js +87 -0
  235. package/dist/usage.js +50 -0
  236. package/dist/validation.js +192 -0
  237. package/dist/visualEditing.js +60 -0
  238. package/dist/web.d.ts +709 -7
  239. package/dist/web.js +50 -2
  240. package/dist/workflow.js +322 -0
  241. package/dist/write.js +419 -0
  242. package/dist/xliff.js +325 -0
  243. package/package.json +20 -6
  244. package/dist/presenceAnchors-4iHAVQB3.js +0 -4367
@@ -0,0 +1,188 @@
1
+ import { ContentNotFound as e } from "./errors.js";
2
+ import { asTyped as t } from "./effectForm.js";
3
+ import { and as n, eq as r, id as i, table as a, text as o, timestamp as s } from "@voltro/database";
4
+ import { tenant as c } from "@voltro/plugin-multitenancy/mixin";
5
+ //#region src/quality.ts
6
+ var l = "cms_quality_exceptions", u = 90, d = a(l, {
7
+ id: i({ prefix: "cqex" }),
8
+ site: o().maxLength(64),
9
+ environment: o().maxLength(64),
10
+ locale: o().maxLength(64),
11
+ contentType: o().maxLength(64),
12
+ variantId: o().maxLength(64),
13
+ ruleId: o().maxLength(64),
14
+ reason: o(),
15
+ status: o().oneOf([
16
+ "requested",
17
+ "approved",
18
+ "rejected",
19
+ "withdrawn"
20
+ ]),
21
+ requestedBy: o(),
22
+ requestedAt: s(),
23
+ decidedBy: o().nullable(),
24
+ decidedAt: s().nullable(),
25
+ note: o().nullable(),
26
+ expiresAt: s()
27
+ }).with(c()).index("cms_quality_exceptions_by_variant", [
28
+ "contentType",
29
+ "variantId",
30
+ "ruleId"
31
+ ]), f = (e, t) => t === null || (e.sites === void 0 || e.sites.includes(t.site)) && (e.locales === void 0 || e.locales.includes(t.locale)), p = (e, t, n = {
32
+ now: /* @__PURE__ */ new Date(),
33
+ scope: null
34
+ }) => (e.quality ?? []).filter((e) => f(e, n.scope) && e.check(t, n)).map((e) => ({
35
+ ruleId: e.id,
36
+ field: e.field,
37
+ message: e.message,
38
+ blocking: e.blocking !== !1,
39
+ pack: e.pack ?? null
40
+ })), m = (e) => e instanceof Date ? e : new Date(String(e)), h = (e, t) => {
41
+ let n = m(e.expiresAt), r = String(e.status);
42
+ return {
43
+ id: String(e.id),
44
+ ruleId: String(e.ruleId),
45
+ reason: String(e.reason),
46
+ state: (r === "approved" || r === "requested") && n.getTime() <= t.getTime() ? "expired" : r,
47
+ requestedBy: String(e.requestedBy),
48
+ requestedAt: m(e.requestedAt),
49
+ decidedBy: typeof e.decidedBy == "string" ? e.decidedBy : null,
50
+ note: typeof e.note == "string" ? e.note : null,
51
+ expiresAt: n
52
+ };
53
+ }, g = (e, t, n) => [
54
+ r("contentType", e.name),
55
+ r("variantId", t),
56
+ r("site", n.site),
57
+ r("environment", n.environment),
58
+ r("locale", n.locale)
59
+ ], _ = async (e, t, r, i, a = /* @__PURE__ */ new Date()) => (await e.query({
60
+ table: l,
61
+ predicate: n(...g(t, r, i)),
62
+ order: [{
63
+ column: "requestedAt",
64
+ direction: "desc"
65
+ }],
66
+ take: void 0,
67
+ skip: void 0,
68
+ projection: void 0
69
+ })).map((e) => h(e, a)), v = async (t, i, a, o, s, c = /* @__PURE__ */ new Date()) => {
70
+ let u = (i.quality ?? []).find((e) => e.id === s.ruleId && f(e, o));
71
+ if (u === void 0) return {
72
+ ok: !1,
73
+ reason: "unknownRule"
74
+ };
75
+ if (u.blocking === !1) return {
76
+ ok: !1,
77
+ reason: "notBlocking"
78
+ };
79
+ let d = s.reason.trim();
80
+ if (d === "" || d.length > 500) return {
81
+ ok: !1,
82
+ reason: "noReason"
83
+ };
84
+ let p = (s.expiresAt.getTime() - c.getTime()) / 864e5;
85
+ if (!(p > 0) || p > 90) return {
86
+ ok: !1,
87
+ reason: "badExpiry"
88
+ };
89
+ let [m] = await t.query({
90
+ table: `${i.name}_drafts`,
91
+ predicate: n(r("id", a), r("site", o.site), r("environment", o.environment), r("locale", o.locale)),
92
+ order: [],
93
+ take: 1,
94
+ skip: void 0,
95
+ projection: void 0
96
+ });
97
+ if (m === void 0) throw new e({
98
+ contentType: i.name,
99
+ id: a,
100
+ stage: "draft"
101
+ });
102
+ if ((await _(t, i, a, o, c)).some((e) => e.ruleId === u.id && (e.state === "requested" || e.state === "approved"))) return {
103
+ ok: !1,
104
+ reason: "alreadyOpen"
105
+ };
106
+ let h = m.tenantId, g = await t.insert(l, {
107
+ site: o.site,
108
+ environment: o.environment,
109
+ locale: o.locale,
110
+ contentType: i.name,
111
+ variantId: a,
112
+ ruleId: u.id,
113
+ reason: d,
114
+ status: "requested",
115
+ requestedBy: s.actorId,
116
+ requestedAt: c,
117
+ decidedBy: null,
118
+ decidedAt: null,
119
+ note: null,
120
+ expiresAt: s.expiresAt,
121
+ ...h == null ? {} : { tenantId: h }
122
+ });
123
+ return {
124
+ ok: !0,
125
+ id: String(g.id)
126
+ };
127
+ }, y = async (e, t, n, i = /* @__PURE__ */ new Date()) => {
128
+ let [a] = await e.query({
129
+ table: l,
130
+ predicate: r("id", t),
131
+ order: [],
132
+ take: 1,
133
+ skip: void 0,
134
+ projection: void 0
135
+ });
136
+ if (a === void 0) return {
137
+ ok: !1,
138
+ reason: "notFound"
139
+ };
140
+ let o = h(a, i), s = n.note !== void 0 && n.note.trim() !== "" ? n.note.trim().slice(0, 500) : null;
141
+ if (n.decision === "withdraw") return o.state === "requested" && o.requestedBy !== n.actorId ? {
142
+ ok: !1,
143
+ reason: "notRequester"
144
+ } : o.state !== "requested" && o.state !== "approved" ? {
145
+ ok: !1,
146
+ reason: "notOpen"
147
+ } : (await e.update(l, t, {
148
+ status: "withdrawn",
149
+ decidedBy: n.actorId,
150
+ decidedAt: i,
151
+ note: s
152
+ }), {
153
+ ok: !0,
154
+ state: "withdrawn"
155
+ });
156
+ if (o.state !== "requested") return {
157
+ ok: !1,
158
+ reason: "notOpen"
159
+ };
160
+ if (o.requestedBy === n.actorId) return {
161
+ ok: !1,
162
+ reason: "selfApproval"
163
+ };
164
+ let c = n.decision === "approve" ? "approved" : "rejected";
165
+ return await e.update(l, t, {
166
+ status: c,
167
+ decidedBy: n.actorId,
168
+ decidedAt: i,
169
+ note: s
170
+ }), {
171
+ ok: !0,
172
+ state: c
173
+ };
174
+ }, b = async (e, t, n, r, i, a = /* @__PURE__ */ new Date()) => {
175
+ let o = p(t, i, {
176
+ now: a,
177
+ scope: r
178
+ }).filter((e) => e.blocking);
179
+ if (o.length === 0) return [];
180
+ let s = new Set((await _(e, t, n, r, a)).filter((e) => e.state === "approved").map((e) => e.ruleId));
181
+ return o.filter((e) => !s.has(e.ruleId)).map((e) => ({
182
+ field: e.field,
183
+ rule: `quality.${e.ruleId}`,
184
+ message: e.message
185
+ }));
186
+ }, x = (...e) => t(() => _(...e)), S = (...n) => t(() => v(...n), e), C = (...e) => t(() => y(...e)), w = (...e) => t(() => b(...e));
187
+ //#endregion
188
+ export { l as CMS_QUALITY_EXCEPTIONS_TABLE, u as MAX_EXCEPTION_DAYS, d as cmsQualityExceptionsTable, y as decideQualityException, C as decideQualityExceptionEffect, _ as qualityExceptions, x as qualityExceptionsEffect, p as qualityFindings, b as qualityViolations, w as qualityViolationsEffect, v as requestQualityException, S as requestQualityExceptionEffect, f as ruleApplies };
@@ -0,0 +1,41 @@
1
+ import { PublicRouteRegistryUnavailable as e, publicRouteRegistryFail as t } from "./publicRouteRegistry.js";
2
+ import { ChangeFeedUnavailable as n, SiteStateUnavailable as r } from "./errors.js";
3
+ import { asTyped as i } from "./effectForm.js";
4
+ import { lockSiteState as a } from "./siteState.js";
5
+ import { invalidatePublicationRelease as o, lockPublicationStream as s } from "./changes.js";
6
+ import { copyOutputActivationScope as c } from "./outputActivation.js";
7
+ import { advancePublicRouteDefinition as l } from "./publicRouteRegistryBinding.js";
8
+ import { reconcilePublicRouteNamespace as u, withPublicRouteNamespaceBoundary as d } from "./publicRouteNamespace.js";
9
+ import { compileCmsPublicRouteDeclaration as f } from "./initializePublicRoutes.js";
10
+ import { readPublicRouteHistoryView as p } from "./publicRouteHistoryView.js";
11
+ import { canonicalJson as m } from "@voltro/runtime";
12
+ //#region src/reconfigurePublicRoutes.ts
13
+ var h = (h, g, _, v) => i(() => d(async () => {
14
+ if (h.savepoint === void 0) return t("configuration");
15
+ let e = v?.expectedRevision, n = v?.now ?? Date.now();
16
+ if (!Number.isSafeInteger(e) || e < 1 || e > 2147483647) return t("revision");
17
+ if (!Number.isSafeInteger(n) || n < 0 || n > 864e13) return t("bounds");
18
+ let r;
19
+ try {
20
+ r = c(g);
21
+ } catch {
22
+ return t("scope");
23
+ }
24
+ let i = f(_);
25
+ return i.site.id !== r.site || !i.site.environments.includes(r.environment) ? t("scope") : h.savepoint(async () => {
26
+ await a(h, r), await s(h, r);
27
+ let c = await p(h, r), d = c.namespace;
28
+ for await (let e of c.entries());
29
+ let f = m(d.binding.definition) === m(i);
30
+ if (e !== d.binding.revision) return f && d.binding.revision === e + 1 ? { revision: d.binding.revision } : t("revision");
31
+ if (f) return { revision: d.binding.revision };
32
+ let g = await l(h, r, {
33
+ expectedRevision: e,
34
+ definition: i,
35
+ now: n
36
+ });
37
+ return await o(h, r), await u(h, r), { revision: g.revision };
38
+ });
39
+ }), e, n, r);
40
+ //#endregion
41
+ export { h as reconfigureCmsPublicRoutes };
@@ -0,0 +1,78 @@
1
+ //#region src/recurrence.ts
2
+ var e = 100, t = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/, n = /^\d{4}-\d{2}-\d{2}$/, r = 6e4, i = /* @__PURE__ */ new Map(), a = (e) => {
3
+ let t = i.get(e);
4
+ return t === void 0 && (t = new Intl.DateTimeFormat("en-US", {
5
+ timeZone: e,
6
+ hourCycle: "h23",
7
+ year: "numeric",
8
+ month: "2-digit",
9
+ day: "2-digit",
10
+ hour: "2-digit",
11
+ minute: "2-digit",
12
+ second: "2-digit"
13
+ }), i.set(e, t)), t;
14
+ }, o = (e) => {
15
+ try {
16
+ return a(e), !0;
17
+ } catch {
18
+ return !1;
19
+ }
20
+ }, s = (e, t) => {
21
+ let n = a(t).formatToParts(new Date(e)), i = (e) => Number(n.find((t) => t.type === e)?.value);
22
+ return (Date.UTC(i("year"), i("month") - 1, i("day"), i("hour"), i("minute"), i("second")) - Math.floor(e / 1e3) * 1e3) / r;
23
+ }, c = (e, n) => {
24
+ let i = t.exec(e);
25
+ if (i === null) throw RangeError(`not a local wall time (YYYY-MM-DDTHH:mm): ${e}`);
26
+ let a = Date.UTC(Number(i[1]), Number(i[2]) - 1, Number(i[3]), Number(i[4]), Number(i[5])), o = s(a - 720 * r, n), c = s(a + 720 * r, n), l = [.../* @__PURE__ */ new Set([o, c])].map((e) => a - e * r).filter((e) => s(e, n) * r === a - e).sort((e, t) => e - t);
27
+ return l.length === 0 ? {
28
+ instant: /* @__PURE__ */ new Date(a - o * r),
29
+ adjusted: "gap"
30
+ } : l.length > 1 ? {
31
+ instant: new Date(l[0]),
32
+ adjusted: "fold"
33
+ } : { instant: new Date(l[0]) };
34
+ }, l = (e) => String(e).padStart(2, "0"), u = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(), d = (e, t, n) => {
35
+ let [r, i, a, o, s] = [
36
+ 1,
37
+ 2,
38
+ 3,
39
+ 4,
40
+ 5
41
+ ].map((t) => Number(e[t]));
42
+ if (t === "month") {
43
+ let e = i - 1 + n, t = r + Math.floor(e / 12), c = e % 12 + 1, d = Math.min(a, u(t, c));
44
+ return {
45
+ local: `${t}-${l(c)}-${l(d)}T${l(o)}:${l(s)}`,
46
+ clamped: d !== a
47
+ };
48
+ }
49
+ let c = new Date(Date.UTC(r, i - 1, a + n * (t === "week" ? 7 : 1)));
50
+ return {
51
+ local: `${c.getUTCFullYear()}-${l(c.getUTCMonth() + 1)}-${l(c.getUTCDate())}T${l(o)}:${l(s)}`,
52
+ clamped: !1
53
+ };
54
+ }, f = (e, t) => t * (e === "day" ? 1440 : e === "week" ? 10080 : 40320), p = (e) => {
55
+ let r = [], i = e.interval ?? 1;
56
+ t.test(e.start) || r.push("start must be a local wall time, YYYY-MM-DDTHH:mm"), o(e.zone) || r.push(`unknown time zone '${e.zone}'`), (!Number.isInteger(e.count) || e.count < 1 || e.count > 100) && r.push("count must be between 1 and 100"), (!Number.isInteger(i) || i < 1 || i > 52) && r.push("interval must be between 1 and 52"), !Number.isInteger(e.durationMinutes) || e.durationMinutes < 1 ? r.push("an occurrence must last at least a minute") : e.durationMinutes >= f(e.every, i) && r.push("an occurrence must end before the next one starts");
57
+ for (let t of e.except ?? []) n.test(t) || r.push(`not a local date (YYYY-MM-DD): ${t}`);
58
+ return r;
59
+ }, m = (e) => {
60
+ let n = p(e);
61
+ if (n.length > 0) throw RangeError(n.join("; "));
62
+ let i = t.exec(e.start), a = e.interval ?? 1, o = new Set(e.except ?? []), s = [];
63
+ for (let t = 0; t < e.count; t++) {
64
+ let { local: n, clamped: l } = d(i, e.every, t * a);
65
+ if (o.has(n.slice(0, 10))) continue;
66
+ let { instant: u, adjusted: f } = c(n, e.zone), p = f ?? (l ? "clamped" : void 0);
67
+ s.push({
68
+ index: t,
69
+ local: n,
70
+ startsAt: u,
71
+ endsAt: new Date(u.getTime() + e.durationMinutes * r),
72
+ ...p === void 0 ? {} : { adjusted: p }
73
+ });
74
+ }
75
+ return s;
76
+ };
77
+ //#endregion
78
+ export { e as MAX_OCCURRENCES, o as isKnownZone, m as occurrencesOf, p as recurrenceProblems, c as zonedInstant };
@@ -0,0 +1,130 @@
1
+ import { ChangeFeedUnavailable as e } from "./errors.js";
2
+ import { asTyped as t } from "./effectForm.js";
3
+ import { buildTree as n } from "./tree.js";
4
+ import { invalidatePublicationRelease as r, lockPublicationStream as i } from "./changes.js";
5
+ import { and as a, eq as o, id as s, neq as c, table as l, text as u } from "@voltro/database";
6
+ import { tenant as d } from "@voltro/plugin-multitenancy/mixin";
7
+ //#region src/redirects.ts
8
+ var f = "cms_paths", p = "cms_redirects", m = l(f, {
9
+ id: s({ prefix: "cpth" }),
10
+ contentType: u().maxLength(64),
11
+ documentId: u().maxLength(64),
12
+ site: u().maxLength(64),
13
+ environment: u().maxLength(64),
14
+ locale: u().maxLength(64),
15
+ path: u()
16
+ }).with(d()).index("cms_paths_by_document", [
17
+ "contentType",
18
+ "documentId",
19
+ "site",
20
+ "environment",
21
+ "locale"
22
+ ]), h = l(p, {
23
+ id: s({ prefix: "crdr" }),
24
+ contentType: u().maxLength(64),
25
+ site: u().maxLength(64),
26
+ environment: u().maxLength(64),
27
+ locale: u().maxLength(64),
28
+ fromPath: u(),
29
+ documentId: u().maxLength(64)
30
+ }).with(d()).index("cms_redirects_by_path", [
31
+ "contentType",
32
+ "site",
33
+ "environment",
34
+ "locale",
35
+ "fromPath"
36
+ ]), g = (e, t, n) => e.query({
37
+ table: t,
38
+ predicate: n,
39
+ order: [],
40
+ take: void 0,
41
+ skip: void 0,
42
+ projection: void 0
43
+ }), _ = (e) => [
44
+ o("site", e.site),
45
+ o("environment", e.environment),
46
+ o("locale", e.locale)
47
+ ], v = (t, n) => {
48
+ if (typeof n != "string" || n.length === 0 || !t.site || !t.environment || !t.locale) throw new e({ reason: "scope" });
49
+ return {
50
+ tenantId: n,
51
+ site: t.site,
52
+ environment: t.environment
53
+ };
54
+ }, y = async (t, n) => {
55
+ let r = await t.query({
56
+ table: p,
57
+ predicate: n,
58
+ order: [],
59
+ take: 2,
60
+ skip: void 0,
61
+ projection: void 0
62
+ });
63
+ if (r.length > 1) throw new e({ reason: "migration" });
64
+ return r[0];
65
+ }, b = async (t, r, s, l) => {
66
+ if (r.tree === void 0 && r.address === void 0) return !1;
67
+ let u = v(s, l);
68
+ await i(t, u);
69
+ let d = o("tenantId", u.tenantId), m = await g(t, `${r.name}_published`, a(d, ..._(s), c("status", "archived"))), h = r.address, b = r.tree === void 0 ? { nodes: m.filter((e) => typeof e[h] == "string" && e[h] !== "").map((e) => ({
70
+ documentId: String(e.documentId),
71
+ path: String(e[h])
72
+ })) } : n(m.map((e) => ({
73
+ row: e,
74
+ locale: s.locale,
75
+ fallback: !1
76
+ })), r.tree), x = await g(t, f, a(d, o("contentType", r.name), ..._(s))), S = new Map(x.map((e) => [String(e.documentId), e]));
77
+ if (S.size !== x.length) throw new e({ reason: "migration" });
78
+ let C = { tenantId: u.tenantId }, w = !1;
79
+ for (let e of b.nodes) {
80
+ let n = S.get(e.documentId);
81
+ if (n === void 0) {
82
+ await t.insert(f, {
83
+ contentType: r.name,
84
+ documentId: e.documentId,
85
+ ...s,
86
+ path: e.path,
87
+ ...C
88
+ }), w = !0;
89
+ continue;
90
+ }
91
+ if (n.path === e.path) continue;
92
+ let i = String(n.path), c = await y(t, a(d, o("contentType", r.name), ..._(s), o("fromPath", i)));
93
+ c === void 0 ? await t.insert(p, {
94
+ contentType: r.name,
95
+ ...s,
96
+ fromPath: i,
97
+ documentId: e.documentId,
98
+ ...C
99
+ }) : await t.update(p, String(c.id), { documentId: e.documentId }), await t.update(f, String(n.id), { path: e.path }), w = !0;
100
+ }
101
+ return w;
102
+ }, x = async (e, t, n, i) => {
103
+ await b(e, t, n, i) && await r(e, v(n, i));
104
+ }, S = async (e, t, n, s, c, l) => {
105
+ let u = s.replace(/^\/+|\/+$/g, "");
106
+ if (u === "") return;
107
+ let d = v(n, l);
108
+ await i(e, d);
109
+ let f = await y(e, a(o("tenantId", d.tenantId), o("contentType", t.name), ..._(n), o("fromPath", u)));
110
+ f?.documentId !== c && (f === void 0 ? await e.insert(p, {
111
+ contentType: t.name,
112
+ ...n,
113
+ fromPath: u,
114
+ documentId: c,
115
+ tenantId: d.tenantId
116
+ }) : await e.update(p, String(f.id), { documentId: c }), await r(e, d));
117
+ }, C = async (e, t, n, r, i) => {
118
+ let s = i === void 0 ? [] : [o("tenantId", i)], [c] = await g(e, p, a(o("contentType", t), ..._(r), o("fromPath", n), ...s));
119
+ return c === void 0 ? null : String(c.documentId);
120
+ }, w = async (e, t, n, s, c) => {
121
+ let l = s.replace(/^\/+|\/+$/g, ""), u = v(n, c);
122
+ await i(e, u);
123
+ let d = await y(e, a(o("tenantId", u.tenantId), o("contentType", t.name), ..._(n), o("fromPath", l)));
124
+ return d !== void 0 && (await e.delete(p, String(d.id)), await r(e, u), !0);
125
+ }, T = async (e, t, n, r, i) => {
126
+ let s = i === void 0 ? [] : [o("tenantId", i)], [c] = await g(e, f, a(o("contentType", t), ..._(r), o("path", n), ...s));
127
+ return c !== void 0 || await C(e, t, n, r, i) !== null;
128
+ }, E = (e, t, n) => g(e, p, a(o("contentType", t), ..._(n))), D = (...n) => t(() => S(...n), e), O = (...e) => t(() => T(...e)), k = (...e) => t(() => E(...e)), A = (...n) => t(() => x(...n), e), j = (...e) => t(() => C(...e)), M = (...n) => t(() => w(...n), e);
129
+ //#endregion
130
+ export { f as CMS_PATHS_TABLE, p as CMS_REDIRECTS_TABLE, S as addRedirect, D as addRedirectEffect, m as cmsPathsTable, h as cmsRedirectsTable, T as hadAddress, O as hadAddressEffect, E as listRedirects, k as listRedirectsEffect, x as recordPaths, A as recordPathsEffect, b as recordPublicationPaths, C as redirectTarget, j as redirectTargetEffect, w as removeRedirect, M as removeRedirectEffect };
@@ -0,0 +1,224 @@
1
+ import { ContentNotFound as e, ContentValidationFailed as t, RevisionMismatch as n } from "./errors.js";
2
+ import { asTyped as r } from "./effectForm.js";
3
+ import { CMS_REVISIONS_TABLE as i } from "./contentType.js";
4
+ import { CMS_PATHS_TABLE as a, CMS_REDIRECTS_TABLE as o } from "./redirects.js";
5
+ import { CMS_REFERENCES_TABLE as s, referencesOf as c, usedBy as l } from "./references.js";
6
+ import { pickDeclared as u } from "./contentValues.js";
7
+ import { saveDraft as d } from "./write.js";
8
+ import { CMS_RELEASES_TABLE as f, CMS_RELEASE_ITEMS_TABLE as p } from "./release.js";
9
+ import { and as m, eq as h, inSet as g } from "@voltro/database";
10
+ //#region src/referenceGraph.ts
11
+ var _ = (e, t, n) => e.query({
12
+ table: t,
13
+ predicate: n,
14
+ order: [],
15
+ take: void 0,
16
+ skip: void 0,
17
+ projection: void 0
18
+ }), v = (e) => [h("site", e.site), h("environment", e.environment)], y = (e, t, n, r) => {
19
+ if (t != null) {
20
+ if (e.kind === "components" && Array.isArray(t)) {
21
+ let i = new Map((e.components ?? []).map((e) => [e.id, e]));
22
+ t.forEach((e, t) => {
23
+ let a = e;
24
+ if (typeof a.componentId != "string") return;
25
+ r.push({
26
+ path: `${n}[${t}]`,
27
+ componentId: a.componentId
28
+ });
29
+ let o = i.get(a.componentId);
30
+ if (o !== void 0 && typeof a.props == "object" && a.props !== null) for (let [e, i] of Object.entries(o.props)) y(i, a.props[e], `${n}[${t}].props.${e}`, r);
31
+ });
32
+ } else if (e.kind === "array" && e.element !== void 0 && Array.isArray(t)) t.forEach((t, i) => y(e.element, t, `${n}[${i}]`, r));
33
+ else if (e.kind === "struct" && e.struct !== void 0 && typeof t == "object") for (let [i, a] of Object.entries(e.struct)) y(a, t[i], `${n}.${i}`, r);
34
+ }
35
+ }, b = (e, t) => {
36
+ let n = [];
37
+ for (let [r, i] of Object.entries(e.fields)) y(i, t[r], r, n);
38
+ return n;
39
+ }, x = async (e, t, n, r) => {
40
+ let i = [];
41
+ if (t.length === 0) return i;
42
+ for (let a of await _(e, s, m(h("stage", "draft"), h("targetType", n.type), h("targetDocumentId", n.documentId), g("sourceType", t.map((e) => e.name)), ...v(r)))) i.push({
43
+ sourceType: String(a.sourceType),
44
+ sourceDocumentId: String(a.sourceDocumentId),
45
+ sourceVariantId: String(a.sourceVariantId),
46
+ locale: String(a.locale),
47
+ path: String(a.path),
48
+ revisionId: typeof a.revisionId == "string" ? a.revisionId : null
49
+ });
50
+ return i.sort((e, t) => e.sourceType.localeCompare(t.sourceType) || e.sourceDocumentId.localeCompare(t.sourceDocumentId) || e.locale.localeCompare(t.locale) || e.path.localeCompare(t.path));
51
+ }, S = async (e, t, n, r) => {
52
+ let i = [];
53
+ if (t.length === 0) return i;
54
+ for (let a of await _(e, s, m(h("stage", "revision"), h("targetType", n.type), h("targetDocumentId", n.documentId), g("sourceType", t.map((e) => e.name)), ...v(r)))) i.push({
55
+ sourceType: String(a.sourceType),
56
+ sourceDocumentId: String(a.sourceDocumentId),
57
+ locale: String(a.locale),
58
+ revisionId: String(a.revisionId),
59
+ number: Number(a.revisionNumber),
60
+ path: String(a.path)
61
+ });
62
+ return i.sort((e, t) => e.sourceType.localeCompare(t.sourceType) || e.sourceDocumentId.localeCompare(t.sourceDocumentId) || t.number - e.number || e.path.localeCompare(t.path));
63
+ }, C = async (e, t, n, r, s = "published") => {
64
+ let { type: u, documentId: d } = n, y = m(h("documentId", d), h("site", r.site), h("environment", r.environment), h("locale", r.locale)), S = null, C = null;
65
+ if (s === "published" || s === "draft") {
66
+ let [t] = await _(e, `${u.name}_${s === "draft" ? "drafts" : "published"}`, y);
67
+ if (t !== void 0 && (S = t, typeof t.revisionId == "string")) {
68
+ let [n] = await _(e, i, h("id", t.revisionId));
69
+ C = {
70
+ id: t.revisionId,
71
+ number: Number(n?.number ?? t.revision ?? 0)
72
+ };
73
+ }
74
+ } else {
75
+ let [t] = await _(e, i, h("id", s.revisionId));
76
+ t !== void 0 && t.contentType === u.name && t.documentId === d && t.site === r.site && t.environment === r.environment && t.locale === r.locale && typeof t.values == "object" && t.values !== null && (S = t.values, C = {
77
+ id: String(t.id),
78
+ number: Number(t.number)
79
+ });
80
+ }
81
+ let w = {
82
+ type: u.name,
83
+ documentId: d
84
+ }, T = s === "draft" ? await x(e, t, w, r) : (await l(e, w, r)).map((e) => ({
85
+ ...e,
86
+ revisionId: null
87
+ })), [E] = await _(e, a, m(h("contentType", u.name), y)), D = (await _(e, o, m(h("contentType", u.name), y))).map((e) => String(e.fromPath)).sort(), O = (await _(e, `${u.name}_drafts`, m(h("documentId", d), ...v(r)))).map((e) => String(e.id)), k = O.length === 0 ? [] : await _(e, p, m(h("contentType", u.name), g("variantId", O))), A = [...new Set(k.map((e) => String(e.releaseId)))], j = A.length === 0 ? [] : await _(e, f, g("id", A)), M = new Map(j.map((e) => [String(e.id), e]));
88
+ return {
89
+ found: S !== null,
90
+ perspective: typeof s == "string" ? s : "revision",
91
+ revision: C,
92
+ references: S === null ? [] : c(u, S),
93
+ components: S === null ? [] : b(u, S),
94
+ usedBy: T,
95
+ routes: {
96
+ path: typeof E?.path == "string" ? E.path : null,
97
+ formerPaths: D
98
+ },
99
+ releases: k.flatMap((e) => {
100
+ let t = M.get(String(e.releaseId));
101
+ return t === void 0 ? [] : [{
102
+ releaseId: String(t.id),
103
+ name: String(t.name),
104
+ status: String(t.status),
105
+ action: String(e.action),
106
+ revisionId: typeof e.revisionId == "string" ? e.revisionId : null,
107
+ locale: String(e.locale)
108
+ }];
109
+ }).sort((e, t) => e.name.localeCompare(t.name) || e.locale.localeCompare(t.locale))
110
+ };
111
+ }, w = /([^.[\]]+)|\[(\d+)\]/g, T = (e, t, n) => {
112
+ let r = [...t.matchAll(w)].map((e) => e[2] === void 0 ? e[1] : Number(e[2])), i = (e, t) => {
113
+ if (t === r.length) {
114
+ if (typeof e == "string") return n;
115
+ if (typeof e == "object" && e && "target" in e) return {
116
+ ...e,
117
+ target: n
118
+ };
119
+ if (typeof e == "object" && e && "asset" in e) return {
120
+ ...e,
121
+ asset: n
122
+ };
123
+ throw Error("no reference here");
124
+ }
125
+ let a = r[t];
126
+ if (typeof a == "number") {
127
+ if (!Array.isArray(e) || a >= e.length) throw Error("no element here");
128
+ return e.map((e, n) => n === a ? i(e, t + 1) : e);
129
+ }
130
+ if (typeof e != "object" || !e || Array.isArray(e)) throw Error("no object here");
131
+ return {
132
+ ...e,
133
+ [a]: i(e[a], t + 1)
134
+ };
135
+ };
136
+ try {
137
+ return i(e, 0);
138
+ } catch {
139
+ return null;
140
+ }
141
+ }, E = async (e, t, n, r, i) => {
142
+ if (n.type !== r.type) return {
143
+ ok: !1,
144
+ reason: "typeMismatch"
145
+ };
146
+ if (n.documentId === r.documentId) return {
147
+ ok: !1,
148
+ reason: "sameDocument"
149
+ };
150
+ let a = /* @__PURE__ */ new Map();
151
+ for (let r of await x(e, t, n, i)) {
152
+ let e = a.get(r.sourceVariantId);
153
+ a.set(r.sourceVariantId, e === void 0 ? {
154
+ type: r.sourceType,
155
+ documentId: r.sourceDocumentId,
156
+ variantId: r.sourceVariantId,
157
+ locale: r.locale,
158
+ revisionId: r.revisionId,
159
+ paths: [r.path]
160
+ } : {
161
+ ...e,
162
+ paths: [...e.paths, r.path]
163
+ });
164
+ }
165
+ return {
166
+ ok: !0,
167
+ items: [...a.values()]
168
+ };
169
+ }, D = async (r, i, a, o, s) => {
170
+ let c = new Map(i.map((e) => [e.name, e])), l = [];
171
+ for (let i of a) {
172
+ let a = c.get(i.type), f = {
173
+ site: s.site,
174
+ environment: s.environment,
175
+ locale: i.locale
176
+ };
177
+ try {
178
+ if (a === void 0) throw new e({
179
+ contentType: i.type,
180
+ id: i.variantId,
181
+ stage: "draft"
182
+ });
183
+ let t = await r.transactional(async (t) => {
184
+ let [n] = await _(t, `${a.name}_drafts`, m(h("id", i.variantId), h("site", f.site), h("environment", f.environment), h("locale", f.locale)));
185
+ if (n === void 0) throw new e({
186
+ contentType: i.type,
187
+ id: i.variantId,
188
+ stage: "draft"
189
+ });
190
+ let r = { ...u(a, n) };
191
+ for (let e of i.paths) r = r === null ? null : T(r, e, o);
192
+ return r === null ? null : d(t, a, {
193
+ ...r,
194
+ id: i.variantId
195
+ }, f, i.revisionId === null ? {} : { expectedRevision: i.revisionId });
196
+ });
197
+ l.push(t === null ? {
198
+ ...i,
199
+ outcome: "failed",
200
+ reason: "pathGone",
201
+ newRevisionId: null,
202
+ detail: []
203
+ } : {
204
+ ...i,
205
+ outcome: "done",
206
+ reason: null,
207
+ newRevisionId: String(t.revisionId),
208
+ detail: []
209
+ });
210
+ } catch (r) {
211
+ let a = r instanceof n ? "revisionMoved" : r instanceof t ? "incomplete" : r instanceof e ? "notFound" : "failed", o = r instanceof t ? r.violations.map((e) => e.field) : a === "failed" ? [r instanceof Error ? r.message : String(r)] : [];
212
+ l.push({
213
+ ...i,
214
+ outcome: "failed",
215
+ reason: a,
216
+ newRevisionId: null,
217
+ detail: o
218
+ });
219
+ }
220
+ }
221
+ return l;
222
+ }, O = (...e) => r(() => C(...e)), k = (...e) => r(() => x(...e)), A = (...e) => r(() => S(...e)), j = (...e) => r(() => E(...e)), M = (...e) => r(() => D(...e));
223
+ //#endregion
224
+ export { b as componentsOf, C as documentGraph, O as documentGraphEffect, x as draftUses, k as draftUsesEffect, E as planReferenceReplacement, j as planReferenceReplacementEffect, D as replaceReferences, M as replaceReferencesEffect, S as revisionsReferencing, A as revisionsReferencingEffect, T as withReferenceAt };