payload-live-preview 2.3.2 → 2.4.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 +13 -46
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/client.d.ts +28 -0
- package/dist/adapters/nextjs/client.js +3 -0
- package/dist/adapters/nextjs/client.js.map +1 -0
- package/dist/adapters/nextjs/index.d.ts +34 -12
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/client.d.ts +29 -0
- package/dist/adapters/nuxt/client.js +2 -0
- package/dist/adapters/nuxt/client.js.map +1 -0
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +23 -3
- package/dist/adapters/nuxt/module.js +1 -1
- package/dist/adapters/nuxt/module.js.map +1 -1
- package/dist/adapters/react/index.d.ts +2 -2
- package/dist/adapters/react/index.js +1 -1
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/sveltekit/client.d.ts +37 -0
- package/dist/adapters/sveltekit/client.js +2 -0
- package/dist/adapters/sveltekit/client.js.map +1 -0
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +2 -2
- package/dist/adapters/vue/index.js +1 -1
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +7 -1
- package/dist/core.d.ts +7 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/{document-session-BuYuO3ae.d.ts → document-session-oK92QjES.d.ts} +7 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +1 -1
- package/dist/lean.cjs.map +1 -1
- package/dist/lean.js +1 -1
- package/dist/lean.js.map +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.js.map +1 -1
- package/package.json +23 -1
|
@@ -18,8 +18,10 @@ import { P as PreviewAdapterOptions, a as PreviewRequestLike } from '../../optio
|
|
|
18
18
|
* A Nuxt module is a plain function of `(inlineOptions, nuxt)`; `defineNuxtModule`
|
|
19
19
|
* from `@nuxt/kit` is sugar around exactly that. Writing the function keeps
|
|
20
20
|
* `@nuxt/kit` out of the dependency list — this package adapts Nuxt, it does not
|
|
21
|
-
* build with it — and keeps the module readable as the
|
|
22
|
-
*
|
|
21
|
+
* build with it — and keeps the module readable as the things it does: take the
|
|
22
|
+
* options, register a Nitro plugin written from them, and register the client
|
|
23
|
+
* plugin that tells the runtime about client navigations (since 2.4; before,
|
|
24
|
+
* docs/nuxt.md had the project copy it).
|
|
23
25
|
*
|
|
24
26
|
* The plugin is generated rather than shipped. The module runs at build time and
|
|
25
27
|
* the plugin runs per request in Nitro's own bundle, so the options cannot travel
|
|
@@ -50,6 +52,13 @@ type LivePreviewModuleOptions = Omit<PreviewAdapterOptions<PreviewRequestLike>,
|
|
|
50
52
|
* specifier is passed to Nitro unchanged.
|
|
51
53
|
*/
|
|
52
54
|
readonly authorizePreviewModule?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the module registers its client plugin for client navigations and
|
|
57
|
+
* route refreshes (`payload-live-preview/nuxt/client`). On by default; a
|
|
58
|
+
* project that still has the plugin docs/nuxt.md had it copy before 2.4
|
|
59
|
+
* keeps its own, and the module registers nothing beside it.
|
|
60
|
+
*/
|
|
61
|
+
readonly navigation?: boolean;
|
|
53
62
|
};
|
|
54
63
|
/** The Nitro config slice this module writes into. */
|
|
55
64
|
interface NitroConfigLike {
|
|
@@ -60,6 +69,13 @@ interface NitroConfigLike {
|
|
|
60
69
|
readonly handler: string;
|
|
61
70
|
}[];
|
|
62
71
|
}
|
|
72
|
+
/** A Nuxt plugin entry as `nuxt.options.plugins` holds it. */
|
|
73
|
+
interface NuxtPluginLike {
|
|
74
|
+
/** The plugin file; the module's own is written into `buildDir`. */
|
|
75
|
+
readonly src: string;
|
|
76
|
+
/** Where the plugin runs; the module's own runs only in the browser. */
|
|
77
|
+
readonly mode?: 'client' | 'server' | 'all';
|
|
78
|
+
}
|
|
63
79
|
/** The one build template shape this module adds; Nuxt writes it to `buildDir/filename`. */
|
|
64
80
|
interface NuxtTemplateLike {
|
|
65
81
|
readonly filename: string;
|
|
@@ -75,10 +91,14 @@ interface NuxtLike {
|
|
|
75
91
|
readonly options: {
|
|
76
92
|
/** Required when authorizePreviewModule names a server hook. */
|
|
77
93
|
readonly rootDir?: string;
|
|
94
|
+
/** Where the app's `plugins/` directory is; `app/` under Nuxt 4. */
|
|
95
|
+
readonly srcDir?: string;
|
|
78
96
|
readonly buildDir: string;
|
|
79
97
|
readonly build: {
|
|
80
98
|
templates: NuxtTemplateLike[];
|
|
81
99
|
};
|
|
100
|
+
/** The app plugins; the module adds its client plugin here. */
|
|
101
|
+
plugins?: (NuxtPluginLike | string)[];
|
|
82
102
|
/** Nuxt's aliases (`~`, `~~`, `@`, …) to their directories. */
|
|
83
103
|
readonly alias?: Readonly<Record<string, string>>;
|
|
84
104
|
livePreview?: LivePreviewModuleOptions;
|
|
@@ -138,4 +158,4 @@ declare function fragmentComponentPlugins(vue: VuePluginFactory, options: {
|
|
|
138
158
|
readonly name: string;
|
|
139
159
|
}[];
|
|
140
160
|
|
|
141
|
-
export { HANDLER_FILENAME, type LivePreviewModuleOptions, type NitroConfigLike, type NuxtLike, type NuxtTemplateLike, PLUGIN_FILENAME, type VuePluginFactory, livePreviewModule as default, fragmentComponentPlugins, pluginSource };
|
|
161
|
+
export { HANDLER_FILENAME, type LivePreviewModuleOptions, type NitroConfigLike, type NuxtLike, type NuxtPluginLike, type NuxtTemplateLike, PLUGIN_FILENAME, type VuePluginFactory, livePreviewModule as default, fragmentComponentPlugins, pluginSource };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{statSync as e}from"fs";import{join as t,relative as
|
|
1
|
+
import{statSync as e}from"fs";import{join as t,relative as i,resolve as o,isAbsolute as r}from"path";var n="authorizePreviewModule";function a(e){if(e.startsWith("../")||e.startsWith("..\\"))throw new Error(`payload-live-preview: ${n} "${e}" is outside the project; name a module inside it, relative to the project root (ADR 0024).`)}function s(e){return JSON.stringify(e).replace(/</g,"\\u003C")}function u(e){const t=`payload-live-preview: ${n} "${e}" must export the authorizePreview hook as its default export (ADR 0024).`;return[`import authorizePreview from ${s(e)};`,`if (typeof authorizePreview !== "function") throw new Error(${s(t)});`]}var l="payload-live-preview-nitro-plugin.mjs",p="payload-live-preview-server-handler.mjs",v="payload-live-preview-navigation.client.mjs",c=[".ts",".mts",".js",".mjs",".cts",".cjs"];function d(e){if("string"!=typeof e||!r(e))throw new Error("payload-live-preview: authorizePreviewModule requires an absolute project root; pass Nuxt options.rootDir, or the rootDir argument to pluginSource().");return e}function f(t){try{return e(t).isFile()}catch{return!1}}function h(e,i,o){const r=function(e,i,o){if(e.startsWith("./"))return t(i,e);const r=Object.keys(o).sort((e,t)=>t.length-e.length).find(t=>e===t||e.startsWith(`${t}/`));return void 0===r?void 0:t(o[r]??"",e.slice(r.length))}(e,i,o);return void 0===r?e:function(e){if(f(e))return e;for(const t of c)if(f(e+t))return e+t;for(const i of c){const o=t(e,`index${i}`);if(f(o))return o}}(r)??(e.startsWith("./")?r:e)}function m(e,t,i){const{authorizePreviewModule:o,navigation:r,...n}=e,s=JSON.stringify(n);return void 0===o?{hook:[],argument:s}:(a(o),{hook:u(h(o,d(t),i)),argument:`{ ...${s}, authorizePreview }`})}function w(e,t,i={}){const{hook:o,argument:r}=m(e,t,i);return["import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';",...o,"",`export default livePreviewNitroPlugin(${r});`,""].join("\n")}function g(){return["import { defineNuxtPlugin, refreshNuxtData } from '#app';","import { bindNuxtNavigation } from 'payload-live-preview/nuxt/client';","","export default defineNuxtPlugin({"," name: 'payload-live-preview:navigation',"," setup(nuxtApp) {"," const cleanup = bindNuxtNavigation(nuxtApp, refreshNuxtData);"," import.meta.hot?.dispose(cleanup);"," },","});",""].join("\n")}function y(e,o){if(!1===o.navigation)return;const r=function(e){if(void 0!==e)for(const i of c){const o=t(e,"plugins","payload-live-preview-navigation.client"+i);if(f(o))return o}}(e.options.srcDir);if(void 0!==r)return void function(e,t){if(!function(){try{const e=globalThis.process?.env;return void 0!==e&&"production"!==e.NODE_ENV}catch{return!1}}())return;const i=globalThis,o=i.__payloadLivePreviewDeprecationsWarned??=/* @__PURE__ */new Set;if(!o.has(e)){o.add(e);try{console.warn(`[payload-live-preview] ${t}`)}catch{}}}("nuxt-navigation-recipe",`${i(e.options.rootDir??process.cwd(),r)} does what the module's own client plugin does since 2.4, so the module leaves it in charge. Delete the file to use the packaged one, or set \`livePreview: { navigation: false }\` to keep yours and silence this.`);e.options.build.templates.push({filename:v,write:!0,getContents:g});const n=t(e.options.buildDir,v),a=e.options.plugins??=[];a.some(e=>("string"==typeof e?e:e.src)===n)||a.push({src:n,mode:"client"})}function P(e,i){const o={...i.options.livePreview??{},...e??{}};void 0!==o.authorizePreviewModule&&(a(o.authorizePreviewModule),d(i.options.rootDir)),i.options.build.templates.push({filename:l,write:!0,getContents:()=>w(o,i.options.rootDir,i.options.alias)});const r=t(i.options.buildDir,l),n=void 0!==o.authorizePreviewModule;n&&i.options.build.templates.push({filename:p,write:!0,getContents:()=>function(e,t,i){const{hook:o,argument:r}=m(e,t,i);return["import { defineEventHandler } from 'h3';","import { defineLivePreviewServerHandler } from 'payload-live-preview/nuxt';",...o,"",`export default defineEventHandler(defineLivePreviewServerHandler(${r}));`,""].join("\n")}(o,i.options.rootDir,i.options.alias??{})});const s=t(i.options.buildDir,p);y(i,o),i.hook("nitro:config",e=>{const t=e.plugins??=[];if(t.includes(r)||t.push(r),!n)return;const i=e.handlers??=[];i.some(e=>e.handler===s)||i.push({middleware:!0,handler:s})})}P.meta={name:"payload-live-preview",configKey:"livePreview"},P.getMeta=()=>Promise.resolve(P.meta);var x="\0payload-live-preview:server-style";function D(e,t){const r=process.cwd();return[{name:"payload-live-preview:server-styles",resolveId:e=>/[?&]type=style\b/u.test(e)?x:null,load:e=>e===x?'export default ""':null},e({features:{componentIdGenerator:(e,n,a,s)=>s(i(t.srcDir,o(r,e)).replaceAll("\\","/")+(!0===a?n:""))}})]}export{p as HANDLER_FILENAME,l as PLUGIN_FILENAME,P as default,D as fragmentComponentPlugins,w as pluginSource};
|
|
2
2
|
//# sourceMappingURL=module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","names":["OPTION","refuseOutsideReference","reference","startsWith","Error","literal","value","JSON","stringify","replace","hookImportLines","specifier","message","PLUGIN_FILENAME","HANDLER_FILENAME","EXTENSIONS","requireProjectRoot","rootDir","isAbsolute","isFile","path","statSync","resolveReference","alias","join","key","Object","keys","sort","left","right","length","find","name","slice","projectPath","extension","index","findFile","generatedParts","options","authorizePreviewModule","serializable","json","hook","argument","pluginSource","livePreviewModule","inlineOptions","nuxt","livePreview","build","templates","push","filename","write","getContents","plugin","buildDir","decides","handlerSource","handler","config","plugins","includes","handlers","some","entry","middleware","meta","configKey","getMeta","Promise","resolve","EMPTY_STYLE","fragmentComponentPlugins","vue","root","process","cwd","resolveId","id","test","load","features","componentIdGenerator","filepath","source","isProduction","getHash","relative","srcDir","replaceAll"],"sources":["../../../src/adapters/shared/hook-reference.ts","../../../src/adapters/nuxt/module.ts"],"sourcesContent":["/**\n * ADR 0024: the setups that serialize their options (Astro's integration in\n * middleware mode, the Nuxt module) take `authorizePreview` by module\n * reference. Both write the same lines into the source they generate: the\n * import, and a check that names the reference when it is not a hook.\n */\n\n/** The option's text in every message, so a reader can search for it. */\nconst OPTION = 'authorizePreviewModule';\n\n/** A reference outside the project is refused: the hook is this project's server code. */\nexport function refuseOutsideReference(reference: string): void {\n if (reference.startsWith('../') || reference.startsWith('..\\\\')) {\n throw new Error(\n `payload-live-preview: ${OPTION} \"${reference}\" is outside the project; ` +\n 'name a module inside it, relative to the project root (ADR 0024).',\n );\n }\n}\n\n/** Written into generated source: `<` escaped as the serialized options are. */\nfunction literal(value: string): string {\n return JSON.stringify(value).replace(/</g, '\\\\u003C');\n}\n\n/** The import of the hook and the check that it is one, as generated source lines. */\nexport function hookImportLines(specifier: string): string[] {\n const message =\n `payload-live-preview: ${OPTION} \"${specifier}\" must export the authorizePreview ` +\n 'hook as its default export (ADR 0024).';\n return [\n `import authorizePreview from ${literal(specifier)};`,\n `if (typeof authorizePreview !== \"function\") throw new Error(${literal(message)});`,\n ];\n}\n","/**\n * The Nuxt module: one line in `nuxt.config.ts` instead of a hand-written\n * Nitro plugin.\n *\n * ```ts\n * export default defineNuxtConfig({\n * modules: ['payload-live-preview/nuxt-module'],\n * livePreview: {\n * // The hook travels by reference (ADR 0024); the strict default holds.\n * authorizePreviewModule: './server/utils/live-preview-auth',\n * allowedOrigins: [process.env.PUBLIC_PAYLOAD_ADMIN_ORIGIN!],\n * },\n * });\n * ```\n *\n * A Nuxt module is a plain function of `(inlineOptions, nuxt)`; `defineNuxtModule`\n * from `@nuxt/kit` is sugar around exactly that. Writing the function keeps\n * `@nuxt/kit` out of the dependency list — this package adapts Nuxt, it does not\n * build with it — and keeps the module readable as the two things it does:\n * take the options, and register a Nitro plugin written from them.\n *\n * The plugin is generated rather than shipped. The module runs at build time and\n * the plugin runs per request in Nitro's own bundle, so the options cannot travel\n * as a closure — they have to be written as source. Nuxt already has the\n * mechanism: a build template, written into `.nuxt/` and registered by its path,\n * which is what `resolveNitroPath` wants (it resolves a plugin entry against\n * `srcDir`, so a bare specifier would be looked for under `server/`).\n *\n * That the options are serialized is why `authorizePreview` and `shouldInject`\n * are not part of this type: a function does not survive `JSON.stringify`.\n * The hook travels by reference instead (ADR 0024): `authorizePreviewModule`\n * names a server module whose default export it is, and the plugin imports\n * it. With a reference the module also registers the server handler, so the\n * decision is made before the app renders and a page can read it on\n * `event.context`. Without it the strict 2.0 default throws when Nitro loads the plugin;\n * `defaults: 'v1'` (or `strict: false`) injects on client-controlled intent\n * alone. A preview that needs `shouldInject` registers\n * `livePreviewNitroPlugin()` by hand, exactly as before (docs/nuxt.md).\n */\n\nimport { statSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport { hookImportLines, refuseOutsideReference } from '@adapters/shared/hook-reference';\nimport type { PreviewAdapterOptions } from '@adapters/shared/options';\nimport type { PreviewRequestLike } from '@adapters/shared/preview-request';\n\n/** What the module accepts, from `livePreview` in `nuxt.config.ts` or from `modules: [[..., options]]`. */\nexport type LivePreviewModuleOptions = Omit<\n PreviewAdapterOptions<PreviewRequestLike>,\n 'authorizePreview' | 'shouldInject'\n> & {\n /**\n * A server module whose default export is the `authorizePreview` hook, so\n * the strict default holds (ADR 0024). A path beginning with `./` is\n * relative to the project root and an alias such as `~/` is Nuxt's own; the\n * module names the file either one points at, with its extension. A package\n * specifier is passed to Nitro unchanged.\n */\n readonly authorizePreviewModule?: string;\n};\n\n/** The Nitro config slice this module writes into. */\nexport interface NitroConfigLike {\n plugins?: string[];\n /** Server handlers; the module adds its own as middleware when a hook is referenced. */\n handlers?: { readonly middleware?: boolean; readonly handler: string }[];\n}\n\n/** The one build template shape this module adds; Nuxt writes it to `buildDir/filename`. */\nexport interface NuxtTemplateLike {\n readonly filename: string;\n readonly write: boolean;\n readonly getContents: () => string;\n}\n\n/**\n * The two config slots and the one hook this module touches, duck-typed. Nuxt's\n * own types would mean a build-time dependency on `nuxt` for everyone who\n * installs this package.\n */\nexport interface NuxtLike {\n readonly options: {\n /** Required when authorizePreviewModule names a server hook. */\n readonly rootDir?: string;\n readonly buildDir: string;\n readonly build: { templates: NuxtTemplateLike[] };\n /** Nuxt's aliases (`~`, `~~`, `@`, …) to their directories. */\n readonly alias?: Readonly<Record<string, string>>;\n livePreview?: LivePreviewModuleOptions;\n };\n readonly hook: (name: 'nitro:config', handler: (config: NitroConfigLike) => void) => void;\n}\n\n/** The generated plugin's name in `.nuxt/`, distinctive enough to recognise in a build listing. @internal */\nexport const PLUGIN_FILENAME = 'payload-live-preview-nitro-plugin.mjs';\n/** The generated server handler's name, written beside the plugin when a hook is referenced. @internal */\nexport const HANDLER_FILENAME = 'payload-live-preview-server-handler.mjs';\n\nconst EXTENSIONS = ['.ts', '.mts', '.js', '.mjs', '.cts', '.cjs'] as const;\n\n/** A new hook reference must never silently resolve from this process's working directory. */\nfunction requireProjectRoot(rootDir: string | undefined): string {\n if (typeof rootDir !== 'string' || !isAbsolute(rootDir)) {\n throw new Error(\n 'payload-live-preview: authorizePreviewModule requires an absolute project root; ' +\n 'pass Nuxt options.rootDir, or the rootDir argument to pluginSource().',\n );\n }\n return rootDir;\n}\n\nfunction isFile(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\n/** The file a path names: itself, then with an extension, then a directory's index. */\nfunction findFile(path: string): string | undefined {\n if (isFile(path)) return path;\n for (const extension of EXTENSIONS) if (isFile(path + extension)) return path + extension;\n for (const extension of EXTENSIONS) {\n const index = join(path, `index${extension}`);\n if (isFile(index)) return index;\n }\n return undefined;\n}\n\n/** Where a project-relative or aliased reference points, before any extension is added. */\nfunction projectPath(\n reference: string,\n rootDir: string,\n alias: Readonly<Record<string, string>>,\n): string | undefined {\n // The files are written into the build directory, so a project-relative path is made absolute.\n if (reference.startsWith('./')) return join(rootDir, reference);\n const aliases = Object.keys(alias).sort((left, right) => right.length - left.length);\n const key = aliases.find((name) => reference === name || reference.startsWith(`${name}/`));\n return key === undefined ? undefined : join(alias[key] ?? '', reference.slice(key.length));\n}\n\n/**\n * The module the generated files import. `nuxt dev` imports them without\n * bundling and nothing there adds an extension to a bare path, so a reference\n * to a TypeScript file answered 500 in development while the production build\n * resolved it. Where the file can be read, its own name is written. Where it\n * cannot, the reference stays as the bundler will see it: absolute for a\n * project path, as written for an alias or a package.\n */\nfunction resolveReference(\n reference: string,\n rootDir: string,\n alias: Readonly<Record<string, string>>,\n): string {\n const path = projectPath(reference, rootDir, alias);\n if (path === undefined) return reference;\n return findFile(path) ?? (reference.startsWith('./') ? path : reference);\n}\n\n/**\n * What both generated files pass on: the options as a literal and, when a\n * hook is referenced, its import and the argument that carries it.\n */\nfunction generatedParts(\n options: LivePreviewModuleOptions,\n rootDir: string | undefined,\n alias: Readonly<Record<string, string>>,\n): { readonly hook: string[]; readonly argument: string } {\n const { authorizePreviewModule: reference, ...serializable } = options;\n const json = JSON.stringify(serializable);\n if (reference === undefined) return { hook: [], argument: json };\n refuseOutsideReference(reference);\n return {\n hook: hookImportLines(resolveReference(reference, requireProjectRoot(rootDir), alias)),\n argument: `{ ...${json}, authorizePreview }`,\n };\n}\n\n/**\n * The generated plugin: an import of the public adapter entry and a call with\n * the options. Nothing framework-private, so a reader who opens the file in\n * `.nuxt/` sees the hand-written setup they would otherwise have typed.\n * @internal\n */\nexport function pluginSource(\n options: LivePreviewModuleOptions,\n rootDir?: string,\n alias: Readonly<Record<string, string>> = {},\n): string {\n const { hook, argument } = generatedParts(options, rootDir, alias);\n return [\n \"import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';\",\n ...hook,\n '',\n `export default livePreviewNitroPlugin(${argument});`,\n '',\n ].join('\\n');\n}\n\n/**\n * The generated server handler, as docs/nuxt.md writes it by hand: it decides\n * before the app renders, so a page can read the verdict on `event.context`\n * for its bindings and its draft read, and the plugin reuses that verdict.\n */\nfunction handlerSource(\n options: LivePreviewModuleOptions,\n rootDir: string | undefined,\n alias: Readonly<Record<string, string>>,\n): string {\n const { hook, argument } = generatedParts(options, rootDir, alias);\n return [\n \"import { defineEventHandler } from 'h3';\",\n \"import { defineLivePreviewServerHandler } from 'payload-live-preview/nuxt';\",\n ...hook,\n '',\n `export default defineEventHandler(defineLivePreviewServerHandler(${argument}));`,\n '',\n ].join('\\n');\n}\n\n/**\n * The module itself. Options come from `livePreview` in the Nuxt config, from\n * the module's own inline options, or from both — the inline ones win, because\n * they are the more specific place to write them.\n */\nexport default function livePreviewModule(\n inlineOptions: LivePreviewModuleOptions | undefined,\n nuxt: NuxtLike,\n): void {\n const options: LivePreviewModuleOptions = {\n ...(nuxt.options.livePreview ?? {}),\n ...(inlineOptions ?? {}),\n };\n // Refused at setup, not later when Nuxt writes the template.\n if (options.authorizePreviewModule !== undefined) {\n refuseOutsideReference(options.authorizePreviewModule);\n requireProjectRoot(nuxt.options.rootDir);\n }\n nuxt.options.build.templates.push({\n filename: PLUGIN_FILENAME,\n // Nitro reads the plugin from disk, not from Nuxt's virtual file system.\n write: true,\n getContents: () => pluginSource(options, nuxt.options.rootDir, nuxt.options.alias),\n });\n const plugin = join(nuxt.options.buildDir, PLUGIN_FILENAME);\n // Only a referenced hook makes a decision a page can read before it renders;\n // the intent-only setup keeps the plugin alone, as before.\n const decides = options.authorizePreviewModule !== undefined;\n if (decides) {\n nuxt.options.build.templates.push({\n filename: HANDLER_FILENAME,\n write: true,\n getContents: () => handlerSource(options, nuxt.options.rootDir, nuxt.options.alias ?? {}),\n });\n }\n const handler = join(nuxt.options.buildDir, HANDLER_FILENAME);\n nuxt.hook('nitro:config', (config) => {\n const plugins = (config.plugins ??= []);\n // Nuxt re-runs modules on a config reload; registering twice would inject\n // the runtime twice into every page.\n if (!plugins.includes(plugin)) plugins.push(plugin);\n if (!decides) return;\n const handlers = (config.handlers ??= []);\n if (!handlers.some((entry) => entry.handler === handler)) {\n handlers.push({ middleware: true, handler });\n }\n });\n}\n\n/** Nuxt reads this off the module function to name it in build output and errors. */\nlivePreviewModule.meta = {\n name: 'payload-live-preview',\n configKey: 'livePreview',\n};\n\n/**\n * How `@nuxt/kit`'s `installModule` actually reads that meta — `.meta` alone\n * names nothing to it. Through this Nuxt also writes the `livePreview` key\n * into `.nuxt/types/schema.d.ts`; without it `nuxt.config.ts` fails to\n * type-check on that key.\n */\nlivePreviewModule.getMeta = (): Promise<typeof livePreviewModule.meta> =>\n Promise.resolve(livePreviewModule.meta);\n\n/**\n * The app's own `@vitejs/plugin-vue` default export, as far as it is called\n * here: with the hook that names a component's scope id.\n */\nexport type VuePluginFactory = (options?: {\n readonly features?: {\n readonly componentIdGenerator?: (\n filepath: string,\n source: string,\n isProduction: boolean | undefined,\n getHash: (text: string) => string,\n ) => string;\n };\n}) => { readonly name: string };\n\nconst EMPTY_STYLE = '\\0payload-live-preview:server-style';\n\n/**\n * The rollup plugins Nitro needs to render the project's single-file\n * components in a fragment endpoint (ADR 0030), for\n * `nitro.rollupConfig.plugins`: Vue's plugin, hashing a scope id from the path\n * under `srcDir` as Nuxt's own build does, and an empty module for every style\n * request, which the page's build delivers instead (ADR 0029).\n *\n * Without the second, rollup fails on a component's `<style>`. Without the\n * first, Nuxt 4's `app/` layout gives the fragment other scope ids than the\n * page, and no scoped rule reaches what it renders.\n */\nexport function fragmentComponentPlugins(\n vue: VuePluginFactory,\n options: { readonly srcDir: string },\n): { readonly name: string }[] {\n // plugin-vue outside Vite resolves paths from the working directory.\n const root = process.cwd();\n const componentIdGenerator = (\n filepath: string,\n source: string,\n isProduction: boolean | undefined,\n getHash: (text: string) => string,\n ): string => {\n const underSrcDir = relative(options.srcDir, resolve(root, filepath)).replaceAll('\\\\', '/');\n return getHash(underSrcDir + (isProduction === true ? source : ''));\n };\n const styles = {\n name: 'payload-live-preview:server-styles',\n resolveId: (id: string): string | null => (/[?&]type=style\\b/u.test(id) ? EMPTY_STYLE : null),\n load: (id: string): string | null => (id === EMPTY_STYLE ? 'export default \"\"' : null),\n };\n return [styles, vue({ features: { componentIdGenerator } })];\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"module.js","names":["OPTION","refuseOutsideReference","reference","startsWith","Error","literal","value","JSON","stringify","replace","hookImportLines","specifier","message","PLUGIN_FILENAME","HANDLER_FILENAME","NAVIGATION_PLUGIN_FILENAME","EXTENSIONS","requireProjectRoot","rootDir","isAbsolute","isFile","path","statSync","resolveReference","alias","join","key","Object","keys","sort","left","right","length","find","name","slice","projectPath","extension","index","findFile","generatedParts","options","authorizePreviewModule","navigation","_navigation","serializable","json","hook","argument","pluginSource","navigationPluginSource","registerNavigationPlugin","nuxt","own","srcDir","recipePlugin","env","globalThis","process","isDevelopmentProcess","holder","warned","Set","has","add","console","warn","warnOnce","relative","cwd","build","templates","push","filename","write","getContents","src","buildDir","plugins","some","entry","mode","livePreviewModule","inlineOptions","livePreview","plugin","decides","handlerSource","handler","config","includes","handlers","middleware","meta","configKey","getMeta","Promise","resolve","EMPTY_STYLE","fragmentComponentPlugins","vue","root","resolveId","id","test","load","features","componentIdGenerator","filepath","source","isProduction","getHash","replaceAll"],"sources":["../../../src/adapters/shared/hook-reference.ts","../../../src/adapters/nuxt/module.ts","../../../src/types/dev-warning.ts"],"sourcesContent":["/**\n * ADR 0024: the setups that serialize their options (Astro's integration in\n * middleware mode, the Nuxt module) take `authorizePreview` by module\n * reference. Both write the same lines into the source they generate: the\n * import, and a check that names the reference when it is not a hook.\n */\n\n/** The option's text in every message, so a reader can search for it. */\nconst OPTION = 'authorizePreviewModule';\n\n/** A reference outside the project is refused: the hook is this project's server code. */\nexport function refuseOutsideReference(reference: string): void {\n if (reference.startsWith('../') || reference.startsWith('..\\\\')) {\n throw new Error(\n `payload-live-preview: ${OPTION} \"${reference}\" is outside the project; ` +\n 'name a module inside it, relative to the project root (ADR 0024).',\n );\n }\n}\n\n/** Written into generated source: `<` escaped as the serialized options are. */\nfunction literal(value: string): string {\n return JSON.stringify(value).replace(/</g, '\\\\u003C');\n}\n\n/** The import of the hook and the check that it is one, as generated source lines. */\nexport function hookImportLines(specifier: string): string[] {\n const message =\n `payload-live-preview: ${OPTION} \"${specifier}\" must export the authorizePreview ` +\n 'hook as its default export (ADR 0024).';\n return [\n `import authorizePreview from ${literal(specifier)};`,\n `if (typeof authorizePreview !== \"function\") throw new Error(${literal(message)});`,\n ];\n}\n","/**\n * The Nuxt module: one line in `nuxt.config.ts` instead of a hand-written\n * Nitro plugin.\n *\n * ```ts\n * export default defineNuxtConfig({\n * modules: ['payload-live-preview/nuxt-module'],\n * livePreview: {\n * // The hook travels by reference (ADR 0024); the strict default holds.\n * authorizePreviewModule: './server/utils/live-preview-auth',\n * allowedOrigins: [process.env.PUBLIC_PAYLOAD_ADMIN_ORIGIN!],\n * },\n * });\n * ```\n *\n * A Nuxt module is a plain function of `(inlineOptions, nuxt)`; `defineNuxtModule`\n * from `@nuxt/kit` is sugar around exactly that. Writing the function keeps\n * `@nuxt/kit` out of the dependency list — this package adapts Nuxt, it does not\n * build with it — and keeps the module readable as the things it does: take the\n * options, register a Nitro plugin written from them, and register the client\n * plugin that tells the runtime about client navigations (since 2.4; before,\n * docs/nuxt.md had the project copy it).\n *\n * The plugin is generated rather than shipped. The module runs at build time and\n * the plugin runs per request in Nitro's own bundle, so the options cannot travel\n * as a closure — they have to be written as source. Nuxt already has the\n * mechanism: a build template, written into `.nuxt/` and registered by its path,\n * which is what `resolveNitroPath` wants (it resolves a plugin entry against\n * `srcDir`, so a bare specifier would be looked for under `server/`).\n *\n * That the options are serialized is why `authorizePreview` and `shouldInject`\n * are not part of this type: a function does not survive `JSON.stringify`.\n * The hook travels by reference instead (ADR 0024): `authorizePreviewModule`\n * names a server module whose default export it is, and the plugin imports\n * it. With a reference the module also registers the server handler, so the\n * decision is made before the app renders and a page can read it on\n * `event.context`. Without it the strict 2.0 default throws when Nitro loads the plugin;\n * `defaults: 'v1'` (or `strict: false`) injects on client-controlled intent\n * alone. A preview that needs `shouldInject` registers\n * `livePreviewNitroPlugin()` by hand, exactly as before (docs/nuxt.md).\n */\n\nimport { statSync } from 'node:fs';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport { hookImportLines, refuseOutsideReference } from '@adapters/shared/hook-reference';\nimport type { PreviewAdapterOptions } from '@adapters/shared/options';\nimport type { PreviewRequestLike } from '@adapters/shared/preview-request';\nimport { warnOnce } from '@/types/dev-warning';\n\n/** What the module accepts, from `livePreview` in `nuxt.config.ts` or from `modules: [[..., options]]`. */\nexport type LivePreviewModuleOptions = Omit<\n PreviewAdapterOptions<PreviewRequestLike>,\n 'authorizePreview' | 'shouldInject'\n> & {\n /**\n * A server module whose default export is the `authorizePreview` hook, so\n * the strict default holds (ADR 0024). A path beginning with `./` is\n * relative to the project root and an alias such as `~/` is Nuxt's own; the\n * module names the file either one points at, with its extension. A package\n * specifier is passed to Nitro unchanged.\n */\n readonly authorizePreviewModule?: string;\n /**\n * Whether the module registers its client plugin for client navigations and\n * route refreshes (`payload-live-preview/nuxt/client`). On by default; a\n * project that still has the plugin docs/nuxt.md had it copy before 2.4\n * keeps its own, and the module registers nothing beside it.\n */\n readonly navigation?: boolean;\n};\n\n/** The Nitro config slice this module writes into. */\nexport interface NitroConfigLike {\n plugins?: string[];\n /** Server handlers; the module adds its own as middleware when a hook is referenced. */\n handlers?: { readonly middleware?: boolean; readonly handler: string }[];\n}\n\n/** A Nuxt plugin entry as `nuxt.options.plugins` holds it. */\nexport interface NuxtPluginLike {\n /** The plugin file; the module's own is written into `buildDir`. */\n readonly src: string;\n /** Where the plugin runs; the module's own runs only in the browser. */\n readonly mode?: 'client' | 'server' | 'all';\n}\n\n/** The one build template shape this module adds; Nuxt writes it to `buildDir/filename`. */\nexport interface NuxtTemplateLike {\n readonly filename: string;\n readonly write: boolean;\n readonly getContents: () => string;\n}\n\n/**\n * The two config slots and the one hook this module touches, duck-typed. Nuxt's\n * own types would mean a build-time dependency on `nuxt` for everyone who\n * installs this package.\n */\nexport interface NuxtLike {\n readonly options: {\n /** Required when authorizePreviewModule names a server hook. */\n readonly rootDir?: string;\n /** Where the app's `plugins/` directory is; `app/` under Nuxt 4. */\n readonly srcDir?: string;\n readonly buildDir: string;\n readonly build: { templates: NuxtTemplateLike[] };\n /** The app plugins; the module adds its client plugin here. */\n plugins?: (NuxtPluginLike | string)[];\n /** Nuxt's aliases (`~`, `~~`, `@`, …) to their directories. */\n readonly alias?: Readonly<Record<string, string>>;\n livePreview?: LivePreviewModuleOptions;\n };\n readonly hook: (name: 'nitro:config', handler: (config: NitroConfigLike) => void) => void;\n}\n\n/** The generated plugin's name in `.nuxt/`, distinctive enough to recognise in a build listing. @internal */\nexport const PLUGIN_FILENAME = 'payload-live-preview-nitro-plugin.mjs';\n/** The generated server handler's name, written beside the plugin when a hook is referenced. @internal */\nexport const HANDLER_FILENAME = 'payload-live-preview-server-handler.mjs';\n/** The generated client plugin's name in `.nuxt/`. */\nconst NAVIGATION_PLUGIN_FILENAME = 'payload-live-preview-navigation.client.mjs';\n\n/** The file docs/nuxt.md had a project create before 2.4, under `srcDir/plugins/`. */\nconst RECIPE_PLUGIN = 'payload-live-preview-navigation.client';\n\nconst EXTENSIONS = ['.ts', '.mts', '.js', '.mjs', '.cts', '.cjs'] as const;\n\n/** A new hook reference must never silently resolve from this process's working directory. */\nfunction requireProjectRoot(rootDir: string | undefined): string {\n if (typeof rootDir !== 'string' || !isAbsolute(rootDir)) {\n throw new Error(\n 'payload-live-preview: authorizePreviewModule requires an absolute project root; ' +\n 'pass Nuxt options.rootDir, or the rootDir argument to pluginSource().',\n );\n }\n return rootDir;\n}\n\nfunction isFile(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\n/** The file a path names: itself, then with an extension, then a directory's index. */\nfunction findFile(path: string): string | undefined {\n if (isFile(path)) return path;\n for (const extension of EXTENSIONS) if (isFile(path + extension)) return path + extension;\n for (const extension of EXTENSIONS) {\n const index = join(path, `index${extension}`);\n if (isFile(index)) return index;\n }\n return undefined;\n}\n\n/** Where a project-relative or aliased reference points, before any extension is added. */\nfunction projectPath(\n reference: string,\n rootDir: string,\n alias: Readonly<Record<string, string>>,\n): string | undefined {\n // The files are written into the build directory, so a project-relative path is made absolute.\n if (reference.startsWith('./')) return join(rootDir, reference);\n const aliases = Object.keys(alias).sort((left, right) => right.length - left.length);\n const key = aliases.find((name) => reference === name || reference.startsWith(`${name}/`));\n return key === undefined ? undefined : join(alias[key] ?? '', reference.slice(key.length));\n}\n\n/**\n * The module the generated files import. `nuxt dev` imports them without\n * bundling and nothing there adds an extension to a bare path, so a reference\n * to a TypeScript file answered 500 in development while the production build\n * resolved it. Where the file can be read, its own name is written. Where it\n * cannot, the reference stays as the bundler will see it: absolute for a\n * project path, as written for an alias or a package.\n */\nfunction resolveReference(\n reference: string,\n rootDir: string,\n alias: Readonly<Record<string, string>>,\n): string {\n const path = projectPath(reference, rootDir, alias);\n if (path === undefined) return reference;\n return findFile(path) ?? (reference.startsWith('./') ? path : reference);\n}\n\n/**\n * What both generated files pass on: the options as a literal and, when a\n * hook is referenced, its import and the argument that carries it.\n */\nfunction generatedParts(\n options: LivePreviewModuleOptions,\n rootDir: string | undefined,\n alias: Readonly<Record<string, string>>,\n): { readonly hook: string[]; readonly argument: string } {\n // `navigation` is the module's own switch; the Nitro adapter does not take it.\n const { authorizePreviewModule: reference, navigation: _navigation, ...serializable } = options;\n const json = JSON.stringify(serializable);\n if (reference === undefined) return { hook: [], argument: json };\n refuseOutsideReference(reference);\n return {\n hook: hookImportLines(resolveReference(reference, requireProjectRoot(rootDir), alias)),\n argument: `{ ...${json}, authorizePreview }`,\n };\n}\n\n/**\n * The generated plugin: an import of the public adapter entry and a call with\n * the options. Nothing framework-private, so a reader who opens the file in\n * `.nuxt/` sees the hand-written setup they would otherwise have typed.\n * @internal\n */\nexport function pluginSource(\n options: LivePreviewModuleOptions,\n rootDir?: string,\n alias: Readonly<Record<string, string>> = {},\n): string {\n const { hook, argument } = generatedParts(options, rootDir, alias);\n return [\n \"import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';\",\n ...hook,\n '',\n `export default livePreviewNitroPlugin(${argument});`,\n '',\n ].join('\\n');\n}\n\n/**\n * The generated server handler, as docs/nuxt.md writes it by hand: it decides\n * before the app renders, so a page can read the verdict on `event.context`\n * for its bindings and its draft read, and the plugin reuses that verdict.\n */\nfunction handlerSource(\n options: LivePreviewModuleOptions,\n rootDir: string | undefined,\n alias: Readonly<Record<string, string>>,\n): string {\n const { hook, argument } = generatedParts(options, rootDir, alias);\n return [\n \"import { defineEventHandler } from 'h3';\",\n \"import { defineLivePreviewServerHandler } from 'payload-live-preview/nuxt';\",\n ...hook,\n '',\n `export default defineEventHandler(defineLivePreviewServerHandler(${argument}));`,\n '',\n ].join('\\n');\n}\n\n/**\n * The generated client plugin. Nuxt's composables come from `#app`, which\n * only a Nuxt build resolves, so the plugin imports them and hands them to the\n * package; the cleanup also goes to hot replacement, which reloads it.\n */\nfunction navigationPluginSource(): string {\n return [\n \"import { defineNuxtPlugin, refreshNuxtData } from '#app';\",\n \"import { bindNuxtNavigation } from 'payload-live-preview/nuxt/client';\",\n '',\n 'export default defineNuxtPlugin({',\n \" name: 'payload-live-preview:navigation',\",\n ' setup(nuxtApp) {',\n ' const cleanup = bindNuxtNavigation(nuxtApp, refreshNuxtData);',\n ' import.meta.hot?.dispose(cleanup);',\n ' },',\n '});',\n '',\n ].join('\\n');\n}\n\n/** The recipe plugin a project still carries, if any: registering a second would dispatch twice. */\nfunction recipePlugin(srcDir: string | undefined): string | undefined {\n if (srcDir === undefined) return undefined;\n for (const extension of EXTENSIONS) {\n const path = join(srcDir, 'plugins', RECIPE_PLUGIN + extension);\n if (isFile(path)) return path;\n }\n return undefined;\n}\n\n/** Register the client plugin unless the options switch it off or the project has its own. */\nfunction registerNavigationPlugin(nuxt: NuxtLike, options: LivePreviewModuleOptions): void {\n if (options.navigation === false) return;\n const own = recipePlugin(nuxt.options.srcDir);\n if (own !== undefined) {\n warnOnce(\n 'nuxt-navigation-recipe',\n `${relative(nuxt.options.rootDir ?? process.cwd(), own)} does what the module's own client ` +\n 'plugin does since 2.4, so the module leaves it in charge. Delete the file to use the ' +\n 'packaged one, or set `livePreview: { navigation: false }` to keep yours and silence this.',\n );\n return;\n }\n nuxt.options.build.templates.push({\n filename: NAVIGATION_PLUGIN_FILENAME,\n write: true,\n getContents: navigationPluginSource,\n });\n const src = join(nuxt.options.buildDir, NAVIGATION_PLUGIN_FILENAME);\n const plugins = (nuxt.options.plugins ??= []);\n // A config reload runs the module again.\n if (!plugins.some((entry) => (typeof entry === 'string' ? entry : entry.src) === src)) {\n plugins.push({ src, mode: 'client' });\n }\n}\n\n/**\n * The module itself. Options come from `livePreview` in the Nuxt config, from\n * the module's own inline options, or from both — the inline ones win, because\n * they are the more specific place to write them.\n */\nexport default function livePreviewModule(\n inlineOptions: LivePreviewModuleOptions | undefined,\n nuxt: NuxtLike,\n): void {\n const options: LivePreviewModuleOptions = {\n ...(nuxt.options.livePreview ?? {}),\n ...(inlineOptions ?? {}),\n };\n // Refused at setup, not later when Nuxt writes the template.\n if (options.authorizePreviewModule !== undefined) {\n refuseOutsideReference(options.authorizePreviewModule);\n requireProjectRoot(nuxt.options.rootDir);\n }\n nuxt.options.build.templates.push({\n filename: PLUGIN_FILENAME,\n // Nitro reads the plugin from disk, not from Nuxt's virtual file system.\n write: true,\n getContents: () => pluginSource(options, nuxt.options.rootDir, nuxt.options.alias),\n });\n const plugin = join(nuxt.options.buildDir, PLUGIN_FILENAME);\n // Only a referenced hook makes a decision a page can read before it renders;\n // the intent-only setup keeps the plugin alone, as before.\n const decides = options.authorizePreviewModule !== undefined;\n if (decides) {\n nuxt.options.build.templates.push({\n filename: HANDLER_FILENAME,\n write: true,\n getContents: () => handlerSource(options, nuxt.options.rootDir, nuxt.options.alias ?? {}),\n });\n }\n const handler = join(nuxt.options.buildDir, HANDLER_FILENAME);\n registerNavigationPlugin(nuxt, options);\n nuxt.hook('nitro:config', (config) => {\n const plugins = (config.plugins ??= []);\n // Nuxt re-runs modules on a config reload; registering twice would inject\n // the runtime twice into every page.\n if (!plugins.includes(plugin)) plugins.push(plugin);\n if (!decides) return;\n const handlers = (config.handlers ??= []);\n if (!handlers.some((entry) => entry.handler === handler)) {\n handlers.push({ middleware: true, handler });\n }\n });\n}\n\n/** Nuxt reads this off the module function to name it in build output and errors. */\nlivePreviewModule.meta = {\n name: 'payload-live-preview',\n configKey: 'livePreview',\n};\n\n/**\n * How `@nuxt/kit`'s `installModule` actually reads that meta — `.meta` alone\n * names nothing to it. Through this Nuxt also writes the `livePreview` key\n * into `.nuxt/types/schema.d.ts`; without it `nuxt.config.ts` fails to\n * type-check on that key.\n */\nlivePreviewModule.getMeta = (): Promise<typeof livePreviewModule.meta> =>\n Promise.resolve(livePreviewModule.meta);\n\n/**\n * The app's own `@vitejs/plugin-vue` default export, as far as it is called\n * here: with the hook that names a component's scope id.\n */\nexport type VuePluginFactory = (options?: {\n readonly features?: {\n readonly componentIdGenerator?: (\n filepath: string,\n source: string,\n isProduction: boolean | undefined,\n getHash: (text: string) => string,\n ) => string;\n };\n}) => { readonly name: string };\n\nconst EMPTY_STYLE = '\\0payload-live-preview:server-style';\n\n/**\n * The rollup plugins Nitro needs to render the project's single-file\n * components in a fragment endpoint (ADR 0030), for\n * `nitro.rollupConfig.plugins`: Vue's plugin, hashing a scope id from the path\n * under `srcDir` as Nuxt's own build does, and an empty module for every style\n * request, which the page's build delivers instead (ADR 0029).\n *\n * Without the second, rollup fails on a component's `<style>`. Without the\n * first, Nuxt 4's `app/` layout gives the fragment other scope ids than the\n * page, and no scoped rule reaches what it renders.\n */\nexport function fragmentComponentPlugins(\n vue: VuePluginFactory,\n options: { readonly srcDir: string },\n): { readonly name: string }[] {\n // plugin-vue outside Vite resolves paths from the working directory.\n const root = process.cwd();\n const componentIdGenerator = (\n filepath: string,\n source: string,\n isProduction: boolean | undefined,\n getHash: (text: string) => string,\n ): string => {\n const underSrcDir = relative(options.srcDir, resolve(root, filepath)).replaceAll('\\\\', '/');\n return getHash(underSrcDir + (isProduction === true ? source : ''));\n };\n const styles = {\n name: 'payload-live-preview:server-styles',\n resolveId: (id: string): string | null => (/[?&]type=style\\b/u.test(id) ? EMPTY_STYLE : null),\n load: (id: string): string | null => (id === EMPTY_STYLE ? 'export default \"\"' : null),\n };\n return [styles, vue({ features: { componentIdGenerator } })];\n}\n","/**\n * One development warning per process. The set of issued keys lives on\n * `globalThis` so two package copies in one process still warn once.\n */\n\nconst WARNED_KEY = '__payloadLivePreviewDeprecationsWarned';\n\n/** `true` outside a production build; `false` when `NODE_ENV` is production or unknown. */\nexport function isDevelopmentProcess(): boolean {\n try {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process\n ?.env;\n if (env === undefined) return false;\n return env['NODE_ENV'] !== 'production';\n } catch {\n return false;\n }\n}\n\n/** Warn once per process for `key`, outside production only. */\nexport function warnOnce(key: string, message: string): void {\n if (!isDevelopmentProcess()) return;\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n const warned = (holder[WARNED_KEY] ??= new Set<string>());\n if (warned.has(key)) return;\n warned.add(key);\n try {\n console.warn(`[payload-live-preview] ${message}`);\n } catch {\n // A console that throws must not break a request.\n }\n}\n\n/**\n * The deprecated options the adapters and the inline generator both accept;\n * an adapter hands them on to the generator, and the shared keys keep that to\n * one warning each (ADR 0026).\n */\nexport function warnDeprecatedOptions(options: {\n readonly defaults?: string | undefined;\n readonly onUnboundChange?: string | undefined;\n}): void {\n if (options.defaults === 'v1') {\n warnOnce(\n 'defaults-v1',\n \"`defaults: 'v1'` is removed in 3.0: `pll migrate` writes the 1.x rows it stands for \" +\n 'into your options, where they keep working (ADR 0026).',\n );\n }\n if (options.onUnboundChange !== undefined) {\n warnOnce(\n 'on-unbound-change',\n \"`onUnboundChange` is removed in 3.0: name it `onUnfaithfulPatch`, where 'route' is \" +\n \"'escalate'; `pll migrate` renames it (ADR 0026).\",\n );\n }\n}\n\n/**\n * The adapter and generator options whose 2.x default 3.0 changes, said once\n * per process in development (ADR 0026, 2026-11-03). A browser-only client\n * hears nothing, as for the removals above.\n */\nexport function warnChangingDefaults(options: {\n readonly mergeTimeoutMs?: number | undefined;\n}): void {\n if (options.mergeTimeoutMs === undefined) {\n warnOnce(\n 'merge-deadline',\n '`mergeTimeoutMs` is not set, so a merge waits as long as the server takes; 3.0 gives it a ' +\n 'default deadline. Set `mergeTimeoutMs` now, or `0` to keep none (ADR 0007, row 27).',\n );\n }\n}\n\n/** Test hook: forget every warning issued so far. */\nexport function resetDevWarnings(): void {\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n holder[WARNED_KEY] = undefined;\n}\n"],"mappings":"qGAQA,IAAMA,EAAS,yBAGR,SAASC,EAAuBC,GACrC,GAAIA,EAAUC,WAAW,QAAUD,EAAUC,WAAW,QACtD,MAAM,IAAIC,MACR,yBAAyBJ,MAAWE,+FAI1C,CAGA,SAASG,EAAQC,GACf,OAAOC,KAAKC,UAAUF,GAAOG,QAAQ,KAAM,UAC7C,CAGO,SAASC,EAAgBC,GAC9B,MAAMC,EACJ,yBAAyBZ,MAAWW,6EAEtC,MAAO,CACL,gCAAgCN,EAAQM,MACxC,+DAA+DN,EAAQO,OAE3E,CCkFO,IAAMC,EAAkB,wCAElBC,EAAmB,0CAE1BC,EAA6B,6CAK7BC,EAAa,CAAC,MAAO,OAAQ,MAAO,OAAQ,OAAQ,QAG1D,SAASC,EAAmBC,GAC1B,GAAuB,iBAAZA,IAAyBC,EAAWD,GAC7C,MAAM,IAAId,MACR,yJAIJ,OAAOc,CACT,CAEA,SAASE,EAAOC,GACd,IACE,OAAOC,EAASD,GAAMD,QACxB,OACE,OAAO,CACT,CACF,CAkCA,SAASG,EACPrB,EACAgB,EACAM,GAEA,MAAMH,EAzBR,SACEnB,EACAgB,EACAM,GAGA,GAAItB,EAAUC,WAAW,MAAO,OAAOsB,EAAKP,EAAShB,GACrD,MACMwB,EADUC,OAAOC,KAAKJ,GAAOK,KAAK,CAACC,EAAMC,IAAUA,EAAMC,OAASF,EAAKE,QACzDC,KAAMC,GAAShC,IAAcgC,GAAQhC,EAAUC,WAAW,GAAG+B,OACjF,YAAe,IAARR,OAAoB,EAAYD,EAAKD,EAAME,IAAQ,GAAIxB,EAAUiC,MAAMT,EAAIM,QACpF,CAeeI,CAAYlC,EAAWgB,EAASM,GAC7C,YAAa,IAATH,EAA2BnB,EArCjC,SAAkBmB,GAChB,GAAID,EAAOC,GAAO,OAAOA,EACzB,UAAWgB,KAAarB,EAAY,GAAII,EAAOC,EAAOgB,GAAS,OAAUhB,EAAOgB,EAChF,UAAWA,KAAarB,EAAY,CAClC,MAAMsB,EAAQb,EAAKJ,EAAM,QAAQgB,KACjC,GAAIjB,EAAOkB,GAAQ,OAAOA,CAC5B,CAEF,CA8BSC,CAASlB,KAAUnB,EAAUC,WAAW,MAAQkB,EAAOnB,EAChE,CAMA,SAASsC,EACPC,EACAvB,EACAM,GAGA,MAAQkB,uBAAwBxC,EAAWyC,WAAYC,KAAgBC,GAAiBJ,EAClFK,EAAOvC,KAAKC,UAAUqC,GAC5B,YAAkB,IAAd3C,EAAgC,CAAE6C,KAAM,GAAIC,SAAUF,IAC1D7C,EAAuBC,GAChB,CACL6C,KAAMrC,EAAgBa,EAAiBrB,EAAWe,EAAmBC,GAAUM,IAC/EwB,SAAU,QAAQF,yBAEtB,CAQO,SAASG,EACdR,EACAvB,EACAM,EAA0C,IAE1C,MAAMuB,KAAEA,EAAAC,SAAMA,GAAaR,EAAeC,EAASvB,EAASM,GAC5D,MAAO,CACL,yEACGuB,EACH,GACA,yCAAyCC,MACzC,IACAvB,KAAK,KACT,CA4BA,SAASyB,IACP,MAAO,CACL,4DACA,yEACA,GACA,oCACA,6CACA,qBACA,oEACA,yCACA,OACA,MACA,IACAzB,KAAK,KACT,CAaA,SAAS0B,EAAyBC,EAAgBX,GAChD,IAA2B,IAAvBA,EAAQE,WAAsB,OAClC,MAAMU,EAZR,SAAsBC,GACpB,QAAe,IAAXA,EACJ,UAAWjB,KAAarB,EAAY,CAClC,MAAMK,EAAOI,EAAK6B,EAAQ,UAxJR,yCAwJmCjB,GACrD,GAAIjB,EAAOC,GAAO,OAAOA,CAC3B,CAEF,CAKckC,CAAaH,EAAKX,QAAQa,QACtC,QAAY,IAARD,EAOF,YChRG,SAAkB3B,EAAad,GACpC,IAbK,WACL,IACE,MAAM4C,EAAOC,WAA0EC,SACnFF,IACJ,YAAY,IAARA,GACuB,eAApBA,EAAc,QACvB,OACE,OAAO,CACT,CACF,CAIOG,GAAwB,OAC7B,MAAMC,EAASH,WACTI,EAAUD,EAAiB,4DAAUE,IAC3C,IAAID,EAAOE,IAAIrC,GAAf,CACAmC,EAAOG,IAAItC,GACX,IACEuC,QAAQC,KAAK,0BAA0BtD,IACzC,OAEA,CANqB,CAOvB,CD+PIuD,CACE,yBACA,GAAGC,EAAShB,EAAKX,QAAQvB,SAAWwC,QAAQW,MAAOhB,yNAMvDD,EAAKX,QAAQ6B,MAAMC,UAAUC,KAAK,CAChCC,SAAU1D,EACV2D,OAAO,EACPC,YAAazB,IAEf,MAAM0B,EAAMnD,EAAK2B,EAAKX,QAAQoC,SAAU9D,GAClC+D,EAAW1B,EAAKX,QAAQqC,UAAY,GAErCA,EAAQC,KAAMC,IAA4B,iBAAVA,EAAqBA,EAAQA,EAAMJ,OAASA,IAC/EE,EAAQN,KAAK,CAAEI,MAAKK,KAAM,UAE9B,CAOe,SAARC,EACLC,EACA/B,GAEA,MAAMX,EAAoC,IACpCW,EAAKX,QAAQ2C,aAAe,MAC5BD,GAAiB,SAGgB,IAAnC1C,EAAQC,yBACVzC,EAAuBwC,EAAQC,wBAC/BzB,EAAmBmC,EAAKX,QAAQvB,UAElCkC,EAAKX,QAAQ6B,MAAMC,UAAUC,KAAK,CAChCC,SAAU5D,EAEV6D,OAAO,EACPC,YAAa,IAAM1B,EAAaR,EAASW,EAAKX,QAAQvB,QAASkC,EAAKX,QAAQjB,SAE9E,MAAM6D,EAAS5D,EAAK2B,EAAKX,QAAQoC,SAAUhE,GAGrCyE,OAA6C,IAAnC7C,EAAQC,uBACpB4C,GACFlC,EAAKX,QAAQ6B,MAAMC,UAAUC,KAAK,CAChCC,SAAU3D,EACV4D,OAAO,EACPC,YAAa,IAzGnB,SACElC,EACAvB,EACAM,GAEA,MAAMuB,KAAEA,EAAAC,SAAMA,GAAaR,EAAeC,EAASvB,EAASM,GAC5D,MAAO,CACL,2CACA,iFACGuB,EACH,GACA,oEAAoEC,OACpE,IACAvB,KAAK,KACT,CA2FyB8D,CAAc9C,EAASW,EAAKX,QAAQvB,QAASkC,EAAKX,QAAQjB,OAAS,MAG1F,MAAMgE,EAAU/D,EAAK2B,EAAKX,QAAQoC,SAAU/D,GAC5CqC,EAAyBC,EAAMX,GAC/BW,EAAKL,KAAK,eAAiB0C,IACzB,MAAMX,EAAWW,EAAOX,UAAY,GAIpC,GADKA,EAAQY,SAASL,IAASP,EAAQN,KAAKa,IACvCC,EAAS,OACd,MAAMK,EAAYF,EAAOE,WAAa,GACjCA,EAASZ,KAAMC,GAAUA,EAAMQ,UAAYA,IAC9CG,EAASnB,KAAK,CAAEoB,YAAY,EAAMJ,aAGxC,CAGAN,EAAkBW,KAAO,CACvB3D,KAAM,uBACN4D,UAAW,eASbZ,EAAkBa,QAAU,IAC1BC,QAAQC,QAAQf,EAAkBW,MAiBpC,IAAMK,EAAc,sCAab,SAASC,EACdC,EACA3D,GAGA,MAAM4D,EAAO3C,QAAQW,MAerB,MAAO,CALQ,CACbnC,KAAM,qCACNoE,UAAYC,GAA+B,oBAAoBC,KAAKD,GAAML,EAAc,KACxFO,KAAOF,GAA+BA,IAAOL,EAAc,oBAAsB,MAEnEE,EAAI,CAAEM,SAAU,CAAEC,qBAdL,CAC3BC,EACAC,EACAC,EACAC,IAGOA,EADa3C,EAAS3B,EAAQa,OAAQ2C,EAAQI,EAAMO,IAAWI,WAAW,KAAM,OACxC,IAAjBF,EAAwBD,EAAS,QAQnE,Q","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DocumentSessionOptions, a as DocumentSnapshot } from '../../document-session-
|
|
2
|
-
export { b as DocumentStatus } from '../../document-session-
|
|
1
|
+
import { D as DocumentSessionOptions, a as DocumentSnapshot } from '../../document-session-oK92QjES.js';
|
|
2
|
+
export { b as DocumentStatus } from '../../document-session-oK92QjES.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `<LivePreviewRouteRefresh />` — lends the runtime the host router's own
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{useTransition as e,useRef as t,useEffect as i,useSyncExternalStore as n}from"react";function r(e){return("object"==typeof e&&null!==e||"function"==typeof e)&&"function"==typeof e.then&&(Promise.resolve(e).catch(()=>{}),!0)}function s(){}function o(e){if(++e.nodes>1e4)throw new Error("invalid or oversized field schema")}function a(e,t,i){if(o(t),i>64||t.active.has(e))throw new Error("invalid or oversized field schema");t.active.add(e)}function c(e){try{return l(e,{nodes:0,active:/* @__PURE__ */new WeakSet},0)}catch{return[]}}function l(e,t,i){if(!Array.isArray(e))return[];a(e,t,i);const n=[];for(const r of e){const e=d(r,t,i);e&&n.push(e)}return t.active.delete(e),n}function d(e,t,i){if(o(t),"object"!=typeof e||null===e)return;const n=e,r=n.name,s=n.type;if("string"!=typeof r||0===r.length)return;if("string"!=typeof s||0===s.length)return;const c=l(n.fields,t,i+1),d=function(e,t,i){if("object"==typeof e&&null!==e&&!Array.isArray(e)){a(e,t,i);const n=[];for(const r in e){if(!Object.hasOwn(e,r))continue;o(t);const s=Reflect.get(e,r);"object"!=typeof s||null===s||["__proto__","constructor","prototype"].includes(r)||n.push({...s,slug:r,fields:l(s.fields,t,i+1)})}return t.active.delete(e),n}if(!Array.isArray(e))return[];a(e,t,i);const n=[];for(const r of e){if(o(t),"object"!=typeof r||null===r)continue;const e=r,s=e.slug;if("string"!=typeof s||0===s.length)continue;const a=l(e.fields,t,i+1);n.push({...e,slug:s,fields:a})}return t.active.delete(e),n}(n.blocks,t,i+1),u={...n,name:r,type:s},h=n.relationTo;if(Array.isArray(h)){const e=[];for(const i of h)o(t),e.push(i);u.relationTo=e}return c.length>0?u.fields=c:delete u.fields,d.length>0?u.blocks=d:delete u.blocks,u}function u(e,t){return void 0===e||t(e)}function h(e,t){return null==e||t(e)}function f(e){if("object"!=typeof e||null===e)return!1;const t=Object.getPrototypeOf(e);return null===t||null===Object.getPrototypeOf(t)}var p=["data","fieldSchemaJSON","globalSlug","collectionSlug","locale","ready","previewToken","protocolVersion"],v=1e4,g=1048576,y=/* @__PURE__ */new Set(["__proto__","constructor","prototype"]);function m(){throw new Error("invalid or oversized legacy population")}function b(e){for(let t=0;t<e.length;t+=1){const i=e.charCodeAt(t);if(i<=31||127===i)return!0}return!1}function w(e,t){if("string"!=typeof e||0===e.length||e.length>t||"."===e||".."===e)return!1;if(e.includes("/")||e.includes("\\")||b(e))return!1;try{return encodeURIComponent(e),!0}catch{return!1}}function S(e){return w(e,128)&&!/[?#%]/u.test(e)&&!y.has(e)}function R(e){return Number.isFinite(e)?String(e):w(e,512)?e:m()}function A(e,t){return Object.hasOwn(e,t)?Reflect.get(e,t):void 0}function O(e,t,i){Object.defineProperty(e,t,{value:i,writable:!0,configurable:!0,enumerable:!0})}function L(e){let t=e.length;for(;t>0&&47===e.charCodeAt(t-1);)t-=1;return e.slice(0,t)}function T(e){const t=/* @__PURE__ */new WeakSet;let i=0,n=0;return function e(r,s){if(++i>v||s>64)return m();if("string"==typeof r)return n+=r.length,n>g&&m(),r;if(null==r||"boolean"==typeof r)return r;if("number"==typeof r)return Number.isFinite(r)?r:m();if(!Array.isArray(r)&&!f(r))return m();if(Array.isArray(r)){r.length>v&&m();for(let e=0;e<r.length;e+=1)Object.hasOwn(r,e)||m()}if(t.has(r))return m();t.add(r);const o=Array.isArray(r)?[]:{};for(const t of Object.keys(r))O(o,t,e(Reflect.get(r,t),s+1));return t.delete(r),o}(e,0)}function k(e,t,i,n,r,s){if(!Number.isSafeInteger(r)||r<0||r>64)return m();void 0!==s&&("string"!=typeof s||s.length>128||b(s))&&m();const o=T(e);if(!f(o))return m();const a=/* @__PURE__ */new Map,c=/* @__PURE__ */new Set;let l=0;const d=/* @__PURE__ */new WeakSet,u=e=>{(++l>v||e>64)&&m()};function h(e,t,i,n){if(null==n||""===n)return;const s=f(n)?A(n,"id"):n,o=R(s);if(0===r)return void O(e,t,s);const l=JSON.stringify([i,o]);c.add(l),c.size>1e3&&m();const d=a.get(i)??[];d.push({owner:e,key:t,id:o}),a.set(i,d)}function p(e,t,i){void 0!==i.hasMany&&"boolean"!=typeof i.hasMany&&m();const n=i.relationTo,r=A(e,t);if(Array.isArray(n)){0===n.length&&m();const e=f(r)?A(r,"relationTo"):void 0;let t;for(const i of n)u(0),S(i)||m(),i===e&&(t=i);if(null==r||""===r)return;f(r)&&void 0!==t||m(),h(r,"value",t,A(r,"value"))}else S(n)||m(),h(e,t,n,r)}function g(e,t){if(u(t),Array.isArray(e)||f(e)){if(f(e)&&Object.hasOwn(e,"relationTo")&&Object.hasOwn(e,"value")){const t=A(e,"relationTo");return S(t)||m(),void h(e,"value",t,A(e,"value"))}for(const i of Object.keys(e))g(Reflect.get(e,i),t+1)}}!function e(t,i,n){u(n),d.has(t)&&m(),d.add(t);for(const r of t){u(n),f(r)&&w(r.name,512)&&!y.has(r.name)||m();const t=A(i,r.name);if("relationship"===r.type||"upload"===r.type)if(r.hasMany)if(null==t||Array.isArray(t)||m(),Array.isArray(t))for(let e=0;e<t.length;e+=1)p(t,e,r);else p(i,r.name,r);else p(i,r.name,r);else if("group"===r.type||"tabs"===r.type)null==t||f(t)||m(),f(t)&&r.fields&&e(r.fields,t,n+1);else if("row"===r.type||"collapsible"===r.type)r.fields&&e(r.fields,i,n+1);else if("array"===r.type||"blocks"===r.type){if(0===t?O(i,r.name,[]):null==t||Array.isArray(t)||m(),Array.isArray(t))for(const i of t)if(f(i)||m(),"array"===r.type&&r.fields)e(r.fields,i,n+1);else if("blocks"===r.type){const t=A(i,"blockType"),s=r.blocks?.find(e=>(u(n),e.slug===t));void 0===s&&m(),e(s.fields,i,n+1)}}else"richText"===r.type&&g(t,n+1)}d.delete(t)}(t,o,0),a.size>25&&m();const k=[];if(0===a.size)return{doc:o,requests:k};const P=new URL(i);(!["http:","https:"].includes(P.protocol)||P.username||P.password||P.search||P.hash)&&m(),(!n.startsWith("/")||n.includes("\\")||/[%?#]/u.test(n)||b(n))&&m(),n.split("/").some(e=>"."===e||".."===e)&&m();const U=`${L(i)}${L(n)}/`;for(const[e,t]of a){const i=[...new Set(t.map(e=>e.id))];let n=0;for(;n<i.length;){const o=i[n];void 0===o&&m();const a=o.includes(","),c=[];let l="";for(;n<i.length&&c.length<20;){const t=i[n];if(void 0===t||c.length>0&&(a||t.includes(",")))break;const o=[...c,t],d=new URLSearchParams({depth:String(r),limit:String(o.length)});void 0!==s&&d.set("locale",s),d.set(a?"where[id][equals]":"where[id][in]",a?t:o.join(","));const u=`${U}${encodeURIComponent(e)}?${d}`;if(u.length>8192){0===c.length&&m();break}new URL(u).origin!==P.origin&&m(),c.push(t),n+=1,l=u}(0===c.length||k.length>=64)&&m();const d=new Set(c);k.push({url:l,ids:d,slots:t.filter(e=>d.has(e.id))})}}return{doc:o,requests:k}}async function P(e,t,i){let n,r=!1,s=!1;const o=/* @__PURE__ */Symbol();let a;const c=new Promise(e=>{a=()=>{e(o)}}),l=()=>{i()&&!t.aborted||m()},d=()=>{if(void 0!==n&&!r){r=!0;try{Promise.resolve(n.cancel()).catch(()=>{})}catch{}}},u=()=>{a?.(),d()};t.addEventListener("abort",u,{once:!0});try{l();const t=e.body??null;if(l(),null===t){const t=e.json.bind(e);l();const i=await Promise.race([Promise.resolve().then(()=>(l(),t())),c]);return l(),i===o&&m(),i}const i=t.getReader.bind(t);l();const r=i();n=r,l();const a=[];let d=0,u=0;for(;;){const e=Promise.resolve().then(()=>{l();const e=r.read.bind(r);return l(),e()}),t=await Promise.race([e,c]);if(l(),t===o&&m(),t.done)break;d+=t.value.byteLength,(++u>1e4||d>g)&&m(),a.push(t.value)}s=!0;const h=new Uint8Array(d);let f=0;for(const e of a)h.set(e,f),f+=e.byteLength;try{return JSON.parse((new TextDecoder).decode(h))}catch{return m()}}finally{t.removeEventListener("abort",u),s||d();try{n?.releaseLock()}catch{}}}function U(e,t){const i=T(t);f(i)||m();const n=A(i,"docs");(!Array.isArray(n)||n.length>20)&&m();const r=/* @__PURE__ */new Map;for(const t of n){f(t)||m();const i=R(A(t,"id"));e.ids.has(i)&&!r.has(i)||m(),r.set(i,t)}r.size!==e.ids.size&&m();for(const t of e.slots)O(t.owner,t.key,r.get(t.id))}function M(e,t){return e.length>0&&e.length<=t&&"."!==e&&".."!==e&&!e.includes("/")&&!e.includes("\\")&&!function(e){for(const t of e){const e=t.codePointAt(0)??0;if(e<=31||127===e)return!0}return!1}(e)}function $(e){return M(e,128)&&!e.includes("?")&&!e.includes("#")}function j(e){return"number"==typeof e?Number.isFinite(e):"string"==typeof e&&M(e,512)}var I=new Error,q=class{serverURL;apiRoute;depth;fetchFn;log;timeoutMs;inflight=null;attempt=0;destroyDepth=0;constructor(e){this.serverURL=function(e){let t=e.length;for(;e.endsWith("/",t);)t-=1;return e.slice(0,t)}(e.serverURL);const t=e.apiRoute??"/api";var i;this.apiRoute=t.startsWith("/")?t:`/${t}`,this.depth=e.depth??1,this.fetchFn=e.fetchFn,this.log=(i=e.log??s,(...e)=>{try{r(i(...e))}catch{}});const n=e.timeoutMs??0;this.timeoutMs=n>0&&n<Number.POSITIVE_INFINITY?n:void 0}canMerge(e){try{const t=e.schema;return void 0!==t?(k(e.data,t,this.serverURL,this.apiRoute,this.depth,e.locale),!0):null!==this.endpointOf(e)}catch{return!1}}endpointOf(e){try{const t=e.globalSlug;if(t)return $(t)?{path:`globals/${encodeURIComponent(t)}`,field:"globalType",value:t}:null;const i=e.collectionSlug??"",n=e.data.id;return $(i)&&j(n)?{path:`${encodeURIComponent(i)}/${encodeURIComponent(String(n))}`,field:"id",value:String(n)}:null}catch{return null}}async merge(e){if(this.destroyDepth>0)return{status:"superseded"};const t=this.attempt+=1,i=this.inflight;this.inflight=null;let n=null,r=!1;const s=()=>this.attempt!==t,o=this.timeoutMs;let a,c,l=!1;const d=(e,t)=>void 0===o?e:(void 0===c&&(c=new Promise((e,i)=>{a=setTimeout(()=>{l=!0,t.abort(),i(I)},o)}),c.catch(()=>{})),Promise.race([e,c]));try{if(i?.abort(),s())return{status:"superseded"};const t=e.schema;if(r=void 0!==t,void 0!==t){const i=k(e.data,t,this.serverURL,this.apiRoute,this.depth,e.locale);if(s())return{status:"superseded"};if(0===i.requests.length)return{status:"merged",doc:i.doc};const r=this.fetchFn??("function"==typeof fetch?fetch:void 0);if(s())return{status:"superseded"};if(void 0===r)return{status:"unavailable"};n=new AbortController,this.inflight=n;for(const e of i.requests){const t=await d(r(e.url,{method:"GET",credentials:"include",redirect:"error",signal:n.signal}),n);if(s())return{status:"superseded"};const i=t.ok;if(s())return{status:"superseded"};if(!i){const e=t.status;return s()?{status:"superseded"}:(n.abort(),s()?{status:"superseded"}:(this.log("merge HTTP",e),s()?{status:"superseded"}:{status:"unavailable"}))}const o=await d(P(t,n.signal,()=>!s()),n);if(s())return{status:"superseded"};if(U(e,o),s())return{status:"superseded"}}return{status:"merged",doc:i.doc}}const o=this.endpointOf(e);if(s())return{status:"superseded"};if(null===o)return{status:"unavailable"};const a=this.fetchFn??("function"==typeof fetch?fetch:void 0);if(s())return{status:"superseded"};if(void 0===a)return{status:"unavailable"};const c=JSON.stringify({data:e.data,depth:this.depth,flattenLocales:!1,locale:e.locale});if(s())return{status:"superseded"};n=new AbortController,this.inflight=n;const l=`${this.serverURL}${this.apiRoute}/${o.path}`,u=await d(a(l,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json","X-Payload-HTTP-Method-Override":"GET"},body:c,signal:n.signal}),n);if(s())return{status:"superseded"};const h=u.ok;if(s())return{status:"superseded"};if(!h){const e=u.status;return s()?{status:"superseded"}:(this.log("merge HTTP",e,l),s()?{status:"superseded"}:{status:"unavailable"})}const f=u.json.bind(u);if(s())return{status:"superseded"};const p=await d(f(),n);if(s())return{status:"superseded"};if(null===p||"object"!=typeof p||Array.isArray(p))return this.log("merge invalid",l),s()?{status:"superseded"}:{status:"unavailable"};const v=p,g=v[o.field],y=Object.hasOwn(v,o.field)&&("id"===o.field?!j(g)||String(g)!==o.value:g!==o.value);return s()?{status:"superseded"}:y?(this.log("merge invalid",l),s()?{status:"superseded"}:{status:"unavailable"}):{status:"merged",doc:v}}catch(e){return s()?{status:"superseded"}:l?(this.log("merge timeout",o),{status:"unavailable"}):r&&(n?.abort(),s())?{status:"superseded"}:(this.log("merge exception",r?new Error("legacy population could not be resolved"):e),s()?{status:"superseded"}:{status:"unavailable"})}finally{clearTimeout(a),this.inflight===n&&(this.inflight=null)}}destroy(){this.attempt+=1;const e=this.inflight;this.inflight=null,this.destroyDepth+=1;try{e?.abort()}finally{this.destroyDepth-=1}}},N=class{matcher;handlers;boundListener=void 0;attachedTarget=void 0;generation=0;revision=0;queueHead=void 0;queueTail=void 0;lastAccepted=void 0;replayedGeneration=0;latestAcceptedAttempt=void 0;constructor(e,t){this.matcher=e,this.handlers=t}attach(e=window){if(void 0!==this.attachedTarget)return;let t=!1;const i=n=>{if(!t||this.boundListener!==i)return;const r=this.generation;try{this.receive(n,r,e)}catch{let e;try{e=n.origin}catch{e=""}this.reportInvalid("shape",e,r)}};this.generation+=1,this.resetQueue(),this.attachedTarget=e,this.boundListener=i;try{e.addEventListener("message",i)}catch(t){this.boundListener===i&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue());try{e.removeEventListener("message",i)}catch{}throw t}if(this.boundListener===i)t=!0;else try{e.removeEventListener("message",i)}catch{}}detach(){const e=this.attachedTarget,t=this.boundListener;void 0!==e&&void 0!==t&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue(),e.removeEventListener("message",t))}advanceGeneration(){return void 0!==this.attachedTarget&&(this.generation+=1,this.resetQueue(),!0)}replayLastAccepted(){const e=this.lastAccepted,t=this.generation,i=this.handlers.onReplay;if(void 0===i||void 0===e||e.generation>=t||this.replayedGeneration===t)return!1;if(!this.matchesOrigin(e.origin,t)||this.lastAccepted!==e)return!1;this.replayedGeneration=t;const n={generation:t,revision:this.revision+=1};return this.invokeHandler(t,i,structuredClone(e.message),e.origin,n),!0}forgetLastAccepted(){this.lastAccepted=void 0,this.replayedGeneration=0,this.latestAcceptedAttempt=void 0}static sendReady(e,t){const i={type:"payload-live-preview",ready:!0,protocolVersion:4};for(const n of e)for(const e of t)try{n.postMessage(i,e)}catch{}}receive(e,t,i){const n=e.origin;if(!this.matchesOrigin(n,t))return void this.reportInvalid("origin",n,t);if(!this.matchesSource(e,i))return void this.reportInvalid("source",n,t);const r=e.data;var s;if("object"==typeof(s=r)&&null!==s&&"type"in s&&"string"==typeof s.type)switch(r.type){case"payload-live-preview":return function(e){const t=e;return!(void 0!==t.data&&null!==t.data&&!f(t.data))&&h(t.fieldSchemaJSON,e=>Array.isArray(e))&&h(t.globalSlug,e=>"string"==typeof e)&&h(t.collectionSlug,e=>"string"==typeof e)&&h(t.locale,e=>"string"==typeof e)&&h(t.ready,e=>"boolean"==typeof e)&&h(t.previewToken,e=>"string"==typeof e)&&h(t.protocolVersion,e=>"number"==typeof e)}(r)?void this.dispatchUpdate(function(e){const t={...e};for(const e of p)null===Reflect.get(t,e)&&Reflect.deleteProperty(t,e);return Array.isArray(t.fieldSchemaJSON)?{...t,fieldSchemaJSON:c(t.fieldSchemaJSON)}:t}(r),n,t):void this.reportInvalid("shape",n,t);case"payload-document-event":return function(e){const t=e;return u(t.action,e=>"updated"===e||"created"===e||"deleted"===e)&&u(t.slug,e=>"string"==typeof e)&&u(t.id,e=>"string"==typeof e||Number.isFinite(e))}(r)?void this.invokeHandler(t,this.handlers.onDocumentEvent,r,n):void this.reportInvalid("shape",n,t);case"payload-live-preview-focus":{const e=function(e){const t=e.field;return"string"==typeof t&&t.length>0?t:void 0}(r);return void 0===e?void this.reportInvalid("shape",n,t):void this.invokeHandler(t,this.handlers.onFocusField,e,n)}default:this.reportInvalid("type",n,t)}else this.reportInvalid("shape",n,t)}dispatchUpdate(e,t,i){const n=f(e.data);if(!this.isCurrentGeneration(i))return;const r=n?{generation:i,revision:this.revision+=1}:void 0,s=this.handlers.validateToken;if(!this.isCurrentGeneration(i))return;if(void 0===s)return void this.commitUpdate(e,t,i,r);if(!0===e.ready&&void 0===e.data)return void this.commitUpdate(e,t,i,void 0);const o={generation:i,message:e,origin:t,messageRevision:r,verdict:void 0,next:void 0};let a;this.enqueue(o);try{a=s(e.previewToken,t)}catch{return void this.settleValidation(o,!1)}"boolean"!=typeof a?Promise.resolve(a).then(e=>{this.settleValidation(o,!0===e)},()=>{this.settleValidation(o,!1)}):this.settleValidation(o,a)}settleValidation(e,t){e.verdict=t,this.drainQueue(e.generation)}drainQueue(e){for(;this.isCurrentGeneration(e);){const t=this.queueHead;if(void 0===t)return;if(this.matchesOrigin(t.origin,e)){if(void 0===t.verdict)return;this.dequeue(t)&&(t.verdict?this.commitUpdate(t.message,t.origin,t.generation,t.messageRevision):this.reportInvalid("token",t.origin,t.generation))}else{if(!this.dequeue(t))continue;this.reportInvalid("origin",t.origin,t.generation)}}}commitUpdate(e,t,i,n){if(void 0===n)this.invokeHandler(i,this.handlers.onUpdate,e,t);else{const r={};this.latestAcceptedAttempt=r;const s=function(e){const t={...e};delete t.previewToken;try{return structuredClone(t)}catch{return null}}(e);if(this.latestAcceptedAttempt!==r||!this.isCurrentGeneration(i))return;this.lastAccepted=null===s?void 0:{generation:i,message:s,origin:t},this.invokeHandler(i,this.handlers.onUpdate,e,t,n)}}reportInvalid(e,t,i){this.invokeHandler(i,this.handlers.onInvalid,e,t)}matchesSource(e,t){if("parent-or-opener"!==this.handlers.sourcePolicy)return!0;try{const i=e.source;if("object"!=typeof i||null===i)return!1;const n=t.parent;return n!==t&&i===n||i===t.opener}catch{return!1}}matchesOrigin(e,t){try{return!0===(this.isCurrentGeneration(t)&&this.matcher(e))&&this.isCurrentGeneration(t)}catch{return!1}}invokeHandler(e,t,...i){if(void 0!==t&&this.isCurrentGeneration(e))try{r(t(...i))}catch{}}isCurrentGeneration(e){return void 0!==this.attachedTarget&&this.generation===e}enqueue(e){void 0===this.queueTail?this.queueHead=e:this.queueTail.next=e,this.queueTail=e}dequeue(e){return this.queueHead===e&&(this.queueHead=e.next,void 0===this.queueHead&&(this.queueTail=void 0),!0)}resetQueue(){this.queueHead=void 0,this.queueTail=void 0}};function isDevMode(){const e=function(){if("undefined"==typeof process)return;const e=process.env.NODE_ENV;return"string"==typeof e?e:void 0}();if(void 0!==e)return"production"!==e;if("undefined"!=typeof window){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e}return!1}var E=/^https?:\/\/(localhost|127\.0\.0\.1)(?::\d+)?$/i,C=/^https?:\/\/[^/?#\s]+$/i,D=[3e3,3001,3333,4e3,4321,5e3,5173,5174,8e3,8080,8888,9e3];function F(){if("undefined"==typeof location)return;const e=location.ancestorOrigins;return e?.[0]}var OriginDetector=class{#e;constructor(e={}){const t=/* @__PURE__ */new Set;for(const i of e.additionalOrigins??[]){const e=H(i);void 0!==e&&t.add(e)}let i;if(e.enableReferrerDetection??1){const t=e.referrer??("undefined"!=typeof document?document.referrer:"");if(t.length>0)try{const e=new URL(t).origin;e&&"null"!==e&&(i=e)}catch{}}const n=(e.enableLocalhostMatching??!0)&&(e.forceDevMode??isDevMode());this.#e=[t,i,n,void 0!==i,void 0,F()]}matches(e){return 0!==e.length&&"null"!==e&&(void 0!==this.#e[4]?e===this.#e[4]:!!this.#e[0].has(e)||0===this.#e[0].size&&void 0!==this.#e[1]&&e===this.#e[1]||!(!this.#e[2]||!E.test(e)))}lockOrigin(e){return!!this.matches(e)&&(this.#e[4]=e,!0)}unlockOrigin(){const e=this.#e[4];return this.#e[4]=void 0,e}get lockedOrigin(){return this.#e[4]}enumerate(){if(void 0!==this.#e[4])return[this.#e[4]];const e=new Set(this.#e[0]);0===this.#e[0].size&&void 0!==this.#e[1]&&e.add(this.#e[1]);const t=this.#e[5];if(this.#e[2]&&void 0!==t)E.test(t)&&e.add(t);else if(this.#e[2])for(const t of D)e.add(`http://localhost:${String(t)}`),e.add(`http://127.0.0.1:${String(t)}`);return[...e]}get referrerWasAvailable(){return this.#e[3]}get isProductionUnconfigured(){return!(!function isInIframe(){if("undefined"==typeof window)return!1;try{return window.self!==window.top}catch{return!0}}()||this.#e[0].size>0||this.#e[2]||void 0!==this.#e[1])}get isReferrerOnlyTrust(){return!(this.#e[0].size>0||this.#e[2]||void 0===this.#e[1])}};function H(e){const t=e.trim();if(0!==t.length)try{const e=new URL(t);if("http:"!==e.protocol&&"https:"!==e.protocol)return;if(!C.test(e.origin))return;return e.origin}catch{return}}function G(e){const[t,i]=e;return"merge HTTP"===t?`the server answered ${String(i)}`:"merge timeout"===t?`the server did not answer within ${String(i)} ms`:"merge invalid"===t?"the server answered with something other than a document":"merge exception"===t?i instanceof Error?i.message:"the request failed":"the update could not be merged"}var z=class{#t;#i;#n;#r;#s=/* @__PURE__ */new Set;#o;#a;#c=0;#l=[];#d=!1;#u;#h;#f;#p=!1;#v=!1;constructor(e,t){this.#n=new OriginDetector({...void 0!==t.allowedOrigins?{additionalOrigins:t.allowedOrigins}:{},enableReferrerDetection:t.enableReferrerDetection??!1,...void 0!==t.enableLocalhostMatching?{enableLocalhostMatching:t.enableLocalhostMatching}:{}}),this.#t=new q({serverURL:t.serverURL,...void 0!==t.apiRoute?{apiRoute:t.apiRoute}:{},...void 0!==t.depth?{depth:t.depth}:{},...void 0!==t.timeoutMs?{timeoutMs:t.timeoutMs}:{},...void 0!==t.fetchFn?{fetchFn:t.fetchFn}:{},log:(...e)=>{this.#l=e}}),this.#i=new N(e=>this.#n.matches(e),{onUpdate:e=>{this.#g(e)},onDocumentEvent:()=>{},sourcePolicy:t.eventSourcePolicy??"parent-or-opener"}),this.#r=t.target,this.#f=t.document,this.#o={data:e,isLoading:!0,status:"idle",error:void 0,revision:0},this.#a=this.#o}subscribe=e=>(this.#s.add(e),this.#d||this.#y(),()=>{this.#s.delete(e),0===this.#s.size&&this.#m()});getSnapshot=()=>this.#a;getServerSnapshot=()=>this.#o;#y(){"undefined"==typeof window&&void 0===this.#r||(this.#d=!0,this.#i.attach(this.#r??window),N.sendReady(this.#b(),this.#n.enumerate()))}#m(){this.#d&&(this.#d=!1,this.#c+=1,this.#i.detach(),this.#t.destroy())}#b(){const e=this.#r??("undefined"==typeof window?void 0:window);if(void 0===e)return[];const t=[];e.parent!==e&&t.push(e.parent);const i=e.opener;return null!=i&&i!==e&&t.push(i),t}#w(e){return this.#d&&e===this.#c}#S(e,t){const i=this.#f;if(void 0===i)return!0;const{locale:n,globalSlug:r,collectionSlug:s}=e;if(void 0!==i.locale&&void 0!==n&&n!==i.locale)return!1;if("global"in i){if(void 0!==r)return r===i.global;if(void 0!==s)return!1}else{if(void 0!==r)return!1;if(void 0!==s&&s!==i.collection)return!1;const e=void 0===s?void 0:function(e){const t=e.id;return"string"==typeof t&&t.length>0?t:"number"==typeof t&&Number.isFinite(t)?String(t):void 0}(t);if(void 0!==e)return e===String(i.id)}return this.#R(i),!1}#R(e){if(this.#p||!isDevMode())return;this.#p=!0;const t="global"in e?`global "${e.global}"`:`collection "${e.collection}", id "${String(e.id)}"`;console.warn(`[payload-live-preview] This hook previews ${t} and ignored an update that does not say which document it is for: Payload 2 sends no collection or global slug, and a create screen has no id yet.`)}async#g(e){const t=e.data;if(void 0===t)return;if(void 0!==e.fieldSchemaJSON&&!this.#v&&isDevMode()&&(this.#v=!0,console.warn("[payload-live-preview] This admin sends fieldSchemaJSON, which only Payload 2 does. Every 2.x release of this package supports Payload 2; 3.0 supports Payload 3 and 4.")),!this.#S(e,t))return;const i=this.#c+=1;void 0!==e.fieldSchemaJSON&&(this.#u=e.fieldSchemaJSON);const n=this.#u;void 0!==e.locale&&(this.#h=e.locale);const r=void 0===n?e.locale:this.#h;if(this.#A({...this.#a,isLoading:!0}),!this.#w(i))return;this.#l=[];const s=await this.#t.merge({data:t,...void 0===n?{}:{schema:n},...void 0!==e.collectionSlug?{collectionSlug:e.collectionSlug}:{},...void 0!==e.globalSlug?{globalSlug:e.globalSlug}:{},...void 0!==r?{locale:r}:{}});this.#w(i)&&"superseded"!==s.status&&("unavailable"!==s.status?this.#A({data:s.doc,isLoading:!1,status:"live",error:void 0,revision:i}):this.#A({...this.#a,isLoading:!1,status:"unavailable",error:new Error(`live preview: ${G(this.#l)}`)}))}#A(e){const t=this.#a;if(t.data!==e.data||t.isLoading!==e.isLoading||t.status!==e.status||t.error!==e.error||t.revision!==e.revision){this.#a=e;for(const e of[...this.#s])e()}}},J="__livePreviewRouteRefresh";function registerRouteRefresh(e){const t="undefined"==typeof window?void 0:window;return void 0===t?()=>{}:(t[J]=e,()=>{t[J]===e&&(t[J]=void 0)})}function _(e){const t=e.current;e.current=[];for(const e of t)e()}function V({refresh:n}){const[r,s]=e(),o=t([]);return i(()=>{r||_(o)}),i(()=>{const e=registerRouteRefresh(()=>new Promise(e=>{o.current.push(e),s(()=>{n()})}));return()=>{e(),_(o)}},[n,s]),null}function x(e){const i=function(e){const{initialData:i,serverURL:n,apiRoute:r,depth:s,timeoutMs:o,allowedOrigins:a,eventSourcePolicy:c,enableReferrerDetection:l,enableLocalhostMatching:d,document:u,fetchFn:h,target:f}=e,p=[n,r??"",String(s??""),String(o??""),(a??[]).join(" "),c??"",String(l??""),String(d??""),void 0===u?"":"global"in u?`global ${u.global} ${u.locale??""}`:`collection ${u.collection} ${String(u.id)} ${u.locale??""}`].join(" | "),v=t(null);return v.current?.key===p&&v.current.target===f||(v.current={key:p,target:f,session:new z(i,{serverURL:n,...void 0!==r?{apiRoute:r}:{},...void 0!==s?{depth:s}:{},...void 0!==o?{timeoutMs:o}:{},...void 0!==a?{allowedOrigins:a}:{},...void 0!==c?{eventSourcePolicy:c}:{},...void 0!==l?{enableReferrerDetection:l}:{},...void 0!==d?{enableLocalhostMatching:d}:{},...void 0!==u?{document:u}:{},...void 0!==h?{fetchFn:h}:{},...void 0!==f?{target:f}:{}})}),v.current.session}(e);return n(i.subscribe,i.getSnapshot,i.getServerSnapshot)}export{V as LivePreviewRouteRefresh,registerRouteRefresh,x as useLivePreviewDocument};
|
|
2
|
+
import{useTransition as e,useRef as t,useEffect as i,useSyncExternalStore as n}from"react";function r(e){return("object"==typeof e&&null!==e||"function"==typeof e)&&"function"==typeof e.then&&(Promise.resolve(e).catch(()=>{}),!0)}function o(){}function s(e){if(++e.nodes>1e4)throw new Error("invalid or oversized field schema")}function a(e,t,i){if(s(t),i>64||t.active.has(e))throw new Error("invalid or oversized field schema");t.active.add(e)}function c(e){try{return l(e,{nodes:0,active:/* @__PURE__ */new WeakSet},0)}catch{return[]}}function l(e,t,i){if(!Array.isArray(e))return[];a(e,t,i);const n=[];for(const r of e){const e=d(r,t,i);e&&n.push(e)}return t.active.delete(e),n}function d(e,t,i){if(s(t),"object"!=typeof e||null===e)return;const n=e,r=n.name,o=n.type;if("string"!=typeof r||0===r.length)return;if("string"!=typeof o||0===o.length)return;const c=l(n.fields,t,i+1),d=function(e,t,i){if("object"==typeof e&&null!==e&&!Array.isArray(e)){a(e,t,i);const n=[];for(const r in e){if(!Object.hasOwn(e,r))continue;s(t);const o=Reflect.get(e,r);"object"!=typeof o||null===o||["__proto__","constructor","prototype"].includes(r)||n.push({...o,slug:r,fields:l(o.fields,t,i+1)})}return t.active.delete(e),n}if(!Array.isArray(e))return[];a(e,t,i);const n=[];for(const r of e){if(s(t),"object"!=typeof r||null===r)continue;const e=r,o=e.slug;if("string"!=typeof o||0===o.length)continue;const a=l(e.fields,t,i+1);n.push({...e,slug:o,fields:a})}return t.active.delete(e),n}(n.blocks,t,i+1),u={...n,name:r,type:o},h=n.relationTo;if(Array.isArray(h)){const e=[];for(const i of h)s(t),e.push(i);u.relationTo=e}return c.length>0?u.fields=c:delete u.fields,d.length>0?u.blocks=d:delete u.blocks,u}function u(e,t){return void 0===e||t(e)}function h(e,t){return null==e||t(e)}function f(e){if("object"!=typeof e||null===e)return!1;const t=Object.getPrototypeOf(e);return null===t||null===Object.getPrototypeOf(t)}var p=["data","fieldSchemaJSON","globalSlug","collectionSlug","locale","ready","previewToken","protocolVersion"],v=1e4,g=1048576,y=/* @__PURE__ */new Set(["__proto__","constructor","prototype"]);function m(){throw new Error("invalid or oversized legacy population")}function b(e){for(let t=0;t<e.length;t+=1){const i=e.charCodeAt(t);if(i<=31||127===i)return!0}return!1}function w(e,t){if("string"!=typeof e||0===e.length||e.length>t||"."===e||".."===e)return!1;if(e.includes("/")||e.includes("\\")||b(e))return!1;try{return encodeURIComponent(e),!0}catch{return!1}}function S(e){return w(e,128)&&!/[?#%]/u.test(e)&&!y.has(e)}function A(e){return Number.isFinite(e)?String(e):w(e,512)?e:m()}function R(e,t){return Object.hasOwn(e,t)?Reflect.get(e,t):void 0}function L(e,t,i){Object.defineProperty(e,t,{value:i,writable:!0,configurable:!0,enumerable:!0})}function O(e){let t=e.length;for(;t>0&&47===e.charCodeAt(t-1);)t-=1;return e.slice(0,t)}function T(e){const t=/* @__PURE__ */new WeakSet;let i=0,n=0;return function e(r,o){if(++i>v||o>64)return m();if("string"==typeof r)return n+=r.length,n>g&&m(),r;if(null==r||"boolean"==typeof r)return r;if("number"==typeof r)return Number.isFinite(r)?r:m();if(!Array.isArray(r)&&!f(r))return m();if(Array.isArray(r)){r.length>v&&m();for(let e=0;e<r.length;e+=1)Object.hasOwn(r,e)||m()}if(t.has(r))return m();t.add(r);const s=Array.isArray(r)?[]:{};for(const t of Object.keys(r))L(s,t,e(Reflect.get(r,t),o+1));return t.delete(r),s}(e,0)}function k(e,t,i,n,r,o){if(!Number.isSafeInteger(r)||r<0||r>64)return m();void 0!==o&&("string"!=typeof o||o.length>128||b(o))&&m();const s=T(e);if(!f(s))return m();const a=/* @__PURE__ */new Map,c=/* @__PURE__ */new Set;let l=0;const d=/* @__PURE__ */new WeakSet,u=e=>{(++l>v||e>64)&&m()};function h(e,t,i,n){if(null==n||""===n)return;const o=f(n)?R(n,"id"):n,s=A(o);if(0===r)return void L(e,t,o);const l=JSON.stringify([i,s]);c.add(l),c.size>1e3&&m();const d=a.get(i)??[];d.push({owner:e,key:t,id:s}),a.set(i,d)}function p(e,t,i){void 0!==i.hasMany&&"boolean"!=typeof i.hasMany&&m();const n=i.relationTo,r=R(e,t);if(Array.isArray(n)){0===n.length&&m();const e=f(r)?R(r,"relationTo"):void 0;let t;for(const i of n)u(0),S(i)||m(),i===e&&(t=i);if(null==r||""===r)return;f(r)&&void 0!==t||m(),h(r,"value",t,R(r,"value"))}else S(n)||m(),h(e,t,n,r)}function g(e,t){if(u(t),Array.isArray(e)||f(e)){if(f(e)&&Object.hasOwn(e,"relationTo")&&Object.hasOwn(e,"value")){const t=R(e,"relationTo");return S(t)||m(),void h(e,"value",t,R(e,"value"))}for(const i of Object.keys(e))g(Reflect.get(e,i),t+1)}}!function e(t,i,n){u(n),d.has(t)&&m(),d.add(t);for(const r of t){u(n),f(r)&&w(r.name,512)&&!y.has(r.name)||m();const t=R(i,r.name);if("relationship"===r.type||"upload"===r.type)if(r.hasMany)if(null==t||Array.isArray(t)||m(),Array.isArray(t))for(let e=0;e<t.length;e+=1)p(t,e,r);else p(i,r.name,r);else p(i,r.name,r);else if("group"===r.type||"tabs"===r.type)null==t||f(t)||m(),f(t)&&r.fields&&e(r.fields,t,n+1);else if("row"===r.type||"collapsible"===r.type)r.fields&&e(r.fields,i,n+1);else if("array"===r.type||"blocks"===r.type){if(0===t?L(i,r.name,[]):null==t||Array.isArray(t)||m(),Array.isArray(t))for(const i of t)if(f(i)||m(),"array"===r.type&&r.fields)e(r.fields,i,n+1);else if("blocks"===r.type){const t=R(i,"blockType"),o=r.blocks?.find(e=>(u(n),e.slug===t));void 0===o&&m(),e(o.fields,i,n+1)}}else"richText"===r.type&&g(t,n+1)}d.delete(t)}(t,s,0),a.size>25&&m();const k=[];if(0===a.size)return{doc:s,requests:k};const P=new URL(i);(!["http:","https:"].includes(P.protocol)||P.username||P.password||P.search||P.hash)&&m(),(!n.startsWith("/")||n.includes("\\")||/[%?#]/u.test(n)||b(n))&&m(),n.split("/").some(e=>"."===e||".."===e)&&m();const U=`${O(i)}${O(n)}/`;for(const[e,t]of a){const i=[...new Set(t.map(e=>e.id))];let n=0;for(;n<i.length;){const s=i[n];void 0===s&&m();const a=s.includes(","),c=[];let l="";for(;n<i.length&&c.length<20;){const t=i[n];if(void 0===t||c.length>0&&(a||t.includes(",")))break;const s=[...c,t],d=new URLSearchParams({depth:String(r),limit:String(s.length)});void 0!==o&&d.set("locale",o),d.set(a?"where[id][equals]":"where[id][in]",a?t:s.join(","));const u=`${U}${encodeURIComponent(e)}?${d}`;if(u.length>8192){0===c.length&&m();break}new URL(u).origin!==P.origin&&m(),c.push(t),n+=1,l=u}(0===c.length||k.length>=64)&&m();const d=new Set(c);k.push({url:l,ids:d,slots:t.filter(e=>d.has(e.id))})}}return{doc:s,requests:k}}async function P(e,t,i){let n,r=!1,o=!1;const s=/* @__PURE__ */Symbol();let a;const c=new Promise(e=>{a=()=>{e(s)}}),l=()=>{i()&&!t.aborted||m()},d=()=>{if(void 0!==n&&!r){r=!0;try{Promise.resolve(n.cancel()).catch(()=>{})}catch{}}},u=()=>{a?.(),d()};t.addEventListener("abort",u,{once:!0});try{l();const t=e.body??null;if(l(),null===t){const t=e.json.bind(e);l();const i=await Promise.race([Promise.resolve().then(()=>(l(),t())),c]);return l(),i===s&&m(),i}const i=t.getReader.bind(t);l();const r=i();n=r,l();const a=[];let d=0,u=0;for(;;){const e=Promise.resolve().then(()=>{l();const e=r.read.bind(r);return l(),e()}),t=await Promise.race([e,c]);if(l(),t===s&&m(),t.done)break;d+=t.value.byteLength,(++u>1e4||d>g)&&m(),a.push(t.value)}o=!0;const h=new Uint8Array(d);let f=0;for(const e of a)h.set(e,f),f+=e.byteLength;try{return JSON.parse((new TextDecoder).decode(h))}catch{return m()}}finally{t.removeEventListener("abort",u),o||d();try{n?.releaseLock()}catch{}}}function U(e,t){const i=T(t);f(i)||m();const n=R(i,"docs");(!Array.isArray(n)||n.length>20)&&m();const r=/* @__PURE__ */new Map;for(const t of n){f(t)||m();const i=A(R(t,"id"));e.ids.has(i)&&!r.has(i)||m(),r.set(i,t)}r.size!==e.ids.size&&m();for(const t of e.slots)L(t.owner,t.key,r.get(t.id))}function q(e,t){return e.length>0&&e.length<=t&&"."!==e&&".."!==e&&!e.includes("/")&&!e.includes("\\")&&!function(e){for(const t of e){const e=t.codePointAt(0)??0;if(e<=31||127===e)return!0}return!1}(e)}function M(e){return q(e,128)&&!e.includes("?")&&!e.includes("#")}function N(e){return"number"==typeof e?Number.isFinite(e):"string"==typeof e&&q(e,512)}var $=new Error,D=class{serverURL;apiRoute;depth;fetchFn;log;timeoutMs;inflight=null;attempt=0;destroyDepth=0;constructor(e){this.serverURL=function(e){let t=e.length;for(;e.endsWith("/",t);)t-=1;return e.slice(0,t)}(e.serverURL);const t=e.apiRoute??"/api";var i;this.apiRoute=t.startsWith("/")?t:`/${t}`,this.depth=e.depth??1,this.fetchFn=e.fetchFn,this.log=(i=e.log??o,(...e)=>{try{r(i(...e))}catch{}});const n=e.timeoutMs??0;this.timeoutMs=n>0&&n<Number.POSITIVE_INFINITY?n:void 0}canMerge(e){try{const t=e.schema;return void 0!==t?(k(e.data,t,this.serverURL,this.apiRoute,this.depth,e.locale),!0):null!==this.endpointOf(e)}catch{return!1}}endpointOf(e){try{const t=e.globalSlug;if(t)return M(t)?{path:`globals/${encodeURIComponent(t)}`,field:"globalType",value:t}:null;const i=e.collectionSlug??"",n=e.data.id;return M(i)&&N(n)?{path:`${encodeURIComponent(i)}/${encodeURIComponent(String(n))}`,field:"id",value:String(n)}:null}catch{return null}}async merge(e){if(this.destroyDepth>0)return{status:"superseded"};const t=this.attempt+=1,i=this.inflight;this.inflight=null;let n=null,r=!1;const o=()=>this.attempt!==t,s=this.timeoutMs;let a,c,l=!1;const d=(e,t)=>void 0===s?e:(void 0===c&&(c=new Promise((e,i)=>{a=setTimeout(()=>{l=!0,t.abort(),i($)},s)}),c.catch(()=>{})),Promise.race([e,c]));try{if(i?.abort(),o())return{status:"superseded"};const t=e.schema;if(r=void 0!==t,void 0!==t){const i=k(e.data,t,this.serverURL,this.apiRoute,this.depth,e.locale);if(o())return{status:"superseded"};if(0===i.requests.length)return{status:"merged",doc:i.doc};const r=this.fetchFn??("function"==typeof fetch?fetch:void 0);if(o())return{status:"superseded"};if(void 0===r)return{status:"unavailable"};n=new AbortController,this.inflight=n;for(const e of i.requests){const t=await d(r(e.url,{method:"GET",credentials:"include",redirect:"error",signal:n.signal}),n);if(o())return{status:"superseded"};const i=t.ok;if(o())return{status:"superseded"};if(!i){const e=t.status;return o()?{status:"superseded"}:(n.abort(),o()?{status:"superseded"}:(this.log("merge HTTP",e),o()?{status:"superseded"}:{status:"unavailable"}))}const s=await d(P(t,n.signal,()=>!o()),n);if(o())return{status:"superseded"};if(U(e,s),o())return{status:"superseded"}}return{status:"merged",doc:i.doc}}const s=this.endpointOf(e);if(o())return{status:"superseded"};if(null===s)return{status:"unavailable"};const a=this.fetchFn??("function"==typeof fetch?fetch:void 0);if(o())return{status:"superseded"};if(void 0===a)return{status:"unavailable"};const c=JSON.stringify({data:e.data,depth:this.depth,flattenLocales:!1,locale:e.locale});if(o())return{status:"superseded"};n=new AbortController,this.inflight=n;const l=`${this.serverURL}${this.apiRoute}/${s.path}`,u=await d(a(l,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json","X-Payload-HTTP-Method-Override":"GET"},body:c,signal:n.signal}),n);if(o())return{status:"superseded"};const h=u.ok;if(o())return{status:"superseded"};if(!h){const e=u.status;return o()?{status:"superseded"}:(this.log("merge HTTP",e,l),o()?{status:"superseded"}:{status:"unavailable"})}const f=u.json.bind(u);if(o())return{status:"superseded"};const p=await d(f(),n);if(o())return{status:"superseded"};if(null===p||"object"!=typeof p||Array.isArray(p))return this.log("merge invalid",l),o()?{status:"superseded"}:{status:"unavailable"};const v=p,g=v[s.field],y=Object.hasOwn(v,s.field)&&("id"===s.field?!N(g)||String(g)!==s.value:g!==s.value);return o()?{status:"superseded"}:y?(this.log("merge invalid",l),o()?{status:"superseded"}:{status:"unavailable"}):{status:"merged",doc:v}}catch(e){return o()?{status:"superseded"}:l?(this.log("merge timeout",s),{status:"unavailable"}):r&&(n?.abort(),o())?{status:"superseded"}:(this.log("merge exception",r?new Error("legacy population could not be resolved"):e),o()?{status:"superseded"}:{status:"unavailable"})}finally{clearTimeout(a),this.inflight===n&&(this.inflight=null)}}destroy(){this.attempt+=1;const e=this.inflight;this.inflight=null,this.destroyDepth+=1;try{e?.abort()}finally{this.destroyDepth-=1}}},E=class{matcher;handlers;boundListener=void 0;attachedTarget=void 0;generation=0;revision=0;queueHead=void 0;queueTail=void 0;lastAccepted=void 0;replayedGeneration=0;latestAcceptedAttempt=void 0;constructor(e,t){this.matcher=e,this.handlers=t}attach(e=window){if(void 0!==this.attachedTarget)return;let t=!1;const i=n=>{if(!t||this.boundListener!==i)return;const r=this.generation;try{this.receive(n,r,e)}catch{let e;try{e=n.origin}catch{e=""}this.reportInvalid("shape",e,r)}};this.generation+=1,this.resetQueue(),this.attachedTarget=e,this.boundListener=i;try{e.addEventListener("message",i)}catch(t){this.boundListener===i&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue());try{e.removeEventListener("message",i)}catch{}throw t}if(this.boundListener===i)t=!0;else try{e.removeEventListener("message",i)}catch{}}detach(){const e=this.attachedTarget,t=this.boundListener;void 0!==e&&void 0!==t&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue(),e.removeEventListener("message",t))}advanceGeneration(){return void 0!==this.attachedTarget&&(this.generation+=1,this.resetQueue(),!0)}replayLastAccepted(){const e=this.lastAccepted,t=this.generation,i=this.handlers.onReplay;if(void 0===i||void 0===e||e.generation>=t||this.replayedGeneration===t)return!1;if(!this.matchesOrigin(e.origin,t)||this.lastAccepted!==e)return!1;this.replayedGeneration=t;const n={generation:t,revision:this.revision+=1};return this.invokeHandler(t,i,structuredClone(e.message),e.origin,n),!0}forgetLastAccepted(){this.lastAccepted=void 0,this.replayedGeneration=0,this.latestAcceptedAttempt=void 0}static sendReady(e,t){const i={type:"payload-live-preview",ready:!0,protocolVersion:4};for(const n of e)for(const e of t)try{n.postMessage(i,e)}catch{}}receive(e,t,i){const n=e.origin;if(!this.matchesOrigin(n,t))return void this.reportInvalid("origin",n,t);if(!this.matchesSource(e,i))return void this.reportInvalid("source",n,t);const r=e.data;var o;if("object"==typeof(o=r)&&null!==o&&"type"in o&&"string"==typeof o.type)switch(r.type){case"payload-live-preview":return function(e){const t=e;return!(void 0!==t.data&&null!==t.data&&!f(t.data))&&h(t.fieldSchemaJSON,e=>Array.isArray(e))&&h(t.globalSlug,e=>"string"==typeof e)&&h(t.collectionSlug,e=>"string"==typeof e)&&h(t.locale,e=>"string"==typeof e)&&h(t.ready,e=>"boolean"==typeof e)&&h(t.previewToken,e=>"string"==typeof e)&&h(t.protocolVersion,e=>"number"==typeof e)}(r)?void this.dispatchUpdate(function(e){const t={...e};for(const e of p)null===Reflect.get(t,e)&&Reflect.deleteProperty(t,e);return Array.isArray(t.fieldSchemaJSON)?{...t,fieldSchemaJSON:c(t.fieldSchemaJSON)}:t}(r),n,t):void this.reportInvalid("shape",n,t);case"payload-document-event":return function(e){const t=e;return u(t.action,e=>"updated"===e||"created"===e||"deleted"===e)&&u(t.slug,e=>"string"==typeof e)&&u(t.id,e=>"string"==typeof e||Number.isFinite(e))}(r)?void this.invokeHandler(t,this.handlers.onDocumentEvent,r,n):void this.reportInvalid("shape",n,t);case"payload-live-preview-focus":{const e=function(e){const t=e.field;return"string"==typeof t&&t.length>0?t:void 0}(r);return void 0===e?void this.reportInvalid("shape",n,t):void this.invokeHandler(t,this.handlers.onFocusField,e,n)}default:this.reportInvalid("type",n,t)}else this.reportInvalid("shape",n,t)}dispatchUpdate(e,t,i){const n=f(e.data);if(!this.isCurrentGeneration(i))return;const r=n?{generation:i,revision:this.revision+=1}:void 0,o=this.handlers.validateToken;if(!this.isCurrentGeneration(i))return;if(void 0===o)return void this.commitUpdate(e,t,i,r);if(!0===e.ready&&void 0===e.data)return void this.commitUpdate(e,t,i,void 0);const s={generation:i,message:e,origin:t,messageRevision:r,verdict:void 0,next:void 0};let a;this.enqueue(s);try{a=o(e.previewToken,t)}catch{return void this.settleValidation(s,!1)}"boolean"!=typeof a?Promise.resolve(a).then(e=>{this.settleValidation(s,!0===e)},()=>{this.settleValidation(s,!1)}):this.settleValidation(s,a)}settleValidation(e,t){e.verdict=t,this.drainQueue(e.generation)}drainQueue(e){for(;this.isCurrentGeneration(e);){const t=this.queueHead;if(void 0===t)return;if(this.matchesOrigin(t.origin,e)){if(void 0===t.verdict)return;this.dequeue(t)&&(t.verdict?this.commitUpdate(t.message,t.origin,t.generation,t.messageRevision):this.reportInvalid("token",t.origin,t.generation))}else{if(!this.dequeue(t))continue;this.reportInvalid("origin",t.origin,t.generation)}}}commitUpdate(e,t,i,n){if(void 0===n)this.invokeHandler(i,this.handlers.onUpdate,e,t);else{const r={};this.latestAcceptedAttempt=r;const o=function(e){const t={...e};delete t.previewToken;try{return structuredClone(t)}catch{return null}}(e);if(this.latestAcceptedAttempt!==r||!this.isCurrentGeneration(i))return;this.lastAccepted=null===o?void 0:{generation:i,message:o,origin:t},this.invokeHandler(i,this.handlers.onUpdate,e,t,n)}}reportInvalid(e,t,i){this.invokeHandler(i,this.handlers.onInvalid,e,t)}matchesSource(e,t){if("parent-or-opener"!==this.handlers.sourcePolicy)return!0;try{const i=e.source;if("object"!=typeof i||null===i)return!1;const n=t.parent;return n!==t&&i===n||i===t.opener}catch{return!1}}matchesOrigin(e,t){try{return!0===(this.isCurrentGeneration(t)&&this.matcher(e))&&this.isCurrentGeneration(t)}catch{return!1}}invokeHandler(e,t,...i){if(void 0!==t&&this.isCurrentGeneration(e))try{r(t(...i))}catch{}}isCurrentGeneration(e){return void 0!==this.attachedTarget&&this.generation===e}enqueue(e){void 0===this.queueTail?this.queueHead=e:this.queueTail.next=e,this.queueTail=e}dequeue(e){return this.queueHead===e&&(this.queueHead=e.next,void 0===this.queueHead&&(this.queueTail=void 0),!0)}resetQueue(){this.queueHead=void 0,this.queueTail=void 0}};function isDevMode(){const e=function(){if("undefined"==typeof process)return;const e=process.env.NODE_ENV;return"string"==typeof e?e:void 0}();if(void 0!==e)return"production"!==e;if("undefined"!=typeof window){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e}return!1}function j(e,t){const i=globalThis,n=i.__payloadLivePreviewNotices??=/* @__PURE__ */new Set;if(!n.has(e)){n.add(e);try{console.warn(`[payload-live-preview] ${t}`)}catch{}}}var I=/^https?:\/\/(localhost|127\.0\.0\.1)(?::\d+)?$/i,C=/^https?:\/\/[^/?#\s]+$/i,F=[3e3,3001,3333,4e3,4321,5e3,5173,5174,8e3,8080,8888,9e3];function H(){if("undefined"==typeof location)return;const e=location.ancestorOrigins;return e?.[0]}var OriginDetector=class{#e;constructor(e={}){const t=/* @__PURE__ */new Set;for(const i of e.additionalOrigins??[]){const e=_(i);void 0!==e&&t.add(e)}let i;if(e.enableReferrerDetection??1){const t=e.referrer??("undefined"!=typeof document?document.referrer:"");if(t.length>0)try{const e=new URL(t).origin;e&&"null"!==e&&(i=e)}catch{}}try{"production"!==process.env.NODE_ENV&&void 0===e.enableReferrerDetection&&void 0!==i&&0===t.size&&j("origin-referrer","`new OriginDetector()` trusts the referrer unless `enableReferrerDetection` says so; 3.0 does not (ADR 0007, row 22).")}catch{}const n=(e.enableLocalhostMatching??!0)&&(e.forceDevMode??isDevMode());this.#e=[t,i,n,void 0!==i,void 0,H()]}matches(e){return 0!==e.length&&"null"!==e&&(void 0!==this.#e[4]?e===this.#e[4]:!!this.#e[0].has(e)||0===this.#e[0].size&&void 0!==this.#e[1]&&e===this.#e[1]||!(!this.#e[2]||!I.test(e)))}lockOrigin(e){return!!this.matches(e)&&(this.#e[4]=e,!0)}unlockOrigin(){const e=this.#e[4];return this.#e[4]=void 0,e}get lockedOrigin(){return this.#e[4]}enumerate(){if(void 0!==this.#e[4])return[this.#e[4]];const e=new Set(this.#e[0]);0===this.#e[0].size&&void 0!==this.#e[1]&&e.add(this.#e[1]);const t=this.#e[5];if(this.#e[2]&&void 0!==t)I.test(t)&&e.add(t);else if(this.#e[2])for(const t of F)e.add(`http://localhost:${String(t)}`),e.add(`http://127.0.0.1:${String(t)}`);return[...e]}get referrerWasAvailable(){return this.#e[3]}get isProductionUnconfigured(){return!(!function isInIframe(){if("undefined"==typeof window)return!1;try{return window.self!==window.top}catch{return!0}}()||this.#e[0].size>0||this.#e[2]||void 0!==this.#e[1])}get isReferrerOnlyTrust(){return!(this.#e[0].size>0||this.#e[2]||void 0===this.#e[1])}};function _(e){const t=e.trim();if(0!==t.length)try{const e=new URL(t);if("http:"!==e.protocol&&"https:"!==e.protocol)return;if(!C.test(e.origin))return;return e.origin}catch{return}}function G(e){const[t,i]=e;return"merge HTTP"===t?`the server answered ${String(i)}`:"merge timeout"===t?`the server did not answer within ${String(i)} ms`:"merge invalid"===t?"the server answered with something other than a document":"merge exception"===t?i instanceof Error?i.message:"the request failed":"the update could not be merged"}var z=class{#t;#i;#n;#r;#o=/* @__PURE__ */new Set;#s;#a;#c=0;#l=[];#d=!1;#u;#h;#f;#p;#v;#g=!1;#y=!1;constructor(e,t){this.#n=new OriginDetector({...void 0!==t.allowedOrigins?{additionalOrigins:t.allowedOrigins}:{},enableReferrerDetection:t.enableReferrerDetection??!1,...void 0!==t.enableLocalhostMatching?{enableLocalhostMatching:t.enableLocalhostMatching}:{}}),this.#t=new D({serverURL:t.serverURL,...void 0!==t.apiRoute?{apiRoute:t.apiRoute}:{},...void 0!==t.depth?{depth:t.depth}:{},...void 0!==t.timeoutMs?{timeoutMs:t.timeoutMs}:{},...void 0!==t.fetchFn?{fetchFn:t.fetchFn}:{},log:(...e)=>{this.#l=e}}),this.#i=new E(e=>this.#n.matches(e),{onUpdate:e=>{this.#m(e)},onDocumentEvent:()=>{},sourcePolicy:t.eventSourcePolicy??"parent-or-opener"}),this.#r=t.target,this.#f=t.document,this.#p=!0===t.requireLocale,this.#v=void 0!==t.timeoutMs,this.#s={data:e,isLoading:!0,status:"idle",error:void 0,revision:0},this.#a=this.#s}subscribe=e=>(this.#o.add(e),this.#d||this.#b(),()=>{this.#o.delete(e),0===this.#o.size&&this.#w()});getSnapshot=()=>this.#a;getServerSnapshot=()=>this.#s;#b(){if("undefined"!=typeof window||void 0!==this.#r){this.#d=!0,this.#i.attach(this.#r??window),E.sendReady(this.#S(),this.#n.enumerate());try{"production"!==process.env.NODE_ENV&&(void 0===this.#f&&j("hook-document","A hook without `document` merges any document; 3.0 requires it (ADR 0007, row 26)."),this.#v||j("hook-deadline","A hook without `timeoutMs` waits for a merge; 3.0 sets a default, `0` keeps none (ADR 0007, row 27)."))}catch{}}}#w(){this.#d&&(this.#d=!1,this.#c+=1,this.#i.detach(),this.#t.destroy())}#S(){const e=this.#r??("undefined"==typeof window?void 0:window);if(void 0===e)return[];const t=[];e.parent!==e&&t.push(e.parent);const i=e.opener;return null!=i&&i!==e&&t.push(i),t}#A(e){return this.#d&&e===this.#c}#R(e,t){const i=this.#f;if(void 0===i)return!0;const{locale:n,globalSlug:r,collectionSlug:o}=e;if(void 0!==i.locale&&n!==i.locale&&(void 0!==n||this.#p))return!1;if("global"in i){if(void 0!==r)return r===i.global;if(void 0!==o)return!1}else{if(void 0!==r)return!1;if(void 0!==o&&o!==i.collection)return!1;const e=void 0===o?void 0:function(e){const t=e.id;return"string"==typeof t&&t.length>0?t:"number"==typeof t&&Number.isFinite(t)?String(t):void 0}(t);if(void 0!==e)return e===String(i.id)}return this.#L(i),!1}#L(e){if(this.#g||!isDevMode())return;this.#g=!0;const t="global"in e?`global "${e.global}"`:`collection "${e.collection}", id "${String(e.id)}"`;console.warn(`[payload-live-preview] This hook previews ${t} and ignored an update that does not say which document it is for: Payload 2 sends no collection or global slug, and a create screen has no id yet.`)}async#m(e){const t=e.data;if(void 0===t)return;if(void 0!==e.fieldSchemaJSON&&!this.#y&&isDevMode()&&(this.#y=!0,console.warn("[payload-live-preview] This admin sends fieldSchemaJSON, which only Payload 2 does. Every 2.x release of this package supports Payload 2; 3.0 supports Payload 3 and 4.")),!this.#R(e,t))return;const i=this.#f;try{"production"!==process.env.NODE_ENV&&void 0!==i?.locale&&void 0===e.locale&&j("hook-locale",`A hook for locale "${i.locale}" merged an update without one; 3.0 skips it, as \`requireLocale: true\` does now (ADR 0007, row 31).`)}catch{}const n=this.#c+=1;void 0!==e.fieldSchemaJSON&&(this.#u=e.fieldSchemaJSON);const r=this.#u;void 0!==e.locale&&(this.#h=e.locale);const o=void 0===r?e.locale:this.#h;if(this.#O({...this.#a,isLoading:!0}),!this.#A(n))return;this.#l=[];const s=await this.#t.merge({data:t,...void 0===r?{}:{schema:r},...void 0!==e.collectionSlug?{collectionSlug:e.collectionSlug}:{},...void 0!==e.globalSlug?{globalSlug:e.globalSlug}:{},...void 0!==o?{locale:o}:{}});this.#A(n)&&"superseded"!==s.status&&("unavailable"!==s.status?this.#O({data:s.doc,isLoading:!1,status:"live",error:void 0,revision:n}):this.#O({...this.#a,isLoading:!1,status:"unavailable",error:new Error(`live preview: ${G(this.#l)}`)}))}#O(e){const t=this.#a;if(t.data!==e.data||t.isLoading!==e.isLoading||t.status!==e.status||t.error!==e.error||t.revision!==e.revision){this.#a=e;for(const e of[...this.#o])e()}}},V="__livePreviewRouteRefresh";function registerRouteRefresh(e){const t="undefined"==typeof window?void 0:window;return void 0===t?()=>{}:(t[V]=e,()=>{t[V]===e&&(t[V]=void 0)})}function J(e){const t=e.current;e.current=[];for(const e of t)e()}function x({refresh:n}){const[r,o]=e(),s=t([]);return i(()=>{r||J(s)}),i(()=>{const e=registerRouteRefresh(()=>new Promise(e=>{s.current.push(e),o(()=>{n()})}));return()=>{e(),J(s)}},[n,o]),null}function Q(e){const i=function(e){const{initialData:i,serverURL:n,apiRoute:r,depth:o,timeoutMs:s,allowedOrigins:a,eventSourcePolicy:c,enableReferrerDetection:l,enableLocalhostMatching:d,document:u,requireLocale:h,fetchFn:f,target:p}=e,v=[n,r??"",String(o??""),String(s??""),(a??[]).join(" "),c??"",String(l??""),String(d??""),void 0===u?"":"global"in u?`global ${u.global} ${u.locale??""}`:`collection ${u.collection} ${String(u.id)} ${u.locale??""}`,String(h??"")].join(" | "),g=t(null);return g.current?.key===v&&g.current.target===p||(g.current={key:v,target:p,session:new z(i,{serverURL:n,...void 0!==r?{apiRoute:r}:{},...void 0!==o?{depth:o}:{},...void 0!==s?{timeoutMs:s}:{},...void 0!==a?{allowedOrigins:a}:{},...void 0!==c?{eventSourcePolicy:c}:{},...void 0!==l?{enableReferrerDetection:l}:{},...void 0!==d?{enableLocalhostMatching:d}:{},...void 0!==u?{document:u}:{},...void 0!==h?{requireLocale:h}:{},...void 0!==f?{fetchFn:f}:{},...void 0!==p?{target:p}:{}})}),g.current.session}(e);return n(i.subscribe,i.getSnapshot,i.getServerSnapshot)}export{x as LivePreviewRouteRefresh,registerRouteRefresh,Q as useLivePreviewDocument};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|