@elytracms/next 0.0.86 → 0.0.88

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.
package/dist/index.js CHANGED
@@ -1,48 +1,21 @@
1
1
  import { ComponentRegistry } from '@elytracms/core/component-registry';
2
2
  export { defineComponent } from '@elytracms/core/component-registry';
3
- import { basePrimitives, getImplementation, renderDocumentBodyItems, documentBodyItems, ImageManifest, serializeListingQuery, RenderErrorBoundary, documentBodyRichTextValues, documentBodyCompositionNodes, richTextEmbedsInValue, collectReferencedAssetIds, collectRichTextRefsInValue, collectReferencedRelations, collectReferencedListings, collectReferencedRichTextLinks, normalizeImageSource } from '@elytracms/core/runtime-renderer';
3
+ import { basePrimitives, getImplementation, registerImplementations, renderDocumentBodyItems, documentBodyItems, ImageManifest, serializeListingQuery, RenderErrorBoundary, documentBodyRichTextValues, documentBodyCompositionNodes, richTextEmbedsInValue, collectReferencedAssetIds, collectRichTextRefsInValue, collectReferencedRelations, collectReferencedListings, collectReferencedRichTextLinks, normalizeImageSource } from '@elytracms/core/runtime-renderer';
4
4
  import { isValidElement } from 'react';
5
5
  import { isBlockSequenceValueShape } from '@elytracms/core/rich-text';
6
6
  import { jsx, Fragment } from 'react/jsx-runtime';
7
- import { cacheTags, isSectionSourceId, parseCmsSourceQueryConfig, listQueryOfCmsConfig, isDocumentHistory, resolvedAsset, createContentClient, createContentContext } from '@elytracms/core/content';
7
+ import { cacheTags, isDocumentHistory, resolvedAsset, createContentClient, createContentContext } from '@elytracms/core/content';
8
8
  import { documentKey, splitLocalePath, hierarchyMount, composePath, localeUrlPath, mergeRouteRecords, fallbackHomeRoutes, presentationBodyFields, splitPath, documentSchema, redirectRecordSchema } from '@elytracms/core/cms-core';
9
9
  export { documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, redirectRecordSchema, resolveLocale, routeRecordSchema, splitLocalePath, textDirection } from '@elytracms/core/cms-core';
10
10
  import { revalidateTag, unstable_cache } from 'next/cache';
11
11
  import { draftMode } from 'next/headers';
12
12
  import { redirect, notFound, permanentRedirect } from 'next/navigation';
13
+ import { COMPOSITE_KEY_SEPARATOR } from '@elytracms/core/project-graph';
13
14
  import { createHmac, timingSafeEqual } from 'crypto';
14
15
  import { z } from 'zod';
15
16
  export { z } from 'zod';
16
17
  import NextImage from 'next/image';
17
18
 
18
- // src/components.ts
19
-
20
- // src/is-component.ts
21
- var EXOTIC_COMPONENT_TYPES = /* @__PURE__ */ new Set([
22
- /* @__PURE__ */ Symbol.for("react.memo"),
23
- /* @__PURE__ */ Symbol.for("react.forward_ref"),
24
- /* @__PURE__ */ Symbol.for("react.lazy")
25
- ]);
26
- function isComponentImplementation(value) {
27
- if (typeof value === "function") return true;
28
- if (typeof value !== "object" || value === null) return false;
29
- const marker = value.$$typeof;
30
- return typeof marker === "symbol" && EXOTIC_COMPONENT_TYPES.has(marker);
31
- }
32
- function describeImplementation(value) {
33
- if (value === null) return "null";
34
- if (value === void 0) return "undefined";
35
- if (typeof value === "string") {
36
- return `the string ${JSON.stringify(value)} (which React would render silently as an HTML tag)`;
37
- }
38
- if (Array.isArray(value)) return "an array";
39
- if (typeof value === "object") {
40
- const marker = value.$$typeof;
41
- return typeof marker === "symbol" ? `an object tagged ${String(marker)}` : "a plain object";
42
- }
43
- return `a ${typeof value}`;
44
- }
45
-
46
19
  // src/components.ts
