2022-12-21 23:26:55 +00:00
"use strict" ;
2022-01-09 15:20:59 +00:00
var _ _defProp = Object . defineProperty ;
var _ _getOwnPropDesc = Object . getOwnPropertyDescriptor ;
var _ _getOwnPropNames = Object . getOwnPropertyNames ;
var _ _hasOwnProp = Object . prototype . hasOwnProperty ;
var _ _export = ( target , all ) => {
for ( var name in all )
_ _defProp ( target , name , { get : all [ name ] , enumerable : true } ) ;
} ;
2022-12-21 23:26:55 +00:00
var _ _copyProps = ( to , from , except , desc ) => {
if ( from && typeof from === "object" || typeof from === "function" ) {
for ( let key of _ _getOwnPropNames ( from ) )
if ( ! _ _hasOwnProp . call ( to , key ) && key !== except )
_ _defProp ( to , key , { get : ( ) => from [ key ] , enumerable : ! ( desc = _ _getOwnPropDesc ( from , key ) ) || desc . enumerable } ) ;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
return to ;
2022-01-09 15:20:59 +00:00
} ;
2022-12-21 23:26:55 +00:00
var _ _toCommonJS = ( mod ) => _ _copyProps ( _ _defProp ( { } , "__esModule" , { value : true } ) , mod ) ;
2022-01-09 15:20:59 +00:00
// source/index.ts
var source _exports = { } ;
_ _export ( source _exports , {
2022-12-21 23:26:55 +00:00
MemoryStore : ( ) => MemoryStore ,
2022-01-18 16:39:42 +00:00
default : ( ) => lib _default ,
rateLimit : ( ) => lib _default
2022-01-09 15:20:59 +00:00
} ) ;
2022-12-21 23:26:55 +00:00
module . exports = _ _toCommonJS ( source _exports ) ;
2022-01-09 15:20:59 +00:00
// source/memory-store.ts
var calculateNextResetTime = ( windowMs ) => {
const resetTime = new Date ( ) ;
resetTime . setMilliseconds ( resetTime . getMilliseconds ( ) + windowMs ) ;
return resetTime ;
} ;
var MemoryStore = class {
init ( options ) {
this . windowMs = options . windowMs ;
this . resetTime = calculateNextResetTime ( this . windowMs ) ;
this . hits = { } ;
2022-12-21 23:26:55 +00:00
this . interval = setInterval ( async ( ) => {
2022-01-09 15:20:59 +00:00
await this . resetAll ( ) ;
} , this . windowMs ) ;
2022-12-21 23:26:55 +00:00
if ( this . interval . unref )
this . interval . unref ( ) ;
2022-01-09 15:20:59 +00:00
}
async increment ( key ) {
2022-12-21 23:26:55 +00:00
var _a ;
const totalHits = ( ( _a = this . hits [ key ] ) != null ? _a : 0 ) + 1 ;
2022-01-09 15:20:59 +00:00
this . hits [ key ] = totalHits ;
return {
totalHits ,
resetTime : this . resetTime
} ;
}
async decrement ( key ) {
const current = this . hits [ key ] ;
2022-12-21 23:26:55 +00:00
if ( current )
2022-01-09 15:20:59 +00:00
this . hits [ key ] = current - 1 ;
}
async resetKey ( key ) {
delete this . hits [ key ] ;
}
async resetAll ( ) {
this . hits = { } ;
this . resetTime = calculateNextResetTime ( this . windowMs ) ;
}
2022-12-21 23:26:55 +00:00
shutdown ( ) {
clearInterval ( this . interval ) ;
}
2022-01-09 15:20:59 +00:00
} ;
// source/lib.ts
var isLegacyStore = ( store ) => typeof store . incr === "function" && typeof store . increment !== "function" ;
var promisifyStore = ( passedStore ) => {
if ( ! isLegacyStore ( passedStore ) ) {
return passedStore ;
}
const legacyStore = passedStore ;
class PromisifiedStore {
async increment ( key ) {
return new Promise ( ( resolve , reject ) => {
2022-12-21 23:26:55 +00:00
legacyStore . incr (
key ,
( error , totalHits , resetTime ) => {
if ( error )
reject ( error ) ;
resolve ( { totalHits , resetTime } ) ;
}
) ;
2022-01-09 15:20:59 +00:00
} ) ;
}
async decrement ( key ) {
2022-12-21 23:26:55 +00:00
return legacyStore . decrement ( key ) ;
2022-01-09 15:20:59 +00:00
}
async resetKey ( key ) {
2022-12-21 23:26:55 +00:00
return legacyStore . resetKey ( key ) ;
2022-01-09 15:20:59 +00:00
}
async resetAll ( ) {
if ( typeof legacyStore . resetAll === "function" )
2022-12-21 23:26:55 +00:00
return legacyStore . resetAll ( ) ;
2022-01-09 15:20:59 +00:00
}
}
return new PromisifiedStore ( ) ;
} ;
var parseOptions = ( passedOptions ) => {
2022-12-21 23:26:55 +00:00
var _a , _b , _c ;
const notUndefinedOptions = omitUndefinedOptions ( passedOptions ) ;
const config = {
2022-01-09 15:20:59 +00:00
windowMs : 60 * 1e3 ,
max : 5 ,
message : "Too many requests, please try again later." ,
statusCode : 429 ,
2022-12-21 23:26:55 +00:00
legacyHeaders : ( _a = passedOptions . headers ) != null ? _a : true ,
standardHeaders : ( _b = passedOptions . draft _polli _ratelimit _headers ) != null ? _b : false ,
2022-01-09 15:20:59 +00:00
requestPropertyName : "rateLimit" ,
skipFailedRequests : false ,
skipSuccessfulRequests : false ,
requestWasSuccessful : ( _request , response ) => response . statusCode < 400 ,
skip : ( _request , _response ) => false ,
2022-12-21 23:26:55 +00:00
keyGenerator ( request , _response ) {
2022-01-09 15:20:59 +00:00
if ( ! request . ip ) {
2022-12-21 23:26:55 +00:00
console . error (
"WARN | `express-rate-limit` | `request.ip` is undefined. You can avoid this by providing a custom `keyGenerator` function, but it may be indicative of a larger issue."
) ;
2022-01-09 15:20:59 +00:00
}
return request . ip ;
} ,
2022-12-21 23:26:55 +00:00
async handler ( request , response , _next , _optionsUsed ) {
response . status ( config . statusCode ) ;
const message = typeof config . message === "function" ? await config . message (
request ,
response
) : config . message ;
if ( ! response . writableEnded ) {
response . send ( message != null ? message : "Too many requests, please try again later." ) ;
}
2022-01-09 15:20:59 +00:00
} ,
2022-12-21 23:26:55 +00:00
onLimitReached ( _request , _response , _optionsUsed ) {
2022-01-09 15:20:59 +00:00
} ,
2022-12-21 23:26:55 +00:00
... notUndefinedOptions ,
store : promisifyStore ( ( _c = notUndefinedOptions . store ) != null ? _c : new MemoryStore ( ) )
2022-01-09 15:20:59 +00:00
} ;
2022-12-21 23:26:55 +00:00
if ( typeof config . store . increment !== "function" || typeof config . store . decrement !== "function" || typeof config . store . resetKey !== "function" || typeof config . store . resetAll !== "undefined" && typeof config . store . resetAll !== "function" || typeof config . store . init !== "undefined" && typeof config . store . init !== "function" ) {
throw new TypeError (
"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface."
) ;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
return config ;
2022-01-09 15:20:59 +00:00
} ;
var handleAsyncErrors = ( fn ) => async ( request , response , next ) => {
try {
await Promise . resolve ( fn ( request , response , next ) ) . catch ( next ) ;
} catch ( error ) {
next ( error ) ;
}
} ;
var rateLimit = ( passedOptions ) => {
2022-12-21 23:26:55 +00:00
const options = parseOptions ( passedOptions != null ? passedOptions : { } ) ;
2022-01-09 15:20:59 +00:00
if ( typeof options . store . init === "function" )
options . store . init ( options ) ;
2022-12-21 23:26:55 +00:00
const middleware = handleAsyncErrors (
async ( request , response , next ) => {
const skip = await options . skip ( request , response ) ;
if ( skip ) {
next ( ) ;
return ;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
const augmentedRequest = request ;
const key = await options . keyGenerator ( request , response ) ;
const { totalHits , resetTime } = await options . store . increment ( key ) ;
const retrieveQuota = typeof options . max === "function" ? options . max ( request , response ) : options . max ;
const maxHits = await retrieveQuota ;
augmentedRequest [ options . requestPropertyName ] = {
limit : maxHits ,
current : totalHits ,
remaining : Math . max ( maxHits - totalHits , 0 ) ,
resetTime
} ;
if ( options . legacyHeaders && ! response . headersSent ) {
response . setHeader ( "X-RateLimit-Limit" , maxHits ) ;
response . setHeader (
"X-RateLimit-Remaining" ,
augmentedRequest [ options . requestPropertyName ] . remaining
) ;
if ( resetTime instanceof Date ) {
response . setHeader ( "Date" , new Date ( ) . toUTCString ( ) ) ;
response . setHeader (
"X-RateLimit-Reset" ,
Math . ceil ( resetTime . getTime ( ) / 1e3 )
) ;
}
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if ( options . standardHeaders && ! response . headersSent ) {
response . setHeader ( "RateLimit-Limit" , maxHits ) ;
response . setHeader (
"RateLimit-Remaining" ,
augmentedRequest [ options . requestPropertyName ] . remaining
) ;
if ( resetTime ) {
const deltaSeconds = Math . ceil (
( resetTime . getTime ( ) - Date . now ( ) ) / 1e3
) ;
response . setHeader ( "RateLimit-Reset" , Math . max ( 0 , deltaSeconds ) ) ;
2022-01-09 15:20:59 +00:00
}
}
2022-12-21 23:26:55 +00:00
if ( options . skipFailedRequests || options . skipSuccessfulRequests ) {
let decremented = false ;
const decrementKey = async ( ) => {
if ( ! decremented ) {
await options . store . decrement ( key ) ;
decremented = true ;
}
} ;
if ( options . skipFailedRequests ) {
response . on ( "finish" , async ( ) => {
if ( ! options . requestWasSuccessful ( request , response ) )
await decrementKey ( ) ;
} ) ;
response . on ( "close" , async ( ) => {
if ( ! response . writableEnded )
await decrementKey ( ) ;
} ) ;
response . on ( "error" , async ( ) => {
2022-01-09 15:20:59 +00:00
await decrementKey ( ) ;
2022-12-21 23:26:55 +00:00
} ) ;
}
if ( options . skipSuccessfulRequests ) {
response . on ( "finish" , async ( ) => {
if ( options . requestWasSuccessful ( request , response ) )
await decrementKey ( ) ;
} ) ;
}
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if ( maxHits && totalHits === maxHits + 1 ) {
options . onLimitReached ( request , response , options ) ;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
if ( maxHits && totalHits > maxHits ) {
if ( ( options . legacyHeaders || options . standardHeaders ) && ! response . headersSent ) {
response . setHeader ( "Retry-After" , Math . ceil ( options . windowMs / 1e3 ) ) ;
}
options . handler ( request , response , next , options ) ;
return ;
}
next ( ) ;
2022-01-09 15:20:59 +00:00
}
2022-12-21 23:26:55 +00:00
) ;
2022-01-09 15:20:59 +00:00
middleware . resetKey = options . store . resetKey . bind ( options . store ) ;
return middleware ;
} ;
2022-12-21 23:26:55 +00:00
var omitUndefinedOptions = ( passedOptions ) => {
const omittedOptions = { } ;
for ( const k of Object . keys ( passedOptions ) ) {
const key = k ;
if ( passedOptions [ key ] !== void 0 ) {
omittedOptions [ key ] = passedOptions [ key ] ;
}
}
return omittedOptions ;
} ;
2022-01-09 15:20:59 +00:00
var lib _default = rateLimit ;
2022-12-21 23:26:55 +00:00
module . exports = rateLimit ; module . exports . default = rateLimit ; module . exports . rateLimit = rateLimit ; module . exports . MemoryStore = MemoryStore ;