UNPKG

@interep/reputation

Version:
172 lines (160 loc) 5.61 kB
/** * @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 };