sanity-plugin-iframe-pane 2.5.5 → 2.5.7
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/lib/_chunks/{is-valid-secret-be2288e3.js → is-valid-secret-926b3d57.js} +6 -2
- package/lib/_chunks/is-valid-secret-926b3d57.js.map +1 -0
- package/lib/_chunks/{is-valid-secret-6020b622.cjs → is-valid-secret-fac49993.cjs} +6 -2
- package/lib/_chunks/is-valid-secret-fac49993.cjs.map +1 -0
- package/lib/_chunks/{utils-95f4ad1b.js → utils-771d70cf.js} +2 -2
- package/lib/_chunks/{utils-95f4ad1b.js.map → utils-771d70cf.js.map} +1 -1
- package/lib/_chunks/{utils-4805e537.cjs → utils-a281f455.cjs} +2 -2
- package/lib/_chunks/{utils-4805e537.cjs.map → utils-a281f455.cjs.map} +1 -1
- package/lib/index.cjs +4 -2
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +5 -3
- package/lib/index.js.map +1 -1
- package/lib/is-valid-secret.cjs +1 -1
- package/lib/is-valid-secret.d.ts +6 -1
- package/lib/is-valid-secret.js +1 -1
- package/lib/preview-url.cjs +2 -2
- package/lib/preview-url.js +2 -2
- package/package.json +12 -12
- package/src/Toolbar.tsx +2 -0
- package/src/isValidSecret.tsx +14 -1
- package/lib/_chunks/is-valid-secret-6020b622.cjs.map +0 -1
- package/lib/_chunks/is-valid-secret-be2288e3.js.map +0 -1
|
@@ -21,10 +21,14 @@ async function isValidSecret(client, urlSecretId, urlSecret) {
|
|
|
21
21
|
if (!client.config().token) {
|
|
22
22
|
throw new TypeError("`client` must have a `token` specified");
|
|
23
23
|
}
|
|
24
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
26
|
+
}
|
|
24
27
|
const customClient = client.withConfig({
|
|
25
28
|
apiVersion,
|
|
26
29
|
useCdn: false,
|
|
27
|
-
perspective: "raw"
|
|
30
|
+
perspective: "raw",
|
|
31
|
+
resultSourceMap: false
|
|
28
32
|
});
|
|
29
33
|
const data = await customClient.fetch(fetchSecretQuery, {
|
|
30
34
|
id: urlSecretId
|
|
@@ -51,4 +55,4 @@ async function isValidSecret(client, urlSecretId, urlSecret) {
|
|
|
51
55
|
return (data == null ? void 0 : data.secret) === urlSecret;
|
|
52
56
|
}
|
|
53
57
|
export { SECRET_TTL, apiVersion, fetchSecretQuery, isValidSecret, tag };
|
|
54
|
-
//# sourceMappingURL=is-valid-secret-
|
|
58
|
+
//# sourceMappingURL=is-valid-secret-926b3d57.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-valid-secret-926b3d57.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;"}
|
|
@@ -23,10 +23,14 @@ async function isValidSecret(client, urlSecretId, urlSecret) {
|
|
|
23
23
|
if (!client.config().token) {
|
|
24
24
|
throw new TypeError("`client` must have a `token` specified");
|
|
25
25
|
}
|
|
26
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
27
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
28
|
+
}
|
|
26
29
|
const customClient = client.withConfig({
|
|
27
30
|
apiVersion,
|
|
28
31
|
useCdn: false,
|
|
29
|
-
perspective: "raw"
|
|
32
|
+
perspective: "raw",
|
|
33
|
+
resultSourceMap: false
|
|
30
34
|
});
|
|
31
35
|
const data = await customClient.fetch(fetchSecretQuery, {
|
|
32
36
|
id: urlSecretId
|
|
@@ -57,4 +61,4 @@ exports.apiVersion = apiVersion;
|
|
|
57
61
|
exports.fetchSecretQuery = fetchSecretQuery;
|
|
58
62
|
exports.isValidSecret = isValidSecret;
|
|
59
63
|
exports.tag = tag;
|
|
60
|
-
//# sourceMappingURL=is-valid-secret-
|
|
64
|
+
//# sourceMappingURL=is-valid-secret-fac49993.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-valid-secret-fac49993.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,4 +1,4 @@
|
|
|
1
|
-
import { tag, SECRET_TTL } from './is-valid-secret-
|
|
1
|
+
import { tag, SECRET_TTL } from './is-valid-secret-926b3d57.js';
|
|
2
2
|
const MissingSlug = Symbol("MissingSlug");
|
|
3
3
|
function defineUrlResolver(options) {
|
|
4
4
|
const {
|
|
@@ -52,4 +52,4 @@ async function patchUrlSecret(client, urlSecretId, signal) {
|
|
|
52
52
|
return newSecret;
|
|
53
53
|
}
|
|
54
54
|
export { MissingSlug, defineUrlResolver, getExpiresAt, patchUrlSecret };
|
|
55
|
-
//# sourceMappingURL=utils-
|
|
55
|
+
//# sourceMappingURL=utils-771d70cf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-
|
|
1
|
+
{"version":3,"file":"utils-771d70cf.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 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","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","_id","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;IACrC,MAAAC,IAAA,GAAA,CAAQR,EAAU,GAAAF,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,QAAA,CAAAU,IAAA,KAAV,IAAwB,GAAA,KAAA,CAAA,GAAAR,EAAA,CAAAS,OAAA;IACtC,IAAID,IAAM,EAAA;MACJP,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,MAAA,EAAQE,IAAI,CAAA;IACxB,CAAA,MAAA,IAAAX,YAAA,CAAaa,QAAS,CAAAZ,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,IAAIU,QAAS,EAAA;EAAA,CACtB;AACF;AC5BO,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,EAAE3B,GAAI,CAAA;IAAC+B,MAAQ,EAAAF;EAAA,CAAU,CAAA;EAC/D,MAAMH,OACHM,WAAY,EAAA,CACZC,kBAAkB;IAACC,GAAA,EAAKP;IAAa1B,KAAO,EAAA0B;EAAY,CAAA,CAAA,CACxDG,MAAMA,KAAK,CAAA,CACXK,OAAO;IAACC,GAAA;IAAKR;GAAO,CAAA;EAChB,OAAAC,SAAA;AACT;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var isValidSecret = require('./is-valid-secret-
|
|
3
|
+
var isValidSecret = require('./is-valid-secret-fac49993.cjs');
|
|
4
4
|
const MissingSlug = Symbol("MissingSlug");
|
|
5
5
|
function defineUrlResolver(options) {
|
|
6
6
|
const {
|
|
@@ -57,4 +57,4 @@ exports.MissingSlug = MissingSlug;
|
|
|
57
57
|
exports.defineUrlResolver = defineUrlResolver;
|
|
58
58
|
exports.getExpiresAt = getExpiresAt;
|
|
59
59
|
exports.patchUrlSecret = patchUrlSecret;
|
|
60
|
-
//# sourceMappingURL=utils-
|
|
60
|
+
//# sourceMappingURL=utils-a281f455.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-
|
|
1
|
+
{"version":3,"file":"utils-a281f455.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 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","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","_id","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;IACrC,MAAAC,IAAA,GAAA,CAAQR,EAAU,GAAAF,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,QAAA,CAAAU,IAAA,KAAV,IAAwB,GAAA,KAAA,CAAA,GAAAR,EAAA,CAAAS,OAAA;IACtC,IAAID,IAAM,EAAA;MACJP,GAAA,CAAAI,YAAA,CAAaC,GAAI,CAAA,MAAA,EAAQE,IAAI,CAAA;IACxB,CAAA,MAAA,IAAAX,YAAA,CAAaa,QAAS,CAAAZ,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,IAAIU,QAAS,EAAA;EAAA,CACtB;AACF;AC5BO,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,EAAE3B,GAAI,CAAA;IAAC+B,MAAQ,EAAAF;EAAA,CAAU,CAAA;EAC/D,MAAMH,OACHM,WAAY,EAAA,CACZC,kBAAkB;IAACC,GAAA,EAAKP;IAAa1B,KAAO,EAAA0B;EAAY,CAAA,CAAA,CACxDG,MAAMA,KAAK,CAAA,CACXK,OAAO;IAAAC,GAAA,EAACA,aAAA,CAAAA,GAAA;IAAKR;GAAO,CAAA;EAChB,OAAAC,SAAA;AACT;;;;"}
|
package/lib/index.cjs
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
var utils = require('./_chunks/utils-
|
|
6
|
+
var utils = require('./_chunks/utils-a281f455.cjs');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var icons = require('@sanity/icons');
|
|
9
9
|
var ui = require('@sanity/ui');
|
|
10
10
|
var framerMotion = require('framer-motion');
|
|
11
11
|
var react = require('react');
|
|
12
12
|
var sanity = require('sanity');
|
|
13
|
-
var isValidSecret = require('./_chunks/is-valid-secret-
|
|
13
|
+
var isValidSecret = require('./_chunks/is-valid-secret-fac49993.cjs');
|
|
14
14
|
var usehooksTs = require('usehooks-ts');
|
|
15
15
|
function GetUrlSecret(props) {
|
|
16
16
|
const {
|
|
@@ -141,6 +141,7 @@ function Toolbar(props) {
|
|
|
141
141
|
children: iframeSize === "mobile" ? "Exit mobile preview" : "Preview mobile viewport"
|
|
142
142
|
}),
|
|
143
143
|
padding: 2,
|
|
144
|
+
placement: "bottom-start",
|
|
144
145
|
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
145
146
|
disabled: !displayUrl,
|
|
146
147
|
fontSize: [1],
|
|
@@ -217,6 +218,7 @@ function Toolbar(props) {
|
|
|
217
218
|
children: "Open URL in a new tab"
|
|
218
219
|
}),
|
|
219
220
|
padding: 2,
|
|
221
|
+
placement: "bottom-end",
|
|
220
222
|
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
221
223
|
disabled: !displayUrl,
|
|
222
224
|
fontSize: [1],
|
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/GetUrlSecret.tsx","../src/DisplayUrl.tsx","../src/Toolbar.tsx","../src/Iframe.tsx"],"sourcesContent":["import {useEffect, useState} from 'react'\nimport {useClient} from 'sanity'\n\nimport {apiVersion, fetchSecretQuery, FetchSecretResponse, tag, UrlSecretId} from './isValidSecret'\nimport {SetError} from './types'\nimport {getExpiresAt, patchUrlSecret} from './utils'\n\nexport interface GetUrlSecretProps {\n urlSecretId: UrlSecretId\n urlSecret: string | null\n setUrlSecret: (secret: string | null) => void\n setError: SetError\n}\nexport function GetUrlSecret(props: GetUrlSecretProps) {\n const {urlSecretId, setUrlSecret, urlSecret, setError} = props\n const client = useClient({apiVersion})\n const [secretExpiresAt, setSecretExpiresAt] = useState<null | Date>(null)\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\n useEffect(() => {\n if (urlSecret) return\n\n async function getSecret(signal: AbortSignal): Promise<void> {\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {signal, tag},\n )\n\n if (signal.aborted) return\n\n if (!data?.secret || !data?._updatedAt) {\n try {\n const newUpdatedAt = new Date()\n const newSecret = await patchUrlSecret(client, urlSecretId, signal)\n if (signal.aborted) return\n setUrlSecret(newSecret)\n setSecretExpiresAt(getExpiresAt(newUpdatedAt))\n } catch (err) {\n console.error(\n 'Failed to create a new preview secret. Ensure the `client` has a `token` specified that has `write` permissions.',\n err,\n )\n }\n return\n }\n\n if (data?.secret !== urlSecret) {\n setUrlSecret(data?.secret)\n setSecretExpiresAt(getExpiresAt(new Date(data?._updatedAt)))\n }\n }\n\n const abort = new AbortController()\n getSecret(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [client, setError, setUrlSecret, urlSecret, urlSecretId])\n\n useEffect(() => {\n if (!secretExpiresAt) return\n\n const timeout = setTimeout(\n () => {\n setUrlSecret(null)\n setSecretExpiresAt(null)\n },\n Math.max(0, secretExpiresAt.getTime() - new Date().getTime()),\n )\n // eslint-disable-next-line consistent-return\n return () => clearTimeout(timeout)\n }, [secretExpiresAt, setUrlSecret])\n\n return null\n}\n","import {Text} from '@sanity/ui'\nimport React, {useMemo} from 'react'\n\nexport function DisplayUrl({displayUrl}: {displayUrl: string}) {\n const truncatedUrl = useMemo(() => {\n const url = new URL(displayUrl)\n\n if (url.searchParams.has('secret')) {\n url.searchParams.delete('secret')\n url.searchParams.append('secret', '***')\n }\n\n return `${url.origin === location.origin ? '' : url.origin}${url.pathname}${url.search}`\n }, [displayUrl])\n\n return (\n <Text size={0} textOverflow=\"ellipsis\" title={displayUrl}>\n {truncatedUrl}\n </Text>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {ClipboardIcon, LaunchIcon, MobileDeviceIcon, UndoIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, Tooltip, useToast} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport {useCopyToClipboard} from 'usehooks-ts'\n\nimport {DisplayUrl} from './DisplayUrl'\nimport {IframeSizeKey, type SizeProps} from './types'\n\nexport const sizes: SizeProps = {\n desktop: {\n width: '100%',\n height: '100%',\n },\n mobile: {\n width: 414,\n height: 746,\n },\n}\n\nexport const DEFAULT_SIZE = `desktop`\n\nexport interface ToolbarProps {\n displayUrl: string\n iframeSize: IframeSizeKey\n setIframeSize: (size: IframeSizeKey) => void\n showDisplayUrl: boolean\n reloading: boolean\n reloadButton: boolean\n handleReload: () => void\n}\nexport function Toolbar(props: ToolbarProps) {\n const {\n displayUrl,\n iframeSize,\n setIframeSize,\n reloading,\n showDisplayUrl,\n reloadButton,\n handleReload,\n } = props\n\n const input = useRef<HTMLTextAreaElement>(null)\n const {push: pushToast} = useToast()\n const [, copy] = useCopyToClipboard()\n\n return (\n <>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Card padding={2} borderBottom>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {iframeSize === 'mobile' ? 'Exit mobile preview' : 'Preview mobile viewport'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n padding={2}\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Tooltip>\n </Flex>\n <Box flex={1}>\n {showDisplayUrl && displayUrl && <DisplayUrl displayUrl={displayUrl} />}\n </Box>\n <Flex align=\"center\" gap={1}>\n {reloadButton ? (\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {reloading ? 'Reloading…' : 'Reload'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n mode=\"bleed\"\n fontSize={[1]}\n padding={2}\n icon={<UndoIcon style={{transform: 'rotate(90deg) scaleY(-1)'}} />}\n loading={reloading}\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n </Tooltip>\n ) : null}\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Copy URL\n </Text>\n }\n padding={2}\n >\n <Button\n mode=\"bleed\"\n disabled={!displayUrl}\n fontSize={[1]}\n icon={ClipboardIcon}\n padding={[2]}\n aria-label=\"Copy URL\"\n onClick={() => {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n pushToast({\n closable: true,\n status: 'success',\n title: 'The URL is copied to the clipboard',\n })\n }}\n />\n </Tooltip>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Open URL in a new tab\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n icon={LaunchIcon}\n mode=\"ghost\"\n paddingY={[2]}\n text=\"Open\"\n aria-label=\"Open URL in a new tab\"\n onClick={() => window.open(displayUrl)}\n />\n </Tooltip>\n </Flex>\n </Flex>\n </Card>\n </>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport {Box, Card, Container, Flex, Spinner, Stack, Text, usePrefersReducedMotion} from '@sanity/ui'\nimport {AnimatePresence, motion, MotionConfig} from 'framer-motion'\nimport React, {forwardRef, useCallback, useDeferredValue, useEffect, useRef, useState} from 'react'\nimport {HTMLAttributeReferrerPolicy} from 'react'\nimport {SanityDocument} from 'sanity'\n\nimport {UrlResolver} from './defineUrlResolver'\nimport {GetUrlSecret} from './GetUrlSecret'\nimport {UrlSecretId} from './isValidSecret'\nimport {DEFAULT_SIZE, sizes, Toolbar} from './Toolbar'\nimport {IframeSizeKey, MissingSlug, SetError, type UrlState} from './types'\n\nexport type {IframeSizeKey, UrlResolver, UrlSecretId}\n\nexport type IframeOptions = {\n urlSecretId?: UrlSecretId\n url: UrlState | UrlResolver\n defaultSize?: IframeSizeKey\n loader?: string | boolean\n showDisplayUrl?: boolean\n reload?: {\n revision?: boolean | number\n button?: boolean\n }\n attributes?: Partial<{\n allow: string\n referrerPolicy: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n onLoad: () => void\n }>\n}\n\nconst MotionFlex = motion(Flex)\n\nexport interface IframeProps {\n document: {\n displayed: SanityDocument\n }\n options: IframeOptions\n}\n\nexport function Iframe(props: IframeProps) {\n const [error, setError] = useState<unknown>(null)\n if (error) {\n throw error\n }\n\n const {document: sanityDocument, options} = props\n const {\n url,\n urlSecretId,\n defaultSize = DEFAULT_SIZE,\n reload,\n loader = 'Loading…',\n attributes = {},\n showDisplayUrl = true,\n } = options\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n\n // Workaround documents that initially appears to be an empty new document but just hasen't loaded yet\n const [workaroundEmptyDocument, setWorkaroundEmptyDocument] = useState(true)\n useEffect(() => {\n const timeout = setTimeout(() => setWorkaroundEmptyDocument(false), 1000)\n return () => clearTimeout(timeout)\n }, [])\n\n const prefersReducedMotion = usePrefersReducedMotion()\n const [urlState, setUrlState] = useState<UrlState>(() => (typeof url === 'function' ? '' : url))\n\n const [loading, setLoading] = useState(true)\n const [reloading, setReloading] = useState(false)\n\n const iframe = useRef<HTMLIFrameElement>(null)\n const {displayed} = sanityDocument\n\n const handleReload = useCallback(() => {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issues\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n\n setReloading(true)\n }, [])\n\n const deferredRevision = useDeferredValue(displayed._rev)\n const displayUrl = typeof urlState === 'string' ? urlState : ''\n\n return (\n <MotionConfig transition={prefersReducedMotion ? {duration: 0} : undefined}>\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Toolbar\n displayUrl={displayUrl}\n iframeSize={iframeSize}\n reloading={reloading}\n setIframeSize={setIframeSize}\n showDisplayUrl={showDisplayUrl}\n reloadButton={!!reload?.button}\n handleReload={handleReload}\n />\n {urlState === MissingSlug && !workaroundEmptyDocument ? (\n <MissingSlugScreen />\n ) : (\n <Card tone=\"transparent\" style={{height: `100%`}}>\n <Frame\n ref={iframe}\n loader={loader}\n loading={loading}\n reloading={reloading}\n iframeSize={iframeSize}\n setReloading={setReloading}\n setLoading={setLoading}\n displayUrl={displayUrl}\n attributes={attributes}\n />\n </Card>\n )}\n {typeof url === 'function' && (\n <AsyncUrl\n // We use the revision as a key, to force a re-render when the revision changes\n // This allows us to respond to changed props (maybe the url function itself changes)\n // But avoid calling async logic on every render accidentally\n key={deferredRevision}\n url={url}\n displayed={displayed}\n urlSecretId={urlSecretId}\n setDisplayUrl={setUrlState}\n setError={setError}\n />\n )}\n {displayUrl && (reload?.revision || reload?.revision === 0) && (\n <ReloadOnRevision\n revision={reload.revision}\n _rev={deferredRevision}\n handleReload={handleReload}\n />\n )}\n </Flex>\n </MotionConfig>\n )\n}\n\ninterface FrameProps extends Required<Pick<IframeOptions, 'loader' | 'attributes'>> {\n loader: string | boolean\n loading: boolean\n reloading: boolean\n setLoading: (loading: boolean) => void\n setReloading: (reloading: boolean) => void\n iframeSize: IframeSizeKey\n displayUrl: string\n}\nconst Frame = forwardRef(function Frame(\n props: FrameProps,\n iframe: React.ForwardedRef<HTMLIFrameElement>,\n) {\n const {loader, loading, setLoading, iframeSize, attributes, reloading, displayUrl, setReloading} =\n props\n\n function handleIframeLoad() {\n setLoading(false)\n setReloading(false)\n // Run onLoad from attributes\n if (attributes.onLoad && typeof attributes.onLoad === 'function') {\n attributes.onLoad()\n }\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`, position: `relative`}}>\n <AnimatePresence>\n {loader && loading && (\n <MotionFlex\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n variants={spinnerVariants}\n justify=\"center\"\n align=\"center\"\n style={{inset: `0`, position: `absolute`}}\n >\n <Flex\n style={{...sizes[iframeSize]}}\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n gap={4}\n >\n <Spinner muted />\n {loader && typeof loader === 'string' && (\n <Text muted size={1}>\n {loader}\n </Text>\n )}\n </Flex>\n </MotionFlex>\n )}\n </AnimatePresence>\n <motion.iframe\n ref={iframe}\n title=\"preview\"\n frameBorder=\"0\"\n style={{maxHeight: '100%'}}\n src={displayUrl}\n initial={['background', iframeSize]}\n variants={iframeVariants}\n animate={[\n loader && loading ? 'background' : 'active',\n reloading ? 'reloading' : 'idle',\n iframeSize,\n ]}\n {...attributes}\n onLoad={handleIframeLoad}\n />\n </Flex>\n )\n})\n\nconst spinnerVariants = {\n initial: {opacity: 1},\n animate: {opacity: [0, 0, 1]},\n exit: {opacity: [1, 0, 0]},\n}\n\nconst iframeVariants = {\n ...sizes,\n desktop: {\n ...sizes.desktop,\n boxShadow: '0 0 0 0px var(--card-shadow-outline-color)',\n },\n mobile: {\n ...sizes.mobile,\n boxShadow: '0 0 0 1px var(--card-shadow-outline-color)',\n },\n background: {\n opacity: 0,\n scale: 1,\n },\n idle: {\n scale: 1,\n },\n reloading: {\n scale: [1, 1, 1, 0.98],\n },\n active: {\n opacity: [0, 0, 1],\n scale: 1,\n },\n}\n\ninterface ReloadOnRevisionProps {\n _rev?: string\n revision: number | boolean\n handleReload: () => void\n}\nfunction ReloadOnRevision(props: ReloadOnRevisionProps) {\n const {revision, handleReload, _rev} = props\n const [initialRev] = useState(_rev)\n // Reload on new revisions\n // eslint-disable-next-line consistent-return\n useEffect(() => {\n if (_rev !== initialRev) {\n const timeout = setTimeout(handleReload, Number(revision === true ? 300 : revision))\n return () => clearTimeout(timeout)\n }\n }, [_rev, revision, handleReload, initialRev])\n\n return null\n}\n\ninterface AsyncUrlProps {\n displayed: SanityDocument\n url: UrlResolver\n urlSecretId?: UrlSecretId\n setDisplayUrl: (url: UrlState) => void\n setError: SetError\n}\nfunction AsyncUrl(props: AsyncUrlProps) {\n const {urlSecretId, setDisplayUrl, setError} = props\n // Snapshot values we only care about when the revision changes, done by changing the `key` prop\n const [displayed] = useState(props.displayed)\n const [url] = useState(() => props.url)\n const [urlSecret, setUrlSecret] = useState<null | string>(null)\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n if (urlSecretId && !urlSecret) return\n\n const getUrl = async (signal: AbortSignal) => {\n const resolveUrl = await url(displayed, urlSecret, abort.signal)\n\n // Only update state if URL has changed\n if (!signal.aborted && resolveUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n const abort = new AbortController()\n getUrl(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [displayed, setDisplayUrl, setError, url, urlSecret, urlSecretId])\n\n if (urlSecretId) {\n return (\n <GetUrlSecret\n urlSecretId={urlSecretId}\n urlSecret={urlSecret}\n setUrlSecret={setUrlSecret}\n setError={setError}\n />\n )\n }\n\n return null\n}\n\nexport function MissingSlugScreen() {\n return (\n <Card height=\"fill\">\n <Flex align=\"center\" height=\"fill\" justify=\"center\" padding={4} sizing=\"border\">\n <Container width={0}>\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Flex>\n <Box>\n <Text size={1}>\n <WarningOutlineIcon />\n </Text>\n </Box>\n <Stack flex={1} marginLeft={3} space={3}>\n <Text as=\"h1\" size={1} weight=\"bold\">\n Missing slug\n </Text>\n <Text as=\"p\" muted size={1}>\n Add a slug to see the preview.\n </Text>\n </Stack>\n </Flex>\n </Card>\n </Container>\n </Flex>\n </Card>\n )\n}\n"],"names":["GetUrlSecret","props","urlSecretId","setUrlSecret","urlSecret","setError","client","useClient","apiVersion","secretExpiresAt","setSecretExpiresAt","useState","includes","TypeError","concat","useEffect","getSecret","signal","data","fetch","fetchSecretQuery","id","tag","aborted","secret","_updatedAt","newUpdatedAt","Date","newSecret","patchUrlSecret","getExpiresAt","err","console","error","abort","AbortController","catch","name","timeout","setTimeout","Math","max","getTime","clearTimeout","DisplayUrl","_ref","displayUrl","truncatedUrl","useMemo","url","URL","searchParams","has","delete","append","origin","location","pathname","search","jsx","Text","size","textOverflow","title","children","sizes","desktop","width","height","mobile","DEFAULT_SIZE","Toolbar","iframeSize","setIframeSize","reloading","showDisplayUrl","reloadButton","handleReload","input","useRef","push","pushToast","useToast","copy","useCopyToClipboard","jsxs","Fragment","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Card","padding","borderBottom","Flex","align","gap","Tooltip","content","whiteSpace","Button","disabled","fontSize","mode","icon","MobileDeviceIcon","onClick","Box","flex","UndoIcon","transform","loading","ClipboardIcon","_a","current","closable","status","LaunchIcon","paddingY","text","window","open","MotionFlex","motion","Iframe","document","sanityDocument","options","defaultSize","reload","loader","attributes","workaroundEmptyDocument","setWorkaroundEmptyDocument","prefersReducedMotion","usePrefersReducedMotion","urlState","setUrlState","setLoading","setReloading","iframe","displayed","useCallback","src","deferredRevision","useDeferredValue","_rev","MotionConfig","transition","duration","direction","button","MissingSlug","MissingSlugScreen","tone","Frame","AsyncUrl","setDisplayUrl","revision","ReloadOnRevision","forwardRef","handleIframeLoad","onLoad","justify","AnimatePresence","initial","animate","exit","variants","spinnerVariants","inset","Spinner","muted","frameBorder","maxHeight","iframeVariants","boxShadow","background","scale","idle","active","initialRev","Number","getUrl","resolveUrl","sizing","Container","radius","shadow","WarningOutlineIcon","Stack","marginLeft","space","as","weight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/GetUrlSecret.tsx","../src/DisplayUrl.tsx","../src/Toolbar.tsx","../src/Iframe.tsx"],"sourcesContent":["import {useEffect, useState} from 'react'\nimport {useClient} from 'sanity'\n\nimport {apiVersion, fetchSecretQuery, FetchSecretResponse, tag, UrlSecretId} from './isValidSecret'\nimport {SetError} from './types'\nimport {getExpiresAt, patchUrlSecret} from './utils'\n\nexport interface GetUrlSecretProps {\n urlSecretId: UrlSecretId\n urlSecret: string | null\n setUrlSecret: (secret: string | null) => void\n setError: SetError\n}\nexport function GetUrlSecret(props: GetUrlSecretProps) {\n const {urlSecretId, setUrlSecret, urlSecret, setError} = props\n const client = useClient({apiVersion})\n const [secretExpiresAt, setSecretExpiresAt] = useState<null | Date>(null)\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\n useEffect(() => {\n if (urlSecret) return\n\n async function getSecret(signal: AbortSignal): Promise<void> {\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {signal, tag},\n )\n\n if (signal.aborted) return\n\n if (!data?.secret || !data?._updatedAt) {\n try {\n const newUpdatedAt = new Date()\n const newSecret = await patchUrlSecret(client, urlSecretId, signal)\n if (signal.aborted) return\n setUrlSecret(newSecret)\n setSecretExpiresAt(getExpiresAt(newUpdatedAt))\n } catch (err) {\n console.error(\n 'Failed to create a new preview secret. Ensure the `client` has a `token` specified that has `write` permissions.',\n err,\n )\n }\n return\n }\n\n if (data?.secret !== urlSecret) {\n setUrlSecret(data?.secret)\n setSecretExpiresAt(getExpiresAt(new Date(data?._updatedAt)))\n }\n }\n\n const abort = new AbortController()\n getSecret(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [client, setError, setUrlSecret, urlSecret, urlSecretId])\n\n useEffect(() => {\n if (!secretExpiresAt) return\n\n const timeout = setTimeout(\n () => {\n setUrlSecret(null)\n setSecretExpiresAt(null)\n },\n Math.max(0, secretExpiresAt.getTime() - new Date().getTime()),\n )\n // eslint-disable-next-line consistent-return\n return () => clearTimeout(timeout)\n }, [secretExpiresAt, setUrlSecret])\n\n return null\n}\n","import {Text} from '@sanity/ui'\nimport React, {useMemo} from 'react'\n\nexport function DisplayUrl({displayUrl}: {displayUrl: string}) {\n const truncatedUrl = useMemo(() => {\n const url = new URL(displayUrl)\n\n if (url.searchParams.has('secret')) {\n url.searchParams.delete('secret')\n url.searchParams.append('secret', '***')\n }\n\n return `${url.origin === location.origin ? '' : url.origin}${url.pathname}${url.search}`\n }, [displayUrl])\n\n return (\n <Text size={0} textOverflow=\"ellipsis\" title={displayUrl}>\n {truncatedUrl}\n </Text>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {ClipboardIcon, LaunchIcon, MobileDeviceIcon, UndoIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, Tooltip, useToast} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport {useCopyToClipboard} from 'usehooks-ts'\n\nimport {DisplayUrl} from './DisplayUrl'\nimport {IframeSizeKey, type SizeProps} from './types'\n\nexport const sizes: SizeProps = {\n desktop: {\n width: '100%',\n height: '100%',\n },\n mobile: {\n width: 414,\n height: 746,\n },\n}\n\nexport const DEFAULT_SIZE = `desktop`\n\nexport interface ToolbarProps {\n displayUrl: string\n iframeSize: IframeSizeKey\n setIframeSize: (size: IframeSizeKey) => void\n showDisplayUrl: boolean\n reloading: boolean\n reloadButton: boolean\n handleReload: () => void\n}\nexport function Toolbar(props: ToolbarProps) {\n const {\n displayUrl,\n iframeSize,\n setIframeSize,\n reloading,\n showDisplayUrl,\n reloadButton,\n handleReload,\n } = props\n\n const input = useRef<HTMLTextAreaElement>(null)\n const {push: pushToast} = useToast()\n const [, copy] = useCopyToClipboard()\n\n return (\n <>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Card padding={2} borderBottom>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {iframeSize === 'mobile' ? 'Exit mobile preview' : 'Preview mobile viewport'}\n </Text>\n }\n padding={2}\n placement=\"bottom-start\"\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n padding={2}\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Tooltip>\n </Flex>\n <Box flex={1}>\n {showDisplayUrl && displayUrl && <DisplayUrl displayUrl={displayUrl} />}\n </Box>\n <Flex align=\"center\" gap={1}>\n {reloadButton ? (\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {reloading ? 'Reloading…' : 'Reload'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n mode=\"bleed\"\n fontSize={[1]}\n padding={2}\n icon={<UndoIcon style={{transform: 'rotate(90deg) scaleY(-1)'}} />}\n loading={reloading}\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n </Tooltip>\n ) : null}\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Copy URL\n </Text>\n }\n padding={2}\n >\n <Button\n mode=\"bleed\"\n disabled={!displayUrl}\n fontSize={[1]}\n icon={ClipboardIcon}\n padding={[2]}\n aria-label=\"Copy URL\"\n onClick={() => {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n pushToast({\n closable: true,\n status: 'success',\n title: 'The URL is copied to the clipboard',\n })\n }}\n />\n </Tooltip>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Open URL in a new tab\n </Text>\n }\n padding={2}\n placement=\"bottom-end\"\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n icon={LaunchIcon}\n mode=\"ghost\"\n paddingY={[2]}\n text=\"Open\"\n aria-label=\"Open URL in a new tab\"\n onClick={() => window.open(displayUrl)}\n />\n </Tooltip>\n </Flex>\n </Flex>\n </Card>\n </>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport {Box, Card, Container, Flex, Spinner, Stack, Text, usePrefersReducedMotion} from '@sanity/ui'\nimport {AnimatePresence, motion, MotionConfig} from 'framer-motion'\nimport React, {forwardRef, useCallback, useDeferredValue, useEffect, useRef, useState} from 'react'\nimport {HTMLAttributeReferrerPolicy} from 'react'\nimport {SanityDocument} from 'sanity'\n\nimport {UrlResolver} from './defineUrlResolver'\nimport {GetUrlSecret} from './GetUrlSecret'\nimport {UrlSecretId} from './isValidSecret'\nimport {DEFAULT_SIZE, sizes, Toolbar} from './Toolbar'\nimport {IframeSizeKey, MissingSlug, SetError, type UrlState} from './types'\n\nexport type {IframeSizeKey, UrlResolver, UrlSecretId}\n\nexport type IframeOptions = {\n urlSecretId?: UrlSecretId\n url: UrlState | UrlResolver\n defaultSize?: IframeSizeKey\n loader?: string | boolean\n showDisplayUrl?: boolean\n reload?: {\n revision?: boolean | number\n button?: boolean\n }\n attributes?: Partial<{\n allow: string\n referrerPolicy: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n onLoad: () => void\n }>\n}\n\nconst MotionFlex = motion(Flex)\n\nexport interface IframeProps {\n document: {\n displayed: SanityDocument\n }\n options: IframeOptions\n}\n\nexport function Iframe(props: IframeProps) {\n const [error, setError] = useState<unknown>(null)\n if (error) {\n throw error\n }\n\n const {document: sanityDocument, options} = props\n const {\n url,\n urlSecretId,\n defaultSize = DEFAULT_SIZE,\n reload,\n loader = 'Loading…',\n attributes = {},\n showDisplayUrl = true,\n } = options\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n\n // Workaround documents that initially appears to be an empty new document but just hasen't loaded yet\n const [workaroundEmptyDocument, setWorkaroundEmptyDocument] = useState(true)\n useEffect(() => {\n const timeout = setTimeout(() => setWorkaroundEmptyDocument(false), 1000)\n return () => clearTimeout(timeout)\n }, [])\n\n const prefersReducedMotion = usePrefersReducedMotion()\n const [urlState, setUrlState] = useState<UrlState>(() => (typeof url === 'function' ? '' : url))\n\n const [loading, setLoading] = useState(true)\n const [reloading, setReloading] = useState(false)\n\n const iframe = useRef<HTMLIFrameElement>(null)\n const {displayed} = sanityDocument\n\n const handleReload = useCallback(() => {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issues\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n\n setReloading(true)\n }, [])\n\n const deferredRevision = useDeferredValue(displayed._rev)\n const displayUrl = typeof urlState === 'string' ? urlState : ''\n\n return (\n <MotionConfig transition={prefersReducedMotion ? {duration: 0} : undefined}>\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Toolbar\n displayUrl={displayUrl}\n iframeSize={iframeSize}\n reloading={reloading}\n setIframeSize={setIframeSize}\n showDisplayUrl={showDisplayUrl}\n reloadButton={!!reload?.button}\n handleReload={handleReload}\n />\n {urlState === MissingSlug && !workaroundEmptyDocument ? (\n <MissingSlugScreen />\n ) : (\n <Card tone=\"transparent\" style={{height: `100%`}}>\n <Frame\n ref={iframe}\n loader={loader}\n loading={loading}\n reloading={reloading}\n iframeSize={iframeSize}\n setReloading={setReloading}\n setLoading={setLoading}\n displayUrl={displayUrl}\n attributes={attributes}\n />\n </Card>\n )}\n {typeof url === 'function' && (\n <AsyncUrl\n // We use the revision as a key, to force a re-render when the revision changes\n // This allows us to respond to changed props (maybe the url function itself changes)\n // But avoid calling async logic on every render accidentally\n key={deferredRevision}\n url={url}\n displayed={displayed}\n urlSecretId={urlSecretId}\n setDisplayUrl={setUrlState}\n setError={setError}\n />\n )}\n {displayUrl && (reload?.revision || reload?.revision === 0) && (\n <ReloadOnRevision\n revision={reload.revision}\n _rev={deferredRevision}\n handleReload={handleReload}\n />\n )}\n </Flex>\n </MotionConfig>\n )\n}\n\ninterface FrameProps extends Required<Pick<IframeOptions, 'loader' | 'attributes'>> {\n loader: string | boolean\n loading: boolean\n reloading: boolean\n setLoading: (loading: boolean) => void\n setReloading: (reloading: boolean) => void\n iframeSize: IframeSizeKey\n displayUrl: string\n}\nconst Frame = forwardRef(function Frame(\n props: FrameProps,\n iframe: React.ForwardedRef<HTMLIFrameElement>,\n) {\n const {loader, loading, setLoading, iframeSize, attributes, reloading, displayUrl, setReloading} =\n props\n\n function handleIframeLoad() {\n setLoading(false)\n setReloading(false)\n // Run onLoad from attributes\n if (attributes.onLoad && typeof attributes.onLoad === 'function') {\n attributes.onLoad()\n }\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`, position: `relative`}}>\n <AnimatePresence>\n {loader && loading && (\n <MotionFlex\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n variants={spinnerVariants}\n justify=\"center\"\n align=\"center\"\n style={{inset: `0`, position: `absolute`}}\n >\n <Flex\n style={{...sizes[iframeSize]}}\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n gap={4}\n >\n <Spinner muted />\n {loader && typeof loader === 'string' && (\n <Text muted size={1}>\n {loader}\n </Text>\n )}\n </Flex>\n </MotionFlex>\n )}\n </AnimatePresence>\n <motion.iframe\n ref={iframe}\n title=\"preview\"\n frameBorder=\"0\"\n style={{maxHeight: '100%'}}\n src={displayUrl}\n initial={['background', iframeSize]}\n variants={iframeVariants}\n animate={[\n loader && loading ? 'background' : 'active',\n reloading ? 'reloading' : 'idle',\n iframeSize,\n ]}\n {...attributes}\n onLoad={handleIframeLoad}\n />\n </Flex>\n )\n})\n\nconst spinnerVariants = {\n initial: {opacity: 1},\n animate: {opacity: [0, 0, 1]},\n exit: {opacity: [1, 0, 0]},\n}\n\nconst iframeVariants = {\n ...sizes,\n desktop: {\n ...sizes.desktop,\n boxShadow: '0 0 0 0px var(--card-shadow-outline-color)',\n },\n mobile: {\n ...sizes.mobile,\n boxShadow: '0 0 0 1px var(--card-shadow-outline-color)',\n },\n background: {\n opacity: 0,\n scale: 1,\n },\n idle: {\n scale: 1,\n },\n reloading: {\n scale: [1, 1, 1, 0.98],\n },\n active: {\n opacity: [0, 0, 1],\n scale: 1,\n },\n}\n\ninterface ReloadOnRevisionProps {\n _rev?: string\n revision: number | boolean\n handleReload: () => void\n}\nfunction ReloadOnRevision(props: ReloadOnRevisionProps) {\n const {revision, handleReload, _rev} = props\n const [initialRev] = useState(_rev)\n // Reload on new revisions\n // eslint-disable-next-line consistent-return\n useEffect(() => {\n if (_rev !== initialRev) {\n const timeout = setTimeout(handleReload, Number(revision === true ? 300 : revision))\n return () => clearTimeout(timeout)\n }\n }, [_rev, revision, handleReload, initialRev])\n\n return null\n}\n\ninterface AsyncUrlProps {\n displayed: SanityDocument\n url: UrlResolver\n urlSecretId?: UrlSecretId\n setDisplayUrl: (url: UrlState) => void\n setError: SetError\n}\nfunction AsyncUrl(props: AsyncUrlProps) {\n const {urlSecretId, setDisplayUrl, setError} = props\n // Snapshot values we only care about when the revision changes, done by changing the `key` prop\n const [displayed] = useState(props.displayed)\n const [url] = useState(() => props.url)\n const [urlSecret, setUrlSecret] = useState<null | string>(null)\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n if (urlSecretId && !urlSecret) return\n\n const getUrl = async (signal: AbortSignal) => {\n const resolveUrl = await url(displayed, urlSecret, abort.signal)\n\n // Only update state if URL has changed\n if (!signal.aborted && resolveUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n const abort = new AbortController()\n getUrl(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [displayed, setDisplayUrl, setError, url, urlSecret, urlSecretId])\n\n if (urlSecretId) {\n return (\n <GetUrlSecret\n urlSecretId={urlSecretId}\n urlSecret={urlSecret}\n setUrlSecret={setUrlSecret}\n setError={setError}\n />\n )\n }\n\n return null\n}\n\nexport function MissingSlugScreen() {\n return (\n <Card height=\"fill\">\n <Flex align=\"center\" height=\"fill\" justify=\"center\" padding={4} sizing=\"border\">\n <Container width={0}>\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Flex>\n <Box>\n <Text size={1}>\n <WarningOutlineIcon />\n </Text>\n </Box>\n <Stack flex={1} marginLeft={3} space={3}>\n <Text as=\"h1\" size={1} weight=\"bold\">\n Missing slug\n </Text>\n <Text as=\"p\" muted size={1}>\n Add a slug to see the preview.\n </Text>\n </Stack>\n </Flex>\n </Card>\n </Container>\n </Flex>\n </Card>\n )\n}\n"],"names":["GetUrlSecret","props","urlSecretId","setUrlSecret","urlSecret","setError","client","useClient","apiVersion","secretExpiresAt","setSecretExpiresAt","useState","includes","TypeError","concat","useEffect","getSecret","signal","data","fetch","fetchSecretQuery","id","tag","aborted","secret","_updatedAt","newUpdatedAt","Date","newSecret","patchUrlSecret","getExpiresAt","err","console","error","abort","AbortController","catch","name","timeout","setTimeout","Math","max","getTime","clearTimeout","DisplayUrl","_ref","displayUrl","truncatedUrl","useMemo","url","URL","searchParams","has","delete","append","origin","location","pathname","search","jsx","Text","size","textOverflow","title","children","sizes","desktop","width","height","mobile","DEFAULT_SIZE","Toolbar","iframeSize","setIframeSize","reloading","showDisplayUrl","reloadButton","handleReload","input","useRef","push","pushToast","useToast","copy","useCopyToClipboard","jsxs","Fragment","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Card","padding","borderBottom","Flex","align","gap","Tooltip","content","whiteSpace","placement","Button","disabled","fontSize","mode","icon","MobileDeviceIcon","onClick","Box","flex","UndoIcon","transform","loading","ClipboardIcon","_a","current","closable","status","LaunchIcon","paddingY","text","window","open","MotionFlex","motion","Iframe","document","sanityDocument","options","defaultSize","reload","loader","attributes","workaroundEmptyDocument","setWorkaroundEmptyDocument","prefersReducedMotion","usePrefersReducedMotion","urlState","setUrlState","setLoading","setReloading","iframe","displayed","useCallback","src","deferredRevision","useDeferredValue","_rev","MotionConfig","transition","duration","direction","button","MissingSlug","MissingSlugScreen","tone","Frame","AsyncUrl","setDisplayUrl","revision","ReloadOnRevision","forwardRef","handleIframeLoad","onLoad","justify","AnimatePresence","initial","animate","exit","variants","spinnerVariants","inset","Spinner","muted","frameBorder","maxHeight","iframeVariants","boxShadow","background","scale","idle","active","initialRev","Number","getUrl","resolveUrl","sizing","Container","radius","shadow","WarningOutlineIcon","Stack","marginLeft","space","as","weight"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { patchUrlSecret, getExpiresAt, MissingSlug } from './_chunks/utils-
|
|
2
|
-
export { defineUrlResolver } from './_chunks/utils-
|
|
1
|
+
import { patchUrlSecret, getExpiresAt, MissingSlug } from './_chunks/utils-771d70cf.js';
|
|
2
|
+
export { defineUrlResolver } from './_chunks/utils-771d70cf.js';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { MobileDeviceIcon, UndoIcon, ClipboardIcon, LaunchIcon, WarningOutlineIcon } from '@sanity/icons';
|
|
5
5
|
import { Text, useToast, Card, Flex, Tooltip, Button, Box, Spinner, usePrefersReducedMotion, Container, Stack } from '@sanity/ui';
|
|
6
6
|
import { motion, AnimatePresence, MotionConfig } from 'framer-motion';
|
|
7
7
|
import { useState, useEffect, useMemo, useRef, forwardRef, useCallback, useDeferredValue } from 'react';
|
|
8
8
|
import { useClient } from 'sanity';
|
|
9
|
-
import { apiVersion, fetchSecretQuery, tag } from './_chunks/is-valid-secret-
|
|
9
|
+
import { apiVersion, fetchSecretQuery, tag } from './_chunks/is-valid-secret-926b3d57.js';
|
|
10
10
|
import { useCopyToClipboard } from 'usehooks-ts';
|
|
11
11
|
function GetUrlSecret(props) {
|
|
12
12
|
const {
|
|
@@ -137,6 +137,7 @@ function Toolbar(props) {
|
|
|
137
137
|
children: iframeSize === "mobile" ? "Exit mobile preview" : "Preview mobile viewport"
|
|
138
138
|
}),
|
|
139
139
|
padding: 2,
|
|
140
|
+
placement: "bottom-start",
|
|
140
141
|
children: /* @__PURE__ */jsx(Button, {
|
|
141
142
|
disabled: !displayUrl,
|
|
142
143
|
fontSize: [1],
|
|
@@ -213,6 +214,7 @@ function Toolbar(props) {
|
|
|
213
214
|
children: "Open URL in a new tab"
|
|
214
215
|
}),
|
|
215
216
|
padding: 2,
|
|
217
|
+
placement: "bottom-end",
|
|
216
218
|
children: /* @__PURE__ */jsx(Button, {
|
|
217
219
|
disabled: !displayUrl,
|
|
218
220
|
fontSize: [1],
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/GetUrlSecret.tsx","../src/DisplayUrl.tsx","../src/Toolbar.tsx","../src/Iframe.tsx"],"sourcesContent":["import {useEffect, useState} from 'react'\nimport {useClient} from 'sanity'\n\nimport {apiVersion, fetchSecretQuery, FetchSecretResponse, tag, UrlSecretId} from './isValidSecret'\nimport {SetError} from './types'\nimport {getExpiresAt, patchUrlSecret} from './utils'\n\nexport interface GetUrlSecretProps {\n urlSecretId: UrlSecretId\n urlSecret: string | null\n setUrlSecret: (secret: string | null) => void\n setError: SetError\n}\nexport function GetUrlSecret(props: GetUrlSecretProps) {\n const {urlSecretId, setUrlSecret, urlSecret, setError} = props\n const client = useClient({apiVersion})\n const [secretExpiresAt, setSecretExpiresAt] = useState<null | Date>(null)\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\n useEffect(() => {\n if (urlSecret) return\n\n async function getSecret(signal: AbortSignal): Promise<void> {\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {signal, tag},\n )\n\n if (signal.aborted) return\n\n if (!data?.secret || !data?._updatedAt) {\n try {\n const newUpdatedAt = new Date()\n const newSecret = await patchUrlSecret(client, urlSecretId, signal)\n if (signal.aborted) return\n setUrlSecret(newSecret)\n setSecretExpiresAt(getExpiresAt(newUpdatedAt))\n } catch (err) {\n console.error(\n 'Failed to create a new preview secret. Ensure the `client` has a `token` specified that has `write` permissions.',\n err,\n )\n }\n return\n }\n\n if (data?.secret !== urlSecret) {\n setUrlSecret(data?.secret)\n setSecretExpiresAt(getExpiresAt(new Date(data?._updatedAt)))\n }\n }\n\n const abort = new AbortController()\n getSecret(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [client, setError, setUrlSecret, urlSecret, urlSecretId])\n\n useEffect(() => {\n if (!secretExpiresAt) return\n\n const timeout = setTimeout(\n () => {\n setUrlSecret(null)\n setSecretExpiresAt(null)\n },\n Math.max(0, secretExpiresAt.getTime() - new Date().getTime()),\n )\n // eslint-disable-next-line consistent-return\n return () => clearTimeout(timeout)\n }, [secretExpiresAt, setUrlSecret])\n\n return null\n}\n","import {Text} from '@sanity/ui'\nimport React, {useMemo} from 'react'\n\nexport function DisplayUrl({displayUrl}: {displayUrl: string}) {\n const truncatedUrl = useMemo(() => {\n const url = new URL(displayUrl)\n\n if (url.searchParams.has('secret')) {\n url.searchParams.delete('secret')\n url.searchParams.append('secret', '***')\n }\n\n return `${url.origin === location.origin ? '' : url.origin}${url.pathname}${url.search}`\n }, [displayUrl])\n\n return (\n <Text size={0} textOverflow=\"ellipsis\" title={displayUrl}>\n {truncatedUrl}\n </Text>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {ClipboardIcon, LaunchIcon, MobileDeviceIcon, UndoIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, Tooltip, useToast} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport {useCopyToClipboard} from 'usehooks-ts'\n\nimport {DisplayUrl} from './DisplayUrl'\nimport {IframeSizeKey, type SizeProps} from './types'\n\nexport const sizes: SizeProps = {\n desktop: {\n width: '100%',\n height: '100%',\n },\n mobile: {\n width: 414,\n height: 746,\n },\n}\n\nexport const DEFAULT_SIZE = `desktop`\n\nexport interface ToolbarProps {\n displayUrl: string\n iframeSize: IframeSizeKey\n setIframeSize: (size: IframeSizeKey) => void\n showDisplayUrl: boolean\n reloading: boolean\n reloadButton: boolean\n handleReload: () => void\n}\nexport function Toolbar(props: ToolbarProps) {\n const {\n displayUrl,\n iframeSize,\n setIframeSize,\n reloading,\n showDisplayUrl,\n reloadButton,\n handleReload,\n } = props\n\n const input = useRef<HTMLTextAreaElement>(null)\n const {push: pushToast} = useToast()\n const [, copy] = useCopyToClipboard()\n\n return (\n <>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Card padding={2} borderBottom>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {iframeSize === 'mobile' ? 'Exit mobile preview' : 'Preview mobile viewport'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n padding={2}\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Tooltip>\n </Flex>\n <Box flex={1}>\n {showDisplayUrl && displayUrl && <DisplayUrl displayUrl={displayUrl} />}\n </Box>\n <Flex align=\"center\" gap={1}>\n {reloadButton ? (\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {reloading ? 'Reloading…' : 'Reload'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n mode=\"bleed\"\n fontSize={[1]}\n padding={2}\n icon={<UndoIcon style={{transform: 'rotate(90deg) scaleY(-1)'}} />}\n loading={reloading}\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n </Tooltip>\n ) : null}\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Copy URL\n </Text>\n }\n padding={2}\n >\n <Button\n mode=\"bleed\"\n disabled={!displayUrl}\n fontSize={[1]}\n icon={ClipboardIcon}\n padding={[2]}\n aria-label=\"Copy URL\"\n onClick={() => {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n pushToast({\n closable: true,\n status: 'success',\n title: 'The URL is copied to the clipboard',\n })\n }}\n />\n </Tooltip>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Open URL in a new tab\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n icon={LaunchIcon}\n mode=\"ghost\"\n paddingY={[2]}\n text=\"Open\"\n aria-label=\"Open URL in a new tab\"\n onClick={() => window.open(displayUrl)}\n />\n </Tooltip>\n </Flex>\n </Flex>\n </Card>\n </>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport {Box, Card, Container, Flex, Spinner, Stack, Text, usePrefersReducedMotion} from '@sanity/ui'\nimport {AnimatePresence, motion, MotionConfig} from 'framer-motion'\nimport React, {forwardRef, useCallback, useDeferredValue, useEffect, useRef, useState} from 'react'\nimport {HTMLAttributeReferrerPolicy} from 'react'\nimport {SanityDocument} from 'sanity'\n\nimport {UrlResolver} from './defineUrlResolver'\nimport {GetUrlSecret} from './GetUrlSecret'\nimport {UrlSecretId} from './isValidSecret'\nimport {DEFAULT_SIZE, sizes, Toolbar} from './Toolbar'\nimport {IframeSizeKey, MissingSlug, SetError, type UrlState} from './types'\n\nexport type {IframeSizeKey, UrlResolver, UrlSecretId}\n\nexport type IframeOptions = {\n urlSecretId?: UrlSecretId\n url: UrlState | UrlResolver\n defaultSize?: IframeSizeKey\n loader?: string | boolean\n showDisplayUrl?: boolean\n reload?: {\n revision?: boolean | number\n button?: boolean\n }\n attributes?: Partial<{\n allow: string\n referrerPolicy: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n onLoad: () => void\n }>\n}\n\nconst MotionFlex = motion(Flex)\n\nexport interface IframeProps {\n document: {\n displayed: SanityDocument\n }\n options: IframeOptions\n}\n\nexport function Iframe(props: IframeProps) {\n const [error, setError] = useState<unknown>(null)\n if (error) {\n throw error\n }\n\n const {document: sanityDocument, options} = props\n const {\n url,\n urlSecretId,\n defaultSize = DEFAULT_SIZE,\n reload,\n loader = 'Loading…',\n attributes = {},\n showDisplayUrl = true,\n } = options\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n\n // Workaround documents that initially appears to be an empty new document but just hasen't loaded yet\n const [workaroundEmptyDocument, setWorkaroundEmptyDocument] = useState(true)\n useEffect(() => {\n const timeout = setTimeout(() => setWorkaroundEmptyDocument(false), 1000)\n return () => clearTimeout(timeout)\n }, [])\n\n const prefersReducedMotion = usePrefersReducedMotion()\n const [urlState, setUrlState] = useState<UrlState>(() => (typeof url === 'function' ? '' : url))\n\n const [loading, setLoading] = useState(true)\n const [reloading, setReloading] = useState(false)\n\n const iframe = useRef<HTMLIFrameElement>(null)\n const {displayed} = sanityDocument\n\n const handleReload = useCallback(() => {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issues\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n\n setReloading(true)\n }, [])\n\n const deferredRevision = useDeferredValue(displayed._rev)\n const displayUrl = typeof urlState === 'string' ? urlState : ''\n\n return (\n <MotionConfig transition={prefersReducedMotion ? {duration: 0} : undefined}>\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Toolbar\n displayUrl={displayUrl}\n iframeSize={iframeSize}\n reloading={reloading}\n setIframeSize={setIframeSize}\n showDisplayUrl={showDisplayUrl}\n reloadButton={!!reload?.button}\n handleReload={handleReload}\n />\n {urlState === MissingSlug && !workaroundEmptyDocument ? (\n <MissingSlugScreen />\n ) : (\n <Card tone=\"transparent\" style={{height: `100%`}}>\n <Frame\n ref={iframe}\n loader={loader}\n loading={loading}\n reloading={reloading}\n iframeSize={iframeSize}\n setReloading={setReloading}\n setLoading={setLoading}\n displayUrl={displayUrl}\n attributes={attributes}\n />\n </Card>\n )}\n {typeof url === 'function' && (\n <AsyncUrl\n // We use the revision as a key, to force a re-render when the revision changes\n // This allows us to respond to changed props (maybe the url function itself changes)\n // But avoid calling async logic on every render accidentally\n key={deferredRevision}\n url={url}\n displayed={displayed}\n urlSecretId={urlSecretId}\n setDisplayUrl={setUrlState}\n setError={setError}\n />\n )}\n {displayUrl && (reload?.revision || reload?.revision === 0) && (\n <ReloadOnRevision\n revision={reload.revision}\n _rev={deferredRevision}\n handleReload={handleReload}\n />\n )}\n </Flex>\n </MotionConfig>\n )\n}\n\ninterface FrameProps extends Required<Pick<IframeOptions, 'loader' | 'attributes'>> {\n loader: string | boolean\n loading: boolean\n reloading: boolean\n setLoading: (loading: boolean) => void\n setReloading: (reloading: boolean) => void\n iframeSize: IframeSizeKey\n displayUrl: string\n}\nconst Frame = forwardRef(function Frame(\n props: FrameProps,\n iframe: React.ForwardedRef<HTMLIFrameElement>,\n) {\n const {loader, loading, setLoading, iframeSize, attributes, reloading, displayUrl, setReloading} =\n props\n\n function handleIframeLoad() {\n setLoading(false)\n setReloading(false)\n // Run onLoad from attributes\n if (attributes.onLoad && typeof attributes.onLoad === 'function') {\n attributes.onLoad()\n }\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`, position: `relative`}}>\n <AnimatePresence>\n {loader && loading && (\n <MotionFlex\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n variants={spinnerVariants}\n justify=\"center\"\n align=\"center\"\n style={{inset: `0`, position: `absolute`}}\n >\n <Flex\n style={{...sizes[iframeSize]}}\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n gap={4}\n >\n <Spinner muted />\n {loader && typeof loader === 'string' && (\n <Text muted size={1}>\n {loader}\n </Text>\n )}\n </Flex>\n </MotionFlex>\n )}\n </AnimatePresence>\n <motion.iframe\n ref={iframe}\n title=\"preview\"\n frameBorder=\"0\"\n style={{maxHeight: '100%'}}\n src={displayUrl}\n initial={['background', iframeSize]}\n variants={iframeVariants}\n animate={[\n loader && loading ? 'background' : 'active',\n reloading ? 'reloading' : 'idle',\n iframeSize,\n ]}\n {...attributes}\n onLoad={handleIframeLoad}\n />\n </Flex>\n )\n})\n\nconst spinnerVariants = {\n initial: {opacity: 1},\n animate: {opacity: [0, 0, 1]},\n exit: {opacity: [1, 0, 0]},\n}\n\nconst iframeVariants = {\n ...sizes,\n desktop: {\n ...sizes.desktop,\n boxShadow: '0 0 0 0px var(--card-shadow-outline-color)',\n },\n mobile: {\n ...sizes.mobile,\n boxShadow: '0 0 0 1px var(--card-shadow-outline-color)',\n },\n background: {\n opacity: 0,\n scale: 1,\n },\n idle: {\n scale: 1,\n },\n reloading: {\n scale: [1, 1, 1, 0.98],\n },\n active: {\n opacity: [0, 0, 1],\n scale: 1,\n },\n}\n\ninterface ReloadOnRevisionProps {\n _rev?: string\n revision: number | boolean\n handleReload: () => void\n}\nfunction ReloadOnRevision(props: ReloadOnRevisionProps) {\n const {revision, handleReload, _rev} = props\n const [initialRev] = useState(_rev)\n // Reload on new revisions\n // eslint-disable-next-line consistent-return\n useEffect(() => {\n if (_rev !== initialRev) {\n const timeout = setTimeout(handleReload, Number(revision === true ? 300 : revision))\n return () => clearTimeout(timeout)\n }\n }, [_rev, revision, handleReload, initialRev])\n\n return null\n}\n\ninterface AsyncUrlProps {\n displayed: SanityDocument\n url: UrlResolver\n urlSecretId?: UrlSecretId\n setDisplayUrl: (url: UrlState) => void\n setError: SetError\n}\nfunction AsyncUrl(props: AsyncUrlProps) {\n const {urlSecretId, setDisplayUrl, setError} = props\n // Snapshot values we only care about when the revision changes, done by changing the `key` prop\n const [displayed] = useState(props.displayed)\n const [url] = useState(() => props.url)\n const [urlSecret, setUrlSecret] = useState<null | string>(null)\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n if (urlSecretId && !urlSecret) return\n\n const getUrl = async (signal: AbortSignal) => {\n const resolveUrl = await url(displayed, urlSecret, abort.signal)\n\n // Only update state if URL has changed\n if (!signal.aborted && resolveUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n const abort = new AbortController()\n getUrl(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [displayed, setDisplayUrl, setError, url, urlSecret, urlSecretId])\n\n if (urlSecretId) {\n return (\n <GetUrlSecret\n urlSecretId={urlSecretId}\n urlSecret={urlSecret}\n setUrlSecret={setUrlSecret}\n setError={setError}\n />\n )\n }\n\n return null\n}\n\nexport function MissingSlugScreen() {\n return (\n <Card height=\"fill\">\n <Flex align=\"center\" height=\"fill\" justify=\"center\" padding={4} sizing=\"border\">\n <Container width={0}>\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Flex>\n <Box>\n <Text size={1}>\n <WarningOutlineIcon />\n </Text>\n </Box>\n <Stack flex={1} marginLeft={3} space={3}>\n <Text as=\"h1\" size={1} weight=\"bold\">\n Missing slug\n </Text>\n <Text as=\"p\" muted size={1}>\n Add a slug to see the preview.\n </Text>\n </Stack>\n </Flex>\n </Card>\n </Container>\n </Flex>\n </Card>\n )\n}\n"],"names":["GetUrlSecret","props","urlSecretId","setUrlSecret","urlSecret","setError","client","useClient","apiVersion","secretExpiresAt","setSecretExpiresAt","useState","includes","TypeError","concat","useEffect","getSecret","signal","data","fetch","fetchSecretQuery","id","tag","aborted","secret","_updatedAt","newUpdatedAt","Date","newSecret","patchUrlSecret","getExpiresAt","err","console","error","abort","AbortController","catch","name","timeout","setTimeout","Math","max","getTime","clearTimeout","DisplayUrl","_ref","displayUrl","truncatedUrl","useMemo","url","URL","searchParams","has","delete","append","origin","location","pathname","search","jsx","Text","size","textOverflow","title","children","sizes","desktop","width","height","mobile","DEFAULT_SIZE","Toolbar","iframeSize","setIframeSize","reloading","showDisplayUrl","reloadButton","handleReload","input","useRef","push","pushToast","useToast","copy","useCopyToClipboard","jsxs","Fragment","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Card","padding","borderBottom","Flex","align","gap","Tooltip","content","whiteSpace","Button","disabled","fontSize","mode","icon","MobileDeviceIcon","onClick","Box","flex","UndoIcon","transform","loading","ClipboardIcon","_a","current","closable","status","LaunchIcon","paddingY","text","window","open","MotionFlex","motion","Iframe","document","sanityDocument","options","defaultSize","reload","loader","attributes","workaroundEmptyDocument","setWorkaroundEmptyDocument","prefersReducedMotion","usePrefersReducedMotion","urlState","setUrlState","setLoading","setReloading","iframe","displayed","useCallback","src","deferredRevision","useDeferredValue","_rev","MotionConfig","transition","duration","direction","button","MissingSlug","MissingSlugScreen","tone","Frame","AsyncUrl","setDisplayUrl","revision","ReloadOnRevision","forwardRef","handleIframeLoad","onLoad","justify","AnimatePresence","initial","animate","exit","variants","spinnerVariants","inset","Spinner","muted","frameBorder","maxHeight","iframeVariants","boxShadow","background","scale","idle","active","initialRev","Number","getUrl","resolveUrl","sizing","Container","radius","shadow","WarningOutlineIcon","Stack","marginLeft","space","as","weight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/GetUrlSecret.tsx","../src/DisplayUrl.tsx","../src/Toolbar.tsx","../src/Iframe.tsx"],"sourcesContent":["import {useEffect, useState} from 'react'\nimport {useClient} from 'sanity'\n\nimport {apiVersion, fetchSecretQuery, FetchSecretResponse, tag, UrlSecretId} from './isValidSecret'\nimport {SetError} from './types'\nimport {getExpiresAt, patchUrlSecret} from './utils'\n\nexport interface GetUrlSecretProps {\n urlSecretId: UrlSecretId\n urlSecret: string | null\n setUrlSecret: (secret: string | null) => void\n setError: SetError\n}\nexport function GetUrlSecret(props: GetUrlSecretProps) {\n const {urlSecretId, setUrlSecret, urlSecret, setError} = props\n const client = useClient({apiVersion})\n const [secretExpiresAt, setSecretExpiresAt] = useState<null | Date>(null)\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\n useEffect(() => {\n if (urlSecret) return\n\n async function getSecret(signal: AbortSignal): Promise<void> {\n const data = await client.fetch<FetchSecretResponse>(\n fetchSecretQuery,\n {id: urlSecretId},\n {signal, tag},\n )\n\n if (signal.aborted) return\n\n if (!data?.secret || !data?._updatedAt) {\n try {\n const newUpdatedAt = new Date()\n const newSecret = await patchUrlSecret(client, urlSecretId, signal)\n if (signal.aborted) return\n setUrlSecret(newSecret)\n setSecretExpiresAt(getExpiresAt(newUpdatedAt))\n } catch (err) {\n console.error(\n 'Failed to create a new preview secret. Ensure the `client` has a `token` specified that has `write` permissions.',\n err,\n )\n }\n return\n }\n\n if (data?.secret !== urlSecret) {\n setUrlSecret(data?.secret)\n setSecretExpiresAt(getExpiresAt(new Date(data?._updatedAt)))\n }\n }\n\n const abort = new AbortController()\n getSecret(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [client, setError, setUrlSecret, urlSecret, urlSecretId])\n\n useEffect(() => {\n if (!secretExpiresAt) return\n\n const timeout = setTimeout(\n () => {\n setUrlSecret(null)\n setSecretExpiresAt(null)\n },\n Math.max(0, secretExpiresAt.getTime() - new Date().getTime()),\n )\n // eslint-disable-next-line consistent-return\n return () => clearTimeout(timeout)\n }, [secretExpiresAt, setUrlSecret])\n\n return null\n}\n","import {Text} from '@sanity/ui'\nimport React, {useMemo} from 'react'\n\nexport function DisplayUrl({displayUrl}: {displayUrl: string}) {\n const truncatedUrl = useMemo(() => {\n const url = new URL(displayUrl)\n\n if (url.searchParams.has('secret')) {\n url.searchParams.delete('secret')\n url.searchParams.append('secret', '***')\n }\n\n return `${url.origin === location.origin ? '' : url.origin}${url.pathname}${url.search}`\n }, [displayUrl])\n\n return (\n <Text size={0} textOverflow=\"ellipsis\" title={displayUrl}>\n {truncatedUrl}\n </Text>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {ClipboardIcon, LaunchIcon, MobileDeviceIcon, UndoIcon} from '@sanity/icons'\nimport {Box, Button, Card, Flex, Text, Tooltip, useToast} from '@sanity/ui'\nimport React, {useRef} from 'react'\nimport {useCopyToClipboard} from 'usehooks-ts'\n\nimport {DisplayUrl} from './DisplayUrl'\nimport {IframeSizeKey, type SizeProps} from './types'\n\nexport const sizes: SizeProps = {\n desktop: {\n width: '100%',\n height: '100%',\n },\n mobile: {\n width: 414,\n height: 746,\n },\n}\n\nexport const DEFAULT_SIZE = `desktop`\n\nexport interface ToolbarProps {\n displayUrl: string\n iframeSize: IframeSizeKey\n setIframeSize: (size: IframeSizeKey) => void\n showDisplayUrl: boolean\n reloading: boolean\n reloadButton: boolean\n handleReload: () => void\n}\nexport function Toolbar(props: ToolbarProps) {\n const {\n displayUrl,\n iframeSize,\n setIframeSize,\n reloading,\n showDisplayUrl,\n reloadButton,\n handleReload,\n } = props\n\n const input = useRef<HTMLTextAreaElement>(null)\n const {push: pushToast} = useToast()\n const [, copy] = useCopyToClipboard()\n\n return (\n <>\n <textarea\n style={{position: `absolute`, pointerEvents: `none`, opacity: 0}}\n ref={input}\n value={displayUrl}\n readOnly\n tabIndex={-1}\n />\n <Card padding={2} borderBottom>\n <Flex align=\"center\" gap={2}>\n <Flex align=\"center\" gap={1}>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {iframeSize === 'mobile' ? 'Exit mobile preview' : 'Preview mobile viewport'}\n </Text>\n }\n padding={2}\n placement=\"bottom-start\"\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n padding={2}\n mode={iframeSize === 'mobile' ? 'default' : 'ghost'}\n icon={MobileDeviceIcon}\n onClick={() => setIframeSize(iframeSize === 'mobile' ? 'desktop' : 'mobile')}\n />\n </Tooltip>\n </Flex>\n <Box flex={1}>\n {showDisplayUrl && displayUrl && <DisplayUrl displayUrl={displayUrl} />}\n </Box>\n <Flex align=\"center\" gap={1}>\n {reloadButton ? (\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n {reloading ? 'Reloading…' : 'Reload'}\n </Text>\n }\n padding={2}\n >\n <Button\n disabled={!displayUrl}\n mode=\"bleed\"\n fontSize={[1]}\n padding={2}\n icon={<UndoIcon style={{transform: 'rotate(90deg) scaleY(-1)'}} />}\n loading={reloading}\n aria-label=\"Reload\"\n onClick={() => handleReload()}\n />\n </Tooltip>\n ) : null}\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Copy URL\n </Text>\n }\n padding={2}\n >\n <Button\n mode=\"bleed\"\n disabled={!displayUrl}\n fontSize={[1]}\n icon={ClipboardIcon}\n padding={[2]}\n aria-label=\"Copy URL\"\n onClick={() => {\n if (!input?.current?.value) return\n\n copy(input.current.value)\n pushToast({\n closable: true,\n status: 'success',\n title: 'The URL is copied to the clipboard',\n })\n }}\n />\n </Tooltip>\n <Tooltip\n content={\n <Text size={1} style={{whiteSpace: 'nowrap'}}>\n Open URL in a new tab\n </Text>\n }\n padding={2}\n placement=\"bottom-end\"\n >\n <Button\n disabled={!displayUrl}\n fontSize={[1]}\n icon={LaunchIcon}\n mode=\"ghost\"\n paddingY={[2]}\n text=\"Open\"\n aria-label=\"Open URL in a new tab\"\n onClick={() => window.open(displayUrl)}\n />\n </Tooltip>\n </Flex>\n </Flex>\n </Card>\n </>\n )\n}\n","/* eslint-disable react/jsx-no-bind */\nimport {WarningOutlineIcon} from '@sanity/icons'\nimport {Box, Card, Container, Flex, Spinner, Stack, Text, usePrefersReducedMotion} from '@sanity/ui'\nimport {AnimatePresence, motion, MotionConfig} from 'framer-motion'\nimport React, {forwardRef, useCallback, useDeferredValue, useEffect, useRef, useState} from 'react'\nimport {HTMLAttributeReferrerPolicy} from 'react'\nimport {SanityDocument} from 'sanity'\n\nimport {UrlResolver} from './defineUrlResolver'\nimport {GetUrlSecret} from './GetUrlSecret'\nimport {UrlSecretId} from './isValidSecret'\nimport {DEFAULT_SIZE, sizes, Toolbar} from './Toolbar'\nimport {IframeSizeKey, MissingSlug, SetError, type UrlState} from './types'\n\nexport type {IframeSizeKey, UrlResolver, UrlSecretId}\n\nexport type IframeOptions = {\n urlSecretId?: UrlSecretId\n url: UrlState | UrlResolver\n defaultSize?: IframeSizeKey\n loader?: string | boolean\n showDisplayUrl?: boolean\n reload?: {\n revision?: boolean | number\n button?: boolean\n }\n attributes?: Partial<{\n allow: string\n referrerPolicy: HTMLAttributeReferrerPolicy | undefined\n sandbox: string\n onLoad: () => void\n }>\n}\n\nconst MotionFlex = motion(Flex)\n\nexport interface IframeProps {\n document: {\n displayed: SanityDocument\n }\n options: IframeOptions\n}\n\nexport function Iframe(props: IframeProps) {\n const [error, setError] = useState<unknown>(null)\n if (error) {\n throw error\n }\n\n const {document: sanityDocument, options} = props\n const {\n url,\n urlSecretId,\n defaultSize = DEFAULT_SIZE,\n reload,\n loader = 'Loading…',\n attributes = {},\n showDisplayUrl = true,\n } = options\n const [iframeSize, setIframeSize] = useState(sizes?.[defaultSize] ? defaultSize : DEFAULT_SIZE)\n\n // Workaround documents that initially appears to be an empty new document but just hasen't loaded yet\n const [workaroundEmptyDocument, setWorkaroundEmptyDocument] = useState(true)\n useEffect(() => {\n const timeout = setTimeout(() => setWorkaroundEmptyDocument(false), 1000)\n return () => clearTimeout(timeout)\n }, [])\n\n const prefersReducedMotion = usePrefersReducedMotion()\n const [urlState, setUrlState] = useState<UrlState>(() => (typeof url === 'function' ? '' : url))\n\n const [loading, setLoading] = useState(true)\n const [reloading, setReloading] = useState(false)\n\n const iframe = useRef<HTMLIFrameElement>(null)\n const {displayed} = sanityDocument\n\n const handleReload = useCallback(() => {\n if (!iframe?.current) {\n return\n }\n\n // Funky way to reload an iframe without CORS issues\n // eslint-disable-next-line no-self-assign\n iframe.current.src = iframe.current.src\n\n setReloading(true)\n }, [])\n\n const deferredRevision = useDeferredValue(displayed._rev)\n const displayUrl = typeof urlState === 'string' ? urlState : ''\n\n return (\n <MotionConfig transition={prefersReducedMotion ? {duration: 0} : undefined}>\n <Flex direction=\"column\" style={{height: `100%`}}>\n <Toolbar\n displayUrl={displayUrl}\n iframeSize={iframeSize}\n reloading={reloading}\n setIframeSize={setIframeSize}\n showDisplayUrl={showDisplayUrl}\n reloadButton={!!reload?.button}\n handleReload={handleReload}\n />\n {urlState === MissingSlug && !workaroundEmptyDocument ? (\n <MissingSlugScreen />\n ) : (\n <Card tone=\"transparent\" style={{height: `100%`}}>\n <Frame\n ref={iframe}\n loader={loader}\n loading={loading}\n reloading={reloading}\n iframeSize={iframeSize}\n setReloading={setReloading}\n setLoading={setLoading}\n displayUrl={displayUrl}\n attributes={attributes}\n />\n </Card>\n )}\n {typeof url === 'function' && (\n <AsyncUrl\n // We use the revision as a key, to force a re-render when the revision changes\n // This allows us to respond to changed props (maybe the url function itself changes)\n // But avoid calling async logic on every render accidentally\n key={deferredRevision}\n url={url}\n displayed={displayed}\n urlSecretId={urlSecretId}\n setDisplayUrl={setUrlState}\n setError={setError}\n />\n )}\n {displayUrl && (reload?.revision || reload?.revision === 0) && (\n <ReloadOnRevision\n revision={reload.revision}\n _rev={deferredRevision}\n handleReload={handleReload}\n />\n )}\n </Flex>\n </MotionConfig>\n )\n}\n\ninterface FrameProps extends Required<Pick<IframeOptions, 'loader' | 'attributes'>> {\n loader: string | boolean\n loading: boolean\n reloading: boolean\n setLoading: (loading: boolean) => void\n setReloading: (reloading: boolean) => void\n iframeSize: IframeSizeKey\n displayUrl: string\n}\nconst Frame = forwardRef(function Frame(\n props: FrameProps,\n iframe: React.ForwardedRef<HTMLIFrameElement>,\n) {\n const {loader, loading, setLoading, iframeSize, attributes, reloading, displayUrl, setReloading} =\n props\n\n function handleIframeLoad() {\n setLoading(false)\n setReloading(false)\n // Run onLoad from attributes\n if (attributes.onLoad && typeof attributes.onLoad === 'function') {\n attributes.onLoad()\n }\n }\n\n return (\n <Flex align=\"center\" justify=\"center\" style={{height: `100%`, position: `relative`}}>\n <AnimatePresence>\n {loader && loading && (\n <MotionFlex\n initial=\"initial\"\n animate=\"animate\"\n exit=\"exit\"\n variants={spinnerVariants}\n justify=\"center\"\n align=\"center\"\n style={{inset: `0`, position: `absolute`}}\n >\n <Flex\n style={{...sizes[iframeSize]}}\n justify=\"center\"\n align=\"center\"\n direction=\"column\"\n gap={4}\n >\n <Spinner muted />\n {loader && typeof loader === 'string' && (\n <Text muted size={1}>\n {loader}\n </Text>\n )}\n </Flex>\n </MotionFlex>\n )}\n </AnimatePresence>\n <motion.iframe\n ref={iframe}\n title=\"preview\"\n frameBorder=\"0\"\n style={{maxHeight: '100%'}}\n src={displayUrl}\n initial={['background', iframeSize]}\n variants={iframeVariants}\n animate={[\n loader && loading ? 'background' : 'active',\n reloading ? 'reloading' : 'idle',\n iframeSize,\n ]}\n {...attributes}\n onLoad={handleIframeLoad}\n />\n </Flex>\n )\n})\n\nconst spinnerVariants = {\n initial: {opacity: 1},\n animate: {opacity: [0, 0, 1]},\n exit: {opacity: [1, 0, 0]},\n}\n\nconst iframeVariants = {\n ...sizes,\n desktop: {\n ...sizes.desktop,\n boxShadow: '0 0 0 0px var(--card-shadow-outline-color)',\n },\n mobile: {\n ...sizes.mobile,\n boxShadow: '0 0 0 1px var(--card-shadow-outline-color)',\n },\n background: {\n opacity: 0,\n scale: 1,\n },\n idle: {\n scale: 1,\n },\n reloading: {\n scale: [1, 1, 1, 0.98],\n },\n active: {\n opacity: [0, 0, 1],\n scale: 1,\n },\n}\n\ninterface ReloadOnRevisionProps {\n _rev?: string\n revision: number | boolean\n handleReload: () => void\n}\nfunction ReloadOnRevision(props: ReloadOnRevisionProps) {\n const {revision, handleReload, _rev} = props\n const [initialRev] = useState(_rev)\n // Reload on new revisions\n // eslint-disable-next-line consistent-return\n useEffect(() => {\n if (_rev !== initialRev) {\n const timeout = setTimeout(handleReload, Number(revision === true ? 300 : revision))\n return () => clearTimeout(timeout)\n }\n }, [_rev, revision, handleReload, initialRev])\n\n return null\n}\n\ninterface AsyncUrlProps {\n displayed: SanityDocument\n url: UrlResolver\n urlSecretId?: UrlSecretId\n setDisplayUrl: (url: UrlState) => void\n setError: SetError\n}\nfunction AsyncUrl(props: AsyncUrlProps) {\n const {urlSecretId, setDisplayUrl, setError} = props\n // Snapshot values we only care about when the revision changes, done by changing the `key` prop\n const [displayed] = useState(props.displayed)\n const [url] = useState(() => props.url)\n const [urlSecret, setUrlSecret] = useState<null | string>(null)\n\n // Set initial URL and refresh on new revisions\n useEffect(() => {\n if (urlSecretId && !urlSecret) return\n\n const getUrl = async (signal: AbortSignal) => {\n const resolveUrl = await url(displayed, urlSecret, abort.signal)\n\n // Only update state if URL has changed\n if (!signal.aborted && resolveUrl) {\n setDisplayUrl(resolveUrl)\n }\n }\n\n const abort = new AbortController()\n getUrl(abort.signal).catch((error) => error.name !== 'AbortError' && setError(error))\n // eslint-disable-next-line consistent-return\n return () => abort.abort()\n }, [displayed, setDisplayUrl, setError, url, urlSecret, urlSecretId])\n\n if (urlSecretId) {\n return (\n <GetUrlSecret\n urlSecretId={urlSecretId}\n urlSecret={urlSecret}\n setUrlSecret={setUrlSecret}\n setError={setError}\n />\n )\n }\n\n return null\n}\n\nexport function MissingSlugScreen() {\n return (\n <Card height=\"fill\">\n <Flex align=\"center\" height=\"fill\" justify=\"center\" padding={4} sizing=\"border\">\n <Container width={0}>\n <Card padding={4} radius={2} shadow={1} tone=\"caution\">\n <Flex>\n <Box>\n <Text size={1}>\n <WarningOutlineIcon />\n </Text>\n </Box>\n <Stack flex={1} marginLeft={3} space={3}>\n <Text as=\"h1\" size={1} weight=\"bold\">\n Missing slug\n </Text>\n <Text as=\"p\" muted size={1}>\n Add a slug to see the preview.\n </Text>\n </Stack>\n </Flex>\n </Card>\n </Container>\n </Flex>\n </Card>\n )\n}\n"],"names":["GetUrlSecret","props","urlSecretId","setUrlSecret","urlSecret","setError","client","useClient","apiVersion","secretExpiresAt","setSecretExpiresAt","useState","includes","TypeError","concat","useEffect","getSecret","signal","data","fetch","fetchSecretQuery","id","tag","aborted","secret","_updatedAt","newUpdatedAt","Date","newSecret","patchUrlSecret","getExpiresAt","err","console","error","abort","AbortController","catch","name","timeout","setTimeout","Math","max","getTime","clearTimeout","DisplayUrl","_ref","displayUrl","truncatedUrl","useMemo","url","URL","searchParams","has","delete","append","origin","location","pathname","search","jsx","Text","size","textOverflow","title","children","sizes","desktop","width","height","mobile","DEFAULT_SIZE","Toolbar","iframeSize","setIframeSize","reloading","showDisplayUrl","reloadButton","handleReload","input","useRef","push","pushToast","useToast","copy","useCopyToClipboard","jsxs","Fragment","style","position","pointerEvents","opacity","ref","value","readOnly","tabIndex","Card","padding","borderBottom","Flex","align","gap","Tooltip","content","whiteSpace","placement","Button","disabled","fontSize","mode","icon","MobileDeviceIcon","onClick","Box","flex","UndoIcon","transform","loading","ClipboardIcon","_a","current","closable","status","LaunchIcon","paddingY","text","window","open","MotionFlex","motion","Iframe","document","sanityDocument","options","defaultSize","reload","loader","attributes","workaroundEmptyDocument","setWorkaroundEmptyDocument","prefersReducedMotion","usePrefersReducedMotion","urlState","setUrlState","setLoading","setReloading","iframe","displayed","useCallback","src","deferredRevision","useDeferredValue","_rev","MotionConfig","transition","duration","direction","button","MissingSlug","MissingSlugScreen","tone","Frame","AsyncUrl","setDisplayUrl","revision","ReloadOnRevision","forwardRef","handleIframeLoad","onLoad","justify","AnimatePresence","initial","animate","exit","variants","spinnerVariants","inset","Spinner","muted","frameBorder","maxHeight","iframeVariants","boxShadow","background","scale","idle","active","initialRev","Number","getUrl","resolveUrl","sizing","Container","radius","shadow","WarningOutlineIcon","Stack","marginLeft","space","as","weight"],"mappings":"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"}
|
package/lib/is-valid-secret.cjs
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
var isValidSecret = require('./_chunks/is-valid-secret-
|
|
6
|
+
var isValidSecret = require('./_chunks/is-valid-secret-fac49993.cjs');
|
|
7
7
|
exports.isValidSecret = isValidSecret.isValidSecret;
|
|
8
8
|
//# sourceMappingURL=is-valid-secret.cjs.map
|
package/lib/is-valid-secret.d.ts
CHANGED
|
@@ -8,7 +8,12 @@ export declare type SanityClientLike = {
|
|
|
8
8
|
config(): {
|
|
9
9
|
token?: string
|
|
10
10
|
}
|
|
11
|
-
withConfig(config: {
|
|
11
|
+
withConfig(config: {
|
|
12
|
+
apiVersion?: string
|
|
13
|
+
useCdn?: boolean
|
|
14
|
+
perspective: 'raw'
|
|
15
|
+
resultSourceMap: boolean
|
|
16
|
+
}): SanityClientLike
|
|
12
17
|
fetch<
|
|
13
18
|
R,
|
|
14
19
|
Q = {
|
package/lib/is-valid-secret.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { isValidSecret } from './_chunks/is-valid-secret-
|
|
1
|
+
export { isValidSecret } from './_chunks/is-valid-secret-926b3d57.js';
|
|
2
2
|
//# sourceMappingURL=is-valid-secret.js.map
|
package/lib/preview-url.cjs
CHANGED
|
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
var sanity = require('sanity');
|
|
7
|
-
var utils = require('./_chunks/utils-
|
|
8
|
-
var isValidSecret = require('./_chunks/is-valid-secret-
|
|
7
|
+
var utils = require('./_chunks/utils-a281f455.cjs');
|
|
8
|
+
var isValidSecret = require('./_chunks/is-valid-secret-fac49993.cjs');
|
|
9
9
|
const previewUrl = sanity.definePlugin(_ref => {
|
|
10
10
|
let {
|
|
11
11
|
urlSecretId,
|
package/lib/preview-url.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { definePlugin } from 'sanity';
|
|
2
|
-
import { patchUrlSecret, MissingSlug, defineUrlResolver } from './_chunks/utils-
|
|
3
|
-
import { apiVersion, fetchSecretQuery, tag } from './_chunks/is-valid-secret-
|
|
2
|
+
import { patchUrlSecret, MissingSlug, defineUrlResolver } from './_chunks/utils-771d70cf.js';
|
|
3
|
+
import { apiVersion, fetchSecretQuery, tag } from './_chunks/is-valid-secret-926b3d57.js';
|
|
4
4
|
const previewUrl = definePlugin(_ref => {
|
|
5
5
|
let {
|
|
6
6
|
urlSecretId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-iframe-pane",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.7",
|
|
4
4
|
"description": "Display any URL in a View Pane, along with helpful buttons to Copy the URL or open in a new tab",
|
|
5
5
|
"homepage": "https://github.com/sanity-io/sanity-plugin-iframe-pane#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -84,34 +84,34 @@
|
|
|
84
84
|
"usehooks-ts": "2.9.1"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
|
-
"@commitlint/cli": "^17.7.
|
|
87
|
+
"@commitlint/cli": "^17.7.1",
|
|
88
88
|
"@commitlint/config-conventional": "^17.7.0",
|
|
89
|
-
"@sanity/pkg-utils": "^2.4.
|
|
90
|
-
"@sanity/plugin-kit": "^3.1.
|
|
91
|
-
"@sanity/semantic-release-preset": "^4.1.
|
|
89
|
+
"@sanity/pkg-utils": "^2.4.8",
|
|
90
|
+
"@sanity/plugin-kit": "^3.1.10",
|
|
91
|
+
"@sanity/semantic-release-preset": "^4.1.4",
|
|
92
92
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
93
93
|
"@typescript-eslint/parser": "^5.62.0",
|
|
94
|
-
"eslint": "^8.
|
|
94
|
+
"eslint": "^8.48.0",
|
|
95
95
|
"eslint-config-prettier": "^9.0.0",
|
|
96
96
|
"eslint-config-react-app": "^7.0.1",
|
|
97
97
|
"eslint-config-sanity": "^6.0.0",
|
|
98
|
-
"eslint-plugin-import": "^2.28.
|
|
98
|
+
"eslint-plugin-import": "^2.28.1",
|
|
99
99
|
"eslint-plugin-prettier": "^5.0.0",
|
|
100
|
-
"eslint-plugin-react": "^7.33.
|
|
100
|
+
"eslint-plugin-react": "^7.33.2",
|
|
101
101
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
102
102
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
103
103
|
"husky": "^8.0.3",
|
|
104
|
-
"lint-staged": "^
|
|
104
|
+
"lint-staged": "^14.0.1",
|
|
105
105
|
"npm-run-all": "^4.1.5",
|
|
106
|
-
"prettier": "^3.0.
|
|
106
|
+
"prettier": "^3.0.3",
|
|
107
107
|
"prettier-plugin-packagejson": "^2.4.5",
|
|
108
108
|
"react": "^18.2.0",
|
|
109
109
|
"react-dom": "^18.2.0",
|
|
110
110
|
"react-is": "^18.2.0",
|
|
111
111
|
"rimraf": "^5.0.1",
|
|
112
|
-
"sanity": "^3.
|
|
112
|
+
"sanity": "^3.16.2",
|
|
113
113
|
"styled-components": "^5.3.11",
|
|
114
|
-
"typescript": "^5.
|
|
114
|
+
"typescript": "^5.2.2"
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
117
|
"react": "^18",
|
package/src/Toolbar.tsx
CHANGED
|
@@ -63,6 +63,7 @@ export function Toolbar(props: ToolbarProps) {
|
|
|
63
63
|
</Text>
|
|
64
64
|
}
|
|
65
65
|
padding={2}
|
|
66
|
+
placement="bottom-start"
|
|
66
67
|
>
|
|
67
68
|
<Button
|
|
68
69
|
disabled={!displayUrl}
|
|
@@ -133,6 +134,7 @@ export function Toolbar(props: ToolbarProps) {
|
|
|
133
134
|
</Text>
|
|
134
135
|
}
|
|
135
136
|
padding={2}
|
|
137
|
+
placement="bottom-end"
|
|
136
138
|
>
|
|
137
139
|
<Button
|
|
138
140
|
disabled={!displayUrl}
|
package/src/isValidSecret.tsx
CHANGED
|
@@ -17,7 +17,12 @@ export const apiVersion = '2023-08-08'
|
|
|
17
17
|
|
|
18
18
|
export type SanityClientLike = {
|
|
19
19
|
config(): {token?: string}
|
|
20
|
-
withConfig(config: {
|
|
20
|
+
withConfig(config: {
|
|
21
|
+
apiVersion?: string
|
|
22
|
+
useCdn?: boolean
|
|
23
|
+
perspective: 'raw'
|
|
24
|
+
resultSourceMap: boolean
|
|
25
|
+
}): SanityClientLike
|
|
21
26
|
fetch<
|
|
22
27
|
R,
|
|
23
28
|
Q = {
|
|
@@ -55,10 +60,18 @@ export async function isValidSecret(
|
|
|
55
60
|
throw new TypeError('`client` must have a `token` specified')
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
// If we're in the Edge Runtime it's usually too quick and we need to delay fetching the secret a little bit
|
|
64
|
+
// eslint-disable-next-line no-warning-comments
|
|
65
|
+
// @ts-expect-error -- @TODO add typings for EdgeRuntime
|
|
66
|
+
if (typeof EdgeRuntime !== 'undefined') {
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 300))
|
|
68
|
+
}
|
|
69
|
+
|
|
58
70
|
const customClient = client.withConfig({
|
|
59
71
|
apiVersion,
|
|
60
72
|
useCdn: false,
|
|
61
73
|
perspective: 'raw',
|
|
74
|
+
resultSourceMap: false,
|
|
62
75
|
})
|
|
63
76
|
const data = await customClient.fetch<FetchSecretResponse>(
|
|
64
77
|
fetchSecretQuery,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"is-valid-secret-6020b622.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: {apiVersion?: string; useCdn?: boolean; perspective: 'raw'}): 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 const customClient = client.withConfig({\n apiVersion,\n useCdn: false,\n perspective: 'raw',\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","customClient","withConfig","useCdn","perspective","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;AAiB1B,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;EAEM,MAAAI,YAAA,GAAeP,OAAOQ,UAAW,CAAA;IACrCd,UAAA;IACAe,MAAQ,EAAA,KAAA;IACRC,WAAa,EAAA;EAAA,CACd,CAAA;EACK,MAAAC,IAAA,GAAO,MAAMJ,YAAa,CAAAK,KAAA,CAC9BtB,gBAAA,EACA;IAACuB,IAAIZ;EAAW,CAAA;EAAA;EAEhB;IAACa,KAAO,EAAA,UAAA;IAAYtB;EAAG,CAAA,CACzB;EAEI,IAAA,EAACmB,IAAM,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAA,CAAAI,MAAA,CAAA,IAAUpB,KAAO,EAAA;IACpB,MAAAqB,MAAA,GAAS,MAAMhB,MAAO,CAAAY,KAAA,EAAA;IACf,kBAAA,EACX;MAACC,IAAIZ;IAAW,CAAA;IAAA;IAEhB;MAACa,KAAO,EAAA,UAAA;MAAYtB;IAAG,CAAA,CACzB;IACA,IAAI,CAACwB,MAAQ,EAAA;MACX,MAAM,IAAIb,SAAA,CACR,wDAAyDZ,MAAW,CAAAU,WAAA,EAAA,4FAAA,CAAA,CACtE;IACF;EACF;EAEA,OAAA,CAAOU,6BAAMI,MAAW,MAAAb,SAAA;AAC1B;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"is-valid-secret-be2288e3.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: {apiVersion?: string; useCdn?: boolean; perspective: 'raw'}): 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 const customClient = client.withConfig({\n apiVersion,\n useCdn: false,\n perspective: 'raw',\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","customClient","withConfig","useCdn","perspective","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;AAiB1B,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;EAEM,MAAAI,YAAA,GAAeP,OAAOQ,UAAW,CAAA;IACrCd,UAAA;IACAe,MAAQ,EAAA,KAAA;IACRC,WAAa,EAAA;EAAA,CACd,CAAA;EACK,MAAAC,IAAA,GAAO,MAAMJ,YAAa,CAAAK,KAAA,CAC9BtB,gBAAA,EACA;IAACuB,IAAIZ;EAAW,CAAA;EAAA;EAEhB;IAACa,KAAO,EAAA,UAAA;IAAYtB;EAAG,CAAA,CACzB;EAEI,IAAA,EAACmB,IAAM,IAAA,IAAA,GAAA,KAAA,CAAA,GAAAA,IAAA,CAAAI,MAAA,CAAA,IAAUpB,KAAO,EAAA;IACpB,MAAAqB,MAAA,GAAS,MAAMhB,MAAO,CAAAY,KAAA,EAAA;IACf,kBAAA,EACX;MAACC,IAAIZ;IAAW,CAAA;IAAA;IAEhB;MAACa,KAAO,EAAA,UAAA;MAAYtB;IAAG,CAAA,CACzB;IACA,IAAI,CAACwB,MAAQ,EAAA;MACX,MAAM,IAAIb,SAAA,CACR,wDAAyDZ,MAAW,CAAAU,WAAA,EAAA,4FAAA,CAAA,CACtE;IACF;EACF;EAEA,OAAA,CAAOU,6BAAMI,MAAW,MAAAb,SAAA;AAC1B;"}
|