47
20
  function defineHostComponents(components = [], options = {}) {
48
21
  const includeBase = options.includeBasePrimitives !== false;
@@ -53,74 +26,9 @@ function defineHostComponents(components = [], options = {}) {
53
26
  const implementation = getImplementation(base.implementations, manifest.id);
54
27
  if (implementation) implementations[manifest.id] = implementation;
55
28
  }
56
- const implementationIssues = [];
57
- for (const component of components) {
58
- const id = component.manifest.id;
59
- if (isComponentImplementation(component.implementation)) {
60
- implementations[id] = component.implementation;
61
- continue;
62
- }
63
- implementationIssues.push({
64
- code: "invalid-implementation",
65
- componentId: id,
66
- message: `Component "${id}": implementation is not a React component \u2014 received ${describeImplementation(component.implementation)}; expected a function or class component, or a React.memo / forwardRef / lazy wrapper. The entry is registered without an implementation, so its nodes render the missing-component fallback.`
67
- });
68
- }
69
- return { registry, implementations, issues: [...registry.issues, ...implementationIssues] };
70
- }
71
-
72
- // src/payloads.ts
73
- var SOURCE_PAYLOAD_ERROR_KEY = "__elytraSourcePayloadError";
74
- function sourcePayloadError(sourceId, messages) {
75
- return { [SOURCE_PAYLOAD_ERROR_KEY]: true, sourceId, messages: [...messages] };
76
- }
77
- function isSourcePayloadError(value) {
78
- return typeof value === "object" && value !== null && value[SOURCE_PAYLOAD_ERROR_KEY] === true && typeof value.sourceId === "string" && Array.isArray(value.messages);
79
- }
80
- function unescapeRefToken(token) {
81
- return token.replace(/~1/g, "/").replace(/~0/g, "~");
82
- }
83
- function pathFromToken(token) {
84
- if (token === "" || token === "/") return [];
85
- if (!token.startsWith("/")) return void 0;
86
- return token.slice(1).split("/").map(unescapeRefToken);
87
- }
88
- var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
89
- function resolvePayloadToken(payload, token) {
90
- const path = pathFromToken(token);
91
- if (path === void 0) return void 0;
92
- let current = payload;
93
- for (const segment of path) {
94
- if (Array.isArray(current)) {
95
- if (!/^(0|[1-9][0-9]*)$/.test(segment)) return void 0;
96
- const index = Number(segment);
97
- if (index >= current.length) return void 0;
98
- current = current[index];
99
- continue;
100
- }
101
- if (isPlainObject(current)) {
102
- if (!Object.prototype.hasOwnProperty.call(current, segment)) return void 0;
103
- current = current[segment];
104
- continue;
105
- }
106
- return void 0;
107
- }
108
- return current;
109
- }
110
- function createBindingResolver(payloads) {
111
- return (ref, item) => {
112
- if (ref.mode === "repeaterItem") {
113
- return item === void 0 ? void 0 : resolvePayloadToken(item.item, ref.token);
114
- }
115
- if (!Object.prototype.hasOwnProperty.call(payloads, ref.sourceId)) return void 0;
116
- const payload = payloads[ref.sourceId];
117
- if (isSourcePayloadError(payload)) {
118
- throw new Error(
119
- `Source "${payload.sourceId}" query was rejected: ${payload.messages.join("; ")}`
120
- );
121
- }
122
- return resolvePayloadToken(payload, ref.token);
123
- };
29
+ const host = registerImplementations(components);
30
+ Object.assign(implementations, host.implementations);
31
+ return { registry, implementations, issues: [...registry.issues, ...host.issues] };
124
32
  }
125
33
  function relationResolver(relations) {
126
34
  return (ref) => relations[`${ref.collection}:${ref.id}`] ?? null;
@@ -159,19 +67,14 @@ function stripServerErrorBoundary(_node, rendered) {
159
67
  }
160
68
  return rendered;
161
69
  }
