@elytracms/next 0.0.85 → 0.0.87
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.d.ts +106 -225
- package/dist/index.js +59 -169
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
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,
|
|
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
|
-
export { documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, redirectRecordSchema, routeRecordSchema, splitLocalePath } from '@elytracms/core/cms-core';
|
|
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';
|
|
@@ -25,64 +26,9 @@ function defineHostComponents(components = [], options = {}) {
|
|
|
25
26
|
const implementation = getImplementation(base.implementations, manifest.id);
|
|
26
27
|
if (implementation) implementations[manifest.id] = implementation;
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return { registry, implementations, issues: registry.issues };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// src/payloads.ts
|
|
35
|
-
var SOURCE_PAYLOAD_ERROR_KEY = "__elytraSourcePayloadError";
|
|
36
|
-
function sourcePayloadError(sourceId, messages) {
|
|
37
|
-
return { [SOURCE_PAYLOAD_ERROR_KEY]: true, sourceId, messages: [...messages] };
|
|
38
|
-
}
|
|
39
|
-
function isSourcePayloadError(value) {
|
|
40
|
-
return typeof value === "object" && value !== null && value[SOURCE_PAYLOAD_ERROR_KEY] === true && typeof value.sourceId === "string" && Array.isArray(value.messages);
|
|
41
|
-
}
|
|
42
|
-
function unescapeRefToken(token) {
|
|
43
|
-
return token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
44
|
-
}
|
|
45
|
-
function pathFromToken(token) {
|
|
46
|
-
if (token === "" || token === "/") return [];
|
|
47
|
-
if (!token.startsWith("/")) return void 0;
|
|
48
|
-
return token.slice(1).split("/").map(unescapeRefToken);
|
|
49
|
-
}
|
|
50
|
-
var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
51
|
-
function resolvePayloadToken(payload, token) {
|
|
52
|
-
const path = pathFromToken(token);
|
|
53
|
-
if (path === void 0) return void 0;
|
|
54
|
-
let current = payload;
|
|
55
|
-
for (const segment of path) {
|
|
56
|
-
if (Array.isArray(current)) {
|
|
57
|
-
if (!/^(0|[1-9][0-9]*)$/.test(segment)) return void 0;
|
|
58
|
-
const index = Number(segment);
|
|
59
|
-
if (index >= current.length) return void 0;
|
|
60
|
-
current = current[index];
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (isPlainObject(current)) {
|
|
64
|
-
if (!Object.prototype.hasOwnProperty.call(current, segment)) return void 0;
|
|
65
|
-
current = current[segment];
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
return void 0;
|
|
69
|
-
}
|
|
70
|
-
return current;
|
|
71
|
-
}
|
|
72
|
-
function createBindingResolver(payloads) {
|
|
73
|
-
return (ref, item) => {
|
|
74
|
-
if (ref.mode === "repeaterItem") {
|
|
75
|
-
return item === void 0 ? void 0 : resolvePayloadToken(item.item, ref.token);
|
|
76
|
-
}
|
|
77
|
-
if (!Object.prototype.hasOwnProperty.call(payloads, ref.sourceId)) return void 0;
|
|
78
|
-
const payload = payloads[ref.sourceId];
|
|
79
|
-
if (isSourcePayloadError(payload)) {
|
|
80
|
-
throw new Error(
|
|
81
|
-
`Source "${payload.sourceId}" query was rejected: ${payload.messages.join("; ")}`
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
return resolvePayloadToken(payload, ref.token);
|
|
85
|
-
};
|
|
29
|
+
const host = registerImplementations(components);
|
|
30
|
+
Object.assign(implementations, host.implementations);
|
|
31
|
+
return { registry, implementations, issues: [...registry.issues, ...host.issues] };
|
|
86
32
|
}
|
|
87
33
|
function relationResolver(relations) {
|
|
88
34
|
return (ref) => relations[`${ref.collection}:${ref.id}`] ?? null;
|
|
@@ -121,19 +67,14 @@ function stripServerErrorBoundary(_node, rendered) {
|
|
|
121
67
|
}
|
|
122
68
|
return rendered;
|
|
123
69
|
}
|
|
124
|
-
function defaultBindingPayloads(result) {
|
|
125
|
-
return { document: result.document, params: result.dynamicParams };
|
|
126
|
-
}
|
|
127
70
|
async function CanvasRenderer(props) {
|
|
128
71
|
const { result, components } = props;
|
|
129
72
|
if (result.status !== "ok") {
|
|
130
73
|
return /* @__PURE__ */ jsx(UnresolvedPageFallback, { status: result.status });
|
|
131
74
|
}
|
|
132
|
-
const resolveBinding = props.resolveBinding ?? createBindingResolver(props.payloads ?? defaultBindingPayloads(result));
|
|
133
75
|
const ctx = {
|
|
134
76
|
registry: components.registry,
|
|
135
77
|
implementations: components.implementations,
|
|
136
|
-
resolveBinding,
|
|
137
78
|
resolveAsset: assetResolver(props.assets ?? []),
|
|
138
79
|
// EC-254: wire relation population only when the host baked the populated
|
|
139
80
|
// targets, so a host that did not opt in keeps the raw-ref passthrough.
|
|
@@ -192,42 +133,6 @@ function mergeCacheTags(first, ...rest) {
|
|
|
192
133
|
locale: first.locale
|
|
193
134
|
});
|
|
194
135
|
}
|
|
195
|
-
function collectBindingSourceIds(node, into = /* @__PURE__ */ new Set()) {
|
|
196
|
-
for (const value of Object.values(node.props ?? {})) {
|
|
197
|
-
if (value.kind === "binding") into.add(value.binding.sourceId);
|
|
198
|
-
}
|
|
199
|
-
if (node.condition) into.add(node.condition.source.sourceId);
|
|
200
|
-
for (const children of Object.values(node.slots ?? {})) {
|
|
201
|
-
for (const child of children) collectBindingSourceIds(child, into);
|
|
202
|
-
}
|
|
203
|
-
return into;
|
|
204
|
-
}
|
|
205
|
-
function materializeSourcePayloads(input) {
|
|
206
|
-
const { client, result, sources } = input;
|
|
207
|
-
const payloads = {};
|
|
208
|
-
const tags = [];
|
|
209
|
-
if (result.status !== "ok") return { payloads, tags };
|
|
210
|
-
const referenced = /* @__PURE__ */ new Set();
|
|
211
|
-
const byId = new Map(sources.map((source) => [source.id, source]));
|
|
212
|
-
for (const sourceId of [...referenced].sort()) {
|
|
213
|
-
if (!isSectionSourceId(sourceId)) continue;
|
|
214
|
-
const definition = byId.get(sourceId);
|
|
215
|
-
if (!definition || definition.kind !== "cms") continue;
|
|
216
|
-
const config = parseCmsSourceQueryConfig(definition.config);
|
|
217
|
-
if (!config || config.documentId !== void 0) continue;
|
|
218
|
-
const list = client.listDocuments(config.collectionId, listQueryOfCmsConfig(config));
|
|
219
|
-
tags.push(list.tags);
|
|
220
|
-
if (list.ok) {
|
|
221
|
-
payloads[sourceId] = list.documents;
|
|
222
|
-
} else {
|
|
223
|
-
payloads[sourceId] = sourcePayloadError(
|
|
224
|
-
sourceId,
|
|
225
|
-
list.errors.map((error) => error.message)
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return { payloads, tags };
|
|
230
|
-
}
|
|
231
136
|
function createStaticContentSource(data) {
|
|
232
137
|
const locales = data.locales;
|
|
233
138
|
const routes = data.routes ?? [];
|
|
@@ -273,7 +178,6 @@ function createStaticContentSource(data) {
|
|
|
273
178
|
// dimensions. Baked into the (serializable) render outcome by the route
|
|
274
179
|
// helper, so a cached page keeps its images during a backend outage.
|
|
275
180
|
assets: () => [...assets.values()].map((record2) => resolvedAsset(record2, record2.url ?? assetUrl(record2))),
|
|
276
|
-
...data.sources ? { sources: data.sources } : {},
|
|
277
181
|
// EC-499: the schema the route helper reads a collection's declared
|
|
278
182
|
// `presentation` from (which field is the delivery body, which component
|
|
279
183
|
// wraps it). Already prefetched for the lookup above — exposing it costs
|
|
@@ -313,7 +217,6 @@ async function createContentSnapshot(adapter, projectId, options) {
|
|
|
313
217
|
locales: options.locales,
|
|
314
218
|
...options.routes ? { routes: options.routes } : {},
|
|
315
219
|
redirects: options.redirects ? [...options.redirects] : redirects,
|
|
316
|
-
...options.sources ? { sources: options.sources } : {},
|
|
317
220
|
...schema ? { collections: schema.collections } : {},
|
|
318
221
|
documents,
|
|
319
222
|
assets: assetRecords,
|
|
@@ -436,26 +339,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
|
436
339
|
if (result.status !== "ok") {
|
|
437
340
|
return { kind: "not-found", tags: result.tags };
|
|
438
341
|
}
|
|
439
|
-
const extraTags = [];
|
|
440
|
-
let payloads = defaultBindingPayloads(result);
|
|
441
|
-
const materialized = materializeSourcePayloads({
|
|
442
|
-
client,
|
|
443
|
-
result,
|
|
444
|
-
sources: source.sources ?? []
|
|
445
|
-
});
|
|
446
|
-
payloads = { ...payloads, ...materialized.payloads };
|
|
447
|
-
extraTags.push(...materialized.tags);
|
|
448
|
-
if (options.payloads) {
|
|
449
|
-
const custom = await options.payloads({
|
|
450
|
-
client,
|
|
451
|
-
result,
|
|
452
|
-
perspective,
|
|
453
|
-
path,
|
|
454
|
-
params: result.dynamicParams,
|
|
455
|
-
addTags: (tags) => extraTags.push(tags)
|
|
456
|
-
});
|
|
457
|
-
payloads = { ...payloads, ...custom };
|
|
458
|
-
}
|
|
459
342
|
const presentation = presentationFor(source, result);
|
|
460
343
|
const body = pageBodyOf(result, presentation);
|
|
461
344
|
const allAssets = source.assets?.() ?? [];
|
|
@@ -486,7 +369,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
|
486
369
|
return {
|
|
487
370
|
kind: "render",
|
|
488
371
|
result,
|
|
489
|
-
payloads,
|
|
490
372
|
assets: bakedAssets,
|
|
491
373
|
relations,
|
|
492
374
|
listings,
|
|
@@ -494,7 +376,6 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
|
494
376
|
...presentation ? { presentation } : {},
|
|
495
377
|
tags: mergeCacheTags(
|
|
496
378
|
result.tags,
|
|
497
|
-
...extraTags,
|
|
498
379
|
...listingTags,
|
|
499
380
|
assetTags,
|
|
500
381
|
relationTags,
|
|
@@ -533,6 +414,9 @@ function nextCacheTags(tags, scope) {
|
|
|
533
414
|
for (const assetId of tags.assets) all.add(assetCacheTag(assetId, scope));
|
|
534
415
|
return [...all].sort();
|
|
535
416
|
}
|
|
417
|
+
function canvasCacheKey({ scope, mode, url }) {
|
|
418
|
+
return ["elytra-route", scope ?? "", mode ?? "", url];
|
|
419
|
+
}
|
|
536
420
|
var CacheDiscoveryBail = class extends Error {
|
|
537
421
|
constructor() {
|
|
538
422
|
super("elytra cache discovery bail (never user-visible)");
|
|
@@ -582,6 +466,9 @@ function resolveOgImage(value, assets) {
|
|
|
582
466
|
if (looksLikeUrl(value)) return value;
|
|
583
467
|
return assets.find((asset) => asset.id === value)?.url ?? null;
|
|
584
468
|
}
|
|
469
|
+
function openGraphLocale(locale) {
|
|
470
|
+
return locale.replace(/-/g, "_");
|
|
471
|
+
}
|
|
585
472
|
function canvasPageMetadata(result, assets = []) {
|
|
586
473
|
const doc = result.document;
|
|
587
474
|
const seoTitle = str(doc?.["seoTitle"]);
|
|
@@ -596,11 +483,12 @@ function canvasPageMetadata(result, assets = []) {
|
|
|
596
483
|
if (title !== null) metadata.title = title;
|
|
597
484
|
if (seoDescription) metadata.description = seoDescription;
|
|
598
485
|
const ogTitle = seoOgTitle ?? title;
|
|
599
|
-
if (
|
|
486
|
+
if (doc) {
|
|
600
487
|
metadata.openGraph = {
|
|
601
488
|
...ogTitle !== null ? { title: ogTitle } : {},
|
|
602
489
|
...seoDescription ? { description: seoDescription } : {},
|
|
603
|
-
...seoOgImage ? { images: [{ url: seoOgImage }] } : {}
|
|
490
|
+
...seoOgImage ? { images: [{ url: seoOgImage }] } : {},
|
|
491
|
+
locale: openGraphLocale(result.tags.locale)
|
|
604
492
|
};
|
|
605
493
|
}
|
|
606
494
|
if (seoNoindex) metadata.robots = { index: false };
|
|
@@ -620,7 +508,6 @@ function createCanvasRoute(options) {
|
|
|
620
508
|
const resolveFresh = async () => {
|
|
621
509
|
const source = await options.loadContent({ perspective });
|
|
622
510
|
return resolveCanvasPage(source, url, perspective, {
|
|
623
|
-
...options.payloads ? { payloads: options.payloads } : {},
|
|
624
511
|
// EC-205: page-scope the baked assets to what the page actually uses.
|
|
625
512
|
registry: options.components.registry
|
|
626
513
|
});
|
|
@@ -630,7 +517,7 @@ function createCanvasRoute(options) {
|
|
|
630
517
|
const scope = options.cache.scope;
|
|
631
518
|
const entry = await loadCachedEntry(
|
|
632
519
|
nextCacheWrapper,
|
|
633
|
-
|
|
520
|
+
canvasCacheKey({ scope, mode: options.cache.mode, url }),
|
|
634
521
|
[projectSweepTag(scope)],
|
|
635
522
|
async () => {
|
|
636
523
|
const outcome = await resolveFresh();
|
|
@@ -656,7 +543,6 @@ function createCanvasRoute(options) {
|
|
|
656
543
|
{
|
|
657
544
|
result: outcome.result,
|
|
658
545
|
components: options.components,
|
|
659
|
-
payloads: outcome.payloads,
|
|
660
546
|
assets: outcome.assets,
|
|
661
547
|
relations: outcome.relations,
|
|
662
548
|
listings: outcome.listings,
|
|
@@ -785,7 +671,7 @@ function canvasSitemapEntries(source, options) {
|
|
|
785
671
|
continue;
|
|
786
672
|
}
|
|
787
673
|
const absolute = originOf(options.baseUrl) + urlPath;
|
|
788
|
-
const group = result.document ? `${route.id}
|
|
674
|
+
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}`;
|
|
789
675
|
if (!byUrl.has(absolute)) byUrl.set(absolute, { group, locale });
|
|
790
676
|
const perLocale = byGroup.get(group) ?? /* @__PURE__ */ new Map();
|
|
791
677
|
if (!perLocale.has(locale)) perLocale.set(locale, absolute);
|
|
@@ -1035,21 +921,6 @@ function parseRedirects(rows) {
|
|
|
1035
921
|
}
|
|
1036
922
|
return redirects;
|
|
1037
923
|
}
|
|
1038
|
-
var canvasDataSourceSchema = z.object({
|
|
1039
|
-
kind: z.string().min(1),
|
|
1040
|
-
id: z.string().min(1),
|
|
1041
|
-
label: z.string().optional(),
|
|
1042
|
-
config: z.unknown().optional()
|
|
1043
|
-
});
|
|
1044
|
-
function parseSources(rows) {
|
|
1045
|
-
if (!Array.isArray(rows)) return [];
|
|
1046
|
-
const sources = [];
|
|
1047
|
-
for (const row of rows) {
|
|
1048
|
-
const parsed = canvasDataSourceSchema.safeParse(row);
|
|
1049
|
-
if (parsed.success) sources.push(parsed.data);
|
|
1050
|
-
}
|
|
1051
|
-
return sources;
|
|
1052
|
-
}
|
|
1053
924
|
function assembleLiveSource(payload, options, perspective) {
|
|
1054
925
|
const locales = options.locales;
|
|
1055
926
|
const documents = parseDocuments(payload.documents);
|
|
@@ -1065,10 +936,7 @@ function assembleLiveSource(payload, options, perspective) {
|
|
|
1065
936
|
redirects: parseRedirects(payload.redirects ?? []),
|
|
1066
937
|
collections: [...options.collections],
|
|
1067
938
|
documents: documentSources,
|
|
1068
|
-
assets: payload.assets
|
|
1069
|
-
// EC-166 LIVE mode: the builder's persisted section/template sources, so
|
|
1070
|
-
// the route helper materializes their payloads.
|
|
1071
|
-
sources: parseSources(payload.sources)
|
|
939
|
+
assets: payload.assets
|
|
1072
940
|
});
|
|
1073
941
|
}
|
|
1074
942
|
async function loadLiveContent(options, perspective) {
|
|
@@ -1207,12 +1075,30 @@ function resolveGlobals(source, options = {}) {
|
|
|
1207
1075
|
}
|
|
1208
1076
|
|
|
1209
1077
|
// src/preview-core.ts
|
|
1078
|
+
var RESOLUTION_ORIGIN = "https://redirect-target.invalid";
|
|
1079
|
+
function resolveOnOrigin(value) {
|
|
1080
|
+
let resolved;
|
|
1081
|
+
try {
|
|
1082
|
+
resolved = new URL(value, RESOLUTION_ORIGIN);
|
|
1083
|
+
} catch {
|
|
1084
|
+
return null;
|
|
1085
|
+
}
|
|
1086
|
+
return resolved.origin === RESOLUTION_ORIGIN ? resolved : null;
|
|
1087
|
+
}
|
|
1088
|
+
function hasControlCharacter(value) {
|
|
1089
|
+
for (let i = 0; i < value.length; i++) {
|
|
1090
|
+
const code = value.charCodeAt(i);
|
|
1091
|
+
if (code <= 31 || code === 127) return true;
|
|
1092
|
+
}
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1210
1095
|
function safeRedirectTarget(value, fallback = "/") {
|
|
1211
1096
|
if (value === null || value === void 0 || value === "") return fallback;
|
|
1212
|
-
if (!value.startsWith("/")) return null;
|
|
1213
|
-
|
|
1214
|
-
if (
|
|
1215
|
-
|
|
1097
|
+
if (!value.startsWith("/") || hasControlCharacter(value)) return null;
|
|
1098
|
+
const resolved = resolveOnOrigin(value);
|
|
1099
|
+
if (resolved === null) return null;
|
|
1100
|
+
const target = resolved.pathname + resolved.search + resolved.hash;
|
|
1101
|
+
return resolveOnOrigin(target) === null ? null : target;
|
|
1216
1102
|
}
|
|
1217
1103
|
function evaluatePreviewRequest(requestUrl, expectedToken) {
|
|
1218
1104
|
if (expectedToken === void 0 || expectedToken.length === 0) {
|
|
@@ -1234,6 +1120,15 @@ function evaluatePreviewRequest(requestUrl, expectedToken) {
|
|
|
1234
1120
|
}
|
|
1235
1121
|
return { ok: true, redirectTo };
|
|
1236
1122
|
}
|
|
1123
|
+
function previewDisableTarget(requestUrl) {
|
|
1124
|
+
let url;
|
|
1125
|
+
try {
|
|
1126
|
+
url = typeof requestUrl === "string" ? new URL(requestUrl, "http://localhost") : requestUrl;
|
|
1127
|
+
} catch {
|
|
1128
|
+
return "/";
|
|
1129
|
+
}
|
|
1130
|
+
return safeRedirectTarget(url.searchParams.get("redirect")) ?? "/";
|
|
1131
|
+
}
|
|
1237
1132
|
|
|
1238
1133
|
// src/preview.ts
|
|
1239
1134
|
function createPreviewRoute(options) {
|
|
@@ -1254,13 +1149,7 @@ function createPreviewDisableRoute() {
|
|
|
1254
1149
|
async GET(request) {
|
|
1255
1150
|
const draft = await draftMode();
|
|
1256
1151
|
draft.disable();
|
|
1257
|
-
|
|
1258
|
-
try {
|
|
1259
|
-
target = safeRedirectTarget(new URL(request.url).searchParams.get("redirect"));
|
|
1260
|
-
} catch {
|
|
1261
|
-
target = "/";
|
|
1262
|
-
}
|
|
1263
|
-
redirect(target ?? "/");
|
|
1152
|
+
redirect(previewDisableTarget(request.url));
|
|
1264
1153
|
}
|
|
1265
1154
|
};
|
|
1266
1155
|
}
|
|
@@ -1287,9 +1176,9 @@ function createElytraHost(options) {
|
|
|
1287
1176
|
// canonical manifest stays (first registration wins in defineHostComponents).
|
|
1288
1177
|
...options.image === false ? [] : [nextImagePrimitive(options.image ?? {})],
|
|
1289
1178
|
// EC-539: the option is the CONFIG's entry shape (`implementation: unknown`)
|
|
1290
|
-
// so the recommended `{ ...site }` spread compiles
|
|
1291
|
-
//
|
|
1292
|
-
//
|
|
1179
|
+
// so the recommended `{ ...site }` spread compiles; EC-541: registration
|
|
1180
|
+
// takes that shape too and checks each implementation at runtime (see the
|
|
1181
|
+
// option's doc comment) — no narrowing cast here.
|
|
1293
1182
|
...options.components ?? []
|
|
1294
1183
|
]);
|
|
1295
1184
|
const emptySource = createStaticContentSource({
|
|
@@ -1300,8 +1189,7 @@ function createElytraHost(options) {
|
|
|
1300
1189
|
redirects: [],
|
|
1301
1190
|
collections: [...options.collections],
|
|
1302
1191
|
documents: [],
|
|
1303
|
-
assets: []
|
|
1304
|
-
sources: []
|
|
1192
|
+
assets: []
|
|
1305
1193
|
});
|
|
1306
1194
|
const loadContent = (request) => {
|
|
1307
1195
|
if (live) {
|
|
@@ -1336,7 +1224,9 @@ function createElytraHost(options) {
|
|
|
1336
1224
|
components,
|
|
1337
1225
|
// Tag scope = the project id the studio publishes under, so its webhook
|
|
1338
1226
|
// tags match this site's cached entries.
|
|
1339
|
-
|
|
1227
|
+
// EC-543: the mode is in the entry key so no world ever reads another's
|
|
1228
|
+
// entries; an explicit override may replace the scope, not drop the mode.
|
|
1229
|
+
...cache === false ? {} : { cache: { mode: contentMode, ...cache ?? { scope: contentScope } } },
|
|
1340
1230
|
...rest
|
|
1341
1231
|
});
|
|
1342
1232
|
};
|
|
@@ -1375,6 +1265,6 @@ function createElytraHost(options) {
|
|
|
1375
1265
|
}
|
|
1376
1266
|
var PACKAGE = "@elytracms/next";
|
|
1377
1267
|
|
|
1378
|
-
export { CanvasRenderer, ELYTRA_HOST_ENV_KEYS, ElytraImage, PACKAGE, REVALIDATE_SIGNATURE_HEADER, assembleLiveSource, bodyItemsOf, canvasPageMetadata, canvasSitemapEntries,
|
|
1268
|
+
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, nextCacheTags, nextImagePrimitive, pathFromSlug, projectSweepTag, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidatePayloadSchema, routeCacheTag, safeRedirectTarget, scopeCacheTag, signRevalidateBody };
|
|
1379
1269
|
//# sourceMappingURL=index.js.map
|
|
1380
1270
|
//# sourceMappingURL=index.js.map
|