express-rate-limit-ioredis-store
Version:
A redis store implementation to be used alongside ioredis for the express-rate-limit middleware
1 lines • 7.65 kB
JSON
{"/home/gusta/express-rate-limit-redis-store/src/index.ts":{"path":"/home/gusta/express-rate-limit-redis-store/src/index.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":62}},"1":{"start":{"line":5,"column":8},"end":{"line":5,"column":29}},"2":{"start":{"line":6,"column":8},"end":{"line":6,"column":122}},"3":{"start":{"line":7,"column":8},"end":{"line":7,"column":26}},"4":{"start":{"line":10,"column":8},"end":{"line":10,"column":41}},"5":{"start":{"line":13,"column":25},"end":{"line":13,"column":45}},"6":{"start":{"line":14,"column":26},"end":{"line":14,"column":58}},"7":{"start":{"line":15,"column":30},"end":{"line":15,"column":78}},"8":{"start":{"line":16,"column":8},"end":{"line":19,"column":10}},"9":{"start":{"line":22,"column":25},"end":{"line":22,"column":45}},"10":{"start":{"line":23,"column":8},"end":{"line":25,"column":9}},"11":{"start":{"line":24,"column":12},"end":{"line":24,"column":45}},"12":{"start":{"line":28,"column":8},"end":{"line":28,"column":52}},"13":{"start":{"line":31,"column":8},"end":{"line":31,"column":39}},"14":{"start":{"line":34,"column":31},"end":{"line":34,"column":42}},"15":{"start":{"line":35,"column":8},"end":{"line":39,"column":9}},"16":{"start":{"line":36,"column":24},"end":{"line":36,"column":44}},"17":{"start":{"line":37,"column":12},"end":{"line":37,"column":61}},"18":{"start":{"line":38,"column":12},"end":{"line":38,"column":23}},"19":{"start":{"line":40,"column":27},"end":{"line":40,"column":70}},"20":{"start":{"line":41,"column":8},"end":{"line":41,"column":36}},"21":{"start":{"line":44,"column":0},"end":{"line":44,"column":47}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":4,"column":4},"end":{"line":4,"column":5}},"loc":{"start":{"line":4,"column":42},"end":{"line":8,"column":5}},"line":4},"1":{"name":"(anonymous_1)","decl":{"start":{"line":9,"column":4},"end":{"line":9,"column":5}},"loc":{"start":{"line":9,"column":18},"end":{"line":11,"column":5}},"line":9},"2":{"name":"(anonymous_2)","decl":{"start":{"line":12,"column":4},"end":{"line":12,"column":5}},"loc":{"start":{"line":12,"column":25},"end":{"line":20,"column":5}},"line":12},"3":{"name":"(anonymous_3)","decl":{"start":{"line":21,"column":4},"end":{"line":21,"column":5}},"loc":{"start":{"line":21,"column":25},"end":{"line":26,"column":5}},"line":21},"4":{"name":"(anonymous_4)","decl":{"start":{"line":27,"column":4},"end":{"line":27,"column":5}},"loc":{"start":{"line":27,"column":24},"end":{"line":29,"column":5}},"line":27},"5":{"name":"(anonymous_5)","decl":{"start":{"line":30,"column":4},"end":{"line":30,"column":5}},"loc":{"start":{"line":30,"column":20},"end":{"line":32,"column":5}},"line":30},"6":{"name":"(anonymous_6)","decl":{"start":{"line":33,"column":4},"end":{"line":33,"column":5}},"loc":{"start":{"line":33,"column":39},"end":{"line":42,"column":5}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":6,"column":28},"end":{"line":6,"column":121}},"type":"cond-expr","locations":[{"start":{"line":6,"column":79},"end":{"line":6,"column":91}},{"start":{"line":6,"column":94},"end":{"line":6,"column":121}}],"line":6},"1":{"loc":{"start":{"line":6,"column":28},"end":{"line":6,"column":76}},"type":"binary-expr","locations":[{"start":{"line":6,"column":28},"end":{"line":6,"column":49}},{"start":{"line":6,"column":53},"end":{"line":6,"column":76}}],"line":6},"2":{"loc":{"start":{"line":23,"column":8},"end":{"line":25,"column":9}},"type":"if","locations":[{"start":{"line":23,"column":8},"end":{"line":25,"column":9}},{"start":{"line":23,"column":8},"end":{"line":25,"column":9}}],"line":23},"3":{"loc":{"start":{"line":35,"column":8},"end":{"line":39,"column":9}},"type":"if","locations":[{"start":{"line":35,"column":8},"end":{"line":39,"column":9}},{"start":{"line":35,"column":8},"end":{"line":39,"column":9}}],"line":35}},"s":{"0":1,"1":4,"2":4,"3":4,"4":4,"5":6,"6":6,"7":6,"8":6,"9":2,"10":2,"11":1,"12":2,"13":10,"14":6,"15":6,"16":5,"17":5,"18":5,"19":1,"20":1,"21":1},"f":{"0":4,"1":4,"2":6,"3":2,"4":2,"5":10,"6":6},"b":{"0":[3,1],"1":[4,4],"2":[1,1],"3":[5,1]},"inputSourceMap":{"version":3,"file":"/home/gusta/express-rate-limit-redis-store/src/index.ts","sources":["/home/gusta/express-rate-limit-redis-store/src/index.ts"],"names":[],"mappings":";;AAQA,MAAqB,4BAA4B;IAK/C,YAAY,EAAC,YAAY,EAAE,MAAM,EAAoB;QACnD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,2BAA2B,CAAC;QAChE,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,OAAgB;QACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAEvE,OAAO;YACL,SAAS;YACT,SAAS,EAAE,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC;SACnD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YACnC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SAClC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW;QACxB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,CAAC;IAEO,UAAU,CAAC,GAAW;QAC5B,OAAO,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,GAAW,EAAE,KAAa;QACvD,MAAM,cAAc,GAAG,KAAK,KAAK,CAAC,CAAC;QACnC,IAAI,cAAc,EAAE;YAClB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,cAAc,EAAE,GAAG,CAAC,CAAC;YACjD,OAAO,GAAG,CAAC;SACZ;QACD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;QAC/D,OAAO,QAAQ,CAAC,UAAoB,CAAC,CAAC;IACxC,CAAC;CACF;AAnDD,+CAmDC","sourcesContent":["import {IncrementResponse, Options, Store} from 'express-rate-limit';\nimport Redis from 'ioredis';\n\ntype RedisStoreOptions = {\n globalPrefix?: string;\n client: Redis.Redis;\n};\n\nexport default class ExpressRateLimitIORedisStore implements Store {\n private client: Redis.Redis;\n private globalPrefix: string;\n private windowMs: number;\n\n constructor({globalPrefix, client}: RedisStoreOptions) {\n this.client = client;\n this.globalPrefix = globalPrefix ?? 'express-rate-limit-store-';\n this.windowMs = 0;\n }\n\n init(options: Options): void {\n this.windowMs = options.windowMs;\n }\n\n async increment(key: string): Promise<IncrementResponse> {\n const redisKey = this.getFullKey(key);\n const totalHits = await this.client.incr(redisKey);\n const insertionTime = await this.getInsertionTime(redisKey, totalHits);\n\n return {\n totalHits,\n resetTime: new Date(insertionTime + this.windowMs),\n };\n }\n\n async decrement(key: string): Promise<void> {\n const redisKey = this.getFullKey(key);\n if (await this.client.get(redisKey)) {\n await this.client.decr(redisKey);\n }\n }\n\n async resetKey(key: string): Promise<void> {\n await this.client.del(this.getFullKey(key));\n }\n\n private getFullKey(key: string) {\n return this.globalPrefix + key;\n }\n\n private async getInsertionTime(key: string, value: number) {\n const isKeyInsertion = value === 1;\n if (isKeyInsertion) {\n const now = new Date().getTime();\n await this.client.set(key + '-create-time', now);\n return now;\n }\n const createTime = await this.client.get(key + '-create-time');\n return parseInt(createTime as string);\n }\n}\n"]},"_coverageSchema":"1a1c01bbd47fc00a2c39e90264f33305004495a9","hash":"04a74a4b100c3e219a592cf76bfd4060a04c49e6","contentHash":"b8839f1d7bfc34616bc7d08fed6c7cfc50914aecc9354c124001b7d523b7594a"}}