payload-live-preview 2.0.6 → 2.1.1
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 +148 -38
- package/dist/adapters/astro/FragmentBridge.astro +25 -0
- package/dist/adapters/astro/PreviewBoundary.astro +2 -4
- package/dist/adapters/astro/RichText.astro +26 -5
- package/dist/adapters/astro/index.d.ts +41 -9
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.d.ts +3 -3
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.d.ts +17 -12
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +11 -6
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +64 -13
- package/dist/adapters/nuxt/module.js +1 -1
- package/dist/adapters/nuxt/module.js.map +1 -1
- package/dist/adapters/react/index.d.ts +11 -7
- package/dist/adapters/react/index.js +1 -1
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.d.ts +10 -5
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +10 -7
- package/dist/adapters/vue/index.js +1 -1
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/annotate.d.ts +15 -2
- package/dist/annotate.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +367 -266
- package/dist/client.d.ts +367 -266
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codegen-cli.js.map +1 -1
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +7 -1
- package/dist/codegen.d.ts +7 -1
- package/dist/codegen.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +549 -393
- package/dist/core.d.ts +549 -393
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +1 -1
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +2 -2
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/{document-session-BfBfLVpg.d.ts → document-session-DWi9H3Qk.d.ts} +7 -0
- package/dist/{fragment-endpoint-DATKU183.d.ts → fragment-endpoint-B2qcRw5T.d.ts} +22 -7
- package/dist/fragment.cjs +1 -1
- package/dist/fragment.cjs.map +1 -1
- package/dist/fragment.d.cts +37 -16
- package/dist/fragment.d.ts +37 -16
- package/dist/fragment.js +1 -1
- package/dist/fragment.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +607 -405
- package/dist/index.d.ts +607 -405
- 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.d.cts +5 -2
- package/dist/lean.d.ts +5 -2
- package/dist/lean.js +1 -1
- package/dist/lean.js.map +1 -1
- package/dist/lexical.cjs +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.d.cts +32 -11
- package/dist/lexical.d.ts +32 -11
- package/dist/lexical.js +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/{locals-CNUGYbA_.d.ts → locals-B1mF3aTb.d.ts} +1 -1
- package/dist/{middleware-CWObDO37.d.ts → middleware-BGobLN9P.d.ts} +11 -5
- package/dist/migrate.js +1 -1
- package/dist/migrate.js.map +1 -1
- package/dist/{options-uHKrDM2U.d.ts → options-Cm8fC7dj.d.ts} +31 -1
- package/dist/payload.cjs +1 -1
- package/dist/payload.cjs.map +1 -1
- package/dist/payload.d.cts +18 -2
- package/dist/payload.d.ts +18 -2
- package/dist/payload.js +1 -1
- package/dist/payload.js.map +1 -1
- package/dist/plugin.cjs +2 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +30 -0
- package/dist/plugin.d.ts +30 -0
- package/dist/plugin.js +2 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +102 -29
- package/dist/plugins.d.ts +102 -29
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{probe-Bzm4fYFL.d.ts → probe-DGPDsnbj.d.ts} +6 -2
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +51 -7
- package/dist/server.d.ts +51 -7
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs +2 -2
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.d.cts +61 -13
- package/dist/structural.d.ts +61 -13
- package/dist/structural.js +2 -2
- package/dist/structural.js.map +1 -1
- package/package.json +33 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PreviewAdapterOptions, a as PreviewRequestLike } from '../../options-
|
|
1
|
+
import { P as PreviewAdapterOptions, a as PreviewRequestLike } from '../../options-Cm8fC7dj.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The Nuxt module: one line in `nuxt.config.ts` instead of a hand-written
|
|
@@ -8,8 +8,8 @@ import { P as PreviewAdapterOptions, a as PreviewRequestLike } from '../../optio
|
|
|
8
8
|
* export default defineNuxtConfig({
|
|
9
9
|
* modules: ['payload-live-preview/nuxt-module'],
|
|
10
10
|
* livePreview: {
|
|
11
|
-
* // The
|
|
12
|
-
*
|
|
11
|
+
* // The hook travels by reference (ADR 0024); the strict default holds.
|
|
12
|
+
* authorizePreviewModule: './server/utils/live-preview-auth',
|
|
13
13
|
* allowedOrigins: [process.env.PUBLIC_PAYLOAD_ADMIN_ORIGIN!],
|
|
14
14
|
* },
|
|
15
15
|
* });
|
|
@@ -29,20 +29,36 @@ import { P as PreviewAdapterOptions, a as PreviewRequestLike } from '../../optio
|
|
|
29
29
|
* `srcDir`, so a bare specifier would be looked for under `server/`).
|
|
30
30
|
*
|
|
31
31
|
* That the options are serialized is why `authorizePreview` and `shouldInject`
|
|
32
|
-
* are not part of this type: a function does not survive `JSON.stringify`.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* (
|
|
32
|
+
* are not part of this type: a function does not survive `JSON.stringify`.
|
|
33
|
+
* The hook travels by reference instead (ADR 0024): `authorizePreviewModule`
|
|
34
|
+
* names a server module whose default export it is, and the plugin imports
|
|
35
|
+
* it. With a reference the module also registers the server handler, so the
|
|
36
|
+
* decision is made before the app renders and a page can read it on
|
|
37
|
+
* `event.context`. Without it the strict 2.0 default throws when Nitro loads the plugin;
|
|
38
|
+
* `defaults: 'v1'` (or `strict: false`) injects on client-controlled intent
|
|
39
|
+
* alone. A preview that needs `shouldInject` registers
|
|
40
|
+
* `livePreviewNitroPlugin()` by hand, exactly as before (docs/nuxt.md).
|
|
39
41
|
*/
|
|
40
42
|
|
|
41
43
|
/** What the module accepts, from `livePreview` in `nuxt.config.ts` or from `modules: [[..., options]]`. */
|
|
42
|
-
type LivePreviewModuleOptions = Omit<PreviewAdapterOptions<PreviewRequestLike>, 'authorizePreview' | 'shouldInject'
|
|
44
|
+
type LivePreviewModuleOptions = Omit<PreviewAdapterOptions<PreviewRequestLike>, 'authorizePreview' | 'shouldInject'> & {
|
|
45
|
+
/**
|
|
46
|
+
* A server module whose default export is the `authorizePreview` hook, so
|
|
47
|
+
* the strict default holds (ADR 0024). A path beginning with `./` is
|
|
48
|
+
* relative to the project root and an alias such as `~/` is Nuxt's own; the
|
|
49
|
+
* module names the file either one points at, with its extension. A package
|
|
50
|
+
* specifier is passed to Nitro unchanged.
|
|
51
|
+
*/
|
|
52
|
+
readonly authorizePreviewModule?: string;
|
|
53
|
+
};
|
|
43
54
|
/** The Nitro config slice this module writes into. */
|
|
44
55
|
interface NitroConfigLike {
|
|
45
56
|
plugins?: string[];
|
|
57
|
+
/** Server handlers; the module adds its own as middleware when a hook is referenced. */
|
|
58
|
+
handlers?: {
|
|
59
|
+
readonly middleware?: boolean;
|
|
60
|
+
readonly handler: string;
|
|
61
|
+
}[];
|
|
46
62
|
}
|
|
47
63
|
/** The one build template shape this module adds; Nuxt writes it to `buildDir/filename`. */
|
|
48
64
|
interface NuxtTemplateLike {
|
|
@@ -57,23 +73,29 @@ interface NuxtTemplateLike {
|
|
|
57
73
|
*/
|
|
58
74
|
interface NuxtLike {
|
|
59
75
|
readonly options: {
|
|
76
|
+
/** Required when authorizePreviewModule names a server hook. */
|
|
77
|
+
readonly rootDir?: string;
|
|
60
78
|
readonly buildDir: string;
|
|
61
79
|
readonly build: {
|
|
62
80
|
templates: NuxtTemplateLike[];
|
|
63
81
|
};
|
|
82
|
+
/** Nuxt's aliases (`~`, `~~`, `@`, …) to their directories. */
|
|
83
|
+
readonly alias?: Readonly<Record<string, string>>;
|
|
64
84
|
livePreview?: LivePreviewModuleOptions;
|
|
65
85
|
};
|
|
66
86
|
readonly hook: (name: 'nitro:config', handler: (config: NitroConfigLike) => void) => void;
|
|
67
87
|
}
|
|
68
88
|
/** The generated plugin's name in `.nuxt/`, distinctive enough to recognise in a build listing. @internal */
|
|
69
89
|
declare const PLUGIN_FILENAME = "payload-live-preview-nitro-plugin.mjs";
|
|
90
|
+
/** The generated server handler's name, written beside the plugin when a hook is referenced. @internal */
|
|
91
|
+
declare const HANDLER_FILENAME = "payload-live-preview-server-handler.mjs";
|
|
70
92
|
/**
|
|
71
93
|
* The generated plugin: an import of the public adapter entry and a call with
|
|
72
94
|
* the options. Nothing framework-private, so a reader who opens the file in
|
|
73
95
|
* `.nuxt/` sees the hand-written setup they would otherwise have typed.
|
|
74
96
|
* @internal
|
|
75
97
|
*/
|
|
76
|
-
declare function pluginSource(options: LivePreviewModuleOptions): string;
|
|
98
|
+
declare function pluginSource(options: LivePreviewModuleOptions, rootDir?: string, alias?: Readonly<Record<string, string>>): string;
|
|
77
99
|
/**
|
|
78
100
|
* The module itself. Options come from `livePreview` in the Nuxt config, from
|
|
79
101
|
* the module's own inline options, or from both — the inline ones win, because
|
|
@@ -85,6 +107,35 @@ declare namespace livePreviewModule {
|
|
|
85
107
|
name: string;
|
|
86
108
|
configKey: string;
|
|
87
109
|
};
|
|
110
|
+
var getMeta: () => Promise<typeof livePreviewModule.meta>;
|
|
88
111
|
}
|
|
89
112
|
|
|
90
|
-
|
|
113
|
+
/**
|
|
114
|
+
* The app's own `@vitejs/plugin-vue` default export, as far as it is called
|
|
115
|
+
* here: with the hook that names a component's scope id.
|
|
116
|
+
*/
|
|
117
|
+
type VuePluginFactory = (options?: {
|
|
118
|
+
readonly features?: {
|
|
119
|
+
readonly componentIdGenerator?: (filepath: string, source: string, isProduction: boolean | undefined, getHash: (text: string) => string) => string;
|
|
120
|
+
};
|
|
121
|
+
}) => {
|
|
122
|
+
readonly name: string;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* The rollup plugins Nitro needs to render the project's single-file
|
|
126
|
+
* components in a fragment endpoint (ADR 0030), for
|
|
127
|
+
* `nitro.rollupConfig.plugins`: Vue's plugin, hashing a scope id from the path
|
|
128
|
+
* under `srcDir` as Nuxt's own build does, and an empty module for every style
|
|
129
|
+
* request, which the page's build delivers instead (ADR 0029).
|
|
130
|
+
*
|
|
131
|
+
* Without the second, rollup fails on a component's `<style>`. Without the
|
|
132
|
+
* first, Nuxt 4's `app/` layout gives the fragment other scope ids than the
|
|
133
|
+
* page, and no scoped rule reaches what it renders.
|
|
134
|
+
*/
|
|
135
|
+
declare function fragmentComponentPlugins(vue: VuePluginFactory, options: {
|
|
136
|
+
readonly srcDir: string;
|
|
137
|
+
}): {
|
|
138
|
+
readonly name: string;
|
|
139
|
+
}[];
|
|
140
|
+
|
|
141
|
+
export { HANDLER_FILENAME, type LivePreviewModuleOptions, type NitroConfigLike, type NuxtLike, type NuxtTemplateLike, PLUGIN_FILENAME, type VuePluginFactory, livePreviewModule as default, fragmentComponentPlugins, pluginSource };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{join as i}from"path";var e="payload-live-preview-nitro-plugin.mjs";function o(i){return["import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';","",`export default livePreviewNitroPlugin(${
|
|
1
|
+
import{statSync as e}from"fs";import{join as t,relative as r,resolve as o,isAbsolute as i}from"path";var n="authorizePreviewModule";function s(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 a(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 ${a(e)};`,`if (typeof authorizePreview !== "function") throw new Error(${a(t)});`]}var l="payload-live-preview-nitro-plugin.mjs",p="payload-live-preview-server-handler.mjs",v=[".ts",".mts",".js",".mjs",".cts",".cjs"];function d(e){if("string"!=typeof e||!i(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 c(e,r,o){const i=function(e,r,o){if(e.startsWith("./"))return t(r,e);const i=Object.keys(o).sort((e,t)=>t.length-e.length).find(t=>e===t||e.startsWith(`${t}/`));return void 0===i?void 0:t(o[i]??"",e.slice(i.length))}(e,r,o);return void 0===i?e:function(e){if(f(e))return e;for(const t of v)if(f(e+t))return e+t;for(const r of v){const o=t(e,`index${r}`);if(f(o))return o}}(i)??(e.startsWith("./")?i:e)}function h(e,t,r){const{authorizePreviewModule:o,...i}=e,n=JSON.stringify(i);return void 0===o?{hook:[],argument:n}:(s(o),{hook:u(c(o,d(t),r)),argument:`{ ...${n}, authorizePreview }`})}function m(e,t,r={}){const{hook:o,argument:i}=h(e,t,r);return["import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';",...o,"",`export default livePreviewNitroPlugin(${i});`,""].join("\n")}function w(e,r){const o={...r.options.livePreview??{},...e??{}};void 0!==o.authorizePreviewModule&&(s(o.authorizePreviewModule),d(r.options.rootDir)),r.options.build.templates.push({filename:l,write:!0,getContents:()=>m(o,r.options.rootDir,r.options.alias)});const i=t(r.options.buildDir,l),n=void 0!==o.authorizePreviewModule;n&&r.options.build.templates.push({filename:p,write:!0,getContents:()=>function(e,t,r){const{hook:o,argument:i}=h(e,t,r);return["import { defineEventHandler } from 'h3';","import { defineLivePreviewServerHandler } from 'payload-live-preview/nuxt';",...o,"",`export default defineEventHandler(defineLivePreviewServerHandler(${i}));`,""].join("\n")}(o,r.options.rootDir,r.options.alias??{})});const a=t(r.options.buildDir,p);r.hook("nitro:config",e=>{const t=e.plugins??=[];if(t.includes(i)||t.push(i),!n)return;const r=e.handlers??=[];r.some(e=>e.handler===a)||r.push({middleware:!0,handler:a})})}w.meta={name:"payload-live-preview",configKey:"livePreview"},w.getMeta=()=>Promise.resolve(w.meta);var g="\0payload-live-preview:server-style";function y(e,t){const i=process.cwd();return[{name:"payload-live-preview:server-styles",resolveId:e=>/[?&]type=style\b/u.test(e)?g:null,load:e=>e===g?'export default ""':null},e({features:{componentIdGenerator:(e,n,s,a)=>a(r(t.srcDir,o(i,e)).replaceAll("\\","/")+(!0===s?n:""))}})]}export{p as HANDLER_FILENAME,l as PLUGIN_FILENAME,w as default,y as fragmentComponentPlugins,m as pluginSource};
|
|
2
2
|
//# sourceMappingURL=module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","names":["PLUGIN_FILENAME","pluginSource","options","JSON","stringify","join","livePreviewModule","inlineOptions","nuxt","livePreview","build","templates","push","filename","write","getContents","plugin","buildDir","hook","config","plugins","includes","meta","name","configKey"],"sources":["../../../src/adapters/nuxt/module.ts"],"sourcesContent":["/**\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 module cannot carry authorizePreview (below), so it runs on the 1.x profile.\n * defaults: 'v1',\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`. It\n * is also why the example sets `defaults: 'v1'`: the generated plugin builds\n * its policy when Nitro loads it, and the strict 2.0 default throws there\n * without `authorizePreview`. Under `'v1'` (or `strict: false`) the plugin\n * injects on client-controlled intent alone. A preview that needs either\n * function registers `livePreviewNitroPlugin()` by hand, exactly as before\n * (docs/nuxt.md).\n */\n\nimport { join } from 'node:path';\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/** The Nitro config slice this module writes into. */\nexport interface NitroConfigLike {\n plugins?: 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 readonly buildDir: string;\n readonly build: { templates: NuxtTemplateLike[] };\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\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(options: LivePreviewModuleOptions): string {\n return [\n \"import { livePreviewNitroPlugin } from 'payload-live-preview/nuxt';\",\n '',\n `export default livePreviewNitroPlugin(${JSON.stringify(options)});`,\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 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),\n });\n const plugin = join(nuxt.options.buildDir, PLUGIN_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 });\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"],"mappings":"4BA2EO,IAAMA,EAAkB,wCAQxB,SAASC,EAAaC,GAC3B,MAAO,CACL,sEACA,GACA,yCAAyCC,KAAKC,UAAUF,OACxD,IACAG,KAAK,KACT,CAOe,SAARC,EACLC,EACAC,GAEA,MAAMN,EAAoC,IACpCM,EAAKN,QAAQO,aAAe,MAC5BF,GAAiB,IAEvBC,EAAKN,QAAQQ,MAAMC,UAAUC,KAAK,CAChCC,SAAUb,EAEVc,OAAO,EACPC,YAAa,IAAMd,EAAaC,KAElC,MAAMc,EAASX,EAAKG,EAAKN,QAAQe,SAAUjB,GAC3CQ,EAAKU,KAAK,eAAiBC,IACzB,MAAMC,EAAWD,EAAOC,UAAY,GAG/BA,EAAQC,SAASL,IAASI,EAAQR,KAAKI,IAEhD,CAGAV,EAAkBgB,KAAO,CACvBC,KAAM,uBACNC,UAAW,sB","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","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":"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,CC4DO,IAAMC,EAAkB,wCAElBC,EAAmB,0CAE1BC,EAAa,CAAC,MAAO,OAAQ,MAAO,OAAQ,OAAQ,QAG1D,SAASC,EAAmBC,GAC1B,GAAuB,iBAAZA,IAAyBC,EAAWD,GAC7C,MAAM,IAAIb,MACR,yJAIJ,OAAOa,CACT,CAEA,SAASE,EAAOC,GACd,IACE,OAAOC,EAASD,GAAMD,QACxB,OACE,OAAO,CACT,CACF,CAkCA,SAASG,EACPpB,EACAe,EACAM,GAEA,MAAMH,EAzBR,SACElB,EACAe,EACAM,GAGA,GAAIrB,EAAUC,WAAW,MAAO,OAAOqB,EAAKP,EAASf,GACrD,MACMuB,EADUC,OAAOC,KAAKJ,GAAOK,KAAK,CAACC,EAAMC,IAAUA,EAAMC,OAASF,EAAKE,QACzDC,KAAMC,GAAS/B,IAAc+B,GAAQ/B,EAAUC,WAAW,GAAG8B,OACjF,YAAe,IAARR,OAAoB,EAAYD,EAAKD,EAAME,IAAQ,GAAIvB,EAAUgC,MAAMT,EAAIM,QACpF,CAeeI,CAAYjC,EAAWe,EAASM,GAC7C,YAAa,IAATH,EAA2BlB,EArCjC,SAAkBkB,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,KAAUlB,EAAUC,WAAW,MAAQiB,EAAOlB,EAChE,CAMA,SAASqC,EACPC,EACAvB,EACAM,GAEA,MAAQkB,uBAAwBvC,KAAcwC,GAAiBF,EACzDG,EAAOpC,KAAKC,UAAUkC,GAC5B,YAAkB,IAAdxC,EAAgC,CAAE0C,KAAM,GAAIC,SAAUF,IAC1D1C,EAAuBC,GAChB,CACL0C,KAAMlC,EAAgBY,EAAiBpB,EAAWc,EAAmBC,GAAUM,IAC/EsB,SAAU,QAAQF,yBAEtB,CAQO,SAASG,EACdN,EACAvB,EACAM,EAA0C,IAE1C,MAAMqB,KAAEA,EAAAC,SAAMA,GAAaN,EAAeC,EAASvB,EAASM,GAC5D,MAAO,CACL,yEACGqB,EACH,GACA,yCAAyCC,MACzC,IACArB,KAAK,KACT,CA4Be,SAARuB,EACLC,EACAC,GAEA,MAAMT,EAAoC,IACpCS,EAAKT,QAAQU,aAAe,MAC5BF,GAAiB,SAGgB,IAAnCR,EAAQC,yBACVxC,EAAuBuC,EAAQC,wBAC/BzB,EAAmBiC,EAAKT,QAAQvB,UAElCgC,EAAKT,QAAQW,MAAMC,UAAUC,KAAK,CAChCC,SAAUzC,EAEV0C,OAAO,EACPC,YAAa,IAAMV,EAAaN,EAASS,EAAKT,QAAQvB,QAASgC,EAAKT,QAAQjB,SAE9E,MAAMkC,EAASjC,EAAKyB,EAAKT,QAAQkB,SAAU7C,GAGrC8C,OAA6C,IAAnCnB,EAAQC,uBACpBkB,GACFV,EAAKT,QAAQW,MAAMC,UAAUC,KAAK,CAChCC,SAAUxC,EACVyC,OAAO,EACPC,YAAa,IAhDnB,SACEhB,EACAvB,EACAM,GAEA,MAAMqB,KAAEA,EAAAC,SAAMA,GAAaN,EAAeC,EAASvB,EAASM,GAC5D,MAAO,CACL,2CACA,iFACGqB,EACH,GACA,oEAAoEC,OACpE,IACArB,KAAK,KACT,CAkCyBoC,CAAcpB,EAASS,EAAKT,QAAQvB,QAASgC,EAAKT,QAAQjB,OAAS,MAG1F,MAAMsC,EAAUrC,EAAKyB,EAAKT,QAAQkB,SAAU5C,GAC5CmC,EAAKL,KAAK,eAAiBkB,IACzB,MAAMC,EAAWD,EAAOC,UAAY,GAIpC,GADKA,EAAQC,SAASP,IAASM,EAAQV,KAAKI,IACvCE,EAAS,OACd,MAAMM,EAAYH,EAAOG,WAAa,GACjCA,EAASC,KAAMC,GAAUA,EAAMN,UAAYA,IAC9CI,EAASZ,KAAK,CAAEe,YAAY,EAAMP,aAGxC,CAGAd,EAAkBsB,KAAO,CACvBpC,KAAM,uBACNqC,UAAW,eASbvB,EAAkBwB,QAAU,IAC1BC,QAAQC,QAAQ1B,EAAkBsB,MAiBpC,IAAMK,EAAc,sCAab,SAASC,EACdC,EACApC,GAGA,MAAMqC,EAAOC,QAAQC,MAerB,MAAO,CALQ,CACb9C,KAAM,qCACN+C,UAAYC,GAA+B,oBAAoBC,KAAKD,GAAMP,EAAc,KACxFS,KAAOF,GAA+BA,IAAOP,EAAc,oBAAsB,MAEnEE,EAAI,CAAEQ,SAAU,CAAEC,qBAdL,CAC3BC,EACAC,EACAC,EACAC,IAGOA,EADaC,EAASlD,EAAQmD,OAAQlB,EAAQI,EAAMS,IAAWM,WAAW,KAAM,OACxC,IAAjBJ,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-DWi9H3Qk.js';
|
|
2
|
+
export { b as DocumentStatus } from '../../document-session-DWi9H3Qk.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `<LivePreviewRouteRefresh />` — lends the runtime the host router's own
|
|
@@ -57,6 +57,9 @@ declare function LivePreviewRouteRefresh({ refresh }: LivePreviewRouteRefreshPro
|
|
|
57
57
|
* A host's own route refresh. It must settle once the fresh markup is
|
|
58
58
|
* committed: the runtime re-applies the revision on top of it, and doing that
|
|
59
59
|
* against the markup being replaced would write into nodes about to be dropped.
|
|
60
|
+
* A function that returns nothing is taken as already committed; the route
|
|
61
|
+
* strategy says once that it could not wait (LP0810), and 3.0 requires the
|
|
62
|
+
* promise (ADR 0028).
|
|
60
63
|
*/
|
|
61
64
|
type RouteRefresh = () => void | Promise<void>;
|
|
62
65
|
/**
|
|
@@ -74,9 +77,10 @@ declare function registerRouteRefresh(refresh: RouteRefresh): () => void;
|
|
|
74
77
|
* that belongs to this hook alone (ADR 0002).
|
|
75
78
|
*
|
|
76
79
|
* It re-renders your component tree, so conditional sections and derived values
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
+
* follow the merged document. React preserves component and DOM state while
|
|
81
|
+
* type, key and position stay stable; a remount or replaced node loses the
|
|
82
|
+
* state it held. The DOM runtime uses direct writes and a keyed morph instead
|
|
83
|
+
* (docs/react.md).
|
|
80
84
|
*
|
|
81
85
|
* `react` is an optional peer. This entry imports it at module scope; `./nextjs`
|
|
82
86
|
* loads it, and `react-dom/server`, only at the first render that needs them.
|
|
@@ -88,7 +92,7 @@ declare function registerRouteRefresh(refresh: RouteRefresh): () => void;
|
|
|
88
92
|
*/
|
|
89
93
|
|
|
90
94
|
interface UseLivePreviewDocumentOptions<T> extends DocumentSessionOptions {
|
|
91
|
-
/** The document
|
|
95
|
+
/** The document this session starts from; create a new hook instance to switch documents. */
|
|
92
96
|
readonly initialData: T;
|
|
93
97
|
}
|
|
94
98
|
/**
|
|
@@ -97,7 +101,7 @@ interface UseLivePreviewDocumentOptions<T> extends DocumentSessionOptions {
|
|
|
97
101
|
* ```tsx
|
|
98
102
|
* const { data, status } = useLivePreviewDocument<Page>({
|
|
99
103
|
* serverURL: process.env.NEXT_PUBLIC_PAYLOAD_URL!,
|
|
100
|
-
* allowedOrigins: [process.env.
|
|
104
|
+
* allowedOrigins: [process.env.NEXT_PUBLIC_PAYLOAD_ADMIN_ORIGIN!],
|
|
101
105
|
* initialData: page,
|
|
102
106
|
* depth: 1,
|
|
103
107
|
* });
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{useTransition as t,useRef as e,useEffect as i,useSyncExternalStore as n}from"react";function r(t){return("object"==typeof t&&null!==t||"function"==typeof t)&&"function"==typeof t.then&&(Promise.resolve(t).catch(()=>{}),!0)}function s(){}function o(t,e){return t.length>0&&t.length<=e&&"."!==t&&".."!==t&&!t.includes("/")&&!t.includes("\\")&&!function(t){for(const e of t){const t=e.codePointAt(0)??0;if(t<=31||127===t)return!0}return!1}(t)}function a(t){return o(t,128)&&!t.includes("?")&&!t.includes("#")}var h=class{serverURL;apiRoute;depth;fetchFn;log;inflight=null;attempt=0;destroyDepth=0;constructor(t){this.serverURL=function(t){let e=t.length;for(;t.endsWith("/",e);)e-=1;return t.slice(0,e)}(t.serverURL);const e=t.apiRoute??"/api";var i;this.apiRoute=e.startsWith("/")?e:`/${e}`,this.depth=t.depth??1,this.fetchFn=t.fetchFn,this.log=(i=t.log??s,(...t)=>{try{r(i(...t))}catch{}})}canMerge(t){return null!==this.endpointOf(t)}endpointOf(t){try{const i=t.globalSlug;if(i)return a(i)?`globals/${encodeURIComponent(i)}`:null;const n=t.collectionSlug??"",r=t.data.id;return a(n)&&("number"==typeof(e=r)?Number.isFinite(e):"string"==typeof e&&o(e,512))?`${encodeURIComponent(n)}/${encodeURIComponent(String(r))}`:null}catch{return null}var e}async merge(t){if(this.destroyDepth>0)return{status:"superseded"};const e=this.attempt+=1,i=this.inflight;this.inflight=null;let n=null;const r=()=>this.attempt!==e;try{if(i?.abort(),r())return{status:"superseded"};const e=this.endpointOf(t);if(null===e)return r()?{status:"superseded"}:{status:"unavailable"};const s=this.fetchFn??("function"==typeof fetch?fetch:void 0);if(void 0===s)return{status:"unavailable"};n=new AbortController,this.inflight=n;const o=`${this.serverURL}${this.apiRoute}/${e}`,a=await s(o,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json","X-Payload-HTTP-Method-Override":"GET"},body:JSON.stringify({data:t.data,depth:this.depth,flattenLocales:!1,locale:t.locale}),signal:n.signal});if(r())return{status:"superseded"};if(!a.ok)return this.log("merge HTTP",a.status,o),{status:"unavailable"};const h=await a.json();return r()?{status:"superseded"}:null===h||"object"!=typeof h||Array.isArray(h)?(this.log("merge invalid",o),{status:"unavailable"}):{status:"merged",doc:h}}catch(t){return r()?{status:"superseded"}:(this.log("merge exception",t),{status:"unavailable"})}finally{this.inflight===n&&(this.inflight=null)}}destroy(){this.attempt+=1;const t=this.inflight;this.inflight=null,this.destroyDepth+=1;try{t?.abort()}finally{this.destroyDepth-=1}}};function d(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){const t=c(i);t&&e.push(t)}return e}function c(t){if("object"!=typeof t||null===t)return;const e=t,i=e.name,n=e.type;if("string"!=typeof i||0===i.length)return;if("string"!=typeof n||0===n.length)return;const r=d(e.fields),s=function(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if("object"!=typeof i||null===i)continue;const t=i,n=t.slug;if("string"!=typeof n||0===n.length)continue;const r=d(t.fields);e.push({...t,slug:n,fields:r})}return e}(e.blocks),o={...e,name:i,type:n};return r.length>0?o.fields=r:delete o.fields,s.length>0?o.blocks=s:delete o.blocks,o}function u(t,e){return void 0===t||e(t)}function l(t,e){return null==t||e(t)}function f(t){if("object"!=typeof t||null===t)return!1;const e=Object.getPrototypeOf(t);return null===e||null===Object.getPrototypeOf(e)}var g=["data","fieldSchemaJSON","globalSlug","collectionSlug","locale","ready","previewToken","protocolVersion"],v=class{matcher;handlers;boundListener=void 0;attachedTarget=void 0;generation=0;revision=0;queueHead=void 0;queueTail=void 0;constructor(t,e){this.matcher=t,this.handlers=e}attach(t=window){if(void 0!==this.attachedTarget)return;let e=!1;const i=n=>{if(!e||this.boundListener!==i)return;const r=this.generation;try{this.receive(n,r,t)}catch{let t;try{t=n.origin}catch{t=""}this.reportInvalid("shape",t,r)}};this.generation+=1,this.resetQueue(),this.attachedTarget=t,this.boundListener=i;try{t.addEventListener("message",i)}catch(e){this.boundListener===i&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue());try{t.removeEventListener("message",i)}catch{}throw e}if(this.boundListener===i)e=!0;else try{t.removeEventListener("message",i)}catch{}}detach(){const t=this.attachedTarget,e=this.boundListener;void 0!==t&&void 0!==e&&(this.attachedTarget=void 0,this.boundListener=void 0,this.resetQueue(),t.removeEventListener("message",e))}advanceGeneration(){return void 0!==this.attachedTarget&&(this.generation+=1,this.resetQueue(),!0)}static sendReady(t,e){const i={type:"payload-live-preview",ready:!0,protocolVersion:4};for(const n of t)for(const t of e)try{n.postMessage(i,t)}catch{}}receive(t,e,i){const n=t.origin;if(!this.matchesOrigin(n,e))return void this.reportInvalid("origin",n,e);if(!this.matchesSource(t,i))return void this.reportInvalid("source",n,e);const r=t.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(t){const e=t;return!(void 0!==e.data&&null!==e.data&&!f(e.data))&&l(e.fieldSchemaJSON,t=>Array.isArray(t))&&l(e.globalSlug,t=>"string"==typeof t)&&l(e.collectionSlug,t=>"string"==typeof t)&&l(e.locale,t=>"string"==typeof t)&&l(e.ready,t=>"boolean"==typeof t)&&l(e.previewToken,t=>"string"==typeof t)&&l(e.protocolVersion,t=>"number"==typeof t)}(r)?void this.dispatchUpdate(function(t){const e={...t};for(const t of g)null===Reflect.get(e,t)&&Reflect.deleteProperty(e,t);if(!Array.isArray(e.fieldSchemaJSON))return e;let i;try{i=d(e.fieldSchemaJSON)}catch{i=[]}return{...e,fieldSchemaJSON:i}}(r),n,e):void this.reportInvalid("shape",n,e);case"payload-document-event":return function(t){const e=t;return u(e.action,t=>"updated"===t||"created"===t||"deleted"===t)&&u(e.slug,t=>"string"==typeof t)&&u(e.id,t=>"string"==typeof t||Number.isFinite(t))}(r)?void this.invokeHandler(e,this.handlers.onDocumentEvent,r,n):void this.reportInvalid("shape",n,e);case"payload-live-preview-focus":{const t=function(t){const e=t.field;return"string"==typeof e&&e.length>0?e:void 0}(r);return void 0===t?void this.reportInvalid("shape",n,e):void this.invokeHandler(e,this.handlers.onFocusField,t,n)}default:this.reportInvalid("type",n,e)}else this.reportInvalid("shape",n,e)}dispatchUpdate(t,e,i){const n=f(t.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(t,e,i,r);if(!0===t.ready&&void 0===t.data)return void this.commitUpdate(t,e,i,void 0);const o={generation:i,message:t,origin:e,messageRevision:r,verdict:void 0,next:void 0};let a;this.enqueue(o);try{a=s(t.previewToken,e)}catch{return void this.settleValidation(o,!1)}"boolean"!=typeof a?Promise.resolve(a).then(t=>{this.settleValidation(o,!0===t)},()=>{this.settleValidation(o,!1)}):this.settleValidation(o,a)}settleValidation(t,e){t.verdict=e,this.drainQueue(t.generation)}drainQueue(t){for(;this.isCurrentGeneration(t);){const e=this.queueHead;if(void 0===e)return;if(this.matchesOrigin(e.origin,t)){if(void 0===e.verdict)return;this.dequeue(e)&&(e.verdict?this.commitUpdate(e.message,e.origin,e.generation,e.messageRevision):this.reportInvalid("token",e.origin,e.generation))}else{if(!this.dequeue(e))continue;this.reportInvalid("origin",e.origin,e.generation)}}}commitUpdate(t,e,i,n){void 0===n?this.invokeHandler(i,this.handlers.onUpdate,t,e):this.invokeHandler(i,this.handlers.onUpdate,t,e,n)}reportInvalid(t,e,i){this.invokeHandler(i,this.handlers.onInvalid,t,e)}matchesSource(t,e){if("parent-or-opener"!==this.handlers.sourcePolicy)return!0;try{const i=t.source;if("object"!=typeof i||null===i)return!1;const n=e.parent;return n!==e&&i===n||i===e.opener}catch{return!1}}matchesOrigin(t,e){try{return!0===(this.isCurrentGeneration(e)&&this.matcher(t))&&this.isCurrentGeneration(e)}catch{return!1}}invokeHandler(t,e,...i){if(void 0!==e&&this.isCurrentGeneration(t))try{r(e(...i))}catch{}}isCurrentGeneration(t){return void 0!==this.attachedTarget&&this.generation===t}enqueue(t){void 0===this.queueTail?this.queueHead=t:this.queueTail.next=t,this.queueTail=t}dequeue(t){return this.queueHead===t&&(this.queueHead=t.next,void 0===this.queueHead&&(this.queueTail=void 0),!0)}resetQueue(){this.queueHead=void 0,this.queueTail=void 0}};var p=/^https?:\/\/(localhost|127\.0\.0\.1)(?::\d+)?$/i,y=/^https?:\/\/[^/?#\s]+$/i,m=[3e3,3001,3333,4e3,4321,5e3,5173,5174,8e3,8080,8888,9e3],OriginDetector=class{#t;constructor(t={}){const e=/* @__PURE__ */new Set;for(const i of t.additionalOrigins??[]){const t=b(i);void 0!==t&&e.add(t)}let i;if(t.enableReferrerDetection??1){const e=t.referrer??("undefined"!=typeof document?document.referrer:"");if(e.length>0)try{const t=new URL(e).origin;t&&"null"!==t&&(i=t)}catch{}}const n=(t.enableLocalhostMatching??!0)&&(t.forceDevMode??function isDevMode(){const t=function(){if("undefined"==typeof process)return;const t=process.env.NODE_ENV;return"string"==typeof t?t:void 0}();if(void 0!==t)return"production"!==t;if("undefined"!=typeof window){const t=window.location.hostname;return"localhost"===t||"127.0.0.1"===t}return!1}());this.#t=[e,i,n,void 0!==i,void 0]}matches(t){return 0!==t.length&&"null"!==t&&(void 0!==this.#t[4]?t===this.#t[4]:!!this.#t[0].has(t)||0===this.#t[0].size&&void 0!==this.#t[1]&&t===this.#t[1]||!(!this.#t[2]||!p.test(t)))}lockOrigin(t){return!!this.matches(t)&&(this.#t[4]=t,!0)}unlockOrigin(){const t=this.#t[4];return this.#t[4]=void 0,t}get lockedOrigin(){return this.#t[4]}enumerate(){if(void 0!==this.#t[4])return[this.#t[4]];const t=new Set(this.#t[0]);if(0===this.#t[0].size&&void 0!==this.#t[1]&&t.add(this.#t[1]),this.#t[2])for(const e of m)t.add(`http://localhost:${String(e)}`),t.add(`http://127.0.0.1:${String(e)}`);return[...t]}get referrerWasAvailable(){return this.#t[3]}get isProductionUnconfigured(){return!(!function isInIframe(){if("undefined"==typeof window)return!1;try{return window.self!==window.top}catch{return!0}}()||this.#t[0].size>0||this.#t[2]||void 0!==this.#t[1])}get isReferrerOnlyTrust(){return!(this.#t[0].size>0||this.#t[2]||void 0===this.#t[1])}};function b(t){const e=t.trim();if(0!==e.length)try{const t=new URL(e);if("http:"!==t.protocol&&"https:"!==t.protocol)return;if(!y.test(t.origin))return;return t.origin}catch{return}}function w(t){const[e,i]=t;return"merge HTTP"===e?`the server answered ${String(i)}`:"merge invalid"===e?"the server answered with something other than a document":"merge exception"===e?i instanceof Error?i.message:"the request failed":"the update could not be merged"}var S=class{#e;#i;#n;#r;#s=/* @__PURE__ */new Set;#o;#a;#h=0;#d=[];#c=!1;constructor(t,e){this.#n=new OriginDetector({...void 0!==e.allowedOrigins?{additionalOrigins:e.allowedOrigins}:{},enableReferrerDetection:e.enableReferrerDetection??!1,...void 0!==e.enableLocalhostMatching?{enableLocalhostMatching:e.enableLocalhostMatching}:{}}),this.#e=new h({serverURL:e.serverURL,...void 0!==e.apiRoute?{apiRoute:e.apiRoute}:{},...void 0!==e.depth?{depth:e.depth}:{},...void 0!==e.fetchFn?{fetchFn:e.fetchFn}:{},log:(...t)=>{this.#d=t}}),this.#i=new v(t=>this.#n.matches(t),{onUpdate:t=>{this.#u(t)},onDocumentEvent:()=>{},sourcePolicy:e.eventSourcePolicy??"parent-or-opener"}),this.#r=e.target,this.#o={data:t,isLoading:!0,status:"idle",error:void 0},this.#a=this.#o}subscribe=t=>(this.#s.add(t),this.#c||this.#l(),()=>{this.#s.delete(t),0===this.#s.size&&this.#f()});getSnapshot=()=>this.#a;getServerSnapshot=()=>this.#o;#l(){"undefined"==typeof window&&void 0===this.#r||(this.#c=!0,this.#i.attach(this.#r??window),v.sendReady(this.#g(),this.#n.enumerate()))}#f(){this.#c&&(this.#c=!1,this.#i.detach(),this.#e.destroy())}#g(){const t=this.#r??("undefined"==typeof window?void 0:window);if(void 0===t)return[];const e=[];t.parent!==t&&e.push(t.parent);const i=t.opener;return null!=i&&i!==t&&e.push(i),e}async#u(t){const e=t.data;if(void 0===e)return;const i=this.#h+=1;this.#v({...this.#a,isLoading:!0}),this.#d=[];const n=await this.#e.merge({data:e,...void 0!==t.collectionSlug?{collectionSlug:t.collectionSlug}:{},...void 0!==t.globalSlug?{globalSlug:t.globalSlug}:{},...void 0!==t.locale?{locale:t.locale}:{}});i===this.#h&&"superseded"!==n.status&&("unavailable"!==n.status?this.#v({data:n.doc,isLoading:!1,status:"live",error:void 0}):this.#v({...this.#a,isLoading:!1,status:"unavailable",error:new Error(`live preview: ${w(this.#d)}`)}))}#v(t){const e=this.#a;if(e.data!==t.data||e.isLoading!==t.isLoading||e.status!==t.status||e.error!==t.error){this.#a=t;for(const t of[...this.#s])t()}}},R="__livePreviewRouteRefresh";function registerRouteRefresh(t){const e="undefined"==typeof window?void 0:window;return void 0===e?()=>{}:(e[R]=t,()=>{e[R]===t&&(e[R]=void 0)})}function L(t){const e=t.current;t.current=[];for(const t of e)t()}function T({refresh:n}){const[r,s]=t(),o=e([]);return i(()=>{r||L(o)}),i(()=>{const t=registerRouteRefresh(()=>new Promise(t=>{o.current.push(t),s(()=>{n()})}));return()=>{t(),L(o)}},[n,s]),null}function O(t){const i=function(t){const{initialData:i,serverURL:n,apiRoute:r,depth:s,allowedOrigins:o,eventSourcePolicy:a,enableReferrerDetection:h,enableLocalhostMatching:d,fetchFn:c,target:u}=t,l=[n,r??"",String(s??""),(o??[]).join(" "),a??"",String(h??""),String(d??"")].join(" | "),f=e(null);return f.current?.key!==l&&(f.current={key:l,session:new S(i,{serverURL:n,...void 0!==r?{apiRoute:r}:{},...void 0!==s?{depth:s}:{},...void 0!==o?{allowedOrigins:o}:{},...void 0!==a?{eventSourcePolicy:a}:{},...void 0!==h?{enableReferrerDetection:h}:{},...void 0!==d?{enableLocalhostMatching:d}:{},...void 0!==c?{fetchFn:c}:{},...void 0!==u?{target:u}:{}})}),f.current.session}(t);return n(i.subscribe,i.getSnapshot,i.getServerSnapshot)}export{T as LivePreviewRouteRefresh,registerRouteRefresh,O 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 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=u(r,t,i);e&&n.push(e)}return t.active.delete(e),n}function u(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),u=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),d={...n,name:r,type:s},h=n.relationTo;if(Array.isArray(h)){const e=[];for(const i of h)o(t),e.push(i);d.relationTo=e}return c.length>0?d.fields=c:delete d.fields,u.length>0?d.blocks=u:delete d.blocks,d}function d(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"],g=1e4,v=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 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,s){if(++i>g||s>64)return m();if("string"==typeof r)return n+=r.length,n>v&&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>g&&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))L(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 u=/* @__PURE__ */new WeakSet,d=e=>{(++l>g||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 L(e,t,s);const l=JSON.stringify([i,o]);c.add(l),c.size>1e3&&m();const u=a.get(i)??[];u.push({owner:e,key:t,id:o}),a.set(i,u)}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)d(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 v(e,t){if(d(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))v(Reflect.get(e,i),t+1)}}!function e(t,i,n){d(n),u.has(t)&&m(),u.add(t);for(const r of t){d(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?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=A(i,"blockType"),s=r.blocks?.find(e=>(d(n),e.slug===t));void 0===s&&m(),e(s.fields,i,n+1)}}else"richText"===r.type&&v(t,n+1)}u.delete(t)}(t,o,0),a.size>25&&m();const k=[];if(0===a.size)return{doc:o,requests:k};const U=new URL(i);(!["http:","https:"].includes(U.protocol)||U.username||U.password||U.search||U.hash)&&m(),(!n.startsWith("/")||n.includes("\\")||/[%?#]/u.test(n)||b(n))&&m(),n.split("/").some(e=>"."===e||".."===e)&&m();const P=`${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 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],u=new URLSearchParams({depth:String(r),limit:String(o.length)});void 0!==s&&u.set("locale",s),u.set(a?"where[id][equals]":"where[id][in]",a?t:o.join(","));const d=`${P}${encodeURIComponent(e)}?${u}`;if(d.length>8192){0===c.length&&m();break}new URL(d).origin!==U.origin&&m(),c.push(t),n+=1,l=d}(0===c.length||k.length>=64)&&m();const u=new Set(c);k.push({url:l,ids:u,slots:t.filter(e=>u.has(e.id))})}}return{doc:o,requests:k}}async function U(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()},u=()=>{if(void 0!==n&&!r){r=!0;try{Promise.resolve(n.cancel()).catch(()=>{})}catch{}}},d=()=>{a?.(),u()};t.addEventListener("abort",d,{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 u=0,d=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;u+=t.value.byteLength,(++d>1e4||u>v)&&m(),a.push(t.value)}s=!0;const h=new Uint8Array(u);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",d),s||u();try{n?.releaseLock()}catch{}}}function P(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)L(t.owner,t.key,r.get(t.id))}function j(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 q(e){return j(e,128)&&!e.includes("?")&&!e.includes("#")}function C(e){return"number"==typeof e?Number.isFinite(e):"string"==typeof e&&j(e,512)}var I=class{serverURL;apiRoute;depth;fetchFn;log;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{}})}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 q(t)?{path:`globals/${encodeURIComponent(t)}`,field:"globalType",value:t}:null;const i=e.collectionSlug??"",n=e.data.id;return q(i)&&C(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;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 r(e.url,{method:"GET",credentials:"include",redirect:"error",signal:n.signal});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 U(t,n.signal,()=>!s());if(s())return{status:"superseded"};if(P(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 a(l,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json","X-Payload-HTTP-Method-Override":"GET"},body:c,signal:n.signal});if(s())return{status:"superseded"};const d=u.ok;if(s())return{status:"superseded"};if(!d){const e=u.status;return s()?{status:"superseded"}:(this.log("merge HTTP",e,l),s()?{status:"superseded"}:{status:"unavailable"})}const h=u.json.bind(u);if(s())return{status:"superseded"};const f=await h();if(s())return{status:"superseded"};if(null===f||"object"!=typeof f||Array.isArray(f))return this.log("merge invalid",l),s()?{status:"superseded"}:{status:"unavailable"};const p=f,g=p[o.field],v=Object.hasOwn(p,o.field)&&("id"===o.field?!C(g)||String(g)!==o.value:g!==o.value);return s()?{status:"superseded"}:v?(this.log("merge invalid",l),s()?{status:"superseded"}:{status:"unavailable"}):{status:"merged",doc:p}}catch(e){return s()||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{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 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 d(t.action,e=>"updated"===e||"created"===e||"deleted"===e)&&d(t.slug,e=>"string"==typeof e)&&d(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}};var H=/^https?:\/\/(localhost|127\.0\.0\.1)(?::\d+)?$/i,$=/^https?:\/\/[^/?#\s]+$/i,N=[3e3,3001,3333,4e3,4321,5e3,5173,5174,8e3,8080,8888,9e3],OriginDetector=class{#e;constructor(e={}){const t=/* @__PURE__ */new Set;for(const i of e.additionalOrigins??[]){const e=D(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??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}());this.#e=[t,i,n,void 0!==i,void 0]}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]||!H.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]);if(0===this.#e[0].size&&void 0!==this.#e[1]&&e.add(this.#e[1]),this.#e[2])for(const t of N)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 D(e){const t=e.trim();if(0!==t.length)try{const e=new URL(t);if("http:"!==e.protocol&&"https:"!==e.protocol)return;if(!$.test(e.origin))return;return e.origin}catch{return}}function F(e){const[t,i]=e;return"merge HTTP"===t?`the server answered ${String(i)}`:"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 M=class{#t;#i;#n;#r;#s=/* @__PURE__ */new Set;#o;#a;#c=0;#l=[];#u=!1;#d;#h;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 I({serverURL:t.serverURL,...void 0!==t.apiRoute?{apiRoute:t.apiRoute}:{},...void 0!==t.depth?{depth:t.depth}:{},...void 0!==t.fetchFn?{fetchFn:t.fetchFn}:{},log:(...e)=>{this.#l=e}}),this.#i=new E(e=>this.#n.matches(e),{onUpdate:e=>{this.#f(e)},onDocumentEvent:()=>{},sourcePolicy:t.eventSourcePolicy??"parent-or-opener"}),this.#r=t.target,this.#o={data:e,isLoading:!0,status:"idle",error:void 0,revision:0},this.#a=this.#o}subscribe=e=>(this.#s.add(e),this.#u||this.#p(),()=>{this.#s.delete(e),0===this.#s.size&&this.#g()});getSnapshot=()=>this.#a;getServerSnapshot=()=>this.#o;#p(){"undefined"==typeof window&&void 0===this.#r||(this.#u=!0,this.#i.attach(this.#r??window),E.sendReady(this.#v(),this.#n.enumerate()))}#g(){this.#u&&(this.#u=!1,this.#c+=1,this.#i.detach(),this.#t.destroy())}#v(){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}#y(e){return this.#u&&e===this.#c}async#f(e){const t=e.data;if(void 0===t)return;const i=this.#c+=1;void 0!==e.fieldSchemaJSON&&(this.#d=e.fieldSchemaJSON);const n=this.#d;void 0!==e.locale&&(this.#h=e.locale);const r=void 0===n?e.locale:this.#h;if(this.#m({...this.#a,isLoading:!0}),!this.#y(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.#y(i)&&"superseded"!==s.status&&("unavailable"!==s.status?this.#m({data:s.doc,isLoading:!1,status:"live",error:void 0,revision:i}):this.#m({...this.#a,isLoading:!1,status:"unavailable",error:new Error(`live preview: ${F(this.#l)}`)}))}#m(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()}}},G="__livePreviewRouteRefresh";function registerRouteRefresh(e){const t="undefined"==typeof window?void 0:window;return void 0===t?()=>{}:(t[G]=e,()=>{t[G]===e&&(t[G]=void 0)})}function z(e){const t=e.current;e.current=[];for(const e of t)e()}function _({refresh:n}){const[r,s]=e(),o=t([]);return i(()=>{r||z(o)}),i(()=>{const e=registerRouteRefresh(()=>new Promise(e=>{o.current.push(e),s(()=>{n()})}));return()=>{e(),z(o)}},[n,s]),null}function J(e){const i=function(e){const{initialData:i,serverURL:n,apiRoute:r,depth:s,allowedOrigins:o,eventSourcePolicy:a,enableReferrerDetection:c,enableLocalhostMatching:l,fetchFn:u,target:d}=e,h=[n,r??"",String(s??""),(o??[]).join(" "),a??"",String(c??""),String(l??"")].join(" | "),f=t(null);return f.current?.key===h&&f.current.target===d||(f.current={key:h,target:d,session:new M(i,{serverURL:n,...void 0!==r?{apiRoute:r}:{},...void 0!==s?{depth:s}:{},...void 0!==o?{allowedOrigins:o}:{},...void 0!==a?{eventSourcePolicy:a}:{},...void 0!==c?{enableReferrerDetection:c}:{},...void 0!==l?{enableLocalhostMatching:l}:{},...void 0!==u?{fetchFn:u}:{},...void 0!==d?{target:d}:{}})}),f.current.session}(e);return n(i.subscribe,i.getSnapshot,i.getServerSnapshot)}export{_ as LivePreviewRouteRefresh,registerRouteRefresh,J as useLivePreviewDocument};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|