next-sanity 13.1.3 → 13.1.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"NextStudioNoScript.js","names":[],"sources":["../src/studio/NextStudioLayout.tsx","../src/studio/NextStudioNoScript.tsx"],"sourcesContent":["/** @public */\nexport interface NextStudioLayoutProps {\n children: React.ReactNode\n}\n\nconst style = {\n height: '100vh',\n maxHeight: '100dvh',\n overscrollBehavior: 'none',\n WebkitFontSmoothing: 'antialiased',\n overflow: 'auto',\n} satisfies React.CSSProperties\n\n/** @public */\nexport const NextStudioLayout = ({children}: NextStudioLayoutProps): React.JSX.Element => {\n return (\n <div id=\"sanity\" data-ui=\"NextStudioLayout\" style={style}>\n {children}\n </div>\n )\n}\n","const styles: Record<'outer' | 'inner', React.CSSProperties> = {\n outer: {\n position: 'absolute',\n top: 0,\n right: 0,\n left: 0,\n bottom: 0,\n background: '#fff',\n zIndex: 1,\n },\n inner: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n textAlign: 'center',\n fontFamily: 'helvetica, arial, sans-serif',\n },\n}\n\n/** @internal */\nexport const NextStudioNoScript = (): React.JSX.Element => (\n <noscript>\n <div style={styles.outer}>\n <div style={styles.inner}>\n <h1>JavaScript disabled</h1>\n <p>\n Please <a href=\"https://www.enable-javascript.com/\">enable JavaScript</a> in your browser\n and reload the page to proceed.\n </p>\n </div>\n </div>\n </noscript>\n)\n"],"mappings":";AAKA,MAAM,QAAQ;CACZ,QAAQ;CACR,WAAW;CACX,oBAAoB;CACpB,qBAAqB;CACrB,UAAU;AACZ;;AAGA,MAAa,oBAAoB,EAAC,eAAwD;CACxF,OACE,oBAAC,OAAD;EAAK,IAAG;EAAS,WAAQ;EAA0B;EAChD;CACE,CAAA;AAET;ACpBA,MAAM,SAAyD;CAC7D,OAAO;EACL,UAAU;EACV,KAAK;EACL,OAAO;EACP,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,QAAQ;CACV;CACA,OAAO;EACL,UAAU;EACV,KAAK;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACX,YAAY;CACd;AACF;;AAGA,MAAa,2BACX,oBAAC,YAAD,EAAA,UACE,oBAAC,OAAD;CAAK,OAAO,OAAO;WACjB,qBAAC,OAAD;EAAK,OAAO,OAAO;YAAnB,CACE,oBAAC,MAAD,EAAA,UAAI,sBAAuB,CAAA,GAC3B,qBAAC,KAAD,EAAA,UAAA;GAAG;GACM,oBAAC,KAAD;IAAG,MAAK;cAAqC;GAAoB,CAAA;GAAC;EAExE,EAAA,CAAA,CACA;;AACF,CAAA,EACG,CAAA"}
1
+ {"version":3,"file":"NextStudioNoScript.js","names":[],"sources":["../src/studio/NextStudioLayout.tsx","../src/studio/NextStudioNoScript.tsx"],"sourcesContent":["/** @public */\nexport interface NextStudioLayoutProps {\n children: React.ReactNode\n}\n\nconst style = {\n height: '100vh',\n maxHeight: '100dvh',\n overscrollBehavior: 'none',\n WebkitFontSmoothing: 'antialiased',\n overflow: 'auto',\n} satisfies React.CSSProperties\n\n/** @public */\nexport const NextStudioLayout = ({children}: NextStudioLayoutProps): React.JSX.Element => {\n return (\n <div id=\"sanity\" data-ui=\"NextStudioLayout\" style={style}>\n {children}\n </div>\n )\n}\n","const styles: Record<'outer' | 'inner', React.CSSProperties> = {\n outer: {\n position: 'absolute',\n top: 0,\n right: 0,\n left: 0,\n bottom: 0,\n background: '#fff',\n zIndex: 1,\n },\n inner: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n textAlign: 'center',\n fontFamily: 'helvetica, arial, sans-serif',\n },\n}\n\n/** @internal */\nexport const NextStudioNoScript = (): React.JSX.Element => (\n <noscript>\n <div style={styles.outer}>\n <div style={styles.inner}>\n <h1>JavaScript disabled</h1>\n <p>\n Please <a href=\"https://www.enable-javascript.com/\">enable JavaScript</a> in your browser\n and reload the page to proceed.\n </p>\n </div>\n </div>\n </noscript>\n)\n"],"mappings":";AAKA,MAAM,QAAQ;CACZ,QAAQ;CACR,WAAW;CACX,oBAAoB;CACpB,qBAAqB;CACrB,UAAU;AACZ;;AAGA,MAAa,oBAAoB,EAAC,eAAwD;CACxF,OACE,oBAAC,OAAD;EAAK,IAAG;EAAS,WAAQ;EAA0B;EAChD;CACE,CAAA;AAET;ACpBA,MAAM,SAAyD;CAC7D,OAAO;EACL,UAAU;EACV,KAAK;EACL,OAAO;EACP,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,QAAQ;CACV;CACA,OAAO;EACL,UAAU;EACV,KAAK;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACX,YAAY;CACd;AACF;;AAGA,MAAa,2BACX,oBAAC,YAAD,EAAA,UACE,oBAAC,OAAD;CAAK,OAAO,OAAO;CACjB,UAAA,qBAAC,OAAD;EAAK,OAAO,OAAO;EAAnB,UAAA,CACE,oBAAC,MAAD,EAAA,UAAI,sBAAuB,CAAA,GAC3B,qBAAC,KAAD,EAAA,UAAA;GAAG;GACM,oBAAC,KAAD;IAAG,MAAK;IAAqC,UAAA;GAAoB,CAAA;GAAC;EAExE,EAAA,CAAA,CACA;;AACF,CAAA,EACG,CAAA"}
@@ -1,5 +1,5 @@
1
- import { t as isCorsOriginError } from "./isCorsOriginError.js";
2
1
  import { n as defaultApiHost, t as cacheTagPrefix } from "./constants.js";
