@invisiblecities/sanity-edge-fetcher
Version:
Lightweight, Edge Runtime-compatible Sanity client for Next.js and Vercel Edge Functions
32 lines • 11.5 kB
JavaScript
var $={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},A={0:8203,1:8204,2:8205,3:65279},W=new Array(4).fill(String.fromCodePoint(A[0])).join("");function I(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(A[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 L(e,n,t="auto"){return t===!0||t==="auto"&&(G(e)||M(e))?e:`${e}${I(n)}`}var Te=Object.fromEntries(Object.entries(A).map(e=>e.reverse())),be=Object.fromEntries(Object.entries($).map(e=>e.reverse())),H=`${Object.values($).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 k(e){return e&&JSON.parse(Z(JSON.stringify(e)).cleaned)}var F=I,j=L,B=k,K={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(K.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(s=>{let o=parseInt(s,10);return String.fromCodePoint(K.base4[o])}).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(B&&B(e)!==e)return e}catch{}return F?j?j(e,n,"auto"):`${e}${F(n)}`:`${e}${te(n)}`}function R(e,n,t,a=[]){if(!t.enabled||!n||e==null)return e;if(typeof e=="string"){if(re(a))return e;let r=se(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,s)=>R(r,n,t,[...a,s]));if(typeof e=="object"){let r={};for(let s in e)e.hasOwnProperty(s)&&(r[s]=R(e[s],n,t,[...a,s]));return r}return e}function se(e,n,t){if(!e?.mappings)return null;let a=`$${n.map(s=>typeof s=="number"?`[${s}]`:`['${s}']`).join("")}`;if(e.mappings[a]){let s=e.mappings[a],o=e.studioUrl||t?.studioUrl,d;try{let c=s?.source,l=typeof c?.document=="number"?e.documents?.[c.document]?._id:void 0,S=typeof c?.path=="number"?e.paths?.[c.path]:void 0;if(o&&l){let g=String(o).replace(/\/?presentation\/?$/,"").replace(/\/$/,""),p=S?`;path=${encodeURIComponent(S)}`:"";d=`${g}/intent/edit/id=${encodeURIComponent(l)}${p}`}}catch{}return{_origin:"sanity",projectId:t?.projectId,dataset:t?.dataset,studioUrl:o,path:a,source:e.source,href:d,...s}}let r=a;for(;r.includes("[")||r.includes(".");){let s=Math.max(r.lastIndexOf("["),r.lastIndexOf("."));if(s===-1)break;if(r=r.substring(0,s),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 Y(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 V(e,n){return n?.enabled!==void 0?n.enabled:e||process.env.NODE_ENV==="development"}function X(e,n,t){if(!V(n,t))return e.result;let a=e.result,r=e.resultSourceMap;if(r&&t?.enabled){let s=Y(t);s&&r&&(r.studioUrl=s);let o=v(n,t);return R(a,r,o)}return a}function v(e,n){let t=n||{},a=V(e,t),r=Y(t),s=t.projectId||process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,o=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}:{},...s!==void 0?{projectId:s}:{},...o!==void 0?{dataset:o}:{}}}var ie=()=>{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,w=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 w;async function m({dataset:e,query:n,params:t={},useCdn:a=!1,useAuth:r=!1,stega:s}){await ue.throttle();let o=ie(),d=r,c=v(d,s),S=(c.enabled?!1:a)?`https://${o}.apicdn.sanity.io`:`https://${o}.api.sanity.io`,g=new URL(`${S}/v${oe}/data/query/${e}`);g.searchParams.set("query",n),r&&g.searchParams.set("perspective","previewDrafts"),c.enabled&&g.searchParams.set("resultSourceMap","true"),Object.entries(t).forEach(([u,z])=>{g.searchParams.set(`$${u}`,JSON.stringify(z))});let p={Accept:"application/json"};if(r){let u=ce();u&&(p.Authorization=`Bearer ${u}`)}let y=await fetch(g.toString(),{method:"GET",headers:p});if(!y.ok)throw await y.text(),new Error(`Sanity fetch failed: ${y.status} ${y.statusText}`);let T=await y.json();return X(T,d,c)}function b(e,n=!1,t){return(a,r)=>{let s={dataset:e,query:a,useAuth:n,...t!==void 0?{stega:t}:{},...r!==void 0?{params:r}:{}};return m(s)}}import{Redis as Q}from"@upstash/redis";var P=process.env.KV_REST_API_URL||process.env.UPSTASH_REDIS_REST_URL,E=process.env.KV_REST_API_TOKEN||process.env.UPSTASH_REDIS_REST_TOKEN,O=process.env.KV_REST_API_READ_ONLY_TOKEN,de=!!(P&&(E||O)),_=null,C=null;if(de&&P&&(E||O))try{_=new Q({url:P,token:O||E,automaticDeserialization:!0}),E?C=new Q({url:P,token:E,automaticDeserialization:!0}):C=_}catch{_=null,C=null}function le(e,n,t){let a=`sanity:${e}:${n}`;if(!t||Object.keys(t).length===0)return a;let r=Object.keys(t).sort().map(s=>`${s}=${JSON.stringify(t[s])}`).join("&");return`${a}:${r}`}var U=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}},x=new U;async function fe(e){let{dataset:n,query:t,params:a,cache:r={}}=e,{ttl:s=60,prefix:o="",force:d=!1,useRedis:c=!0}=r,l=o+le(n,t,a);if(!d){let u=x.get(l);if(u!==null)return u}if(!d&&c&&_)try{let u=await _.get(l);if(u&&Date.now()<=u.validUntil)return x.set(l,u.value,s),u.value}catch{}let{cache:S,params:g,...p}=e,y=a!==void 0?{...p,params:a}:{...p},T=await m(y);if(x.set(l,T,s),c&&C)try{let u={value:T,timestamp:Date.now(),validUntil:Date.now()+s*1e3};await C.set(l,u,{ex:s})}catch{}return T}function h(e,n){return(t,a,r)=>fe({dataset:e,query:t,...a!==void 0?{params:a}:{},cache:{...n||{},...r||{}}})}var N=null,ge=async()=>{if(N)return N;try{return N=await import("p-retry"),N}catch{return null}};async function q(e,n){let t=await ge();if(!t)return m(e);let a={retries:3,minTimeout:100,maxTimeout:2e3,onFailedAttempt:r=>{r.attemptNumber,r.retriesLeft}};return t.default(()=>m(e),{...a,...n})}var f={projectId:process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,apiVersion:process.env.NEXT_PUBLIC_SANITY_API_VERSION||"2025-02-10",dataset:process.env.NEXT_PUBLIC_SANITY_DATASET||"production",token:process.env.SANITY_VIEWER_TOKEN,useCdn:process.env.NODE_ENV==="production"},i={ttl:{default:60,static:3600,dynamic:30,long:86400},prefixes:{page:"page:",post:"post:",author:"author:",category:"cat:",section:"section:",global:"global:"},layers:{memory:{enabled:!0,maxSize:100},redis:{enabled:!!(process.env.KV_REST_API_URL||process.env.UPSTASH_REDIS_REST_URL),url:process.env.KV_REST_API_URL||process.env.UPSTASH_REDIS_REST_URL,token:process.env.KV_REST_API_TOKEN||process.env.UPSTASH_REDIS_REST_TOKEN,readOnlyToken:process.env.KV_REST_API_READ_ONLY_TOKEN},nextCache:{enabled:typeof window>"u"}}},he={minInterval:100,maxRequestsPerSecond:10},J={retries:3,minTimeout:100,maxTimeout:2e3,factor:2},pe={sse:{endpoint:"/api/sanity-updates",pollInterval:5e3,heartbeatInterval:3e4},websocket:{endpoint:process.env.NEXT_PUBLIC_WEBSOCKET_URL||"wss://your-worker.workers.dev/ws",reconnectDelay:1e3,maxReconnectAttempts:5}},ye={basic:b(f.dataset,!1),authenticated:b(f.dataset,!0),cached:h(f.dataset,{ttl:i.ttl.default,useRedis:i.layers.redis.enabled,useNextCache:i.layers.nextCache.enabled}),static:h(f.dataset,{ttl:i.ttl.long,prefix:i.prefixes.global,useRedis:i.layers.redis.enabled,useNextCache:!0}),dynamic:h(f.dataset,{ttl:i.ttl.dynamic,useRedis:i.layers.redis.enabled,useNextCache:!1}),page:h(f.dataset,{ttl:i.ttl.static,prefix:i.prefixes.page,useRedis:i.layers.redis.enabled,useNextCache:!0}),section:h(f.dataset,{ttl:i.ttl.default,prefix:i.prefixes.section,useRedis:i.layers.redis.enabled,useNextCache:!0})};function De(e){let{dataset:n=f.dataset,ttl:t=i.ttl.default,prefix:a="",useAuth:r=!1,useCache:s=!0,useRetry:o=!1}=e;return!s&&!o?b(n,r):s&&!o?h(n,{ttl:t,prefix:a,useRedis:i.layers.redis.enabled,useNextCache:i.layers.nextCache.enabled}):async(d,c)=>{let l=s?h(n,{ttl:t,prefix:a}):b(n,r);return o?q({dataset:n,query:d,params:c,useAuth:r},J):l(d,c)}}var me=[{query:'*[_type == "siteSettings"][0]',ttl:i.ttl.long,fetcher:"static"},{query:'*[_type == "navigation"][0]',ttl:i.ttl.long,fetcher:"static"},{query:'*[_type == "post"] | order(_createdAt desc)[0..10]',ttl:i.ttl.default,fetcher:"cached"},{query:'*[_type == "page" && slug.current == "home"][0]',ttl:i.ttl.static,fetcher:"page"}],Se={sanity:f,cache:i,rateLimit:he,retry:J,realtime:pe,fetchers:ye,warmupQueries:me},$e=Se;export{i as cacheConfig,Se as config,De as createCustomFetcher,$e as default,ye as fetchers,he as rateLimitConfig,pe as realtimeConfig,J as retryConfig,f as sanityConfig,me as warmupQueries};
/**
* @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 cache.ts
* @description Multi-layer caching for Sanity Edge Fetcher
* @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 config.ts
* @description Centralized configuration for Sanity Edge Fetcher
* @author Invisible Cities Agency
* @license MIT
*/
//# sourceMappingURL=config.js.map