import assert from 'assert'; import { isNil, isObject } from 'lodash'; import { DateTime } from 'luxon'; import { LimitResultInterface } from '@/models/limiter'; /** * Attach limit headers * * @param {Request} request * @param {Response} response * @param {Date} curDate * @returns {void} */ export function attachLimitToRequest(request, response, curDate = DateTime.utc().toJSDate()): void { const { limitResult }: { limitResult: LimitResultInterface } = request?.locals || {}; if (!limitResult) return; response.set('X-RateLimit-Limit', limitResult.limit); response.set('X-RateLimit-Remaining', limitResult.remaining); response.set('X-RateLimit-Reset', DateTime.fromJSDate(curDate).plus({ milliseconds: limitResult.resetMs }).toISO()); if (limitResult.blockReason) { // eslint-disable-next-line no-magic-numbers response.set('Retry-After', Math.round(limitResult.resetMs / 1000)); } } /** * Assert properties of object * * @param {{}} obj * @param {string[]} properties * @returns {void} */ export function assertProperties(obj: any, properties: string[]): void { if (!isObject(obj)) throw new Error('not object'); if (properties.length === 0) throw new Error('no properties provided'); properties.map((prop) => assert(!isNil(obj[prop]), `${prop} not found on obj`)); }