refactor: shared types (miodec) (#4978)

* rework shared types

* revert one small change
This commit is contained in:
Jack 2024-01-29 15:53:42 +01:00 committed by GitHub
parent ee629db5b5
commit 0751375ab6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 146 additions and 153 deletions

View file

@ -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

View file

@ -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",

View file

@ -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;

View file

@ -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);

View file

@ -23,7 +23,7 @@ const emptyMiddleware = (
* the criteria.
*/
function validateConfiguration(
options: ValidationOptions<MonkeyTypes.Configuration>
options: ValidationOptions<SharedTypes.Configuration>
): RequestHandler {
const {
criteria,

View file

@ -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) {

View file

@ -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}`;

View file

@ -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;

View file

@ -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[];
};
};
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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",

View file

@ -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;
}
}

View file

@ -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"

View file

@ -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
View 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[];
};
};
}
}