UNPKG

pixel-serve-server

Version:

A robust Node.js utility for handling and processing images. This package provides features like resizing, format conversion and etc.

4 lines 20.5 kB
'use strict';var v=require('path'),R=require('fs/promises'),crypto=require('crypto'),X=require('sharp'),url=require('url'),j=require('dns/promises'),te=require('http'),re=require('https'),net=require('net'),Ee=require('axios'),zod=require('zod');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var v__default=/*#__PURE__*/_interopDefault(v);var R__namespace=/*#__PURE__*/_interopNamespace(R);var X__default=/*#__PURE__*/_interopDefault(X);var j__namespace=/*#__PURE__*/_interopNamespace(j);var te__namespace=/*#__PURE__*/_interopNamespace(te);var re__namespace=/*#__PURE__*/_interopNamespace(re);var Ee__default=/*#__PURE__*/_interopDefault(Ee);var Pe=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,F=Pe();var Ae=v__default.default.dirname(url.fileURLToPath(F)),Y=e=>v__default.default.join(Ae,"assets",e),Ie=Y("noimage.jpg"),Re=Y("noavatar.png"),E={normal:async()=>R.readFile(Ie),avatar:async()=>R.readFile(Re)},B=/^\/api\/v1\//,W=["jpeg","jpg","png","webp","gif","tiff","avif"],T={jpeg:"image/jpeg",jpg:"image/jpeg",png:"image/png",webp:"image/webp",gif:"image/gif",tiff:"image/tiff",avif:"image/avif"};var w=(e,t,n,r)=>{if(e)try{e(t,{phase:n,src:r});}catch{}},Se=4096,D=async(e,t)=>{try{if(!e||!t||typeof t!="string"||t.length>Se||t.includes("\0")||t.includes("\\")||v__default.default.isAbsolute(t)||!/^[^\x00-\x1F\x7F]+$/.test(t))return !1;let n=v__default.default.resolve(e),r=v__default.default.resolve(n,t),[i,l]=await Promise.all([R__namespace.realpath(n),R__namespace.realpath(r)]);if(!(await R__namespace.stat(i)).isDirectory()||!(await R__namespace.stat(l)).isFile())return !1;let c=i+v__default.default.sep,g=(l+v__default.default.sep).startsWith(c)||l===i,s=v__default.default.relative(i,l);return !s.startsWith("..")&&!v__default.default.isAbsolute(s)&&g}catch{return false}},Fe=e=>{let t=e,n=t.lastIndexOf(":"),r=n>=0?t.slice(n+1):t;if(net.isIP(r)===4){let m=r.split(".").map(Number),c=(m[0]<<8|m[1]).toString(16),o=(m[2]<<8|m[3]).toString(16);t=t.slice(0,n+1)+c+":"+o;}let i=t.split("::");if(i.length>2)return null;let l=m=>{if(m==="")return [];let c=[];for(let o of m.split(":")){if(!/^[0-9a-f]{1,4}$/i.test(o))return null;c.push(parseInt(o,16));}return c},a;if(i.length===1){let m=l(i[0]);if(m===null)return null;a=m;}else {let m=l(i[0]),c=l(i[1]);if(m===null||c===null)return null;let o=8-m.length-c.length;if(o<0)return null;a=[...m,...Array(o).fill(0),...c];}return a.length===8?a:null},I=e=>{let t=net.isIP(e);if(t===0)return true;if(t===4){let f=e.split(".").map(x=>Number(x));if(f.length!==4||f.some(x=>Number.isNaN(x)))return true;let[d,h]=f;return d===0||d===10||d===100&&h>=64&&h<=127||d===127||d===169&&h===254||d===172&&h>=16&&h<=31||d===192&&h===168||d===192&&h===0||d===192&&h===88&&f[2]===99||d===198&&(h===18||h===19)||d===198&&h===51&&f[2]===100||d===203&&h===0&&f[2]===113||d>=224&&d<=239||d>=240}let n=Fe(e.toLowerCase());if(!n)return true;let[r,i,l,a,m,c,o,g]=n,s=(f,d)=>`${f>>8}.${f&255}.${d>>8}.${d&255}`,y=r===0&&i===0&&l===0&&a===0&&m===0;if(y&&c===0||y&&c===65535)return I(s(o,g));if(r===100&&i===65435){if(l===0&&a===0&&m===0&&c===0)return I(s(o,g));if(l===1)return true}return r===8194?I(s(i,l)):r>=65152&&r<=65215||r>=65216&&r<=65279||r>=64512&&r<=65023||r>=65280&&r<=65535},Ce=async e=>{if(!e)return false;let t=e.replace(/^\[|\]$/g,"");if(net.isIP(t)!==0)return !I(t);try{let n=await j__namespace.lookup(t,{all:!0,verbatim:!0});return n.length?n.every(r=>!I(r.address)):!1}catch{return false}},O=async e=>{if(!e)return null;let t=e.replace(/^\[|\]$/g,"");if(net.isIP(t)!==0){if(I(t))return null;let n=net.isIP(t)===6?6:4;return [{address:t,family:n}]}try{let n=await j__namespace.lookup(t,{all:!0,verbatim:!0});return !n.length||n.some(r=>I(r.address))?null:n.map(r=>({address:r.address,family:r.family===6?6:4}))}catch{return null}},Le=async e=>{let t=await O(e);return t?t[0]:null},He=e=>(t,n,r)=>{if(n?.all)r(null,e);else {let i=e[0];r(null,i.address,i.family);}};function ne(e,t){let n=Array.isArray(e)?e:[{address:e,family:t}],r=He(n);return {httpAgent:new te__namespace.Agent({lookup:r}),httpsAgent:new re__namespace.Agent({lookup:r})}}var ee=(e,t)=>{if(t.startsWith("*.")){let n=t.slice(1);return e===t.slice(2)||e.endsWith(n)}return e===t},ie=(e,t,n)=>n.some(r=>ee(e,r)||ee(t,r)),Ue=async(e,t,n,r)=>{try{return await Ee__default.default.get(e,{responseType:"arraybuffer",timeout:t,maxContentLength:n,maxBodyLength:n,maxRedirects:0,httpAgent:r.httpAgent,httpsAgent:r.httpsAgent,proxy:!1,validateStatus:i=>i>=200&&i<300||i>=300&&i<400})}catch(i){let l=i;return l?.response?l.response:null}},Te=async(e,t="normal",{timeoutMs:n,maxBytes:r,allowedNetworkList:i,maxRedirects:l,onError:a,onFallback:m})=>{let c=async()=>(m?.(),E[t]());try{let o=e;for(let g=0;g<=l;g++){let s;try{s=new URL(o);}catch(b){return w(a,b,"fetch",o),await c()}if(!["http:","https:"].includes(s.protocol))return w(a,new Error(`disallowed protocol ${s.protocol}`),"fetch",o),await c();if(!ie(s.hostname,s.host,i))return w(a,new Error(`host ${s.hostname} not in allowedNetworkList`),"fetch",o),await c();let y=await O(s.hostname);if(!y)return w(a,new Error(`host ${s.hostname} resolves to a private IP or DNS lookup failed`),"fetch",o),await c();let f=ne(y),d=await Ue(o,n,r,f);if(!d)return w(a,new Error("network request returned no response"),"fetch",o),await c();if(d.status>=300&&d.status<400){let b=d.headers?.location;if(!b)return w(a,new Error("redirect response missing Location header"),"fetch",o),await c();try{o=new URL(b,o).toString();}catch(H){return w(a,H,"fetch",b),await c()}continue}if(d.status<200||d.status>=300)return w(a,new Error(`non-2xx status ${d.status}`),"fetch",o),await c();let h=d.headers?.["content-type"]?.toLowerCase()?.split(";")[0]?.trim(),x=Object.values(T);return h&&x.includes(h)?Buffer.from(d.data):(w(a,new Error(`disallowed content-type ${h??"missing"} for ${o}`),"fetch",o),await c())}return w(a,new Error(`exceeded maxRedirects=${l}`),"fetch",e),await c()}catch(o){return w(a,o,"fetch",e),await c()}},_=async(e,t,n="normal",r,i,l)=>{let a=async()=>(l?.(),E[n]());if(!await D(t,e))return w(i,new Error(`invalid local path: ${e}`),"fs",e),await a();try{let c=v__default.default.resolve(t,e);if(r){let o=await R__namespace.stat(c);if(o.size>r)return w(i,new Error(`local file ${e} exceeds maxDownloadBytes (${o.size} > ${r})`),"fs",e),await a()}return await R__namespace.readFile(c)}catch(c){return w(i,c,"fs",e),await a()}},se=(e,t,n)=>n!==void 0?e.startsWith(n)?e.slice(n.length):e:e.replace(t,""),$e=e=>{if(e===void 0)return null;try{let t=new URL(e.includes("://")?e:`http://${e}`);return {hostname:t.hostname,host:t.host}}catch{return {hostname:e,host:e}}},N=(e,t,n,r)=>{let i;try{i=new URL(e);}catch{return null}let l=$e(t);return l!==null&&([l.hostname,`www.${l.hostname}`].includes(i.hostname)||[l.host,`www.${l.host}`].includes(i.host))?se(i.pathname,n,r):null},oe=(e,t,n,r="normal",i,l=[],{timeoutMs:a,maxBytes:m,maxRedirects:c=3,onError:o,apiPrefix:g,onFallback:s})=>{try{let y=N(e,n,i,g);if(y!==null)return _(y,t,r,m,o,s);let f=new URL(e);return ie(f.hostname,f.host,l)?["http:","https:"].includes(f.protocol)?Te(e,r,{timeoutMs:a,maxBytes:m,allowedNetworkList:l,maxRedirects:c,onError:o,onFallback:s}):(w(o,new Error(`disallowed protocol ${f.protocol}`),"fetch",e),s?.(),E[r]()):(w(o,new Error(`host ${f.hostname} not in allowedNetworkList`),"fetch",e),s?.(),E[r]())}catch(y){return w(o,y,"fetch",e),_(e,t,r,m,o,s)}};var ke=zod.z.enum(W),Be=zod.z.enum(["avatar","normal"]),V=zod.z.object({src:zod.z.preprocess((e,t)=>{if(e==null||typeof e=="string")return e;let n=Array.isArray(e)?"array":typeof e;return t.addIssue({code:zod.z.ZodIssueCode.custom,message:`src must be a string (received ${n})`}),zod.z.NEVER},zod.z.string().optional()).optional(),format:zod.z.string().optional().transform(e=>{let t=e?.toLowerCase();return t&&ke.options.includes(t)?t:void 0}).optional(),width:zod.z.union([zod.z.number(),zod.z.string()]).optional().transform(e=>e==null?void 0:Number(e)).pipe(zod.z.number().int().min(1,"width too small").max(4e3,"width too large").optional()),height:zod.z.union([zod.z.number(),zod.z.string()]).optional().transform(e=>e==null?void 0:Number(e)).pipe(zod.z.number().int().min(1,"height too small").max(4e3,"height too large").optional()),quality:zod.z.union([zod.z.number(),zod.z.string()]).optional().transform(e=>e==null?void 0:Number(e)).pipe(zod.z.number().int().min(1).max(100).optional()),folder:zod.z.enum(["public","private"]).default("public"),type:Be.default("normal"),userId:zod.z.union([zod.z.string(),zod.z.number()]).optional().transform(e=>e==null?void 0:String(e).trim()).pipe(zod.z.string().min(1,"userId cannot be empty").max(128,"userId too long").optional())}).strict(),G=zod.z.object({baseDir:zod.z.string().min(1,"baseDir is required"),idHandler:zod.z.custom(e=>typeof e=="function",{message:"idHandler must be a function"}).optional(),getUserFolder:zod.z.custom(e=>typeof e=="function",{message:"getUserFolder must be a function"}).optional(),getUserFolderRootDir:zod.z.string().min(1).optional(),websiteURL:zod.z.union([zod.z.url(),zod.z.string().regex(/^(?!-)[A-Za-z0-9-]{1,63}(\.(?!-)[A-Za-z0-9-]{1,63})*$/)]).optional(),apiRegex:zod.z.instanceof(RegExp).default(B),apiPrefix:zod.z.string().min(1,"apiPrefix cannot be empty").optional(),allowedNetworkList:zod.z.array(zod.z.string().transform(e=>e.trim()).pipe(zod.z.string().min(1,"allowedNetworkList entries cannot be empty").regex(/^(\*\.)?[a-z0-9.-]+$/i,"allowedNetworkList entry is not a valid hostname").refine(e=>!e.startsWith("*.")||e.slice(2).split(".").filter(Boolean).length>=2,{message:"wildcard allowedNetworkList entry must have at least two labels after '*.' (e.g. *.example.com)"}))).transform(e=>e.map(t=>t.toLowerCase())).default([]),cacheControl:zod.z.string().optional(),etag:zod.z.boolean().default(true),minWidth:zod.z.number().int().positive().default(50),maxWidth:zod.z.number().int().positive().default(4e3),minHeight:zod.z.number().int().positive().default(50),maxHeight:zod.z.number().int().positive().default(4e3),defaultQuality:zod.z.number().int().min(1).max(100).default(80),requestTimeoutMs:zod.z.number().int().positive().default(5e3),idHandlerTimeoutMs:zod.z.number().int().positive().optional(),maxDownloadBytes:zod.z.number().int().positive().default(5e6),maxRedirects:zod.z.number().int().min(0).max(10).default(3),maxInputPixels:zod.z.number().int().positive().default(16e3*16e3),allowSvgInput:zod.z.boolean().default(false),onError:zod.z.custom(e=>typeof e=="function",{message:"onError must be a function"}).optional(),onComplete:zod.z.custom(e=>typeof e=="function",{message:"onComplete must be a function"}).optional()}).strict().refine(e=>e.minWidth<=e.maxWidth,{message:"minWidth must be less than or equal to maxWidth",path:["minWidth"]}).refine(e=>e.minHeight<=e.maxHeight,{message:"minHeight must be less than or equal to maxHeight",path:["minHeight"]}).refine(e=>e.maxWidth<=4e3,{message:"maxWidth must lie within the framework's hard [1, 4000] dimension window",path:["maxWidth"]}).refine(e=>e.maxHeight<=4e3,{message:"maxHeight must lie within the framework's hard [1, 4000] dimension window",path:["maxHeight"]});var ae=e=>G.parse(e),le=(e,t)=>{let n=V.parse(e),r=(i,l,a)=>{if(i!==void 0)return Math.min(Math.max(i,l),a)};return {...n,width:r(n.width,t.minWidth,t.maxWidth),height:r(n.height,t.minHeight,t.maxHeight),quality:n.quality??t.defaultQuality,format:n.format??"jpeg"}};var A=(e,t,n)=>{if(e)try{e(t,n);}catch{}},M=(e,t)=>{if(e)try{e(t);}catch{}},q=e=>{let t=process.hrtime.bigint()-e,n=Number(t/1000000n),r=Number(t%1000000n)/1e6;return n+r},We=100,ue="image",K="public, max-age=86400, stale-while-revalidate=604800",Q="public, max-age=60",fe=(e,t)=>{let n=t,r=(e??"").split("#")[0].split("?")[0],i=v__default.default.basename(r),l=i&&i!=="/"&&i!=="\\"?v__default.default.basename(i,v__default.default.extname(i)):"",a=l.replace(/[^\x20-\x7E]/g,"_").replace(/["\\\x00-\x1F\x7F]/g,"_").replace(/_+/g,"_");a.startsWith("_")&&(a=a.slice(1)),a.endsWith("_")&&(a=a.slice(0,-1));let m=a.length>0?a:ue,c=Math.max(1,We-n.length-1),g=`${m.slice(0,c)}.${n}`,s=l.length>0?l:ue,f=encodeURIComponent(s).replace(/['()*]/g,x=>`%${x.charCodeAt(0).toString(16).toUpperCase()}`).slice(0,c),d=f.lastIndexOf("%");for(d>=0&&f.length-d<3&&(f=f.slice(0,d));f.length>=3;){let x=f.slice(-3);if(x[0]!=="%")break;let b=parseInt(x.slice(1),16);if(b>=192&&b<=253){f=f.slice(0,-3);break}if(b>=128&&b<=191){f=f.slice(0,-3);continue}break}let h=`${f}.${n}`;return {asciiFilename:g,encodedFilename:h}},ge=async(e,t,n)=>{if(!e)return null;let r=async i=>{if(!await D(t,i))return null;try{let l=v__default.default.resolve(t,i),a=await R__namespace.stat(l);return n?.maxBytes!==void 0&&a.size>n.maxBytes?null:`file:${a.mtimeMs}:${a.size}`}catch{return null}};if(e.startsWith("http://")||e.startsWith("https://")){let i=N(e,n?.websiteURL,n?.apiRegex??B,n?.apiPrefix);return i!==null?r(i):`url:${e}`}return r(e)},pe=(e,t)=>{let n=JSON.stringify({src:e.src??"",w:e.width??"",h:e.height??"",f:e.format,q:e.quality,t:e.type,fo:e.folder,u:e.parsedUserId??"",sid:t});return `"${crypto.createHash("sha256").update(n).digest("hex")}"`},me=async(e,t,n)=>{let r;try{return await Promise.race([e,new Promise((i,l)=>{r=setTimeout(()=>l(new Error(`${n} timed out after ${t}ms`)),t);})])}finally{r!==void 0&&clearTimeout(r);}},he=async(e,t,n)=>{if(!e||!t)return false;let r;if(n!==void 0)r=n;else try{r=await R__namespace.realpath(v__default.default.resolve(e));}catch{r=v__default.default.resolve(e);}let i=v__default.default.resolve(t),l;try{l=await R__namespace.realpath(i);}catch{l=i;}if(r===l)return true;let a=v__default.default.relative(r,l);return a===""||a==="."?true:!a.startsWith("..")&&!v__default.default.isAbsolute(a)},xe=async e=>{try{return await R__namespace.realpath(v__default.default.resolve(e))}catch{return v__default.default.resolve(e)}},_e=/^<!doctype\s+svg(?:[\s[>]|$)/,De=e=>{let t=0,n=()=>{for(;t<e.length&&(e[t]===" "||e[t]===" "||e[t]===` `||e[t]==="\r");)t++;};for(;;){if(n(),e.startsWith("<?xml",t)){let r=e.indexOf("?>",t);if(r===-1)return e.slice(t);t=r+2;continue}if(e.startsWith("<!--",t)){let r=e.indexOf("-->",t);if(r===-1)return e.slice(t);t=r+3;continue}return e.slice(t)}},ce=e=>e.startsWith("<svg")?true:e.startsWith("<?xml")||e.startsWith("<!--")||e.startsWith("<!doctype")?/<svg[\s>]/.test(e)?true:_e.test(De(e)):false,ye=e=>{if(!e||e.length===0)return false;let t=0;for(;t<e.length&&(e[t]===9||e[t]===10||e[t]===13||e[t]===32);)t++;if(e.length>=t+2&&(e[t]===254&&e[t+1]===255||e[t]===255&&e[t+1]===254)){let r=e[t]===255,i=Math.min(e.length,t+2+4096),l;if(r)l=e.subarray(t+2,i).toString("utf16le");else {let m=e.subarray(t+2,i),c=Buffer.alloc(m.length-m.length%2);for(let o=0;o+1<m.length;o+=2)c[o]=m[o+1],c[o+1]=m[o];l=c.toString("utf16le");}let a=l.trimStart().toLowerCase();return ce(a)}e.length>=t+3&&e[t]===239&&e[t+1]===187&&e[t+2]===191&&(t+=3);let n=e.subarray(t,Math.min(e.length,t+4096)).toString("latin1").trimStart().toLowerCase();return ce(n)},Ne=async(e,t,n,r,i)=>{let l=process.hrtime.bigint(),a="normal",m=r.onError,c=r.onComplete,o,g;try{let s;try{s=le(e.query,{minWidth:r.minWidth,maxWidth:r.maxWidth,minHeight:r.minHeight,maxHeight:r.maxHeight,defaultQuality:r.defaultQuality});}catch(p){throw A(m,p,{phase:"validation"}),p}o=s.src,g=s.userId,a=s.type??"normal";let y=r.baseDir,f;if(s.userId&&(f=s.userId,r.idHandler)){let p=s.userId,P=r.idHandlerTimeoutMs??r.requestTimeoutMs;try{let C=Promise.resolve().then(()=>r.idHandler(p)),k=await me(C,P,"idHandler");f=typeof k=="string"?k:p,typeof k!="string"&&A(m,new Error(`idHandler returned a non-string value (${typeof k})`),{phase:"idHandler",src:o,userId:p});}catch(C){f=p,A(m,C,{phase:"idHandler",src:o,userId:p});}g=f;}if(s.folder==="private"&&r.getUserFolder)try{let p=Promise.resolve().then(()=>r.getUserFolder(e,f)),P=await me(p,r.requestTimeoutMs,"getUserFolder");P&&(r.getUserFolderRootDir?await he(r.getUserFolderRootDir,P,i)?y=P:A(m,new Error(`getUserFolder returned path "${P}" outside getUserFolderRootDir "${r.getUserFolderRootDir}"`),{phase:"getUserFolder",src:o,userId:g}):y=P);}catch(p){A(m,p,{phase:"getUserFolder",src:o,userId:g});}let d=W.includes(s.format)?s.format:"jpeg",h=await ge(s.src,y,{websiteURL:r.websiteURL,apiRegex:r.apiRegex,apiPrefix:r.apiPrefix,maxBytes:r.maxDownloadBytes}),x;if(r.etag&&h&&(x=pe({src:s.src,width:s.width,height:s.height,format:d,quality:s.quality,type:s.type,folder:s.folder,parsedUserId:f},h),e.headers["if-none-match"]===x)){t.setHeader("Vary","Accept-Encoding"),t.setHeader("Cache-Control",r.cacheControl??K),t.setHeader("ETag",x),t.status(304).end(),M(c,{src:o,userId:g,format:d,outputBytes:0,cached:!0,durationMs:q(l),fallback:!1});return}let b=!1,H=()=>{b=!0;},z=await(async()=>s.src?s.src.startsWith("http://")||s.src.startsWith("https://")?oe(s.src,y,r.websiteURL,s.type,r.apiRegex,r.allowedNetworkList,{timeoutMs:r.requestTimeoutMs,maxBytes:r.maxDownloadBytes,maxRedirects:r.maxRedirects,onError:m,apiPrefix:r.apiPrefix,onFallback:H}):_(s.src,y,s.type,r.maxDownloadBytes,m,H):(H(),E[s.type]()))();if(b&&(x=void 0),!r.allowSvgInput&&ye(z)){let p=new Error("svg input rejected");throw A(m,p,{phase:"sharp",src:o,userId:g}),p}let U;try{let p=X__default.default(z,{failOn:"warning",limitInputPixels:r.maxInputPixels,sequentialRead:!0,unlimited:!1}),P=await p.metadata();if(P.width&&P.height&&P.width*P.height>r.maxInputPixels)throw new Error("input exceeds maxInputPixels");if(!r.allowSvgInput&&P.format==="svg")throw new Error("svg input rejected");if(p=X__default.default(z,{failOn:"warning",limitInputPixels:r.maxInputPixels,sequentialRead:!0,unlimited:!1}).rotate(),s.width||s.height){let C={width:s.width??void 0,height:s.height??void 0,fit:X__default.default.fit.cover,withoutEnlargement:!0};p=p.resize(C);}U=await p.toFormat(d,{quality:s.quality}).toBuffer();}catch(p){throw A(m,p,{phase:"sharp",src:o,userId:g}),p}if(r.etag&&!x&&(x=`"${crypto.createHash("sha256").update(U).digest("hex")}"`,e.headers["if-none-match"]===x)){t.setHeader("Vary","Accept-Encoding"),t.setHeader("Cache-Control",b?Q:r.cacheControl??K),t.setHeader("ETag",x),t.status(304).end(),M(c,{src:o,userId:g,format:d,outputBytes:0,cached:!0,durationMs:q(l),fallback:!1});return}let{asciiFilename:we,encodedFilename:be}=fe(s.src,d);t.type(T[d]),t.setHeader("Content-Disposition",`inline; filename="${we}"; filename*=UTF-8''${be}`),t.setHeader("Vary","Accept-Encoding"),t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("Cache-Control",b?Q:r.cacheControl??K),x&&t.setHeader("ETag",x),t.setHeader("Content-Length",U.length.toString()),t.send(U),M(c,{src:o,userId:g,format:d,outputBytes:U.length,cached:!1,durationMs:q(l),fallback:b});}catch{if(t.headersSent){let s=new Error("response already flushed");A(m,s,{phase:"fs",src:o,userId:g}),n(s);return}try{let s=a==="avatar"?"avatar":"normal",y=await E[s](),f=s==="avatar"?"png":"jpeg";t.type(T[f]),t.setHeader("Content-Disposition",`inline; filename="fallback.${f}"`),t.setHeader("Vary","Accept-Encoding"),t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("Cache-Control",Q),t.send(y),M(c,{src:o,userId:g,format:f,outputBytes:y.length,cached:!1,durationMs:q(l),fallback:!0});}catch(s){A(m,s,{phase:"fs",src:o,userId:g}),n(s);}}},Me=e=>{let t;try{t=ae(e);}catch(a){throw A(e.onError,a,{phase:"schema"}),a}let n,r=false,i,l=async a=>r&&n!==void 0?n:(i||(i=xe(a).then(m=>(n=m,r=true,m))),i);return async(a,m,c)=>{let o;return t.getUserFolderRootDir&&(o=await l(t.getUserFolderRootDir)),Ne(a,m,c,t,o)}},qe=Me; exports.buildDeterministicEtag=pe;exports.buildFilename=fe;exports.buildPinnedAgents=ne;exports.buildSourceIdentifier=ge;exports.isInsideRoot=he;exports.isPrivateIp=I;exports.isPublicHost=Ce;exports.isValidPath=D;exports.looksLikeSvg=ye;exports.optionsSchema=G;exports.registerServe=qe;exports.resolveInternalLocalPath=N;exports.resolvePinnedAddress=Le;exports.resolvePinnedAddresses=O;exports.resolveRootDir=xe;exports.stripApiPrefix=se;exports.userDataSchema=V;//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map