162
- function defaultBindingPayloads(result) {
163
- return { document: result.document, params: result.dynamicParams };
164
- }
165
70
  async function CanvasRenderer(props) {
166
71
  const { result, components } = props;
167
72
  if (result.status !== "ok") {
168
73
  return /* @__PURE__ */ jsx(UnresolvedPageFallback, { status: result.status });
169
74
  }
170
- const resolveBinding = props.resolveBinding ?? createBindingResolver(props.payloads ?? defaultBindingPayloads(result));
171
75
  const ctx = {
172
76
  registry: components.registry,
173
77
  implementations: components.implementations,
174
- resolveBinding,
175
78
  resolveAsset: assetResolver(props.assets ?? []),
176
79
  // EC-254: wire relation population only when the host baked the populated
177
80
  // targets, so a host that did not opt in keeps the raw-ref passthrough.
@@ -230,42 +133,6 @@ function mergeCacheTags(first, ...rest) {
230
133
  locale: first.locale
231
134
  });
232
135
  }
233
- function collectBindingSourceIds(node, into = /* @__PURE__ */ new Set()) {
234
- for (const value of Object.values(node.props ?? {})) {
235
- if (value.kind === "binding") into.add(value.binding.sourceId);
236
- }
237
- if (node.condition) into.add(node.condition.source.sourceId);
238
- for (const children of Object.values(node.slots ?? {})) {
239
- for (const child of children) collectBindingSourceIds(child, into);
240
- }
241
- return into;
242
- }
243
- function materializeSourcePayloads(input) {
244
- const { client, result, sources } = input;
245
- const payloads = {};
246
- const tags = [];
247
- if (result.status !== "ok") return { payloads, tags };
248
- const referenced = /* @__PURE__ */ new Set();
249
- const byId = new Map(sources.map((source) => [source.id, source]));
250
- for (const sourceId of [...referenced].sort()) {
251
- if (!isSectionSourceId(sourceId)) continue;
252
- const definition = byId.get(sourceId);
253
- if (!definition || definition.kind !== "cms") continue;
254
- const config = parseCmsSourceQueryConfig(definition.config);
255
- if (!config || config.documentId !== void 0) continue;
256
- const list = client.listDocuments(config.collectionId, listQueryOfCmsConfig(config));
257
- tags.push(list.tags);
258
- if (list.ok) {
259
- payloads[sourceId] = list.documents;
260
- } else {
261
- payloads[sourceId] = sourcePayloadError(
262
- sourceId,
263
- list.errors.map((error) => error.message)
264
- );
265
- }
266
- }
267
- return { payloads, tags };
268
- }
269
136
  function createStaticContentSource(data) {
270
137
  const locales = data.locales;
271
138
  const routes = data.routes ?? [];
@@ -311,7 +178,6 @@ function createStaticContentSource(data) {
311
178
  // dimensions. Baked into the (serializable) render outcome by the route
312
179
  // helper, so a cached page keeps its images during a backend outage.
313
180
  assets: () => [...assets.values()].map((record2) => resolvedAsset(record2, record2.url ?? assetUrl(record2))),
314
- ...data.sources ? { sources: data.sources } : {},
315
181
  // EC-499: the schema the route helper reads a collection's declared
316
182
  // `presentation` from (which field is the delivery body, which component
317
183
  // wraps it). Already prefetched for the lookup above — exposing it costs
@@ -351,7 +217,6 @@ async function createContentSnapshot(adapter, projectId, options) {
351
217
  locales: options.locales,
352
218
  ...options.routes ? { routes: options.routes } : {},
353
219
  redirects: options.redirects ? [...options.redirects] : redirects,
354
- ...options.sources ? { sources: options.sources } : {},
355
220
  ...schema ? { collections: schema.collections } : {},
356
221
  documents,
357
222
  assets: assetRecords,
@@ -474,26 +339,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
474
339
  if (result.status !== "ok") {
475
340
  return { kind: "not-found", tags: result.tags };
476
341
  }
477
- const extraTags = [];
478
- let payloads = defaultBindingPayloads(result);
479
- const materialized = materializeSourcePayloads({
480
- client,
481
- result,
482
- sources: source.sources ?? []
483
- });
484
- payloads = { ...payloads, ...materialized.payloads };
485
- extraTags.push(...materialized.tags);
486
- if (options.payloads) {
487
- const custom = await options.payloads({
488
- client,
489
- result,
490
- perspective,
491
- path,
492
- params: result.dynamicParams,
493
- addTags: (tags) => extraTags.push(tags)
494
- });
495
- payloads = { ...payloads, ...custom };
496
- }
497
342
  const presentation = presentationFor(source, result);
498
343
  const body = pageBodyOf(result, presentation);
499
344
  const allAssets = source.assets?.() ?? [];
@@ -524,7 +369,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
524
369
  return {
525
370
  kind: "render",
526
371
  result,
527
- payloads,
528
372
  assets: bakedAssets,
529
373
  relations,
530
374
  listings,
@@ -532,7 +376,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
532
376
  ...presentation ? { presentation } : {},
533
377
  tags: mergeCacheTags(
534
378
  result.tags,
535
- ...extraTags,
536
379
  ...listingTags,
537
380
  assetTags,
538
381
  relationTags,
@@ -624,7 +467,7 @@ function resolveOgImage(value, assets) {
624
467
  return assets.find((asset) => asset.id === value)?.url ?? null;
625
468
  }
626
469
  function openGraphLocale(locale) {
627
- return locale.replace(/-/g, "_");
470
+ return locale.includes("-") ? locale.replace(/-/g, "_") : null;
628
471
  }
629
472
  function canvasPageMetadata(result, assets = []) {
630
473
  const doc = result.document;
@@ -641,17 +484,32 @@ function canvasPageMetadata(result, assets = []) {
641
484
  if (seoDescription) metadata.description = seoDescription;
642
485
  const ogTitle = seoOgTitle ?? title;
643
486
  if (doc) {
487
+ const ogLocale = openGraphLocale(result.tags.locale);
644
488
  metadata.openGraph = {
645
489
  ...ogTitle !== null ? { title: ogTitle } : {},
646
490
  ...seoDescription ? { description: seoDescription } : {},
647
491
  ...seoOgImage ? { images: [{ url: seoOgImage }] } : {},
648
- locale: openGraphLocale(result.tags.locale)
492
+ ...ogLocale !== null ? { locale: ogLocale } : {}
649
493
  };
650
494
  }
651
495
  if (seoNoindex) metadata.robots = { index: false };
652
496
  if (seoCanonical) metadata.alternates = { canonical: seoCanonical };
653
497
  return metadata;
654
498
  }
499
+ function mergeMetadataOverParent(parent, page) {
500
+ if (!parent) return page;
501
+ const merged = { ...page };
502
+ for (const [key, pageValue] of Object.entries(page)) {
503
+ const parentValue = parent[key];
504
+ if (isPlainObject(pageValue) && isPlainObject(parentValue)) {
505
+ merged[key] = { ...parentValue, ...pageValue };
506
+ }
507
+ }
508
+ return merged;
509
+ }
510
+ function isPlainObject(value) {
511
+ return typeof value === "object" && value !== null && !Array.isArray(value);
512
+ }
655
513
  function defaultMetadata(result, assets) {
656
514
  return canvasPageMetadata(result, assets);
657
515
  }
@@ -665,7 +523,6 @@ function createCanvasRoute(options) {
665
523
  const resolveFresh = async () => {
666
524
  const source = await options.loadContent({ perspective });
667
525
  return resolveCanvasPage(source, url, perspective, {
668
- ...options.payloads ? { payloads: options.payloads } : {},
669
526
  // EC-205: page-scope the baked assets to what the page actually uses.
670
527
  registry: options.components.registry
671
528
  });
@@ -701,7 +558,6 @@ function createCanvasRoute(options) {
701
558
  {
702
559
  result: outcome.result,
703
560
  components: options.components,
704
- payloads: outcome.payloads,
705
561
  assets: outcome.assets,
706
562
  relations: outcome.relations,
707
563
  listings: outcome.listings,
@@ -714,7 +570,7 @@ function createCanvasRoute(options) {
714
570
  }
715
571
  }
716
572
  };
717
- const generateMetadata = async (props) => {
573
+ const pageMetadata = async (props) => {
718
574
  const { slug } = await props.params;
719
575
  const url = pathFromSlug(slug);
720
576
  const perspective = await requestPerspective();
@@ -728,6 +584,10 @@ function createCanvasRoute(options) {
728
584
  if (outcome.kind !== "render") return {};
729
585
  return options.metadata ? options.metadata(outcome.result, { url, perspective }) : defaultMetadata(outcome.result, outcome.assets);
730
586
  };
587
+ const generateMetadata = async (props, parent) => {
588
+ const [page, resolvedParent] = await Promise.all([pageMetadata(props), parent ?? null]);
589
+ return mergeMetadataOverParent(resolvedParent, page);
590
+ };
731
591
  return { Page, generateMetadata };
732
592
  }
733
593
  function paramNamesOf(pattern) {
@@ -830,7 +690,7 @@ function canvasSitemapEntries(source, options) {
830
690
  continue;
831
691
  }
832
692
  const absolute = originOf(options.baseUrl) + urlPath;
833
- const group = result.document ? `${route.id}\0doc\0${result.document.collection}\0${result.document.id}` : `${route.id}\0path\0${path}`;
693
+ const group = result.document ? `${route.id}${COMPOSITE_KEY_SEPARATOR}doc${COMPOSITE_KEY_SEPARATOR}${result.document.collection}${COMPOSITE_KEY_SEPARATOR}${result.document.id}` : `${route.id}${COMPOSITE_KEY_SEPARATOR}path${COMPOSITE_KEY_SEPARATOR}${path}`;
834
694
  if (!byUrl.has(absolute)) byUrl.set(absolute, { group, locale });
835
695
  const perLocale = byGroup.get(group) ?? /* @__PURE__ */ new Map();
836
696
  if (!perLocale.has(locale)) perLocale.set(locale, absolute);
@@ -1080,21 +940,6 @@ function parseRedirects(rows) {
1080
940
  }
1081
941
  return redirects;
1082
942
  }
1083
- var canvasDataSourceSchema = z.object({
1084
- kind: z.string().min(1),
1085
- id: z.string().min(1),
1086
- label: z.string().optional(),
1087
- config: z.unknown().optional()
1088
- });
1089
- function parseSources(rows) {
1090
- if (!Array.isArray(rows)) return [];
1091
- const sources = [];
1092
- for (const row of rows) {
1093
- const parsed = canvasDataSourceSchema.safeParse(row);
1094
- if (parsed.success) sources.push(parsed.data);
1095
- }
1096
- return sources;
1097
- }
1098
943
  function assembleLiveSource(payload, options, perspective) {
1099
944
  const locales = options.locales;
1100
945
  const documents = parseDocuments(payload.documents);
@@ -1110,10 +955,7 @@ function assembleLiveSource(payload, options, perspective) {
1110
955
  redirects: parseRedirects(payload.redirects ?? []),
1111
956
  collections: [...options.collections],
1112
957
  documents: documentSources,
1113
- assets: payload.assets,
1114
- // EC-166 LIVE mode: the builder's persisted section/template sources, so
1115
- // the route helper materializes their payloads.
1116
- sources: parseSources(payload.sources)
958
+ assets: payload.assets
1117
959
  });
1118
960
  }
1119
961
  async function loadLiveContent(options, perspective) {
@@ -1252,12 +1094,30 @@ function resolveGlobals(source, options = {}) {
1252
1094
  }
1253
1095
 
1254
1096
  // src/preview-core.ts
1097
+ var RESOLUTION_ORIGIN = "https://redirect-target.invalid";
1098
+ function resolveOnOrigin(value) {
1099
+ let resolved;
1100
+ try {
1101
+ resolved = new URL(value, RESOLUTION_ORIGIN);
1102
+ } catch {
1103
+ return null;
1104
+ }
1105
+ return resolved.origin === RESOLUTION_ORIGIN ? resolved : null;
1106
+ }
1107
+ function hasControlCharacter(value) {
1108
+ for (let i = 0; i < value.length; i++) {
1109
+ const code = value.charCodeAt(i);
1110
+ if (code <= 31 || code === 127) return true;
1111
+ }
1112
+ return false;
1113
+ }
1255
1114
  function safeRedirectTarget(value, fallback = "/") {
1256
1115
  if (value === null || value === void 0 || value === "") return fallback;
1257
- if (!value.startsWith("/")) return null;
1258
- if (value.includes("\\")) return null;
1259
- if (value.startsWith("//")) return null;
1260
- return value;
1116
+ if (!value.startsWith("/") || hasControlCharacter(value)) return null;
1117
+ const resolved = resolveOnOrigin(value);
1118
+ if (resolved === null) return null;
1119
+ const target = resolved.pathname + resolved.search + resolved.hash;
1120
+ return resolveOnOrigin(target) === null ? null : target;
1261
1121
  }
1262
1122
  function evaluatePreviewRequest(requestUrl, expectedToken) {
1263
1123
  if (expectedToken === void 0 || expectedToken.length === 0) {
@@ -1279,6 +1139,15 @@ function evaluatePreviewRequest(requestUrl, expectedToken) {
1279
1139
  }
1280
1140
  return { ok: true, redirectTo };
1281
1141
  }
1142
+ function previewDisableTarget(requestUrl) {
1143
+ let url;
1144
+ try {
1145
+ url = typeof requestUrl === "string" ? new URL(requestUrl, "http://localhost") : requestUrl;
1146
+ } catch {
1147
+ return "/";
1148
+ }
1149
+ return safeRedirectTarget(url.searchParams.get("redirect")) ?? "/";
1150
+ }
1282
1151
 
1283
1152
  // src/preview.ts
1284
1153
  function createPreviewRoute(options) {
@@ -1299,13 +1168,7 @@ function createPreviewDisableRoute() {
1299
1168
  async GET(request) {
1300
1169
  const draft = await draftMode();
1301
1170
  draft.disable();
1302
- let target;
1303
- try {
1304
- target = safeRedirectTarget(new URL(request.url).searchParams.get("redirect"));
1305
- } catch {
1306
- target = "/";
1307
- }
1308
- redirect(target ?? "/");
1171
+ redirect(previewDisableTarget(request.url));
1309
1172
  }
1310
1173
  };
1311
1174
  }
@@ -1345,8 +1208,7 @@ function createElytraHost(options) {
1345
1208
  redirects: [],
1346
1209
  collections: [...options.collections],
1347
1210
  documents: [],
1348
- assets: [],
1349
- sources: []
1211
+ assets: []
1350
1212
  });
1351
1213
  const loadContent = (request) => {
1352
1214
  if (live) {
@@ -1422,6 +1284,6 @@ function createElytraHost(options) {
1422
1284
  }
1423
1285
  var PACKAGE = "@elytracms/next";
1424
1286
 
1425
- export { CanvasRenderer, ELYTRA_HOST_ENV_KEYS, ElytraImage, PACKAGE, REVALIDATE_SIGNATURE_HEADER, assembleLiveSource, bodyItemsOf, canvasPageMetadata, canvasSitemapEntries, collectBindingSourceIds, collectionCacheTag, createAssetImageLoader, createBindingResolver, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defaultBindingPayloads, defineHostComponents, docCacheTag, elytraHostImage, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed, isSourcePayloadError, loadCachedEntry, loadLiveContent, materializeSourcePayloads, mergeCacheTags, nextCacheTags, nextImagePrimitive, pathFromSlug, projectSweepTag, resolveCanvasPage, resolveGlobals, resolveHostEnv, resolvePayloadToken, revalidatePayloadSchema, routeCacheTag, safeRedirectTarget, scopeCacheTag, signRevalidateBody, sourcePayloadError };
1287
+ export { CanvasRenderer, ELYTRA_HOST_ENV_KEYS, ElytraImage, PACKAGE, REVALIDATE_SIGNATURE_HEADER, assembleLiveSource, bodyItemsOf, canvasPageMetadata, canvasSitemapEntries, collectionCacheTag, createAssetImageLoader, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defineHostComponents, docCacheTag, elytraHostImage, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed, loadCachedEntry, loadLiveContent, mergeCacheTags, mergeMetadataOverParent, nextCacheTags, nextImagePrimitive, openGraphLocale, pathFromSlug, projectSweepTag, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidatePayloadSchema, routeCacheTag, safeRedirectTarget, scopeCacheTag, signRevalidateBody };
1426
1288
  //# sourceMappingURL=index.js.map
1427
1289
  //# sourceMappingURL=index.js.map