payload-live-preview 1.0.2 → 1.0.4
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 +150 -84
- package/dist/adapters/astro/RichText.astro +8 -4
- package/dist/adapters/astro/index.d.ts +84 -9
- package/dist/adapters/astro/index.js +1 -363
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.d.ts +1 -1
- package/dist/adapters/astro/middleware-entry.js +1 -296
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.d.ts +24 -10
- package/dist/adapters/nextjs/index.js +1 -305
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +20 -10
- package/dist/adapters/nuxt/index.js +1 -293
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.d.ts +22 -6
- package/dist/adapters/sveltekit/index.js +1 -272
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/codegen-astro.js +1 -609
- package/dist/codegen-astro.js.map +1 -1
- package/dist/codegen-cli.js +1 -665
- package/dist/codegen-cli.js.map +1 -1
- package/dist/codegen.cjs +1 -550
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.js +1 -546
- package/dist/codegen.js.map +1 -1
- package/dist/core.cjs +1 -3719
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1210 -7
- package/dist/core.d.ts +1210 -7
- package/dist/core.js +1 -3692
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -4118
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1359 -34
- package/dist/index.d.ts +1359 -34
- package/dist/index.js +1 -4075
- package/dist/index.js.map +1 -1
- package/dist/{middleware-BwIlf0jW.d.cts → middleware-CkSeLZ-9.d.ts} +35 -19
- package/dist/payload.cjs +1 -30
- package/dist/payload.cjs.map +1 -1
- package/dist/payload.d.cts +4 -3
- package/dist/payload.d.ts +4 -3
- package/dist/payload.js +1 -28
- package/dist/payload.js.map +1 -1
- package/package.json +55 -16
- package/dist/adapters/astro/index.cjs +0 -370
- package/dist/adapters/astro/index.cjs.map +0 -1
- package/dist/adapters/astro/index.d.cts +0 -105
- package/dist/adapters/astro/middleware-entry.cjs +0 -303
- package/dist/adapters/astro/middleware-entry.cjs.map +0 -1
- package/dist/adapters/astro/middleware-entry.d.cts +0 -15
- package/dist/adapters/nextjs/index.cjs +0 -309
- package/dist/adapters/nextjs/index.cjs.map +0 -1
- package/dist/adapters/nextjs/index.d.cts +0 -75
- package/dist/adapters/nuxt/index.cjs +0 -299
- package/dist/adapters/nuxt/index.cjs.map +0 -1
- package/dist/adapters/nuxt/index.d.cts +0 -126
- package/dist/adapters/sveltekit/index.cjs +0 -275
- package/dist/adapters/sveltekit/index.cjs.map +0 -1
- package/dist/adapters/sveltekit/index.d.cts +0 -80
- package/dist/bind-BSgxoQhN.d.cts +0 -1137
- package/dist/bind-BSgxoQhN.d.ts +0 -1137
- package/dist/codegen-astro.cjs +0 -612
- package/dist/codegen-astro.cjs.map +0 -1
- package/dist/codegen-astro.d.cts +0 -54
- package/dist/codegen-cli.cjs +0 -669
- package/dist/codegen-cli.cjs.map +0 -1
- package/dist/codegen-cli.d.cts +0 -19
- package/dist/middleware-BwIlf0jW.d.ts +0 -168
- package/dist/preview-request-DAvxm18T.d.cts +0 -68
- package/dist/preview-request-DAvxm18T.d.ts +0 -68
|
@@ -10,15 +10,20 @@ interface LivePreviewAstroOptions {
|
|
|
10
10
|
* - `'inline'` (default) — bake the runtime into every page at
|
|
11
11
|
* build time. For `output: 'static'` projects.
|
|
12
12
|
* - `'middleware'` — auto-register the preview middleware:
|
|
13
|
-
* request-time injection into preview
|
|
14
|
-
* `frame-ancestors` CSP management. For `output: 'server'`.
|
|
13
|
+
* request-time injection into requests with preview intent,
|
|
14
|
+
* plus `frame-ancestors` CSP management. For `output: 'server'`.
|
|
15
15
|
* (`shouldInject` is unsupported here — options serialize into
|
|
16
16
|
* the build.)
|
|
17
|
+
*
|
|
18
|
+
* Intent signals are not authorization. If either response change
|
|
19
|
+
* must be access-controlled, compose `createLivePreviewMiddleware()`
|
|
20
|
+
* manually after an application-owned server-side authorization.
|
|
17
21
|
*/
|
|
18
22
|
readonly mode?: 'inline' | 'middleware';
|
|
19
23
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
24
|
+
* Allowed Payload admin origin(s) for inbound browser messages and
|
|
25
|
+
* the optional Referer intent signal. This does not authenticate the
|
|
26
|
+
* incoming HTTP request or authorize draft access.
|
|
22
27
|
*/
|
|
23
28
|
readonly allowedOrigins?: readonly string[];
|
|
24
29
|
/**
|
|
@@ -41,10 +46,11 @@ interface LivePreviewAstroOptions {
|
|
|
41
46
|
* When the middleware injects the script (integration-based
|
|
42
47
|
* injection is always build-time and unaffected):
|
|
43
48
|
*
|
|
44
|
-
* - `'preview-only'` (default) — only into responses
|
|
45
|
-
*
|
|
49
|
+
* - `'preview-only'` (default) — only into responses carrying a
|
|
50
|
+
* preview-intent signal (`?preview=true` / `?draft=true` query,
|
|
46
51
|
* `Sec-Fetch-Dest: iframe`, or a referer from `allowedOrigins`).
|
|
47
|
-
*
|
|
52
|
+
* These client-controlled signals are a delivery optimisation,
|
|
53
|
+
* not authorization.
|
|
48
54
|
* - `'always'` — into every HTML response.
|
|
49
55
|
*/
|
|
50
56
|
readonly inject?: 'preview-only' | 'always';
|
|
@@ -54,7 +60,7 @@ interface LivePreviewAstroOptions {
|
|
|
54
60
|
*/
|
|
55
61
|
readonly previewQueryParams?: readonly string[];
|
|
56
62
|
/**
|
|
57
|
-
* Which signals count as
|
|
63
|
+
* Which signals count as preview intent. Default: all three
|
|
58
64
|
* (`query`, `fetch-dest`, `referer`). Restrict to `['query']` when
|
|
59
65
|
* an unsolicited iframe load must never trigger preview handling
|
|
60
66
|
* (e.g. sites that serve `frame-ancestors 'none'` and only allow
|
|
@@ -62,12 +68,17 @@ interface LivePreviewAstroOptions {
|
|
|
62
68
|
*/
|
|
63
69
|
readonly previewSignals?: readonly ('query' | 'fetch-dest' | 'referer')[];
|
|
64
70
|
/**
|
|
65
|
-
* Restrict
|
|
66
|
-
* `true`. Applied on top of the `inject` mode.
|
|
71
|
+
* Restrict script injection to requests where this function returns
|
|
72
|
+
* `true`. Applied on top of the `inject` mode. This is a synchronous
|
|
73
|
+
* route/content filter, not authentication, and it does not suppress
|
|
74
|
+
* the adapter's CSP handling. Perform authorization before invoking
|
|
75
|
+
* the middleware.
|
|
67
76
|
*/
|
|
68
77
|
readonly shouldInject?: (request: Request) => boolean;
|
|
69
78
|
/**
|
|
70
|
-
* Content-Security-Policy management on preview
|
|
79
|
+
* Content-Security-Policy management on responses carrying preview
|
|
80
|
+
* intent. The adapter does not authenticate those requests; invoke
|
|
81
|
+
* it only after authorization when this policy change is privileged:
|
|
71
82
|
*
|
|
72
83
|
* - `'frame-ancestors'` (default) — merge a `frame-ancestors`
|
|
73
84
|
* directive allowing the admin origins to embed the page.
|
|
@@ -99,9 +110,7 @@ interface LivePreviewAstroOptions {
|
|
|
99
110
|
* (only with `manageCsp: 'full'`).
|
|
100
111
|
*/
|
|
101
112
|
readonly scriptSrcExtra?: readonly string[];
|
|
102
|
-
/**
|
|
103
|
-
* Enable verbose debug logging in the injected client. Default: dev mode.
|
|
104
|
-
*/
|
|
113
|
+
/** Enable verbose debug logging in the injected client. Defaults to `false`. */
|
|
105
114
|
readonly debug?: boolean;
|
|
106
115
|
/**
|
|
107
116
|
* Debounce window for incoming updates. Default: 50 ms.
|
|
@@ -122,15 +131,22 @@ interface LivePreviewAstroOptions {
|
|
|
122
131
|
*
|
|
123
132
|
* 1. Generate a per-response CSP nonce and stash it on
|
|
124
133
|
* `Astro.locals.livePreviewNonce` so consumers can reference it.
|
|
125
|
-
* 2. On **preview
|
|
126
|
-
* the HTML response to inject the
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* 3. On preview requests, merge `frame-ancestors` into the
|
|
134
|
+
* 2. On requests carrying **preview intent** (see
|
|
135
|
+
* `isPreviewRequest`), rewrite the HTML response to inject the
|
|
136
|
+
* live-preview `<script>` tag.
|
|
137
|
+
* 3. On those requests, merge `frame-ancestors` into the
|
|
130
138
|
* `Content-Security-Policy` header so the Payload admin may embed
|
|
131
139
|
* the page. Full `script-src` nonce management is opt-in via
|
|
132
140
|
* `manageCsp: 'full'`.
|
|
133
141
|
*
|
|
142
|
+
* The intent signals are client-controlled and this middleware does
|
|
143
|
+
* not authenticate them. For protected preview responses, first verify
|
|
144
|
+
* an application-owned server session or short-lived authorization,
|
|
145
|
+
* then invoke this middleware with that same decision also governing
|
|
146
|
+
* draft reads, credentials, and cache policy. `shouldInject` filters
|
|
147
|
+
* script insertion only; it is not an authorization boundary and does
|
|
148
|
+
* not disable CSP handling.
|
|
149
|
+
*
|
|
134
150
|
* Prerendered pages are skipped entirely: Astro runs middleware at
|
|
135
151
|
* build time for those, where per-request nonces and response headers
|
|
136
152
|
* are meaningless.
|
package/dist/payload.cjs
CHANGED
|
@@ -1,31 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// src/payload/index.ts
|
|
4
|
-
function buildLivePreviewUrl(options) {
|
|
5
|
-
const base = options.baseUrl.replace(/\/+$/, "");
|
|
6
|
-
const fallback = options.fallback ?? "/";
|
|
7
|
-
const previewParam = options.previewParam === void 0 ? "preview" : options.previewParam;
|
|
8
|
-
return (args) => {
|
|
9
|
-
const locale = normaliseLocale(args.locale);
|
|
10
|
-
const context = { data: args.data, locale };
|
|
11
|
-
const resolver = (args.collectionConfig !== void 0 ? options.collections?.[args.collectionConfig.slug] : void 0) ?? (args.globalConfig !== void 0 ? options.globals?.[args.globalConfig.slug] : void 0);
|
|
12
|
-
let path = fallback;
|
|
13
|
-
if (resolver !== void 0) {
|
|
14
|
-
const resolved = typeof resolver === "function" ? resolver(context) : resolver;
|
|
15
|
-
if (resolved.length > 0) path = resolved;
|
|
16
|
-
}
|
|
17
|
-
if (!path.startsWith("/")) path = `/${path}`;
|
|
18
|
-
if (previewParam === null) return `${base}${path}`;
|
|
19
|
-
const separator = path.includes("?") ? "&" : "?";
|
|
20
|
-
return `${base}${path}${separator}${previewParam}=true`;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function normaliseLocale(locale) {
|
|
24
|
-
if (locale === void 0) return void 0;
|
|
25
|
-
if (typeof locale === "string") return locale.length > 0 ? locale : void 0;
|
|
26
|
-
return locale.code.length > 0 ? locale.code : void 0;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
exports.buildLivePreviewUrl = buildLivePreviewUrl;
|
|
30
|
-
//# sourceMappingURL=payload.cjs.map
|
|
1
|
+
"use strict";var g=Object.defineProperty,o=(e,l)=>g(e,"name",{value:l,configurable:!0});function y(e){let l=e.baseUrl.replace(/\/+$/,""),o=e.fallback??"/",i=void 0===e.previewParam?"preview":e.previewParam;return t=>{let r=u(t.locale),n={data:t.data,locale:r},a=(void 0!==t.collectionConfig?e.collections?.[t.collectionConfig.slug]:void 0)??(void 0!==t.globalConfig?e.globals?.[t.globalConfig.slug]:void 0),c=o;if(void 0!==a){let e="function"==typeof a?a(n):a;e.length>0&&(c=e)}if(c.startsWith("/")||(c=`/${c}`),null===i)return`${l}${c}`;let v=c.includes("?")?"&":"?";return`${l}${c}${v}${i}=true`}}function u(e){if(void 0!==e)return"string"==typeof e?e.length>0?e:void 0:e.code.length>0?e.code:void 0}o(y,"buildLivePreviewUrl"),o(u,"normaliseLocale"),exports.buildLivePreviewUrl=y;
|
|
31
2
|
//# sourceMappingURL=payload.cjs.map
|
package/dist/payload.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"payload.cjs","names":["g","Object","defineProperty","o","e","t","value","configurable","buildLivePreviewUrl","options","base","baseUrl","replace","fallback","previewParam","args","locale","normaliseLocale","context","data","resolver","collectionConfig","collections","slug","globalConfig","globals","path","resolved","length","startsWith","separator","includes","code","__name","exports","y"],"sources":["../src/payload/index.ts"],"sourcesContent":["/**\n * Backend-side helpers for `payload.config.ts`.\n *\n * Payload's `admin.livePreview.url` callback maps the document being\n * edited to the frontend URL that should be shown in the preview\n * iframe. In practice every project hand-writes the same lookup-table\n * boilerplate (global → path, collection → localized route, fallback\n * when a new draft has no slug yet). `buildLivePreviewUrl` packages\n * that pattern.\n *\n * This module is dependency-free and framework-agnostic — it does not\n * import `payload`, it just produces a function with the documented\n * callback shape.\n *\n * ```ts\n * // payload.config.ts\n * import { buildLivePreviewUrl } from 'payload-live-preview/payload';\n *\n * admin: {\n * livePreview: {\n * url: buildLivePreviewUrl({\n * baseUrl: process.env.FRONTEND_URL ?? 'http://localhost:4321',\n * collections: {\n * services: ({ data, locale }) => `/${locale}/services/${String(data.slug ?? '')}`,\n * posts: ({ data }) => `/blog/${String(data.slug ?? '')}`,\n * },\n * globals: {\n * homepage: '/',\n * contact: ({ locale }) => `/${locale}/contact`,\n * },\n * fallback: '/',\n * }),\n * collections: ['services', 'posts'],\n * globals: ['homepage', 'contact'],\n * },\n * }\n * ```\n *\n * @module @payload\n */\n\n/** Arguments Payload passes to `admin.livePreview.url`. */\nexport interface LivePreviewUrlArgs {\n readonly data: Record<string, unknown>;\n readonly locale?: string | { readonly code: string };\n readonly collectionConfig?: { readonly slug: string };\n readonly globalConfig?: { readonly slug: string };\n readonly [extra: string]: unknown;\n}\n\n/** Context handed to per-slug path resolvers. */\nexport interface PathResolverContext {\n readonly data: Record<string, unknown>;\n /** Normalised locale code (string), or `undefined`. */\n readonly locale: string | undefined;\n}\n\nexport type PathResolver = string | ((context: PathResolverContext) => string);\n\nexport interface BuildLivePreviewUrlOptions {\n /** Frontend origin, e.g. `https://site.example` (no trailing slash needed). */\n readonly baseUrl: string;\n /** Per-collection path resolvers keyed by collection slug. */\n readonly collections?: Readonly<Record<string, PathResolver>>;\n /** Per-global path resolvers keyed by global slug. */\n readonly globals?: Readonly<Record<string, PathResolver>>;\n /**\n * Path used when no resolver matches, or when a resolver returns an\n * empty string (e.g. a brand-new draft without a slug). Default `/`.\n */\n readonly fallback?: string;\n /**\n * Query parameter appended so the frontend can detect preview intent\n * (`isPreviewRequest` checks it). This client-controlled signal does\n * not authenticate or authorize draft access or response changes.\n * Set `null` to disable. Default `'preview'` → `?preview=true`.\n */\n readonly previewParam?: string | null;\n}\n\n/**\n * Build an `admin.livePreview.url` callback from declarative slug →\n * path mappings.\n */\nexport function buildLivePreviewUrl(\n options: BuildLivePreviewUrlOptions,\n): (args: LivePreviewUrlArgs) => string {\n const base = options.baseUrl.replace(/\\/+$/, '');\n const fallback = options.fallback ?? '/';\n const previewParam = options.previewParam === undefined ? 'preview' : options.previewParam;\n\n return (args) => {\n const locale = normaliseLocale(args.locale);\n const context: PathResolverContext = { data: args.data, locale };\n\n const resolver =\n (args.collectionConfig !== undefined\n ? options.collections?.[args.collectionConfig.slug]\n : undefined) ??\n (args.globalConfig !== undefined ? options.globals?.[args.globalConfig.slug] : undefined);\n\n let path = fallback;\n if (resolver !== undefined) {\n const resolved = typeof resolver === 'function' ? resolver(context) : resolver;\n if (resolved.length > 0) path = resolved;\n }\n if (!path.startsWith('/')) path = `/${path}`;\n\n if (previewParam === null) return `${base}${path}`;\n const separator = path.includes('?') ? '&' : '?';\n return `${base}${path}${separator}${previewParam}=true`;\n };\n}\n\nfunction normaliseLocale(locale: LivePreviewUrlArgs['locale']): string | undefined {\n if (locale === undefined) return undefined;\n if (typeof locale === 'string') return locale.length > 0 ? locale : undefined;\n return locale.code.length > 0 ? locale.code : undefined;\n}\n"],"mappings":"aAoFO,IAAAA,EAAAC,OAAAC,eAAAC,EAAA,CAAAC,EAAAC,IAAAL,EAAAI,EAAA,QAAAE,MAAAD,EAAAE,cAAA,aAASC,EACdC,GAEA,IAAMC,EAAOD,EAAQE,QAAQC,QAAQ,OAAQ,IACvCC,EAAWJ,EAAQI,UAAY,IAC/BC,OAAwC,IAAzBL,EAAQK,aAA6B,UAAYL,EAAQK,aAE9E,OAAQC,IACN,IAAMC,EAASC,EAAgBF,EAAKC,QAC9BE,EAA+B,CAAEC,KAAMJ,EAAKI,KAAMH,UAElDI,QACuB,IAA1BL,EAAKM,iBACFZ,EAAQa,cAAcP,EAAKM,iBAAiBE,WAC5C,UACmB,IAAtBR,EAAKS,aAA6Bf,EAAQgB,UAAUV,EAAKS,aAAaD,WAAQ,GAE7EG,EAAOb,EACX,QAAiB,IAAbO,EAAwB,CAC1B,IAAMO,EAA+B,mBAAbP,EAA0BA,EAASF,GAAWE,EAClEO,EAASC,OAAS,IAAGF,EAAOC,EAClC,CAGA,GAFKD,EAAKG,WAAW,OAAMH,EAAO,IAAIA,KAEjB,OAAjBZ,EAAuB,MAAO,GAAGJ,IAAOgB,IAC5C,IAAMI,EAAYJ,EAAKK,SAAS,KAAO,IAAM,IAC7C,MAAO,GAAGrB,IAAOgB,IAAOI,IAAYhB,SAExC,CAEA,SAASG,EAAgBD,GACvB,QAAe,IAAXA,EACJ,MAAsB,iBAAXA,EAA4BA,EAAOY,OAAS,EAAIZ,OAAS,EAC7DA,EAAOgB,KAAKJ,OAAS,EAAIZ,EAAOgB,UAAO,CAChD,CAlCgBC,EAAAzB,EAAA,uBA8BPyB,EAAAhB,EAAA,mBAAAiB,QAAA1B,oBAAA2B","ignoreList":[]}
|
package/dist/payload.d.cts
CHANGED
|
@@ -72,9 +72,10 @@ interface BuildLivePreviewUrlOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
readonly fallback?: string;
|
|
74
74
|
/**
|
|
75
|
-
* Query parameter appended so the frontend can
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* Query parameter appended so the frontend can detect preview intent
|
|
76
|
+
* (`isPreviewRequest` checks it). This client-controlled signal does
|
|
77
|
+
* not authenticate or authorize draft access or response changes.
|
|
78
|
+
* Set `null` to disable. Default `'preview'` → `?preview=true`.
|
|
78
79
|
*/
|
|
79
80
|
readonly previewParam?: string | null;
|
|
80
81
|
}
|
package/dist/payload.d.ts
CHANGED
|
@@ -72,9 +72,10 @@ interface BuildLivePreviewUrlOptions {
|
|
|
72
72
|
*/
|
|
73
73
|
readonly fallback?: string;
|
|
74
74
|
/**
|
|
75
|
-
* Query parameter appended so the frontend can
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* Query parameter appended so the frontend can detect preview intent
|
|
76
|
+
* (`isPreviewRequest` checks it). This client-controlled signal does
|
|
77
|
+
* not authenticate or authorize draft access or response changes.
|
|
78
|
+
* Set `null` to disable. Default `'preview'` → `?preview=true`.
|
|
78
79
|
*/
|
|
79
80
|
readonly previewParam?: string | null;
|
|
80
81
|
}
|
package/dist/payload.js
CHANGED
|
@@ -1,29 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
function buildLivePreviewUrl(options) {
|
|
3
|
-
const base = options.baseUrl.replace(/\/+$/, "");
|
|
4
|
-
const fallback = options.fallback ?? "/";
|
|
5
|
-
const previewParam = options.previewParam === void 0 ? "preview" : options.previewParam;
|
|
6
|
-
return (args) => {
|
|
7
|
-
const locale = normaliseLocale(args.locale);
|
|
8
|
-
const context = { data: args.data, locale };
|
|
9
|
-
const resolver = (args.collectionConfig !== void 0 ? options.collections?.[args.collectionConfig.slug] : void 0) ?? (args.globalConfig !== void 0 ? options.globals?.[args.globalConfig.slug] : void 0);
|
|
10
|
-
let path = fallback;
|
|
11
|
-
if (resolver !== void 0) {
|
|
12
|
-
const resolved = typeof resolver === "function" ? resolver(context) : resolver;
|
|
13
|
-
if (resolved.length > 0) path = resolved;
|
|
14
|
-
}
|
|
15
|
-
if (!path.startsWith("/")) path = `/${path}`;
|
|
16
|
-
if (previewParam === null) return `${base}${path}`;
|
|
17
|
-
const separator = path.includes("?") ? "&" : "?";
|
|
18
|
-
return `${base}${path}${separator}${previewParam}=true`;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function normaliseLocale(locale) {
|
|
22
|
-
if (locale === void 0) return void 0;
|
|
23
|
-
if (typeof locale === "string") return locale.length > 0 ? locale : void 0;
|
|
24
|
-
return locale.code.length > 0 ? locale.code : void 0;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { buildLivePreviewUrl };
|
|
28
|
-
//# sourceMappingURL=payload.js.map
|
|
1
|
+
var e=Object.defineProperty,l=(l,i)=>e(l,"name",{value:i,configurable:!0});function i(e){let l=e.baseUrl.replace(/\/+$/,""),i=e.fallback??"/",t=void 0===e.previewParam?"preview":e.previewParam;return r=>{let n=o(r.locale),a={data:r.data,locale:n},c=(void 0!==r.collectionConfig?e.collections?.[r.collectionConfig.slug]:void 0)??(void 0!==r.globalConfig?e.globals?.[r.globalConfig.slug]:void 0),v=i;if(void 0!==c){let e="function"==typeof c?c(a):c;e.length>0&&(v=e)}if(v.startsWith("/")||(v=`/${v}`),null===t)return`${l}${v}`;let d=v.includes("?")?"&":"?";return`${l}${v}${d}${t}=true`}}function o(e){if(void 0!==e)return"string"==typeof e?e.length>0?e:void 0:e.code.length>0?e.code:void 0}l(i,"buildLivePreviewUrl"),l(o,"normaliseLocale");export{i as buildLivePreviewUrl};
|
|
29
2
|
//# sourceMappingURL=payload.js.map
|
package/dist/payload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"payload.js","names":["g","Object","defineProperty","o","e","t","value","configurable","buildLivePreviewUrl","options","base","baseUrl","replace","fallback","previewParam","args","locale","normaliseLocale","context","data","resolver","collectionConfig","collections","slug","globalConfig","globals","path","resolved","length","startsWith","separator","includes","code","__name","y"],"sources":["../src/payload/index.ts"],"sourcesContent":["/**\n * Backend-side helpers for `payload.config.ts`.\n *\n * Payload's `admin.livePreview.url` callback maps the document being\n * edited to the frontend URL that should be shown in the preview\n * iframe. In practice every project hand-writes the same lookup-table\n * boilerplate (global → path, collection → localized route, fallback\n * when a new draft has no slug yet). `buildLivePreviewUrl` packages\n * that pattern.\n *\n * This module is dependency-free and framework-agnostic — it does not\n * import `payload`, it just produces a function with the documented\n * callback shape.\n *\n * ```ts\n * // payload.config.ts\n * import { buildLivePreviewUrl } from 'payload-live-preview/payload';\n *\n * admin: {\n * livePreview: {\n * url: buildLivePreviewUrl({\n * baseUrl: process.env.FRONTEND_URL ?? 'http://localhost:4321',\n * collections: {\n * services: ({ data, locale }) => `/${locale}/services/${String(data.slug ?? '')}`,\n * posts: ({ data }) => `/blog/${String(data.slug ?? '')}`,\n * },\n * globals: {\n * homepage: '/',\n * contact: ({ locale }) => `/${locale}/contact`,\n * },\n * fallback: '/',\n * }),\n * collections: ['services', 'posts'],\n * globals: ['homepage', 'contact'],\n * },\n * }\n * ```\n *\n * @module @payload\n */\n\n/** Arguments Payload passes to `admin.livePreview.url`. */\nexport interface LivePreviewUrlArgs {\n readonly data: Record<string, unknown>;\n readonly locale?: string | { readonly code: string };\n readonly collectionConfig?: { readonly slug: string };\n readonly globalConfig?: { readonly slug: string };\n readonly [extra: string]: unknown;\n}\n\n/** Context handed to per-slug path resolvers. */\nexport interface PathResolverContext {\n readonly data: Record<string, unknown>;\n /** Normalised locale code (string), or `undefined`. */\n readonly locale: string | undefined;\n}\n\nexport type PathResolver = string | ((context: PathResolverContext) => string);\n\nexport interface BuildLivePreviewUrlOptions {\n /** Frontend origin, e.g. `https://site.example` (no trailing slash needed). */\n readonly baseUrl: string;\n /** Per-collection path resolvers keyed by collection slug. */\n readonly collections?: Readonly<Record<string, PathResolver>>;\n /** Per-global path resolvers keyed by global slug. */\n readonly globals?: Readonly<Record<string, PathResolver>>;\n /**\n * Path used when no resolver matches, or when a resolver returns an\n * empty string (e.g. a brand-new draft without a slug). Default `/`.\n */\n readonly fallback?: string;\n /**\n * Query parameter appended so the frontend can detect preview intent\n * (`isPreviewRequest` checks it). This client-controlled signal does\n * not authenticate or authorize draft access or response changes.\n * Set `null` to disable. Default `'preview'` → `?preview=true`.\n */\n readonly previewParam?: string | null;\n}\n\n/**\n * Build an `admin.livePreview.url` callback from declarative slug →\n * path mappings.\n */\nexport function buildLivePreviewUrl(\n options: BuildLivePreviewUrlOptions,\n): (args: LivePreviewUrlArgs) => string {\n const base = options.baseUrl.replace(/\\/+$/, '');\n const fallback = options.fallback ?? '/';\n const previewParam = options.previewParam === undefined ? 'preview' : options.previewParam;\n\n return (args) => {\n const locale = normaliseLocale(args.locale);\n const context: PathResolverContext = { data: args.data, locale };\n\n const resolver =\n (args.collectionConfig !== undefined\n ? options.collections?.[args.collectionConfig.slug]\n : undefined) ??\n (args.globalConfig !== undefined ? options.globals?.[args.globalConfig.slug] : undefined);\n\n let path = fallback;\n if (resolver !== undefined) {\n const resolved = typeof resolver === 'function' ? resolver(context) : resolver;\n if (resolved.length > 0) path = resolved;\n }\n if (!path.startsWith('/')) path = `/${path}`;\n\n if (previewParam === null) return `${base}${path}`;\n const separator = path.includes('?') ? '&' : '?';\n return `${base}${path}${separator}${previewParam}=true`;\n };\n}\n\nfunction normaliseLocale(locale: LivePreviewUrlArgs['locale']): string | undefined {\n if (locale === undefined) return undefined;\n if (typeof locale === 'string') return locale.length > 0 ? locale : undefined;\n return locale.code.length > 0 ? locale.code : undefined;\n}\n"],"mappings":"AAoFO,IAAAA,EAAAC,OAAAC,eAAAC,EAAA,CAAAC,EAAAC,IAAAL,EAAAI,EAAA,QAAAE,MAAAD,EAAAE,cAAA,aAASC,EACdC,GAEA,IAAMC,EAAOD,EAAQE,QAAQC,QAAQ,OAAQ,IACvCC,EAAWJ,EAAQI,UAAY,IAC/BC,OAAwC,IAAzBL,EAAQK,aAA6B,UAAYL,EAAQK,aAE9E,OAAQC,IACN,IAAMC,EAASC,EAAgBF,EAAKC,QAC9BE,EAA+B,CAAEC,KAAMJ,EAAKI,KAAMH,UAElDI,QACuB,IAA1BL,EAAKM,iBACFZ,EAAQa,cAAcP,EAAKM,iBAAiBE,WAC5C,UACmB,IAAtBR,EAAKS,aAA6Bf,EAAQgB,UAAUV,EAAKS,aAAaD,WAAQ,GAE7EG,EAAOb,EACX,QAAiB,IAAbO,EAAwB,CAC1B,IAAMO,EAA+B,mBAAbP,EAA0BA,EAASF,GAAWE,EAClEO,EAASC,OAAS,IAAGF,EAAOC,EAClC,CAGA,GAFKD,EAAKG,WAAW,OAAMH,EAAO,IAAIA,KAEjB,OAAjBZ,EAAuB,MAAO,GAAGJ,IAAOgB,IAC5C,IAAMI,EAAYJ,EAAKK,SAAS,KAAO,IAAM,IAC7C,MAAO,GAAGrB,IAAOgB,IAAOI,IAAYhB,SAExC,CAEA,SAASG,EAAgBD,GACvB,QAAe,IAAXA,EACJ,MAAsB,iBAAXA,EAA4BA,EAAOY,OAAS,EAAIZ,OAAS,EAC7DA,EAAOgB,KAAKJ,OAAS,EAAIZ,EAAOgB,UAAO,CAChD,CAlCgBC,EAAAzB,EAAA,uBA8BPyB,EAAAhB,EAAA,0BAAAiB","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload-live-preview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Live preview for Payload CMS in Astro and any SSR/static frontend (SvelteKit, Nuxt, Next.js, plain HTML). Patches the DOM live, no rebuild.",
|
|
5
5
|
"author": "relative23",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"packageManager": "npm@11.16.0",
|
|
8
9
|
"main": "./dist/index.cjs",
|
|
9
10
|
"module": "./dist/index.js",
|
|
10
11
|
"types": "./dist/index.d.ts",
|
|
@@ -97,9 +98,8 @@
|
|
|
97
98
|
],
|
|
98
99
|
"sideEffects": false,
|
|
99
100
|
"scripts": {
|
|
100
|
-
"prepare": "npm run build:runtime",
|
|
101
101
|
"build:runtime": "tsx scripts/build-runtime.ts",
|
|
102
|
-
"build": "npm run build:runtime &&
|
|
102
|
+
"build": "npm run build:runtime && tsx scripts/build-dist.ts && npm run build:assets && npm run test:bundle",
|
|
103
103
|
"build:assets": "node -e \"require('node:fs').copyFileSync('src/adapters/astro/RichText.astro','dist/adapters/astro/RichText.astro')\"",
|
|
104
104
|
"dev": "tsup --watch",
|
|
105
105
|
"test": "vitest run",
|
|
@@ -107,37 +107,76 @@
|
|
|
107
107
|
"test:unit": "vitest run tests/unit",
|
|
108
108
|
"test:integration": "vitest run tests/integration",
|
|
109
109
|
"test:e2e": "playwright test",
|
|
110
|
+
"test:e2e:real-payload": "playwright test --config playwright.real-payload.config.ts",
|
|
111
|
+
"test:a11y": "playwright test tests/e2e/specs/accessibility.spec.ts",
|
|
112
|
+
"test:soak": "playwright test --config playwright.soak.config.ts",
|
|
110
113
|
"test:bench": "vitest bench tests/benchmarks",
|
|
114
|
+
"test:bench:codspeed": "vitest bench --run --config vitest.bench.config.ts",
|
|
115
|
+
"test:bundle": "tsx scripts/check-bundle-size.ts",
|
|
116
|
+
"test:package": "tsx scripts/check-package.ts",
|
|
111
117
|
"test:coverage": "vitest run --coverage",
|
|
118
|
+
"test:coverage:diff": "tsx scripts/coverage-policy.ts",
|
|
119
|
+
"test:policy": "tsx scripts/test-policy.ts",
|
|
120
|
+
"test:architecture": "tsx scripts/architecture-policy.ts && tsx scripts/quality-workflow-policy.ts && knip --no-progress --treat-config-hints-as-errors",
|
|
121
|
+
"test:property": "vitest run tests/unit/property",
|
|
122
|
+
"test:mutation": "stryker run stryker.config.js",
|
|
123
|
+
"test:mutation:policy:pr": "tsx scripts/mutation-policy.ts --policy quality/mutation-policy-pr.json --report test-results/stryker-pr.json",
|
|
124
|
+
"test:mutation:policy": "tsx scripts/mutation-policy.ts",
|
|
125
|
+
"test:leak": "node --expose-gc --import tsx scripts/leak-soak.ts",
|
|
126
|
+
"test:leak:quick": "node --expose-gc --import tsx scripts/leak-soak.ts --quick",
|
|
127
|
+
"api:update": "npm run build && tsx scripts/check-package.ts --update-api-reports",
|
|
112
128
|
"typecheck": "tsc --noEmit",
|
|
113
129
|
"lint": "eslint .",
|
|
114
130
|
"lint:fix": "eslint . --fix",
|
|
115
|
-
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
116
|
-
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
117
|
-
"check": "npm run typecheck && npm run lint && npm run test",
|
|
118
|
-
"prepublishOnly": "npm run check && npm run
|
|
131
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.ts\" \"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\" \"quality/**/*.json\" \"docs/**/*.md\" \"type-tests/**/*.md\" \".prettierrc.json\" \".changeset/*.{json,md}\" \".github/**/*.{yml,yaml,json}\" \"examples/**/*.{ts,tsx,js,cjs,mjs,json}\" && prettier --write \"type-tests/packed/*.fixture\" --parser typescript",
|
|
132
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.ts\" \"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\" \"quality/**/*.json\" \"docs/**/*.md\" \"type-tests/**/*.md\" \".prettierrc.json\" \".changeset/*.{json,md}\" \".github/**/*.{yml,yaml,json}\" \"examples/**/*.{ts,tsx,js,cjs,mjs,json}\" && prettier --check \"type-tests/packed/*.fixture\" --parser typescript",
|
|
133
|
+
"check": "npm run typecheck && npm run lint && npm run test:policy && npm run test:architecture && npm run test",
|
|
134
|
+
"prepublishOnly": "npm run build && npm run check && npm run format:check && npm run test:package",
|
|
119
135
|
"changeset": "changeset",
|
|
120
136
|
"version": "changeset version",
|
|
121
|
-
"release": "
|
|
137
|
+
"release": "tsx scripts/publish-artifact.ts"
|
|
122
138
|
},
|
|
123
139
|
"devDependencies": {
|
|
124
|
-
"@
|
|
140
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
141
|
+
"@axe-core/playwright": "^4.13.0",
|
|
142
|
+
"@changesets/cli": "^2.31.1",
|
|
143
|
+
"@codspeed/vitest-plugin": "^5.7.1",
|
|
125
144
|
"@eslint/js": "^10.0.1",
|
|
126
|
-
"@
|
|
145
|
+
"@fast-check/vitest": "^0.4.1",
|
|
146
|
+
"@microsoft/api-extractor": "^7.58.12",
|
|
147
|
+
"@playwright/test": "^1.62.1",
|
|
148
|
+
"@stryker-mutator/core": "^9.6.1",
|
|
149
|
+
"@stryker-mutator/vitest-runner": "^9.6.1",
|
|
150
|
+
"@types/jsdom": "^30.0.0",
|
|
127
151
|
"@types/node": "^22.20.1",
|
|
128
152
|
"@vitest/coverage-v8": "^4.1.10",
|
|
129
|
-
"esbuild": "^0.28.
|
|
130
|
-
"eslint": "^10.
|
|
131
|
-
"
|
|
153
|
+
"esbuild": "^0.28.2",
|
|
154
|
+
"eslint": "^10.8.1",
|
|
155
|
+
"fast-check": "^4.9.0",
|
|
156
|
+
"globals": "^17.11.0",
|
|
132
157
|
"jsdom": "^29.1.1",
|
|
133
|
-
"
|
|
158
|
+
"knip": "^6.32.2",
|
|
159
|
+
"prettier": "^3.9.6",
|
|
160
|
+
"publint": "^0.3.23",
|
|
161
|
+
"terser": "^5.46.1",
|
|
134
162
|
"ts-morph": "^28.0.0",
|
|
135
163
|
"tsup": "^8.5.1",
|
|
136
|
-
"tsx": "^4.23.
|
|
164
|
+
"tsx": "^4.23.12",
|
|
137
165
|
"typescript": "^5.9.3",
|
|
138
|
-
"typescript-eslint": "^8.
|
|
166
|
+
"typescript-eslint": "^8.67.0",
|
|
139
167
|
"vitest": "^4.1.10"
|
|
140
168
|
},
|
|
169
|
+
"overrides": {
|
|
170
|
+
"qs": "6.15.3",
|
|
171
|
+
"tsup": {
|
|
172
|
+
"esbuild": "0.28.2"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"allowScripts": {
|
|
176
|
+
"esbuild@0.28.2": true,
|
|
177
|
+
"fsevents@2.3.2": false,
|
|
178
|
+
"fsevents@2.3.3": false
|
|
179
|
+
},
|
|
141
180
|
"keywords": [
|
|
142
181
|
"astro",
|
|
143
182
|
"astro-payload",
|