next-sanity 8.5.5 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  The official [Sanity.io][sanity] toolkit for Next.js apps.
4
4
 
5
- > [!IMPORTANT]
6
- > You're looking at the README for v8, the README for [v7 is available here](https://github.com/sanity-io/next-sanity/tree/v7?tab=readme-ov-file#next-sanity) as well as an [migration guide][migrate-v7-to-v8].
5
+ > [!IMPORTANT]
6
+ > You're looking at the README for v9, the README for [v8 is available here](https://github.com/sanity-io/next-sanity/tree/v8?tab=readme-ov-file#next-sanity) as well as an [migration guide][migrate-v8-to-v9].
7
7
 
8
8
  **Features:**
9
9
 
@@ -725,6 +725,7 @@ function StudioPage() {
725
725
 
726
726
  ## Migration guides
727
727
 
728
+ - [From `v8` to `v9`][migrate-v8-to-v9]
728
729
  - [From `v7` to `v8`][migrate-v7-to-v8]
729
730
  - [From `v6` to `v7`][migrate-v6-to-v7]
730
731
  - [From `v5` to `v6`][migrate-v5-to-v6]
@@ -756,6 +757,7 @@ MIT-licensed. See [LICENSE][LICENSE].
756
757
  [migrate-v5-to-v6]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v5-to-v6.md
757
758
  [migrate-v6-to-v7]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v6-to-v7.md
758
759
  [migrate-v7-to-v8]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v7-to-v8.md
760
+ [migrate-v8-to-v9]: https://github.com/sanity-io/next-sanity/blob/main/packages/next-sanity/MIGRATE-v8-to-v9.md
759
761
  [next-cache]: https://nextjs.org/docs/app/building-your-application/caching
760
762
  [next-data-fetching]: https://nextjs.org/docs/basic-features/data-fetching/overview
761
763
  [next-preview-mode]: https://nextjs.org/docs/advanced-features/preview-mode
package/dist/webhook.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@sanity/webhook");exports.config={api:{bodyParser:!1},runtime:"nodejs"},exports.parseBody=async function(r,t,n=!0){return"text"in r?async function(r,t,n=!0){const i=r.headers.get(e.SIGNATURE_HEADER_NAME);if(!i)return console.error("Missing signature header"),{body:null,isValidSignature:null};const a=await r.text(),o=t?await e.isValidSignature(a,i,t.trim()):null;return!1!==o&&n&&await new Promise((e=>setTimeout(e,3e3))),{body:a.trim()?JSON.parse(a):null,isValidSignature:o}}(r,t,n):async function(r,t,n=!0){let i=r.headers[e.SIGNATURE_HEADER_NAME];if(Array.isArray(i)&&(i=i[0]),!i)return console.error("Missing signature header"),{body:null,isValidSignature:null};if(r.readableEnded)throw new Error("Request already ended and the POST body can't be read. Have you setup `export {config} from 'next-sanity/webhook' in your webhook API handler?`");const a=await async function(e){const r=[];for await(const t of e)r.push("string"==typeof t?Buffer.from(t):t);return Buffer.concat(r).toString("utf8")}(r),o=t?await e.isValidSignature(a,i,t.trim()):null;return!1!==o&&n&&await new Promise((e=>setTimeout(e,1e3))),{body:a.trim()?JSON.parse(a):null,isValidSignature:o}}(r,t,n)};//# sourceMappingURL=webhook.cjs.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@sanity/webhook");exports.parseBody=async function(r,t,i=!0){const a=r.headers.get(e.SIGNATURE_HEADER_NAME);if(!a)return console.error("Missing signature header"),{body:null,isValidSignature:null};const s=await r.text(),n=t?await e.isValidSignature(s,a,t.trim()):null;return!1!==n&&i&&await new Promise((e=>setTimeout(e,3e3))),{body:s.trim()?JSON.parse(s):null,isValidSignature:n}};//# sourceMappingURL=webhook.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.cjs","sources":["../src/webhook/index.ts"],"sourcesContent":["import type {SanityDocument} from '@sanity/types'\nimport {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'\nimport type {NextApiRequest} from 'next'\nimport type {NextRequest} from 'next/server'\nimport type {PageConfig} from 'next/types'\n\n/**\n * Configurates the API function with the right runtime and body parsing to handle Sanity Webhook events.\n * @public\n * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.\n */\nexport const config: PageConfig = {\n api: {\n /**\n * Next.js will by default parse the body, which can lead to invalid signatures.\n */\n bodyParser: false,\n },\n runtime: 'nodejs',\n}\n\n/** @public */\nexport type ParsedBody<T> = {\n /**\n * If a secret is given then it returns a boolean. If no secret is provided then no validation is done on the signature, and it'll return `null`\n */\n isValidSignature: boolean | null\n body: T | null\n}\n\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency?: boolean,\n): Promise<ParsedBody<Body>>\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency?: boolean,\n): Promise<ParsedBody<Body>>\n// eslint-disable-next-line require-await\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest | NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n return 'text' in req\n ? parseAppBody(req, secret, waitForContentLakeEventualConsistency)\n : parsePageBody(req, secret, waitForContentLakeEventualConsistency)\n}\n\n/** @deprecated */\nasync function parsePageBody<Body = SanityDocument>(\n req: NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n let signature = req.headers[SIGNATURE_HEADER_NAME]\n if (Array.isArray(signature)) {\n signature = signature[0]\n }\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n if (req.readableEnded) {\n throw new Error(\n `Request already ended and the POST body can't be read. Have you setup \\`export {config} from 'next-sanity/webhook' in your webhook API handler?\\``,\n )\n }\n\n const body = await readBody(req)\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n\nasync function parseAppBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n const signature = req.headers.get(SIGNATURE_HEADER_NAME)!\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n const body = await req.text()\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 3000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n\nasync function readBody(readable: NextApiRequest): Promise<string> {\n const chunks = []\n for await (const chunk of readable) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks).toString('utf8')\n}\n"],"names":["Object","defineProperty","exports","value","webhook","require","config","api","bodyParser","runtime","parseBody","async","req","secret","waitForContentLakeEventualConsistency","signature","headers","get","SIGNATURE_HEADER_NAME","console","error","body","isValidSignature","text","validSignature","trim","Promise","resolve","setTimeout","JSON","parse","parseAppBody","Array","isArray","readableEnded","Error","readable","chunks","chunk","push","Buffer","from","concat","toString","readBody","parsePageBody"],"mappings":"aAWOA,OAAAC,eAAAC,QAAA,aAAA,CAAAC,OAAA,IAAA,IAAAC,EAAAC,QAAA,mBAmHPH,QAAAI,OAnHkC,CAChCC,IAAK,CAIHC,YAAY,GAEdC,QAAS,UA4GXP,QAAAQ,UA1EAC,eACEC,EACAC,EACAC,GAAiD,GAE1C,MAAA,SAAUF,EAuCnBD,eACEC,EACAC,EACAC,GAAiD,GAEjD,MAAMC,EAAYH,EAAII,QAAQC,IAAIC,EAAqBA,uBACvD,IAAKH,EACH,OAAAI,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMC,iBAAkB,MAGxC,MAAMD,QAAaT,EAAIW,OACjBC,EAAiBX,QAAeS,EAAAA,iBAAiBD,EAAMN,EAAWF,EAAOY,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BV,SACxB,IAAIY,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLN,KAAMA,EAAKI,OAASI,KAAKC,MAAMT,GAAQ,KACvCC,iBAAkBE,EAEtB,CA5DMO,CAAanB,EAAKC,EAAQC,GAKhCH,eACEC,EACAC,EACAC,GAAiD,GAE7C,IAAAC,EAAYH,EAAII,QAAQE,EAAqBA,uBAC7C,GAAAc,MAAMC,QAAQlB,KAChBA,EAAYA,EAAU,KAEnBA,EACH,OAAAI,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMC,iBAAkB,MAGxC,GAAIV,EAAIsB,cACN,MAAM,IAAIC,MACR,mJAIJ,MAAMd,QAqCRV,eAAwByB,GACtB,MAAMC,EAAS,GACf,UAAA,MAAiBC,KAASF,EACjBC,EAAAE,KAAsB,iBAAVD,EAAqBE,OAAOC,KAAKH,GAASA,GAE/D,OAAOE,OAAOE,OAAOL,GAAQM,SAAS,OACxC,CA3CqBC,CAAShC,GACtBY,EAAiBX,QAAeS,EAAAA,iBAAiBD,EAAMN,EAAWF,EAAOY,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BV,SACxB,IAAIY,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLN,KAAMA,EAAKI,OAASI,KAAKC,MAAMT,GAAQ,KACvCC,iBAAkBE,EAEtB,CAnCMqB,CAAcjC,EAAKC,EAAQC,EACjC"}
1
+ {"version":3,"file":"webhook.cjs","sources":["../src/webhook/index.ts"],"sourcesContent":["import type {SanityDocument} from '@sanity/types'\nimport {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'\nimport type {NextRequest} from 'next/server'\n\n/** @public */\nexport type ParsedBody<T> = {\n /**\n * If a secret is given then it returns a boolean. If no secret is provided then no validation is done on the signature, and it'll return `null`\n */\n isValidSignature: boolean | null\n body: T | null\n}\n\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency = true,\n): Promise<ParsedBody<Body>> {\n const signature = req.headers.get(SIGNATURE_HEADER_NAME)\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n const body = await req.text()\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 3000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n"],"names":["exports","parseBody","async","req","secret","waitForContentLakeEventualConsistency","signature","headers","get","SIGNATURE_HEADER_NAME","console","error","body","isValidSignature","text","validSignature","trim","Promise","resolve","setTimeout","JSON","parse"],"mappings":"qGAwCAA,QAAAC,UAtBAC,eACEC,EACAC,EACAC,GAAwC,GAExC,MAAMC,EAAYH,EAAII,QAAQC,IAAIC,EAAqBA,uBACvD,IAAKH,EACH,OAAAI,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMC,iBAAkB,MAGxC,MAAMD,QAAaT,EAAIW,OACjBC,EAAiBX,QAAeS,EAAAA,iBAAiBD,EAAMN,EAAWF,EAAOY,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BV,SACxB,IAAIY,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLN,KAAMA,EAAKI,OAASI,KAAKC,MAAMT,GAAQ,KACvCC,iBAAkBE,EAEtB"}
@@ -1,15 +1,6 @@
1
- import type {NextApiRequest} from 'next'
2
1
  import type {NextRequest} from 'next/server'
