nest-feature-guard
Version:
A powerful, NestJS-first feature flag guard and decorator library with Redis caching support. Perfect for implementing feature toggles, A/B testing, gradual rollouts, and user-specific feature access control.
60 lines • 2.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RedisFeatureFlagCache = void 0;
class RedisFeatureFlagCache {
redis;
featureKeyPrefix;
constructor(redis, featureKeyPrefix = 'crudmates:feature-guard') {
this.redis = redis;
this.featureKeyPrefix = featureKeyPrefix;
}
async setFeatureFlag({ flag, enabled, userIds }) {
const featureInfoKey = `${this.featureKeyPrefix}:${flag}:info`;
const featureUsersKey = `${this.featureKeyPrefix}:${flag}:users`;
await this.redis.hmset(featureInfoKey, { enabled: enabled ? 'true' : 'false' });
if (userIds && userIds.length > 0) {
await this.redis.del(featureUsersKey);
const batchSize = 1000;
for (let i = 0; i < userIds.length; i += batchSize) {
const batch = userIds.slice(i, i + batchSize);
await this.redis.sadd(featureUsersKey, ...batch);
}
}
else {
await this.redis.del(featureUsersKey);
}
}
async getFeature(flag) {
const featureInfoKey = `${this.featureKeyPrefix}:${flag}:info`;
const featureUsersKey = `${this.featureKeyPrefix}:${flag}:users`;
const info = await this.redis.hgetall(featureInfoKey);
if (!info || !('enabled' in info))
return null;
const enabled = info.enabled === 'true';
const userIds = await this.redis.smembers(featureUsersKey);
return {
enabled,
userIds: userIds.length > 0 ? userIds : undefined,
};
}
async hasFeatureFlag(flag, userId) {
const featureInfoKey = `${this.featureKeyPrefix}:${flag}:info`;
const featureUsersKey = `${this.featureKeyPrefix}:${flag}:users`;
const info = await this.redis.hgetall(featureInfoKey);
if (!info || !('enabled' in info))
return false;
const enabled = info.enabled === 'true';
if (!enabled) {
return false;
}
const userIds = await this.redis.smembers(featureUsersKey);
const hasUsers = userIds.length > 0;
if (!hasUsers) {
return true;
}
const isUserInList = userIds.includes(userId);
return isUserInList;
}
}
exports.RedisFeatureFlagCache = RedisFeatureFlagCache;
//# sourceMappingURL=redis-feature-flag-cache.js.map