mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 07:16:17 +08:00
refactor: shared types (miodec) (#4978)
* rework shared types * revert one small change
This commit is contained in:
parent
ee629db5b5
commit
0751375ab6
|
@ -644,7 +644,7 @@ interface XpResult {
|
|||
|
||||
async function calculateXp(
|
||||
result,
|
||||
xpConfiguration: MonkeyTypes.Configuration["users"]["xp"],
|
||||
xpConfiguration: SharedTypes.Configuration["users"]["xp"],
|
||||
uid: string,
|
||||
currentTotalXp: number,
|
||||
streak: number
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* To add a new configuration. Simply add it to this object.
|
||||
* When changing this template, please follow the principle of "Secure by default" (https://en.wikipedia.org/wiki/Secure_by_default).
|
||||
*/
|
||||
export const BASE_CONFIGURATION: MonkeyTypes.Configuration = {
|
||||
export const BASE_CONFIGURATION: SharedTypes.Configuration = {
|
||||
maintenance: false,
|
||||
results: {
|
||||
savingEnabled: false,
|
||||
|
@ -141,7 +141,7 @@ type Schema<T> = {
|
|||
: never;
|
||||
};
|
||||
|
||||
export const CONFIGURATION_FORM_SCHEMA: ObjectSchema<MonkeyTypes.Configuration> =
|
||||
export const CONFIGURATION_FORM_SCHEMA: ObjectSchema<SharedTypes.Configuration> =
|
||||
{
|
||||
type: "object",
|
||||
label: "Server Configuration",
|
||||
|
|
|
@ -847,7 +847,7 @@ interface AddToInboxBulkEntry {
|
|||
|
||||
export async function addToInboxBulk(
|
||||
entries: AddToInboxBulkEntry[],
|
||||
inboxConfig: MonkeyTypes.Configuration["users"]["inbox"]
|
||||
inboxConfig: SharedTypes.Configuration["users"]["inbox"]
|
||||
): Promise<void> {
|
||||
const { enabled, maxMail } = inboxConfig;
|
||||
|
||||
|
@ -875,7 +875,7 @@ export async function addToInboxBulk(
|
|||
export async function addToInbox(
|
||||
uid: string,
|
||||
mail: MonkeyTypes.MonkeyMail[],
|
||||
inboxConfig: MonkeyTypes.Configuration["users"]["inbox"]
|
||||
inboxConfig: SharedTypes.Configuration["users"]["inbox"]
|
||||
): Promise<void> {
|
||||
const { enabled, maxMail } = inboxConfig;
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ import { BASE_CONFIGURATION } from "../constants/base-configuration";
|
|||
const CONFIG_UPDATE_INTERVAL = 10 * 60 * 1000; // 10 Minutes
|
||||
|
||||
function mergeConfigurations(
|
||||
baseConfiguration: MonkeyTypes.Configuration,
|
||||
liveConfiguration: Partial<MonkeyTypes.Configuration>
|
||||
baseConfiguration: SharedTypes.Configuration,
|
||||
liveConfiguration: Partial<SharedTypes.Configuration>
|
||||
): void {
|
||||
if (
|
||||
!_.isPlainObject(baseConfiguration) ||
|
||||
|
@ -45,7 +45,7 @@ let serverConfigurationUpdated = false;
|
|||
|
||||
export async function getCachedConfiguration(
|
||||
attemptCacheUpdate = false
|
||||
): Promise<MonkeyTypes.Configuration> {
|
||||
): Promise<SharedTypes.Configuration> {
|
||||
if (
|
||||
attemptCacheUpdate &&
|
||||
lastFetchTime < Date.now() - CONFIG_UPDATE_INTERVAL
|
||||
|
@ -57,7 +57,7 @@ export async function getCachedConfiguration(
|
|||
return configuration;
|
||||
}
|
||||
|
||||
export async function getLiveConfiguration(): Promise<MonkeyTypes.Configuration> {
|
||||
export async function getLiveConfiguration(): Promise<SharedTypes.Configuration> {
|
||||
lastFetchTime = Date.now();
|
||||
|
||||
const configurationCollection = db.collection("configuration");
|
||||
|
@ -71,7 +71,7 @@ export async function getLiveConfiguration(): Promise<MonkeyTypes.Configuration>
|
|||
const liveConfigurationWithoutId = _.omit(
|
||||
liveConfiguration,
|
||||
"_id"
|
||||
) as MonkeyTypes.Configuration;
|
||||
) as SharedTypes.Configuration;
|
||||
mergeConfigurations(baseConfiguration, liveConfigurationWithoutId);
|
||||
|
||||
pushConfiguration(baseConfiguration);
|
||||
|
@ -93,7 +93,7 @@ export async function getLiveConfiguration(): Promise<MonkeyTypes.Configuration>
|
|||
}
|
||||
|
||||
async function pushConfiguration(
|
||||
configuration: MonkeyTypes.Configuration
|
||||
configuration: SharedTypes.Configuration
|
||||
): Promise<void> {
|
||||
if (serverConfigurationUpdated) {
|
||||
return;
|
||||
|
@ -111,7 +111,7 @@ async function pushConfiguration(
|
|||
}
|
||||
|
||||
export async function patchConfiguration(
|
||||
configurationUpdates: Partial<MonkeyTypes.Configuration>
|
||||
configurationUpdates: Partial<SharedTypes.Configuration>
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const currentConfiguration = _.cloneDeep(configuration);
|
||||
|
|
|
@ -23,7 +23,7 @@ const emptyMiddleware = (
|
|||
* the criteria.
|
||||
*/
|
||||
function validateConfiguration(
|
||||
options: ValidationOptions<MonkeyTypes.Configuration>
|
||||
options: ValidationOptions<SharedTypes.Configuration>
|
||||
): RequestHandler {
|
||||
const {
|
||||
criteria,
|
||||
|
|
|
@ -105,7 +105,7 @@ function authenticateRequest(authOptions = DEFAULT_OPTIONS): Handler {
|
|||
|
||||
async function authenticateWithAuthHeader(
|
||||
authHeader: string,
|
||||
configuration: MonkeyTypes.Configuration,
|
||||
configuration: SharedTypes.Configuration,
|
||||
options: RequestAuthenticationOptions
|
||||
): Promise<MonkeyTypes.DecodedToken> {
|
||||
if (authHeader === undefined || authHeader === "") {
|
||||
|
@ -215,7 +215,7 @@ async function authenticateWithBearerToken(
|
|||
|
||||
async function authenticateWithApeKey(
|
||||
key: string,
|
||||
configuration: MonkeyTypes.Configuration,
|
||||
configuration: SharedTypes.Configuration,
|
||||
options: RequestAuthenticationOptions
|
||||
): Promise<MonkeyTypes.DecodedToken> {
|
||||
if (!configuration.apeKeys.acceptKeys) {
|
||||
|
|
|
@ -17,7 +17,7 @@ export interface LaterTask<T extends LaterTaskType> {
|
|||
export type LaterTaskContexts = {
|
||||
"daily-leaderboard-results": {
|
||||
yesterdayTimestamp: number;
|
||||
modeRule: MonkeyTypes.ValidModeRule;
|
||||
modeRule: SharedTypes.ValidModeRule;
|
||||
};
|
||||
"weekly-xp-leaderboard-results": {
|
||||
lastWeekTimestamp: number;
|
||||
|
@ -82,7 +82,7 @@ class LaterQueue extends MonkeyQueue<LaterTask<LaterTaskType>> {
|
|||
async scheduleForTomorrow(
|
||||
taskName: LaterTaskType,
|
||||
taskId: string,
|
||||
modeRule: MonkeyTypes.ValidModeRule
|
||||
modeRule: SharedTypes.ValidModeRule
|
||||
): Promise<void> {
|
||||
const currentDayTimestamp = getCurrentDayTimestamp();
|
||||
const jobId = `${taskName}:${currentDayTimestamp}:${taskId}`;
|
||||
|
|
|
@ -59,7 +59,7 @@ export class WeeklyXpLeaderboard {
|
|||
}
|
||||
|
||||
public async addResult(
|
||||
weeklyXpLeaderboardConfig: MonkeyTypes.Configuration["leaderboards"]["weeklyXp"],
|
||||
weeklyXpLeaderboardConfig: SharedTypes.Configuration["leaderboards"]["weeklyXp"],
|
||||
opts: AddResultOpts
|
||||
): Promise<number> {
|
||||
const { entry, xpGained, timeTypedSeconds } = opts;
|
||||
|
@ -116,7 +116,7 @@ export class WeeklyXpLeaderboard {
|
|||
public async getResults(
|
||||
minRank: number,
|
||||
maxRank: number,
|
||||
weeklyXpLeaderboardConfig: MonkeyTypes.Configuration["leaderboards"]["weeklyXp"]
|
||||
weeklyXpLeaderboardConfig: SharedTypes.Configuration["leaderboards"]["weeklyXp"]
|
||||
): Promise<WeeklyXpLeaderboardEntry[]> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !weeklyXpLeaderboardConfig.enabled) {
|
||||
|
@ -161,7 +161,7 @@ export class WeeklyXpLeaderboard {
|
|||
|
||||
public async getRank(
|
||||
uid: string,
|
||||
weeklyXpLeaderboardConfig: MonkeyTypes.Configuration["leaderboards"]["weeklyXp"]
|
||||
weeklyXpLeaderboardConfig: SharedTypes.Configuration["leaderboards"]["weeklyXp"]
|
||||
): Promise<WeeklyXpLeaderboardEntry | null> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !weeklyXpLeaderboardConfig.enabled) {
|
||||
|
@ -196,7 +196,7 @@ export class WeeklyXpLeaderboard {
|
|||
}
|
||||
|
||||
export function get(
|
||||
weeklyXpLeaderboardConfig: MonkeyTypes.Configuration["leaderboards"]["weeklyXp"],
|
||||
weeklyXpLeaderboardConfig: SharedTypes.Configuration["leaderboards"]["weeklyXp"],
|
||||
customTimestamp?: number
|
||||
): WeeklyXpLeaderboard | null {
|
||||
const { enabled } = weeklyXpLeaderboardConfig;
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
// Shared types between server/client.
|
||||
export interface ValidModeRule {
|
||||
language: string;
|
||||
mode: string;
|
||||
mode2: string;
|
||||
}
|
||||
export interface RewardBracket {
|
||||
minRank: number;
|
||||
maxRank: number;
|
||||
minReward: number;
|
||||
maxReward: number;
|
||||
}
|
||||
|
||||
export interface Configuration {
|
||||
maintenance: boolean;
|
||||
quotes: {
|
||||
reporting: {
|
||||
enabled: boolean;
|
||||
maxReports: number;
|
||||
contentReportLimit: number;
|
||||
};
|
||||
submissionsEnabled: boolean;
|
||||
maxFavorites: number;
|
||||
};
|
||||
results: {
|
||||
savingEnabled: boolean;
|
||||
objectHashCheckEnabled: boolean;
|
||||
filterPresets: {
|
||||
enabled: boolean;
|
||||
maxPresetsPerUser: number;
|
||||
};
|
||||
limits: {
|
||||
regularUser: number;
|
||||
premiumUser: number;
|
||||
};
|
||||
maxBatchSize: number;
|
||||
};
|
||||
users: {
|
||||
signUp: boolean;
|
||||
lastHashesCheck: {
|
||||
enabled: boolean;
|
||||
maxHashes: number;
|
||||
};
|
||||
autoBan: {
|
||||
enabled: boolean;
|
||||
maxCount: number;
|
||||
maxHours: number;
|
||||
};
|
||||
profiles: {
|
||||
enabled: boolean;
|
||||
};
|
||||
discordIntegration: {
|
||||
enabled: boolean;
|
||||
};
|
||||
xp: {
|
||||
enabled: boolean;
|
||||
funboxBonus: number;
|
||||
gainMultiplier: number;
|
||||
maxDailyBonus: number;
|
||||
minDailyBonus: number;
|
||||
streak: {
|
||||
enabled: boolean;
|
||||
maxStreakDays: number;
|
||||
maxStreakMultiplier: number;
|
||||
};
|
||||
};
|
||||
inbox: {
|
||||
enabled: boolean;
|
||||
maxMail: number;
|
||||
};
|
||||
premium: {
|
||||
enabled: boolean;
|
||||
};
|
||||
};
|
||||
admin: {
|
||||
endpointsEnabled: boolean;
|
||||
};
|
||||
apeKeys: {
|
||||
endpointsEnabled: boolean;
|
||||
acceptKeys: boolean;
|
||||
maxKeysPerUser: number;
|
||||
apeKeyBytes: number;
|
||||
apeKeySaltRounds: number;
|
||||
};
|
||||
rateLimiting: {
|
||||
badAuthentication: {
|
||||
enabled: boolean;
|
||||
penalty: number;
|
||||
flaggedStatusCodes: number[];
|
||||
};
|
||||
};
|
||||
dailyLeaderboards: {
|
||||
enabled: boolean;
|
||||
leaderboardExpirationTimeInDays: number;
|
||||
maxResults: number;
|
||||
validModeRules: ValidModeRule[];
|
||||
scheduleRewardsModeRules: ValidModeRule[];
|
||||
topResultsToAnnounce: number;
|
||||
xpRewardBrackets: RewardBracket[];
|
||||
};
|
||||
leaderboards: {
|
||||
weeklyXp: {
|
||||
enabled: boolean;
|
||||
expirationTimeInDays: number;
|
||||
xpRewardBrackets: RewardBracket[];
|
||||
};
|
||||
};
|
||||
}
|
7
backend/src/types/types.d.ts
vendored
7
backend/src/types/types.d.ts
vendored
|
@ -1,13 +1,8 @@
|
|||
type Configuration = import("../types/shared").Configuration;
|
||||
|
||||
type ObjectId = import("mongodb").ObjectId;
|
||||
|
||||
type ExpressRequest = import("express").Request;
|
||||
|
||||
declare namespace MonkeyTypes {
|
||||
type Configuration = import("./shared").Configuration;
|
||||
type ValidModeRule = import("./shared").ValidModeRule;
|
||||
type RewardBracket = import("./shared").RewardBracket;
|
||||
interface DecodedToken {
|
||||
type: "Bearer" | "ApeKey" | "None";
|
||||
uid: string;
|
||||
|
@ -15,7 +10,7 @@ declare namespace MonkeyTypes {
|
|||
}
|
||||
|
||||
interface Context {
|
||||
configuration: Configuration;
|
||||
configuration: SharedTypes.Configuration;
|
||||
decodedToken: DecodedToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ export class DailyLeaderboard {
|
|||
private leaderboardScoresKeyName: string;
|
||||
private leaderboardModeKey: string;
|
||||
private customTime: number;
|
||||
private modeRule: MonkeyTypes.ValidModeRule;
|
||||
private modeRule: SharedTypes.ValidModeRule;
|
||||
|
||||
constructor(modeRule: MonkeyTypes.ValidModeRule, customTime = -1) {
|
||||
constructor(modeRule: SharedTypes.ValidModeRule, customTime = -1) {
|
||||
const { language, mode, mode2 } = modeRule;
|
||||
|
||||
this.leaderboardModeKey = `${language}:${mode}:${mode2}`;
|
||||
|
@ -67,7 +67,7 @@ export class DailyLeaderboard {
|
|||
|
||||
public async addResult(
|
||||
entry: DailyLeaderboardEntry,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
dailyLeaderboardsConfig: SharedTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<number> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !dailyLeaderboardsConfig.enabled) {
|
||||
|
@ -123,7 +123,7 @@ export class DailyLeaderboard {
|
|||
public async getResults(
|
||||
minRank: number,
|
||||
maxRank: number,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
dailyLeaderboardsConfig: SharedTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<LbEntryWithRank[]> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !dailyLeaderboardsConfig.enabled) {
|
||||
|
@ -161,7 +161,7 @@ export class DailyLeaderboard {
|
|||
|
||||
public async getRank(
|
||||
uid: string,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
dailyLeaderboardsConfig: SharedTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<GetRankResponse | null> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !dailyLeaderboardsConfig.enabled) {
|
||||
|
@ -204,7 +204,7 @@ export class DailyLeaderboard {
|
|||
|
||||
export async function purgeUserFromDailyLeaderboards(
|
||||
uid: string,
|
||||
configuration: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
configuration: SharedTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<void> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !configuration.enabled) {
|
||||
|
@ -216,8 +216,8 @@ export async function purgeUserFromDailyLeaderboards(
|
|||
}
|
||||
|
||||
function isValidModeRule(
|
||||
modeRule: MonkeyTypes.ValidModeRule,
|
||||
modeRules: MonkeyTypes.ValidModeRule[]
|
||||
modeRule: SharedTypes.ValidModeRule,
|
||||
modeRules: SharedTypes.ValidModeRule[]
|
||||
): boolean {
|
||||
const { language, mode, mode2 } = modeRule;
|
||||
|
||||
|
@ -233,7 +233,7 @@ export function getDailyLeaderboard(
|
|||
language: string,
|
||||
mode: string,
|
||||
mode2: string,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"],
|
||||
dailyLeaderboardsConfig: SharedTypes.Configuration["dailyLeaderboards"],
|
||||
customTimestamp = -1
|
||||
): DailyLeaderboard | null {
|
||||
const { validModeRules, enabled } = dailyLeaderboardsConfig;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"ts-node": {
|
||||
"files": true
|
||||
},
|
||||
"files": ["./src/types/types.d.ts"],
|
||||
"files": ["./src/types/types.d.ts", "../shared-types/types.d.ts"],
|
||||
"include": ["./src/**/*"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Ape from ".";
|
||||
|
||||
let config: MonkeyTypes.Configuration | undefined = undefined;
|
||||
let config: SharedTypes.Configuration | undefined = undefined;
|
||||
|
||||
export function get(): MonkeyTypes.Configuration | undefined {
|
||||
export function get(): SharedTypes.Configuration | undefined {
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,6 @@ export async function sync(): Promise<void> {
|
|||
console.error("Could not fetch configuration", response.message);
|
||||
return;
|
||||
} else {
|
||||
config = response.data as MonkeyTypes.Configuration;
|
||||
config = response.data as SharedTypes.Configuration;
|
||||
}
|
||||
}
|
||||
|
|
4
frontend/src/ts/types/types.d.ts
vendored
4
frontend/src/ts/types/types.d.ts
vendored
|
@ -1,8 +1,4 @@
|
|||
declare namespace MonkeyTypes {
|
||||
type Configuration = import("@backend/types/shared").Configuration;
|
||||
type ValidModeRule = import("@backend/types/shared").ValidModeRule;
|
||||
type RewardBracket = import("@backend/types/shared").RewardBracket;
|
||||
|
||||
type PageName =
|
||||
| "loading"
|
||||
| "test"
|
||||
|
|
|
@ -36,6 +36,6 @@
|
|||
}
|
||||
},
|
||||
"include": ["./src/**/*.ts"],
|
||||
"files": ["src/ts/modules.d.ts"],
|
||||
"files": ["src/ts/modules.d.ts", "../shared-types/types.d.ts"],
|
||||
"exclude": ["node_modules", "build", "setup-tests.ts", "**/*.spec.ts"]
|
||||
}
|
||||
|
|
110
shared-types/types.d.ts
vendored
Normal file
110
shared-types/types.d.ts
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Shared types between server/client.
|
||||
declare namespace SharedTypes {
|
||||
interface ValidModeRule {
|
||||
language: string;
|
||||
mode: string;
|
||||
mode2: string;
|
||||
}
|
||||
interface RewardBracket {
|
||||
minRank: number;
|
||||
maxRank: number;
|
||||
minReward: number;
|
||||
maxReward: number;
|
||||
}
|
||||
|
||||
interface Configuration {
|
||||
maintenance: boolean;
|
||||
quotes: {
|
||||
reporting: {
|
||||
enabled: boolean;
|
||||
maxReports: number;
|
||||
contentReportLimit: number;
|
||||
};
|
||||
submissionsEnabled: boolean;
|
||||
maxFavorites: number;
|
||||
};
|
||||
results: {
|
||||
savingEnabled: boolean;
|
||||
objectHashCheckEnabled: boolean;
|
||||
filterPresets: {
|
||||
enabled: boolean;
|
||||
maxPresetsPerUser: number;
|
||||
};
|
||||
limits: {
|
||||
regularUser: number;
|
||||
premiumUser: number;
|
||||
};
|
||||
maxBatchSize: number;
|
||||
};
|
||||
users: {
|
||||
signUp: boolean;
|
||||
lastHashesCheck: {
|
||||
enabled: boolean;
|
||||
maxHashes: number;
|
||||
};
|
||||
autoBan: {
|
||||
enabled: boolean;
|
||||
maxCount: number;
|
||||
maxHours: number;
|
||||
};
|
||||
profiles: {
|
||||
enabled: boolean;
|
||||
};
|
||||
discordIntegration: {
|
||||
enabled: boolean;
|
||||
};
|
||||
xp: {
|
||||
enabled: boolean;
|
||||
funboxBonus: number;
|
||||
gainMultiplier: number;
|
||||
maxDailyBonus: number;
|
||||
minDailyBonus: number;
|
||||
streak: {
|
||||
enabled: boolean;
|
||||
maxStreakDays: number;
|
||||
maxStreakMultiplier: number;
|
||||
};
|
||||
};
|
||||
inbox: {
|
||||
enabled: boolean;
|
||||
maxMail: number;
|
||||
};
|
||||
premium: {
|
||||
enabled: boolean;
|
||||
};
|
||||
};
|
||||
admin: {
|
||||
endpointsEnabled: boolean;
|
||||
};
|
||||
apeKeys: {
|
||||
endpointsEnabled: boolean;
|
||||
acceptKeys: boolean;
|
||||
maxKeysPerUser: number;
|
||||
apeKeyBytes: number;
|
||||
apeKeySaltRounds: number;
|
||||
};
|
||||
rateLimiting: {
|
||||
badAuthentication: {
|
||||
enabled: boolean;
|
||||
penalty: number;
|
||||
flaggedStatusCodes: number[];
|
||||
};
|
||||
};
|
||||
dailyLeaderboards: {
|
||||
enabled: boolean;
|
||||
leaderboardExpirationTimeInDays: number;
|
||||
maxResults: number;
|
||||
validModeRules: ValidModeRule[];
|
||||
scheduleRewardsModeRules: ValidModeRule[];
|
||||
topResultsToAnnounce: number;
|
||||
xpRewardBrackets: RewardBracket[];
|
||||
};
|
||||
leaderboards: {
|
||||
weeklyXp: {
|
||||
enabled: boolean;
|
||||
expirationTimeInDays: number;
|
||||
xpRewardBrackets: RewardBracket[];
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue