@invisiblecities/sanity-edge-fetcher
Version:
Lightweight, Edge Runtime-compatible Sanity client for Next.js and Vercel Edge Functions
32 lines • 13.6 kB
JavaScript
var j={0:8203,1:8204,2:8205,3:8290,4:8291,5:8288,6:65279,7:8289,8:119155,9:119156,a:119157,b:119158,c:119159,d:119160,e:119161,f:119162},w={0:8203,1:8204,2:8205,3:65279},W=new Array(4).fill(String.fromCodePoint(w[0])).join("");function A(e){let n=JSON.stringify(e);return`${W}${Array.from(n).map(t=>{let a=t.charCodeAt(0);if(a>255)throw new Error(`Only ASCII edit info can be encoded. Error attempting to encode ${n} on character ${t} (${a})`);return Array.from(a.toString(4).padStart(4,"0")).map(r=>String.fromCodePoint(w[r])).join("")}).join("")}`}function G(e){return!Number.isNaN(Number(e))||/[a-z]/i.test(e)&&!/\d+(?:[-:\/]\d+){2}(?:T\d+(?:[-:\/]\d+){1,2}(\.\d+)?Z?)?/.test(e)?!1:!!Date.parse(e)}function M(e){try{new URL(e,e.startsWith("/")?"https://acme.com":void 0)}catch{return!1}return!0}function k(e,n,t="auto"){return t===!0||t==="auto"&&(G(e)||M(e))?e:`${e}${A(n)}`}var we=Object.fromEntries(Object.entries(w).map(e=>e.reverse())),Ae=Object.fromEntries(Object.entries(j).map(e=>e.reverse())),H=`${Object.values(j).map(e=>`\\u{${e.toString(16)}}`).join("")}`,D=new RegExp(`[${H}]{4,}`,"gu");function Z(e){var n;return{cleaned:e.replace(D,""),encoded:((n=e.match(D))==null?void 0:n[0])||""}}function L(e){return e&&JSON.parse(Z(JSON.stringify(e)).cleaned)}var B=A,Y=k,C=L,I={base4:[8203,8204,8205,65279],hex:{0:8203,1:8204,2:8205,3:8290,4:8291,5:8288,6:65279,7:8289,8:119155,9:119156,a:119157,b:119158,c:119159,d:119160,e:119161,f:119162}},ee=new Array(4).fill(String.fromCodePoint(I.base4[0])).join("");function te(e){let n=JSON.stringify(e),t=Array.from(n).map(a=>{let r=a.charCodeAt(0);if(r>255)throw new Error(`Only ASCII can be encoded. Error on character ${a} (${r})`);return Array.from(r.toString(4).padStart(4,"0")).map(i=>{let s=parseInt(i,10);return String.fromCodePoint(I.base4[s])}).join("")}).join("");return`${ee}${t}`}function ne(e){let n=/\d+(?:[-:\/]\d+){2}(?:T\d+(?:[-:\/]\d+){1,2}(\.\d+)?Z?)?/.test(e),t=(()=>{try{return new URL(e,e.startsWith("/")?"https://example.com":void 0),!0}catch{return!1}})(),a=/^(image|file)-[A-Za-z0-9]+-\d+x\d+-[A-Za-z0-9]+$/.test(e);return n||t||a}function re(e){if(!e.length)return!1;let n=String(e[e.length-1]);return!!(new Set(["_id","_ref","_key","_type","slug","current","asset","path","href","url","src"]).has(n)||e.length>=2&&String(e[e.length-2])==="asset")}function ae(e,n,t){if(!t.enabled||!n||ne(e)||typeof e!="string"||e.trim().length===0)return e;try{if(C&&C(e)!==e)return e}catch{}return B?Y?Y(e,n,"auto"):`${e}${B(n)}`:`${e}${te(n)}`}function N(e,n,t,a=[]){if(!t.enabled||!n||e==null)return e;if(typeof e=="string"){if(re(a))return e;let r=ie(n,a,t);return r&&(r.type===void 0||r.type==="value")?ae(e,r,t):e}if(Array.isArray(e))return e.map((r,i)=>N(r,n,t,[...a,i]));if(typeof e=="object"){let r={};for(let i in e)e.hasOwnProperty(i)&&(r[i]=N(e[i],n,t,[...a,i]));return r}return e}function ie(e,n,t){if(!e?.mappings)return null;let a=`$${n.map(i=>typeof i=="number"?`[${i}]`:`['${i}']`).join("")}`;if(e.mappings[a]){let i=e.mappings[a],s=e.studioUrl||t?.studioUrl,f;try{let o=i?.source,g=typeof o?.document=="number"?e.documents?.[o.document]?._id:void 0,m=typeof o?.path=="number"?e.paths?.[o.path]:void 0;if(s&&g){let d=String(s).replace(/\/?presentation\/?$/,"").replace(/\/$/,""),l=m?`;path=${encodeURIComponent(m)}`:"";f=`${d}/intent/edit/id=${encodeURIComponent(g)}${l}`}}catch{}return{_origin:"sanity",projectId:t?.projectId,dataset:t?.dataset,studioUrl:s,path:a,source:e.source,href:f,...i}}let r=a;for(;r.includes("[")||r.includes(".");){let i=Math.max(r.lastIndexOf("["),r.lastIndexOf("."));if(i===-1)break;if(r=r.substring(0,i),e.mappings[r])return{_origin:"sanity",projectId:t?.projectId,dataset:t?.dataset,studioUrl:e.studioUrl,source:e.source,path:r,...e.mappings[r]}}return null}function K(e){if(e?.studioUrl)return e.studioUrl;let n=process.env.NEXT_PUBLIC_SANITY_STUDIO_URL||process.env.SANITY_STUDIO_URL;if(n)return n;if(process.env.NODE_ENV==="development")return"https://localhost:3334/presentation"}function R(e,n){return n?.enabled!==void 0?n.enabled:e||process.env.NODE_ENV==="development"}function Q(e,n,t){if(!R(n,t))return e.result;let a=e.result,r=e.resultSourceMap;if(r&&t?.enabled){let i=K(t);i&&r&&(r.studioUrl=i);let s=P(n,t);return N(a,r,s)}return a}function P(e,n){let t=n||{},a=R(e,t),r=K(t),i=t.projectId||process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,s=t.dataset||process.env.NEXT_PUBLIC_SANITY_DATASET;return{enabled:a,...r!==void 0?{studioUrl:r}:{},...t.basePath!==void 0?{basePath:t.basePath}:{},...t.filter!==void 0?{filter:t.filter}:{},...i!==void 0?{projectId:i}:{},...s!==void 0?{dataset:s}:{}}}function v(e){if(C)return C(e);let n=Object.values(I.hex).map(r=>`\\u{${r.toString(16)}}`).join(""),t=new RegExp(`[${n}]{4,}`,"gu"),a=r=>r.replace(t,"");if(typeof e=="string")return a(e);if(Array.isArray(e))return e.map(r=>v(r));if(e&&typeof e=="object"){let r={};for(let i in e)e.hasOwnProperty(i)&&(r[i]=v(e[i]));return r}return e}async function X(){try{let{draftMode:e}=await import("next/headers");return(await e()).isEnabled}catch{return!1}}async function J(e){if(e?.forceEnable)return!0;if(e?.forceDisable)return!1;let n=e?.cookieName??"ic_stega",t=e?.studioUrl||process.env.NEXT_PUBLIC_SANITY_STUDIO_URL||process.env.SANITY_STUDIO_URL;try{let a=await import("next/headers"),r=a.cookies?.bind(a),i=a.headers?.bind(a);if((await(a.draftMode?.()??{isEnabled:!1}))?.isEnabled||(typeof r=="function"?!!r().get(n)?.value:!1))return!0;let o=typeof i=="function"?i():void 0,m=[e?.headerName,"x-ic-stega","x-sanity-present","x-sanity-preview"].filter(Boolean);if(o)for(let d of m){let l=o.get(d);if(l&&l!=="0"&&l.toLowerCase()!=="false")return!0}if(o&&t){let d=o.get("referer");if(d)try{let l=new URL(d).origin,h=new URL(t).origin;if(l===h)return!0}catch{}}}catch{}return process.env.NEXT_PUBLIC_ENABLE_STEGA==="1"}var se=()=>{let e=process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;if(!e)throw new Error("NEXT_PUBLIC_SANITY_PROJECT_ID environment variable is required");return e},oe=process.env.NEXT_PUBLIC_SANITY_API_VERSION||"2025-02-10",ce=()=>process.env.SANITY_VIEWER_TOKEN||process.env.SANITY_API_READ_TOKEN||process.env.NEXT_PUBLIC_SANITY_VIEWER_TOKEN,O=class{constructor(){this.lastRequest=0;this.minInterval=100}async throttle(){let t=Date.now()-this.lastRequest;if(t<this.minInterval){let a=this.minInterval-t;await new Promise(r=>setTimeout(r,a))}this.lastRequest=Date.now()}},ue=new O;async function c({dataset:e,query:n,params:t={},useCdn:a=!1,useAuth:r=!1,stega:i}){await ue.throttle();let s=se(),f=r,o=P(f,i),m=(o.enabled?!1:a)?`https://${s}.apicdn.sanity.io`:`https://${s}.api.sanity.io`,d=new URL(`${m}/v${oe}/data/query/${e}`);d.searchParams.set("query",n),r&&d.searchParams.set("perspective","previewDrafts"),o.enabled&&d.searchParams.set("resultSourceMap","true"),Object.entries(t).forEach(([u,q])=>{d.searchParams.set(`$${u}`,JSON.stringify(q))});let l={Accept:"application/json"};if(r){let u=ce();u&&(l.Authorization=`Bearer ${u}`)}let h=await fetch(d.toString(),{method:"GET",headers:l});if(!h.ok)throw await h.text(),new Error(`Sanity fetch failed: ${h.status} ${h.statusText}`);let b=await h.json();return Q(b,f,o)}function de(e,n=!1,t){return(a,r)=>{let i={dataset:e,query:a,useAuth:n,...t!==void 0?{stega:t}:{},...r!==void 0?{params:r}:{}};return c(i)}}async function z(e,n,t){let a=t?.dataset||process.env.NEXT_PUBLIC_SANITY_DATASET||"production",r=t?.forceAuth??await X();return c({dataset:a,query:e,...n!==void 0?{params:n}:{},useCdn:!r,useAuth:r,stega:t?.stega||{enabled:r}})}async function le(e,n,t){let a=t?.dataset||process.env.NEXT_PUBLIC_SANITY_DATASET||"production",r=await J({...t?.cookieName!==void 0?{cookieName:t.cookieName}:{},...t?.headerName!==void 0?{headerName:t.headerName}:{},...t?.studioUrl!==void 0?{studioUrl:t.studioUrl}:{},...t?.forceEnableStega!==void 0?{forceEnable:t.forceEnableStega}:{},...t?.forceDisableStega!==void 0?{forceDisable:t.forceDisableStega}:{}});return c({dataset:a,query:e,...n!==void 0?{params:n}:{},useCdn:!r,useAuth:r,stega:{enabled:r,...t?.stega||{}}})}async function fe(e,n,t){let a=t?.dataset||process.env.NEXT_PUBLIC_SANITY_DATASET||"production";if(await X())return c({dataset:a,query:e,...n!==void 0?{params:n}:{},useCdn:!1,useAuth:!0,stega:t?.stega||{enabled:!0}});let i=await c({dataset:a,query:e,...n!==void 0?{params:n}:{},useCdn:!0,useAuth:!1});if(i)return i;t?.logFallback!==!1&&process.env.NODE_ENV!=="production"&&console.warn("[sanityFetchWithFallback] No published content found, checking for drafts...");let s=await c({dataset:a,query:e,...n!==void 0?{params:n}:{},useCdn:!1,useAuth:!0,stega:t?.stega||{enabled:!0}});return s&&t?.logFallback!==!1&&process.env.NODE_ENV!=="production"&&console.warn("[sanityFetchWithFallback] Draft content found and returned"),s}async function ge(e,n,t){return c({dataset:t||process.env.NEXT_PUBLIC_SANITY_DATASET||"production",query:e,...n!==void 0?{params:n}:{},useCdn:!0,useAuth:!1})}async function he(e,n,t){return c({dataset:t||process.env.NEXT_PUBLIC_SANITY_DATASET||"production",query:e,...n!==void 0?{params:n}:{},useCdn:!1,useAuth:!0})}var _=null,ye=async()=>{if(_)return _;try{return _=await import("p-retry"),_}catch{return null}};async function me(e,n){let t=await ye();if(!t)return c(e);let a={retries:3,minTimeout:100,maxTimeout:2e3,onFailedAttempt:r=>{r.attemptNumber,r.retriesLeft}};return t.default(()=>c(e),{...a,...n})}function Se(e,n=60,t){return(a,r)=>c({dataset:e,query:a,...r!==void 0?{params:r}:{},useCdn:!0})}function pe(e,n="production",t){let a=t?.endpoint||"/api/sanity-updates",r=new URL(a,window.location.origin);r.searchParams.set("query",e),r.searchParams.set("dataset",n);let i=new EventSource(r.toString());return t?.onMessage&&(i.onmessage=s=>{try{let f=JSON.parse(s.data);t.onMessage&&t.onMessage(f)}catch{}}),t?.onError&&(i.onerror=t.onError),i}async function be(e,n,t){let a={};return await Promise.all(Object.entries(e).map(async([r,{query:i,params:s}])=>{try{a[r]=await c({dataset:n,query:i,...s!==void 0?{params:s}:{},...t})}catch{a[r]=null}})),a}import{Redis as V}from"@upstash/redis";var p=process.env.KV_REST_API_URL||process.env.UPSTASH_REDIS_REST_URL,T=process.env.KV_REST_API_TOKEN||process.env.UPSTASH_REDIS_REST_TOKEN,x=process.env.KV_REST_API_READ_ONLY_TOKEN,U=!!(p&&(T||x)),y=null,S=null;if(U&&p&&(T||x))try{y=new V({url:p,token:x||T,automaticDeserialization:!0}),T?S=new V({url:p,token:T,automaticDeserialization:!0}):S=y}catch{y=null,S=null}function Te(e,n,t){let a=`sanity:${e}:${n}`;if(!t||Object.keys(t).length===0)return a;let r=Object.keys(t).sort().map(i=>`${i}=${JSON.stringify(t[i])}`).join("&");return`${a}:${r}`}var $=class{constructor(){this.cache=new Map;this.maxSize=100}get(n){let t=this.cache.get(n);return t?Date.now()>t.validUntil?(this.cache.delete(n),null):(this.cache.delete(n),this.cache.set(n,t),t.value):null}set(n,t,a){if(this.cache.size>=this.maxSize&&!this.cache.has(n)){let r=this.cache.keys().next().value;r!==void 0&&this.cache.delete(r)}this.cache.set(n,{value:t,timestamp:Date.now(),validUntil:Date.now()+a*1e3})}delete(n){this.cache.delete(n)}clear(){this.cache.clear()}size(){return this.cache.size}},E=new $;async function F(e){let{dataset:n,query:t,params:a,cache:r={}}=e,{ttl:i=60,prefix:s="",force:f=!1,useRedis:o=!0}=r,g=s+Te(n,t,a);if(!f){let u=E.get(g);if(u!==null)return u}if(!f&&o&&y)try{let u=await y.get(g);if(u&&Date.now()<=u.validUntil)return E.set(g,u.value,i),u.value}catch{}let{cache:m,params:d,...l}=e,h=a!==void 0?{...l,params:a}:{...l},b=await c(h);if(E.set(g,b,i),o&&S)try{let u={value:b,timestamp:Date.now(),validUntil:Date.now()+i*1e3};await S.set(g,u,{ex:i})}catch{}return b}function Ee(e,n){return(t,a,r)=>F({dataset:e,query:t,...a!==void 0?{params:a}:{},cache:{...n||{},...r||{}}})}async function Ce(e){let{dataset:n,pattern:t,clearMemory:a=!0,clearRedis:r=!0}=e||{};if(a&&!n&&!t&&E.clear(),r&&S&&y)try{let i=t||(n?`sanity:${n}:*`:"sanity:*"),s=await y.keys(i);s.length>0&&await S.del(...s)}catch{}}async function Pe(e){await Promise.all(e.map(({dataset:n,query:t,params:a,ttl:r})=>F({dataset:n,query:t,...a!==void 0?{params:a}:{},cache:{...r!==void 0?{ttl:r}:{}}}).catch(()=>{})))}function _e(){return{memory:{available:!0,size:E.size()},redis:{available:U&&y!==null,configured:U,url:p?new URL(p).hostname:null},nextCache:{available:typeof window>"u"}}}export{be as batchSanityFetch,P as buildStegaConfig,F as cachedSanityFetch,Ce as clearSanityCache,Ee as createCachedFetcher,Se as createCachedSanityFetcher,de as createEdgeSanityFetcher,pe as createSanityEventSource,z as default,J as detectStegaRequest,c as edgeSanityFetch,me as edgeSanityFetchWithRetry,_e as getCacheStatus,z as sanityFetch,he as sanityFetchAuthenticated,le as sanityFetchHybrid,ge as sanityFetchStatic,fe as sanityFetchWithFallback,R as shouldEnableStega,v as stegaClean,Pe as warmSanityCache};
/**
* @file stega.ts
* @description Stega encoding support for visual editing with optional @vercel/stega dependency
* @author Invisible Cities Agency
* @license MIT
*/
/**
* @file core.ts
* @description Next.js-native, edge-compatible Sanity data fetcher with stega support
* @author Invisible Cities Agency
* @license MIT
*/
/**
* @file enhanced.ts
* @description Enhanced Sanity fetcher with retry and real-time capabilities
* @author Invisible Cities Agency
* @license MIT
*/
/**
* @file cache.ts
* @description Multi-layer caching for Sanity Edge Fetcher
* @author Invisible Cities Agency
* @license MIT
*/
/**
* @file index.ts
* @description Sanity Edge Fetcher - Next.js-native Sanity client for edge runtime
* @author Invisible Cities Agency
* @license MIT
*/
//# sourceMappingURL=index.js.map