@elytracms/next 0.0.88 → 0.0.90
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 +158 -112
- package/dist/index.js +51 -66
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -6,15 +6,16 @@ export { ComponentImplementations, RenderAsset } from '@elytracms/core/runtime-r
|
|
|
6
6
|
import { HostComponentEntry } from '@elytracms/core/studio-core';
|
|
7
7
|
import { ResolvePageResult, ResolvedAsset, Perspective, ContentClient, CacheTags, ContentDocumentSource, ResolvedDocument } from '@elytracms/core/content';
|
|
8
8
|
export { Perspective } from '@elytracms/core/content';
|
|
9
|
-
import { LocaleConfig, Locale, RouteRecord, CollectionDef, RedirectRecord } from '@elytracms/core/cms-core';
|
|
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';
|
|
9
|
+
import { LocaleConfig, Locale, RouteRecord, CollectionDef, RedirectRecord, LocaleConfigInput } from '@elytracms/core/cms-core';
|
|
10
|
+
export { CmsDocument, CollectionDef, FieldDef, Locale, LocaleConfig, LocaleConfigInput, LocaleRequest, LocaleStrategy, LocaleUrlPath, RedirectRecord, RouteRecord, documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, parseLocaleConfig, redirectRecordSchema, resolveLocale, routeRecordSchema, splitLocalePath, textDirection } from '@elytracms/core/cms-core';
|
|
11
11
|
import { AssetRecord, PersistenceAdapter } from '@elytracms/core/persistence';
|
|
12
12
|
export { AssetRecord } from '@elytracms/core/persistence';
|
|
13
13
|
import { ResolvingMetadata, Metadata, ResolvedMetadata, MetadataRoute } from 'next';
|
|
14
|
-
import {
|
|
15
|
-
export {
|
|
14
|
+
import { RevalidationEvent } from '@elytracms/core/revalidation';
|
|
15
|
+
export { REVALIDATE_SIGNATURE_HEADER, RevalidationEvent, RevalidationEventKind, revalidationEventSchema, signRevalidationBody, signedRevalidationRequest } from '@elytracms/core/revalidation';
|
|
16
16
|
import { ImageLoader } from 'next/image';
|
|
17
17
|
import { HostImageRenderer } from './host-image.js';
|
|
18
|
+
export { z } from 'zod';
|
|
18
19
|
export { ComponentNode } from '@elytracms/core/project-graph';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -259,9 +260,9 @@ interface ContentSnapshotOptions {
|
|
|
259
260
|
* and EC-519 collapsed the two declarations into one; this was the last place
|
|
260
261
|
* in the chain still inventing the value, and it sits in the package that
|
|
261
262
|
* resolves the URLs. Hand it the project's `LocaleConfig` — the one the
|
|
262
|
-
* config declares.
|
|
263
|
+
* config declares. Parsed here (EC-580): a `default` outside `locales` throws.
|
|
263
264
|
*/
|
|
264
|
-
locales:
|
|
265
|
+
locales: LocaleConfigInput;
|
|
265
266
|
}
|
|
266
267
|
interface ContentSnapshot extends ContentSource {
|
|
267
268
|
readonly projectId: string;
|
|
@@ -275,8 +276,8 @@ interface ContentSnapshot extends ContentSource {
|
|
|
275
276
|
*/
|
|
276
277
|
interface StaticContentData {
|
|
277
278
|
projectId: string;
|
|
278
|
-
/** Locale configuration — **required**, never defaulted (see EC-530 above). */
|
|
279
|
-
locales:
|
|
279
|
+
/** Locale configuration — **required**, never defaulted (see EC-530 above); parsed (EC-580). */
|
|
280
|
+
locales: LocaleConfigInput;
|
|
280
281
|
/** Route records served by `resolvePage` (EC-019). */
|
|
281
282
|
routes?: readonly RouteRecord[];
|
|
282
283
|
/** Redirect records served by `resolvePage` (EC-019/020). */
|
|
@@ -443,9 +444,9 @@ declare function resolveCanvasPage(source: ContentSource, url: string, perspecti
|
|
|
443
444
|
|
|
444
445
|
interface CanvasCacheOptions {
|
|
445
446
|
/**
|
|
446
|
-
* Project scope prefix for every tag (`p:<scope>:…`) — must be the
|
|
447
|
-
*
|
|
448
|
-
*
|
|
447
|
+
* Project scope prefix for every tag (`p:<scope>:…`) — must be the SAME scope
|
|
448
|
+
* the revalidate receiver derives its tags with (`createRevalidateRoute`'s
|
|
449
|
+
* `scope`; the delivery kit hands its one `contentScope` to both, EC-579).
|
|
449
450
|
*/
|
|
450
451
|
scope?: string;
|
|
451
452
|
/**
|
|
@@ -543,8 +544,14 @@ interface CanvasRoute {
|
|
|
543
544
|
* Next passes the parent segment's resolving metadata as the second argument;
|
|
544
545
|
* the route merges the page's tags over it (EC-610). A caller that invokes this
|
|
545
546
|
* by hand (the scaffold's `app/page.tsx`) forwards its own `parent`.
|
|
547
|
+
*
|
|
548
|
+
* `parent` is REQUIRED, not optional (EC-614): Next's webpack build validates a
|
|
549
|
+
* page's `generateMetadata` with `SecondArg<…> extends ResolvingMetadata`, and an
|
|
550
|
+
* optional parameter reads as `ResolvingMetadata | undefined`, which fails that
|
|
551
|
+
* constraint — a consumer re-exporting this hook could not `next build --webpack`
|
|
552
|
+
* on 0.0.88 (the Turbopack validator is lenient, which is how the gate missed it).
|
|
546
553
|
*/
|
|
547
|
-
generateMetadata: (props: CanvasRouteProps, parent
|
|
554
|
+
generateMetadata: (props: CanvasRouteProps, parent: ResolvingMetadata) => Promise<Metadata>;
|
|
548
555
|
}
|
|
549
556
|
/** Create the `{ Page, generateMetadata }` pair for `app/[[...slug]]/page.tsx`. */
|
|
550
557
|
declare function createCanvasRoute(options: CanvasRouteOptions): CanvasRoute;
|
|
@@ -688,10 +695,17 @@ declare function createCanvasSitemap(options: CreateCanvasSitemapOptions): () =>
|
|
|
688
695
|
* Cache-tag pipeline (EC-146, vision AD-5) — the pure half.
|
|
689
696
|
*
|
|
690
697
|
* This module defines (a) the **canonical Next.js tag string format** mapping
|
|
691
|
-
* the accessor-level `CacheTags` (EC-143) onto `revalidateTag` keys,
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
698
|
+
* the accessor-level `CacheTags` (EC-143) onto `revalidateTag` keys, (b) the
|
|
699
|
+
* **tag derivation for a revalidation event** ({@link revalidationTags}, EC-579 —
|
|
700
|
+
* the receiver's half of the one emitter), and (c) the **tag-discovery caching
|
|
701
|
+
* logic** the catch-all route helper runs inside `unstable_cache`. No Next.js
|
|
702
|
+
* imports — everything here is unit-testable; `route.tsx` injects the real
|
|
703
|
+
* `unstable_cache` via {@link CacheWrapper}.
|
|
704
|
+
*
|
|
705
|
+
* This is the ONE tag module: the entries are tagged here and the invalidations
|
|
706
|
+
* are derived here, from the same formatters and the same scope. Before EC-579 the
|
|
707
|
+
* format was mirrored twice more (the studio's browser dispatcher and an inline
|
|
708
|
+
* literal in the Convex emitter), and each emitter brought its own scope.
|
|
695
709
|
*
|
|
696
710
|
* ## Tag format
|
|
697
711
|
*
|
|
@@ -709,8 +723,8 @@ declare function createCanvasSitemap(options: CreateCanvasSitemapOptions): () =>
|
|
|
709
723
|
* (alt/dimensions/re-upload) drops exactly the pages that baked it. Not
|
|
710
724
|
* locale-scoped — an asset record is locale-agnostic.
|
|
711
725
|
* - `project` — the whole-project sweep tag attached to **every** cached
|
|
712
|
-
* entry;
|
|
713
|
-
*
|
|
726
|
+
* entry; every revalidation event that changes live output invalidates it
|
|
727
|
+
* (see {@link revalidationTags} for why, until EC-515).
|
|
714
728
|
*
|
|
715
729
|
* ## Project scope
|
|
716
730
|
*
|
|
@@ -718,16 +732,11 @@ declare function createCanvasSitemap(options: CreateCanvasSitemapOptions): () =>
|
|
|
718
732
|
* `p:prj_aurora:doc:post:post-1`). The cost is a few bytes per tag and it
|
|
719
733
|
* keeps multi-project hosts (one Next app serving several builder projects)
|
|
720
734
|
* from cross-invalidating, so the prefix is **on whenever the host knows its
|
|
721
|
-
* project id** — decision: include it.
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
* The studio-side emitter cannot depend on this package (it would drag the
|
|
728
|
-
* `next` peer dependency into the studio bundle), so
|
|
729
|
-
* `packages/studio/src/lib/webhooks/tags.ts` mirrors these formatters; tests on
|
|
730
|
-
* both sides pin the exact literal strings to keep them in lock-step.
|
|
735
|
+
* project id** — decision: include it. Since EC-579 the scope has ONE owner: the
|
|
736
|
+
* host. The webhook carries an event, not tags, and the receiver derives the
|
|
737
|
+
* tags with the same scope its cache entries are written under (the delivery
|
|
738
|
+
* kit hands both the one `contentScope`), so emitter and host can no longer
|
|
739
|
+
* disagree about it.
|
|
731
740
|
*/
|
|
732
741
|
/** Apply the optional multi-project scope prefix to one tag. */
|
|
733
742
|
declare function scopeCacheTag(tag: string, scope?: string): string;
|
|
@@ -741,9 +750,8 @@ declare function collectionCacheTag(collection: string, locale: string, scope?:
|
|
|
741
750
|
/** Tag for one resolved route path (or redirect-chain hop) in one locale. */
|
|
742
751
|
declare function routeCacheTag(pattern: string, locale: string, scope?: string): string;
|
|
743
752
|
/**
|
|
744
|
-
* The whole-project sweep tag. Attached to every cached page entry;
|
|
745
|
-
*
|
|
746
|
-
* change's precise tag set is unknowable).
|
|
753
|
+
* The whole-project sweep tag. Attached to every cached page entry; derived for
|
|
754
|
+
* every revalidation event that changes live output ({@link revalidationTags}).
|
|
747
755
|
*/
|
|
748
756
|
declare function projectSweepTag(scope?: string): string;
|
|
749
757
|
/**
|
|
@@ -752,6 +760,38 @@ declare function projectSweepTag(scope?: string): string;
|
|
|
752
760
|
* cache entry — including the project sweep tag.
|
|
753
761
|
*/
|
|
754
762
|
declare function nextCacheTags(tags: CacheTags, scope?: string): string[];
|
|
763
|
+
/** The receiver's own project — what its cached entries are tagged with. */
|
|
764
|
+
interface RevalidationProject {
|
|
765
|
+
/** The tag scope of this host's cache entries (`p:<scope>:…`), if any. */
|
|
766
|
+
scope?: string | undefined;
|
|
767
|
+
/** Every locale this host serves — one `collection:` tag per locale. */
|
|
768
|
+
locales: readonly string[];
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* The tags one revalidation event invalidates on this host — sorted, deduplicated,
|
|
772
|
+
* scoped with the receiver's OWN scope, so the emitter never needs to know it.
|
|
773
|
+
*
|
|
774
|
+
* - `publish` / `unpublish` / `delete` → `doc:<collection>:<id>` (its detail page and
|
|
775
|
+
* every cached list that contained it) + `collection:<collection>:<locale>` for
|
|
776
|
+
* EVERY locale this host serves (list membership may have changed) + the sweep;
|
|
777
|
+
* - `redirects` → the sweep (routing can change any URL; see the `redirects` trigger
|
|
778
|
+
* in the studio's `convex/triggers.ts` for why a targeted `route:` tag is wrong);
|
|
779
|
+
* - `asset` → `asset:<id>` + the sweep (a page reading the asset through a document
|
|
780
|
+
* asset FIELD carries no `asset:` tag — EC-566 D16, EC-589);
|
|
781
|
+
* - `probe` → nothing (the doctor's no-op ping).
|
|
782
|
+
*
|
|
783
|
+
* **Why every live-output event also carries the project sweep — a deliberate,
|
|
784
|
+
* measured deviation from the EC-579 ruling's text, which lists the sweep only for
|
|
785
|
+
* redirects and asset removes.** A self-hosted Next host honours ONLY the baseline
|
|
786
|
+
* tags of a cache read (measured in EC-515 on Next 16.2.10 — see
|
|
787
|
+
* {@link loadCachedEntry}): a discovered `doc:` / `collection:` / `asset:` tag
|
|
788
|
+
* invalidates nothing there, silently, and Vercel is unmeasured. Until EC-515's
|
|
789
|
+
* option D makes the precise tags honoured, the precise tags alone would turn
|
|
790
|
+
* "revalidates coarsely" into "never revalidates" on every self-hosted host — so the
|
|
791
|
+
* sweep stays on every event, exactly as the Convex path sent it before. Dropping it
|
|
792
|
+
* from a publish is EC-515's job, together with the read that makes it safe.
|
|
793
|
+
*/
|
|
794
|
+
declare function revalidationTags(event: RevalidationEvent, project: RevalidationProject): string[];
|
|
755
795
|
/**
|
|
756
796
|
* The slice of `unstable_cache` the discovery logic needs, injectable so the
|
|
757
797
|
* logic is testable against a faithful in-memory model (and so the test model
|
|
@@ -849,11 +889,11 @@ interface CachedEntry<T> {
|
|
|
849
889
|
* webhook are all correct — the read simply never consults them.
|
|
850
890
|
*
|
|
851
891
|
* Consequence for a self-hosted deployment: invalidation granularity collapses
|
|
852
|
-
* to whatever is in `baselineTags`.
|
|
853
|
-
*
|
|
854
|
-
* coarsely;
|
|
855
|
-
*
|
|
856
|
-
*
|
|
892
|
+
* to whatever is in `baselineTags`. {@link revalidationTags} therefore adds the
|
|
893
|
+
* project sweep to every event that changes live output (EC-579), so instant
|
|
894
|
+
* publish still *works* there, coarsely; its targeted `doc:`/`collection:`/`asset:`
|
|
895
|
+
* tags do not reach a self-hosted host's entries at all. Vercel-hosted deployments
|
|
896
|
+
* are unaffected in practice — both consumer
|
|
857
897
|
* sites were measured healthy on 2026-08-01 — which is consistent with Vercel's
|
|
858
898
|
* cache handler purging by the entry's stored tags, though that has **not** been
|
|
859
899
|
* measured here.
|
|
@@ -866,90 +906,80 @@ interface CachedEntry<T> {
|
|
|
866
906
|
declare function loadCachedEntry<T>(cache: CacheWrapper, keyParts: string[], baselineTags: readonly string[], load: () => Promise<CachedEntry<T>>): Promise<CachedEntry<T>>;
|
|
867
907
|
|
|
868
908
|
/**
|
|
869
|
-
* Pure
|
|
870
|
-
*
|
|
871
|
-
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
909
|
+
* Pure request logic of the revalidation webhook receiver (EC-146), kept free of
|
|
910
|
+
* Next.js imports so it is unit-testable. `revalidate.ts` wires it into a route
|
|
911
|
+
* handler with `revalidateTag`.
|
|
912
|
+
*
|
|
913
|
+
* The wire — event schema, signer, header — is NOT declared here: it is the one
|
|
914
|
+
* module `@elytracms/core/revalidation`, shared with the emitter (the studio's
|
|
915
|
+
* Convex write chokepoint) and the doctor probe (EC-579). This file only decides
|
|
916
|
+
* the HTTP answer: auth before parsing, then the event.
|
|
877
917
|
*/
|
|
878
|
-
/** Header carrying the HMAC signature. */
|
|
879
|
-
declare const REVALIDATE_SIGNATURE_HEADER = "x-elytra-signature";
|
|
880
|
-
/** The webhook body: which tags to revalidate, and why. */
|
|
881
|
-
declare const revalidatePayloadSchema: z.ZodObject<{
|
|
882
|
-
projectId: z.ZodString;
|
|
883
|
-
event: z.ZodString;
|
|
884
|
-
tags: z.ZodArray<z.ZodString>;
|
|
885
|
-
timestamp: z.ZodString;
|
|
886
|
-
}, z.core.$strip>;
|
|
887
|
-
type RevalidatePayload = z.infer<typeof revalidatePayloadSchema>;
|
|
888
|
-
/** Compute the signature header value for a raw body (emitter/test side). */
|
|
889
|
-
declare function signRevalidateBody(rawBody: string, secret: string): string;
|
|
890
918
|
type RevalidateEvaluation = {
|
|
891
919
|
ok: true;
|
|
892
|
-
|
|
920
|
+
event: RevalidationEvent;
|
|
893
921
|
} | {
|
|
894
922
|
ok: false;
|
|
895
923
|
status: 400 | 401;
|
|
896
924
|
message: string;
|
|
897
925
|
};
|
|
898
926
|
/**
|
|
899
|
-
* Evaluate one webhook request: verify the HMAC first (auth before parsing),
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
* - unconfigured (empty) secret → 401 for every request: the endpoint stays
|
|
903
|
-
*
|
|
904
|
-
* - missing/malformed/mismatched signature → 401 (
|
|
905
|
-
* - unparseable or schema-invalid body → 400
|
|
927
|
+
* Evaluate one webhook request: verify the HMAC first (auth before parsing), then
|
|
928
|
+
* read the event.
|
|
929
|
+
*
|
|
930
|
+
* - unconfigured (empty) secret → 401 for every request: the endpoint stays closed
|
|
931
|
+
* until a secret is deliberately configured (mirrors EC-144 preview);
|
|
932
|
+
* - missing/malformed/mismatched signature → 401 (constant-time verify);
|
|
933
|
+
* - unparseable or schema-invalid body → 400, nothing revalidated; a body in the
|
|
934
|
+
* pre-EC-579 tag-list shape gets its own named 400 (an older Elytra emitter —
|
|
935
|
+
* deploy the matching studio functions), because a version skew between the
|
|
936
|
+
* Convex deployment and this host is the one way a correctly signed body can
|
|
937
|
+
* arrive in the wrong shape.
|
|
906
938
|
*/
|
|
907
|
-
declare function evaluateRevalidateRequest(rawBody: string, signature: string | null | undefined, secret: string | undefined): RevalidateEvaluation
|
|
939
|
+
declare function evaluateRevalidateRequest(rawBody: string, signature: string | null | undefined, secret: string | undefined): Promise<RevalidateEvaluation>;
|
|
908
940
|
|
|
909
941
|
/**
|
|
910
942
|
* Revalidation webhook route handler (EC-146): the receiving end of the
|
|
911
|
-
* publish → live-in-seconds pipeline. The studio's
|
|
912
|
-
* `{
|
|
913
|
-
* HMAC over the raw body
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
943
|
+
* publish → live-in-seconds pipeline. The studio's Convex write chokepoint — the ONE
|
|
944
|
+
* emitter (EC-579) — POSTs a signed EVENT (`{ kind, collection?, id? }`, the wire in
|
|
945
|
+
* `@elytracms/core/revalidation`); this handler verifies the HMAC over the raw body,
|
|
946
|
+
* derives the tags from the event with this host's OWN scope and locales
|
|
947
|
+
* (`revalidationTags`, `cache.ts`) and calls `revalidateTag` for each, dropping the
|
|
948
|
+
* cached entries whose fetch-time tag sets contained them.
|
|
949
|
+
*
|
|
950
|
+
* Server-to-server only: the emitter runs in Convex, so there is no CORS and no
|
|
951
|
+
* `OPTIONS` preflight (the studio's browser dispatcher that needed them is deleted).
|
|
952
|
+
* Server-only by construction — consumed from an App Router route handler file,
|
|
953
|
+
* never from client bundles.
|
|
918
954
|
*/
|
|
919
|
-
interface RevalidateRouteOptions {
|
|
955
|
+
interface RevalidateRouteOptions extends RevalidationProject {
|
|
920
956
|
/**
|
|
921
957
|
* Shared HMAC secret. An empty/undefined secret rejects every request with
|
|
922
958
|
* 401 — the endpoint stays closed until deliberately configured.
|
|
923
959
|
*/
|
|
924
960
|
secret: string | undefined;
|
|
925
|
-
/**
|
|
926
|
-
* CORS origin allowed to call this endpoint (e.g. the studio's origin).
|
|
927
|
-
* The v1 dispatcher is a browser `fetch` from the studio, and the custom
|
|
928
|
-
* signature header always triggers a CORS preflight — so cross-origin
|
|
929
|
-
* studio → host dispatch only works when this is set. Server-side emitters
|
|
930
|
-
* (the Convex action variant, CLIs, CI) need no CORS and may leave it
|
|
931
|
-
* unset. Never use `*` with a real secret-bearing deployment unless you
|
|
932
|
-
* accept that any origin may *attempt* deliveries (they still need the
|
|
933
|
-
* secret to have any effect).
|
|
934
|
-
*/
|
|
935
|
-
allowOrigin?: string;
|
|
936
961
|
}
|
|
937
962
|
interface RevalidateRouteHandlers {
|
|
938
963
|
POST(request: Request): Promise<Response>;
|
|
939
|
-
OPTIONS(): Promise<Response>;
|
|
940
964
|
}
|
|
941
965
|
/**
|
|
942
|
-
* Create the webhook route
|
|
966
|
+
* Create the webhook route handler for `app/api/revalidate/route.ts`. Through the
|
|
967
|
+
* delivery kit it is `export const { POST } = elytra.revalidateRoute()`, which hands
|
|
968
|
+
* it the kit's own scope and locales — the ones its cached entries carry. Wiring it
|
|
969
|
+
* by hand, pass the SAME scope your canvas route caches under:
|
|
943
970
|
*
|
|
944
971
|
* ```ts
|
|
945
|
-
* export const { POST
|
|
972
|
+
* export const { POST } = createRevalidateRoute({
|
|
946
973
|
* secret: process.env.REVALIDATE_SECRET,
|
|
974
|
+
* scope: process.env.ELYTRA_PROJECT_ID,
|
|
975
|
+
* locales: ['en', 'de'],
|
|
947
976
|
* })
|
|
948
977
|
* ```
|
|
949
978
|
*
|
|
950
|
-
* Unsigned/invalid requests are rejected with 401 (
|
|
951
|
-
*
|
|
952
|
-
*
|
|
979
|
+
* Unsigned/invalid requests are rejected with 401 (constant-time HMAC verify, see
|
|
980
|
+
* `evaluateRevalidateRequest`), signed-but-unreadable ones with 400; a valid event
|
|
981
|
+
* revalidates its derived tags and answers `{ revalidated: tags }` (`[]` for the
|
|
982
|
+
* doctor's `probe`).
|
|
953
983
|
*/
|
|
954
984
|
declare function createRevalidateRoute(options: RevalidateRouteOptions): RevalidateRouteHandlers;
|
|
955
985
|
|
|
@@ -1152,7 +1182,9 @@ declare function elytraHostImage(options?: ElytraHostImageOptions): HostImageRen
|
|
|
1152
1182
|
* | | equal the Convex deployment's own env var) |
|
|
1153
1183
|
* | `REVALIDATE_SECRET` | Instant-publish webhook HMAC secret (must equal the |
|
|
1154
1184
|
* | | deployment's `CANVAS_REVALIDATE_SECRET`) |
|
|
1155
|
-
*
|
|
1185
|
+
*
|
|
1186
|
+
* EC-579 retired `STUDIO_ORIGIN` (the CORS origin of the studio's deleted browser
|
|
1187
|
+
* dispatcher): the one emitter is the Convex deployment, server to server.
|
|
1156
1188
|
*/
|
|
1157
1189
|
/** The kit's documented env names (single source of truth, also used in docs/tests). */
|
|
1158
1190
|
declare const ELYTRA_HOST_ENV_KEYS: {
|
|
@@ -1160,14 +1192,12 @@ declare const ELYTRA_HOST_ENV_KEYS: {
|
|
|
1160
1192
|
readonly projectId: "ELYTRA_PROJECT_ID";
|
|
1161
1193
|
readonly draftToken: "DRAFT_PREVIEW_TOKEN";
|
|
1162
1194
|
readonly revalidateSecret: "REVALIDATE_SECRET";
|
|
1163
|
-
readonly studioOrigin: "STUDIO_ORIGIN";
|
|
1164
1195
|
};
|
|
1165
1196
|
interface ElytraHostEnv {
|
|
1166
1197
|
convexUrl?: string;
|
|
1167
1198
|
projectId?: string;
|
|
1168
1199
|
draftToken?: string;
|
|
1169
1200
|
revalidateSecret?: string;
|
|
1170
|
-
studioOrigin?: string;
|
|
1171
1201
|
}
|
|
1172
1202
|
/**
|
|
1173
1203
|
* Resolve the kit's env bag from a raw env record (`process.env` by default at
|
|
@@ -1338,7 +1368,7 @@ declare function createPreviewDisableRoute(): PreviewRouteHandlers;
|
|
|
1338
1368
|
* export const generateMetadata = route.generateMetadata
|
|
1339
1369
|
*
|
|
1340
1370
|
* // app/api/revalidate/route.ts
|
|
1341
|
-
* export const { POST
|
|
1371
|
+
* export const { POST } = elytra.revalidateRoute()
|
|
1342
1372
|
*
|
|
1343
1373
|
* // app/api/draft/route.ts — GET /api/draft?token=…&redirect=/path
|
|
1344
1374
|
* export const { GET } = elytra.previewRoute()
|
|
@@ -1364,7 +1394,7 @@ interface ElytraHostOptions {
|
|
|
1364
1394
|
* Locale config — config-owned (AD-11), never read from the snapshot.
|
|
1365
1395
|
*
|
|
1366
1396
|
* **Import it, do not restate it** (EC-519). This is the *same*
|
|
1367
|
-
* {@link
|
|
1397
|
+
* {@link LocaleConfigInput} `elytra.config.ts` takes, so a project declares its
|
|
1368
1398
|
* locales once and hands that one binding to both mounts. It stays a host
|
|
1369
1399
|
* option because the engine cannot know where a repo keeps the value — but it
|
|
1370
1400
|
* is no longer an option you have to *retype*: since EC-532 the delivery
|
|
@@ -1376,8 +1406,14 @@ interface ElytraHostOptions {
|
|
|
1376
1406
|
* fact `locales` + `defaultLocale`, and in our own demo the two drifted — the
|
|
1377
1407
|
* host said `['en']`, the config said `['en','de']`, and every `/de` URL 404'd
|
|
1378
1408
|
* silently for weeks (EC-512).
|
|
1409
|
+
*
|
|
1410
|
+
* The DECLARED shape (EC-580): the kit parses it into the engine's `LocaleConfig`
|
|
1411
|
+
* where every content source is assembled (`createStaticContentSource` — the
|
|
1412
|
+
* empty source is built at boot), so a `default` outside `locales` stops the host
|
|
1413
|
+
* with a located message instead of serving — the same rule the studio's
|
|
1414
|
+
* workspace gate applies to the same value.
|
|
1379
1415
|
*/
|
|
1380
|
-
locales:
|
|
1416
|
+
locales: LocaleConfigInput;
|
|
1381
1417
|
/** CMS collection schema — config-owned (AD-11). */
|
|
1382
1418
|
collections: readonly CollectionDef[];
|
|
1383
1419
|
/** Routes as code (AD-3/AD-11): records, or the `(collections) => records` derive. */
|
|
@@ -1424,7 +1460,7 @@ interface ElytraHostOptions {
|
|
|
1424
1460
|
/**
|
|
1425
1461
|
* Env bag; defaults to `process.env`. Documented names (see `host-env.ts`):
|
|
1426
1462
|
* `ELYTRA_CONVEX_URL`, `ELYTRA_PROJECT_ID`, `DRAFT_PREVIEW_TOKEN`,
|
|
1427
|
-
* `REVALIDATE_SECRET
|
|
1463
|
+
* `REVALIDATE_SECRET`.
|
|
1428
1464
|
*/
|
|
1429
1465
|
env?: Record<string, string | undefined>;
|
|
1430
1466
|
/**
|
|
@@ -1455,13 +1491,17 @@ interface HostCanvasRouteOptions {
|
|
|
1455
1491
|
*/
|
|
1456
1492
|
wrap?: (children: ReactNode, ctx: CanvasWrapContext) => ReactNode;
|
|
1457
1493
|
/**
|
|
1458
|
-
* Tagged data cache (instant publish).
|
|
1459
|
-
*
|
|
1460
|
-
*
|
|
1461
|
-
*
|
|
1462
|
-
*
|
|
1494
|
+
* Tagged data cache (instant publish). Always on and always scoped to the kit's
|
|
1495
|
+
* {@link ElytraHost.contentScope}, with the kit's
|
|
1496
|
+
* {@link ElytraHost.contentMode} in the entry key (EC-543). `false` disables
|
|
1497
|
+
* caching entirely.
|
|
1498
|
+
*
|
|
1499
|
+
* There is no scope override (EC-579): the kit's revalidate receiver derives its
|
|
1500
|
+
* tags with that same `contentScope`, so one value scopes both the entries and
|
|
1501
|
+
* their invalidation. An override here was the one way left for the two to
|
|
1502
|
+
* disagree — and a disagreement drops nothing, silently.
|
|
1463
1503
|
*/
|
|
1464
|
-
cache?:
|
|
1504
|
+
cache?: false;
|
|
1465
1505
|
}
|
|
1466
1506
|
interface LoadGlobalsOptions {
|
|
1467
1507
|
/** Perspective of the chrome read. Default `'published'` (live is published-only). */
|
|
@@ -1498,8 +1538,9 @@ type ElytraContentMode = 'live' | 'fallback' | 'empty';
|
|
|
1498
1538
|
/** The delivery host handle {@link createElytraHost} yields. */
|
|
1499
1539
|
interface ElytraHost {
|
|
1500
1540
|
/**
|
|
1501
|
-
* The cache-tag scope: `ELYTRA_PROJECT_ID` in live mode
|
|
1502
|
-
*
|
|
1541
|
+
* The cache-tag scope: `ELYTRA_PROJECT_ID` in live mode, else the config slug.
|
|
1542
|
+
* The ONE scope of this host (EC-579): its cache entries are written under it and
|
|
1543
|
+
* its revalidate receiver derives every invalidation tag with it.
|
|
1503
1544
|
*/
|
|
1504
1545
|
contentScope: string;
|
|
1505
1546
|
/**
|
|
@@ -1532,11 +1573,13 @@ interface ElytraHost {
|
|
|
1532
1573
|
/** The catch-all canvas route pair for `app/[[...slug]]/page.tsx`. */
|
|
1533
1574
|
canvasRoute(options?: HostCanvasRouteOptions): CanvasRoute;
|
|
1534
1575
|
/**
|
|
1535
|
-
* The instant-publish webhook
|
|
1536
|
-
*
|
|
1537
|
-
*
|
|
1576
|
+
* The instant-publish webhook handler for `app/api/revalidate/route.ts`, wired to
|
|
1577
|
+
* `REVALIDATE_SECRET` and to this host's own project — {@link contentScope} and the
|
|
1578
|
+
* config locales — which it derives the tags of every event with (EC-579). Unset
|
|
1579
|
+
* secret = endpoint closed (401), never a default secret. Only the secret can be
|
|
1580
|
+
* overridden: the scope and locales are the ones this kit's cache entries carry.
|
|
1538
1581
|
*/
|
|
1539
|
-
revalidateRoute(overrides?: Partial<RevalidateRouteOptions
|
|
1582
|
+
revalidateRoute(overrides?: Partial<Pick<RevalidateRouteOptions, 'secret'>>): RevalidateRouteHandlers;
|
|
1540
1583
|
/**
|
|
1541
1584
|
* The draft-mode ENABLE route for e.g. `app/api/draft/route.ts` —
|
|
1542
1585
|
* `GET /api/draft?token=…&redirect=/path`, gated by the ONE
|
|
@@ -1582,8 +1625,11 @@ interface LiveContentOptions {
|
|
|
1582
1625
|
/** Convex deployment URL, e.g. `https://your-deployment-123.convex.cloud`. */
|
|
1583
1626
|
convexUrl: string;
|
|
1584
1627
|
projectId: string;
|
|
1585
|
-
/**
|
|
1586
|
-
|
|
1628
|
+
/**
|
|
1629
|
+
* Project locale config — config-owned (AD-11), never read from the snapshot.
|
|
1630
|
+
* The declared shape; parsed where the source is assembled (EC-580).
|
|
1631
|
+
*/
|
|
1632
|
+
locales: LocaleConfigInput;
|
|
1587
1633
|
/** CMS collection schema — config-owned (AD-11); drives depth-1 relation population. */
|
|
1588
1634
|
collections: readonly CollectionDef[];
|
|
1589
1635
|
/** Route records — config-owned (AD-3/AD-11); merged with the home fallback. */
|
|
@@ -1708,4 +1754,4 @@ declare function evaluatePreviewRequest(requestUrl: string | URL, expectedToken:
|
|
|
1708
1754
|
*/
|
|
1709
1755
|
declare const PACKAGE = "@elytracms/next";
|
|
1710
1756
|
|
|
1711
|
-
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,
|
|
1757
|
+
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, type ResolveCanvasPageOptions, type ResolveGlobalsOptions, type ResolvedLink, type ResolvedNavEntry, type ResolvedNavLink, type RevalidateEvaluation, type RevalidateRouteHandlers, type RevalidateRouteOptions, type RevalidationProject, 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, mergeMetadataOverParent, nextCacheTags, nextImagePrimitive, openGraphLocale, pathFromSlug, projectSweepTag, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidationTags, routeCacheTag, safeRedirectTarget, scopeCacheTag };
|