UNPKG

elysia

Version:

Ergonomic Framework for Human

149 lines (148 loc) 6.09 kB
import { mapResponse, mapEarlyResponse, mapCompactResponse, createStaticHandler } from "./handler.mjs"; const WebStandardAdapter = { name: "web-standard", isWebStandard: !0, handler: { mapResponse, mapEarlyResponse, mapCompactResponse, createStaticHandler }, composeHandler: { mapResponseContext: "c.request", preferWebstandardHeaders: !0, // @ts-ignore Bun specific headers: `c.headers={} for(const [k,v] of c.request.headers.entries())c.headers[k]=v `, parser: { json(isOptional) { return isOptional ? `try{c.body=await c.request.json()}catch{} ` : `c.body=await c.request.json() `; }, text() { return `c.body=await c.request.text() `; }, urlencoded() { return `c.body=parseQuery(await c.request.text()) `; }, arrayBuffer() { return `c.body=await c.request.arrayBuffer() `; }, formData(isOptional) { let fnLiteral = ` c.body={} `; return isOptional ? fnLiteral += "let form;try{form=await c.request.formData()}catch{}" : fnLiteral += `const form=await c.request.formData() `, fnLiteral + `const dangerousKeys=new Set(['__proto__','constructor','prototype']) const isDangerousKey=(k)=>{if(dangerousKeys.has(k))return true;const m=k.match(/^(.+)\\[(\\d+)\\]$/);return m?dangerousKeys.has(m[1]):false} const parseArrayKey=(k)=>{const m=k.match(/^(.+)\\[(\\d+)\\]$/);return m?{name:m[1],index:parseInt(m[2],10)}:null} for(const key of form.keys()){if(c.body[key])continue const value=form.getAll(key) let finalValue if(value.length===1){ const sv=value[0] if(typeof sv==='string'&&(sv.charCodeAt(0)===123||sv.charCodeAt(0)===91)){ try{ const p=JSON.parse(sv) if(p&&typeof p==='object')finalValue=p }catch{} } if(finalValue===undefined)finalValue=sv }else finalValue=value if(Array.isArray(finalValue)){ const stringValue=finalValue.find((entry)=>typeof entry==='string') const files=typeof File==='undefined'?[]:finalValue.filter((entry)=>entry instanceof File) if(stringValue&&files.length&&stringValue.charCodeAt(0)===123){ try{ const parsed=JSON.parse(stringValue) if(parsed&&typeof parsed==='object'&&!Array.isArray(parsed)){ if(!('file' in parsed)&&files.length===1)parsed.file=files[0] else if(!('files' in parsed)&&files.length>1)parsed.files=files finalValue=parsed } }catch{} } } if(key.includes('.')||key.includes('[')){const keys=key.split('.') const lastKey=keys.pop() if(isDangerousKey(lastKey)||keys.some(isDangerousKey))continue let current=c.body for(const k of keys){const arrayInfo=parseArrayKey(k) if(arrayInfo){if(!Array.isArray(current[arrayInfo.name]))current[arrayInfo.name]=[] const existing=current[arrayInfo.name][arrayInfo.index] const isFile=typeof File!=='undefined'&&existing instanceof File if(!existing||typeof existing!=='object'||Array.isArray(existing)||isFile){ let parsed if(typeof existing==='string'&&existing.charCodeAt(0)===123){ try{parsed=JSON.parse(existing) if(!parsed||typeof parsed!=='object'||Array.isArray(parsed))parsed=undefined}catch{} } current[arrayInfo.name][arrayInfo.index]=parsed||{} } current=current[arrayInfo.name][arrayInfo.index]}else{if(!current[k]||typeof current[k]!=='object')current[k]={} current=current[k]}} const arrayInfo=parseArrayKey(lastKey) if(arrayInfo){if(!Array.isArray(current[arrayInfo.name]))current[arrayInfo.name]=[] current[arrayInfo.name][arrayInfo.index]=finalValue}else{current[lastKey]=finalValue}}else c.body[key]=finalValue}`; } } }, async stop(app, closeActiveConnections) { if (!app.server) throw new Error( "Elysia isn't running. Call `app.listen` to start the server." ); if (app.server && (await app.server.stop(closeActiveConnections), app.server = null, app.event.stop?.length)) for (let i = 0; i < app.event.stop.length; i++) app.event.stop[i].fn(app); }, composeGeneralHandler: { parameters: "r", createContext(app) { let decoratorsLiteral = "", fnLiteral = ""; const defaultHeaders = app.setHeaders; for (const key of Object.keys(app.decorator)) decoratorsLiteral += `,'${key}':decorator['${key}']`; const standardHostname = app.config.handler?.standardHostname ?? !0, hasTrace = !!app.event.trace?.length; return fnLiteral += `const u=r.url,s=u.indexOf('/',${standardHostname ? 11 : 7}),qi=u.indexOf('?',s+1),p=u.substring(s,qi===-1?undefined:qi) `, hasTrace && (fnLiteral += `const id=randomId() `), fnLiteral += "const c={request:r,store,qi,path:p,url:u,redirect,status,set:{headers:", fnLiteral += Object.keys(defaultHeaders ?? {}).length ? "Object.assign({},app.setHeaders)" : "Object.create(null)", fnLiteral += ",status:200}", app.inference.server && (fnLiteral += ",get server(){return app.getServer()}"), hasTrace && (fnLiteral += ",[ELYSIA_REQUEST_ID]:id"), fnLiteral += decoratorsLiteral, fnLiteral += `} `, fnLiteral; }, error404(hasEventHook, hasErrorHook, afterHandle = "") { let findDynamicRoute = "if(route===null){" + afterHandle + (hasErrorHook ? "" : "c.set.status=404") + ` return `; return hasErrorHook ? findDynamicRoute += `app.handleError(c,notFound,false,${this.parameters})` : findDynamicRoute += hasEventHook ? "c.response=c.responseValue=new Response(error404Message,{status:c.set.status===200?404:c.set.status,headers:c.set.headers})" : "c.response=c.responseValue=error404.clone()", findDynamicRoute += "}", { declare: hasErrorHook ? "" : `const error404Message=notFound.message.toString() const error404=new Response(error404Message,{status:404}) `, code: findDynamicRoute }; } }, composeError: { mapResponseContext: "", validationError: "set.headers['content-type']='application/json';return mapResponse(error.message,set)", unknownError: "set.status=error.status??set.status??500;return mapResponse(error.message,set)" }, listen() { return () => { throw new Error( "WebStandard does not support listen, you might want to export default Elysia.fetch instead" ); }; } }; export { WebStandardAdapter };