@alessiofrittoli/next-api
Version:
Next.js API utility library
1 lines • 5.25 kB
JavaScript
import {ErrorCode}from'@alessiofrittoli/exception/code';import {NextResponse}from'next/server';import {removeTrailingSlash}from'@alessiofrittoli/url-utils/slash';import {Exception}from'@alessiofrittoli/exception';import {generatorToReadableStream}from'@alessiofrittoli/stream-reader/utils';import {isGeneratorObject}from'@alessiofrittoli/web-utils/generators';import {jsx}from'react/jsx-runtime';import {getTypedMap}from'@alessiofrittoli/web-utils';import {Cookie}from'@alessiofrittoli/web-utils/storage/Cookie';export{Priority,SameSite}from'@alessiofrittoli/web-utils/storage/Cookie';var y=(s=>s)(y||{}),P={Exception:ErrorCode,Next:y};var c=class c extends NextResponse{constructor(e={}){let{body:t,init:r,request:a,cors:o}=e;o&&c.cors(a,typeof o!="boolean"?o:void 0),super(t,c.CorsInit(r));}static json(e,t){return super.json(e,this.CorsInit(t))}static successJson(e,t){let r={message:e};return this.json(r,t)}static errorJson(e,t={}){let r=t.status||e.status||500;return t.status=r,e.status=r,this.json(e,t)}static stream(e,t){return new Response(isGeneratorObject(e)?this.generatorToStream(e):e,this.CorsInit(t))}static emptyBody(e){return this.errorJson(new Exception("Empty, invalid or locked Request Body",{code:P.Exception.EMPTY_VALUE,status:422}),e)}static cors(e,t){let r=e?.headers.get("origin")||void 0;return this.CorsOptions={...t,requestOrigin:r},this}static CorsInit(e){if(!this.CorsOptions)return e;let t=this.CorsHeaders({options:this.CorsOptions,headers:e?.headers});return this.CorsOptions=void 0,{...e,headers:t}}static CorsHeaders({options:e={},headers:t}={}){let r="*",{ALLOWED_API_ORIGINS:a}=process.env,{requestOrigin:o}=e,n=e.methods||this.CorsAllowedMethods,i=e.origin||a||r;typeof i=="string"&&i!==r&&(i=i.replace(/\s/g,"").split(",").filter(Boolean).map(removeTrailingSlash)),o&&(i.includes(removeTrailingSlash(o))||i===r)&&(i=o);let p=new Headers(t);p.set("Access-Control-Allow-Origin",i.toString()),typeof e.credentials<"u"&&p.set("Access-Control-Allow-Credentials",e.credentials.toString());let l=this.CorsAllowedHeaders.concat(e.headers||[]),f=this.CorsExposedHeaders.concat(e.exposedHeaders||[]);return l.length>0&&p.set("Access-Control-Allow-Headers",l.join(", ")),f.length>0&&p.set("Access-Control-Expose-Headers",f.join(", ")),n.length>0&&p.set("Access-Control-Allow-Methods",n.join(", ")),p}};c.CorsAllowedMethods=["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"],c.CorsAllowedHeaders=["Accept","Accept-Version","Authorization","Content-Length","Content-MD5","Content-Type","Date","X-Api-Key","X-Api-Version","X-CSRF-Token","X-Locale","X-Requested-With"],c.CorsExposedHeaders=["Connection","Retry-After","Keep-Alive","Date"],c.generatorToStream=generatorToReadableStream;var u=c;var N=(s,e,t=true)=>new u({body:null,init:{status:204},request:s,cors:t});var j=()=>()=>u.next();var I=(s,e)=>typeof e>"u";function W(s,e=false){return async(r,a)=>{let o=await r.params,n=e?await r.searchParams:r.searchParams;return I(s,a)?jsx(s,{...r,params:o,searchParams:n}):s({...r,params:o,searchParams:n},await a)}}var Y=async(s,e=false)=>{try{return e?await s.clone().json():await s.json()}catch{return null}},_=async(s,e=false,t)=>{let r=await(e?s.clone():s).formData(),a=getTypedMap();return Array.from(r.entries()).map(([o,n],i,p)=>{if(a.has(o))return;let l=p.filter(([R])=>R===o),f=l.length<=1?n:l.map(([,R])=>R);if(t)return a.set(o,t(o,f));a.set(o,f);}),a},Z=async(s,e=false)=>Array.from((await(e?s.clone():s).formData()).entries()).map(([,t])=>t).filter(t=>t instanceof File);var x=async s=>{let e=s?.headers||await(await import('next/headers')).headers(),t=e.get("X-Forwarded-For")?.replace(/\s/g,"").split(",").at(-1),r=e.get("X-Real-Ip")?.replace(/\s/g,"").split(",").at(-1);return t||r||null};var g=null,h=new Map,oe=async(s,e,t,r,a,o)=>{if(!t||t===1/0)return e(s);let n=await x(s)||"::1";r&&(g&&(clearTimeout(g),g=null),g=setTimeout(()=>{h.delete(n);},r*1e3));let i=(h.get(n)||0)+1;if(h.set(n,i),i<=t)return e(s);let p={status:429,headers:r?{"Retry-After":r.toString(),"X-Max-Requests":t.toString()}:void 0},l=a?{...typeof a=="object"?a:void 0,exposedHeaders:[...typeof a=="object"?a.exposedHeaders||[]:[],"X-Max-Requests"]}:void 0;return o&&await o(n,h),new u({body:null,init:p,cors:l,request:s})};var m=class m{static request(e){return this._request=e,this}static headers(e){return this._headers=e,this}static getHeaders(){return this._headers||(this._headers=new Headers),this._headers}static get(e){if(this._request)return Cookie.fromListString(this._request.headers.get("Cookie")||"").get(e)}static getAll(){return Cookie.fromListString(this._request?.headers.get("Cookie")||"")}static set(e){let t=Cookie.parse(e),r=this.getHeaders();return t.has("path")||t.set("path","/"),t.has("httpOnly")||t.set("httpOnly",true),r.append("Set-Cookie",Cookie.toString(t)),this}static delete(e){return m.set(Cookie.parse(e).set("maxAge",0))}};m.toString=Cookie.toString,m.fromString=Cookie.fromString,m.fromListString=Cookie.fromListString,m.parse=Cookie.parse;var C=m;export{P as ErrorCode,C as HttpCookie,y as Next,u as NextResponse,N as corsPreflight,Z as getRequestFiles,x as getRequestIp,I as isPageReactFC,j as lastMiddleware,_ as readFormDataBody,Y as readJsonBody,W as withAwaitedParams,oe as withRateLimit};