2
+ import { t as isCorsOriginError } from "./isCorsOriginError.js";
3
3
  import { useRouter } from "next/navigation";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { createClient } from "@sanity/client";
package/dist/constants.js CHANGED
@@ -1,6 +1,14 @@
1
1
  const cacheTagPrefix = "sanity:";
2
2
  /** The default API host used by @sanity/client when none is specified. */
3
3
  const defaultApiHost = "https://api.sanity.io";
4
- export { defaultApiHost as n, cacheTagPrefix as t };
4
+ /**
5
+ * Companion cookie set alongside CHIPS-partitioned draft-mode cookies.
6
+ * Presence of this cookie tells later writes (e.g. perspective changes via
7
+ * server actions) to keep using the `Partitioned` attribute.
8
+ *
9
+ * @see https://github.com/sanity-io/sanity/issues/12806
10
+ */
11
+ const partitionedCookieName = "sanity-preview-partitioned";
12
+ export { defaultApiHost as n, partitionedCookieName as r, cacheTagPrefix as t };
5
13
 
6
14
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../src/live/shared/constants.ts"],"sourcesContent":["import type {CacheTagPrefix} from '#live/types'\n\n// @TODO make this configurable\nexport const cacheTagPrefix: 'sanity:' = 'sanity:' satisfies CacheTagPrefix\n\n/** The default API host used by @sanity/client when none is specified. */\nexport const defaultApiHost = 'https://api.sanity.io'\n"],"mappings":"AAGA,MAAa,iBAA4B;;AAGzC,MAAa,iBAAiB"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../src/live/shared/constants.ts"],"sourcesContent":["import type {CacheTagPrefix} from '#live/types'\n\n// @TODO make this configurable\nexport const cacheTagPrefix: 'sanity:' = 'sanity:' satisfies CacheTagPrefix\n\n/** The default API host used by @sanity/client when none is specified. */\nexport const defaultApiHost = 'https://api.sanity.io'\n\n/**\n * Companion cookie set alongside CHIPS-partitioned draft-mode cookies.\n * Presence of this cookie tells later writes (e.g. perspective changes via\n * server actions) to keep using the `Partitioned` attribute.\n *\n * @see https://github.com/sanity-io/sanity/issues/12806\n */\nexport const partitionedCookieName = 'sanity-preview-partitioned'\n"],"mappings":"AAGA,MAAa,iBAA4B;;AAGzC,MAAa,iBAAiB;;;;;;;;AAS9B,MAAa,wBAAwB"}
@@ -21,6 +21,14 @@ interface EnableDraftMode {
21
21
  /**
22
22
  * Sets up an API route for enabling draft mode, can be paired with the `previewUrl.previewMode.enable` in `sanity/presentation`.
23
23
  * Can also be used with `sanity-plugin-iframe-pane`.
24
+ *
25
+ * When the preview loads in a cross-site iframe (Presentation Tool), draft-mode
26
+ * cookies are set with the CHIPS `Partitioned` attribute so Safari 18.4+ stores
27
+ * them despite third-party cookie blocking. Top-level / same-site requests keep
28
+ * unpartitioned cookies so `draftMode().disable()` continues to work.
29
+ *
30
+ * @see https://github.com/sanity-io/sanity/issues/12806
31
+ *
24
32
  * @example
25
33
  * ```ts
26
34
  * // src/app/api/draft-mode/enable/route.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/draft-mode/define-enable-draft-mode.ts"],"mappings":";;;;UASiB;EACf,QAAQ;;;;;;;EAOR;;;;;UAMe;EACf,MAAM,SAAS,YAAY,QAAQ;;;;;;;;;;;;;;;;;;;iBAoBrB,sBAAsB,SAAS,+BAA+B"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/draft-mode/define-enable-draft-mode.ts"],"mappings":";;;;UAWiB;EACf,QAAQ;;;;;;;EAOR;;;;;UAMe;EACf,MAAM,SAAS,YAAY,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4BrB,sBAAsB,SAAS,+BAA+B"}
@@ -1,3 +1,4 @@
1
+ import { r as partitionedCookieName } from "../constants.js";
1
2
  import { validatePreviewUrl } from "@sanity/preview-url-secret";
2
3
  import { perspectiveCookieName } from "@sanity/preview-url-secret/constants";
3
4
  import { cookies, draftMode } from "next/headers";
@@ -5,6 +6,14 @@ import { redirect } from "next/navigation";
5
6
  /**
6
7
  * Sets up an API route for enabling draft mode, can be paired with the `previewUrl.previewMode.enable` in `sanity/presentation`.
7
8
  * Can also be used with `sanity-plugin-iframe-pane`.
9
+ *
10
+ * When the preview loads in a cross-site iframe (Presentation Tool), draft-mode
11
+ * cookies are set with the CHIPS `Partitioned` attribute so Safari 18.4+ stores
12
+ * them despite third-party cookie blocking. Top-level / same-site requests keep
13
+ * unpartitioned cookies so `draftMode().disable()` continues to work.
14
+ *
15
+ * @see https://github.com/sanity-io/sanity/issues/12806
16
+ *
8
17
  * @example
9
18
  * ```ts
10
19
  * // src/app/api/draft-mode/enable/route.ts
@@ -27,6 +36,7 @@ function defineEnableDraftMode(options) {
27
36
  const draftModeStore = await draftMode();
28
37
  if (!draftModeStore.isEnabled) draftModeStore.enable();
29
38
  const isSecure = process.env.NODE_ENV === "production" || (options.secureDevMode ?? false);
39
+ const partitioned = isSecure && request.headers.get("sec-fetch-dest") === "iframe" && request.headers.get("sec-fetch-site") === "cross-site";
30
40
  const cookieStore = await cookies();
31
41
  const cookie = cookieStore.get("__prerender_bypass");
32
42
  cookieStore.set({
@@ -35,7 +45,8 @@ function defineEnableDraftMode(options) {
35
45
  httpOnly: true,
36
46
  path: "/",
37
47
  secure: isSecure,
38
- sameSite: isSecure ? "none" : "lax"
48
+ sameSite: isSecure ? "none" : "lax",
49
+ partitioned
39
50
  });
40
51
  if (studioPreviewPerspective) cookieStore.set({
41
52
  name: perspectiveCookieName,
@@ -43,7 +54,17 @@ function defineEnableDraftMode(options) {
43
54
  httpOnly: true,
44
55
  path: "/",
45
56
  secure: isSecure,
46
- sameSite: isSecure ? "none" : "lax"
57
+ sameSite: isSecure ? "none" : "lax",
58
+ partitioned
59
+ });
60
+ if (partitioned) cookieStore.set({
61
+ name: partitionedCookieName,
62
+ value: "1",
63
+ httpOnly: true,
64
+ path: "/",
65
+ secure: true,
66
+ sameSite: "none",
67
+ partitioned: true
47
68
  });
48
69
  return redirect(redirectTo);
49
70
  } };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/draft-mode/define-enable-draft-mode.ts"],"sourcesContent":["import type {SanityClient} from '@sanity/client'\nimport {validatePreviewUrl} from '@sanity/preview-url-secret'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {cookies, draftMode} from 'next/headers'\nimport {redirect} from 'next/navigation'\n\n/**\n * @public\n */\nexport interface DefineEnableDraftModeOptions {\n client: SanityClient\n /**\n * Force secure cookies in development mode.\n * Enable this when using Next.js --experimental-https flag.\n * This option has no effect in production (cookies are always secure).\n * @defaultValue false\n */\n secureDevMode?: boolean\n}\n\n/**\n * @public\n */\nexport interface EnableDraftMode {\n GET: (request: Request) => Promise<Response>\n}\n\n/**\n * Sets up an API route for enabling draft mode, can be paired with the `previewUrl.previewMode.enable` in `sanity/presentation`.\n * Can also be used with `sanity-plugin-iframe-pane`.\n * @example\n * ```ts\n * // src/app/api/draft-mode/enable/route.ts\n *\n * import { defineEnableDraftMode } from \"next-sanity/draft-mode\";\n * import { client } from \"@/sanity/lib/client\";\n *\n * export const { GET } = defineEnableDraftMode({\n * client: client.withConfig({ token: process.env.SANITY_API_READ_TOKEN }),\n * });\n * ```\n *\n * @public\n */\nexport function defineEnableDraftMode(options: DefineEnableDraftModeOptions): EnableDraftMode {\n const {client} = options\n return {\n GET: async (request: Request) => {\n // @TODO check if already in draft mode at a much earlier stage, and skip validation\n\n const {\n isValid,\n redirectTo = '/',\n studioPreviewPerspective,\n } = await validatePreviewUrl(client, request.url)\n if (!isValid) {\n return new Response('Invalid secret', {status: 401})\n }\n\n const draftModeStore = await draftMode()\n\n // Let's enable draft mode if it's not already enabled\n if (!draftModeStore.isEnabled) {\n draftModeStore.enable()\n }\n\n const isProduction = process.env.NODE_ENV === 'production'\n\n // We can't auto-detect HTTPS in dev due to Next.js limitations,\n // so we need an explicit option\n const isSecure = isProduction || (options.secureDevMode ?? false)\n\n // Override cookie header for draft mode for usage in live-preview\n // https://github.com/vercel/next.js/issues/49927\n const cookieStore = await cookies()\n const cookie = cookieStore.get('__prerender_bypass')!\n cookieStore.set({\n name: '__prerender_bypass',\n value: cookie?.value,\n httpOnly: true,\n path: '/',\n secure: isSecure,\n sameSite: isSecure ? 'none' : 'lax',\n })\n\n if (studioPreviewPerspective) {\n cookieStore.set({\n name: perspectiveCookieName,\n value: studioPreviewPerspective,\n httpOnly: true,\n path: '/',\n secure: isSecure,\n sameSite: isSecure ? 'none' : 'lax',\n })\n }\n\n return redirect(redirectTo)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,sBAAsB,SAAwD;CAC5F,MAAM,EAAC,WAAU;CACjB,OAAO,EACL,KAAK,OAAO,YAAqB;EAG/B,MAAM,EACJ,SACA,aAAa,KACb,6BACE,MAAM,mBAAmB,QAAQ,QAAQ,GAAG;EAChD,IAAI,CAAC,SACH,OAAO,IAAI,SAAS,kBAAkB,EAAC,QAAQ,IAAG,CAAC;EAGrD,MAAM,iBAAiB,MAAM,UAAU;EAGvC,IAAI,CAAC,eAAe,WAClB,eAAe,OAAO;EAOxB,MAAM,WAJe,QAAQ,IAAI,aAAa,iBAIZ,QAAQ,iBAAiB;EAI3D,MAAM,cAAc,MAAM,QAAQ;EAClC,MAAM,SAAS,YAAY,IAAI,oBAAoB;EACnD,YAAY,IAAI;GACd,MAAM;GACN,OAAO,QAAQ;GACf,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU,WAAW,SAAS;EAChC,CAAC;EAED,IAAI,0BACF,YAAY,IAAI;GACd,MAAM;GACN,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU,WAAW,SAAS;EAChC,CAAC;EAGH,OAAO,SAAS,UAAU;CAC5B,EACF;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/draft-mode/define-enable-draft-mode.ts"],"sourcesContent":["import type {SanityClient} from '@sanity/client'\nimport {validatePreviewUrl} from '@sanity/preview-url-secret'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {cookies, draftMode} from 'next/headers'\nimport {redirect} from 'next/navigation'\n\nimport {partitionedCookieName} from '#live/constants'\n\n/**\n * @public\n */\nexport interface DefineEnableDraftModeOptions {\n client: SanityClient\n /**\n * Force secure cookies in development mode.\n * Enable this when using Next.js --experimental-https flag.\n * This option has no effect in production (cookies are always secure).\n * @defaultValue false\n */\n secureDevMode?: boolean\n}\n\n/**\n * @public\n */\nexport interface EnableDraftMode {\n GET: (request: Request) => Promise<Response>\n}\n\n/**\n * Sets up an API route for enabling draft mode, can be paired with the `previewUrl.previewMode.enable` in `sanity/presentation`.\n * Can also be used with `sanity-plugin-iframe-pane`.\n *\n * When the preview loads in a cross-site iframe (Presentation Tool), draft-mode\n * cookies are set with the CHIPS `Partitioned` attribute so Safari 18.4+ stores\n * them despite third-party cookie blocking. Top-level / same-site requests keep\n * unpartitioned cookies so `draftMode().disable()` continues to work.\n *\n * @see https://github.com/sanity-io/sanity/issues/12806\n *\n * @example\n * ```ts\n * // src/app/api/draft-mode/enable/route.ts\n *\n * import { defineEnableDraftMode } from \"next-sanity/draft-mode\";\n * import { client } from \"@/sanity/lib/client\";\n *\n * export const { GET } = defineEnableDraftMode({\n * client: client.withConfig({ token: process.env.SANITY_API_READ_TOKEN }),\n * });\n * ```\n *\n * @public\n */\nexport function defineEnableDraftMode(options: DefineEnableDraftModeOptions): EnableDraftMode {\n const {client} = options\n return {\n GET: async (request: Request) => {\n // @TODO check if already in draft mode at a much earlier stage, and skip validation\n\n const {\n isValid,\n redirectTo = '/',\n studioPreviewPerspective,\n } = await validatePreviewUrl(client, request.url)\n if (!isValid) {\n return new Response('Invalid secret', {status: 401})\n }\n\n const draftModeStore = await draftMode()\n\n // Let's enable draft mode if it's not already enabled\n if (!draftModeStore.isEnabled) {\n draftModeStore.enable()\n }\n\n const isProduction = process.env.NODE_ENV === 'production'\n\n // We can't auto-detect HTTPS in dev due to Next.js limitations,\n // so we need an explicit option\n const isSecure = isProduction || (options.secureDevMode ?? false)\n\n // Safari blocks unpartitioned third-party cookies. When the enable route is\n // hit from a cross-site iframe (Presentation), opt into CHIPS so the cookies\n // are stored under the studio's partition. Skip partitioning for top-level /\n // same-site requests so draftMode().disable() can still clear them.\n // https://github.com/sanity-io/sanity/issues/12806\n const partitioned =\n isSecure &&\n request.headers.get('sec-fetch-dest') === 'iframe' &&\n request.headers.get('sec-fetch-site') === 'cross-site'\n\n // Override cookie header for draft mode for usage in live-preview\n // https://github.com/vercel/next.js/issues/49927\n const cookieStore = await cookies()\n const cookie = cookieStore.get('__prerender_bypass')!\n cookieStore.set({\n name: '__prerender_bypass',\n value: cookie?.value,\n httpOnly: true,\n path: '/',\n secure: isSecure,\n sameSite: isSecure ? 'none' : 'lax',\n partitioned,\n })\n\n if (studioPreviewPerspective) {\n cookieStore.set({\n name: perspectiveCookieName,\n value: studioPreviewPerspective,\n httpOnly: true,\n path: '/',\n secure: isSecure,\n sameSite: isSecure ? 'none' : 'lax',\n partitioned,\n })\n }\n\n // Persist the partitioning decision for later writes (server actions have no\n // Sec-Fetch iframe signal). The flag cookie is itself partitioned, so it is\n // only visible inside the same cross-site iframe context.\n if (partitioned) {\n cookieStore.set({\n name: partitionedCookieName,\n value: '1',\n httpOnly: true,\n path: '/',\n secure: true,\n sameSite: 'none',\n partitioned: true,\n })\n }\n\n return redirect(redirectTo)\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,sBAAsB,SAAwD;CAC5F,MAAM,EAAC,WAAU;CACjB,OAAO,EACL,KAAK,OAAO,YAAqB;EAG/B,MAAM,EACJ,SACA,aAAa,KACb,6BACE,MAAM,mBAAmB,QAAQ,QAAQ,GAAG;EAChD,IAAI,CAAC,SACH,OAAO,IAAI,SAAS,kBAAkB,EAAC,QAAQ,IAAG,CAAC;EAGrD,MAAM,iBAAiB,MAAM,UAAU;EAGvC,IAAI,CAAC,eAAe,WAClB,eAAe,OAAO;EAOxB,MAAM,WAJe,QAAQ,IAAI,aAAa,iBAIZ,QAAQ,iBAAiB;EAO3D,MAAM,cACJ,YACA,QAAQ,QAAQ,IAAI,gBAAgB,MAAM,YAC1C,QAAQ,QAAQ,IAAI,gBAAgB,MAAM;EAI5C,MAAM,cAAc,MAAM,QAAQ;EAClC,MAAM,SAAS,YAAY,IAAI,oBAAoB;EACnD,YAAY,IAAI;GACd,MAAM;GACN,OAAO,QAAQ;GACf,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU,WAAW,SAAS;GAC9B;EACF,CAAC;EAED,IAAI,0BACF,YAAY,IAAI;GACd,MAAM;GACN,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU,WAAW,SAAS;GAC9B;EACF,CAAC;EAMH,IAAI,aACF,YAAY,IAAI;GACd,MAAM;GACN,OAAO;GACP,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU;GACV,aAAa;EACf,CAAC;EAGH,OAAO,SAAS,UAAU;CAC5B,EACF;AACF"}
@@ -1,5 +1,5 @@
1
- import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
1
  import { t as cacheTagPrefix } from "../../../constants.js";
2
+ import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
3
3
  import { i as preconnect, n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
4
4
  import { t as parseTags } from "../../../parseTags.js";
5
5
  import { jsx } from "react/jsx-runtime";
@@ -1,5 +1,5 @@
1
- import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
2
1
  import "../../../constants.js";
2
+ import { t as isCorsOriginError } from "../../../isCorsOriginError.js";
3
3
  import { i as preconnect, n as validateStrictFetchOptions, r as validateStrictSanityLiveProps, t as resolvePerspectiveFromCookies } from "../../../resolvePerspectiveFromCookies.js";
4
4
  import { t as parseTags } from "../../../parseTags.js";
5
5
  import { cookies, draftMode } from "next/headers";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/studio/client-component/NextStudioLazy.tsx"],"sourcesContent":["/**\n *\n * If pages router supported `next/dynamic` imports (it wants `next/dynamic.js`),\n * or if turbopack in app router allowed `next/dynamic.js` (it doesn't yet)\n * we could use `dynamic(() => import('...), {ssr: false})` here.\n * Since we can't, we need to use a lazy import and Suspense ourself.\n */\n\nimport {lazy, Suspense} from 'react'\n\nimport type {NextStudioProps} from './NextStudio'\n\nconst NextStudioClientComponent = lazy(() => import('./NextStudio'))\n\nexport function NextStudioLazyClientComponent(props: NextStudioProps): React.ReactNode {\n return (\n <Suspense fallback={null}>\n <NextStudioClientComponent {...props} />\n </Suspense>\n )\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,4BAA4B,WAAW,OAAO,sBAAe;AAEnE,SAAgB,8BAA8B,OAAyC;CACrF,OACE,oBAAC,UAAD;EAAU,UAAU;YAClB,oBAAC,2BAAD,EAA2B,GAAI,MAAQ,CAAA;CAC/B,CAAA;AAEd"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/studio/client-component/NextStudioLazy.tsx"],"sourcesContent":["/**\n *\n * If pages router supported `next/dynamic` imports (it wants `next/dynamic.js`),\n * or if turbopack in app router allowed `next/dynamic.js` (it doesn't yet)\n * we could use `dynamic(() => import('...), {ssr: false})` here.\n * Since we can't, we need to use a lazy import and Suspense ourself.\n */\n\nimport {lazy, Suspense} from 'react'\n\nimport type {NextStudioProps} from './NextStudio'\n\nconst NextStudioClientComponent = lazy(() => import('./NextStudio'))\n\nexport function NextStudioLazyClientComponent(props: NextStudioProps): React.ReactNode {\n return (\n <Suspense fallback={null}>\n <NextStudioClientComponent {...props} />\n </Suspense>\n )\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAM,4BAA4B,WAAW,OAAO,sBAAe;AAEnE,SAAgB,8BAA8B,OAAyC;CACrF,OACE,oBAAC,UAAD;EAAU,UAAU;EAClB,UAAA,oBAAC,2BAAD,EAA2B,GAAI,MAAQ,CAAA;CAC/B,CAAA;AAEd"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/visual-editing/server-actions/index.ts"],"mappings":";;;;iBAYsB,wBAAwB,aAAa,oBAAoB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/visual-editing/server-actions/index.ts"],"mappings":";;;;iBAasB,wBAAwB,aAAa,oBAAoB"}
@@ -1,4 +1,5 @@
1
1
  "use server";
2
+ import { r as partitionedCookieName } from "../../constants.js";
2
3
  import { t as sanitizePerspective } from "../../sanitizePerspective.js";
3
4
  import { perspectiveCookieName } from "@sanity/preview-url-secret/constants";
4
5
  import { cookies } from "next/headers";
@@ -19,7 +20,8 @@ async function perspectiveChangeAction(perspective) {
19
20
  httpOnly: true,
20
21
  path: "/",
21
22
  secure: true,
22
- sameSite: "none"
23
+ sameSite: "none",
24
+ partitioned: jar.has(partitionedCookieName)
23
25
  });
24
26
  refresh();
25
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/visual-editing/server-actions/index.ts"],"sourcesContent":["'use server'\n\nimport type {ClientPerspective} from '@sanity/client'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {refresh} from 'next/cache'\nimport {cookies} from 'next/headers'\n\nimport {sanitizePerspective} from '#live/sanitizePerspective'\n\n/**\n * @internal CAUTION: this is an internal action and does not follow semver. Using it directly is at your own risk.\n */\nexport async function perspectiveChangeAction(perspective: ClientPerspective): Promise<void> {\n const sanitizedPerspective = sanitizePerspective(perspective, 'drafts')\n if (\n !sanitizedPerspective ||\n (Array.isArray(sanitizedPerspective) && sanitizedPerspective.length === 0)\n ) {\n throw new Error(`Invalid perspective`, {cause: perspective})\n }\n\n const nextPerspective = Array.isArray(sanitizedPerspective)\n ? sanitizedPerspective.join(',')\n : sanitizedPerspective\n const jar = await cookies()\n if (\n nextPerspective === jar.get(perspectiveCookieName)?.value &&\n process.env.NODE_ENV !== 'production'\n ) {\n // oxlint-disable-next-line no-console\n console.debug('perspectiveChangeAction', 'Perspective is the same, skipping', nextPerspective)\n return\n }\n jar.set(perspectiveCookieName, nextPerspective, {\n httpOnly: true,\n path: '/',\n secure: true,\n sameSite: 'none',\n })\n\n refresh()\n}\n"],"mappings":";;;;;;;;AAYA,eAAsB,wBAAwB,aAA+C;CAC3F,MAAM,uBAAuB,oBAAoB,aAAa,QAAQ;CACtE,IACE,CAAC,wBACA,MAAM,QAAQ,oBAAoB,KAAK,qBAAqB,WAAW,GAExE,MAAM,IAAI,MAAM,uBAAuB,EAAC,OAAO,YAAW,CAAC;CAG7D,MAAM,kBAAkB,MAAM,QAAQ,oBAAoB,IACtD,qBAAqB,KAAK,GAAG,IAC7B;CACJ,MAAM,MAAM,MAAM,QAAQ;CAC1B,IACE,oBAAoB,IAAI,IAAI,qBAAqB,CAAC,EAAE,SACpD,QAAQ,IAAI,aAAa,cACzB;EAEA,QAAQ,MAAM,2BAA2B,qCAAqC,eAAe;EAC7F;CACF;CACA,IAAI,IAAI,uBAAuB,iBAAiB;EAC9C,UAAU;EACV,MAAM;EACN,QAAQ;EACR,UAAU;CACZ,CAAC;CAED,QAAQ;AACV"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/visual-editing/server-actions/index.ts"],"sourcesContent":["'use server'\n\nimport type {ClientPerspective} from '@sanity/client'\nimport {perspectiveCookieName} from '@sanity/preview-url-secret/constants'\nimport {refresh} from 'next/cache'\nimport {cookies} from 'next/headers'\n\nimport {partitionedCookieName} from '#live/constants'\nimport {sanitizePerspective} from '#live/sanitizePerspective'\n\n/**\n * @internal CAUTION: this is an internal action and does not follow semver. Using it directly is at your own risk.\n */\nexport async function perspectiveChangeAction(perspective: ClientPerspective): Promise<void> {\n const sanitizedPerspective = sanitizePerspective(perspective, 'drafts')\n if (\n !sanitizedPerspective ||\n (Array.isArray(sanitizedPerspective) && sanitizedPerspective.length === 0)\n ) {\n throw new Error(`Invalid perspective`, {cause: perspective})\n }\n\n const nextPerspective = Array.isArray(sanitizedPerspective)\n ? sanitizedPerspective.join(',')\n : sanitizedPerspective\n const jar = await cookies()\n if (\n nextPerspective === jar.get(perspectiveCookieName)?.value &&\n process.env.NODE_ENV !== 'production'\n ) {\n // oxlint-disable-next-line no-console\n console.debug('perspectiveChangeAction', 'Perspective is the same, skipping', nextPerspective)\n return\n }\n // Mirror the CHIPS partitioning decision from defineEnableDraftMode. Server\n // actions do not receive Sec-Fetch iframe headers, so we rely on the companion\n // flag cookie set during enable.\n // https://github.com/sanity-io/sanity/issues/12806\n jar.set(perspectiveCookieName, nextPerspective, {\n httpOnly: true,\n path: '/',\n secure: true,\n sameSite: 'none',\n partitioned: jar.has(partitionedCookieName),\n })\n\n refresh()\n}\n"],"mappings":";;;;;;;;;AAaA,eAAsB,wBAAwB,aAA+C;CAC3F,MAAM,uBAAuB,oBAAoB,aAAa,QAAQ;CACtE,IACE,CAAC,wBACA,MAAM,QAAQ,oBAAoB,KAAK,qBAAqB,WAAW,GAExE,MAAM,IAAI,MAAM,uBAAuB,EAAC,OAAO,YAAW,CAAC;CAG7D,MAAM,kBAAkB,MAAM,QAAQ,oBAAoB,IACtD,qBAAqB,KAAK,GAAG,IAC7B;CACJ,MAAM,MAAM,MAAM,QAAQ;CAC1B,IACE,oBAAoB,IAAI,IAAI,qBAAqB,CAAC,EAAE,SACpD,QAAQ,IAAI,aAAa,cACzB;EAEA,QAAQ,MAAM,2BAA2B,qCAAqC,eAAe;EAC7F;CACF;CAKA,IAAI,IAAI,uBAAuB,iBAAiB;EAC9C,UAAU;EACV,MAAM;EACN,QAAQ;EACR,UAAU;EACV,aAAa,IAAI,IAAI,qBAAqB;CAC5C,CAAC;CAED,QAAQ;AACV"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-sanity",
3
- "version": "13.1.3",
3
+ "version": "13.1.5",
4
4
  "description": "Sanity.io toolkit for Next.js",
5
5
  "keywords": [
6
6
  "live",
@@ -59,17 +59,16 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@portabletext/react": "^6.2.0",
62
- "@sanity/client": "^7.23.1",
62
+ "@sanity/client": "^7.24.0",
63
63
  "@sanity/generate-help-url": "^4.0.0",
64
- "@sanity/preview-url-secret": "^4.0.8",
65
- "@sanity/visual-editing": "^5.5.0",
64
+ "@sanity/preview-url-secret": "^4.1.0",
65
+ "@sanity/visual-editing": "^5.6.0",
66
66
  "@sanity/webhook": "^4.0.4",
67
67
  "groq": "^6.5.0",
68
68
  "history": "^5.3.0"
69
69
  },
70
70
  "devDependencies": {
71
- "@sanity/tsconfig": "^2.2.0",
72
- "@types/js-yaml": "^4.0.9",
71
+ "@sanity/tsconfig": "^2.2.1",
73
72
  "@types/node": "^24.13.3",
74
73
  "@types/react": "^19.2.17",
75
74
  "@types/react-dom": "^19.2.3",
@@ -77,23 +76,22 @@
77
76
  "@vitejs/plugin-react": "^6.0.3",
78
77
  "@vitest/browser-playwright": "^4.1.10",
79
78
  "@vitest/coverage-v8": "^4.1.10",
80
- "js-yaml": "^4.3.0",
79
+ "js-yaml": "^5.2.1",
81
80
  "msw": "^2.15.0",
82
- "next": "16.3.0-canary.83",
81
+ "next": "16.3.0-canary.91",
83
82
  "publint": "^0.3.21",
84
- "react": "^19.2.7",
85
- "react-dom": "^19.2.7",
86
- "styled-components": "^6.4.3",
87
- "tsdown": "^0.22.7",
88
- "typedoc": "^0.28.20",
89
- "typescript": "6.0.3",
90
- "vite": "^8.1.4",
83
+ "react": "^19.2.8",
84
+ "react-dom": "^19.2.8",
85
+ "styled-components": "^6.4.4",
86
+ "tsdown": "^0.22.12",
87
+ "typescript": "7.0.2",
88
+ "vite": "^8.1.5",
91
89
  "vitest": "^4.1.10",
92
90
  "vitest-browser-react": "^2.2.0",
93
91
  "vitest-package-exports": "^1.2.0"
94
92
  },
95
93
  "peerDependencies": {
96
- "@sanity/client": "^7.23.1",
94
+ "@sanity/client": "^7.24.0",
97
95
  "next": "^16.0.0-0",
98
96
  "react": "^19.2.3",
99
97
  "react-dom": "^19.2.3",
@@ -112,7 +110,6 @@
112
110
  "build": "tsdown --publint",
113
111
  "coverage": "npm test -- --coverage",
114
112
  "dev": "tsdown --watch",
115
- "docs:generate": "typedoc",
116
113
  "test": "vitest --project unit",
117
114
  "test:coverage": "vitest --coverage run",
118
115
  "test:e2e": "vitest --project browser"