payload-live-preview 2.0.0-beta.0 → 2.0.0
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/README.md +60 -775
- package/dist/adapters/astro/PreviewBoundary.astro +2 -2
- package/dist/adapters/astro/index.d.ts +28 -154
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.d.ts +3 -2
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.d.ts +247 -6
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +58 -3
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +82 -0
- package/dist/adapters/nuxt/module.js +2 -0
- package/dist/adapters/nuxt/module.js.map +1 -0
- package/dist/adapters/react/index.d.ts +110 -0
- package/dist/adapters/react/index.js +3 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/sveltekit/index.d.ts +65 -7
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +56 -0
- package/dist/adapters/vue/index.js +2 -0
- package/dist/adapters/vue/index.js.map +1 -0
- package/dist/annotate.d.ts +161 -0
- package/dist/annotate.js +2 -0
- package/dist/annotate.js.map +1 -0
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +182 -9
- package/dist/client.d.ts +182 -9
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codegen-astro.js +1 -1
- package/dist/codegen-astro.js.map +1 -1
- package/dist/codegen-cli.js +1 -1
- package/dist/codegen-cli.js.map +1 -1
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +129 -4
- package/dist/codegen.d.ts +129 -4
- package/dist/codegen.js +1 -1
- package/dist/codegen.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +264 -73
- package/dist/core.d.ts +264 -73
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +1 -1
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +7 -6
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/document-session-BfBfLVpg.d.ts +53 -0
- package/dist/fragment-endpoint-3Mlz7GDz.d.ts +189 -0
- package/dist/fragment.cjs +1 -1
- package/dist/fragment.cjs.map +1 -1
- package/dist/fragment.d.cts +64 -18
- package/dist/fragment.d.ts +64 -18
- package/dist/fragment.js +1 -1
- package/dist/fragment.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +422 -83
- package/dist/index.d.ts +422 -83
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +2 -0
- package/dist/lean.cjs.map +1 -0
- package/dist/lean.d.cts +44 -0
- package/dist/lean.d.ts +44 -0
- package/dist/lean.js +2 -0
- package/dist/lean.js.map +1 -0
- package/dist/lexical.cjs +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.d.cts +19 -1
- package/dist/lexical.d.ts +19 -1
- package/dist/lexical.js +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/locals-DBXDMxOA.d.ts +45 -0
- package/dist/{middleware-CEPsY1P7.d.ts → middleware-Bx9I7PXW.d.ts} +14 -14
- package/dist/migrate.d.ts +4 -3
- package/dist/migrate.js +1 -1
- package/dist/migrate.js.map +1 -1
- package/dist/{options-CEzzfHJu.d.ts → options-BW1eqXvc.d.ts} +90 -2
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +111 -6
- package/dist/plugins.d.ts +111 -6
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{probe-CYtvj_Lm.d.ts → probe-CELeUciC.d.ts} +26 -4
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +67 -13
- package/dist/server.d.ts +67 -13
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs +2 -2
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.d.cts +47 -4
- package/dist/structural.d.ts +47 -4
- package/dist/structural.js +2 -2
- package/dist/structural.js.map +1 -1
- package/package.json +77 -9
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { P as PreviewAdapterOptions } from '../../options-BW1eqXvc.js';
|
|
2
|
+
import { F as FragmentEndpointOptions$1, a as FragmentRegistry$1, b as FragmentRegistryEntry$1, c as FragmentRenderer$1, d as FragmentRenderInput } from '../../fragment-endpoint-3Mlz7GDz.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* Next.js adapter.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Next.js adapter. The script goes into the root layout, because
|
|
6
|
+
* `NextResponse.next()` carries no body for the middleware to inject into:
|
|
7
|
+
* `livePreviewScriptProps()` for the App Router's JSX, `renderLivePreviewScript()`
|
|
8
|
+
* for HTML a server assembles as a string.
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
type LivePreviewNextOptions = PreviewAdapterOptions;
|
|
@@ -14,9 +16,248 @@ type LivePreviewNextOptions = PreviewAdapterOptions;
|
|
|
14
16
|
* `authorizePreviewRequest()` in the route when a page needs it.
|
|
15
17
|
*/
|
|
16
18
|
declare function createLivePreviewMiddleware(options?: LivePreviewNextOptions): (request: Request, response: Response) => Promise<Response>;
|
|
17
|
-
/**
|
|
19
|
+
/** What a `<script>` element needs to carry the runtime; see `livePreviewScriptProps`. */
|
|
20
|
+
interface LivePreviewScriptProps {
|
|
21
|
+
readonly dangerouslySetInnerHTML: {
|
|
22
|
+
readonly __html: string;
|
|
23
|
+
};
|
|
24
|
+
/** Present only when a nonce was passed, so React omits the attribute otherwise. */
|
|
25
|
+
readonly nonce?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Props for the `<script>` in `app/layout.tsx`:
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <script {...livePreviewScriptProps({ allowedOrigins: [ADMIN], serverURL: ADMIN, mergeDepth: 1 })} />
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* The nonce stays a prop rather than going into the body, because that is where
|
|
35
|
+
* the framework — and any CSP handling built on it — expects the attribute.
|
|
36
|
+
*/
|
|
37
|
+
declare function livePreviewScriptProps(options?: LivePreviewNextOptions & {
|
|
38
|
+
readonly nonce?: string;
|
|
39
|
+
}): LivePreviewScriptProps;
|
|
40
|
+
/**
|
|
41
|
+
* The complete `<script>` tag, for HTML a server builds as a string. A JSX
|
|
42
|
+
* framework cannot render it — use `livePreviewScriptProps()` there.
|
|
43
|
+
*/
|
|
18
44
|
declare function renderLivePreviewScript(options?: LivePreviewNextOptions & {
|
|
19
45
|
readonly nonce?: string;
|
|
20
46
|
}): string;
|
|
21
47
|
|
|
22
|
-
|
|
48
|
+
/**
|
|
49
|
+
* A React function component.
|
|
50
|
+
*
|
|
51
|
+
* The parameter is `never` rather than the props object it will receive:
|
|
52
|
+
* parameters are checked contravariantly, so this accepts a component with any
|
|
53
|
+
* props while a `Record<string, unknown>` would accept almost none. What the
|
|
54
|
+
* component and its props have to agree on is checked by `defineFragment()`,
|
|
55
|
+
* which is why that helper exists.
|
|
56
|
+
*/
|
|
57
|
+
type ReactComponentLike = (props: never) => unknown;
|
|
58
|
+
type FragmentRegistryEntry<Props extends object = object> = FragmentRegistryEntry$1<ReactComponentLike, Props>;
|
|
59
|
+
/** @internal */
|
|
60
|
+
type FragmentRegistry = FragmentRegistry$1<ReactComponentLike>;
|
|
61
|
+
/** @internal */
|
|
62
|
+
type FragmentRenderer = FragmentRenderer$1<ReactComponentLike>;
|
|
63
|
+
type FragmentEndpointOptions = FragmentEndpointOptions$1<ReactComponentLike>;
|
|
64
|
+
/**
|
|
65
|
+
* Pairs a component with the props it takes, so the two cannot drift apart.
|
|
66
|
+
* Without it a registry entry types its props as any record and a renamed prop
|
|
67
|
+
* is found by the editor, in the preview, at the worst moment.
|
|
68
|
+
*
|
|
69
|
+
* ```ts
|
|
70
|
+
* const registry = { hero: defineFragment(Hero, ({ fields }) => ({ title: String(fields.title ?? '') })) };
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function defineFragment<Props extends object>(component: (props: Props) => unknown, props: (input: FragmentRenderInput) => Props | Promise<Props>): FragmentRegistryEntry<Props>;
|
|
74
|
+
/** Build the endpoint; export it as the `POST` of an App Router route handler. */
|
|
75
|
+
declare function createFragmentEndpoint(options: FragmentEndpointOptions): (request: Request) => Promise<Response>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* `withLivePreview(nextConfig)` — the parts of a Next.js setup that belong in
|
|
79
|
+
* `next.config.ts` rather than in a layout: the admin's host in
|
|
80
|
+
* `allowedDevOrigins`, so Next's dev server does not refuse the admin's own
|
|
81
|
+
* server actions behind a proxy, and `private, no-store` on a request that
|
|
82
|
+
* carries preview intent.
|
|
83
|
+
*
|
|
84
|
+
* What it cannot do is inject the script: no config hook renders HTML. That
|
|
85
|
+
* stays one import and one spread in `app/layout.tsx` (docs/nextjs.md), so this
|
|
86
|
+
* is a two-line setup, not a one-line one — said plainly rather than implied
|
|
87
|
+
* away.
|
|
88
|
+
*
|
|
89
|
+
* **And it writes no CSP.** A config rule cannot run `authorizePreview`, so it
|
|
90
|
+
* can never be the place a privileged response change is decided (ADR 0006 §5).
|
|
91
|
+
* It could not even widen `frame-ancestors` safely: Next collects every
|
|
92
|
+
* matching rule into one object keyed by header name and applies it with
|
|
93
|
+
* `setHeader`, and these rules are appended after the consumer's, so a policy
|
|
94
|
+
* written here replaces the one the site already sends instead of adding to
|
|
95
|
+
* it. Measured on Next.js 16.3.4 (`next build` + `next start`): a site sending
|
|
96
|
+
* `frame-ancestors 'none'` answered a bare `/?preview=true` with
|
|
97
|
+
* `frame-ancestors 'self' <admin>` and nothing else — its `script-src` gone,
|
|
98
|
+
* for anyone who appends the query parameter. `frame-ancestors` for the admin
|
|
99
|
+
* origin is `createLivePreviewMiddleware`'s, which merges into an existing
|
|
100
|
+
* policy and only once the engine has authorized the request.
|
|
101
|
+
*/
|
|
102
|
+
/** The slice of `next.config` this touches; everything else is passed through. */
|
|
103
|
+
interface NextConfigLike {
|
|
104
|
+
readonly allowedDevOrigins?: readonly string[];
|
|
105
|
+
readonly headers?: () => Promise<readonly NextHeaderRule[]> | readonly NextHeaderRule[];
|
|
106
|
+
readonly [option: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
interface NextHeaderRule {
|
|
109
|
+
readonly source: string;
|
|
110
|
+
readonly headers: readonly {
|
|
111
|
+
readonly key: string;
|
|
112
|
+
readonly value: string;
|
|
113
|
+
}[];
|
|
114
|
+
readonly has?: readonly {
|
|
115
|
+
readonly type: string;
|
|
116
|
+
readonly key: string;
|
|
117
|
+
readonly value?: string;
|
|
118
|
+
}[];
|
|
119
|
+
readonly [option: string]: unknown;
|
|
120
|
+
}
|
|
121
|
+
interface WithLivePreviewOptions {
|
|
122
|
+
/** Payload admin origins. Required; their hosts are what `allowedDevOrigins` needs. */
|
|
123
|
+
readonly allowedOrigins: readonly string[];
|
|
124
|
+
/**
|
|
125
|
+
* Query parameters that mark preview intent, matching the runtime's own
|
|
126
|
+
* defaults. The cache header is set only for requests carrying one of them.
|
|
127
|
+
*/
|
|
128
|
+
readonly previewQueryParams?: readonly string[];
|
|
129
|
+
/** Add the admin origins to `allowedDevOrigins`. Default `true`. */
|
|
130
|
+
readonly allowDevOrigins?: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** One rule per intent parameter: Next matches `has` entries as a conjunction. @internal */
|
|
133
|
+
declare function previewHeaderRules(options: WithLivePreviewOptions): readonly NextHeaderRule[];
|
|
134
|
+
/**
|
|
135
|
+
* ```ts
|
|
136
|
+
* // next.config.ts
|
|
137
|
+
* export default withLivePreview(nextConfig, {
|
|
138
|
+
* allowedOrigins: [process.env.NEXT_PUBLIC_PAYLOAD_URL!],
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function withLivePreview(nextConfig: NextConfigLike, options: WithLivePreviewOptions): NextConfigLike;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The route half of `delivery: 'asset'` for Next.js.
|
|
146
|
+
*
|
|
147
|
+
* ```ts
|
|
148
|
+
* // app/payload-live-preview/[file]/route.ts
|
|
149
|
+
* import { createRuntimeAssetRoute } from 'payload-live-preview/nextjs';
|
|
150
|
+
*
|
|
151
|
+
* export const { GET } = createRuntimeAssetRoute();
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* The dynamic segment is what carries the content hash. The handler answers
|
|
155
|
+
* only the file name this package build produces and 404s everything else, so a
|
|
156
|
+
* client holding a year-old `immutable` copy of some other build gets an
|
|
157
|
+
* honest miss rather than different bytes under the same name.
|
|
158
|
+
*
|
|
159
|
+
* No route segment config is exported with it. `dynamic: 'force-static'` would
|
|
160
|
+
* be tempting — the bytes are the same for every request — but on a dynamic
|
|
161
|
+
* segment it asks Next to prerender one arbitrary param at build time. The
|
|
162
|
+
* caching that matters is the response's own `immutable`, which browsers and
|
|
163
|
+
* CDNs honour without Next's help.
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
/** What a route file re-exports. */
|
|
167
|
+
interface RuntimeAssetRoute {
|
|
168
|
+
readonly GET: (request: Request) => Response;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Takes the adapter's own options so the one object can be passed to both
|
|
172
|
+
* halves: only `assetPath` and `runtime` are read, but those two are exactly
|
|
173
|
+
* what the page and the route have to agree on, and `runtime: LEAN_RUNTIME`
|
|
174
|
+
* means the page asks for that artifact's hash.
|
|
175
|
+
*/
|
|
176
|
+
declare function createRuntimeAssetRoute(options?: LivePreviewNextOptions): RuntimeAssetRoute;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* `<LivePreviewScript />` — the delivery that charges an anonymous visitor
|
|
180
|
+
* nothing.
|
|
181
|
+
*
|
|
182
|
+
* A root layout renders for every request, and the two helpers that served it
|
|
183
|
+
* until now build the script whoever is asking: `livePreviewScriptProps()` and
|
|
184
|
+
* `renderLivePreviewScript()` are synchronous, so they cannot wait for a
|
|
185
|
+
* verdict and do not try. That is why the demo answered a `curl` without a
|
|
186
|
+
* cookie with 195 342 of 254 707 bytes of preview runtime — once in the
|
|
187
|
+
* document, once more escaped into the RSC flight payload underneath it.
|
|
188
|
+
*
|
|
189
|
+
* An async server component can wait. This one runs the same policy every
|
|
190
|
+
* adapter runs — intent, then `authorizePreview` — and returns `null` unless
|
|
191
|
+
* the answer is yes. Not a few hundred bytes of bootstrap for the public:
|
|
192
|
+
* nothing, the same as the Astro middleware, the SvelteKit handle and the Nuxt
|
|
193
|
+
* Nitro plugin already deliver.
|
|
194
|
+
*
|
|
195
|
+
* **`next` is not imported here and must not become a dependency.** The
|
|
196
|
+
* component takes the request as a prop, the way `<LivePreviewRouteRefresh />`
|
|
197
|
+
* takes the router's refresh, and the caller builds it from what the framework
|
|
198
|
+
* hands a server component:
|
|
199
|
+
*
|
|
200
|
+
* ```tsx
|
|
201
|
+
* // app/layout.tsx — the App Router
|
|
202
|
+
* import { headers } from 'next/headers';
|
|
203
|
+
* import { LivePreviewScript } from 'payload-live-preview/nextjs';
|
|
204
|
+
*
|
|
205
|
+
* export default async function RootLayout({ children }: { children: ReactNode }) {
|
|
206
|
+
* return (
|
|
207
|
+
* <html lang="en">
|
|
208
|
+
* <head>
|
|
209
|
+
* <LivePreviewScript
|
|
210
|
+
* request={new Request(SITE_URL, { headers: await headers() })}
|
|
211
|
+
* inject="always"
|
|
212
|
+
* allowedOrigins={[ADMIN_URL]}
|
|
213
|
+
* authorizePreview={authorize}
|
|
214
|
+
* />
|
|
215
|
+
* </head>
|
|
216
|
+
* <body>{children}</body>
|
|
217
|
+
* </html>
|
|
218
|
+
* );
|
|
219
|
+
* }
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* A `Request` rather than a shape of our own: it is what `authorizePreview`
|
|
223
|
+
* and `shouldInject` already receive from the middleware, so one options object
|
|
224
|
+
* serves both entry points and neither hook has to be written twice.
|
|
225
|
+
*
|
|
226
|
+
* The URL is the caller's to supply, and the recipe above says why `headers()`
|
|
227
|
+
* alone is not enough: Next gives a server component the request headers and
|
|
228
|
+
* cookies but not its URL, so a layout cannot see `?preview=true` and the
|
|
229
|
+
* `query` signal — the 2.0 default — cannot fire there. `inject: 'always'`
|
|
230
|
+
* then makes `authorizePreview` the single gate, which is the stricter reading
|
|
231
|
+
* anyway and exactly what LP-8 needs. A page, which does get `searchParams`,
|
|
232
|
+
* can pass the real URL and keep intent as the cheap pre-filter it is.
|
|
233
|
+
* docs/nextjs.md carries both recipes.
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
/** What the component takes: every adapter option, plus the request it decides for. */
|
|
237
|
+
interface LivePreviewScriptComponentProps extends LivePreviewNextOptions {
|
|
238
|
+
/**
|
|
239
|
+
* The request this render answers: in the App Router, a `Request` built from
|
|
240
|
+
* the URL and `await headers()`. A promise is accepted so the caller need not
|
|
241
|
+
* resolve `headers()` first.
|
|
242
|
+
*/
|
|
243
|
+
readonly request: Request | Promise<Request>;
|
|
244
|
+
/** CSP nonce for the element, when the application manages one. */
|
|
245
|
+
readonly nonce?: string;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The `<script>` this resolves to, described structurally rather than as
|
|
249
|
+
* `ReactElement`: the entry must not carry React's types any more than its
|
|
250
|
+
* code, and a JSX consumer accepts this shape as a node all the same.
|
|
251
|
+
*/
|
|
252
|
+
interface LivePreviewScriptElement {
|
|
253
|
+
readonly type: 'script';
|
|
254
|
+
readonly props: LivePreviewScriptProps;
|
|
255
|
+
readonly key: null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Renders the runtime for an authorized preview and nothing at all for
|
|
259
|
+
* everyone else. Mount it in the layout or page that owns `<head>`.
|
|
260
|
+
*/
|
|
261
|
+
declare function LivePreviewScript(props: LivePreviewScriptComponentProps): Promise<LivePreviewScriptElement | null>;
|
|
262
|
+
|
|
263
|
+
export { type FragmentEndpointOptions, type FragmentRegistry, type FragmentRegistryEntry, FragmentRenderInput, type FragmentRenderer, type LivePreviewNextOptions, LivePreviewScript, type LivePreviewScriptComponentProps, type LivePreviewScriptElement, type LivePreviewScriptProps, type NextConfigLike, type NextHeaderRule, PreviewAdapterOptions, type ReactComponentLike, type RuntimeAssetRoute, type WithLivePreviewOptions, createFragmentEndpoint, createLivePreviewMiddleware, createRuntimeAssetRoute, defineFragment, livePreviewScriptProps, previewHeaderRules, renderLivePreviewScript, withLivePreview };
|