sanity-plugin-iframe-pane 2.6.1 → 2.6.2-canary.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.
@@ -1,64 +0,0 @@
1
- 'use strict';
2
-
3
- var name = "sanity-plugin-iframe-pane";
4
- const SECRET_TTL = 60 * 60;
5
- const fetchSecretQuery = /* groq */
6
- "*[_id == $id && dateTime(_updatedAt) > dateTime(now()) - ".concat(SECRET_TTL, "][0]{secret, _updatedAt}");
7
- const tag = name;
8
- const apiVersion = "2023-08-08";
9
- const isDev = process.env.NODE_ENV === "development";
10
- async function isValidSecret(client, urlSecretId, urlSecret) {
11
- if (!urlSecret) {
12
- throw new TypeError("`urlSecret` is required");
13
- }
14
- if (!urlSecretId) {
15
- throw new TypeError("`urlSecretId` is required");
16
- }
17
- if (!urlSecretId.includes(".")) {
18
- throw new TypeError("`urlSecretId` must have a dot prefix, `".concat(urlSecretId, "` is not secure, add a prefix, for example `preview.").concat(urlSecretId, "` "));
19
- }
20
- if (!client) {
21
- throw new TypeError("`client` is required");
22
- }
23
- if (!client.config().token) {
24
- throw new TypeError("`client` must have a `token` specified");
25
- }
26
- if (typeof EdgeRuntime !== "undefined") {
27
- await new Promise(resolve => setTimeout(resolve, 300));
28
- }
29
- const customClient = client.withConfig({
30
- apiVersion,
31
- useCdn: false,
32
- perspective: "raw",
33
- resultSourceMap: false
34
- });
35
- const data = await customClient.fetch(fetchSecretQuery, {
36
- id: urlSecretId
37
- },
38
- // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed
39
- {
40
- cache: "no-store",
41
- tag
42
- });
43
- if (!(data == null ? void 0 : data.secret) && isDev) {
44
- const exists = await client.fetch( /* groq */
45
- "*[_id == $id][0]", {
46
- id: urlSecretId
47
- },
48
- // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed
49
- {
50
- cache: "no-store",
51
- tag
52
- });
53
- if (!exists) {
54
- throw new TypeError("Unable to find a secret in the dataset, with the id `".concat(urlSecretId, "`. Have you set the `urlSecretId` option in your `Iframe` and `previewUrl` configurations?"));
55
- }
56
- }
57
- return (data == null ? void 0 : data.secret) === urlSecret;
58
- }
59
- exports.SECRET_TTL = SECRET_TTL;
60
- exports.apiVersion = apiVersion;
61
- exports.fetchSecretQuery = fetchSecretQuery;
62
- exports.isValidSecret = isValidSecret;
63
- exports.tag = tag;
64
- //# sourceMappingURL=is-valid-secret-VKMJU99B.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-valid-secret-VKMJU99B.cjs","sources":["../../src/isValidSecret.tsx"],"sourcesContent":["import {name} from '../package.json'\n\nexport type UrlSecretId = `${string}.${string}`\n\n// updated within the hour, if it's older it'll create a new secret or return null\nexport const SECRET_TTL = 60 * 60\n\nexport const fetchSecretQuery = /* groq */ `*[_id == $id && dateTime(_updatedAt) > dateTime(now()) - ${SECRET_TTL}][0]{secret, _updatedAt}`\nexport type FetchSecretResponse = {\n secret: string | null\n _updatedAt: string | null\n} | null\n\nexport const tag = name\n\nexport const apiVersion = '2023-08-08'\n\nexport type SanityClientLike = {\n config(): {token?: string}\n withConfig(config: {\n apiVersion?: string\n useCdn?: boolean\n perspective: 'raw'\n resultSourceMap: boolean\n }): SanityClientLike\n fetch<\n R,\n Q = {\n [key: string]: any\n },\n >(\n query: string,\n params: Q,\n options: {tag?: string},\n ): Promise<R>\n}\n\nconst isDev = process.env.NODE_ENV === 'development'\n\nexport async function isValidSecret(\n client: SanityClientLike,\n urlSecretId: UrlSecretId,\n urlSecret: string,\n): Promise<boolean> {\n if (!urlSecret) {\n throw new TypeError('`urlSecret` is required')\n }\n if (!urlSecretId) {\n throw new TypeError('`urlSecretId` is required')\n }\n if (!urlSecretId.includes('.')) {\n throw new TypeError(\n `\\`urlSecretId\\` must have a dot prefix, \\`${urlSecretId}\\` is not secure, add a prefix, for example \\`preview.${urlSecretId}\\` `,\n )\n }\n if (!client) {\n throw new TypeError('`client` is required')\n }\n if (!client.config().token) {\n throw new TypeError('`client` must have a `token` specified')\n }\n\n // If we're in the Edge Runtime it's usually too quick and we need to delay fetching the secret a little bit\n // eslint-disable-next-line no-warning-comments\n // @ts-expect-error -- @TODO add typings for EdgeRuntime\n if (typeof EdgeRuntime !== 'undefined') {\n await new Promise((resolve) => setTimeout(resolve, 300))\n }\n\n const customClient = client.withConfig({\n apiVersion,\n useCdn: false,\n perspective: 'raw',\n resultSourceMap: false,\n })\n const data = await customClient.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed\n {cache: 'no-store', tag},\n )\n // eslint-disable-next-line no-process-env\n if (!data?.secret && isDev) {\n const exists = await client.fetch<null | Record<string, any>>(\n /* groq */ `*[_id == $id][0]`,\n {id: urlSecretId},\n // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed\n {cache: 'no-store', tag},\n )\n if (!exists) {\n throw new TypeError(\n `Unable to find a secret in the dataset, with the id \\`${urlSecretId}\\`. Have you set the \\`urlSecretId\\` option in your \\`Iframe\\` and \\`previewUrl\\` configurations?`,\n )\n }\n }\n\n return data?.secret === urlSecret\n}\n"],"names":["SECRET_TTL","fetchSecretQuery","concat","tag","name","apiVersion","isDev","process","env","NODE_ENV","isValidSecret","client","urlSecretId","urlSecret","TypeError","includes","config","token","EdgeRuntime","Promise","resolve","setTimeout","customClient","withConfig","useCdn","perspective","resultSourceMap","data","fetch","id","cache","secret","exists"],"mappings":";;;AAKO,MAAMA,aAAa,EAAK,GAAA,EAAA;AAElB,MAAAC,gBAAA,GAAA;AAA8B,4DAA4DC,MAAU,CAAAF,UAAA,EAAA,0BAAA,CAAA;AAM1G,MAAMG,GAAM,GAAAC,IAAA;AAEZ,MAAMC,UAAa,GAAA,YAAA;AAsB1B,MAAMC,KAAA,GAAQC,OAAQ,CAAAC,GAAA,CAAIC,QAAa,KAAA,aAAA;AAEjB,eAAAC,aAAAA,CACpBC,MACA,EAAAC,WAAA,EACAC,SACkB,EAAA;EAClB,IAAI,CAACA,SAAW,EAAA;IACR,MAAA,IAAIC,UAAU,yBAAyB,CAAA;EAC/C;EACA,IAAI,CAACF,WAAa,EAAA;IACV,MAAA,IAAIE,UAAU,2BAA2B,CAAA;EACjD;EACA,IAAI,CAACF,WAAA,CAAYG,QAAS,CAAA,GAAG,CAAG,EAAA;IAC9B,MAAM,IAAID,SAAA,CACR,yCAAA,CAA6CZ,MAAW,CAAAU,WAAA,EAAA,sDAAA,CAAA,CAAyDV,MAAW,CAAAU,WAAA,EAAA,IAAA,CAAA,CAC9H;EACF;EACA,IAAI,CAACD,MAAQ,EAAA;IACL,MAAA,IAAIG,UAAU,sBAAsB,CAAA;EAC5C;EACA,IAAI,CAACH,MAAA,CAAOK,MAAO,CAAA,CAAA,CAAEC,KAAO,EAAA;IACpB,MAAA,IAAIH,UAAU,wCAAwC,CAAA;EAC9D;EAKI,IAAA,OAAOI,gBAAgB,WAAa,EAAA;IACtC,MAAM,IAAIC,OAAQ,CAACC,WAAYC,UAAW,CAAAD,OAAA,EAAS,GAAG,CAAC,CAAA;EACzD;EAEM,MAAAE,YAAA,GAAeX,OAAOY,UAAW,CAAA;IACrClB,UAAA;IACAmB,MAAQ,EAAA,KAAA;IACRC,WAAa,EAAA,KAAA;IACbC,eAAiB,EAAA;EAAA,CAClB,CAAA;EACK,MAAAC,IAAA,GAAO,MAAML,YAAa,CAAAM,KAAA,CAC9B3B,gBAAA,EACA;IAAC4B,IAAIjB;EAAW,CAAA;EAAA;EAEhB;IAACkB,KAAO,EAAA,UAAA;IAAY3B;EAAG,CAAA,CACzB;EAEI,IAAA,EAACwB,IAAM,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAA,CAAAI,MAAA,CAAA,IAAUzB,KAAO,EAAA;IACpB,MAAA0B,MAAA,GAAS,MAAMrB,MAAO,CAAAiB,KAAA,EAAA;IACf,kBAAA,EACX;MAACC,IAAIjB;IAAW,CAAA;IAAA;IAEhB;MAACkB,KAAO,EAAA,UAAA;MAAY3B;IAAG,CAAA,CACzB;IACA,IAAI,CAAC6B,MAAQ,EAAA;MACX,MAAM,IAAIlB,SAAA,CACR,wDAAyDZ,MAAW,CAAAU,WAAA,EAAA,4FAAA,CAAA,CACtE;IACF;EACF;EAEA,OAAA,CAAOe,6BAAMI,MAAW,MAAAlB,SAAA;AAC1B;;;;;"}
@@ -1,58 +0,0 @@
1
- var name = "sanity-plugin-iframe-pane";
2
- const SECRET_TTL = 60 * 60;
3
- const fetchSecretQuery = /* groq */
4
- "*[_id == $id && dateTime(_updatedAt) > dateTime(now()) - ".concat(SECRET_TTL, "][0]{secret, _updatedAt}");
5
- const tag = name;
6
- const apiVersion = "2023-08-08";
7
- const isDev = process.env.NODE_ENV === "development";
8
- async function isValidSecret(client, urlSecretId, urlSecret) {
9
- if (!urlSecret) {
10
- throw new TypeError("`urlSecret` is required");
11
- }
12
- if (!urlSecretId) {
13
- throw new TypeError("`urlSecretId` is required");
14
- }
15
- if (!urlSecretId.includes(".")) {
16
- throw new TypeError("`urlSecretId` must have a dot prefix, `".concat(urlSecretId, "` is not secure, add a prefix, for example `preview.").concat(urlSecretId, "` "));
17
- }
18
- if (!client) {
19
- throw new TypeError("`client` is required");
20
- }
21
- if (!client.config().token) {
22
- throw new TypeError("`client` must have a `token` specified");
23
- }
24
- if (typeof EdgeRuntime !== "undefined") {
25
- await new Promise(resolve => setTimeout(resolve, 300));
26
- }
27
- const customClient = client.withConfig({
28
- apiVersion,
29
- useCdn: false,
30
- perspective: "raw",
31
- resultSourceMap: false
32
- });
33
- const data = await customClient.fetch(fetchSecretQuery, {
34
- id: urlSecretId
35
- },
36
- // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed
37
- {
38
- cache: "no-store",
39
- tag
40
- });
41
- if (!(data == null ? void 0 : data.secret) && isDev) {
42
- const exists = await client.fetch( /* groq */
43
- "*[_id == $id][0]", {
44
- id: urlSecretId
45
- },
46
- // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed
47
- {
48
- cache: "no-store",
49
- tag
50
- });
51
- if (!exists) {
52
- throw new TypeError("Unable to find a secret in the dataset, with the id `".concat(urlSecretId, "`. Have you set the `urlSecretId` option in your `Iframe` and `previewUrl` configurations?"));
53
- }
54
- }
55
- return (data == null ? void 0 : data.secret) === urlSecret;
56
- }
57
- export { SECRET_TTL, apiVersion, fetchSecretQuery, isValidSecret, tag };
58
- //# sourceMappingURL=is-valid-secret-zi24WaHG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-valid-secret-zi24WaHG.js","sources":["../../src/isValidSecret.tsx"],"sourcesContent":["import {name} from '../package.json'\n\nexport type UrlSecretId = `${string}.${string}`\n\n// updated within the hour, if it's older it'll create a new secret or return null\nexport const SECRET_TTL = 60 * 60\n\nexport const fetchSecretQuery = /* groq */ `*[_id == $id && dateTime(_updatedAt) > dateTime(now()) - ${SECRET_TTL}][0]{secret, _updatedAt}`\nexport type FetchSecretResponse = {\n secret: string | null\n _updatedAt: string | null\n} | null\n\nexport const tag = name\n\nexport const apiVersion = '2023-08-08'\n\nexport type SanityClientLike = {\n config(): {token?: string}\n withConfig(config: {\n apiVersion?: string\n useCdn?: boolean\n perspective: 'raw'\n resultSourceMap: boolean\n }): SanityClientLike\n fetch<\n R,\n Q = {\n [key: string]: any\n },\n >(\n query: string,\n params: Q,\n options: {tag?: string},\n ): Promise<R>\n}\n\nconst isDev = process.env.NODE_ENV === 'development'\n\nexport async function isValidSecret(\n client: SanityClientLike,\n urlSecretId: UrlSecretId,\n urlSecret: string,\n): Promise<boolean> {\n if (!urlSecret) {\n throw new TypeError('`urlSecret` is required')\n }\n if (!urlSecretId) {\n throw new TypeError('`urlSecretId` is required')\n }\n if (!urlSecretId.includes('.')) {\n throw new TypeError(\n `\\`urlSecretId\\` must have a dot prefix, \\`${urlSecretId}\\` is not secure, add a prefix, for example \\`preview.${urlSecretId}\\` `,\n )\n }\n if (!client) {\n throw new TypeError('`client` is required')\n }\n if (!client.config().token) {\n throw new TypeError('`client` must have a `token` specified')\n }\n\n // If we're in the Edge Runtime it's usually too quick and we need to delay fetching the secret a little bit\n // eslint-disable-next-line no-warning-comments\n // @ts-expect-error -- @TODO add typings for EdgeRuntime\n if (typeof EdgeRuntime !== 'undefined') {\n await new Promise((resolve) => setTimeout(resolve, 300))\n }\n\n const customClient = client.withConfig({\n apiVersion,\n useCdn: false,\n perspective: 'raw',\n resultSourceMap: false,\n })\n const data = await customClient.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed\n {cache: 'no-store', tag},\n )\n // eslint-disable-next-line no-process-env\n if (!data?.secret && isDev) {\n const exists = await client.fetch<null | Record<string, any>>(\n /* groq */ `*[_id == $id][0]`,\n {id: urlSecretId},\n // @ts-expect-error -- the `cache` option is valid, but not in the types when NextJS typings aren't installed\n {cache: 'no-store', tag},\n )\n if (!exists) {\n throw new TypeError(\n `Unable to find a secret in the dataset, with the id \\`${urlSecretId}\\`. Have you set the \\`urlSecretId\\` option in your \\`Iframe\\` and \\`previewUrl\\` configurations?`,\n )\n }\n }\n\n return data?.secret === urlSecret\n}\n"],"names":["SECRET_TTL","fetchSecretQuery","concat","tag","name","apiVersion","isDev","process","env","NODE_ENV","isValidSecret","client","urlSecretId","urlSecret","TypeError","includes","config","token","EdgeRuntime","Promise","resolve","setTimeout","customClient","withConfig","useCdn","perspective","resultSourceMap","data","fetch","id","cache","secret","exists"],"mappings":";AAKO,MAAMA,aAAa,EAAK,GAAA,EAAA;AAElB,MAAAC,gBAAA,GAAA;AAA8B,4DAA4DC,MAAU,CAAAF,UAAA,EAAA,0BAAA,CAAA;AAM1G,MAAMG,GAAM,GAAAC,IAAA;AAEZ,MAAMC,UAAa,GAAA,YAAA;AAsB1B,MAAMC,KAAA,GAAQC,OAAQ,CAAAC,GAAA,CAAIC,QAAa,KAAA,aAAA;AAEjB,eAAAC,aAAAA,CACpBC,MACA,EAAAC,WAAA,EACAC,SACkB,EAAA;EAClB,IAAI,CAACA,SAAW,EAAA;IACR,MAAA,IAAIC,UAAU,yBAAyB,CAAA;EAC/C;EACA,IAAI,CAACF,WAAa,EAAA;IACV,MAAA,IAAIE,UAAU,2BAA2B,CAAA;EACjD;EACA,IAAI,CAACF,WAAA,CAAYG,QAAS,CAAA,GAAG,CAAG,EAAA;IAC9B,MAAM,IAAID,SAAA,CACR,yCAAA,CAA6CZ,MAAW,CAAAU,WAAA,EAAA,sDAAA,CAAA,CAAyDV,MAAW,CAAAU,WAAA,EAAA,IAAA,CAAA,CAC9H;EACF;EACA,IAAI,CAACD,MAAQ,EAAA;IACL,MAAA,IAAIG,UAAU,sBAAsB,CAAA;EAC5C;EACA,IAAI,CAACH,MAAA,CAAOK,MAAO,CAAA,CAAA,CAAEC,KAAO,EAAA;IACpB,MAAA,IAAIH,UAAU,wCAAwC,CAAA;EAC9D;EAKI,IAAA,OAAOI,gBAAgB,WAAa,EAAA;IACtC,MAAM,IAAIC,OAAQ,CAACC,WAAYC,UAAW,CAAAD,OAAA,EAAS,GAAG,CAAC,CAAA;EACzD;EAEM,MAAAE,YAAA,GAAeX,OAAOY,UAAW,CAAA;IACrClB,UAAA;IACAmB,MAAQ,EAAA,KAAA;IACRC,WAAa,EAAA,KAAA;IACbC,eAAiB,EAAA;EAAA,CAClB,CAAA;EACK,MAAAC,IAAA,GAAO,MAAML,YAAa,CAAAM,KAAA,CAC9B3B,gBAAA,EACA;IAAC4B,IAAIjB;EAAW,CAAA;EAAA;EAEhB;IAACkB,KAAO,EAAA,UAAA;IAAY3B;EAAG,CAAA,CACzB;EAEI,IAAA,EAACwB,IAAM,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAA,CAAAI,MAAA,CAAA,IAAUzB,KAAO,EAAA;IACpB,MAAA0B,MAAA,GAAS,MAAMrB,MAAO,CAAAiB,KAAA,EAAA;IACf,kBAAA,EACX;MAACC,IAAIjB;IAAW,CAAA;IAAA;IAEhB;MAACkB,KAAO,EAAA,UAAA;MAAY3B;IAAG,CAAA,CACzB;IACA,IAAI,CAAC6B,MAAQ,EAAA;MACX,MAAM,IAAIlB,SAAA,CACR,wDAAyDZ,MAAW,CAAAU,WAAA,EAAA,4FAAA,CAAA,CACtE;IACF;EACF;EAEA,OAAA,CAAOe,6BAAMI,MAAW,MAAAlB,SAAA;AAC1B;"}
@@ -1,61 +0,0 @@
1
- 'use strict';
2
-
3
- var isValidSecret = require('./is-valid-secret-VKMJU99B.cjs');
4
- const MissingSlug = Symbol("MissingSlug");
5
- function defineUrlResolver(options) {
6
- const {
7
- base,
8
- requiresSlug = []
9
- } = options;
10
- return (document, urlSecret) => {
11
- var _a;
12
- const url = new URL(base, location.origin);
13
- url.searchParams.set("type", document._type);
14
- url.searchParams.set("id", document._id);
15
- const slug = (_a = document == null ? void 0 : document.slug) == null ? void 0 : _a.current;
16
- if (slug) {
17
- url.searchParams.set("slug", slug);
18
- } else if (requiresSlug.includes(document._type)) {
19
- return MissingSlug;
20
- }
21
- if (urlSecret) {
22
- url.searchParams.set("secret", urlSecret);
23
- }
24
- return url.toString();
25
- };
26
- }
27
- function getExpiresAt(_updatedAt) {
28
- return new Date(_updatedAt.getTime() + 1e3 * isValidSecret.SECRET_TTL);
29
- }
30
- function generateUrlSecret() {
31
- if (typeof crypto !== "undefined") {
32
- const array = new Uint8Array(16);
33
- crypto.getRandomValues(array);
34
- let key = "";
35
- for (let i = 0; i < array.length; i++) {
36
- key += array[i].toString(16).padStart(2, "0");
37
- }
38
- key = btoa(key).replace(/\+/g, "-").replace(/\//g, "_").replace(/[=]+$/, "");
39
- return key;
40
- }
41
- return Math.random().toString(36).slice(2);
42
- }
43
- async function patchUrlSecret(client, urlSecretId, signal) {
44
- const newSecret = generateUrlSecret();
45
- const patch = client.patch(urlSecretId).set({
46
- secret: newSecret
47
- });
48
- await client.transaction().createIfNotExists({
49
- _id: urlSecretId,
50
- _type: urlSecretId
51
- }).patch(patch).commit({
52
- tag: isValidSecret.tag,
53
- signal
54
- });
55
- return newSecret;
56
- }
57
- exports.MissingSlug = MissingSlug;
58
- exports.defineUrlResolver = defineUrlResolver;
59
- exports.getExpiresAt = getExpiresAt;
60
- exports.patchUrlSecret = patchUrlSecret;
61
- //# sourceMappingURL=utils-HbzA_NjI.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-HbzA_NjI.cjs","sources":["../../src/types.ts","../../src/defineUrlResolver.tsx","../../src/utils.ts"],"sourcesContent":["export const MissingSlug = Symbol('MissingSlug')\n\nexport type UrlState = string | typeof MissingSlug\n\nexport type IframeSizeKey = keyof SizeProps\n\nexport type Size = 'desktop' | 'mobile'\n\nexport type SizeProps = {\n // eslint-disable-next-line no-unused-vars\n [key in Size]: {\n width: string | number\n height: string | number\n }\n}\n\nexport type SetError = (error: unknown) => void\n","import type {SanityDocument} from 'sanity'\n\nimport {MissingSlug, UrlState} from './types'\n\nexport type {UrlState}\n\nexport type UrlResolver = (\n document: SanityDocument,\n urlSecret: string | null | undefined,\n signal?: AbortSignal,\n) => UrlState | Promise<UrlState>\n\nexport interface DefineUrlResolverOptions {\n base: string | URL\n requiresSlug?: string[]\n}\nexport function defineUrlResolver(options: DefineUrlResolverOptions): UrlResolver {\n const {base, requiresSlug = []} = options\n return (document, urlSecret) => {\n const url = new URL(base, location.origin)\n url.searchParams.set('type', document._type)\n url.searchParams.set('id', document._id)\n const slug = (document?.slug as any)?.current\n if (slug) {\n url.searchParams.set('slug', slug)\n } else if (requiresSlug.includes(document._type)) {\n return MissingSlug\n }\n if (urlSecret) {\n url.searchParams.set('secret', urlSecret)\n }\n return url.toString()\n }\n}\n","import type {SanityClient} from 'sanity'\n\nimport {SECRET_TTL, tag, UrlSecretId} from './isValidSecret'\n\nexport function getExpiresAt(_updatedAt: Date) {\n return new Date(_updatedAt.getTime() + 1000 * SECRET_TTL)\n}\n\nfunction generateUrlSecret() {\n // Try using WebCrypto if available\n if (typeof crypto !== 'undefined') {\n // Generate a random array of 16 bytes\n const array = new Uint8Array(16)\n crypto.getRandomValues(array)\n\n // Convert the array to a URL-safe string\n let key = ''\n for (let i = 0; i < array.length; i++) {\n // Convert each byte to a 2-digit hexadecimal number\n key += array[i].toString(16).padStart(2, '0')\n }\n\n // Replace '+' and '/' from base64url to '-' and '_'\n key = btoa(key).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/[=]+$/, '')\n\n return key\n }\n // If not fallback to Math.random\n return Math.random().toString(36).slice(2)\n}\n\nexport async function patchUrlSecret(\n client: SanityClient,\n urlSecretId: UrlSecretId,\n signal?: AbortSignal,\n): Promise<string> {\n const newSecret = generateUrlSecret()\n const patch = client.patch(urlSecretId).set({secret: newSecret})\n await client\n .transaction()\n .createIfNotExists({_id: urlSecretId, _type: urlSecretId})\n .patch(patch)\n .commit({tag, signal})\n return newSecret\n}\n"],"names":["MissingSlug","Symbol","defineUrlResolver","options","base","requiresSlug","document","urlSecret","_a","url","URL","location","origin","searchParams","set","_type","_id","slug","current","includes","toString","getExpiresAt","_updatedAt","Date","getTime","SECRET_TTL","generateUrlSecret","crypto","array","Uint8Array","getRandomValues","key","i","length","padStart","btoa","replace","Math","random","slice","patchUrlSecret","client","urlSecretId","signal","newSecret","patch","secret","transaction","createIfNotExists","commit","tag"],"mappings":";;;AAAa,MAAAA,WAAA,GAAcC,OAAO,aAAa,CAAA;ACgBxC,SAASC,kBAAkBC,OAAgD,EAAA;EAChF,MAAM;IAACC,IAAA;IAAMC,YAAe,GAAA;GAAM,GAAAF,OAAA;EAC3B,OAAA,CAACG,UAAUC,SAAc,KAAA;IAlBlC,IAAAC,EAAA;IAmBI,MAAMC,GAAM,GAAA,IAAIC,GAAI,CAAAN,IAAA,EAAMO,SAASC,MAAM,CAAA;IACzCH,GAAA,CAAII,YAAa,CAAAC,GAAA,CAAI,MAAQ,EAAAR,QAAA,CAASS,KAAK,CAAA;IAC3CN,GAAA,CAAII,YAAa,CAAAC,GAAA,CAAI,IAAM,EAAAR,QAAA,CAASU,GAAG,CAAA;IACjC,MAAAC,IAAA,GAAA,CAAQT,EAAU,GAAAF,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,QAAA,CAAAW,IAAA,KAAV,IAAwB,GAAA,KAAA,CAAA,GAAAT,EAAA,CAAAU,OAAA;IACtC,IAAID,IAAM,EAAA;MACJR,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,MAAA,EAAQG,IAAI,CAAA;IACxB,CAAA,MAAA,IAAAZ,YAAA,CAAac,QAAS,CAAAb,QAAA,CAASS,KAAK,CAAG,EAAA;MACzC,OAAAf,WAAA;IACT;IACA,IAAIO,SAAW,EAAA;MACTE,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,QAAA,EAAUP,SAAS,CAAA;IAC1C;IACA,OAAOE,IAAIW,QAAS,EAAA;EAAA,CACtB;AACF;AC7BO,SAASC,aAAaC,UAAkB,EAAA;EAC7C,OAAO,IAAIC,IAAK,CAAAD,UAAA,CAAWE,OAAQ,CAAA,CAAA,GAAI,MAAOC,aAAAA,CAAAA,UAAU,CAAA;AAC1D;AAEA,SAASC,iBAAoBA,CAAA,EAAA;EAEvB,IAAA,OAAOC,WAAW,WAAa,EAAA;IAE3B,MAAAC,KAAA,GAAQ,IAAIC,UAAA,CAAW,EAAE,CAAA;IAC/BF,MAAA,CAAOG,gBAAgBF,KAAK,CAAA;IAG5B,IAAIG,GAAM,GAAA,EAAA;IACV,KAAA,IAASC,CAAI,GAAA,CAAA,EAAGA,CAAI,GAAAJ,KAAA,CAAMK,QAAQD,CAAK,EAAA,EAAA;MAE9BD,GAAA,IAAAH,KAAA,CAAMI,CAAC,CAAE,CAAAZ,QAAA,CAAS,EAAE,CAAE,CAAAc,QAAA,CAAS,GAAG,GAAG,CAAA;IAC9C;IAGAH,GAAA,GAAMI,IAAK,CAAAJ,GAAG,CAAE,CAAAK,OAAA,CAAQ,KAAO,EAAA,GAAG,CAAE,CAAAA,OAAA,CAAQ,KAAO,EAAA,GAAG,CAAE,CAAAA,OAAA,CAAQ,SAAS,EAAE,CAAA;IAEpE,OAAAL,GAAA;EACT;EAEA,OAAOM,KAAKC,MAAO,EAAA,CAAElB,SAAS,EAAE,CAAA,CAAEmB,MAAM,CAAC,CAAA;AAC3C;AAEsB,eAAAC,cAAAA,CACpBC,MACA,EAAAC,WAAA,EACAC,MACiB,EAAA;EACjB,MAAMC,YAAYlB,iBAAkB,EAAA;EAC9B,MAAAmB,KAAA,GAAQJ,OAAOI,KAAM,CAAAH,WAAW,EAAE5B,GAAI,CAAA;IAACgC,MAAQ,EAAAF;EAAA,CAAU,CAAA;EAC/D,MAAMH,OACHM,WAAY,EAAA,CACZC,kBAAkB;IAAChC,GAAA,EAAK0B;IAAa3B,KAAO,EAAA2B;EAAY,CAAA,CAAA,CACxDG,MAAMA,KAAK,CAAA,CACXI,OAAO;IAAAC,GAAA,EAACA,aAAA,CAAAA,GAAA;IAAKP;GAAO,CAAA;EAChB,OAAAC,SAAA;AACT;;;;"}
@@ -1,56 +0,0 @@
1
- import { tag, SECRET_TTL } from './is-valid-secret-zi24WaHG.js';
2
- const MissingSlug = Symbol("MissingSlug");
3
- function defineUrlResolver(options) {
4
- const {
5
- base,
6
- requiresSlug = []
7
- } = options;
8
- return (document, urlSecret) => {
9
- var _a;
10
- const url = new URL(base, location.origin);
11
- url.searchParams.set("type", document._type);
12
- url.searchParams.set("id", document._id);
13
- const slug = (_a = document == null ? void 0 : document.slug) == null ? void 0 : _a.current;
14
- if (slug) {
15
- url.searchParams.set("slug", slug);
16
- } else if (requiresSlug.includes(document._type)) {
17
- return MissingSlug;
18
- }
19
- if (urlSecret) {
20
- url.searchParams.set("secret", urlSecret);
21
- }
22
- return url.toString();
23
- };
24
- }
25
- function getExpiresAt(_updatedAt) {
26
- return new Date(_updatedAt.getTime() + 1e3 * SECRET_TTL);
27
- }
28
- function generateUrlSecret() {
29
- if (typeof crypto !== "undefined") {
30
- const array = new Uint8Array(16);
31
- crypto.getRandomValues(array);
32
- let key = "";
33
- for (let i = 0; i < array.length; i++) {
34
- key += array[i].toString(16).padStart(2, "0");
35
- }
36
- key = btoa(key).replace(/\+/g, "-").replace(/\//g, "_").replace(/[=]+$/, "");
37
- return key;
38
- }
39
- return Math.random().toString(36).slice(2);
40
- }
41
- async function patchUrlSecret(client, urlSecretId, signal) {
42
- const newSecret = generateUrlSecret();
43
- const patch = client.patch(urlSecretId).set({
44
- secret: newSecret
45
- });
46
- await client.transaction().createIfNotExists({
47
- _id: urlSecretId,
48
- _type: urlSecretId
49
- }).patch(patch).commit({
50
- tag,
51
- signal
52
- });
53
- return newSecret;
54
- }
55
- export { MissingSlug, defineUrlResolver, getExpiresAt, patchUrlSecret };
56
- //# sourceMappingURL=utils-j2CLEOFh.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-j2CLEOFh.js","sources":["../../src/types.ts","../../src/defineUrlResolver.tsx","../../src/utils.ts"],"sourcesContent":["export const MissingSlug = Symbol('MissingSlug')\n\nexport type UrlState = string | typeof MissingSlug\n\nexport type IframeSizeKey = keyof SizeProps\n\nexport type Size = 'desktop' | 'mobile'\n\nexport type SizeProps = {\n // eslint-disable-next-line no-unused-vars\n [key in Size]: {\n width: string | number\n height: string | number\n }\n}\n\nexport type SetError = (error: unknown) => void\n","import type {SanityDocument} from 'sanity'\n\nimport {MissingSlug, UrlState} from './types'\n\nexport type {UrlState}\n\nexport type UrlResolver = (\n document: SanityDocument,\n urlSecret: string | null | undefined,\n signal?: AbortSignal,\n) => UrlState | Promise<UrlState>\n\nexport interface DefineUrlResolverOptions {\n base: string | URL\n requiresSlug?: string[]\n}\nexport function defineUrlResolver(options: DefineUrlResolverOptions): UrlResolver {\n const {base, requiresSlug = []} = options\n return (document, urlSecret) => {\n const url = new URL(base, location.origin)\n url.searchParams.set('type', document._type)\n url.searchParams.set('id', document._id)\n const slug = (document?.slug as any)?.current\n if (slug) {\n url.searchParams.set('slug', slug)\n } else if (requiresSlug.includes(document._type)) {\n return MissingSlug\n }\n if (urlSecret) {\n url.searchParams.set('secret', urlSecret)\n }\n return url.toString()\n }\n}\n","import type {SanityClient} from 'sanity'\n\nimport {SECRET_TTL, tag, UrlSecretId} from './isValidSecret'\n\nexport function getExpiresAt(_updatedAt: Date) {\n return new Date(_updatedAt.getTime() + 1000 * SECRET_TTL)\n}\n\nfunction generateUrlSecret() {\n // Try using WebCrypto if available\n if (typeof crypto !== 'undefined') {\n // Generate a random array of 16 bytes\n const array = new Uint8Array(16)\n crypto.getRandomValues(array)\n\n // Convert the array to a URL-safe string\n let key = ''\n for (let i = 0; i < array.length; i++) {\n // Convert each byte to a 2-digit hexadecimal number\n key += array[i].toString(16).padStart(2, '0')\n }\n\n // Replace '+' and '/' from base64url to '-' and '_'\n key = btoa(key).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/[=]+$/, '')\n\n return key\n }\n // If not fallback to Math.random\n return Math.random().toString(36).slice(2)\n}\n\nexport async function patchUrlSecret(\n client: SanityClient,\n urlSecretId: UrlSecretId,\n signal?: AbortSignal,\n): Promise<string> {\n const newSecret = generateUrlSecret()\n const patch = client.patch(urlSecretId).set({secret: newSecret})\n await client\n .transaction()\n .createIfNotExists({_id: urlSecretId, _type: urlSecretId})\n .patch(patch)\n .commit({tag, signal})\n return newSecret\n}\n"],"names":["MissingSlug","Symbol","defineUrlResolver","options","base","requiresSlug","document","urlSecret","_a","url","URL","location","origin","searchParams","set","_type","_id","slug","current","includes","toString","getExpiresAt","_updatedAt","Date","getTime","SECRET_TTL","generateUrlSecret","crypto","array","Uint8Array","getRandomValues","key","i","length","padStart","btoa","replace","Math","random","slice","patchUrlSecret","client","urlSecretId","signal","newSecret","patch","secret","transaction","createIfNotExists","commit","tag"],"mappings":";AAAa,MAAAA,WAAA,GAAcC,OAAO,aAAa,CAAA;ACgBxC,SAASC,kBAAkBC,OAAgD,EAAA;EAChF,MAAM;IAACC,IAAA;IAAMC,YAAe,GAAA;GAAM,GAAAF,OAAA;EAC3B,OAAA,CAACG,UAAUC,SAAc,KAAA;IAlBlC,IAAAC,EAAA;IAmBI,MAAMC,GAAM,GAAA,IAAIC,GAAI,CAAAN,IAAA,EAAMO,SAASC,MAAM,CAAA;IACzCH,GAAA,CAAII,YAAa,CAAAC,GAAA,CAAI,MAAQ,EAAAR,QAAA,CAASS,KAAK,CAAA;IAC3CN,GAAA,CAAII,YAAa,CAAAC,GAAA,CAAI,IAAM,EAAAR,QAAA,CAASU,GAAG,CAAA;IACjC,MAAAC,IAAA,GAAA,CAAQT,EAAU,GAAAF,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,QAAA,CAAAW,IAAA,KAAV,IAAwB,GAAA,KAAA,CAAA,GAAAT,EAAA,CAAAU,OAAA;IACtC,IAAID,IAAM,EAAA;MACJR,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,MAAA,EAAQG,IAAI,CAAA;IACxB,CAAA,MAAA,IAAAZ,YAAA,CAAac,QAAS,CAAAb,QAAA,CAASS,KAAK,CAAG,EAAA;MACzC,OAAAf,WAAA;IACT;IACA,IAAIO,SAAW,EAAA;MACTE,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,QAAA,EAAUP,SAAS,CAAA;IAC1C;IACA,OAAOE,IAAIW,QAAS,EAAA;EAAA,CACtB;AACF;AC7BO,SAASC,aAAaC,UAAkB,EAAA;EAC7C,OAAO,IAAIC,IAAK,CAAAD,UAAA,CAAWE,OAAQ,CAAA,CAAA,GAAI,MAAOC,UAAU,CAAA;AAC1D;AAEA,SAASC,iBAAoBA,CAAA,EAAA;EAEvB,IAAA,OAAOC,WAAW,WAAa,EAAA;IAE3B,MAAAC,KAAA,GAAQ,IAAIC,UAAA,CAAW,EAAE,CAAA;IAC/BF,MAAA,CAAOG,gBAAgBF,KAAK,CAAA;IAG5B,IAAIG,GAAM,GAAA,EAAA;IACV,KAAA,IAASC,CAAI,GAAA,CAAA,EAAGA,CAAI,GAAAJ,KAAA,CAAMK,QAAQD,CAAK,EAAA,EAAA;MAE9BD,GAAA,IAAAH,KAAA,CAAMI,CAAC,CAAE,CAAAZ,QAAA,CAAS,EAAE,CAAE,CAAAc,QAAA,CAAS,GAAG,GAAG,CAAA;IAC9C;IAGAH,GAAA,GAAMI,IAAK,CAAAJ,GAAG,CAAE,CAAAK,OAAA,CAAQ,KAAO,EAAA,GAAG,CAAE,CAAAA,OAAA,CAAQ,KAAO,EAAA,GAAG,CAAE,CAAAA,OAAA,CAAQ,SAAS,EAAE,CAAA;IAEpE,OAAAL,GAAA;EACT;EAEA,OAAOM,KAAKC,MAAO,EAAA,CAAElB,SAAS,EAAE,CAAA,CAAEmB,MAAM,CAAC,CAAA;AAC3C;AAEsB,eAAAC,cAAAA,CACpBC,MACA,EAAAC,WAAA,EACAC,MACiB,EAAA;EACjB,MAAMC,YAAYlB,iBAAkB,EAAA;EAC9B,MAAAmB,KAAA,GAAQJ,OAAOI,KAAM,CAAAH,WAAW,EAAE5B,GAAI,CAAA;IAACgC,MAAQ,EAAAF;EAAA,CAAU,CAAA;EAC/D,MAAMH,OACHM,WAAY,EAAA,CACZC,kBAAkB;IAAChC,GAAA,EAAK0B;IAAa3B,KAAO,EAAA2B;EAAY,CAAA,CAAA,CACxDG,MAAMA,KAAK,CAAA,CACXI,OAAO;IAACC,GAAA;IAAKP;GAAO,CAAA;EAChB,OAAAC,SAAA;AACT;"}
@@ -1,8 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', {
4
- value: true
5
- });
6
- var isValidSecret = require('./_chunks/is-valid-secret-VKMJU99B.cjs');
7
- exports.isValidSecret = isValidSecret.isValidSecret;
8
- //# sourceMappingURL=is-valid-secret.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-valid-secret.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -1,33 +0,0 @@
1
- export declare function isValidSecret(
2
- client: SanityClientLike,
3
- urlSecretId: UrlSecretId,
4
- urlSecret: string,
5
- ): Promise<boolean>
6
-
7
- export declare type SanityClientLike = {
8
- config(): {
9
- token?: string
10
- }
11
- withConfig(config: {
12
- apiVersion?: string
13
- useCdn?: boolean
14
- perspective: 'raw'
15
- resultSourceMap: boolean
16
- }): SanityClientLike
17
- fetch<
18
- R,
19
- Q = {
20
- [key: string]: any
21
- },
22
- >(
23
- query: string,
24
- params: Q,
25
- options: {
26
- tag?: string
27
- },
28
- ): Promise<R>
29
- }
30
-
31
- export declare type UrlSecretId = `${string}.${string}`
32
-
33
- export {}
@@ -1,2 +0,0 @@
1
- export { isValidSecret } from './_chunks/is-valid-secret-zi24WaHG.js';
2
- //# sourceMappingURL=is-valid-secret.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"is-valid-secret.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,56 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', {
4
- value: true
5
- });
6
- var sanity = require('sanity');
7
- var utils = require('./_chunks/utils-HbzA_NjI.cjs');
8
- var isValidSecret = require('./_chunks/is-valid-secret-VKMJU99B.cjs');
9
- const previewUrl = sanity.definePlugin(_ref => {
10
- let {
11
- urlSecretId,
12
- base,
13
- matchTypes,
14
- requiresSlug
15
- } = _ref;
16
- if (!base) {
17
- throw new TypeError("`base` is required");
18
- }
19
- const urlResolver = utils.defineUrlResolver({
20
- base,
21
- requiresSlug
22
- });
23
- return {
24
- name: "previewUrl",
25
- document: {
26
- productionUrl: async (prev, _ref2) => {
27
- let {
28
- document,
29
- getClient
30
- } = _ref2;
31
- if ((matchTypes == null ? void 0 : matchTypes.length) && !matchTypes.includes(document._type)) {
32
- return prev;
33
- }
34
- let urlSecret = null;
35
- if (urlSecretId) {
36
- const client = getClient({
37
- apiVersion: isValidSecret.apiVersion
38
- });
39
- const data = await client.fetch(isValidSecret.fetchSecretQuery, {
40
- id: urlSecretId
41
- }, {
42
- tag: isValidSecret.tag
43
- });
44
- urlSecret = (data == null ? void 0 : data.secret) ? data.secret : await utils.patchUrlSecret(client, urlSecretId);
45
- }
46
- const url = urlResolver(document, urlSecret);
47
- if (url) {
48
- return url === utils.MissingSlug ? prev : url;
49
- }
50
- return prev;
51
- }
52
- }
53
- };
54
- });
55
- exports.previewUrl = previewUrl;
56
- //# sourceMappingURL=preview-url.cjs.map
@@ -1,4 +0,0 @@
1
- import cjs from './preview-url.cjs';
2
-
3
- export const previewUrl = cjs.previewUrl;
4
-
@@ -1 +0,0 @@
1
- {"version":3,"file":"preview-url.cjs","sources":["../src/previewUrl.ts"],"sourcesContent":["/**\n * This plugin sets up the \"Open preview (CTRL + ALT + O)\" in the dropdown menu that hosts\n * other actions like \"Review changes\" and \"Inspect\"\n */\n\nimport {definePlugin, SanityDocument} from 'sanity'\n\nimport {defineUrlResolver, DefineUrlResolverOptions} from './defineUrlResolver'\nimport {\n apiVersion,\n fetchSecretQuery,\n FetchSecretResponse,\n tag,\n type UrlSecretId,\n} from './isValidSecret'\nimport {MissingSlug} from './types'\nimport {patchUrlSecret} from './utils'\n\nexport type {DefineUrlResolverOptions, UrlSecretId}\n\nexport interface ProductionUrlOptions extends DefineUrlResolverOptions {\n matchTypes?: string[]\n urlSecretId?: UrlSecretId\n}\n\nexport const previewUrl = definePlugin<ProductionUrlOptions>(\n ({urlSecretId, base, matchTypes, requiresSlug}) => {\n if (!base) {\n throw new TypeError('`base` is required')\n }\n\n const urlResolver = defineUrlResolver({base, requiresSlug})\n return {\n name: 'previewUrl',\n document: {\n productionUrl: async (prev, {document, getClient}) => {\n if (matchTypes?.length && !matchTypes.includes(document._type)) {\n return prev\n }\n\n let urlSecret: string | null = null\n if (urlSecretId) {\n const client = getClient({apiVersion})\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {tag},\n )\n urlSecret = data?.secret ? data.secret : await patchUrlSecret(client, urlSecretId)\n }\n\n const url = urlResolver(document as SanityDocument, urlSecret)\n if (url) {\n return url === MissingSlug ? prev : url\n }\n\n return prev\n },\n },\n }\n },\n)\n"],"names":["previewUrl","definePlugin","_ref","urlSecretId","base","matchTypes","requiresSlug","TypeError","urlResolver","defineUrlResolver","name","document","productionUrl","prev","_ref2","getClient","length","includes","_type","urlSecret","client","apiVersion","data","fetch","fetchSecretQuery","id","tag","secret","patchUrlSecret","url","MissingSlug"],"mappings":";;;;;;;;AAyBO,MAAMA,UAAa,GAAAC,MAAA,CAAAA,YAAA,CACxBC,IAAA,IAAmD;EAAA,IAAlD;IAACC,WAAA;IAAaC,IAAM;IAAAC,UAAA;IAAYC;GAAkB,GAAAJ,IAAA;EACjD,IAAI,CAACE,IAAM,EAAA;IACH,MAAA,IAAIG,UAAU,oBAAoB,CAAA;EAC1C;EAEA,MAAMC,WAAc,GAAAC,KAAA,CAAAA,iBAAA,CAAkB;IAACL,IAAA;IAAME;EAAa,CAAA,CAAA;EACnD,OAAA;IACLI,IAAM,EAAA,YAAA;IACNC,QAAU,EAAA;MACRC,eAAe,MAAAA,CAAOC,IAAA,EAAAC,KAAA,KAAgC;QAAA,IAA1B;UAACH,QAAA;UAAUI;SAAe,GAAAD,KAAA;QACpD,IAAA,CAAIT,yCAAYW,MAAU,KAAA,CAACX,WAAWY,QAAS,CAAAN,QAAA,CAASO,KAAK,CAAG,EAAA;UACvD,OAAAL,IAAA;QACT;QAEA,IAAIM,SAA2B,GAAA,IAAA;QAC/B,IAAIhB,WAAa,EAAA;UACf,MAAMiB,MAAS,GAAAL,SAAA,CAAU;YAACM,UAAAA,EAAAA,aAAAA,CAAAA;UAAW,CAAA,CAAA;UAC/B,MAAAC,IAAA,GAAO,MAAMF,MAAO,CAAAG,KAAA,CACxBC,aAAA,CAAAA,gBAAA,EACA;YAACC,IAAItB;UAAW,CAAA,EAChB;YAAAuB,GAAA,EAACA;UAAG,CAAA,CACN;UACAP,SAAA,GAAA,CAAYG,6BAAMK,MAAS,IAAAL,IAAA,CAAKK,SAAS,MAAMC,KAAA,CAAAA,cAAA,CAAeR,QAAQjB,WAAW,CAAA;QACnF;QAEM,MAAA0B,GAAA,GAAMrB,WAAY,CAAAG,QAAA,EAA4BQ,SAAS,CAAA;QAC7D,IAAIU,GAAK,EAAA;UACA,OAAAA,GAAA,KAAQC,KAAAA,CAAAA,cAAcjB,IAAO,GAAAgB,GAAA;QACtC;QAEO,OAAAhB,IAAA;MACT;IACF;EAAA,CACF;AACF,CACF,CAAA;"}
@@ -1,17 +0,0 @@
1
- import {Plugin as Plugin_2} from 'sanity'
2
-
3
- export declare interface DefineUrlResolverOptions {
4
- base: string | URL
5
- requiresSlug?: string[]
6
- }
7
-
8
- export declare const previewUrl: Plugin_2<ProductionUrlOptions>
9
-
10
- export declare interface ProductionUrlOptions extends DefineUrlResolverOptions {
11
- matchTypes?: string[]
12
- urlSecretId?: UrlSecretId
13
- }
14
-
15
- export declare type UrlSecretId = `${string}.${string}`
16
-
17
- export {}
@@ -1,51 +0,0 @@
1
- import { definePlugin } from 'sanity';
2
- import { patchUrlSecret, MissingSlug, defineUrlResolver } from './_chunks/utils-j2CLEOFh.js';
3
- import { apiVersion, fetchSecretQuery, tag } from './_chunks/is-valid-secret-zi24WaHG.js';
4
- const previewUrl = definePlugin(_ref => {
5
- let {
6
- urlSecretId,
7
- base,
8
- matchTypes,
9
- requiresSlug
10
- } = _ref;
11
- if (!base) {
12
- throw new TypeError("`base` is required");
13
- }
14
- const urlResolver = defineUrlResolver({
15
- base,
16
- requiresSlug
17
- });
18
- return {
19
- name: "previewUrl",
20
- document: {
21
- productionUrl: async (prev, _ref2) => {
22
- let {
23
- document,
24
- getClient
25
- } = _ref2;
26
- if ((matchTypes == null ? void 0 : matchTypes.length) && !matchTypes.includes(document._type)) {
27
- return prev;
28
- }
29
- let urlSecret = null;
30
- if (urlSecretId) {
31
- const client = getClient({
32
- apiVersion
33
- });
34
- const data = await client.fetch(fetchSecretQuery, {
35
- id: urlSecretId
36
- }, {
37
- tag
38
- });
39
- urlSecret = (data == null ? void 0 : data.secret) ? data.secret : await patchUrlSecret(client, urlSecretId);
40
- }
41
- const url = urlResolver(document, urlSecret);
42
- if (url) {
43
- return url === MissingSlug ? prev : url;
44
- }
45
- return prev;
46
- }
47
- }
48
- };
49
- });
50
- export { previewUrl };
51
- //# sourceMappingURL=preview-url.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preview-url.js","sources":["../src/previewUrl.ts"],"sourcesContent":["/**\n * This plugin sets up the \"Open preview (CTRL + ALT + O)\" in the dropdown menu that hosts\n * other actions like \"Review changes\" and \"Inspect\"\n */\n\nimport {definePlugin, SanityDocument} from 'sanity'\n\nimport {defineUrlResolver, DefineUrlResolverOptions} from './defineUrlResolver'\nimport {\n apiVersion,\n fetchSecretQuery,\n FetchSecretResponse,\n tag,\n type UrlSecretId,\n} from './isValidSecret'\nimport {MissingSlug} from './types'\nimport {patchUrlSecret} from './utils'\n\nexport type {DefineUrlResolverOptions, UrlSecretId}\n\nexport interface ProductionUrlOptions extends DefineUrlResolverOptions {\n matchTypes?: string[]\n urlSecretId?: UrlSecretId\n}\n\nexport const previewUrl = definePlugin<ProductionUrlOptions>(\n ({urlSecretId, base, matchTypes, requiresSlug}) => {\n if (!base) {\n throw new TypeError('`base` is required')\n }\n\n const urlResolver = defineUrlResolver({base, requiresSlug})\n return {\n name: 'previewUrl',\n document: {\n productionUrl: async (prev, {document, getClient}) => {\n if (matchTypes?.length && !matchTypes.includes(document._type)) {\n return prev\n }\n\n let urlSecret: string | null = null\n if (urlSecretId) {\n const client = getClient({apiVersion})\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {tag},\n )\n urlSecret = data?.secret ? data.secret : await patchUrlSecret(client, urlSecretId)\n }\n\n const url = urlResolver(document as SanityDocument, urlSecret)\n if (url) {\n return url === MissingSlug ? prev : url\n }\n\n return prev\n },\n },\n }\n },\n)\n"],"names":["previewUrl","definePlugin","_ref","urlSecretId","base","matchTypes","requiresSlug","TypeError","urlResolver","defineUrlResolver","name","document","productionUrl","prev","_ref2","getClient","length","includes","_type","urlSecret","client","apiVersion","data","fetch","fetchSecretQuery","id","tag","secret","patchUrlSecret","url","MissingSlug"],"mappings":";;;AAyBO,MAAMA,UAAa,GAAAC,YAAA,CACxBC,IAAA,IAAmD;EAAA,IAAlD;IAACC,WAAA;IAAaC,IAAM;IAAAC,UAAA;IAAYC;GAAkB,GAAAJ,IAAA;EACjD,IAAI,CAACE,IAAM,EAAA;IACH,MAAA,IAAIG,UAAU,oBAAoB,CAAA;EAC1C;EAEA,MAAMC,WAAc,GAAAC,iBAAA,CAAkB;IAACL,IAAA;IAAME;EAAa,CAAA,CAAA;EACnD,OAAA;IACLI,IAAM,EAAA,YAAA;IACNC,QAAU,EAAA;MACRC,eAAe,MAAAA,CAAOC,IAAA,EAAAC,KAAA,KAAgC;QAAA,IAA1B;UAACH,QAAA;UAAUI;SAAe,GAAAD,KAAA;QACpD,IAAA,CAAIT,yCAAYW,MAAU,KAAA,CAACX,WAAWY,QAAS,CAAAN,QAAA,CAASO,KAAK,CAAG,EAAA;UACvD,OAAAL,IAAA;QACT;QAEA,IAAIM,SAA2B,GAAA,IAAA;QAC/B,IAAIhB,WAAa,EAAA;UACf,MAAMiB,MAAS,GAAAL,SAAA,CAAU;YAACM;UAAW,CAAA,CAAA;UAC/B,MAAAC,IAAA,GAAO,MAAMF,MAAO,CAAAG,KAAA,CACxBC,gBAAA,EACA;YAACC,IAAItB;UAAW,CAAA,EAChB;YAACuB;UAAG,CAAA,CACN;UACAP,SAAA,GAAA,CAAYG,6BAAMK,MAAS,IAAAL,IAAA,CAAKK,SAAS,MAAMC,cAAA,CAAeR,QAAQjB,WAAW,CAAA;QACnF;QAEM,MAAA0B,GAAA,GAAMrB,WAAY,CAAAG,QAAA,EAA4BQ,SAAS,CAAA;QAC7D,IAAIU,GAAK,EAAA;UACA,OAAAA,GAAA,KAAQC,cAAcjB,IAAO,GAAAgB,GAAA;QACtC;QAEO,OAAAhB,IAAA;MACT;IACF;EAAA,CACF;AACF,CACF,CAAA;"}
@@ -1,80 +0,0 @@
1
- import {useEffect, useState} from 'react'
2
- import {useClient} from 'sanity'
3
-
4
- import {apiVersion, fetchSecretQuery, FetchSecretResponse, tag, UrlSecretId} from './isValidSecret'
5
- import {SetError} from './types'
6
- import {getExpiresAt, patchUrlSecret} from './utils'
7
-
8
- export interface GetUrlSecretProps {
9
- urlSecretId: UrlSecretId
10
- urlSecret: string | null
11
- setUrlSecret: (secret: string | null) => void
12
- setError: SetError
13
- }
14
- export function GetUrlSecret(props: GetUrlSecretProps) {
15
- const {urlSecretId, setUrlSecret, urlSecret, setError} = props
16
- const client = useClient({apiVersion})
17
- const [secretExpiresAt, setSecretExpiresAt] = useState<null | Date>(null)
18
-
19
- if (!urlSecretId.includes('.')) {
20
- throw new TypeError(
21
- `\`urlSecretId\` must have a dot prefix, \`${urlSecretId}\` is not secure, add a prefix, for example \`preview.${urlSecretId}\` `,
22
- )
23
- }
24
-
25
- useEffect(() => {
26
- if (urlSecret) return
27
-
28
- async function getSecret(signal: AbortSignal): Promise<void> {
29
- const data = await client.fetch<FetchSecretResponse>(
30
- fetchSecretQuery,
31
- {id: urlSecretId},
32
- {signal, tag},
33
- )
34
-
35
- if (signal.aborted) return
36
-
37
- if (!data?.secret || !data?._updatedAt) {
38
- try {
39
- const newUpdatedAt = new Date()
40
- const newSecret = await patchUrlSecret(client, urlSecretId, signal)
41
- if (signal.aborted) return
42
- setUrlSecret(newSecret)
43
- setSecretExpiresAt(getExpiresAt(newUpdatedAt))
44
- } catch (err) {
45
- console.error(
46
- 'Failed to create a new preview secret. Ensure the `client` has a `token` specified that has `write` permissions.',
47
- err,
48
- )
49
- }
50
- return
51
- }
52
-
53
- if (data?.secret !== urlSecret) {
54
- setUrlSecret(data?.secret)
55
- setSecretExpiresAt(getExpiresAt(new Date(data?._updatedAt)))
56
- }
57
- }
58
-
59
- const abort = new AbortController()
60
- getSecret(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))
61
- // eslint-disable-next-line consistent-return
62
- return () => abort.abort()
63
- }, [client, setError, setUrlSecret, urlSecret, urlSecretId])
64
-
65
- useEffect(() => {
66
- if (!secretExpiresAt) return
67
-
68
- const timeout = setTimeout(
69
- () => {
70
- setUrlSecret(null)
71
- setSecretExpiresAt(null)
72
- },
73
- Math.max(0, secretExpiresAt.getTime() - new Date().getTime()),
74
- )
75
- // eslint-disable-next-line consistent-return
76
- return () => clearTimeout(timeout)
77
- }, [secretExpiresAt, setUrlSecret])
78
-
79
- return null
80
- }
@@ -1,34 +0,0 @@
1
- import type {SanityDocument} from 'sanity'
2
-
3
- import {MissingSlug, UrlState} from './types'
4
-
5
- export type {UrlState}
6
-
7
- export type UrlResolver = (
8
- document: SanityDocument,
9
- urlSecret: string | null | undefined,
10
- signal?: AbortSignal,
11
- ) => UrlState | Promise<UrlState>
12
-
13
- export interface DefineUrlResolverOptions {
14
- base: string | URL
15
- requiresSlug?: string[]
16
- }
17
- export function defineUrlResolver(options: DefineUrlResolverOptions): UrlResolver {
18
- const {base, requiresSlug = []} = options
19
- return (document, urlSecret) => {
20
- const url = new URL(base, location.origin)
21
- url.searchParams.set('type', document._type)
22
- url.searchParams.set('id', document._id)
23
- const slug = (document?.slug as any)?.current
24
- if (slug) {
25
- url.searchParams.set('slug', slug)
26
- } else if (requiresSlug.includes(document._type)) {
27
- return MissingSlug
28
- }
29
- if (urlSecret) {
30
- url.searchParams.set('secret', urlSecret)
31
- }
32
- return url.toString()
33
- }
34
- }
@@ -1 +0,0 @@
1
- export {isValidSecret, type SanityClientLike, type UrlSecretId} from './isValidSecret'