@graphql-mesh/plugin-rate-limit
Version:
50 lines (49 loc) • 2.18 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = useMeshRateLimit;
const rate_limiter_1 = require("@envelop/rate-limiter");
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
const string_interpolation_1 = require("@graphql-mesh/string-interpolation");
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
class RateLimitMeshStore extends rate_limiter_1.Store {
constructor(cache) {
super();
this.cache = cache;
}
getForIdentity(identity) {
return (0, promise_helpers_1.handleMaybePromise)(() => this.cache.get(`rate-limit:${identity.contextIdentity}:${identity.fieldIdentity}`), value => value || []);
}
setForIdentity(identity, timestamps, windowMs) {
return this.cache.set(`rate-limit:${identity.contextIdentity}:${identity.fieldIdentity}`, timestamps, { ttl: windowMs / 1000 });
}
}
function useMeshRateLimit({ config, cache, }) {
return (0, rate_limiter_1.useRateLimiter)({
identifyFn: (context) => context.headers?.authorization ||
context.req?.socket?.remoteAddress ||
context.req?.connection?.remoteAddress ||
context.req?.ip ||
context.headers?.['x-forwarded-for'] ||
context.headers?.host ||
'unknown',
store: new RateLimitMeshStore(cache),
interpolateMessage: (message, identifier, params) => string_interpolation_1.stringInterpolator.parse(message, {
...params,
id: identifier,
identifier,
}),
configByField: config.map(origConfig => ({
type: origConfig.type,
field: origConfig.field,
max: origConfig.max,
window: `${origConfig.ttl}ms`,
message: `Rate limit of "${origConfig.type}.${origConfig.field}" exceeded for "{id}"`,
identifyFn: origConfig.identifier
? (context) => string_interpolation_1.stringInterpolator.parse(origConfig.identifier, {
context,
env: cross_helpers_1.process.env,
})
: undefined,
})),
});
}
;