@elytracms/next 0.0.100 → 0.0.101
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 +63 -5
- package/dist/index.js +57 -39
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -394,6 +394,14 @@ interface CanvasWrapContext extends CanvasRequestInfo {
|
|
|
394
394
|
* a serializable declaration).
|
|
395
395
|
*/
|
|
396
396
|
result: ResolvePageResult;
|
|
397
|
+
/**
|
|
398
|
+
* The request's locale — the one the page resolved and renders in (EC-720). A NAME for
|
|
399
|
+
* `result.tags.locale`, the value the route split from the URL once and that the page,
|
|
400
|
+
* its metadata, listings, assets and beacon already read: never a second derivation, so
|
|
401
|
+
* a wrapper's chrome strings and the content it wraps cannot disagree. Hand it to
|
|
402
|
+
* `elytra.loadGlobals({ locale })` for chrome the wrapper reads itself.
|
|
403
|
+
*/
|
|
404
|
+
locale: Locale;
|
|
397
405
|
}
|
|
398
406
|
/**
|
|
399
407
|
* EC-618 — what the route's `analytics` slot is told about the page it renders on: the
|
|
@@ -490,6 +498,13 @@ type CanvasPageOutcome = {
|
|
|
490
498
|
presentation?: DeliveryPresentation;
|
|
491
499
|
tags: CacheTags;
|
|
492
500
|
};
|
|
501
|
+
/**
|
|
502
|
+
* The outcome a page renders (EC-722): what `route.load(url)` returns once the route has
|
|
503
|
+
* answered a redirect or a not-found itself — a caller of it never branches on `kind`.
|
|
504
|
+
*/
|
|
505
|
+
type CanvasRenderOutcome = Extract<CanvasPageOutcome, {
|
|
506
|
+
kind: 'render';
|
|
507
|
+
}>;
|
|
493
508
|
/** Build the request path from a Next catch-all `slug` param. */
|
|
494
509
|
declare function pathFromSlug(slug: readonly string[] | undefined): string;
|
|
495
510
|
|
|
@@ -834,6 +849,31 @@ interface CanvasRoute {
|
|
|
834
849
|
applyCacheTags: (result: {
|
|
835
850
|
tags: CacheTags;
|
|
836
851
|
}) => void;
|
|
852
|
+
/**
|
|
853
|
+
* EC-722 — resolve one URL for a route of YOUR OWN and settle its status, before any
|
|
854
|
+
* `<Suspense>` boundary: `const outcome = await route.load('/blog/' + slug)`.
|
|
855
|
+
*
|
|
856
|
+
* It does what {@link Page} does before rendering, and nothing else: reads the request's
|
|
857
|
+
* perspective, resolves a published request through your
|
|
858
|
+
* {@link CanvasRouteOptions.published} cache function with the SAME key `Page` hands it
|
|
859
|
+
* (one entry; a draft resolves fresh), and answers a redirect with
|
|
860
|
+
* `redirect()`/`permanentRedirect()` and a missing document with `notFound()` itself —
|
|
861
|
+
* so what comes back is always a page to render.
|
|
862
|
+
*
|
|
863
|
+
* **Call it outside every `<Suspense>` boundary** (the route's page, not a suspended
|
|
864
|
+
* child). Inside one, the response status is already committed when the call settles:
|
|
865
|
+
* measured, a hand-written route that resolved and called `notFound()` inside
|
|
866
|
+
* `<Suspense>` answered a missing document with HTTP 200 (EC-567 V11). Outside, under
|
|
867
|
+
* Cache Components, it is legal because a published request is a cache read through
|
|
868
|
+
* `published` — the reason the catch-all page can stand outside a boundary too. Without
|
|
869
|
+
* `published`, a live-mode read outside `<Suspense>` fails `next build` under Cache
|
|
870
|
+
* Components (the same rule `Page` lives by); without Cache Components it is a plain
|
|
871
|
+
* dynamic read.
|
|
872
|
+
*
|
|
873
|
+
* Your route's own `generateMetadata` can delegate to {@link generateMetadata} with the
|
|
874
|
+
* catch-all slug of the same URL; `load` fires no `onTags` (the route's `Page` does).
|
|
875
|
+
*/
|
|
876
|
+
load: (url: string) => Promise<CanvasRenderOutcome>;
|
|
837
877
|
/**
|
|
838
878
|
* `export const generateStaticParams = route.generateStaticParams` — needed in the
|
|
839
879
|
* catch-all page file only when the HOST enables `cacheComponents` (that flag's
|
|
@@ -873,7 +913,8 @@ declare function requestPerspective(): Promise<Perspective>;
|
|
|
873
913
|
/**
|
|
874
914
|
* Create the canvas route for `app/[[...slug]]/page.tsx` — `{ Page, generateMetadata,
|
|
875
915
|
* generateStaticParams }` to export, plus `resolve` / `applyCacheTags` for the host's
|
|
876
|
-
* own cache function ({@link CanvasRouteOptions.published})
|
|
916
|
+
* own cache function ({@link CanvasRouteOptions.published}) and `load` for a route of the
|
|
917
|
+
* host's own (EC-722 — {@link CanvasRoute.load}).
|
|
877
918
|
*/
|
|
878
919
|
declare function createCanvasRoute(options: CanvasRouteOptions): CanvasRoute;
|
|
879
920
|
|
|
@@ -951,7 +992,7 @@ declare function seoMetadata(doc: Record<string, unknown> | null | undefined, ct
|
|
|
951
992
|
* page segment's `openGraph` object REPLACES the layout's whole `openGraph`, so a
|
|
952
993
|
* site-wide `type`, `siteName`, site image or `locale` declared once in the root
|
|
953
994
|
* layout never reached a canvas page, and both real sites hand-rolled around it
|
|
954
|
-
* differently (
|
|
995
|
+
* differently (a page hook on one, a post bypass on the other). This is the one
|
|
955
996
|
* merge, applied by the canvas route to whatever builds the page's metadata (the
|
|
956
997
|
* kit's default or the host's `metadata` option): every object-valued key the
|
|
957
998
|
* page sets (`openGraph`, `twitter`, `robots`, `alternates`, …) is merged one
|
|
@@ -1336,7 +1377,7 @@ interface ElytraImageProps {
|
|
|
1336
1377
|
quality?: number;
|
|
1337
1378
|
className?: string;
|
|
1338
1379
|
/**
|
|
1339
|
-
* Loading strategy forwarded to `next/image` (EC-428
|
|
1380
|
+
* Loading strategy forwarded to `next/image` (EC-428). `'eager'` opts an
|
|
1340
1381
|
* image out of lazy-loading without the preload `priority` implies. Next throws
|
|
1341
1382
|
* on `priority` + `loading='lazy'` together, so {@link ElytraImage} drops `lazy`
|
|
1342
1383
|
* when `priority` is set (priority wins) — delivery never crashes.
|
|
@@ -1597,6 +1638,12 @@ interface SiteGlobals {
|
|
|
1597
1638
|
interface ResolveGlobalsOptions {
|
|
1598
1639
|
/** Perspective of the chrome read. Default `'published'` (live is published-only). */
|
|
1599
1640
|
perspective?: Perspective;
|
|
1641
|
+
/**
|
|
1642
|
+
* The request's locale (EC-720). Default: the source's default locale. A locale the
|
|
1643
|
+
* project does not declare throws a located `unknown-locale` error — read silently, it
|
|
1644
|
+
* would serve every field from the default locale's fallback and look like a translation
|
|
1645
|
+
* gap rather than a wrong argument.
|
|
1646
|
+
*/
|
|
1600
1647
|
locale?: Locale;
|
|
1601
1648
|
conventions?: GlobalsConventions;
|
|
1602
1649
|
}
|
|
@@ -1830,6 +1877,16 @@ interface HostCanvasRouteOptions {
|
|
|
1830
1877
|
interface LoadGlobalsOptions {
|
|
1831
1878
|
/** Perspective of the chrome read. Default `'published'` (live is published-only). */
|
|
1832
1879
|
perspective?: Perspective;
|
|
1880
|
+
/**
|
|
1881
|
+
* The request's locale (EC-720) — the chrome's settings, menus and link paths are read in
|
|
1882
|
+
* it. Default: the project's default locale, which is every page's locale on a
|
|
1883
|
+
* single-locale site. On a multi-locale site pass the locale the page renders in: from a
|
|
1884
|
+
* layout in the catch-all segment, `resolveLocale({ pathname: pathFromSlug(slug) },
|
|
1885
|
+
* locales)` — the SAME split the catch-all resolves the page with — or a `wrap`
|
|
1886
|
+
* function's `ctx.locale`. A locale the project does not declare is an error, never a
|
|
1887
|
+
* silent read of the default.
|
|
1888
|
+
*/
|
|
1889
|
+
locale?: Locale;
|
|
1833
1890
|
}
|
|
1834
1891
|
/**
|
|
1835
1892
|
* Which world {@link ElytraHost.loadContent} reads from.
|
|
@@ -1920,7 +1977,8 @@ interface ElytraHost<Collections extends readonly CollectionDef[] = readonly Col
|
|
|
1920
1977
|
/**
|
|
1921
1978
|
* Load + resolve the site-chrome globals (settings singleton, navigation by
|
|
1922
1979
|
* slot alias, link/asset resolution — see `host-globals.ts`). One content
|
|
1923
|
-
* load per call; published perspective
|
|
1980
|
+
* load per call; published perspective and the project's default locale by
|
|
1981
|
+
* default — pass the request's `locale` on a multi-locale site (EC-720).
|
|
1924
1982
|
*
|
|
1925
1983
|
* An UNCACHED read, like {@link loadContent}: under `cacheComponents`, render the
|
|
1926
1984
|
* chrome that awaits it inside `<Suspense>` — and keep the canvas page OUTSIDE
|
|
@@ -2132,4 +2190,4 @@ declare function evaluatePreviewRequest(requestUrl: string | URL, expectedToken:
|
|
|
2132
2190
|
*/
|
|
2133
2191
|
declare const PACKAGE = "@elytracms/next";
|
|
2134
2192
|
|
|
2135
|
-
export { type AssetImageLoaderOptions, type BakedListing, type BotGateVerdict, CANVAS_VALIDATION_SLUG, type CanvasBeaconProps, type CanvasCacheKey, type CanvasContentRequest, type CanvasPageOutcome, CanvasRenderer, type CanvasRendererProps, type CanvasRequestInfo, type CanvasRoute, type CanvasRouteOptions, type CanvasRouteProps, type CanvasSitemapOptions, type CanvasSitemapResult, type CanvasWrapContext, type ContentSnapshot, type ContentSnapshotOptions, type ContentSource, type CreateCanvasSitemapOptions, type DeliveryPresentation, ELYTRA_HOST_ENV_KEYS, type ElytraContentMode, type ElytraHost, type ElytraHostEnv, type ElytraHostImageOptions, type ElytraHostOptions, ElytraImage, type ElytraImageAsset, type ElytraImageProps, type FixedWindowLimiter, type GlobalsConventions, type HostCanvasRouteOptions, type HostComponent, type HostComponents, type IngestBotGate, type IngestEnrich, type IngestEvaluation, type IngestRouteHandlers, type IngestRouteOptions, type LiveContentOptions, type LoadGlobalsOptions, type NextImageOptions, PACKAGE, type PreviewEvaluation, type PreviewRouteHandlers, type PreviewRouteOptions, type ResolveCanvasPageOptions, type ResolveGlobalsOptions, type ResolvedLink, type ResolvedNavEntry, type ResolvedNavLink, type RevalidateEvaluation, type RevalidateRouteHandlers, type RevalidateRouteOptions, type RevalidationProject, type SeoMetadataContext, type SiteGlobals, type SitemapSkippedRoute, type StaticContentData, assembleLiveSource, bodyItemsOf, canvasBeaconProps, canvasSitemapEntries, collectionCacheTag, createAssetImageLoader, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createFixedWindowLimiter, createIngestRoute, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defaultIngestClientKey, defineHostComponents, docCacheTag, elytraHostImage, evaluateIngestRequest, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed, isCrossOrigin, loadLiveContent, mergeCacheTags, mergeMetadataOverParent, nextCacheTags, openGraphLocale, pathFromSlug, projectSweepTag, readCappedBody, requestPerspective, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidationTags, routeCacheTag, safeRedirectTarget, scopeCacheTag, seoContextOf, seoMetadata, seoObjectOf, withNextImage };
|
|
2193
|
+
export { type AssetImageLoaderOptions, type BakedListing, type BotGateVerdict, CANVAS_VALIDATION_SLUG, type CanvasBeaconProps, type CanvasCacheKey, type CanvasContentRequest, type CanvasPageOutcome, type CanvasRenderOutcome, CanvasRenderer, type CanvasRendererProps, type CanvasRequestInfo, type CanvasRoute, type CanvasRouteOptions, type CanvasRouteProps, type CanvasSitemapOptions, type CanvasSitemapResult, type CanvasWrapContext, type ContentSnapshot, type ContentSnapshotOptions, type ContentSource, type CreateCanvasSitemapOptions, type DeliveryPresentation, ELYTRA_HOST_ENV_KEYS, type ElytraContentMode, type ElytraHost, type ElytraHostEnv, type ElytraHostImageOptions, type ElytraHostOptions, ElytraImage, type ElytraImageAsset, type ElytraImageProps, type FixedWindowLimiter, type GlobalsConventions, type HostCanvasRouteOptions, type HostComponent, type HostComponents, type IngestBotGate, type IngestEnrich, type IngestEvaluation, type IngestRouteHandlers, type IngestRouteOptions, type LiveContentOptions, type LoadGlobalsOptions, type NextImageOptions, PACKAGE, type PreviewEvaluation, type PreviewRouteHandlers, type PreviewRouteOptions, type ResolveCanvasPageOptions, type ResolveGlobalsOptions, type ResolvedLink, type ResolvedNavEntry, type ResolvedNavLink, type RevalidateEvaluation, type RevalidateRouteHandlers, type RevalidateRouteOptions, type RevalidationProject, type SeoMetadataContext, type SiteGlobals, type SitemapSkippedRoute, type StaticContentData, assembleLiveSource, bodyItemsOf, canvasBeaconProps, canvasSitemapEntries, collectionCacheTag, createAssetImageLoader, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createFixedWindowLimiter, createIngestRoute, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defaultIngestClientKey, defineHostComponents, docCacheTag, elytraHostImage, evaluateIngestRequest, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed, isCrossOrigin, loadLiveContent, mergeCacheTags, mergeMetadataOverParent, nextCacheTags, openGraphLocale, pathFromSlug, projectSweepTag, readCappedBody, requestPerspective, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidationTags, routeCacheTag, safeRedirectTarget, scopeCacheTag, seoContextOf, seoMetadata, seoObjectOf, withNextImage };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { registerComponents, createRenderContext, renderDocumentBodyItems, docum
|
|
|
2
2
|
import { isBlockSequenceValueShape } from '@elytracms/core/rich-text';
|
|
3
3
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
import { cacheTags, isDocumentHistory, assetWithoutUrlIssue, assetMetaDriftIssue, resolvedAsset, parseDeliveredDocuments, parseDeliveredRedirects, createContentClient, createContentContext } from '@elytracms/core/content';
|
|
5
|
-
import { DEFAULT_SEO_FIELD, parseLocaleConfig, documentKey, readLiveRedirects, SEO_SUBFIELDS,
|
|
5
|
+
import { DEFAULT_SEO_FIELD, parseLocaleConfig, documentKey, readLiveRedirects, SEO_SUBFIELDS, DRAFT_PERSPECTIVE, splitPath, localeUrlPath, variantOf, DRAFT_VARIANT, createRouter, splitLocalePath, deliverCompositionProps, presentationBodyFields, validateLocale } from '@elytracms/core/cms-core';
|
|
6
6
|
export { DRAFT_PERSPECTIVE, documentSchema, localeConfigSchema, localeUrlPath, parseLocaleConfig, redirectRecordSchema, resolveLocale, routeRecordSchema, splitLocalePath, textDirection, variantOf } from '@elytracms/core/cms-core';
|
|
7
7
|
import { assetMetaLens, assetMetaDrift, assetReadLocale, redirectRecordKind } from '@elytracms/core/persistence';
|
|
8
8
|
import { propFieldLookupOf } from '@elytracms/core/component-registry';
|
|
@@ -309,7 +309,8 @@ function canvasWrapContext(result, info) {
|
|
|
309
309
|
...info,
|
|
310
310
|
...collection !== void 0 ? { collection } : {},
|
|
311
311
|
document: result.document,
|
|
312
|
-
result
|
|
312
|
+
result,
|
|
313
|
+
locale: result.tags.locale
|
|
313
314
|
};
|
|
314
315
|
}
|
|
315
316
|
function canvasBeaconProps(result, info) {
|
|
@@ -442,10 +443,13 @@ function populatePageLinks(body, client, registry) {
|
|
|
442
443
|
}
|
|
443
444
|
return { links, docKeys: Object.keys(refs) };
|
|
444
445
|
}
|
|
445
|
-
|
|
446
|
+
function resolveRequestPage(source, url, perspective) {
|
|
446
447
|
const { locale, path } = splitLocalePath(url, source.locales);
|
|
447
448
|
const client = source.client({ perspective, locale });
|
|
448
|
-
|
|
449
|
+
return { locale, client, resolved: client.resolvePage(path) };
|
|
450
|
+
}
|
|
451
|
+
async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
452
|
+
const { locale, client, resolved } = resolveRequestPage(source, url, perspective);
|
|
449
453
|
if (resolved.status === "redirect" && resolved.redirect) {
|
|
450
454
|
return {
|
|
451
455
|
kind: "redirect",
|
|
@@ -626,41 +630,49 @@ function createCanvasRoute(options) {
|
|
|
626
630
|
if (perspective !== "published" || !options.published) return resolveFresh(url, perspective);
|
|
627
631
|
return options.published(keyFor(url));
|
|
628
632
|
};
|
|
629
|
-
const
|
|
630
|
-
const { slug } = await props.params;
|
|
631
|
-
const url = pathFromSlug(slug);
|
|
632
|
-
if (url === CANVAS_VALIDATION_PATH) return notFound();
|
|
633
|
-
const perspective = await requestPerspective();
|
|
634
|
-
const outcome = await loadOutcome(url, perspective);
|
|
635
|
-
options.onTags?.(outcome.tags, { url, perspective });
|
|
633
|
+
const settle = (outcome) => {
|
|
636
634
|
switch (outcome.kind) {
|
|
637
635
|
case "redirect":
|
|
638
636
|
return outcome.permanent ? permanentRedirect(outcome.target) : redirect(outcome.target);
|
|
639
637
|
case "not-found":
|
|
640
638
|
return notFound();
|
|
641
|
-
case "render":
|
|
642
|
-
|
|
643
|
-
CanvasRenderer,
|
|
644
|
-
{
|
|
645
|
-
result: outcome.result,
|
|
646
|
-
components: options.components,
|
|
647
|
-
assets: outcome.assets,
|
|
648
|
-
relations: outcome.relations,
|
|
649
|
-
listings: outcome.listings,
|
|
650
|
-
links: outcome.links,
|
|
651
|
-
presentation: outcome.presentation
|
|
652
|
-
}
|
|
653
|
-
);
|
|
654
|
-
const page = options.wrap ? options.wrap(rendered, canvasWrapContext(outcome.result, { url, perspective })) : rendered;
|
|
655
|
-
const Beacon = options.analytics;
|
|
656
|
-
if (!Beacon || perspective !== "published") return page;
|
|
657
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
658
|
-
page,
|
|
659
|
-
/* @__PURE__ */ jsx(Beacon, { ...canvasBeaconProps(outcome.result, { url}) })
|
|
660
|
-
] });
|
|
661
|
-
}
|
|
639
|
+
case "render":
|
|
640
|
+
return outcome;
|
|
662
641
|
}
|
|
663
642
|
};
|
|
643
|
+
const load = async (url) => {
|
|
644
|
+
if (url === CANVAS_VALIDATION_PATH) return notFound();
|
|
645
|
+
const perspective = await requestPerspective();
|
|
646
|
+
return settle(await loadOutcome(url, perspective));
|
|
647
|
+
};
|
|
648
|
+
const Page = async (props) => {
|
|
649
|
+
const { slug } = await props.params;
|
|
650
|
+
const url = pathFromSlug(slug);
|
|
651
|
+
if (url === CANVAS_VALIDATION_PATH) return notFound();
|
|
652
|
+
const perspective = await requestPerspective();
|
|
653
|
+
const loaded = await loadOutcome(url, perspective);
|
|
654
|
+
options.onTags?.(loaded.tags, { url, perspective });
|
|
655
|
+
const outcome = settle(loaded);
|
|
656
|
+
const rendered = /* @__PURE__ */ jsx(
|
|
657
|
+
CanvasRenderer,
|
|
658
|
+
{
|
|
659
|
+
result: outcome.result,
|
|
660
|
+
components: options.components,
|
|
661
|
+
assets: outcome.assets,
|
|
662
|
+
relations: outcome.relations,
|
|
663
|
+
listings: outcome.listings,
|
|
664
|
+
links: outcome.links,
|
|
665
|
+
presentation: outcome.presentation
|
|
666
|
+
}
|
|
667
|
+
);
|
|
668
|
+
const page = options.wrap ? options.wrap(rendered, canvasWrapContext(outcome.result, { url, perspective })) : rendered;
|
|
669
|
+
const Beacon = options.analytics;
|
|
670
|
+
if (!Beacon || perspective !== "published") return page;
|
|
671
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
672
|
+
page,
|
|
673
|
+
/* @__PURE__ */ jsx(Beacon, { ...canvasBeaconProps(outcome.result, { url}) })
|
|
674
|
+
] });
|
|
675
|
+
};
|
|
664
676
|
const pageMetadata = async (props) => {
|
|
665
677
|
const { slug } = await props.params;
|
|
666
678
|
const url = pathFromSlug(slug);
|
|
@@ -683,7 +695,7 @@ function createCanvasRoute(options) {
|
|
|
683
695
|
const generateStaticParams = async () => [
|
|
684
696
|
{ slug: [...CANVAS_VALIDATION_SLUG] }
|
|
685
697
|
];
|
|
686
|
-
return { Page, generateMetadata, resolve, applyCacheTags, generateStaticParams };
|
|
698
|
+
return { Page, generateMetadata, resolve, applyCacheTags, load, generateStaticParams };
|
|
687
699
|
}
|
|
688
700
|
function originOf(baseUrl) {
|
|
689
701
|
return baseUrl.replace(/\/+$/, "");
|
|
@@ -1189,9 +1201,14 @@ async function loadLiveContent(options, perspective) {
|
|
|
1189
1201
|
}
|
|
1190
1202
|
return assembleLiveSource(payload, options, perspective);
|
|
1191
1203
|
}
|
|
1192
|
-
|
|
1193
|
-
// src/host-globals.ts
|
|
1194
1204
|
var DEFAULT_ITEMS_FIELDS = ["items", "links"];
|
|
1205
|
+
function assertDeclaredLocale(source, locale) {
|
|
1206
|
+
const [issue] = validateLocale(source.locales, locale);
|
|
1207
|
+
if (!issue) return;
|
|
1208
|
+
throw new Error(
|
|
1209
|
+
`Elytra chrome globals: ${issue.code} at ${issue.path.join(".")} \u2014 the locale "${locale}" is not one of this project's locales (it declares ${source.locales.locales.join(", ")}). Pass the locale the page renders in \u2014 resolveLocale({ pathname }, locales) splits it from the URL exactly as the catch-all does \u2014 or omit it for the default locale.`
|
|
1210
|
+
);
|
|
1211
|
+
}
|
|
1195
1212
|
function record(value) {
|
|
1196
1213
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
1197
1214
|
}
|
|
@@ -1207,7 +1224,8 @@ function resolveGlobals(source, options = {}) {
|
|
|
1207
1224
|
const settingsCollection = conventions.settingsCollection ?? "settings";
|
|
1208
1225
|
const navigationCollection = conventions.navigationCollection ?? "navigation";
|
|
1209
1226
|
const itemsFields = conventions.navigationItemsFields ?? DEFAULT_ITEMS_FIELDS;
|
|
1210
|
-
|
|
1227
|
+
if (options.locale !== void 0) assertDeclaredLocale(source, options.locale);
|
|
1228
|
+
const client = source.client({ perspective, ...options.locale !== void 0 ? { locale: options.locale } : {} });
|
|
1211
1229
|
const assets = source.assets?.(options.locale) ?? [];
|
|
1212
1230
|
const assetById = new Map(assets.map((asset) => [asset.id, asset]));
|
|
1213
1231
|
const listDocs = (collection) => {
|
|
@@ -1445,6 +1463,8 @@ function createElytraHost(options) {
|
|
|
1445
1463
|
const source = await loadContent({ perspective });
|
|
1446
1464
|
return resolveGlobals(source, {
|
|
1447
1465
|
perspective,
|
|
1466
|
+
// EC-720: the request's locale, judged against the project's locales by the core.
|
|
1467
|
+
...globalsOptions.locale !== void 0 ? { locale: globalsOptions.locale } : {},
|
|
1448
1468
|
...globals ? { conventions: globals } : {}
|
|
1449
1469
|
});
|
|
1450
1470
|
};
|
|
@@ -1481,9 +1501,7 @@ function createElytraHost(options) {
|
|
|
1481
1501
|
const pageOpensFullBleed = async (slug) => {
|
|
1482
1502
|
const perspective = await requestPerspective();
|
|
1483
1503
|
const source = await loadContent({ perspective });
|
|
1484
|
-
const {
|
|
1485
|
-
const client = source.client({ perspective, locale });
|
|
1486
|
-
const resolved = client.resolvePage(path);
|
|
1504
|
+
const { resolved } = resolveRequestPage(source, pathFromSlug(slug), perspective);
|
|
1487
1505
|
return firstBlockFullBleed(resolved.document, components.registry);
|
|
1488
1506
|
};
|
|
1489
1507
|
const frontendUrl = projectFrontendUrl(project);
|