@voltro/cms 0.86.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 (201) hide show
  1. package/CHANGELOG.md +5321 -0
  2. package/README.md +138 -0
  3. package/THIRD-PARTY-NOTICES.md +860 -221
  4. package/dist/RichDocumentView.js +81 -36
  5. package/dist/aiCandidates.js +3 -3
  6. package/dist/applicationBuildSnapshotService.js +101 -0
  7. package/dist/assetRenditions.js +102 -0
  8. package/dist/assetRevision.js +46 -0
  9. package/dist/assetUseRights.js +72 -0
  10. package/dist/availability.js +19 -16
  11. package/dist/blueprint.js +75 -75
  12. package/dist/build.d.ts +3063 -0
  13. package/dist/build.js +37 -0
  14. package/dist/buildApplicationAdmission.js +16 -0
  15. package/dist/buildApplicationCatalog.js +136 -0
  16. package/dist/buildApplicationCatalogTable.js +24 -0
  17. package/dist/buildApplicationRest.js +99 -0
  18. package/dist/buildApplicationUpload.js +111 -0
  19. package/dist/buildSnapshot.js +401 -0
  20. package/dist/buildSnapshotApplicationPin.js +32 -0
  21. package/dist/buildSnapshotRest.js +210 -0
  22. package/dist/buildSnapshotService.js +265 -0
  23. package/dist/buildSnapshotTables.js +25 -0
  24. package/dist/bulk.js +71 -70
  25. package/dist/changes.js +279 -62
  26. package/dist/consent.js +5 -5
  27. package/dist/contentLocations.js +53 -0
  28. package/dist/contentProjection.js +83 -0
  29. package/dist/contentRouteIdentity.js +13 -0
  30. package/dist/contentRouteMaterializer.js +97 -0
  31. package/dist/contentRouteTypes.js +39 -0
  32. package/dist/contentSeo.js +189 -0
  33. package/dist/contentTreePath.js +60 -0
  34. package/dist/contentType.js +117 -100
  35. package/dist/contentValues.js +18 -0
  36. package/dist/copies.js +3 -3
  37. package/dist/domainHost.js +7 -0
  38. package/dist/domains.js +81 -87
  39. package/dist/draftTexts.js +37 -37
  40. package/dist/duplicates.js +23 -23
  41. package/dist/environmentAliases.js +138 -0
  42. package/dist/environments.js +107 -69
  43. package/dist/errors.js +54 -14
  44. package/dist/experiments.js +7 -7
  45. package/dist/frontendBindings.js +99 -0
  46. package/dist/frontendMedia.js +18 -0
  47. package/dist/index.d.ts +760 -47
  48. package/dist/index.js +89 -73
  49. package/dist/initializePublicRoutes.js +28 -0
  50. package/dist/liveContentRouteView.js +76 -0
  51. package/dist/nativeOutputDeploymentService.js +205 -0
  52. package/dist/outputActivation.js +234 -0
  53. package/dist/outputActivationOrigin.js +51 -0
  54. package/dist/outputActivationStore.js +411 -0
  55. package/dist/outputActivationTables.js +11 -0
  56. package/dist/outputActivationTarget.js +81 -0
  57. package/dist/outputActivationTargetTable.js +25 -0
  58. package/dist/outputDeployment.js +174 -0
  59. package/dist/outputDeploymentRest.js +168 -0
  60. package/dist/outputDeploymentService.js +241 -0
  61. package/dist/outputRouteGraph.js +177 -0
  62. package/dist/outputSafetyArtifact.js +147 -0
  63. package/dist/outputTargetRest.js +62 -0
  64. package/dist/pathSegmentEncoding.js +4 -0
  65. package/dist/privateCmsTransport.js +76 -0
  66. package/dist/privateNativeRouteReservation.js +10 -0
  67. package/dist/promotion.js +68 -59
  68. package/dist/publicBuild.js +90 -0
  69. package/dist/publicBuildRest.js +98 -0
  70. package/dist/publicBuildService.js +63 -0
  71. package/dist/publicOutputHttp.js +129 -0
  72. package/dist/publicOutputService.js +287 -0
  73. package/dist/publicPresentation.js +17 -0
  74. package/dist/publicRouteDispositionAdmission.js +38 -0
  75. package/dist/publicRouteHistoryStore.js +12 -0
  76. package/dist/publicRouteHistoryView.js +34 -0
  77. package/dist/publicRouteIntegrity.js +5 -0
  78. package/dist/publicRouteMutation.js +6 -0
  79. package/dist/publicRouteNamespace.js +134 -0
  80. package/dist/publicRoutePublication.js +36 -0
  81. package/dist/publicRouteRegistry.js +17 -0
  82. package/dist/publicRouteRegistryBinding.js +194 -0
  83. package/dist/publicRouteRegistryDefinition.js +76 -0
  84. package/dist/publicRouteSitePublication.js +40 -0
  85. package/dist/publicRouteTables.js +13 -0
  86. package/dist/publicRouteUrl.js +18 -0
  87. package/dist/publicationSeo.js +52 -0
  88. package/dist/publicationState.js +296 -0
  89. package/dist/quality.js +8 -8
  90. package/dist/reconfigurePublicRoutes.js +41 -0
  91. package/dist/redirects.js +104 -73
  92. package/dist/referenceGraph.js +15 -14
  93. package/dist/references.js +2 -2
  94. package/dist/release.js +177 -141
  95. package/dist/renderReadAuthority.js +43 -0
  96. package/dist/renderReadGrant.js +137 -0
  97. package/dist/review.js +28 -28
  98. package/dist/richDocument.js +54 -24
  99. package/dist/routeDispositionGraph.js +44 -0
  100. package/dist/routeDispositionRest.js +51 -0
  101. package/dist/routeDispositionService.js +73 -0
  102. package/dist/routeDispositionStore.js +289 -0
  103. package/dist/routeDispositionTables.js +5 -0
  104. package/dist/routeDispositions.js +91 -0
  105. package/dist/routeHistoryStorage.js +320 -0
  106. package/dist/routeHistoryStore.js +12 -0
  107. package/dist/schedule.js +36 -36
  108. package/dist/seo.js +1 -1
  109. package/dist/series.js +11 -11
  110. package/dist/share.js +13 -13
  111. package/dist/siteBindings.js +159 -0
  112. package/dist/siteBuildCandidate.js +104 -0
  113. package/dist/siteDelivery.js +115 -0
  114. package/dist/siteState.js +47 -0
  115. package/dist/snapshotAddressGraph.js +55 -0
  116. package/dist/snapshotAddressRead.js +73 -0
  117. package/dist/snapshotAppConsumer.js +71 -0
  118. package/dist/snapshotAppExecution.js +102 -0
  119. package/dist/snapshotApplication.js +75 -0
  120. package/dist/snapshotApprovedRouteDispositions.js +44 -0
  121. package/dist/snapshotAssetAssembly.js +70 -0
  122. package/dist/snapshotAssetAssemblyRest.js +50 -0
  123. package/dist/snapshotBindingRead.js +61 -0
  124. package/dist/snapshotCodeSeo.js +29 -0
  125. package/dist/snapshotComponent.js +34 -0
  126. package/dist/snapshotComponentSource.js +24 -0
  127. package/dist/snapshotConsumer.js +87 -0
  128. package/dist/snapshotContentIdentity.js +10 -0
  129. package/dist/snapshotDefinitions.js +264 -0
  130. package/dist/snapshotDocumentAssembly.js +193 -0
  131. package/dist/snapshotDocumentAssemblyRest.js +84 -0
  132. package/dist/snapshotDocumentProjection.js +202 -0
  133. package/dist/snapshotDocumentTransfer.js +35 -0
  134. package/dist/snapshotDocumentTransferRest.js +80 -0
  135. package/dist/snapshotDomains.js +56 -0
  136. package/dist/snapshotEnvironment.js +31 -0
  137. package/dist/snapshotFieldPlan.js +85 -0
  138. package/dist/snapshotFrontend.js +103 -0
  139. package/dist/snapshotLink.js +8 -0
  140. package/dist/snapshotMedia.js +111 -0
  141. package/dist/snapshotMediaCapture.js +246 -0
  142. package/dist/snapshotMediaFields.js +225 -0
  143. package/dist/snapshotMediaRead.js +185 -0
  144. package/dist/snapshotMediaReader.js +13 -0
  145. package/dist/snapshotObservation.js +16 -0
  146. package/dist/snapshotObservedRouteHistory.js +34 -0
  147. package/dist/snapshotOutputTransfer.js +78 -0
  148. package/dist/snapshotPageLoader.js +7 -0
  149. package/dist/snapshotPageSeo.js +59 -0
  150. package/dist/snapshotPathLocale.js +15 -0
  151. package/dist/snapshotPresentation.js +86 -0
  152. package/dist/snapshotPresentationPolicy.js +12 -0
  153. package/dist/snapshotProjection.js +119 -0
  154. package/dist/snapshotPublicAccess.js +161 -0
  155. package/dist/snapshotPublicRouteHistory.js +40 -0
  156. package/dist/snapshotReadAdmission.js +38 -0
  157. package/dist/snapshotRedirectOutput.js +151 -0
  158. package/dist/snapshotRedirectTargets.js +24 -0
  159. package/dist/snapshotRedirects.js +132 -0
  160. package/dist/snapshotReference.js +8 -0
  161. package/dist/snapshotReferenceAddress.js +10 -0
  162. package/dist/snapshotReferenceGraph.js +79 -0
  163. package/dist/snapshotReferenceRead.js +65 -0
  164. package/dist/snapshotRelease.js +99 -0
  165. package/dist/snapshotRender.js +361 -0
  166. package/dist/snapshotRenderDependencies.js +178 -0
  167. package/dist/snapshotRenditions.js +88 -0
  168. package/dist/snapshotRichDocument.js +62 -0
  169. package/dist/snapshotRoleTransfer.js +106 -0
  170. package/dist/snapshotRoleTransferRest.js +99 -0
  171. package/dist/snapshotRouteAdmission.js +71 -0
  172. package/dist/snapshotRouteDispatch.js +111 -0
  173. package/dist/snapshotRouteDispositionPlan.js +73 -0
  174. package/dist/snapshotRouteRead.js +43 -0
  175. package/dist/snapshotRoutes.js +79 -0
  176. package/dist/snapshotRouting.js +113 -0
  177. package/dist/snapshotSeo.js +179 -0
  178. package/dist/snapshotSeoControls.js +101 -0
  179. package/dist/snapshotSeoDocumentInventory.js +115 -0
  180. package/dist/snapshotSeoDocuments.js +129 -0
  181. package/dist/snapshotSeoMerge.js +85 -0
  182. package/dist/snapshotSeoMetadata.js +137 -0
  183. package/dist/snapshotSeoOutput.js +173 -0
  184. package/dist/snapshotSeoPathSets.js +105 -0
  185. package/dist/snapshotSeoRead.js +88 -0
  186. package/dist/snapshotSite.js +128 -0
  187. package/dist/snapshotSitemapFiles.js +36 -0
  188. package/dist/snapshotTreeDependencies.js +58 -0
  189. package/dist/snapshotTreeLoader.js +10 -0
  190. package/dist/snapshotTreeRead.js +158 -0
  191. package/dist/staticPathSet.js +177 -0
  192. package/dist/staticPathSetRest.js +129 -0
  193. package/dist/staticPathSetService.js +249 -0
  194. package/dist/staticPathSetStore.js +338 -0
  195. package/dist/tree.js +9 -9
  196. package/dist/validation.js +53 -53
  197. package/dist/web.d.ts +709 -7
  198. package/dist/web.js +50 -33
  199. package/dist/workflow.js +8 -8
  200. package/dist/write.js +250 -225
  201. package/package.json +20 -6
