@interep/reputation
Version:
Definitions and utility functions of Interep reputation.
172 lines (160 loc) • 5.61 kB
JavaScript
/**
* @module @interep/reputation
* @version 0.5.0
* @file Definitions and utility functions of Interep reputation.
* @copyright Omar Desogus 2023
* @license MIT
* @see [Github]{@link https://github.com/interep-project/interep.js/tree/main/packages/reputation}
*/
import { object, min, number, boolean, size, assert } from 'superstruct';
var OAuthProvider;
(function (OAuthProvider) {
OAuthProvider["TWITTER"] = "twitter";
OAuthProvider["GITHUB"] = "github";
OAuthProvider["REDDIT"] = "reddit";
})(OAuthProvider || (OAuthProvider = {}));
var ReputationLevel;
(function (ReputationLevel) {
ReputationLevel["Commoner"] = "commoner";
ReputationLevel["UpAndComing"] = "up-and-coming";
ReputationLevel["Established"] = "established";
ReputationLevel["Star"] = "star";
ReputationLevel["Icon"] = "icon";
})(ReputationLevel || (ReputationLevel = {}));
var Operator;
(function (Operator) {
Operator["Eq"] = "eq";
Operator["Gt"] = "gt";
Operator["Lt"] = "lt";
Operator["Gte"] = "gte";
})(Operator || (Operator = {}));
var _a;
var CRITERIA_CONFIG = (_a = {},
_a[OAuthProvider.GITHUB] = {
bins: [
[0, 1],
[1, 10],
[10, 100],
[100, 1000]
],
condition: { operator: Operator.Gte, operand: 1, binIndexGrantedIfSatisfied: 2 } // sponsors + sponsoring
},
_a[OAuthProvider.REDDIT] = {
bins: [
[0, 2000],
[2000, 20000],
[20000, 100000],
[100000, 200000]
],
condition: { operator: Operator.Eq, operand: true, binIndexGrantedIfSatisfied: 1 } // is_gold
},
_a[OAuthProvider.TWITTER] = {
bins: [
[0, 100],
[100, 1000],
[1000, 10000],
[10000, 100000]
],
condition: { operator: Operator.Eq, operand: true, binIndexGrantedIfSatisfied: 2 } // verified
},
_a);
function getBin(x, bins) {
if (x < 0)
throw new Error("only accept positive numbers");
var i = 0;
while (i < bins.length && !(bins[i][0] <= x && x < bins[i][1])) {
i += 1;
}
return i;
}
var operate = function (input, op) {
var operator = op.operator, operand = op.operand;
switch (operator) {
case Operator.Eq:
return input === operand;
case Operator.Gt:
return input > operand;
case Operator.Lt:
return input < operand;
case Operator.Gte:
return input >= operand;
default:
throw new Error("Unknown operator ".concat(operator));
}
};
var createRule = function (_a) {
var bins = _a.bins, condition = _a.condition;
return function (numericalAttr, extraAttr) {
var binIndex = getBin(numericalAttr, bins);
var extraAttrSatisfiesCondition = operate(extraAttr, condition);
var tierIndex = extraAttrSatisfiesCondition ? condition.binIndexGrantedIfSatisfied : binIndex;
return [
ReputationLevel.Commoner,
ReputationLevel.UpAndComing,
ReputationLevel.Established,
ReputationLevel.Star,
ReputationLevel.Icon
][tierIndex];
};
};
var criteria = Object.fromEntries(Object.entries(CRITERIA_CONFIG).map(function (_a) {
var provider = _a[0], config = _a[1];
return [provider, createRule(config)];
}));
var GhStruct = object({
receivedStars: min(number(), 0),
sponsorsCount: min(number(), 0),
sponsoringCount: min(number(), 0)
});
var RedditStruct = object({
totalKarma: min(number(), 0),
isGold: boolean()
});
var TwitterStruct = object({
followers: min(number(), 0),
botometerOverallScore: size(number(), 0, 1),
verifiedProfile: boolean()
});
/**
* Returns the reputation based on the parameters.
* @param provider The provider.
* @param parameters The provider parameters to check.
* @returns The reputation level found.
*/
// eslint-disable-next-line consistent-return
var calculateReputation = function (provider, parameters) {
if (!Object.values(OAuthProvider).includes(provider))
throw new Error("Provider '".concat(provider, "' is not supported"));
if (provider === OAuthProvider.GITHUB) {
assert(parameters, GhStruct);
var _a = parameters, receivedStars = _a.receivedStars, sponsorsCount = _a.sponsorsCount, sponsoringCount = _a.sponsoringCount;
return criteria[OAuthProvider.GITHUB](receivedStars, sponsorsCount + sponsoringCount);
}
if (provider === OAuthProvider.REDDIT) {
assert(parameters, RedditStruct);
var _b = parameters, totalKarma = _b.totalKarma, isGold = _b.isGold;
return criteria[OAuthProvider.REDDIT](totalKarma, isGold);
}
if (provider === OAuthProvider.TWITTER) {
assert(parameters, TwitterStruct);
var _c = parameters, followers = _c.followers, verifiedProfile = _c.verifiedProfile, botometerOverallScore = _c.botometerOverallScore;
if (botometerOverallScore >= 0.95)
throw new Error("You are a bot!");
return criteria[OAuthProvider.TWITTER](followers, verifiedProfile);
}
};
/**
* Returns all supported OAuth providers.
* @returns A list of providers.
*/
function getOAuthProviders() {
return Object.values(OAuthProvider);
}
/**
* Returns all the reputation levels (gold, silver, bronze).
* @returns A list of reputation levels.
*/
function getReputationLevels() {
return Object.values(ReputationLevel);
}
export { OAuthProvider, ReputationLevel, calculateReputation, getOAuthProviders, getReputationLevels };