3
- import type {PageConfig} from 'next/types'
4
2
  import type {SanityDocument} from '@sanity/types'
5
3
 
6
- /**
7
- * Configurates the API function with the right runtime and body parsing to handle Sanity Webhook events.
8
- * @public
9
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
10
- */
11
- export declare const config: PageConfig
12
-
13
4
  /**
14
5
  * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries
15
6
  * without worrying about getting stale data.
@@ -21,18 +12,6 @@ export declare function parseBody<Body = SanityDocument>(
21
12
  waitForContentLakeEventualConsistency?: boolean,
22
13
  ): Promise<ParsedBody<Body>>
23
14
 
24
- /**
25
- * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries
26
- * without worrying about getting stale data.
27
- * @public
28
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
29
- */
30
- export declare function parseBody<Body = SanityDocument>(
31
- req: NextApiRequest,
32
- secret?: string,
33
- waitForContentLakeEventualConsistency?: boolean,
34
- ): Promise<ParsedBody<Body>>
35
-
36
15
  /** @public */
37
16
  export declare type ParsedBody<T> = {
38
17
  /**
package/dist/webhook.d.ts CHANGED
@@ -1,15 +1,6 @@
1
- import type {NextApiRequest} from 'next'
2
1
  import type {NextRequest} from 'next/server'
3
- import type {PageConfig} from 'next/types'
4
2
  import type {SanityDocument} from '@sanity/types'
5
3
 
6
- /**
7
- * Configurates the API function with the right runtime and body parsing to handle Sanity Webhook events.
8
- * @public
9
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
10
- */
11
- export declare const config: PageConfig
12
-
13
4
  /**
14
5
  * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries
15
6
  * without worrying about getting stale data.
@@ -21,18 +12,6 @@ export declare function parseBody<Body = SanityDocument>(
21
12
  waitForContentLakeEventualConsistency?: boolean,
22
13
  ): Promise<ParsedBody<Body>>
23
14
 
24
- /**
25
- * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries
26
- * without worrying about getting stale data.
27
- * @public
28
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
29
- */
30
- export declare function parseBody<Body = SanityDocument>(
31
- req: NextApiRequest,
32
- secret?: string,
33
- waitForContentLakeEventualConsistency?: boolean,
34
- ): Promise<ParsedBody<Body>>
35
-
36
15
  /** @public */
37
16
  export declare type ParsedBody<T> = {
38
17
  /**
package/dist/webhook.js CHANGED
@@ -1 +1 @@
1
- import{isValidSignature as e,SIGNATURE_HEADER_NAME as r}from"@sanity/webhook";const n={api:{bodyParser:!1},runtime:"nodejs"};async function t(n,t,i=!0){return"text"in n?async function(n,t,i=!0){const a=n.headers.get(r);if(!a)return console.error("Missing signature header"),{body:null,isValidSignature:null};const o=await n.text(),s=t?await e(o,a,t.trim()):null;return!1!==s&&i&&await new Promise((e=>setTimeout(e,3e3))),{body:o.trim()?JSON.parse(o):null,isValidSignature:s}}(n,t,i):async function(n,t,i=!0){let a=n.headers[r];if(Array.isArray(a)&&(a=a[0]),!a)return console.error("Missing signature header"),{body:null,isValidSignature:null};if(n.readableEnded)throw new Error("Request already ended and the POST body can't be read. Have you setup `export {config} from 'next-sanity/webhook' in your webhook API handler?`");const o=await async function(e){const r=[];for await(const n of e)r.push("string"==typeof n?Buffer.from(n):n);return Buffer.concat(r).toString("utf8")}(n),s=t?await e(o,a,t.trim()):null;return!1!==s&&i&&await new Promise((e=>setTimeout(e,1e3))),{body:o.trim()?JSON.parse(o):null,isValidSignature:s}}(n,t,i)}export{n as config,t as parseBody};//# sourceMappingURL=webhook.js.map
1
+ import{SIGNATURE_HEADER_NAME as e,isValidSignature as t}from"@sanity/webhook";async function i(i,r,n=!0){const a=i.headers.get(e);if(!a)return console.error("Missing signature header"),{body:null,isValidSignature:null};const o=await i.text(),s=r?await t(o,a,r.trim()):null;return!1!==s&&n&&await new Promise((e=>setTimeout(e,3e3))),{body:o.trim()?JSON.parse(o):null,isValidSignature:s}}export{i as parseBody};//# sourceMappingURL=webhook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.js","sources":["../src/webhook/index.ts"],"sourcesContent":["import type {SanityDocument} from '@sanity/types'\nimport {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'\nimport type {NextApiRequest} from 'next'\nimport type {NextRequest} from 'next/server'\nimport type {PageConfig} from 'next/types'\n\n/**\n * Configurates the API function with the right runtime and body parsing to handle Sanity Webhook events.\n * @public\n * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.\n */\nexport const config: PageConfig = {\n api: {\n /**\n * Next.js will by default parse the body, which can lead to invalid signatures.\n */\n bodyParser: false,\n },\n runtime: 'nodejs',\n}\n\n/** @public */\nexport type ParsedBody<T> = {\n /**\n * If a secret is given then it returns a boolean. If no secret is provided then no validation is done on the signature, and it'll return `null`\n */\n isValidSignature: boolean | null\n body: T | null\n}\n\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency?: boolean,\n): Promise<ParsedBody<Body>>\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency?: boolean,\n): Promise<ParsedBody<Body>>\n// eslint-disable-next-line require-await\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest | NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n return 'text' in req\n ? parseAppBody(req, secret, waitForContentLakeEventualConsistency)\n : parsePageBody(req, secret, waitForContentLakeEventualConsistency)\n}\n\n/** @deprecated */\nasync function parsePageBody<Body = SanityDocument>(\n req: NextApiRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n let signature = req.headers[SIGNATURE_HEADER_NAME]\n if (Array.isArray(signature)) {\n signature = signature[0]\n }\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n if (req.readableEnded) {\n throw new Error(\n `Request already ended and the POST body can't be read. Have you setup \\`export {config} from 'next-sanity/webhook' in your webhook API handler?\\``,\n )\n }\n\n const body = await readBody(req)\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 1000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n\nasync function parseAppBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency: boolean = true,\n): Promise<ParsedBody<Body>> {\n const signature = req.headers.get(SIGNATURE_HEADER_NAME)!\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n const body = await req.text()\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 3000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n\nasync function readBody(readable: NextApiRequest): Promise<string> {\n const chunks = []\n for await (const chunk of readable) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks).toString('utf8')\n}\n"],"names":["isValidSignature","SIGNATURE_HEADER_NAME","config","api","bodyParser","runtime","async","parseBody","req","secret","waitForContentLakeEventualConsistency","signature","headers","get","console","error","body","text","validSignature","trim","Promise","resolve","setTimeout","JSON","parse","parseAppBody","Array","isArray","readableEnded","Error","readable","chunks","chunk","push","Buffer","from","concat","toString","readBody","parsePageBody"],"mappings":"2BAWOA,2BAAAC,MAAA,kBAAA,MAAMC,EAAqB,CAChCC,IAAK,CAIHC,YAAY,GAEdC,QAAS,UAkCXC,eAAsBC,EACpBC,EACAC,EACAC,GAAiD,GAE1C,MAAA,SAAUF,EAuCnBF,eACEE,EACAC,EACAC,GAAiD,GAEjD,MAAMC,EAAYH,EAAII,QAAQC,IAAIZ,GAClC,IAAKU,EACH,OAAAG,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMhB,iBAAkB,MAGxC,MAAMgB,QAAaR,EAAIS,OACjBC,EAAiBT,QAAeT,EAAiBgB,EAAML,EAAWF,EAAOU,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BR,SACxB,IAAIU,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLL,KAAMA,EAAKG,OAASI,KAAKC,MAAMR,GAAQ,KACvChB,iBAAkBkB,EAEtB,CA5DMO,CAAajB,EAAKC,EAAQC,GAKhCJ,eACEE,EACAC,EACAC,GAAiD,GAE7C,IAAAC,EAAYH,EAAII,QAAQX,GACxB,GAAAyB,MAAMC,QAAQhB,KAChBA,EAAYA,EAAU,KAEnBA,EACH,OAAAG,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMhB,iBAAkB,MAGxC,GAAIQ,EAAIoB,cACN,MAAM,IAAIC,MACR,mJAIJ,MAAMb,QAqCRV,eAAwBwB,GACtB,MAAMC,EAAS,GACf,UAAA,MAAiBC,KAASF,EACjBC,EAAAE,KAAsB,iBAAVD,EAAqBE,OAAOC,KAAKH,GAASA,GAE/D,OAAOE,OAAOE,OAAOL,GAAQM,SAAS,OACxC,CA3CqBC,CAAS9B,GACtBU,EAAiBT,QAAeT,EAAiBgB,EAAML,EAAWF,EAAOU,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BR,SACxB,IAAIU,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLL,KAAMA,EAAKG,OAASI,KAAKC,MAAMR,GAAQ,KACvChB,iBAAkBkB,EAEtB,CAnCMqB,CAAc/B,EAAKC,EAAQC,EACjC"}
1
+ {"version":3,"file":"webhook.js","sources":["../src/webhook/index.ts"],"sourcesContent":["import type {SanityDocument} from '@sanity/types'\nimport {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'\nimport type {NextRequest} from 'next/server'\n\n/** @public */\nexport type ParsedBody<T> = {\n /**\n * If a secret is given then it returns a boolean. If no secret is provided then no validation is done on the signature, and it'll return `null`\n */\n isValidSignature: boolean | null\n body: T | null\n}\n\n/**\n * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries\n * without worrying about getting stale data.\n * @public\n */\nexport async function parseBody<Body = SanityDocument>(\n req: NextRequest,\n secret?: string,\n waitForContentLakeEventualConsistency = true,\n): Promise<ParsedBody<Body>> {\n const signature = req.headers.get(SIGNATURE_HEADER_NAME)\n if (!signature) {\n console.error('Missing signature header')\n return {body: null, isValidSignature: null}\n }\n\n const body = await req.text()\n const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null\n\n if (validSignature !== false && waitForContentLakeEventualConsistency) {\n await new Promise((resolve) => setTimeout(resolve, 3000))\n }\n\n return {\n body: body.trim() ? JSON.parse(body) : null,\n isValidSignature: validSignature,\n }\n}\n"],"names":["async","parseBody","req","secret","waitForContentLakeEventualConsistency","signature","headers","get","SIGNATURE_HEADER_NAME","console","error","body","isValidSignature","text","validSignature","trim","Promise","resolve","setTimeout","JSON","parse"],"mappings":"8EAkBAA,eAAsBC,EACpBC,EACAC,EACAC,GAAwC,GAExC,MAAMC,EAAYH,EAAII,QAAQC,IAAIC,GAClC,IAAKH,EACH,OAAAI,QAAQC,MAAM,4BACP,CAACC,KAAM,KAAMC,iBAAkB,MAGxC,MAAMD,QAAaT,EAAIW,OACjBC,EAAiBX,QAAeS,EAAiBD,EAAMN,EAAWF,EAAOY,QAAU,KAEzF,OAAuB,IAAnBD,GAA4BV,SACxB,IAAIY,SAASC,GAAYC,WAAWD,EAAS,OAG9C,CACLN,KAAMA,EAAKI,OAASI,KAAKC,MAAMT,GAAQ,KACvCC,iBAAkBE,EAEtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-sanity",
3
- "version": "8.5.5",
3
+ "version": "9.0.0",
4
4
  "description": "Sanity.io toolkit for Next.js",
5
5
  "keywords": [
6
6
  "sanity",
@@ -55,18 +55,6 @@
55
55
  "require": "./dist/studio/index.cjs",
56
56
  "default": "./dist/studio/index.js"
57
57
  },
58
- "./studio/metadata": {
59
- "source": "./src/studio/metadata.ts",
60
- "import": "./dist/studio/metadata.js",
61
- "require": "./dist/studio/metadata.cjs",
62
- "default": "./dist/studio/metadata.js"
63
- },
64
- "./studio/viewport": {
65
- "source": "./src/studio/viewport.ts",
66
- "import": "./dist/studio/viewport.js",
67
- "require": "./dist/studio/viewport.cjs",
68
- "default": "./dist/studio/viewport.js"
69
- },
70
58
  "./webhook": {
71
59
  "source": "./src/webhook/index.ts",
72
60
  "import": "./dist/webhook.js",
@@ -93,12 +81,6 @@
93
81
  "studio": [
94
82
  "./dist/studio/index.d.ts"
95
83
  ],
96
- "studio/metadata": [
97
- "./dist/studio/metadata.d.ts"
98
- ],
99
- "studio/viewport": [
100
- "./dist/studio/viewport.d.ts"
101
- ],
102
84
  "webhook": [
103
85
  "./dist/webhook.d.ts"
104
86
  ]
@@ -115,15 +97,15 @@
115
97
  "@sanity/preview-kit": "5.0.41",
116
98
  "@sanity/visual-editing": "1.8.7",
117
99
  "@sanity/webhook": "4.0.2-bc",
118
- "groq": "^3.19",
100
+ "groq": "^3.37.1",
119
101
  "history": "^5.3.0"
120
102
  },
121
103
  "devDependencies": {
122
104
  "@sanity/browserslist-config": "^1.0.3",
123
105
  "@sanity/eslint-config-studio": "^4.0.0",
124
- "@sanity/pkg-utils": "^5.1.12",
125
- "@types/react": "^18.2.74",
126
- "@typescript-eslint/eslint-plugin": "^7.5.0",
106
+ "@sanity/pkg-utils": "^6.1.0",
107
+ "@types/react": "^18.2.75",
108
+ "@typescript-eslint/eslint-plugin": "^7.6.0",
127
109
  "@vitest/coverage-v8": "^1.4.0",
128
110
  "eslint": "^8.57.0",
129
111
  "eslint-config-prettier": "^9.1.0",
@@ -141,13 +123,13 @@
141
123
  },
142
124
  "peerDependencies": {
143
125
  "@sanity/client": "^6.15.11",
144
- "@sanity/icons": "^2.8",
145
- "@sanity/types": "^3.25",
146
- "@sanity/ui": "^1.8 || ^2.0.0-beta || ^2.0",
126
+ "@sanity/icons": "^2.11.3",
127
+ "@sanity/types": "^3.37.1",
128
+ "@sanity/ui": "^2.0.11",
147
129
  "next": "^14.1",
148
130
  "react": "^18.2",
149
- "sanity": "^3.25",
150
- "styled-components": "^5.2 || ^6.0"
131
+ "sanity": "^3.37.1",
132
+ "styled-components": "^6.1"
151
133
  },
152
134
  "engines": {
153
135
  "node": ">=18.17"
@@ -1,23 +1,6 @@
1
1
  import type {SanityDocument} from '@sanity/types'
2
2
  import {isValidSignature, SIGNATURE_HEADER_NAME} from '@sanity/webhook'
3
- import type {NextApiRequest} from 'next'
4
3
  import type {NextRequest} from 'next/server'
5
- import type {PageConfig} from 'next/types'
6
-
7
- /**
8
- * Configurates the API function with the right runtime and body parsing to handle Sanity Webhook events.
9
- * @public
10
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
11
- */
12
- export const config: PageConfig = {
13
- api: {
14
- /**
15
- * Next.js will by default parse the body, which can lead to invalid signatures.
16
- */
17
- bodyParser: false,
18
- },
19
- runtime: 'nodejs',
20
- }
21
4
 
22
5
  /** @public */
23
6
  export type ParsedBody<T> = {
@@ -36,70 +19,9 @@ export type ParsedBody<T> = {
36
19
  export async function parseBody<Body = SanityDocument>(
37
20
  req: NextRequest,
38
21
  secret?: string,
39
- waitForContentLakeEventualConsistency?: boolean,
40
- ): Promise<ParsedBody<Body>>
41
- /**
42
- * Handles parsing the body JSON, and validating its signature. Also waits for Content Lake eventual consistency so you can run your queries
43
- * without worrying about getting stale data.
44
- * @public
45
- * @deprecated using `parseBody` with `NextApiRequest` is deprecated and will be removed in the next major version. Use `parseBody` with `NextRequest` instead from a Route Handler in App Router.
46
- */
47
- export async function parseBody<Body = SanityDocument>(
48
- req: NextApiRequest,
49
- secret?: string,
50
- waitForContentLakeEventualConsistency?: boolean,
51
- ): Promise<ParsedBody<Body>>
52
- // eslint-disable-next-line require-await
53
- export async function parseBody<Body = SanityDocument>(
54
- req: NextRequest | NextApiRequest,
55
- secret?: string,
56
- waitForContentLakeEventualConsistency: boolean = true,
22
+ waitForContentLakeEventualConsistency = true,
57
23
  ): Promise<ParsedBody<Body>> {
58
- return 'text' in req
59
- ? parseAppBody(req, secret, waitForContentLakeEventualConsistency)
60
- : parsePageBody(req, secret, waitForContentLakeEventualConsistency)
61
- }
62
-
63
- /** @deprecated */
64
- async function parsePageBody<Body = SanityDocument>(
65
- req: NextApiRequest,
66
- secret?: string,
67
- waitForContentLakeEventualConsistency: boolean = true,
68
- ): Promise<ParsedBody<Body>> {
69
- let signature = req.headers[SIGNATURE_HEADER_NAME]
70
- if (Array.isArray(signature)) {
71
- signature = signature[0]
72
- }
73
- if (!signature) {
74
- console.error('Missing signature header')
75
- return {body: null, isValidSignature: null}
76
- }
77
-
78
- if (req.readableEnded) {
79
- throw new Error(
80
- `Request already ended and the POST body can't be read. Have you setup \`export {config} from 'next-sanity/webhook' in your webhook API handler?\``,
81
- )
82
- }
83
-
84
- const body = await readBody(req)
85
- const validSignature = secret ? await isValidSignature(body, signature, secret.trim()) : null
86
-
87
- if (validSignature !== false && waitForContentLakeEventualConsistency) {
88
- await new Promise((resolve) => setTimeout(resolve, 1000))
89
- }
90
-
91
- return {
92
- body: body.trim() ? JSON.parse(body) : null,
93
- isValidSignature: validSignature,
94
- }
95
- }
96
-
97
- async function parseAppBody<Body = SanityDocument>(
98
- req: NextRequest,
99
- secret?: string,
100
- waitForContentLakeEventualConsistency: boolean = true,
101
- ): Promise<ParsedBody<Body>> {
102
- const signature = req.headers.get(SIGNATURE_HEADER_NAME)!
24
+ const signature = req.headers.get(SIGNATURE_HEADER_NAME)
103
25
  if (!signature) {
104
26
  console.error('Missing signature header')
105
27
  return {body: null, isValidSignature: null}
@@ -117,11 +39,3 @@ async function parseAppBody<Body = SanityDocument>(
117
39
  isValidSignature: validSignature,
118
40
  }
119
41
  }
120
-
121
- async function readBody(readable: NextApiRequest): Promise<string> {
122
- const chunks = []
123
- for await (const chunk of readable) {
124
- chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)
125
- }
126
- return Buffer.concat(chunks).toString('utf8')
127
- }
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e=require("./head.cjs").metadata;exports.metadata=e;//# sourceMappingURL=metadata.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metadata.cjs","sources":["../../src/studio/metadata.ts"],"sourcesContent":["import type {Metadata} from 'next'\n\nimport {metadata as _metadata} from './head'\n\n/**\n * @public\n * @deprecated use `export {metadata} from 'next-sanity/studio'` instead\n */\nexport const metadata = _metadata satisfies Metadata\n"],"names":["Object","defineProperty","exports","value","metadata","require","_metadata"],"mappings":"aAQOA,OAAAC,eAAAC,QAAA,aAAA,CAAAC,OAAA,IAAA,MAAMC,EAANC,QAAA,cAAiBC,SAAAA,QAAAA,SAAAA"}
@@ -1,10 +0,0 @@
1
- /**
2
- * @public
3
- * @deprecated use `export {metadata} from 'next-sanity/studio'` instead
4
- */
5
- export declare const metadata: {
6
- referrer: 'same-origin'
7
- robots: 'noindex'
8
- }
9
-
10
- export {}
@@ -1,10 +0,0 @@
1
- /**
2
- * @public
3
- * @deprecated use `export {metadata} from 'next-sanity/studio'` instead
4
- */
5
- export declare const metadata: {
6
- referrer: 'same-origin'
7
- robots: 'noindex'
8
- }
9
-
10
- export {}
@@ -1 +0,0 @@
1
- import{metadata as a}from"./head.js";const t=a;export{t as metadata};//# sourceMappingURL=metadata.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metadata.js","sources":["../../src/studio/metadata.ts"],"sourcesContent":["import type {Metadata} from 'next'\n\nimport {metadata as _metadata} from './head'\n\n/**\n * @public\n * @deprecated use `export {metadata} from 'next-sanity/studio'` instead\n */\nexport const metadata = _metadata satisfies Metadata\n"],"names":["metadata$1","metadata","_metadata"],"mappings":"mBAQOA,MAAA,YAAA,MAAMC,EAAWC"}
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e=require("./head.cjs").viewport;exports.viewport=e;//# sourceMappingURL=viewport.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"viewport.cjs","sources":["../../src/studio/viewport.ts"],"sourcesContent":["import type {Viewport} from 'next'\n\nimport {viewport as _viewport} from './head'\n\n/**\n * @public\n * @deprecated use `export {viewport} from 'next-sanity/studio'` instead\n */\nexport const viewport = _viewport satisfies Viewport\n"],"names":["Object","defineProperty","exports","value","viewport","require","_viewport"],"mappings":"aAQOA,OAAAC,eAAAC,QAAA,aAAA,CAAAC,OAAA,IAAA,MAAMC,EAANC,QAAA,cAAiBC,SAAAA,QAAAA,SAAAA"}
@@ -1,11 +0,0 @@
1
- /**
2
- * @public
3
- * @deprecated use `export {viewport} from 'next-sanity/studio'` instead
4
- */
5
- export declare const viewport: {
6
- width: string
7
- initialScale: number
8
- viewportFit: 'cover'
9
- }
10
-
11
- export {}
@@ -1,11 +0,0 @@
1
- /**
2
- * @public
3
- * @deprecated use `export {viewport} from 'next-sanity/studio'` instead
4
- */
5
- export declare const viewport: {
6
- width: string
7
- initialScale: number
8
- viewportFit: 'cover'
9
- }
10
-
11
- export {}
@@ -1 +0,0 @@
1
- import{viewport as o}from"./head.js";const r=o;export{r as viewport};//# sourceMappingURL=viewport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"viewport.js","sources":["../../src/studio/viewport.ts"],"sourcesContent":["import type {Viewport} from 'next'\n\nimport {viewport as _viewport} from './head'\n\n/**\n * @public\n * @deprecated use `export {viewport} from 'next-sanity/studio'` instead\n */\nexport const viewport = _viewport satisfies Viewport\n"],"names":["viewport$1","viewport","_viewport"],"mappings":"mBAQOA,MAAA,YAAA,MAAMC,EAAWC"}
@@ -1,9 +0,0 @@
1
- import type {Metadata} from 'next'
2
-
3
- import {metadata as _metadata} from './head'
4
-
5
- /**
6
- * @public
7
- * @deprecated use `export {metadata} from 'next-sanity/studio'` instead
8
- */
9
- export const metadata = _metadata satisfies Metadata
@@ -1,9 +0,0 @@
1
- import type {Viewport} from 'next'
2
-
3
- import {viewport as _viewport} from './head'
4
-
5
- /**
6
- * @public
7
- * @deprecated use `export {viewport} from 'next-sanity/studio'` instead
8
- */
9
- export const viewport = _viewport satisfies Viewport