@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.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { ComponentType, ReactNode } from 'react';
|
|
2
2
|
import { ComponentRegistry, ComponentIssue, ComponentManifest } from '@elytracms/core/component-registry';
|
|
3
3
|
export { ComponentManifest, PropField, SlotSpec, defineComponent } from '@elytracms/core/component-registry';
|
|
4
|
-
import { ComponentImplementations,
|
|
4
|
+
import { ComponentImplementations, RelationTarget, DocumentBodyItem } from '@elytracms/core/runtime-renderer';
|
|
5
5
|
export { ComponentImplementations, RenderAsset } from '@elytracms/core/runtime-renderer';
|
|
6
|
+
import { HostComponentEntry } from '@elytracms/core/studio-core';
|
|
6
7
|
import { ResolvePageResult, ResolvedAsset, Perspective, ContentClient, CacheTags, ContentDocumentSource, ResolvedDocument } from '@elytracms/core/content';
|
|
7
8
|
export { Perspective } from '@elytracms/core/content';
|
|
8
9
|
import { LocaleConfig, Locale, RouteRecord, CollectionDef, RedirectRecord } from '@elytracms/core/cms-core';
|
|
9
|
-
export { CmsDocument, CollectionDef, FieldDef, Locale, LocaleConfig, LocaleUrlPath, RedirectRecord, RouteRecord, documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, redirectRecordSchema, routeRecordSchema, splitLocalePath } from '@elytracms/core/cms-core';
|
|
10
|
-
import { ComponentNode } from '@elytracms/core/project-graph';
|
|
11
|
-
export { ComponentNode } from '@elytracms/core/project-graph';
|
|
10
|
+
export { CmsDocument, CollectionDef, FieldDef, Locale, LocaleConfig, LocaleRequest, LocaleStrategy, LocaleUrlPath, RedirectRecord, RouteRecord, documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, redirectRecordSchema, resolveLocale, routeRecordSchema, splitLocalePath, textDirection } from '@elytracms/core/cms-core';
|
|
12
11
|
import { AssetRecord, PersistenceAdapter } from '@elytracms/core/persistence';
|
|
13
12
|
export { AssetRecord } from '@elytracms/core/persistence';
|
|
14
13
|
import { Metadata, MetadataRoute } from 'next';
|
|
@@ -16,12 +15,19 @@ import { z } from 'zod';
|
|
|
16
15
|
export { z } from 'zod';
|
|
17
16
|
import { ImageLoader } from 'next/image';
|
|
18
17
|
import { HostImageRenderer } from './host-image.js';
|
|
19
|
-
|
|
18
|
+
export { ComponentNode } from '@elytracms/core/project-graph';
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* One host-repo component: the manifest the builder edits against plus the
|
|
23
22
|
* real React implementation that renders it (vision AD-2 — project components
|
|
24
23
|
* are real code in the host repo, never generated).
|
|
24
|
+
*
|
|
25
|
+
* This is the STRICT shape — the one a hand-authored component module should
|
|
26
|
+
* export (`export const heroComponent: HostComponent = …`), so the compiler
|
|
27
|
+
* checks the implementation where it is written. It is assignable to the
|
|
28
|
+
* config's {@link HostComponentEntry}, which is what {@link defineHostComponents}
|
|
29
|
+
* accepts, so both hand-built lists and the config's own list register through
|
|
30
|
+
* the one signature (EC-541).
|
|
25
31
|
*/
|
|
26
32
|
interface HostComponent {
|
|
27
33
|
manifest: ComponentManifest;
|
|
@@ -36,7 +42,11 @@ interface HostComponent {
|
|
|
36
42
|
interface HostComponents {
|
|
37
43
|
registry: ComponentRegistry;
|
|
38
44
|
implementations: ComponentImplementations;
|
|
39
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Structural registration issues: the registry's own (duplicate ids, invalid
|
|
47
|
+
* namespaces, …) plus `invalid-implementation` for an entry whose
|
|
48
|
+
* `implementation` is not a React component (EC-541).
|
|
49
|
+
*/
|
|
40
50
|
issues: readonly ComponentIssue[];
|
|
41
51
|
}
|
|
42
52
|
interface DefineHostComponentsOptions {
|
|
@@ -53,73 +63,30 @@ interface DefineHostComponentsOptions {
|
|
|
53
63
|
* default. A host implementation registered under a primitive id replaces the
|
|
54
64
|
* default implementation (the manifest of the first registration wins, which
|
|
55
65
|
* is the primitive's — by design, so prop schemas stay canonical).
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*/
|
|
79
|
-
declare
|
|
80
|
-
/**
|
|
81
|
-
* Explicit issue payload for a source whose stored query was REJECTED at
|
|
82
|
-
* delivery (EC-177 gap 3) — e.g. a sort/filter field that is no longer
|
|
83
|
-
* filterable in the live schema. Materialization stores this instead of a
|
|
84
|
-
* silently-absent payload; `createBindingResolver` throws on it, which the
|
|
85
|
-
* renderer converts into its visible per-node render-error fallback (EC-015).
|
|
86
|
-
* Validation principle: a broken stored query is a visible state, never an
|
|
87
|
-
* empty section.
|
|
88
|
-
*/
|
|
89
|
-
interface SourcePayloadError {
|
|
90
|
-
[SOURCE_PAYLOAD_ERROR_KEY]: true;
|
|
91
|
-
sourceId: string;
|
|
92
|
-
/** Human-readable messages of the structured query errors. */
|
|
93
|
-
messages: string[];
|
|
94
|
-
}
|
|
95
|
-
/** Build the explicit issue payload for one failed source query. */
|
|
96
|
-
declare function sourcePayloadError(sourceId: string, messages: readonly string[]): SourcePayloadError;
|
|
97
|
-
/** `true` when a payload value is an explicit {@link SourcePayloadError}. */
|
|
98
|
-
declare function isSourcePayloadError(value: unknown): value is SourcePayloadError;
|
|
99
|
-
/**
|
|
100
|
-
* Resolve a JSON Pointer token within a payload value. Numeric segments index
|
|
101
|
-
* arrays; string segments index plain objects. Any miss (unknown key,
|
|
102
|
-
* out-of-range index, traversal through a primitive) yields `undefined`.
|
|
103
|
-
*/
|
|
104
|
-
declare function resolvePayloadToken(payload: unknown, token: string): unknown;
|
|
105
|
-
/**
|
|
106
|
-
* Create the renderer's `ResolveBinding` over a payload map. Mode semantics
|
|
107
|
-
* (brief §4.6, uniform binding model):
|
|
108
|
-
*
|
|
109
|
-
* - `value` / `object` / `condition` — the value at the token within the
|
|
110
|
-
* payload named by `sourceId`.
|
|
111
|
-
* - `spread` — same lookup; the renderer spreads the resulting object.
|
|
112
|
-
* - `repeaterItem` — the token resolves against the active repeater item,
|
|
113
|
-
* not the root payload.
|
|
114
|
-
*
|
|
115
|
-
* Total for data misses: an unknown `sourceId` or missing path resolves to
|
|
116
|
-
* `undefined` — the renderer (EC-015) degrades visibly instead of crashing.
|
|
117
|
-
* An explicit {@link SourcePayloadError} payload (a REJECTED stored query, not
|
|
118
|
-
* merely missing data) throws instead: the renderer catches per node and
|
|
119
|
-
* renders its visible render-error fallback with the query error message;
|
|
120
|
-
* conditions treat the throw as `false` (the node hides) — never a page crash.
|
|
121
|
-
*/
|
|
122
|
-
declare function createBindingResolver(payloads: BindingPayloads): ResolveBinding;
|
|
66
|
+
*
|
|
67
|
+
* Accepts the CONFIG's entry shape (`implementation: unknown`) rather than the
|
|
68
|
+
* strict {@link HostComponent}: the config declares implementations opaquely,
|
|
69
|
+
* and EC-539 made `createElytraHost({ ...site })` the contract, so a
|
|
70
|
+
* compile-time check at this seam was already gone for the recommended path.
|
|
71
|
+
* The check is RUNTIME instead (EC-541), through core's one registration step
|
|
72
|
+
* `registerImplementations` (EC-555 — the studio registry and the preview
|
|
73
|
+
* harness call the same one): a value that is not a component is
|
|
74
|
+
* recorded as an `invalid-implementation` issue naming the component id and
|
|
75
|
+
* the received kind, and is NOT put into `implementations` — so the renderer
|
|
76
|
+
* takes its missing-component path (a visible EC-015 fallback) instead of
|
|
77
|
+
* crashing the server render on `createElement` ("Element type is invalid")
|
|
78
|
+
* or, for a string, silently rendering an HTML tag. The manifest still
|
|
79
|
+
* registers, so the registry's own issues (duplicate id, invalid id) for that
|
|
80
|
+
* entry are reported alongside.
|
|
81
|
+
*
|
|
82
|
+
* One consequence of the `unknown` parameter: an INLINE
|
|
83
|
+
* `implementation: (props) => …` literal no longer gets `props` contextually
|
|
84
|
+
* typed (it is `noImplicitAny` under strict). Annotate the parameter, or
|
|
85
|
+
* author the entry as a {@link HostComponent} — which is the documented shape
|
|
86
|
+
* anyway. (An overload pair was tried and does not restore it: TypeScript
|
|
87
|
+
* resolves the context-sensitive literal against the wider overload.)
|
|
88
|
+
*/
|
|
89
|
+
declare function defineHostComponents(components?: readonly HostComponentEntry[], options?: DefineHostComponentsOptions): HostComponents;
|
|
123
90
|
|
|
124
91
|
/**
|
|
125
92
|
* `<CanvasRenderer />` (EC-144, vision AD-1): an async React Server Component
|
|
@@ -134,13 +101,6 @@ interface CanvasRendererProps {
|
|
|
134
101
|
result: ResolvePageResult;
|
|
135
102
|
/** Host component surface from `defineHostComponents`. */
|
|
136
103
|
components: HostComponents;
|
|
137
|
-
/**
|
|
138
|
-
* Binding payloads keyed by `sourceId`. Defaults to
|
|
139
|
-
* `{ document, params }` derived from the result.
|
|
140
|
-
*/
|
|
141
|
-
payloads?: BindingPayloads;
|
|
142
|
-
/** Full custom binding resolver — overrides `payloads` when provided. */
|
|
143
|
-
resolveBinding?: ResolveBinding;
|
|
144
104
|
/**
|
|
145
105
|
* Delivery-shaped assets the page may reference (EC-195, from the render
|
|
146
106
|
* outcome). An `asset`-typed Image prop resolves through these to a url +
|
|
@@ -194,8 +154,6 @@ interface DeliveryPresentation {
|
|
|
194
154
|
/** Field names whose values form the body, in render order. */
|
|
195
155
|
body?: readonly string[];
|
|
196
156
|
}
|
|
197
|
-
/** Default payloads: the route-bound document and the dynamic route params. */
|
|
198
|
-
declare function defaultBindingPayloads(result: ResolvePageResult): BindingPayloads;
|
|
199
157
|
/**
|
|
200
158
|
* Render a resolved page server-side. Async so hosts can compose it like any
|
|
201
159
|
* other RSC; resolution itself is synchronous (the content was prefetched by
|
|
@@ -221,22 +179,10 @@ declare function bodyItemsOf(document: Record<string, unknown> | null | undefine
|
|
|
221
179
|
*
|
|
222
180
|
* Accessors are synchronous over a prefetched `ContentLookup` (vision AD-4);
|
|
223
181
|
* any fetching happens when the source is loaded, before clients are minted.
|
|
182
|
+
*
|
|
183
|
+
* EC-574: the `CanvasDataSource` shape and the `sources` member (the data-binding
|
|
184
|
+
* subsystem's per-section query definitions, EC-166) are gone with that subsystem.
|
|
224
185
|
*/
|
|
225
|
-
/**
|
|
226
|
-
* One data-source definition the published graph's bindings reference
|
|
227
|
-
* (EC-166 delivery): the structural shape of an `@elytracms/core/data-binding`
|
|
228
|
-
* `DataSource`, declared here so the embedded runtime stays free of
|
|
229
|
-
* builder-side packages. Only `cms`-kind sources with the EC-166 per-scope id
|
|
230
|
-
* prefixes (`cms.section.<nodeId>` / `cms.template.<pageId>`) participate in
|
|
231
|
-
* automatic payload materialization; everything else is ignored.
|
|
232
|
-
*/
|
|
233
|
-
interface CanvasDataSource {
|
|
234
|
-
kind: string;
|
|
235
|
-
id: string;
|
|
236
|
-
label?: string;
|
|
237
|
-
/** Kind-specific config; cms query configs parse via `@elytracms/core/content`. */
|
|
238
|
-
config?: unknown;
|
|
239
|
-
}
|
|
240
186
|
interface ContentSource {
|
|
241
187
|
/** The project's locale configuration (default + supported set, EC-018). */
|
|
242
188
|
readonly locales: LocaleConfig;
|
|
@@ -267,15 +213,6 @@ interface ContentSource {
|
|
|
267
213
|
* picker decides, exactly as before.
|
|
268
214
|
*/
|
|
269
215
|
readonly collections?: readonly CollectionDef[];
|
|
270
|
-
/**
|
|
271
|
-
* Data-source definitions the graph's bindings reference (EC-166 delivery,
|
|
272
|
-
* additive). When present, the route helper materializes per-section list
|
|
273
|
-
* sources automatically by replaying their stored where/sort/limit through
|
|
274
|
-
* `listDocuments` — see `materializeSourcePayloads`. Optional so existing
|
|
275
|
-
* custom sources stay valid; absent definitions degrade to unresolved
|
|
276
|
-
* bindings (the renderer's visible fallbacks), never a crash.
|
|
277
|
-
*/
|
|
278
|
-
readonly sources?: readonly CanvasDataSource[];
|
|
279
216
|
/**
|
|
280
217
|
* The project's delivery-shaped assets (EC-195, additive). Lets the route
|
|
281
218
|
* helper bake the assets a page may reference into the (serializable) render
|
|
@@ -295,60 +232,6 @@ interface ContentSource {
|
|
|
295
232
|
*/
|
|
296
233
|
declare function mergeCacheTags(first: CacheTags, ...rest: readonly CacheTags[]): CacheTags;
|
|
297
234
|
|
|
298
|
-
/**
|
|
299
|
-
* Automatic payload materialization for EC-166 repeating sections — the
|
|
300
|
-
* delivery half of the builder's collection-driven LAYOUTS (EC-187: layouts
|
|
301
|
-
* are the only graph trees that can bind section sources now). A published
|
|
302
|
-
* layout may carry bindings against per-scope CMS sources; the renderer needs
|
|
303
|
-
* the source PAYLOADS:
|
|
304
|
-
*
|
|
305
|
-
* - **Repeating sections** (`cms.section.<nodeId>`): the stored source config
|
|
306
|
-
* carries the closed AD-3 query. For every section source a referenced
|
|
307
|
-
* layout tree actually binds, the stored where/sort/limit replays through
|
|
308
|
-
* the request client's `listDocuments` — published perspective and ambient
|
|
309
|
-
* locale come from the client itself. The list result's `CacheTags` (the
|
|
310
|
-
* fetch-time doc tags of what was actually returned plus the coarse
|
|
311
|
-
* collection tag — the EC-146 contract) are surfaced so the route helper
|
|
312
|
-
* merges them into the request tag set.
|
|
313
|
-
*
|
|
314
|
-
* The `cms.template.<pageId>` "current document" source is RETIRED (EC-187):
|
|
315
|
-
* there is no template page, and a routed page document's `body` uses static
|
|
316
|
-
* props (v1). A collection detail route's document is read by the dev route
|
|
317
|
-
* component directly via the route's `document` ref.
|
|
318
|
-
*
|
|
319
|
-
* Everything degrades visibly, never a crash:
|
|
320
|
-
*
|
|
321
|
-
* - a missing source definition, a non-cms kind, or a malformed config leaves
|
|
322
|
-
* the payload absent, so the binding resolves to `undefined` and the
|
|
323
|
-
* renderer shows its EC-015 fallback (an empty list renders the section's
|
|
324
|
-
* empty state);
|
|
325
|
-
* - a structured query error (the stored query was REJECTED at delivery, e.g.
|
|
326
|
-
* a sort field no longer filterable in the live schema) stores an explicit
|
|
327
|
-
* {@link sourcePayloadError} payload instead — the binding resolver throws
|
|
328
|
-
* on it and the renderer shows its visible per-node render-error fallback,
|
|
329
|
-
* not a silently empty section (EC-177 gap 3).
|
|
330
|
-
*/
|
|
331
|
-
/** Collect every binding `sourceId` referenced in a node tree (props, conditions, slots). */
|
|
332
|
-
declare function collectBindingSourceIds(node: ComponentNode, into?: Set<string>): Set<string>;
|
|
333
|
-
interface MaterializeSourcePayloadsInput {
|
|
334
|
-
/** Accessor client bound to this request's perspective + locale. */
|
|
335
|
-
client: ContentClient;
|
|
336
|
-
result: ResolvePageResult;
|
|
337
|
-
/** Source definitions from the `ContentSource` (absent ones simply skip). */
|
|
338
|
-
sources: readonly CanvasDataSource[];
|
|
339
|
-
}
|
|
340
|
-
interface MaterializedSourcePayloads {
|
|
341
|
-
payloads: BindingPayloads;
|
|
342
|
-
/** `CacheTags` of every accessor call made here (one entry per section list). */
|
|
343
|
-
tags: CacheTags[];
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Materialize the EC-166 source payloads for one resolved page. Pure over the
|
|
347
|
-
* prefetched source — `listDocuments` is synchronous; tags are returned (not
|
|
348
|
-
* applied) so the caller owns the merge.
|
|
349
|
-
*/
|
|
350
|
-
declare function materializeSourcePayloads(input: MaterializeSourcePayloadsInput): MaterializedSourcePayloads;
|
|
351
|
-
|
|
352
235
|
/**
|
|
353
236
|
* Bridge from a `PersistenceAdapter` to the synchronous `ContentLookup` the
|
|
354
237
|
* accessors (EC-143) read through: prefetch the project's collections,
|
|
@@ -379,12 +262,6 @@ interface ContentSnapshotOptions {
|
|
|
379
262
|
* config declares.
|
|
380
263
|
*/
|
|
381
264
|
locales: LocaleConfig;
|
|
382
|
-
/**
|
|
383
|
-
* Data-source definitions the graph's bindings reference (EC-166): section
|
|
384
|
-
* sources (`cms.section.<nodeId>`) carry their stored where/sort/limit, and
|
|
385
|
-
* the route helper materializes their payloads automatically.
|
|
386
|
-
*/
|
|
387
|
-
sources?: readonly CanvasDataSource[];
|
|
388
265
|
}
|
|
389
266
|
interface ContentSnapshot extends ContentSource {
|
|
390
267
|
readonly projectId: string;
|
|
@@ -419,11 +296,6 @@ interface StaticContentData {
|
|
|
419
296
|
* explicit unresolved-placeholder scheme (never a silent empty string).
|
|
420
297
|
*/
|
|
421
298
|
assetUrl?: (asset: AssetRecord) => string;
|
|
422
|
-
/**
|
|
423
|
-
* Data-source definitions section bindings reference (EC-166 delivery).
|
|
424
|
-
* Absent definitions degrade to unresolved bindings, never a crash.
|
|
425
|
-
*/
|
|
426
|
-
sources?: readonly CanvasDataSource[];
|
|
427
299
|
}
|
|
428
300
|
|
|
429
301
|
/**
|
|
@@ -444,8 +316,9 @@ declare function createContentSnapshot(adapter: PersistenceAdapter, projectId: s
|
|
|
444
316
|
|
|
445
317
|
/**
|
|
446
318
|
* The pure half of the catch-all route helper (EC-144): URL → outcome, with
|
|
447
|
-
* no Next.js imports — so redirects, 404s, locale handling,
|
|
448
|
-
* and tag merging are all unit-testable as plain
|
|
319
|
+
* no Next.js imports — so redirects, 404s, locale handling, asset/relation/
|
|
320
|
+
* listing/link baking, and tag merging are all unit-testable as plain
|
|
321
|
+
* functions. `route.tsx` maps
|
|
449
322
|
* each outcome onto `redirect()` / `permanentRedirect()` / `notFound()` /
|
|
450
323
|
* `<CanvasRenderer />`.
|
|
451
324
|
*/
|
|
@@ -486,27 +359,6 @@ interface CanvasWrapContext extends CanvasRequestInfo {
|
|
|
486
359
|
*/
|
|
487
360
|
result: ResolvePageResult;
|
|
488
361
|
}
|
|
489
|
-
/** What the host's payload factory sees for one request. */
|
|
490
|
-
interface CanvasPayloadContext {
|
|
491
|
-
/** Accessor client bound to this request's perspective + locale. */
|
|
492
|
-
client: ContentClient;
|
|
493
|
-
result: ResolvePageResult;
|
|
494
|
-
perspective: Perspective;
|
|
495
|
-
/** The normalized request path (locale prefix stripped). */
|
|
496
|
-
path: string;
|
|
497
|
-
params: Record<string, string>;
|
|
498
|
-
/**
|
|
499
|
-
* Register the `CacheTags` of any extra accessor call this factory makes
|
|
500
|
-
* (e.g. `listDocuments`) so they join the request's merged tag set — the
|
|
501
|
-
* EC-146 invalidation hook sees everything the request actually read.
|
|
502
|
-
*/
|
|
503
|
-
addTags(tags: CacheTags): void;
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Builds the binding payloads for a page render. The defaults
|
|
507
|
-
* (`document`, `params`) are always present; factory entries win on conflict.
|
|
508
|
-
*/
|
|
509
|
-
type CanvasPayloadsFactory = (ctx: CanvasPayloadContext) => BindingPayloads | Promise<BindingPayloads>;
|
|
510
362
|
type CanvasPageOutcome = {
|
|
511
363
|
kind: 'redirect';
|
|
512
364
|
target: string;
|
|
@@ -518,7 +370,6 @@ type CanvasPageOutcome = {
|
|
|
518
370
|
} | {
|
|
519
371
|
kind: 'render';
|
|
520
372
|
result: ResolvePageResult;
|
|
521
|
-
payloads: BindingPayloads;
|
|
522
373
|
/**
|
|
523
374
|
* The delivery-shaped assets the page may reference (EC-195). Baked into
|
|
524
375
|
* the outcome (serializable) so the renderer resolves `asset`-typed Image
|
|
@@ -572,7 +423,6 @@ type CanvasPageOutcome = {
|
|
|
572
423
|
declare function pathFromSlug(slug: readonly string[] | undefined): string;
|
|
573
424
|
|
|
574
425
|
interface ResolveCanvasPageOptions {
|
|
575
|
-
payloads?: CanvasPayloadsFactory;
|
|
576
426
|
/**
|
|
577
427
|
* Component registry (EC-205): when provided, the baked {@link CanvasPageOutcome}
|
|
578
428
|
* `assets` are PAGE-SCOPED to exactly the asset ids this page's composition +
|
|
@@ -598,6 +448,13 @@ interface CanvasCacheOptions {
|
|
|
598
448
|
* Omit only when the emitter also emits unscoped tags (see `cache.ts`).
|
|
599
449
|
*/
|
|
600
450
|
scope?: string;
|
|
451
|
+
/**
|
|
452
|
+
* Which content world `loadContent` reads — the delivery kit passes its
|
|
453
|
+
* `contentMode` (`'live' | 'fallback' | 'empty'`), so entries written in one
|
|
454
|
+
* world can never be served in another (EC-543, see `canvasCacheKey`). A host
|
|
455
|
+
* driving this helper directly with a single world may omit it.
|
|
456
|
+
*/
|
|
457
|
+
mode?: string;
|
|
601
458
|
}
|
|
602
459
|
/**
|
|
603
460
|
* What the route helper tells the content loader about the request it is
|
|
@@ -624,22 +481,18 @@ interface CanvasRouteOptions {
|
|
|
624
481
|
loadContent: (request: CanvasContentRequest) => Promise<ContentSource>;
|
|
625
482
|
/** Host component surface from `defineHostComponents`. */
|
|
626
483
|
components: HostComponents;
|
|
627
|
-
/** Extra binding payloads per request (e.g. `listDocuments` for a list page). */
|
|
628
|
-
payloads?: CanvasPayloadsFactory;
|
|
629
484
|
/**
|
|
630
485
|
* EC-146 instant publish: cache the published-perspective resolution in
|
|
631
486
|
* Next's data cache (`unstable_cache`), tagged with the response's own
|
|
632
487
|
* fetch-time tags, invalidated by the `/api/revalidate` webhook. Draft mode
|
|
633
488
|
* always bypasses this cache entirely. Tag-driven only — no time-based
|
|
634
|
-
* revalidation (the AD-5 model). Cached values are JSON-serialized
|
|
635
|
-
* payload factories must return plain data on the cached path.
|
|
489
|
+
* revalidation (the AD-5 model). Cached values are JSON-serialized plain data.
|
|
636
490
|
*/
|
|
637
491
|
cache?: CanvasCacheOptions;
|
|
638
492
|
/**
|
|
639
493
|
* EC-146 hook: receives the merged `CacheTags` of everything this request
|
|
640
|
-
* read (the `resolvePage` tags plus
|
|
641
|
-
*
|
|
642
|
-
* the run that wrote the entry.
|
|
494
|
+
* read (the `resolvePage` tags plus the baked relations/listings/links). On a
|
|
495
|
+
* cache hit these are the stored tags of the run that wrote the entry.
|
|
643
496
|
*/
|
|
644
497
|
onTags?: (tags: CacheTags, info: CanvasRequestInfo) => void;
|
|
645
498
|
/** Override the generated `<head>` metadata for a resolved page. */
|
|
@@ -1411,7 +1264,9 @@ declare function createPreviewRoute(options: PreviewRouteOptions): PreviewRouteH
|
|
|
1411
1264
|
/**
|
|
1412
1265
|
* Create the preview-disable route handler (e.g.
|
|
1413
1266
|
* `app/api/preview/disable/route.ts`). Disabling needs no token — it only
|
|
1414
|
-
* ever reduces visibility back to the published perspective.
|
|
1267
|
+
* ever reduces visibility back to the published perspective. The `redirect`
|
|
1268
|
+
* target passes the same same-site check as the enable route; an off-site one
|
|
1269
|
+
* redirects to `/` instead.
|
|
1415
1270
|
*/
|
|
1416
1271
|
declare function createPreviewDisableRoute(): PreviewRouteHandlers;
|
|
1417
1272
|
|
|
@@ -1503,13 +1358,16 @@ interface ElytraHostOptions {
|
|
|
1503
1358
|
* / `WorkspaceProjectEntry` annotation did not. Both production consumers hit
|
|
1504
1359
|
* exactly that and each carried one hand-restated `components` line (EC-539).
|
|
1505
1360
|
*
|
|
1506
|
-
* What
|
|
1507
|
-
*
|
|
1508
|
-
* component
|
|
1509
|
-
*
|
|
1510
|
-
*
|
|
1511
|
-
*
|
|
1512
|
-
*
|
|
1361
|
+
* What the widening costs, and where it is paid (EC-541): a list passed HERE
|
|
1362
|
+
* gets no compile-time check that each `implementation` is really a
|
|
1363
|
+
* component. The check is RUNTIME instead — `defineHostComponents` takes the
|
|
1364
|
+
* same `HostComponentEntry` shape (no cast, one signature) and tests every
|
|
1365
|
+
* implementation on registration; a value that is not a component becomes an
|
|
1366
|
+
* `invalid-implementation` issue in `components.issues` and is withheld from
|
|
1367
|
+
* the implementation map, so its nodes render the visible missing-component
|
|
1368
|
+
* fallback rather than crashing the server render. Authoring a component
|
|
1369
|
+
* module as the strict {@link HostComponent} keeps the compile-time check at
|
|
1370
|
+
* the place the implementation is written.
|
|
1513
1371
|
*/
|
|
1514
1372
|
components?: readonly HostComponentEntry[];
|
|
1515
1373
|
/**
|
|
@@ -1533,8 +1391,10 @@ interface ElytraHostOptions {
|
|
|
1533
1391
|
* The no-backend content fallback, used whenever `ELYTRA_CONVEX_URL` +
|
|
1534
1392
|
* `ELYTRA_PROJECT_ID` are not both set. Default: a build-safe EMPTY source —
|
|
1535
1393
|
* consumer CI builds green with no backend, and every URL is a clean 404
|
|
1536
|
-
* until content exists
|
|
1537
|
-
*
|
|
1394
|
+
* until content exists — in every cache state, not only a cold one, because
|
|
1395
|
+
* the content mode is part of the route's data-cache key (see
|
|
1396
|
+
* {@link ElytraContentMode}). The starter template overrides this with its
|
|
1397
|
+
* seeded in-memory world.
|
|
1538
1398
|
*/
|
|
1539
1399
|
fallbackContent?: (request: CanvasContentRequest) => Promise<ContentSource>;
|
|
1540
1400
|
/** Chrome-globals conventions (settings/navigation collection ids, items fields). */
|
|
@@ -1544,8 +1404,6 @@ interface ElytraHostOptions {
|
|
|
1544
1404
|
}
|
|
1545
1405
|
/** Pass-through canvas-route options the kit does not own. */
|
|
1546
1406
|
interface HostCanvasRouteOptions {
|
|
1547
|
-
/** Extra binding payloads per request (see `CanvasRouteOptions.payloads`). */
|
|
1548
|
-
payloads?: CanvasPayloadsFactory;
|
|
1549
1407
|
/** Tag observation hook (see `CanvasRouteOptions.onTags`). */
|
|
1550
1408
|
onTags?: (tags: CacheTags, info: CanvasRequestInfo) => void;
|
|
1551
1409
|
/** Metadata override (see `CanvasRouteOptions.metadata`). */
|
|
@@ -1560,6 +1418,8 @@ interface HostCanvasRouteOptions {
|
|
|
1560
1418
|
* Tagged data cache (instant publish). Default: enabled, scoped to the
|
|
1561
1419
|
* kit's content scope so the studio's webhook tags match. `false` disables
|
|
1562
1420
|
* caching entirely; an explicit `CanvasCacheOptions` overrides the scope.
|
|
1421
|
+
* The kit's {@link ElytraHost.contentMode} is always part of the entry key
|
|
1422
|
+
* (EC-543) — an override can replace the scope, never drop the mode.
|
|
1563
1423
|
*/
|
|
1564
1424
|
cache?: CanvasCacheOptions | false;
|
|
1565
1425
|
}
|
|
@@ -1584,6 +1444,15 @@ interface LoadGlobalsOptions {
|
|
|
1584
1444
|
* §5 gets no signal that the thing under test was never exercised. Declared
|
|
1585
1445
|
* once, read here, so a host can *say* which world it is in instead of
|
|
1586
1446
|
* re-deriving it from `env` and drifting.
|
|
1447
|
+
*
|
|
1448
|
+
* **The mode is also part of the route's data-cache key** (EC-543). A cache
|
|
1449
|
+
* entry outlives the process that wrote it and a hit never runs the loader, so
|
|
1450
|
+
* until 0.0.85 the "clean 404" above held only on a COLD cache: measured, a
|
|
1451
|
+
* `next start` with both env vars blanked and a warm `.next/cache` from a live
|
|
1452
|
+
* run answered `200` with the live world's bytes on every cached URL while
|
|
1453
|
+
* reporting `empty` — the wrong-world failure EC-527 removed, one layer down.
|
|
1454
|
+
* Keyed on the mode (`canvasCacheKey`, `cache.ts`), a world change is a cold
|
|
1455
|
+
* miss per URL, never a stale hit, in either direction.
|
|
1587
1456
|
*/
|
|
1588
1457
|
type ElytraContentMode = 'live' | 'fallback' | 'empty';
|
|
1589
1458
|
/** The delivery host handle {@link createElytraHost} yields. */
|
|
@@ -1687,13 +1556,13 @@ interface LiveContentOptions {
|
|
|
1687
1556
|
/**
|
|
1688
1557
|
* The `delivery.ts` payload shape (validated field-by-field below). A
|
|
1689
1558
|
* deployment IS one environment (EC-179); the snapshot carries content only
|
|
1690
|
-
* (EC-287) — documents, assets, editorial redirects (EC-303)
|
|
1691
|
-
*
|
|
1559
|
+
* (EC-287) — documents, assets, editorial redirects (EC-303). (A `sources`
|
|
1560
|
+
* strand from an older deployment is ignored — it belonged to the deleted
|
|
1561
|
+
* data-binding subsystem, EC-574.)
|
|
1692
1562
|
*/
|
|
1693
1563
|
interface DeliverySnapshotPayload {
|
|
1694
1564
|
projectId: string;
|
|
1695
1565
|
redirects?: unknown[];
|
|
1696
|
-
sources?: unknown;
|
|
1697
1566
|
documents: unknown[];
|
|
1698
1567
|
assets: unknown[];
|
|
1699
1568
|
}
|
|
@@ -1755,13 +1624,25 @@ type PreviewEvaluation = {
|
|
|
1755
1624
|
message: string;
|
|
1756
1625
|
};
|
|
1757
1626
|
/**
|
|
1758
|
-
*
|
|
1759
|
-
* preview
|
|
1627
|
+
* The ONE same-site check for a preview redirect target, shared by the enable and
|
|
1628
|
+
* disable routes, so the preview endpoints can never be used as an open redirect.
|
|
1629
|
+
* `null` means rejected; an empty value yields `fallback`.
|
|
1630
|
+
*
|
|
1631
|
+
* EC-594: the parser a browser uses decides, not a blocklist of shapes (the old
|
|
1632
|
+
* blocklist caught `//host` and backslashes — EC-304 B-3 — but not `/<TAB>/host`,
|
|
1633
|
+
* which the parser collapses to `//host`):
|
|
1634
|
+
*
|
|
1635
|
+
* - only a path-absolute reference (`/…`) is accepted — a relative one would be
|
|
1636
|
+
* resolved against the route's own path by a browser, so it has no fixed meaning;
|
|
1637
|
+
* - any C0 control or DEL is rejected outright;
|
|
1638
|
+
* - the value is resolved against a fixed origin and must stay on it;
|
|
1639
|
+
* - what is returned is the parser's normalised `pathname + search + hash`, never
|
|
1640
|
+
* the raw input — and that returned target must itself stay on the origin, since
|
|
1641
|
+
* dot-segment removal can leave a pathname starting with `//` (`/.//host`,
|
|
1642
|
+
* `/..//host`, `/%2e//host`), which as a `Location` is scheme-relative.
|
|
1760
1643
|
*
|
|
1761
|
-
*
|
|
1762
|
-
*
|
|
1763
|
-
* `//host` does. A leading single `/` followed by a non-slash, with no backslash
|
|
1764
|
-
* anywhere, is the only accepted same-site shape.
|
|
1644
|
+
* A scheme-relative or absolute value naming the resolution origin itself resolves
|
|
1645
|
+
* on it and yields its path — harmless, because only that path is returned.
|
|
1765
1646
|
*/
|
|
1766
1647
|
declare function safeRedirectTarget(value: string | null | undefined, fallback?: string): string | null;
|
|
1767
1648
|
/**
|
|
@@ -1787,4 +1668,4 @@ declare function evaluatePreviewRequest(requestUrl: string | URL, expectedToken:
|
|
|
1787
1668
|
*/
|
|
1788
1669
|
declare const PACKAGE = "@elytracms/next";
|
|
1789
1670
|
|
|
1790
|
-
export { type AssetImageLoaderOptions, type
|
|
1671
|
+
export { type AssetImageLoaderOptions, type CacheWrapper, type CacheWrapperOptions, type CachedEntry, type CanvasCacheOptions, 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 DefineHostComponentsOptions, type DeliveryPresentation, ELYTRA_HOST_ENV_KEYS, type ElytraContentMode, type ElytraHost, type ElytraHostEnv, type ElytraHostImageOptions, type ElytraHostOptions, ElytraImage, type ElytraImageAsset, type ElytraImageProps, type GlobalsConventions, type HostCanvasRouteOptions, type HostComponent, type HostComponents, type LiveContentOptions, type LoadGlobalsOptions, type NextImagePrimitiveOptions, PACKAGE, type PreviewEvaluation, type PreviewRouteHandlers, type PreviewRouteOptions, REVALIDATE_SIGNATURE_HEADER, type ResolveCanvasPageOptions, type ResolveGlobalsOptions, type ResolvedLink, type ResolvedNavEntry, type ResolvedNavLink, type RevalidateEvaluation, type RevalidatePayload, type RevalidateRouteHandlers, type RevalidateRouteOptions, type SiteGlobals, type SitemapParamsProvider, type SitemapRouteContext, type SitemapSkippedRoute, type StaticContentData, 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 };
|