@@ -0,0 +1,289 @@
1
+ import { invalidatePublicationRelease as e, lockPublicationStream as t } from "./changes.js";
2
+ import { copyOutputActivationScope as n, outputActivationHash as r } from "./outputActivation.js";
3
+ import { copyCanonicalPublicRouteUrl as i } from "./publicRouteUrl.js";
4
+ import { copyRouteDispositionDefinition as a, routeDispositionFail as o } from "./routeDispositions.js";
5
+ import { copyRenderReadAuthority as s } from "./renderReadAuthority.js";
6
+ import { and as c, eq as l, generateId as u, gt as d, id as f, inSet as p, integer as m, json as h, table as g, text as _, timestamp as v } from "@voltro/database";
7
+ import { tenant as y } from "@voltro/plugin-multitenancy/mixin";
8
+ import { canonicalJson as b } from "@voltro/runtime";
9
+ //#region src/routeDispositionStore.ts
10
+ var x = "_voltro_cms_route_disposition_heads", S = "_voltro_cms_route_dispositions", C = "_voltro_cms_route_disposition_revisions", w = g(x, {
11
+ id: f({ prefix: "crph" }),
12
+ site: _().maxLength(64),
13
+ environment: _().maxLength(64),
14
+ revision: m(),
15
+ count: m()
16
+ }).with(y()).unique("cms_route_disposition_scope", [
17
+ "tenantId",
18
+ "site",
19
+ "environment"
20
+ ]), T = () => ({
21
+ site: _().maxLength(64),
22
+ environment: _().maxLength(64),
23
+ urlKey: _().maxLength(64),
24
+ revision: m(),
25
+ revisionId: _().maxLength(64),
26
+ previousRevisionId: _().maxLength(64).nullable(),
27
+ definition: h(),
28
+ authority: h(),
29
+ approvedAt: v(),
30
+ integrityDigest: _().maxLength(64)
31
+ }), E = g(S, {
32
+ id: f({ prefix: "crpd" }),
33
+ ...T()
34
+ }).with(y()).unique("cms_route_disposition_source", [
35
+ "tenantId",
36
+ "site",
37
+ "environment",
38
+ "urlKey"
39
+ ]), D = g(C, {
40
+ id: f({ prefix: "crpv" }),
41
+ ...T()
42
+ }).with(y()).unique("cms_route_disposition_revision", [
43
+ "tenantId",
44
+ "site",
45
+ "environment",
46
+ "revision"
47
+ ]), O = [
48
+ w,
49
+ E,
50
+ D
51
+ ], k = 2147483647, A = 1e5, j = (e) => Number.isSafeInteger(e) && Number(e) >= 0 && Number(e) <= k, M = (e) => typeof e == "string" && /^[A-Za-z0-9_-]{1,64}$/.test(e), N = (e) => typeof e == "string" && /^[a-f0-9]{64}$/.test(e), P = (e) => {
52
+ try {
53
+ return n(e);
54
+ } catch {
55
+ return o("scope");
56
+ }
57
+ }, F = (e) => c(l("tenantId", e.tenantId), l("site", e.site), l("environment", e.environment)), I = (e, t) => u({
58
+ kind: "typeid",
59
+ prefix: e
60
+ }, t) ?? o("state"), L = async (e, t, n) => {
61
+ let r = () => e.query({
62
+ table: x,
63
+ predicate: F(t),
64
+ lock: "update",
65
+ order: [],
66
+ take: 2,
67
+ skip: void 0,
68
+ projection: void 0
69
+ }), i = await r();
70
+ if (i.length === 0) {
71
+ for (let n of [S, C]) if ((await e.query({
72
+ table: n,
73
+ predicate: F(t),
74
+ lock: "update",
75
+ order: [],
76
+ take: 1,
77
+ skip: void 0,
78
+ projection: ["id"]
79
+ })).length > 0) return o("state");
80
+ if (!n) return null;
81
+ await e.insertIgnore(x, {
82
+ id: I("crph", x),
83
+ ...t,
84
+ revision: 0,
85
+ count: 0
86
+ }, { conflictColumns: [
87
+ "tenantId",
88
+ "site",
89
+ "environment"
90
+ ] }), i = await r();
91
+ }
92
+ let a = i[0];
93
+ return i.length !== 1 || a === void 0 || !M(a.id) || !j(a.revision) || !j(a.count) || a.count > A || a.count > a.revision || a.count === 0 != (a.revision === 0) ? o("state") : {
94
+ id: a.id,
95
+ revision: a.revision,
96
+ count: a.count
97
+ };
98
+ }, R = (e, t, n) => {
99
+ let i;
100
+ try {
101
+ i = a(e.definition);
102
+ } catch {
103
+ return o("state");
104
+ }
105
+ let c = s(e.authority), l = e.approvedAt instanceof Date ? e.approvedAt.getTime() : NaN;
106
+ if (!M(e.revisionId) || !j(e.revision) || e.revision < 1 || e.revision > n.revision || !(e.previousRevisionId === null || M(e.previousRevisionId)) || e.previousRevisionId === e.revisionId || c === null || !Number.isSafeInteger(l) || l < 0 || !N(e.urlKey) || e.urlKey !== r(i.source.url)) return o("state");
107
+ let u = {
108
+ revision: e.revision,
109
+ revisionId: e.revisionId,
110
+ previousRevisionId: e.previousRevisionId,
111
+ definition: i,
112
+ authority: c,
113
+ approvedAt: l
114
+ }, d = r({
115
+ scope: t,
116
+ ...u
117
+ });
118
+ return e.integrityDigest === d ? {
119
+ ...u,
120
+ urlKey: e.urlKey,
121
+ integrityDigest: d
122
+ } : o("state");
123
+ }, z = async (e, t, n, r) => {
124
+ let i = r.map((e) => R(e, t, n)), a = i.map((e) => e.revisionId);
125
+ if (new Set(a).size !== a.length) return o("state");
126
+ let s = a.length === 0 ? [] : await e.query({
127
+ table: C,
128
+ predicate: c(F(t), p("id", a)),
129
+ lock: "update",
130
+ order: [],
131
+ take: a.length + 1,
132
+ skip: void 0,
133
+ projection: void 0
134
+ });
135
+ if (s.length !== a.length) return o("state");
136
+ let l = new Map(s.map((e) => [String(e.id), e]));
137
+ if (l.size !== s.length) return o("state");
138
+ for (let e of i) {
139
+ let r = l.get(e.revisionId);
140
+ if (r === void 0 || r.id !== r.revisionId || b(R(r, t, n)) !== b(e)) return o("state");
141
+ }
142
+ return i.map(({ integrityDigest: e, ...t }) => t);
143
+ }, B = async (e, t, n) => {
144
+ let a = P(t);
145
+ try {
146
+ i(n);
147
+ } catch {
148
+ return o("input");
149
+ }
150
+ let s = await L(e, a, !1);
151
+ if (s === null) return null;
152
+ let u = await e.query({
153
+ table: S,
154
+ predicate: c(F(a), l("urlKey", r(n))),
155
+ lock: "update",
156
+ order: [],
157
+ take: 2,
158
+ skip: void 0,
159
+ projection: void 0
160
+ });
161
+ if (u.length > 1) return o("state");
162
+ let d = (await z(e, a, s, u))[0];
163
+ if (d === void 0) return null;
164
+ if (d.definition.source.url !== n) return o("state");
165
+ let { urlKey: f, ...p } = d;
166
+ return p;
167
+ }, V = async (e, t, n = {}) => {
168
+ let r = P(t), { expectedRevision: i, after: a, take: s = 500 } = n;
169
+ if (!Number.isInteger(s) || s < 1 || s > 1e3 || i !== void 0 && !j(i) || a !== void 0 && (!N(a) || i === void 0)) return o("input");
170
+ let l = await L(e, r, !1);
171
+ if (i !== void 0 && i !== (l?.revision ?? 0)) return o("revision");
172
+ if (l === null) return {
173
+ revision: 0,
174
+ count: 0,
175
+ entries: [],
176
+ next: null
177
+ };
178
+ let u = await z(e, r, l, await e.query({
179
+ table: S,
180
+ predicate: c(F(r), ...a === void 0 ? [] : [d("urlKey", a)]),
181
+ lock: "update",
182
+ order: [{
183
+ column: "urlKey",
184
+ direction: "asc"
185
+ }],
186
+ take: s + 1,
187
+ skip: void 0,
188
+ projection: void 0
189
+ }));
190
+ if (u.length > l.count) return o("state");
191
+ let f = a ?? "";
192
+ for (let e of u) {
193
+ if (e.urlKey <= f) return o("state");
194
+ f = e.urlKey;
195
+ }
196
+ return {
197
+ revision: l.revision,
198
+ count: l.count,
199
+ entries: u.slice(0, s),
200
+ next: u.length > s ? u[s - 1].urlKey : null
201
+ };
202
+ }, H = async (n, i, u) => {
203
+ let d = P(i), f = u.expectedRevision, p = a(u.definition), m = s(u.authority), h = u.now;
204
+ if (!j(f) || m === null || !Number.isSafeInteger(h) || h < 0 || h > 864e13) return o("input");
205
+ await t(n, d);
206
+ let g = await L(n, d, !0);
207
+ if (g === null) return o("state");
208
+ let _ = r(p.source.url), v = await n.query({
209
+ table: S,
210
+ predicate: c(F(d), l("urlKey", _)),
211
+ lock: "update",
212
+ order: [],
213
+ take: 2,
214
+ skip: void 0,
215
+ projection: void 0
216
+ });
217
+ if (v.length > 1) return o("state");
218
+ let y = (await z(n, d, g, v))[0], x = y !== void 0 && b(y.definition) === b(p) && b(y.authority) === b(m);
219
+ if (g.revision !== f) {
220
+ if (g.revision === f + 1 && y?.revision === g.revision && x) {
221
+ let { urlKey: e, ...t } = y;
222
+ return {
223
+ ...t,
224
+ count: g.count
225
+ };
226
+ }
227
+ return o("revision");
228
+ }
229
+ if (x && y !== void 0) {
230
+ let { urlKey: e, ...t } = y;
231
+ return {
232
+ ...t,
233
+ count: g.count
234
+ };
235
+ }
236
+ if (g.revision === k || y === void 0 && g.count === A) return o("bounds");
237
+ let w = {
238
+ revision: g.revision + 1,
239
+ revisionId: I("crpv", C),
240
+ previousRevisionId: y?.revisionId ?? null,
241
+ definition: p,
242
+ authority: m,
243
+ approvedAt: h
244
+ }, T = {
245
+ ...d,
246
+ urlKey: _,
247
+ ...w,
248
+ approvedAt: new Date(h),
249
+ integrityDigest: r({
250
+ scope: d,
251
+ ...w
252
+ })
253
+ };
254
+ if (await n.insert(C, {
255
+ id: w.revisionId,
256
+ ...T
257
+ }), y === void 0) await n.insert(S, {
258
+ id: I("crpd", S),
259
+ ...T
260
+ });
261
+ else {
262
+ let e = v[0];
263
+ if (!M(e.id)) return o("state");
264
+ await n.update(S, e.id, T);
265
+ }
266
+ let E = g.count + +(y === void 0);
267
+ return await n.updateMany("_voltro_cms_route_disposition_heads", {
268
+ revision: w.revision,
269
+ count: E
270
+ }, { where: c(F(d), l("id", g.id), l("revision", g.revision)) }) === 1 ? (await e(n, d), {
271
+ ...w,
272
+ count: E
273
+ }) : o("revision");
274
+ };
275
+ async function* U(e, t) {
276
+ let n, r, i = 0, a = 0;
277
+ do {
278
+ let o = await V(e, t, {
279
+ ...r === void 0 ? {} : { expectedRevision: r },
280
+ ...n === void 0 ? {} : { after: n }
281
+ });
282
+ r = o.revision, a = o.count;
283
+ for (let { urlKey: e, ...t } of o.entries) i++, yield t;
284
+ n = o.next ?? void 0;
285
+ } while (n !== void 0);
286
+ if (i !== a) return o("state");
287
+ }
288
+ //#endregion
289
+ export { S as ROUTE_DISPOSITIONS, x as ROUTE_DISPOSITION_HEADS, C as ROUTE_DISPOSITION_REVISIONS, U as iterateApprovedRouteDispositions, V as readApprovedRouteDispositionPage, B as readApprovedRouteDispositionUrl, w as routeDispositionHeadsTable, D as routeDispositionRevisionsTable, O as routeDispositionTables, E as routeDispositionsTable, H as writeApprovedRouteDisposition };
@@ -0,0 +1,5 @@
1
+ import { routeDispositionTables as e } from "./routeDispositionStore.js";
2
+ //#region src/routeDispositionTables.ts
3
+ var t = Object.freeze([...e]);
4
+ //#endregion
5
+ export { t as cmsRouteDispositionTables };
@@ -0,0 +1,91 @@
1
+ import { copyCanonicalPublicRouteUrl as e } from "./publicRouteUrl.js";
2
+ import { Schema as t } from "effect";
3
+ //#region src/routeDispositions.ts
4
+ var n = class extends t.TaggedError()("RouteDispositionUnavailable", { reason: t.Literals([
5
+ "input",
6
+ "bounds",
7
+ "scope",
8
+ "state",
9
+ "revision",
10
+ "credential",
11
+ "graph",
12
+ "hold"
13
+ ]) }) {}, r = (e) => {
14
+ throw new n({ reason: e });
15
+ }, i = (e, t) => {
16
+ if (typeof e != "object" || !e || Array.isArray(e) || ![Object.prototype, null].includes(Object.getPrototypeOf(e)) || Object.getOwnPropertySymbols(e).length > 0) return r("input");
17
+ let n = Object.getOwnPropertyDescriptors(e);
18
+ return Object.values(n).some((e) => !e.enumerable || !("value" in e)) || t !== void 0 && Object.keys(n).sort().join(",") !== t ? r("input") : Object.fromEntries(Object.entries(n).map(([e, t]) => [e, t.value]));
19
+ }, a = (t) => {
20
+ let n = i(t, "routeId,url");
21
+ if (typeof n.routeId != "string" || !/^(route|native)_[a-f0-9]{64}$/.test(n.routeId)) return r("input");
22
+ try {
23
+ return {
24
+ url: e(n.url),
25
+ routeId: n.routeId
26
+ };
27
+ } catch {
28
+ return r("input");
29
+ }
30
+ }, o = (e) => e === null ? null : Number.isSafeInteger(e) && Number(e) >= 0 && Number(e) <= 864e13 ? Number(e) : r("input"), s = (e) => {
31
+ let t = i(e);
32
+ if (t.kind === "hold") return i(e, "kind"), { kind: "hold" };
33
+ if (t.kind === "gone") return i(e, "kind,status"), t.status === 404 || t.status === 410 ? {
34
+ kind: "gone",
35
+ status: t.status
36
+ } : r("input");
37
+ if (t.kind !== "redirect") return r("input");
38
+ i(e, "kind,method,status,target");
39
+ let n = a(t.target);
40
+ return (t.status === 301 || t.status === 302) && t.method === "allow-post-to-get" ? {
41
+ kind: "redirect",
42
+ status: t.status,
43
+ method: "allow-post-to-get",
44
+ target: n
45
+ } : (t.status === 307 || t.status === 308) && t.method === "preserve" ? {
46
+ kind: "redirect",
47
+ status: t.status,
48
+ method: "preserve",
49
+ target: n
50
+ } : r("input");
51
+ }, c = (e) => {
52
+ let t = i(e, "action,activeFrom,activeUntil,source,version");
53
+ if (t.version !== 1) return r("input");
54
+ let n = a(t.source), c = s(t.action), l = o(t.activeFrom), u = o(t.activeUntil);
55
+ return l !== null && u !== null && l >= u || c.kind === "redirect" && c.target.url === n.url ? r("input") : {
56
+ version: 1,
57
+ source: n,
58
+ action: c,
59
+ activeFrom: l,
60
+ activeUntil: u
61
+ };
62
+ }, l = t.Struct({
63
+ url: t.String,
64
+ routeId: t.String
65
+ }), u = t.Struct({
66
+ version: t.Literal(1),
67
+ source: l,
68
+ action: t.Union([
69
+ t.Struct({
70
+ kind: t.Literal("redirect"),
71
+ status: t.Literals([301, 302]),
72
+ method: t.Literal("allow-post-to-get"),
73
+ target: l
74
+ }),
75
+ t.Struct({
76
+ kind: t.Literal("redirect"),
77
+ status: t.Literals([307, 308]),
78
+ method: t.Literal("preserve"),
79
+ target: l
80
+ }),
81
+ t.Struct({
82
+ kind: t.Literal("gone"),
83
+ status: t.Literals([404, 410])
84
+ }),
85
+ t.Struct({ kind: t.Literal("hold") })
86
+ ]),
87
+ activeFrom: t.NullOr(t.Int),
88
+ activeUntil: t.NullOr(t.Int)
89
+ });
90
+ //#endregion
91
+ export { u as RouteDispositionDefinitionSchema, n as RouteDispositionUnavailable, c as copyRouteDispositionDefinition, r as routeDispositionFail };
@@ -0,0 +1,320 @@
1
+ import { copyOutputActivationScope as e, outputActivationHash as t } from "./outputActivation.js";
2
+ import { copyCanonicalPublicRouteUrl as n } from "./publicRouteUrl.js";
3
+ import { Schema as r } from "effect";
4
+ import { and as i, boolean as a, eq as o, generateId as s, gt as c, id as l, integer as u, table as d, text as f } from "@voltro/database";
5
+ import { tenant as p } from "@voltro/plugin-multitenancy/mixin";
6
+ import { canonicalJson as m } from "@voltro/runtime";
7
+ //#region src/routeHistoryStorage.ts
8
+ var h = class extends r.TaggedError()("RouteHistoryUnavailable", { reason: r.Literals([
9
+ "scope",
10
+ "input",
11
+ "state",
12
+ "revision",
13
+ "bounds"
14
+ ]) }) {}, g = 2147483647, _ = 1e5, v = 67108864, y = (e) => {
15
+ throw new h({ reason: e });
16
+ }, b = (e) => typeof e == "string" && /^[a-f0-9]{64}$/.test(e), x = (e) => Number.isSafeInteger(e) && Number(e) >= 0 && Number(e) <= g, S = (t) => {
17
+ try {
18
+ return e(t);
19
+ } catch {
20
+ return y("scope");
21
+ }
22
+ }, C = (e) => i(o("tenantId", e.tenantId), o("site", e.site), o("environment", e.environment)), w = (e, t) => {
23
+ let n = s({
24
+ kind: "typeid",
25
+ prefix: e
26
+ }, t);
27
+ return n === null ? y("state") : n;
28
+ }, T = (e) => {
29
+ if (typeof e != "object" || !e || Array.isArray(e) || ![Object.prototype, null].includes(Object.getPrototypeOf(e)) || Object.getOwnPropertySymbols(e).length > 0) return y("input");
30
+ let t = Object.getOwnPropertyDescriptors(e);
31
+ if (Object.keys(t).sort().join(",") !== "routeId,url" || Object.values(t).some((e) => !e.enumerable || !("value" in e))) return y("input");
32
+ let r = t.url.value, i = t.routeId.value;
33
+ if (typeof r != "string" || r.length > 4400 || typeof i != "string" || !/^(route|native)_[a-f0-9]{64}$/.test(i)) return y("input");
34
+ try {
35
+ n(r);
36
+ } catch {
37
+ return y("input");
38
+ }
39
+ return {
40
+ url: r,
41
+ routeId: i
42
+ };
43
+ }, E = (e) => {
44
+ if (!Array.isArray(e) || e.length > _ || Object.getOwnPropertySymbols(e).length > 0 || Object.keys(e).length !== e.length) return y("bounds");
45
+ let t = 2, n = Array.from({ length: e.length }, (n, r) => {
46
+ let i = Object.getOwnPropertyDescriptor(e, String(r));
47
+ if (i === void 0 || !("value" in i)) return y("input");
48
+ let a = T(i.value);
49
+ return t += Buffer.byteLength(m(a)) + (r === 0 ? 0 : 1), t > v ? y("bounds") : a;
50
+ }).sort((e, t) => e.url < t.url ? -1 : +(e.url > t.url));
51
+ return n.some((e, t) => t > 0 && n[t - 1].url === e.url) ? y("input") : n;
52
+ }, D = (e) => {
53
+ let { heads: r, entries: s, headPrefix: m, entryPrefix: h, headIndex: v, entryIndex: D } = e, O = d(r, {
54
+ id: l({ prefix: m }),
55
+ site: f().maxLength(64),
56
+ environment: f().maxLength(64),
57
+ revision: u(),
58
+ sourceDigest: f().maxLength(64).nullable(),
59
+ currentDigest: f().maxLength(64).nullable(),
60
+ currentCount: u(),
61
+ historyCount: u()
62
+ }).with(p()).unique(v, [
63
+ "tenantId",
64
+ "site",
65
+ "environment"
66
+ ]), k = d(s, {
67
+ id: l({ prefix: h }),
68
+ site: f().maxLength(64),
69
+ environment: f().maxLength(64),
70
+ urlKey: f().maxLength(64),
71
+ url: f(),
72
+ routeId: f().maxLength(71),
73
+ active: a(),
74
+ firstRevision: u(),
75
+ lastRevision: u(),
76
+ firstSourceDigest: f().maxLength(64),
77
+ lastSourceDigest: f().maxLength(64)
78
+ }).with(p()).unique(D, [
79
+ "tenantId",
80
+ "site",
81
+ "environment",
82
+ "urlKey"
83
+ ]), A = [O, k], j = async (e, t, n) => {
84
+ let i = () => e.query({
85
+ table: r,
86
+ predicate: C(t),
87
+ lock: "update",
88
+ order: [],
89
+ take: 2,
90
+ skip: void 0,
91
+ projection: void 0
92
+ }), a = await i();
93
+ if (a.length === 0) {
94
+ if ((await e.query({
95
+ table: s,
96
+ predicate: C(t),
97
+ lock: "update",
98
+ order: [],
99
+ take: 1,
100
+ skip: void 0,
101
+ projection: ["id"]
102
+ })).length > 0) return y("state");
103
+ if (!n) return null;
104
+ await e.insertIgnore(r, {
105
+ id: w(m, r),
106
+ ...t,
107
+ revision: 0,
108
+ sourceDigest: null,
109
+ currentDigest: null,
110
+ currentCount: 0,
111
+ historyCount: 0
112
+ }, { conflictColumns: [
113
+ "tenantId",
114
+ "site",
115
+ "environment"
116
+ ] }), a = await i();
117
+ }
118
+ let o = a[0];
119
+ if (a.length !== 1 || o === void 0 || typeof o.id != "string" || !x(o.revision) || !x(o.currentCount) || Number(o.currentCount) > _ || !x(o.historyCount) || Number(o.historyCount) < Number(o.currentCount)) return y("state");
120
+ let c = Number(o.revision), l = o.sourceDigest, u = o.currentDigest;
121
+ return (c === 0 ? l !== null || u !== null || o.historyCount !== 0 : !b(l) || !b(u)) ? y("state") : {
122
+ id: o.id,
123
+ revision: c,
124
+ sourceDigest: l,
125
+ currentDigest: u,
126
+ currentCount: Number(o.currentCount),
127
+ historyCount: Number(o.historyCount)
128
+ };
129
+ }, M = ({ revision: e, sourceDigest: t, currentDigest: n, currentCount: r, historyCount: i }) => ({
130
+ revision: e,
131
+ sourceDigest: t,
132
+ currentDigest: n,
133
+ currentCount: r,
134
+ historyCount: i
135
+ }), N = (e, n) => {
136
+ let r;
137
+ try {
138
+ r = T({
139
+ url: e.url,
140
+ routeId: e.routeId
141
+ });
142
+ } catch {
143
+ return y("state");
144
+ }
145
+ return typeof e.id != "string" || e.urlKey !== t(r.url) || typeof e.active != "boolean" || !x(e.firstRevision) || Number(e.firstRevision) < 1 || !x(e.lastRevision) || Number(e.lastRevision) < Number(e.firstRevision) || Number(e.lastRevision) > n.revision || !b(e.firstSourceDigest) || !b(e.lastSourceDigest) ? y("state") : {
146
+ id: e.id,
147
+ ...r,
148
+ urlKey: String(e.urlKey),
149
+ active: e.active,
150
+ firstRevision: Number(e.firstRevision),
151
+ lastRevision: Number(e.lastRevision),
152
+ firstSourceDigest: e.firstSourceDigest,
153
+ lastSourceDigest: e.lastSourceDigest
154
+ };
155
+ }, P = async (e, t, n = {}) => {
156
+ let r = S(t), a = n.take ?? 500, o = n.after, l = n.expectedRevision;
157
+ if (!Number.isInteger(a) || a < 1 || a > 1e3 || o !== void 0 && (!b(o) || l === void 0) || l !== void 0 && !x(l)) return y("input");
158
+ let u = await j(e, r, !1);
159
+ if (l !== void 0 && l !== (u?.revision ?? 0)) return y("revision");
160
+ if (u === null) return {
161
+ revision: 0,
162
+ sourceDigest: null,
163
+ currentDigest: null,
164
+ currentCount: 0,
165
+ historyCount: 0,
166
+ entries: [],
167
+ next: null
168
+ };
169
+ let d = (await e.query({
170
+ table: s,
171
+ predicate: i(C(r), ...o === void 0 ? [] : [c("urlKey", o)]),
172
+ lock: "update",
173
+ order: [{
174
+ column: "urlKey",
175
+ direction: "asc"
176
+ }],
177
+ take: a + 1,
178
+ skip: void 0,
179
+ projection: void 0
180
+ })).map((e) => {
181
+ let { id: t, ...n } = N(e, u);
182
+ return n;
183
+ });
184
+ return o === void 0 && d.length === 0 && u.historyCount !== 0 || d.length > u.historyCount ? y("state") : {
185
+ ...M(u),
186
+ entries: d.slice(0, a),
187
+ next: d.length > a ? d[a - 1].urlKey : null
188
+ };
189
+ }, F = async (e, r, a) => {
190
+ let c = S(r), l;
191
+ try {
192
+ l = n(a);
193
+ } catch {
194
+ return y("input");
195
+ }
196
+ let u = await j(e, c, !1);
197
+ if (u === null) return null;
198
+ let d = await e.query({
199
+ table: s,
200
+ predicate: i(C(c), o("urlKey", t(l))),
201
+ lock: "update",
202
+ order: [],
203
+ take: 2,
204
+ skip: void 0,
205
+ projection: void 0
206
+ });
207
+ if (d.length > 1) return y("state");
208
+ if (d.length === 0) return null;
209
+ let { id: f, ...p } = N(d[0], u);
210
+ return p.url === l ? p : y("state");
211
+ }, I = async (e, n, a) => {
212
+ let l = S(n), u = a.expectedRevision, d = a.sourceDigest, f = E(a.routes);
213
+ if (!x(u) || !b(d)) return y("input");
214
+ let p = await j(e, l, u === 0);
215
+ if (p === null) return y("revision");
216
+ let m = t(f), v = /* @__PURE__ */ new Map(), T;
217
+ for (;;) {
218
+ let t = await e.query({
219
+ table: s,
220
+ predicate: i(C(l), o("active", !0), ...T === void 0 ? [] : [c("urlKey", T)]),
221
+ lock: "update",
222
+ order: [{
223
+ column: "urlKey",
224
+ direction: "asc"
225
+ }],
226
+ take: 500,
227
+ skip: void 0,
228
+ projection: void 0
229
+ });
230
+ if (t.length === 0) break;
231
+ for (let e of t) {
232
+ let t = N(e, p);
233
+ if (v.has(t.url) || v.size >= _) return y("state");
234
+ v.set(t.url, t);
235
+ }
236
+ T = String(t[t.length - 1].urlKey);
237
+ }
238
+ let D = E([...v.values()].map(({ url: e, routeId: t }) => ({
239
+ url: e,
240
+ routeId: t
241
+ })));
242
+ if (v.size !== p.currentCount || p.revision > 0 && t(D) !== p.currentDigest) return y("state");
243
+ let O = p.sourceDigest === d && p.currentDigest === m;
244
+ if (p.revision !== u) return p.revision === u + 1 && O ? M(p) : y("revision");
245
+ if (O) return M(p);
246
+ if (p.revision === g) return y("bounds");
247
+ let k = p.revision + 1, A = new Set(f.map((e) => e.url)), P = p.historyCount;
248
+ for (let n of f) {
249
+ let r = v.get(n.url), a = t(n.url);
250
+ if (r === void 0) {
251
+ let t = await e.query({
252
+ table: s,
253
+ predicate: i(C(l), o("urlKey", a)),
254
+ lock: "update",
255
+ order: [],
256
+ take: 2,
257
+ skip: void 0,
258
+ projection: void 0
259
+ });
260
+ if (t.length > 1 || (r = t[0] === void 0 ? void 0 : N(t[0], p), r !== void 0 && r.url !== n.url)) return y("state");
261
+ }
262
+ if (r === void 0) {
263
+ if (P === g) return y("bounds");
264
+ await e.insert(s, {
265
+ id: w(h, s),
266
+ ...l,
267
+ ...n,
268
+ urlKey: a,
269
+ active: !0,
270
+ firstRevision: k,
271
+ lastRevision: k,
272
+ firstSourceDigest: d,
273
+ lastSourceDigest: d
274
+ }), P++;
275
+ } else (!r.active || r.routeId !== n.routeId) && await e.update(s, r.id, {
276
+ routeId: n.routeId,
277
+ active: !0,
278
+ lastRevision: k,
279
+ lastSourceDigest: d
280
+ });
281
+ }
282
+ for (let t of v.values()) A.has(t.url) || await e.update(s, t.id, {
283
+ active: !1,
284
+ lastRevision: k,
285
+ lastSourceDigest: d
286
+ });
287
+ let F = {
288
+ revision: k,
289
+ sourceDigest: d,
290
+ currentDigest: m,
291
+ currentCount: f.length,
292
+ historyCount: P
293
+ };
294
+ return await e.updateMany(r, F, { where: i(C(l), o("id", p.id), o("revision", p.revision)) }) === 1 ? F : y("revision");
295
+ };
296
+ async function* L(e, t, n) {
297
+ let r, i = n, a = 0, o = 0;
298
+ do {
299
+ let n = await P(e, t, {
300
+ ...r === void 0 ? {} : { after: r },
301
+ ...i === void 0 ? {} : { expectedRevision: i }
302
+ });
303
+ i = n.revision, o = n.historyCount;
304
+ for (let e of n.entries) a++, yield e;
305
+ r = n.next ?? void 0;
306
+ } while (r !== void 0);
307
+ if (a !== o) return y("state");
308
+ }
309
+ return {
310
+ routeHistoryTables: A,
311
+ routeHistoryHeadsTable: O,
312
+ routeHistoryEntriesTable: k,
313
+ readRouteHistoryPage: P,
314
+ readRouteHistoryUrl: F,
315
+ replaceRouteHistory: I,
316
+ iterateRouteHistory: L
317
+ };
318
+ };
319
+ //#endregion
320
+ export { h as RouteHistoryUnavailable, E as copyObservedRoutes, D as createRouteHistoryStore };