payload-live-preview 1.0.2 → 1.0.4

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