@voltro/cms 0.86.0 → 0.88.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 (243) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/README.md +138 -0
  3. package/THIRD-PARTY-NOTICES.md +1511 -276
  4. package/dist/ContentForm.js +1 -2
  5. package/dist/RichDocumentEditor.js +1 -2
  6. package/dist/RichDocumentView.js +82 -38
  7. package/dist/RichTextSurface.js +1 -2
  8. package/dist/aiCandidates.js +4 -5
  9. package/dist/aiOperations.js +1 -2
  10. package/dist/applicationBuildSnapshotService.js +100 -0
  11. package/dist/assetRenditions.js +101 -0
  12. package/dist/assetRevision.js +45 -0
  13. package/dist/assetUseRights.js +71 -0
  14. package/dist/audiences.js +1 -2
  15. package/dist/availability.js +20 -18
  16. package/dist/blueprint.js +76 -77
  17. package/dist/build.d.ts +3063 -0
  18. package/dist/build.js +37 -0
  19. package/dist/buildApplicationAdmission.js +15 -0
  20. package/dist/buildApplicationCatalog.js +135 -0
  21. package/dist/buildApplicationCatalogTable.js +23 -0
  22. package/dist/buildApplicationRest.js +98 -0
  23. package/dist/buildApplicationUpload.js +110 -0
  24. package/dist/buildSnapshot.js +400 -0
  25. package/dist/buildSnapshotApplicationPin.js +31 -0
  26. package/dist/buildSnapshotRest.js +209 -0
  27. package/dist/buildSnapshotService.js +264 -0
  28. package/dist/buildSnapshotTables.js +24 -0
  29. package/dist/bulk.js +72 -72
  30. package/dist/cacheIdentity.js +1 -2
  31. package/dist/changes.js +280 -64
  32. package/dist/cmsContext.js +1 -2
  33. package/dist/collections.js +1 -2
  34. package/dist/consent.js +6 -7
  35. package/dist/contentLocations.js +52 -0
  36. package/dist/contentProjection.js +82 -0
  37. package/dist/contentRouteIdentity.js +12 -0
  38. package/dist/contentRouteMaterializer.js +96 -0
  39. package/dist/contentRouteTypes.js +38 -0
  40. package/dist/contentSeo.js +188 -0
  41. package/dist/contentTreePath.js +59 -0
  42. package/dist/contentType.js +121 -105
  43. package/dist/contentValues.js +17 -0
  44. package/dist/contentfulImport.js +1 -2
  45. package/dist/copies.js +4 -5
  46. package/dist/cutover.js +1 -2
  47. package/dist/deliveryChecks.js +1 -2
  48. package/dist/domainHost.js +6 -0
  49. package/dist/domains.js +82 -89
  50. package/dist/draftTexts.js +38 -39
  51. package/dist/duplicates.js +24 -25
  52. package/dist/edgePurge.js +1 -2
  53. package/dist/editHistory.js +1 -2
  54. package/dist/effectForm.js +1 -2
  55. package/dist/environmentAliases.js +137 -0
  56. package/dist/environments.js +108 -71
  57. package/dist/errors.js +55 -16
  58. package/dist/experiments.js +8 -9
  59. package/dist/exposure.js +1 -2
  60. package/dist/extensionManifest.js +2 -3
  61. package/dist/extensions.js +1 -2
  62. package/dist/fieldSchema.js +1 -2
  63. package/dist/formStrings.js +1 -2
  64. package/dist/frontendBindings.js +98 -0
  65. package/dist/frontendMedia.js +17 -0
  66. package/dist/glossary.js +1 -2
  67. package/dist/history.js +1 -2
  68. package/dist/htmlImport.js +1 -2
  69. package/dist/index.d.ts +760 -47
  70. package/dist/index.js +89 -73
  71. package/dist/initializePublicRoutes.js +27 -0
  72. package/dist/liveContentRouteView.js +75 -0
  73. package/dist/media.js +1 -2
  74. package/dist/metrics.js +1 -2
  75. package/dist/migration.js +1 -2
  76. package/dist/migrationStages.js +1 -2
  77. package/dist/nativeOutputDeploymentService.js +204 -0
  78. package/dist/outputActivation.js +233 -0
  79. package/dist/outputActivationOrigin.js +50 -0
  80. package/dist/outputActivationStore.js +410 -0
  81. package/dist/outputActivationTables.js +10 -0
  82. package/dist/outputActivationTarget.js +80 -0
  83. package/dist/outputActivationTargetTable.js +24 -0
  84. package/dist/outputDeployment.js +173 -0
  85. package/dist/outputDeploymentRest.js +167 -0
  86. package/dist/outputDeploymentService.js +240 -0
  87. package/dist/outputRouteGraph.js +176 -0
  88. package/dist/outputSafetyArtifact.js +146 -0
  89. package/dist/outputTargetRest.js +61 -0
  90. package/dist/pathSegmentEncoding.js +3 -0
  91. package/dist/presenceAnchors.js +1 -2
  92. package/dist/preview.js +1 -2
  93. package/dist/privateCmsTransport.js +75 -0
  94. package/dist/privateNativeRouteReservation.js +9 -0
  95. package/dist/promotion.js +69 -61
  96. package/dist/publicBuild.js +89 -0
  97. package/dist/publicBuildRest.js +97 -0
  98. package/dist/publicBuildService.js +62 -0
  99. package/dist/publicOutputHttp.js +128 -0
  100. package/dist/publicOutputService.js +286 -0
  101. package/dist/publicPresentation.js +16 -0
  102. package/dist/publicRouteDispositionAdmission.js +37 -0
  103. package/dist/publicRouteHistoryStore.js +11 -0
  104. package/dist/publicRouteHistoryView.js +33 -0
  105. package/dist/publicRouteIntegrity.js +4 -0
  106. package/dist/publicRouteMutation.js +5 -0
  107. package/dist/publicRouteNamespace.js +133 -0
  108. package/dist/publicRoutePublication.js +35 -0
  109. package/dist/publicRouteRegistry.js +16 -0
  110. package/dist/publicRouteRegistryBinding.js +193 -0
  111. package/dist/publicRouteRegistryDefinition.js +75 -0
  112. package/dist/publicRouteSitePublication.js +39 -0
  113. package/dist/publicRouteTables.js +12 -0
  114. package/dist/publicRouteUrl.js +17 -0
  115. package/dist/publicationSeo.js +51 -0
  116. package/dist/publicationState.js +295 -0
  117. package/dist/quality.js +9 -10
  118. package/dist/reconfigurePublicRoutes.js +40 -0
  119. package/dist/recurrence.js +1 -2
  120. package/dist/redirects.js +105 -75
  121. package/dist/referenceGraph.js +16 -16
  122. package/dist/references.js +3 -4
  123. package/dist/release.js +178 -143
  124. package/dist/renderReadAuthority.js +42 -0
  125. package/dist/renderReadGrant.js +136 -0
  126. package/dist/rest.js +1 -2
  127. package/dist/review.js +29 -30
  128. package/dist/richDocument.js +56 -27
  129. package/dist/richInline.js +1 -2
  130. package/dist/routeDispositionGraph.js +43 -0
  131. package/dist/routeDispositionRest.js +50 -0
  132. package/dist/routeDispositionService.js +72 -0
  133. package/dist/routeDispositionStore.js +288 -0
  134. package/dist/routeDispositionTables.js +4 -0
  135. package/dist/routeDispositions.js +90 -0
  136. package/dist/routeHistoryStorage.js +319 -0
  137. package/dist/routeHistoryStore.js +11 -0
  138. package/dist/schedule.js +37 -38
  139. package/dist/search.js +1 -2
  140. package/dist/selectionIntent.js +1 -2
  141. package/dist/seo.js +2 -3
  142. package/dist/series.js +12 -13
  143. package/dist/share.js +14 -15
  144. package/dist/siteBindings.js +158 -0
  145. package/dist/siteBuildCandidate.js +103 -0
  146. package/dist/siteDelivery.js +114 -0
  147. package/dist/siteState.js +46 -0
  148. package/dist/snapshotAddressGraph.js +54 -0
  149. package/dist/snapshotAddressRead.js +72 -0
  150. package/dist/snapshotAppConsumer.js +70 -0
  151. package/dist/snapshotAppExecution.js +101 -0
  152. package/dist/snapshotApplication.js +74 -0
  153. package/dist/snapshotApprovedRouteDispositions.js +43 -0
  154. package/dist/snapshotAssetAssembly.js +69 -0
  155. package/dist/snapshotAssetAssemblyRest.js +49 -0
  156. package/dist/snapshotBindingRead.js +60 -0
  157. package/dist/snapshotCodeSeo.js +28 -0
  158. package/dist/snapshotComponent.js +33 -0
  159. package/dist/snapshotComponentSource.js +23 -0
  160. package/dist/snapshotConsumer.js +86 -0
  161. package/dist/snapshotContentIdentity.js +9 -0
  162. package/dist/snapshotDefinitions.js +263 -0
  163. package/dist/snapshotDocumentAssembly.js +192 -0
  164. package/dist/snapshotDocumentAssemblyRest.js +83 -0
  165. package/dist/snapshotDocumentProjection.js +201 -0
  166. package/dist/snapshotDocumentTransfer.js +34 -0
  167. package/dist/snapshotDocumentTransferRest.js +79 -0
  168. package/dist/snapshotDomains.js +55 -0
  169. package/dist/snapshotEnvironment.js +30 -0
  170. package/dist/snapshotFieldPlan.js +84 -0
  171. package/dist/snapshotFrontend.js +102 -0
  172. package/dist/snapshotLink.js +7 -0
  173. package/dist/snapshotMedia.js +110 -0
  174. package/dist/snapshotMediaCapture.js +245 -0
  175. package/dist/snapshotMediaFields.js +224 -0
  176. package/dist/snapshotMediaRead.js +184 -0
  177. package/dist/snapshotMediaReader.js +12 -0
  178. package/dist/snapshotObservation.js +15 -0
  179. package/dist/snapshotObservedRouteHistory.js +33 -0
  180. package/dist/snapshotOutputTransfer.js +77 -0
  181. package/dist/snapshotPageLoader.js +6 -0
  182. package/dist/snapshotPageSeo.js +58 -0
  183. package/dist/snapshotPathLocale.js +14 -0
  184. package/dist/snapshotPresentation.js +85 -0
  185. package/dist/snapshotPresentationPolicy.js +11 -0
  186. package/dist/snapshotProjection.js +118 -0
  187. package/dist/snapshotPublicAccess.js +160 -0
  188. package/dist/snapshotPublicRouteHistory.js +39 -0
  189. package/dist/snapshotReadAdmission.js +37 -0
  190. package/dist/snapshotRedirectOutput.js +150 -0
  191. package/dist/snapshotRedirectTargets.js +23 -0
  192. package/dist/snapshotRedirects.js +131 -0
  193. package/dist/snapshotReference.js +7 -0
  194. package/dist/snapshotReferenceAddress.js +9 -0
  195. package/dist/snapshotReferenceGraph.js +78 -0
  196. package/dist/snapshotReferenceRead.js +64 -0
  197. package/dist/snapshotRelease.js +98 -0
  198. package/dist/snapshotRender.js +360 -0
  199. package/dist/snapshotRenderDependencies.js +177 -0
  200. package/dist/snapshotRenditions.js +87 -0
  201. package/dist/snapshotRichDocument.js +61 -0
  202. package/dist/snapshotRoleTransfer.js +105 -0
  203. package/dist/snapshotRoleTransferRest.js +98 -0
  204. package/dist/snapshotRouteAdmission.js +70 -0
  205. package/dist/snapshotRouteDispatch.js +110 -0
  206. package/dist/snapshotRouteDispositionPlan.js +72 -0
  207. package/dist/snapshotRouteRead.js +42 -0
  208. package/dist/snapshotRoutes.js +78 -0
  209. package/dist/snapshotRouting.js +112 -0
  210. package/dist/snapshotSeo.js +178 -0
  211. package/dist/snapshotSeoControls.js +100 -0
  212. package/dist/snapshotSeoDocumentInventory.js +114 -0
  213. package/dist/snapshotSeoDocuments.js +128 -0
  214. package/dist/snapshotSeoMerge.js +84 -0
  215. package/dist/snapshotSeoMetadata.js +136 -0
  216. package/dist/snapshotSeoOutput.js +172 -0
  217. package/dist/snapshotSeoPathSets.js +104 -0
  218. package/dist/snapshotSeoRead.js +87 -0
  219. package/dist/snapshotSite.js +127 -0
  220. package/dist/snapshotSitemapFiles.js +35 -0
  221. package/dist/snapshotTreeDependencies.js +57 -0
  222. package/dist/snapshotTreeLoader.js +9 -0
  223. package/dist/snapshotTreeRead.js +157 -0
  224. package/dist/staticPathSet.js +176 -0
  225. package/dist/staticPathSetRest.js +128 -0
  226. package/dist/staticPathSetService.js +248 -0
  227. package/dist/staticPathSetStore.js +337 -0
  228. package/dist/stewardship.js +2 -3
  229. package/dist/taxonomy.js +1 -2
  230. package/dist/team.js +1 -2
  231. package/dist/templates.js +2 -3
  232. package/dist/trackChanges.js +1 -2
  233. package/dist/translation.js +1 -2
  234. package/dist/tree.js +10 -11
  235. package/dist/usage.js +1 -2
  236. package/dist/validation.js +54 -55
  237. package/dist/visualEditing.js +1 -2
  238. package/dist/web.d.ts +709 -7
  239. package/dist/web.js +50 -33
  240. package/dist/workflow.js +9 -10
  241. package/dist/write.js +251 -227
  242. package/dist/xliff.js +1 -2
  243. package/package.json +21 -7
@@ -0,0 +1,112 @@
1
+ import { copySnapshotResource as e } from "./buildSnapshot.js";
2
+ import { Schema as t } from "effect";
3
+ import { createHash as n } from "node:crypto";
4
+ import { canonicalJson as r } from "@voltro/runtime";
5
+ // src/snapshotRouting.ts
6
+ var i = class extends t.TaggedError()("SnapshotRoutingUnavailable", { reason: t.Literals([
7
+ "definition",
8
+ "discovery",
9
+ "claim",
10
+ "missing",
11
+ "collision",
12
+ "ownership"
13
+ ]) }) {}, a = (e) => {
14
+ throw new i({ reason: e });
15
+ }, o = (e) => n("sha256").update(r(e)).digest("hex"), s = (e) => typeof e != "object" || !e || Array.isArray(e) ? a("definition") : e, c = (e) => typeof e == "string" && e.length > 0 && e.length <= 1024 && !/[\\\x00-\x1f\x7f:]/.test(e) && e.split("/").every((e) => e !== "" && e !== "." && e !== ".." && e.toLowerCase() !== ".git"), l = (e) => typeof e == "string" && /^[a-f0-9]{64}$/.test(e), u = (t) => e({
16
+ key: "routing",
17
+ value: { data: t }
18
+ }).value.data, d = (e) => {
19
+ if (e === null) return null;
20
+ let t = s(u(e)), n = s(t.claims);
21
+ if (Object.keys(t).length !== 2 || !c(t.pagesDirectory) || Object.keys(n).length > 4096) return a("definition");
22
+ let r = Object.fromEntries(Object.keys(n).sort().map((e) => {
23
+ if (!c(e)) return a("definition");
24
+ let t = s(n[e]);
25
+ return t.kind === "cms" && Object.keys(t).length === 1 ? [e, { kind: "cms" }] : t.kind === "code" && ["collision,kind", "collision,kind,public"].includes(Object.keys(t).sort().join(",")) && [
26
+ "reject",
27
+ "cms",
28
+ "code"
29
+ ].includes(String(t.collision)) && (t.public === void 0 || typeof t.public == "boolean") ? [e, {
30
+ kind: "code",
31
+ collision: t.collision,
32
+ ...t.public === void 0 ? {} : { public: t.public }
33
+ }] : a("definition");
34
+ }));
35
+ return {
36
+ pagesDirectory: t.pagesDirectory,
37
+ claims: r
38
+ };
39
+ }, f = (e, t, n) => {
40
+ let i = d(e);
41
+ if (i === null) return t === null ? {
42
+ definition: null,
43
+ discovery: null
44
+ } : a("discovery");
45
+ let f = s(u(t)), { digest: p, ...m } = f, h = s(f.inputs);
46
+ if (f.version !== 2 || !l(p) || o(m) !== p || f.pagesDirectory !== i.pagesDirectory || !l(h.id) || r(h) !== r({
47
+ id: h.id,
48
+ ...n
49
+ }) || !Array.isArray(f.pages) || f.pages.length === 0 || f.pages.length > 4096) return a("discovery");
50
+ let g = /* @__PURE__ */ new Set();
51
+ for (let e of f.pages) {
52
+ let t = s(e), n = s(t.source), r = s(t.matcher);
53
+ if (!c(t.file) || g.has(t.file) || n.path !== `${i.pagesDirectory}/${t.file}` || !l(n.digest) || typeof t.pattern != "string" || !t.pattern.startsWith("/") || t.pattern.length > 4096 || typeof r.source != "string" || r.source.length > 8192 || r.flags !== "" || !Number.isSafeInteger(r.priority) || Number(r.priority) < 0) return a("discovery");
54
+ try {
55
+ new RegExp(r.source);
56
+ } catch {
57
+ return a("discovery");
58
+ }
59
+ g.add(t.file);
60
+ }
61
+ return Object.keys(i.claims).some((e) => !g.has(e)) ? a("claim") : {
62
+ definition: i,
63
+ discovery: f
64
+ };
65
+ }, p = (e, t, n) => {
66
+ if (e.definition === null || e.discovery === null) return n ? {
67
+ owner: "cms",
68
+ code: null
69
+ } : null;
70
+ let r = e.discovery.pages.filter((e) => new RegExp(e.matcher.source, e.matcher.flags).test(t)).sort((e, t) => e.matcher.priority - t.matcher.priority), i = r[0];
71
+ if (i === void 0) return n ? a("missing") : null;
72
+ if (r[1]?.matcher.priority === i.matcher.priority) return a("collision");
73
+ let o = e.definition.claims[i.file] ?? {
74
+ kind: "code",
75
+ collision: "reject"
76
+ }, s = {
77
+ file: i.file,
78
+ pattern: i.pattern,
79
+ sourceDigest: i.source.digest
80
+ };
81
+ return n ? o.kind === "code" && o.collision === "reject" ? a("collision") : {
82
+ owner: o.kind === "cms" ? "cms" : o.collision,
83
+ code: s
84
+ } : o.kind === "cms" ? null : {
85
+ owner: "code",
86
+ code: s
87
+ };
88
+ }, m = (e, t) => p(e, t, !0), h = (e, t) => {
89
+ if (e.definition === null || e.discovery === null) return a("missing");
90
+ let n = e.discovery.pages.filter((n) => e.definition.claims[n.file]?.kind === "cms" && new RegExp(n.matcher.source, n.matcher.flags).test(t)).sort((e, t) => e.matcher.priority - t.matcher.priority), r = n[0];
91
+ return r === void 0 ? a("missing") : n[1]?.matcher.priority === r.matcher.priority ? a("collision") : {
92
+ file: r.file,
93
+ pattern: r.pattern,
94
+ sourceDigest: r.source.digest
95
+ };
96
+ }, g = (e) => {
97
+ let t = s(e.routing), n = f(t.definition, t.discovery, e.app);
98
+ return r(t) === r(n) ? n : a("discovery");
99
+ }, _ = (e, t) => {
100
+ let n = m(g(e), String(t.path));
101
+ return r(t.ownership) === r(n) ? n : a("ownership");
102
+ }, v = (e, t, n, r) => `native_${o([
103
+ {
104
+ tenantId: e.tenantId,
105
+ site: e.site,
106
+ environment: e.environment
107
+ },
108
+ t,
109
+ n,
110
+ r
111
+ ])}`;
112
+ export { i as SnapshotRoutingUnavailable, f as compileSnapshotRouting, d as copySnapshotRoutingDefinition, v as nativeSnapshotRouteId, g as readSnapshotRouting, h as snapshotCmsPage, p as snapshotRouteDispatch, m as snapshotRouteOwnership, c as snapshotRoutingPath, _ as verifySnapshotRouteOwnership };
@@ -0,0 +1,178 @@
1
+ import { compileSiteDelivery as e } from "./siteDelivery.js";
2
+ import { normalizeHost as t } from "./domainHost.js";
3
+ import { copySnapshotResource as n, findVerifiedSnapshotResource as r, pinnedSnapshotPartSource as i, readVerifiedSnapshotResource as a, verifyBuildSnapshot as o } from "./buildSnapshot.js";
4
+ import { verifySnapshotRouteOwnership as s } from "./snapshotRouting.js";
5
+ import { contentRouteId as c } from "./contentRouteIdentity.js";
6
+ import { Schema as l } from "effect";
7
+ import { createHash as u } from "node:crypto";
8
+ import { canonicalJson as d } from "@voltro/runtime";
9
+ // src/snapshotSeo.ts
10
+ var f = class extends l.TaggedError()("SnapshotSeoUnavailable", { reason: l.Literals([
11
+ "scope",
12
+ "format",
13
+ "configuration",
14
+ "domain",
15
+ "route",
16
+ "publication"
17
+ ]) }) {}, p = (e) => {
18
+ throw new f({ reason: e });
19
+ }, m = (e) => u("sha256").update(d(e)).digest("hex"), h = (e) => typeof e == "string" && e.length > 0, g = async (l, u, f, g) => {
20
+ let _ = {
21
+ tenantId: u.tenantId,
22
+ site: u.site,
23
+ environment: u.environment
24
+ }, v = {
25
+ id: f.id,
26
+ digest: f.digest
27
+ }, y = g.now ?? Date.now(), b = g.xDefault, x = g.routeKey;
28
+ if (x !== void 0 && !/^path:[a-f0-9]{64}$/.test(x)) return p("route");
29
+ if (!Object.values(_).every(h) || typeof b != "boolean") return p("scope");
30
+ let S = await o(l, _, v, y), C = (e, t) => {
31
+ let n = i(l, _, S, e, y);
32
+ return n.format === t ? n : p("format");
33
+ }, w = C("routes", "voltro.cms.content-routes/v4"), T = C("domains", "voltro.cms.domains/v1");
34
+ C("locales", "voltro.cms.locales/v1");
35
+ let E = (await a(l, _, S, "routes", "configuration")).value, D = (await a(l, _, S, "locales", "policy")).value, O = e(E.site);
36
+ if (O.definition.id !== _.site || !O.definition.environments.includes(_.environment) || [E, D].some((e) => e.tenantId !== _.tenantId || e.environment !== _.environment) || D.site !== _.site || d(E.app) !== d(D.app) || E.resolution !== "per-node" || D.resolution !== "per-node" || !Array.isArray(E.types) || E.types.some((e) => typeof e != "object" || !e || !Array.isArray(e.locations))) return p("configuration");
37
+ let k = {
38
+ version: O.definition.version,
39
+ defaultLocale: O.definition.defaultLocale,
40
+ sourceLocale: O.definition.sourceLocale,
41
+ locales: O.definition.locales
42
+ }, A = {
43
+ contentLocales: O.contentLocales,
44
+ defaultLocale: O.defaultLocale,
45
+ sourceLocale: O.sourceLocale,
46
+ fallback: O.fallback,
47
+ prefixes: O.prefixes,
48
+ tags: O.tags,
49
+ directions: O.directions
50
+ };
51
+ if (d(D.definition) !== d(k) || d(D.compiled) !== d(A)) return p("configuration");
52
+ let j;
53
+ for await (let e of T.entries(S.manifest.publication)) {
54
+ let n = e.value;
55
+ if (n.version !== 1 || n.tenantId !== _.tenantId || n.site !== _.site || typeof n.host != "string" || t(n.host) !== n.host || e.key !== n.host || typeof n.primary != "boolean") return p("domain");
56
+ if (n.primary) {
57
+ if (j !== void 0) return p("domain");
58
+ j = n.host;
59
+ }
60
+ }
61
+ if (j === void 0) return p("domain");
62
+ let M = `https://${j}`, N = O.definition.locales.filter((e) => e.enabled), P = (e) => {
63
+ let t = e.value;
64
+ if (t.version !== 1 || t.tenantId !== _.tenantId || t.site !== _.site || t.environment !== _.environment || ![
65
+ t.contentType,
66
+ t.documentId,
67
+ t.mappingId,
68
+ t.localeId,
69
+ t.requestedLocale,
70
+ t.sourceLocale,
71
+ t.variantId,
72
+ t.revisionId
73
+ ].every(h) || !Number.isSafeInteger(t.revision) || Number(t.revision) < 1 || typeof t.fallback != "boolean" || t.definitionDigest !== E.definitionDigest) return p("route");
74
+ let n = t.lastModified;
75
+ if (n !== null && (typeof n != "string" || !Number.isFinite(Date.parse(n)) || new Date(n).toISOString() !== n)) return p("route");
76
+ let r = N.find((e) => e.id === t.localeId), i = E.types.find((e) => e.name === t.contentType);
77
+ if (r === void 0 || r.contentLocale !== t.requestedLocale || i === void 0 || !i.locations.some((e) => e.id === t.mappingId) || ![r.contentLocale, ...O.fallback[r.contentLocale]].includes(String(t.sourceLocale)) || t.fallback !== (t.sourceLocale !== t.requestedLocale) || t.routeId !== c(_, r.id, String(t.contentType), String(t.documentId), String(t.mappingId))) return p("route");
78
+ if (t.state === "unroutable") {
79
+ if (e.key !== `unroutable:${t.routeId}` || t.reason !== "orphan") return p("route");
80
+ } else if (t.state !== "resolved" || typeof t.path != "string" || !t.path.startsWith("/") || t.path.startsWith("//") || /[?#\\]/.test(t.path) || e.key !== `path:${m(t.path)}`) return p("route");
81
+ return t.state === "resolved" && s(E, t), t;
82
+ }, F = async (e, t) => {
83
+ let n = c(_, t, String(e.contentType), String(e.documentId), String(e.mappingId)), i = await r(l, _, S, "routes", `identity:${n}`);
84
+ if (i === null) return null;
85
+ if (i.value.version !== 1 || i.value.kind !== "route-index" || !h(i.value.target)) return p("route");
86
+ let o = await a(l, _, S, "routes", i.value.target), s = P(o);
87
+ return s.routeId === n ? s : p("route");
88
+ }, I = n({
89
+ key: "configuration",
90
+ value: {
91
+ version: 1,
92
+ ..._,
93
+ origin: M,
94
+ xDefault: b,
95
+ sourceSnapshot: {
96
+ id: S.id,
97
+ digest: S.digest
98
+ },
99
+ inputs: S.manifest.parts.filter((e) => [
100
+ "routes",
101
+ "domains",
102
+ "locales"
103
+ ].includes(e.part)),
104
+ addressPolicy: "published-own-variants/v1",
105
+ publicAdmission: "required"
106
+ }
107
+ });
108
+ return {
109
+ format: "voltro.cms.seo-addresses/v2",
110
+ entries: async function* (e) {
111
+ if (d(e) !== d(S.manifest.publication)) return p("publication");
112
+ yield n(I);
113
+ let t = x === void 0 ? w.entries(e) : (async function* () {
114
+ yield await a(l, _, S, "routes", x);
115
+ })();
116
+ for await (let e of t) {
117
+ if (e.key === "configuration" || e.key.startsWith("identity:")) continue;
118
+ let t = P(e), r = await F(t, String(t.localeId));
119
+ if (r === null || d(r) !== d(t)) return p("route");
120
+ if (t.state === "unroutable") {
121
+ yield {
122
+ key: String(t.routeId),
123
+ value: {
124
+ version: 1,
125
+ routeKey: e.key,
126
+ state: "excluded",
127
+ reason: "unroutable"
128
+ }
129
+ };
130
+ continue;
131
+ }
132
+ if (s(E, t).owner === "code") {
133
+ yield {
134
+ key: String(t.routeId),
135
+ value: {
136
+ version: 1,
137
+ routeKey: e.key,
138
+ state: "excluded",
139
+ reason: "code-owned"
140
+ }
141
+ };
142
+ continue;
143
+ }
144
+ let i = [];
145
+ for (let e of N) {
146
+ let n = await F(t, e.id);
147
+ n !== null && n.state === "resolved" && n.fallback === !1 && s(E, n).owner === "cms" && i.push({
148
+ localeId: e.id,
149
+ locale: e.tag,
150
+ routeId: String(n.routeId),
151
+ href: M + String(n.path)
152
+ });
153
+ }
154
+ let a = N.find((e) => e.contentLocale === t.sourceLocale), o = a === void 0 ? void 0 : i.find((e) => e.localeId === a.id);
155
+ if (o === void 0) return p("route");
156
+ yield n({
157
+ key: String(t.routeId),
158
+ value: {
159
+ version: 1,
160
+ state: "resolved",
161
+ routeKey: e.key,
162
+ routeId: t.routeId,
163
+ revisionId: t.revisionId,
164
+ lastModified: t.lastModified,
165
+ requestedLocale: t.requestedLocale,
166
+ sourceLocale: t.sourceLocale,
167
+ fallback: t.fallback,
168
+ canonical: o.href,
169
+ canonicalRouteId: o.routeId,
170
+ alternates: i,
171
+ xDefault: b ? i.find((e) => e.localeId === O.definition.defaultLocale)?.href ?? null : null
172
+ }
173
+ });
174
+ }
175
+ }
176
+ };
177
+ };
178
+ export { f as SnapshotSeoUnavailable, g as snapshotSeoAddressSource };
@@ -0,0 +1,100 @@
1
+ import { defineSiteDelivery as e } from "./siteDelivery.js";
2
+ import { pageSnapshotResources as t, readVerifiedSnapshotResource as n } from "./buildSnapshot.js";
3
+ import { verifySnapshotRouteOwnership as r } from "./snapshotRouting.js";
4
+ import { staticPathHash as i } from "./staticPathSet.js";
5
+ import { snapshotSeoMetadataSource as a } from "./snapshotSeoMetadata.js";
6
+ import { readSnapshotRouteAdmission as o, verifySnapshotContentRoute as s } from "./snapshotRouteAdmission.js";
7
+ import { readAdmittedSnapshotContentRoute as c } from "./snapshotRouteRead.js";
8
+ import { SnapshotSeoReadUnavailable as l, readAdmittedSnapshotSeo as u } from "./snapshotSeoRead.js";
9
+ import { snapshotSitemapFiles as d } from "./snapshotSitemapFiles.js";
10
+ import { canonicalJson as f } from "@voltro/runtime";
11
+ // src/snapshotSeoControls.ts
12
+ var p = () => {
13
+ throw new l({ reason: "binding" });
14
+ }, m = async (l, m, h, g, _) => {
15
+ let v = await o(l, m, h, {
16
+ ...g,
17
+ path: "/"
18
+ }, _), { snapshot: y, configuration: b, now: x } = v, S = e(b.site);
19
+ if (y.manifest.parts.find((e) => e.part === "seo")?.format !== "voltro.cms.seo-metadata/v1") return p();
20
+ let C = (await n(l, m, y, "seo", "configuration")).value;
21
+ if (typeof C.origin != "string" || typeof C.xDefault != "boolean") return p();
22
+ let w = await a(l, m, y, {
23
+ now: x,
24
+ xDefault: C.xDefault
25
+ }), T = !1;
26
+ for await (let e of w.entries(y.manifest.publication)) {
27
+ if (e.key !== "configuration") return p();
28
+ let t = (e) => Object.fromEntries(Object.entries(e).filter(([e]) => e !== "sourceSnapshot"));
29
+ if (f(t(e.value)) !== f(t(C))) return p();
30
+ T = !0;
31
+ break;
32
+ }
33
+ if (!T) return p();
34
+ let E = new URL(C.origin);
35
+ if (E.protocol !== "https:" || E.origin !== C.origin) return p();
36
+ let D = m.environment === "production" && m.environment === S.defaultEnvironment, O = [], k;
37
+ do {
38
+ let e = await t(l, m, y.id, "routes", {
39
+ now: x,
40
+ limit: 200,
41
+ ...k === void 0 ? {} : { after: k }
42
+ });
43
+ for (let t of e.items) {
44
+ if (!t.key.startsWith("path:")) continue;
45
+ let e = t.value;
46
+ if (typeof e.path != "string" || t.key !== "path:" + i(e.path)) return p();
47
+ if (s(m, e.path, e), e.fallback !== !1 || r(b, e).owner !== "cms") continue;
48
+ let a = await c(l, {
49
+ ...v,
50
+ input: {
51
+ ...v.input,
52
+ path: e.path
53
+ },
54
+ route: e
55
+ });
56
+ if (a === null) continue;
57
+ let { seo: o } = await u(l, m, a, x), d = (await n(l, m, y, "seo", a.output.routeId)).value, f = d.metadata;
58
+ if (!D || f?.sitemap !== !0 || !o.robots.index || o.canonical === null) continue;
59
+ let h = E.origin + a.output.path;
60
+ if (o.canonical !== h || (O.push({
61
+ documentId: a.document.documentId,
62
+ locale: o.languageTag,
63
+ path: h,
64
+ lastmod: d.lastModified,
65
+ alternates: o.alternates.map((e) => ({
66
+ locale: e.locale,
67
+ path: e.href
68
+ }))
69
+ }), O.length > 1e5)) return p();
70
+ }
71
+ k = e.next ?? void 0;
72
+ } while (k !== void 0);
73
+ O.sort((e, t) => e.path < t.path ? -1 : +(e.path > t.path));
74
+ let A = new Set(O.map((e) => e.path));
75
+ if (A.size !== O.length) return p();
76
+ let j = O.map((e) => ({
77
+ ...e,
78
+ alternates: e.alternates.filter((e) => A.has(e.path))
79
+ })), M = S.locales.find((e) => e.id === S.defaultLocale)?.tag, N = d(j, E.origin, C.xDefault ? M : void 0), P = N[0].text, F = D ? `User-agent: *\nAllow: /\n\nSitemap: ${E.origin}/sitemap.xml\n` : "User-agent: *\nDisallow: /\n", I = (await n(l, m, y, "app", "configuration")).value.execution, L = typeof I == "object" && !!I && !Array.isArray(I) && I.web !== void 0;
80
+ return await o(l, m, h, {
81
+ ...g,
82
+ path: "/"
83
+ }, _), {
84
+ sitemap: P,
85
+ robots: F,
86
+ urls: j,
87
+ files: N,
88
+ origin: E.origin,
89
+ indexable: D,
90
+ defaultLanguage: M ?? null,
91
+ xDefault: C.xDefault,
92
+ locales: S.locales.map((e) => ({
93
+ id: e.id,
94
+ tag: e.tag,
95
+ enabled: e.enabled
96
+ })),
97
+ productionDocumentRequired: L
98
+ };
99
+ };
100
+ export { m as readSnapshotSeoControls };
@@ -0,0 +1,114 @@
1
+ import { canonicalCmsPublicPath as e } from "./publicBuild.js";
2
+ import { copySnapshotResource as t } from "./buildSnapshot.js";
3
+ import { snapshotRoutingPath as n } from "./snapshotRouting.js";
4
+ import { copySnapshotConsentPurposes as r, copySnapshotPresentationValue as i, snapshotPresentations as a } from "./snapshotPresentation.js";
5
+ import { SnapshotSeoReadUnavailable as o } from "./snapshotSeoRead.js";
6
+ import { createHash as s } from "node:crypto";
7
+ import { canonicalJson as c } from "@voltro/runtime";
8
+ // src/snapshotSeoDocumentInventory.ts
9
+ var l = () => {
10
+ throw new o({ reason: "binding" });
11
+ }, u = (e) => s("sha256").update(c(e)).digest("hex"), d = (e) => typeof e == "string" && /^[a-f0-9]{64}$/.test(e), f = (e, t) => typeof e != "object" || !e || Array.isArray(e) || ![Object.prototype, null].includes(Object.getPrototypeOf(e)) || Reflect.ownKeys(e).some((t) => typeof t != "string" || !Object.getOwnPropertyDescriptor(e, t).enumerable || !Object.hasOwn(Object.getOwnPropertyDescriptor(e, t), "value")) || t !== void 0 && Object.keys(e).sort().join(",") !== t ? l() : e, p = (e, t) => !Array.isArray(e) || e.length > t || Reflect.ownKeys(e).length !== e.length + 1 ? l() : Array.from({ length: e.length }, (t, n) => {
12
+ let r = Object.getOwnPropertyDescriptor(e, String(n));
13
+ return r === void 0 || !r.enumerable || !Object.hasOwn(r, "value") ? l() : r.value;
14
+ }), m = (o) => {
15
+ let m = f(o, "id,manifest");
16
+ if (!d(m.id)) return l();
17
+ let h = f(m.manifest, "files,subject,version"), g = f(h.subject, "build,consentPurposes,pathSetIds,presentations,profile,records,selector,version");
18
+ if (h.version !== 1 || g.version !== 3 || g.profile !== "voltro.cms-public-documents/v3") return l();
19
+ let _ = f(g.build, "executionId,inputsId,snapshotDigest,version");
20
+ if (_.version !== 1 || !d(_.snapshotDigest) || !d(_.inputsId) || !d(_.executionId)) return l();
21
+ let v = {
22
+ version: 1,
23
+ snapshotDigest: _.snapshotDigest,
24
+ inputsId: _.inputsId,
25
+ executionId: _.executionId
26
+ }, y = [
27
+ "1",
28
+ v.snapshotDigest,
29
+ v.inputsId,
30
+ v.executionId
31
+ ].join(".");
32
+ if (g.selector !== y) return l();
33
+ let b = t({
34
+ key: "public-classes",
35
+ value: {
36
+ consentPurposes: g.consentPurposes,
37
+ presentations: g.presentations
38
+ }
39
+ }).value, x = r(b.consentPurposes), S = a(x, 257).map((e) => ({
40
+ presentation: e,
41
+ key: u(e)
42
+ })).sort((e, t) => e.key < t.key ? -1 : +(e.key > t.key)).map((e) => e.presentation);
43
+ if (c({
44
+ consentPurposes: x,
45
+ presentations: S
46
+ }) !== c(b)) return l();
47
+ let C = p(g.pathSetIds, 64).map((e, t, n) => !d(e) || t > 0 && String(n[t - 1]) >= e ? l() : e);
48
+ if (C.length === 0) return l();
49
+ let w = S.map((e) => u(e)).sort(), T = /* @__PURE__ */ new Map(), E = /* @__PURE__ */ new Map(), D = /* @__PURE__ */ new Map(), O = /* @__PURE__ */ new Map(), k = p(h.files, 1e5).map((e) => {
50
+ let t = f(e, "contentType,digest,path,size");
51
+ if (typeof t.path != "string" || t.contentType !== "text/html" || !d(t.digest) || !Number.isSafeInteger(t.size) || Number(t.size) < 0 || Number(t.size) > 4194304 || O.has(t.path)) return l();
52
+ let n = {
53
+ path: t.path,
54
+ contentType: t.contentType,
55
+ digest: t.digest,
56
+ size: Number(t.size)
57
+ };
58
+ return O.set(n.path, n), n;
59
+ }), A = "", j = p(g.records, 1e5).map((r) => {
60
+ let a = t({
61
+ key: "public-document",
62
+ value: f(r, "artifactId,digest,file,media,pageFile,path,presentation,routeId,size,url")
63
+ }).value;
64
+ if (!n(a.pageFile) || typeof a.url != "string" || typeof a.path != "string" || e(a.path) !== a.path || typeof a.routeId != "string" || !/^(route_|native_)[a-f0-9]{64}$/.test(a.routeId) || !d(a.artifactId) || !d(a.digest)) return l();
65
+ let o = new URL(a.url);
66
+ if (o.protocol !== "https:" || o.origin + o.pathname !== a.url || o.pathname !== a.path) return l();
67
+ let c = i(a.presentation), m = u(c), h = a.url + "#" + m;
68
+ if (h <= A || a.file !== "pages/" + s("sha256").update(h).digest("hex") + ".html") return l();
69
+ A = h;
70
+ let g = O.get(String(a.file));
71
+ if (g === void 0 || g.digest !== a.digest || g.size !== a.size) return l();
72
+ let _ = p(a.media, 1e5).map((e) => {
73
+ let t = f(e, "digest,rights"), n = f(t.rights);
74
+ return !d(t.digest) || n.version !== 1 ? l() : {
75
+ digest: t.digest,
76
+ rights: n
77
+ };
78
+ }), v = T.get(a.url) ?? [], y = E.get(a.url);
79
+ return y !== void 0 && (y !== a.routeId || D.get(a.url) !== a.pageFile) ? l() : (D.set(a.url, a.pageFile), E.set(a.url, a.routeId), v.push(m), T.set(a.url, v), {
80
+ url: a.url,
81
+ path: a.path,
82
+ routeId: a.routeId,
83
+ artifactId: a.artifactId,
84
+ presentation: c,
85
+ file: g.path,
86
+ pageFile: a.pageFile,
87
+ digest: g.digest,
88
+ size: g.size,
89
+ media: _
90
+ });
91
+ });
92
+ return k.length !== j.length || [...T.values()].some((e) => c(e.sort()) !== c(w)) || u({
93
+ version: 1,
94
+ subject: {
95
+ version: 3,
96
+ profile: "voltro.cms-public-documents/v3",
97
+ build: v,
98
+ selector: y,
99
+ pathSetIds: C,
100
+ consentPurposes: x,
101
+ presentations: S,
102
+ records: j
103
+ },
104
+ files: k
105
+ }) !== m.id ? l() : {
106
+ build: v,
107
+ selector: y,
108
+ pathSetIds: C,
109
+ consentPurposes: x,
110
+ presentations: S,
111
+ records: j
112
+ };
113
+ };
114
+ export { m as readSnapshotSeoDocumentInventory };
@@ -0,0 +1,128 @@
1
+ import { copySnapshotResource as e } from "./buildSnapshot.js";
2
+ import { readCapturedSnapshotConsentPurposes as t } from "./snapshotPresentationPolicy.js";
3
+ import { copySnapshotCodeSeo as n } from "./snapshotCodeSeo.js";
4
+ import { admitCapturedAssetUseRights as r } from "./assetUseRights.js";
5
+ import { SnapshotSeoReadUnavailable as i } from "./snapshotSeoRead.js";
6
+ import { readSnapshotSeoPathSets as a } from "./snapshotSeoPathSets.js";
7
+ import { readSnapshotSeoDocumentInventory as o } from "./snapshotSeoDocumentInventory.js";
8
+ import { createHash as s } from "node:crypto";
9
+ import { canonicalJson as c } from "@voltro/runtime";
10
+ // src/snapshotSeoDocuments.ts
11
+ var l = (e) => {
12
+ let { app: t, admission: n } = e.paths.admission, r = n.input;
13
+ return {
14
+ snapshot: {
15
+ id: n.snapshot.id,
16
+ digest: n.snapshot.digest
17
+ },
18
+ app: {
19
+ inputsId: t.inputsId,
20
+ executionId: t.executionId
21
+ },
22
+ documents: {
23
+ artifactId: e.paths.selection.artifactId,
24
+ pathSetIds: e.inventory.pathSetIds
25
+ },
26
+ consumerId: r.consumerId,
27
+ buildId: r.buildId,
28
+ host: r.host
29
+ };
30
+ }, u = () => {
31
+ throw new i({ reason: "binding" });
32
+ }, d = (e) => s("sha256").update(c(e)).digest("hex"), f = (e, t) => typeof e != "object" || !e || Array.isArray(e) || ![Object.prototype, null].includes(Object.getPrototypeOf(e)) || Reflect.ownKeys(e).some((t) => typeof t != "string" || !Object.getOwnPropertyDescriptor(e, t).enumerable || !Object.hasOwn(Object.getOwnPropertyDescriptor(e, t), "value")) || t !== void 0 && Object.keys(e).sort().join(",") !== t ? u() : e, p = (e) => !Array.isArray(e) || e.length > 1e5 || Reflect.ownKeys(e).length !== e.length + 1 ? u() : Array.from({ length: e.length }, (t, n) => {
33
+ let r = Object.getOwnPropertyDescriptor(e, String(n));
34
+ return r === void 0 || !r.enumerable || !Object.hasOwn(r, "value") ? u() : r.value;
35
+ }), m = async (i, s, l, m, h) => {
36
+ let g = {
37
+ snapshot: {
38
+ id: l.snapshot.id,
39
+ digest: l.snapshot.digest
40
+ },
41
+ token: l.token,
42
+ consumerId: l.consumerId,
43
+ buildId: l.buildId,
44
+ host: l.host
45
+ }, _ = {
46
+ tenantId: s.tenantId,
47
+ site: s.site,
48
+ environment: s.environment
49
+ }, v = {
50
+ keys: h.keys.map((e) => ({
51
+ id: e.id,
52
+ material: new Uint8Array(e.material)
53
+ })),
54
+ now: h.now ?? Date.now
55
+ }, y = { ...h.use }, b = h.provider.read?.bind(h.provider);
56
+ if (b === void 0) return u();
57
+ let x = await a(i, _, g, m, v), S = await b(x.selection.artifactId);
58
+ if (f(S, "id,manifest").id !== x.selection.artifactId) return u();
59
+ let C = o(S), w = x.admission.app, T = x.admission.admission;
60
+ if (w.web === void 0 || c(C.build) !== c({
61
+ version: 1,
62
+ snapshotDigest: T.snapshot.digest,
63
+ inputsId: w.inputsId,
64
+ executionId: w.executionId
65
+ }) || c(C.pathSetIds) !== c(x.selection.pathSets.map((e) => e.digest).sort())) return u();
66
+ let E = await t(i, _, T.snapshot, T.configuration.app);
67
+ if (c(E) !== c(C.consentPurposes)) return u();
68
+ let D = new Map(x.entries.map((e) => ["https://" + e.host + e.path, e])), O = /* @__PURE__ */ new Map(), k = /* @__PURE__ */ new Set();
69
+ for (let t of C.records) {
70
+ let a = D.get(t.url);
71
+ if (a === void 0 || t.path !== a.path || t.routeId !== a.routeId || t.pageFile !== a.file) return u();
72
+ let o = f(await b(t.artifactId), "id,manifest"), s = f(o.manifest, "files,subject,version");
73
+ if (o.id !== t.artifactId || s.version !== 1) return u();
74
+ let l = f(s.subject, a.owner === "code" ? "assets,codeSeo,receipt" : "assets,receipt"), m = p(l.assets).map((t) => {
75
+ let n = f(e({
76
+ key: "rendered-asset",
77
+ value: f(t)
78
+ }).value);
79
+ if (n.routeId !== a.routeId || n.snapshotDigest !== T.snapshot.digest || typeof n.checksum != "string" || !/^[a-f0-9]{64}$/.test(n.checksum)) return u();
80
+ let r = f(n.rights);
81
+ return r.version === 1 ? {
82
+ digest: n.checksum,
83
+ rights: r
84
+ } : u();
85
+ });
86
+ if (c(m) !== c(t.media)) return u();
87
+ for (let e of m) await r(i, _, e.rights, v.now(), y);
88
+ let h = f(l.receipt);
89
+ if (h.version !== (a.owner === "code" ? 13 : 12) || h.owner !== a.owner || h.snapshotId !== T.snapshot.id || h.snapshotDigest !== T.snapshot.digest || h.inputsId !== w.inputsId || h.executionId !== w.executionId || h.consumerId !== T.input.consumerId || h.buildId !== T.input.buildId || h.pageFile !== t.pageFile || h.path !== a.path || h.routeId !== a.routeId || h.documentDigest !== t.digest) return u();
90
+ let g = e({
91
+ key: "renderer-binding",
92
+ value: {
93
+ consentPurposes: h.consentPurposes,
94
+ presentation: h.presentation,
95
+ web: h.web
96
+ }
97
+ }).value;
98
+ if (c(g) !== c({
99
+ consentPurposes: E,
100
+ presentation: t.presentation,
101
+ web: w.web
102
+ })) return u();
103
+ let x = p(s.files).map((e) => f(e, "contentType,digest,path,size")).find((e) => e.path === "document.html");
104
+ if (x === void 0 || x.contentType !== "text/html" || x.digest !== t.digest || x.size !== t.size) return u();
105
+ if (a.owner === "code") {
106
+ let e = n(l.codeSeo);
107
+ if (h.codeSeoDigest !== d(e)) return u();
108
+ let r = {
109
+ url: t.url,
110
+ path: a.path,
111
+ localeId: a.localeId,
112
+ routeId: a.routeId,
113
+ seo: e
114
+ }, i = O.get(t.url);
115
+ if (i !== void 0 && c(i) !== c(r)) return u();
116
+ O.set(t.url, r);
117
+ }
118
+ k.add(t.url);
119
+ }
120
+ if (k.size !== D.size || [...D.keys()].some((e) => !k.has(e))) return u();
121
+ let A = await a(i, _, g, x.selection, v);
122
+ return c(A.entries) !== c(x.entries) || c(A.admission.context) !== c(x.admission.context) ? u() : {
123
+ inventory: C,
124
+ paths: A,
125
+ native: [...O.values()]
126
+ };
127
+ };
128
+ export { m as readSnapshotSeoDocuments, l as snapshotOutputSafetyBinding };