mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
workspace: update eslint rule (#1027)
This commit is contained in:
1 parent
05c3b8f2bd
commit
cee3c00ddb
150 files changed
+1069
-1043
No files matched your search
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable ts/no-unsafe-declaration-merging */
|
||||
import LoggerService from '@cordisjs/plugin-logger';
|
||||
import { TimerService } from '@cordisjs/plugin-timer';
|
||||
import * as cordis from 'cordis';
|
||||
@@ -25,7 +26,7 @@ function provideModule<T extends keyof ModuleInterfaces>(type: T, id: string, mo
|
||||
|
||||
export type Fiber = cordis.Fiber<Context>;
|
||||
|
||||
export { Disposable, Plugin, FiberState } from 'cordis';
|
||||
export { Disposable, FiberState, Plugin } from 'cordis';
|
||||
|
||||
export interface Context extends cordis.Context {
|
||||
[Context.events]: EventMap & cordis.Events<Context>;
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
|
||||
const argv = cac().parse();
|
||||
const tmpdir = path.resolve(os.tmpdir(), 'hydro');
|
||||
const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
||||
const ARR = /=>.*$/mg;
|
||||
const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
|
||||
const ARR = /=>.*$/gm;
|
||||
function parseParameters(fn: Function) {
|
||||
const code = fn.toString()
|
||||
.replace(COMMENTS, '')
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/no-dynamic-require */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import '../lib/index';
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export class ContestListHandler extends Handler {
|
||||
if (group && !groups.includes(group)) throw new NotAssignedError(group);
|
||||
const rules = Object.keys(contest.RULES).filter((i) => !contest.RULES[i].hidden);
|
||||
const escaped = escapeRegExp(q.toLowerCase());
|
||||
const $regex = new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gmi');
|
||||
const $regex = new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gim');
|
||||
const filter = {
|
||||
...(this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_CONTEST) && !group)
|
||||
? {}
|
||||
@@ -626,10 +626,10 @@ export class ContestBalloonHandler extends ContestManagementBaseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
type BuiltinInput = {
|
||||
interface BuiltinInput {
|
||||
tdoc: Tdoc;
|
||||
groups: any[];
|
||||
};
|
||||
}
|
||||
type AnyFunction = (...args: any) => any;
|
||||
type ParseArgs<T extends { [key: string]: keyof BuiltinInput | AnyFunction | Type<any> }> = {
|
||||
[key in keyof T]: T[key] extends keyof BuiltinInput ? BuiltinInput[T[key]] : T[key] extends AnyFunction ? ReturnType<T[key]> : any
|
||||
@@ -696,9 +696,9 @@ class ScoreboardService extends Service {
|
||||
addView<T extends { [key: string]: keyof BuiltinInput | AnyFunction | Type<any> }>(
|
||||
id: string, name: string, args: T,
|
||||
{ display, supportedRules, cacheTime }: {
|
||||
display: (this: ContestScoreboardHandler, args: ParseArgs<T>) => Promise<void>,
|
||||
supportedRules: string[],
|
||||
cacheTime?: number,
|
||||
display: (this: ContestScoreboardHandler, args: ParseArgs<T>) => Promise<void>;
|
||||
supportedRules: string[];
|
||||
cacheTime?: number;
|
||||
},
|
||||
) {
|
||||
if (this.views[id]) throw new Error(`View ${id} already exists`);
|
||||
@@ -766,7 +766,7 @@ export async function apply(ctx: Context) {
|
||||
config.lockAt = this.tdoc.lockAt;
|
||||
}
|
||||
const [, rows, udict, pdict] = await contest.getScoreboard.call(this, tdoc.domainId, tdoc._id, config);
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
// eslint-disable-next-line ts/naming-convention
|
||||
const page_name = tdoc.rule === 'homework'
|
||||
? 'homework_scoreboard'
|
||||
: 'contest_scoreboard';
|
||||
|
||||
@@ -95,7 +95,7 @@ class DiscussionNodeHandler extends DiscussionHandler {
|
||||
async get(domainId: string, type: string, _name: string, page = 1) {
|
||||
let name: ObjectId | string | number;
|
||||
if (ObjectId.isValid(_name)) name = new ObjectId(_name);
|
||||
else if (isSafeInteger(parseInt(_name, 10))) name = parseInt(_name, 10);
|
||||
else if (isSafeInteger(Number.parseInt(_name, 10))) name = Number.parseInt(_name, 10);
|
||||
else name = _name;
|
||||
const hidden = this.user.own(this.vnode) || this.user.hasPerm(PERM.PERM_EDIT_DISCUSSION) ? {} : { hidden: false };
|
||||
const [ddocs, dpcount] = await this.paginate(
|
||||
|
||||
@@ -534,7 +534,7 @@ class HomeDomainCreateHandler extends Handler {
|
||||
@param('name', Types.Title)
|
||||
@param('bulletin', Types.Content)
|
||||
@param('avatar', Types.Content, true)
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
// eslint-disable-next-line ts/no-shadow
|
||||
async post(_: string, id: string, name: string, bulletin: string, avatar: string) {
|
||||
const doc = await domain.get(id);
|
||||
if (doc) throw new DomainAlreadyExistsError(id);
|
||||
|
||||
@@ -52,7 +52,7 @@ class HomeworkMainHandler extends Handler {
|
||||
],
|
||||
},
|
||||
...group ? { assign: { $in: [group] } } : {},
|
||||
...q ? { title: { $regex: new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gmi') } } : {},
|
||||
...q ? { title: { $regex: new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gim') } } : {},
|
||||
}).sort({
|
||||
penaltySince: -1, endAt: -1, beginAt: -1, _id: -1,
|
||||
});
|
||||
|
||||
@@ -79,7 +79,7 @@ export class JudgeResultCallbackContext {
|
||||
private relatedId = new ObjectId();
|
||||
private meta: { rejudge?: JudgeMeta['rejudge'] };
|
||||
|
||||
constructor(public ctx: Context, public readonly task: Omit<Task, '_id'> & { type: string }) { // eslint-disable-line @typescript-eslint/no-shadow
|
||||
constructor(public ctx: Context, public readonly task: Omit<Task, '_id'> & { type: string }) { // eslint-disable-line ts/no-shadow
|
||||
this.meta = task.meta as JudgeMeta || {};
|
||||
this.finishPromise = new Promise((resolve) => {
|
||||
this.resolve = resolve;
|
||||
|
||||
@@ -239,7 +239,7 @@ class SystemUserImportHandler extends SystemHandler {
|
||||
@param('draft', Types.Boolean)
|
||||
async post(domainId: string, _users: string, draft: boolean) {
|
||||
const users = _users.split('\n');
|
||||
const udocs: { email: string, username: string, password: string, displayName?: string, [key: string]: any; }[] = [];
|
||||
const udocs: { email: string, username: string, password: string, displayName?: string, [key: string]: any }[] = [];
|
||||
const messages = [];
|
||||
const mapping = Object.create(null);
|
||||
const groups: Record<string, string[]> = Object.create(null);
|
||||
|
||||
@@ -56,7 +56,7 @@ function buildQuery(udoc: User) {
|
||||
const defaultSearch = async (domainId: string, q: string, options?: ProblemSearchOptions) => {
|
||||
const escaped = escapeRegExp(q.toLowerCase());
|
||||
const projection: (keyof ProblemDoc)[] = ['domainId', 'docId', 'pid'];
|
||||
const $regex = new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gmi');
|
||||
const $regex = new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gim');
|
||||
const filter = { $or: [{ pid: { $regex } }, { title: { $regex } }, { tag: q }] };
|
||||
const pdocs = await problem.getMulti(domainId, filter, projection)
|
||||
.skip(options.skip || 0).limit(options.limit || system.get('pagination.problem')).toArray();
|
||||
@@ -109,7 +109,7 @@ export class ProblemMainHandler extends Handler {
|
||||
this.response.template = 'problem_main.html';
|
||||
if (!limit || limit > this.ctx.setting.get('pagination.problem') || page > 1) limit = this.ctx.setting.get('pagination.problem');
|
||||
this.queryContext.query = buildQuery(this.user);
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
// eslint-disable-next-line ts/no-shadow
|
||||
const query = this.queryContext.query;
|
||||
const psdict = {};
|
||||
const search = Object.values(global.Hydro.module.problemSearch)[0] || defaultSearch;
|
||||
@@ -607,7 +607,7 @@ export class ProblemEditHandler extends ProblemManageHandler {
|
||||
@route('pid', Types.ProblemId)
|
||||
@post('title', Types.Title)
|
||||
@post('content', Types.Content)
|
||||
@post('pid', Types.ProblemId, true, (i) => /^([a-zA-Z0-9]{1,10}-)?[a-zA-Z]+[a-zA-Z0-9]*$/i.test(i))
|
||||
@post('pid', Types.ProblemId, true, (i) => /^(?:[a-z0-9]{1,10}-)?[a-z][a-z0-9]*$/i.test(i))
|
||||
@post('hidden', Types.Boolean)
|
||||
@post('tag', Types.Content, true, null, parseCategory)
|
||||
@post('difficulty', Types.PositiveInt, (i) => +i <= 10, true)
|
||||
@@ -837,7 +837,7 @@ export class ProblemSolutionHandler extends ProblemDetailHandler {
|
||||
if (!accepted || !this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_SOLUTION_ACCEPT)) {
|
||||
this.checkPerm(PERM.PERM_VIEW_PROBLEM_SOLUTION);
|
||||
}
|
||||
// eslint-disable-next-line prefer-const
|
||||
|
||||
let [psdocs, pcount, pscount] = await this.paginate(
|
||||
solution.getMulti(domainId, this.pdoc.docId),
|
||||
page,
|
||||
@@ -995,7 +995,7 @@ export class ProblemCreateHandler extends Handler {
|
||||
|
||||
@post('title', Types.Title)
|
||||
@post('content', Types.Content)
|
||||
@post('pid', Types.ProblemId, true, (i) => /^([a-zA-Z0-9]{1,10}-)?[a-zA-Z]+[a-zA-Z0-9]*$/i.test(i))
|
||||
@post('pid', Types.ProblemId, true, (i) => /^(?:[a-z0-9]{1,10}-)?[a-z][a-z0-9]*$/i.test(i))
|
||||
@post('hidden', Types.Boolean)
|
||||
@post('difficulty', Types.PositiveInt, (i) => +i <= 10, true)
|
||||
@post('tag', Types.Content, true, null, parseCategory)
|
||||
@@ -1006,7 +1006,7 @@ export class ProblemCreateHandler extends Handler {
|
||||
if (typeof pid !== 'string') pid = `P${pid}`;
|
||||
if (pid && await problem.get(domainId, pid)) throw new ProblemAlreadyExistError(pid);
|
||||
const docId = await problem.add(domainId, pid, title, content, this.user._id, tag ?? [], { hidden, difficulty });
|
||||
const files = new Set(Array.from(content.matchAll(/file:\/\/([a-zA-Z0-9_-]+\.[a-zA-Z0-9]+)/g)).map((i) => i[1]));
|
||||
const files = new Set(Array.from(content.matchAll(/file:\/\/([\w-]+\.[a-zA-Z0-9]+)/g)).map((i) => i[1]));
|
||||
const tasks = [];
|
||||
for (const file of files) {
|
||||
if (this.user._files.find((i) => i.name === file)) {
|
||||
|
||||
@@ -70,7 +70,7 @@ class RecordListHandler extends ContestDetailBaseHandler {
|
||||
}
|
||||
if (pid) {
|
||||
if (typeof pid === 'string' && tdoc && /^[A-Z]$/.test(pid)) {
|
||||
pid = tdoc.pids[parseInt(pid, 36) - 10];
|
||||
pid = tdoc.pids[Number.parseInt(pid, 36) - 10];
|
||||
}
|
||||
const pdoc = await problem.get(domainId, pid);
|
||||
if (pdoc) q.pid = pdoc.docId;
|
||||
@@ -341,7 +341,6 @@ class RecordMainConnectionHandler extends ConnectionHandler {
|
||||
if (typeof this.pid === 'number' && rdoc.pid !== this.pid) return;
|
||||
if (typeof this.uid === 'number' && rdoc.uid !== this.uid) return;
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [udoc, pdoc] = await Promise.all([
|
||||
user.getById(this.args.domainId, rdoc.uid),
|
||||
problem.get(rdoc.domainId, rdoc.pid),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const versionNum = +process.version.replace(/v/gim, '').split('.')[0];
|
||||
const versionNum = +process.version.replace(/v/gi, '').split('.')[0];
|
||||
if (versionNum < 22) throw new Error('NodeJS >=22 required');
|
||||
|
||||
console.log('Process', process.pid, 'running as', process.env.NODE_APP_INSTANCE === '0' ? 'master' : 'worker');
|
||||
|
||||
+114
-113
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable perfectionist/sort-exports */
|
||||
import type { AttestationFormat, CredentialDeviceType } from '@simplewebauthn/server';
|
||||
import type { ParsedAuthenticatorData } from '@simplewebauthn/server/helpers';
|
||||
import type fs from 'fs';
|
||||
@@ -16,43 +17,43 @@ export * from '@hydrooj/common/types';
|
||||
type document = typeof import('./model/document');
|
||||
|
||||
export interface System {
|
||||
_id: string,
|
||||
value: any,
|
||||
_id: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface SystemKeys {
|
||||
'smtp.user': string,
|
||||
'smtp.from': string,
|
||||
'smtp.pass': string,
|
||||
'smtp.host': string,
|
||||
'smtp.port': number,
|
||||
'smtp.secure': boolean,
|
||||
'installid': string,
|
||||
'server.name': string,
|
||||
'server.url': string,
|
||||
'server.xff': string,
|
||||
'server.xhost': string,
|
||||
'server.host': string,
|
||||
'server.port': number,
|
||||
'server.language': string,
|
||||
'limit.problem_files_max': number,
|
||||
'problem.categories': string,
|
||||
'session.keys': string[],
|
||||
'session.saved_expire_seconds': number,
|
||||
'session.unsaved_expire_seconds': number,
|
||||
'user.quota': number,
|
||||
'smtp.user': string;
|
||||
'smtp.from': string;
|
||||
'smtp.pass': string;
|
||||
'smtp.host': string;
|
||||
'smtp.port': number;
|
||||
'smtp.secure': boolean;
|
||||
installid: string;
|
||||
'server.name': string;
|
||||
'server.url': string;
|
||||
'server.xff': string;
|
||||
'server.xhost': string;
|
||||
'server.host': string;
|
||||
'server.port': number;
|
||||
'server.language': string;
|
||||
'limit.problem_files_max': number;
|
||||
'problem.categories': string;
|
||||
'session.keys': string[];
|
||||
'session.saved_expire_seconds': number;
|
||||
'session.unsaved_expire_seconds': number;
|
||||
'user.quota': number;
|
||||
}
|
||||
|
||||
export interface Setting {
|
||||
family: string,
|
||||
key: string,
|
||||
range: [string, string][] | Record<string, string>,
|
||||
value: any,
|
||||
type: string,
|
||||
subType?: string,
|
||||
name: string,
|
||||
desc: string,
|
||||
flag: number,
|
||||
family: string;
|
||||
key: string;
|
||||
range: [string, string][] | Record<string, string>;
|
||||
value: any;
|
||||
type: string;
|
||||
subType?: string;
|
||||
name: string;
|
||||
desc: string;
|
||||
flag: number;
|
||||
}
|
||||
|
||||
export interface Authenticator {
|
||||
@@ -119,7 +120,7 @@ export interface UserPreferenceDoc {
|
||||
content: string;
|
||||
}
|
||||
|
||||
export type ownerInfo = { owner: number, maintainer?: number[] };
|
||||
export interface OwnerInfo { owner: number, maintainer?: number[] }
|
||||
|
||||
export type User = import('./model/user').User;
|
||||
export type Udict = Record<number, User>;
|
||||
@@ -190,11 +191,11 @@ export type { ProblemDoc } from './model/problem';
|
||||
export type ProblemDict = NumericDictionary<ProblemDoc>;
|
||||
|
||||
export interface StatusDocBase {
|
||||
_id: ObjectId,
|
||||
docId: any,
|
||||
docType: number,
|
||||
domainId: string,
|
||||
uid: number,
|
||||
_id: ObjectId;
|
||||
docId: any;
|
||||
docType: number;
|
||||
domainId: string;
|
||||
uid: number;
|
||||
}
|
||||
|
||||
export interface ProblemStatusDoc extends StatusDocBase {
|
||||
@@ -241,10 +242,10 @@ export type ScoreboardRow = ScoreboardNode[] & { raw?: any };
|
||||
export type PenaltyRules = Dictionary<number>;
|
||||
|
||||
export interface TrainingNode {
|
||||
_id: number,
|
||||
title: string,
|
||||
requireNids: number[],
|
||||
pids: number[],
|
||||
_id: number;
|
||||
title: string;
|
||||
requireNids: number[];
|
||||
pids: number[];
|
||||
}
|
||||
|
||||
export interface Tdoc extends Document {
|
||||
@@ -287,28 +288,28 @@ export interface Tdoc extends Document {
|
||||
}
|
||||
|
||||
export interface TrainingDoc extends Omit<Tdoc, 'docType'> {
|
||||
docType: document['TYPE_TRAINING'],
|
||||
docType: document['TYPE_TRAINING'];
|
||||
description: string;
|
||||
pin?: number;
|
||||
dag: TrainingNode[];
|
||||
}
|
||||
|
||||
export interface DomainDoc extends Record<string, any> {
|
||||
_id: string,
|
||||
owner: number,
|
||||
roles: Dictionary<string>,
|
||||
avatar: string,
|
||||
bulletin: string,
|
||||
_join?: any,
|
||||
host?: string[],
|
||||
_id: string;
|
||||
owner: number;
|
||||
roles: Dictionary<string>;
|
||||
avatar: string;
|
||||
bulletin: string;
|
||||
_join?: any;
|
||||
host?: string[];
|
||||
}
|
||||
|
||||
// Message
|
||||
export interface MessageDoc {
|
||||
from: number,
|
||||
to: number,
|
||||
content: string,
|
||||
flag: number,
|
||||
from: number;
|
||||
to: number;
|
||||
content: string;
|
||||
flag: number;
|
||||
}
|
||||
|
||||
// Blacklist
|
||||
@@ -382,22 +383,22 @@ export interface ContestClarificationDoc extends Document {
|
||||
}
|
||||
|
||||
export interface TokenDoc {
|
||||
_id: string,
|
||||
tokenType: number,
|
||||
createAt: Date,
|
||||
updateAt: Date,
|
||||
expireAt: Date,
|
||||
[key: string]: any,
|
||||
_id: string;
|
||||
tokenType: number;
|
||||
createAt: Date;
|
||||
updateAt: Date;
|
||||
expireAt: Date;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface OplogDoc extends Record<string, any> {
|
||||
_id: ObjectId,
|
||||
type: string,
|
||||
_id: ObjectId;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface ContestStat extends Record<string, any> {
|
||||
detail: Record<number, Record<string, any>>,
|
||||
unrank?: boolean,
|
||||
detail: Record<number, Record<string, any>>;
|
||||
unrank?: boolean;
|
||||
}
|
||||
|
||||
export interface ScoreboardConfig {
|
||||
@@ -438,9 +439,9 @@ export type ContestRules = Dictionary<ContestRule>;
|
||||
export type ProblemImporter = (url: string, handler: any) => Promise<[ProblemDoc, fs.ReadStream?]> | [ProblemDoc, fs.ReadStream?];
|
||||
|
||||
export interface Script {
|
||||
run: (args: any, report: Function) => any,
|
||||
description: string,
|
||||
validate: any,
|
||||
run: (args: any, report: Function) => any;
|
||||
description: string;
|
||||
validate: any;
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
@@ -528,66 +529,66 @@ export interface LockDoc {
|
||||
|
||||
declare module './service/db' {
|
||||
interface Collections {
|
||||
'blacklist': BlacklistDoc;
|
||||
'domain': DomainDoc;
|
||||
blacklist: BlacklistDoc;
|
||||
domain: DomainDoc;
|
||||
'domain.user': any;
|
||||
'record': RecordDoc;
|
||||
record: RecordDoc;
|
||||
'record.stat': RecordStatDoc;
|
||||
'record.history': RecordHistoryDoc;
|
||||
'document': any;
|
||||
document: any;
|
||||
'document.status': StatusDocBase & {
|
||||
[K in keyof DocStatusType]: { docType: K } & DocStatusType[K];
|
||||
}[keyof DocStatusType];
|
||||
'discussion.history': DiscussionHistoryDoc;
|
||||
'user': Udoc;
|
||||
user: Udoc;
|
||||
'user.preference': UserPreferenceDoc;
|
||||
'vuser': VUdoc;
|
||||
vuser: VUdoc;
|
||||
'user.group': GDoc;
|
||||
'check': System;
|
||||
'message': MessageDoc;
|
||||
'token': TokenDoc;
|
||||
'status': any;
|
||||
'oauth': OauthMap;
|
||||
'system': System;
|
||||
'task': Task;
|
||||
'storage': FileNode;
|
||||
'oplog': OplogDoc;
|
||||
'event': EventDoc;
|
||||
'opcount': OpCountDoc;
|
||||
'schedule': Schedule;
|
||||
check: System;
|
||||
message: MessageDoc;
|
||||
token: TokenDoc;
|
||||
status: any;
|
||||
oauth: OauthMap;
|
||||
system: System;
|
||||
task: Task;
|
||||
storage: FileNode;
|
||||
oplog: OplogDoc;
|
||||
event: EventDoc;
|
||||
opcount: OpCountDoc;
|
||||
schedule: Schedule;
|
||||
'contest.balloon': ContestBalloonDoc;
|
||||
'lock': LockDoc;
|
||||
lock: LockDoc;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Model {
|
||||
blacklist: typeof import('./model/blacklist').default,
|
||||
builtin: typeof import('./model/builtin'),
|
||||
contest: typeof import('./model/contest'),
|
||||
discussion: typeof import('./model/discussion'),
|
||||
document: Omit<typeof import('./model/document'), 'apply'>,
|
||||
domain: typeof import('./model/domain').default,
|
||||
message: typeof import('./model/message').default,
|
||||
opcount: typeof import('./model/opcount'),
|
||||
problem: typeof import('./model/problem').default,
|
||||
record: typeof import('./model/record').default,
|
||||
setting: typeof import('./model/setting'),
|
||||
solution: typeof import('./model/solution').default,
|
||||
system: typeof import('./model/system'),
|
||||
task: typeof import('./model/task').default,
|
||||
blacklist: typeof import('./model/blacklist').default;
|
||||
builtin: typeof import('./model/builtin');
|
||||
contest: typeof import('./model/contest');
|
||||
discussion: typeof import('./model/discussion');
|
||||
document: Omit<typeof import('./model/document'), 'apply'>;
|
||||
domain: typeof import('./model/domain').default;
|
||||
message: typeof import('./model/message').default;
|
||||
opcount: typeof import('./model/opcount');
|
||||
problem: typeof import('./model/problem').default;
|
||||
record: typeof import('./model/record').default;
|
||||
setting: typeof import('./model/setting');
|
||||
solution: typeof import('./model/solution').default;
|
||||
system: typeof import('./model/system');
|
||||
task: typeof import('./model/task').default;
|
||||
schedule: typeof import('./model/schedule').default;
|
||||
oplog: typeof import('./model/oplog'),
|
||||
token: typeof import('./model/token').default,
|
||||
training: typeof import('./model/training'),
|
||||
user: typeof import('./model/user').default,
|
||||
oauth: typeof import('./model/oauth').default,
|
||||
storage: typeof import('./model/storage').default,
|
||||
rp: typeof import('./script/rating').RpTypes,
|
||||
oplog: typeof import('./model/oplog');
|
||||
token: typeof import('./model/token').default;
|
||||
training: typeof import('./model/training');
|
||||
user: typeof import('./model/user').default;
|
||||
oauth: typeof import('./model/oauth').default;
|
||||
storage: typeof import('./model/storage').default;
|
||||
rp: typeof import('./script/rating').RpTypes;
|
||||
}
|
||||
|
||||
export interface GeoIP {
|
||||
provider: string,
|
||||
lookup: (ip: string, locale?: string) => any,
|
||||
provider: string;
|
||||
lookup: (ip: string, locale?: string) => any;
|
||||
}
|
||||
|
||||
export interface ProblemSearchResponse {
|
||||
@@ -604,9 +605,9 @@ export type ProblemSearch = (domainId: string, q: string, options?: ProblemSearc
|
||||
|
||||
export type UIInjectableFields = 'ProblemAdd' | 'Notification' | 'Nav' | 'UserDropdown' | 'DomainManage' | 'ControlPanel';
|
||||
export interface UI {
|
||||
nodes: Record<UIInjectableFields, any[]>,
|
||||
getNodes: typeof import('./lib/ui').getNodes,
|
||||
inject: typeof import('./lib/ui').inject,
|
||||
nodes: Record<UIInjectableFields, any[]>;
|
||||
getNodes: typeof import('./lib/ui').getNodes;
|
||||
inject: typeof import('./lib/ui').inject;
|
||||
}
|
||||
|
||||
export interface ModuleInterfaces {
|
||||
@@ -629,8 +630,8 @@ export interface HydroGlobal {
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface Global {
|
||||
Hydro: HydroGlobal,
|
||||
addons: string[],
|
||||
Hydro: HydroGlobal;
|
||||
addons: string[];
|
||||
}
|
||||
}
|
||||
/** @deprecated */
|
||||
|
||||
@@ -6,7 +6,7 @@ type AvatarProvider = (src: string, size: number) => string;
|
||||
export const providers: Record<string, AvatarProvider> = {
|
||||
gravatar: (email, size) => `${global.Hydro.model.system.get('avatar.gravatar_url')}`
|
||||
+ `${md5((email || '').toString().trim().toLowerCase())}?d=mm&s=${size || 32}`,
|
||||
qq: (id) => `//q1.qlogo.cn/g?b=qq&nk=${(/(\d+)/g.exec(id) || ['', ''])[1]}&s=160`,
|
||||
qq: (id) => `//q1.qlogo.cn/g?b=qq&nk=${(/(\d+)/.exec(id) || ['', ''])[1]}&s=160`,
|
||||
github: (id, size) => `//github.com/${id}.png?size=${Math.min(size, 460)}`,
|
||||
url: (url) => url,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export interface ProblemSource {
|
||||
description?: string,
|
||||
input?: string,
|
||||
output?: string,
|
||||
samples?: [string, string][],
|
||||
samplesRaw?: string,
|
||||
hint?: string,
|
||||
source?: string,
|
||||
description?: string;
|
||||
input?: string;
|
||||
output?: string;
|
||||
samples?: [string, string][];
|
||||
samplesRaw?: string;
|
||||
hint?: string;
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export function buildContent(source: ProblemSource, type: 'markdown' | 'html' = 'markdown', translate?: (s: string) => string) {
|
||||
|
||||
@@ -91,14 +91,14 @@ class RatingCalculator {
|
||||
}
|
||||
|
||||
interface RatingInputUser {
|
||||
old: number,
|
||||
uid: number,
|
||||
rank: number,
|
||||
old: number;
|
||||
uid: number;
|
||||
rank: number;
|
||||
}
|
||||
|
||||
interface RatingOutputUser {
|
||||
new: number,
|
||||
uid: number,
|
||||
new: number;
|
||||
uid: number;
|
||||
}
|
||||
|
||||
function calculate(users: RatingInputUser[]): RatingOutputUser[] {
|
||||
|
||||
@@ -5,13 +5,13 @@ import { ObjectId as ObjectID } from 'mongodb';
|
||||
import Schema from 'schemastery';
|
||||
import superagent from 'superagent';
|
||||
import { Context } from './context';
|
||||
export { ObjectId, Filter } from 'mongodb';
|
||||
export { WebSocket, WebSocketServer } from '@hydrooj/framework';
|
||||
export * from './utils';
|
||||
export * from './interface';
|
||||
export * from './typeutils';
|
||||
export * from './utils';
|
||||
export { WebSocket, WebSocketServer } from '@hydrooj/framework';
|
||||
export { Filter, ObjectId } from 'mongodb';
|
||||
export {
|
||||
Schema, superagent, _, ObjectID, Zip,
|
||||
_, ObjectID, Schema, superagent, Zip,
|
||||
};
|
||||
/** @deprecated Use ZipReader/ZipWriter instead */
|
||||
export const AdmZip = _AdmZip;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/no-dynamic-require */
|
||||
/* eslint-disable consistent-return */
|
||||
/* eslint-disable simple-import-sort/imports */
|
||||
import './init';
|
||||
@@ -181,7 +180,7 @@ export async function load() {
|
||||
if (process.env.DEV) {
|
||||
const q = await simpleGit().listRemote(['--get-url']);
|
||||
if (!q.includes('hydro-dev/Hydro')) {
|
||||
console.warn('\x1b[93m');
|
||||
console.warn('\x1B[93m');
|
||||
console.warn('DISCLAIMER:');
|
||||
console.warn(' You are under development mode.');
|
||||
console.warn(' The Hydro project is licensed under AGPL3,');
|
||||
@@ -195,7 +194,7 @@ export async function load() {
|
||||
console.warn(' 这意味着除非你获得了原作者的其他授权,');
|
||||
console.warn(' 你需要同样以 AGPL3 协议开源所有的修改,');
|
||||
console.warn(' 并保留所有的版权声明。');
|
||||
console.warn('\x1b[39m');
|
||||
console.warn('\x1B[39m');
|
||||
console.log('');
|
||||
console.log('Hydro will start in 5s.');
|
||||
console.log('Hydro 将在五秒后继续启动。');
|
||||
|
||||
@@ -641,7 +641,7 @@ const homework = buildContestRule({
|
||||
);
|
||||
if (exceedSeconds < 0) return rate * jdoc.score;
|
||||
let coefficient = 1;
|
||||
const keys = Object.keys(tdoc.penaltyRules).map(parseFloat).sort((a, b) => a - b);
|
||||
const keys = Object.keys(tdoc.penaltyRules).map(Number.parseFloat).sort((a, b) => a - b);
|
||||
for (const i of keys) {
|
||||
if (i * 3600 <= exceedSeconds) coefficient = tdoc.penaltyRules[i];
|
||||
else break;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
import assert from 'assert';
|
||||
import {
|
||||
Filter, FindCursor, ObjectId, OnlyFieldsOfType, PushOperator, UpdateFilter,
|
||||
@@ -43,9 +42,9 @@ export interface DocType {
|
||||
}
|
||||
|
||||
export interface DocStatusType {
|
||||
[TYPE_PROBLEM]: ProblemStatusDoc,
|
||||
[TYPE_PROBLEM]: ProblemStatusDoc;
|
||||
// FIXME: this need to be typed
|
||||
[key: number]: any
|
||||
[key: number]: any;
|
||||
}
|
||||
|
||||
export async function add<T extends keyof DocType, K extends DocType[T]['docId']>(
|
||||
|
||||
@@ -15,8 +15,8 @@ const collUser = db.collection('domain.user');
|
||||
const cache = new LRUCache<string, DomainDoc>({ max: 1000, ttl: 300 * 1000 });
|
||||
|
||||
interface DomainUserArg {
|
||||
_id: number,
|
||||
priv: number,
|
||||
_id: number;
|
||||
priv: number;
|
||||
}
|
||||
|
||||
class DomainModel {
|
||||
@@ -282,7 +282,7 @@ class DomainModel {
|
||||
|
||||
@ArgMethod
|
||||
static async getPrefixSearch(prefix: string, limit: number = 50) {
|
||||
const $regex = new RegExp(escapeRegExp(prefix), 'mi');
|
||||
const $regex = new RegExp(escapeRegExp(prefix), 'im');
|
||||
const ddocs = await coll.find({
|
||||
$or: [{ _id: { $regex } }, { name: { $regex } }],
|
||||
}).limit(limit).toArray();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
import { pick, sum } from 'lodash';
|
||||
import moment from 'moment-timezone';
|
||||
import {
|
||||
@@ -133,11 +132,11 @@ export default class RecordModel {
|
||||
domainId: string, pid: number, uid: number,
|
||||
lang: string, code: string, addTask: boolean,
|
||||
args: {
|
||||
contest?: ObjectId,
|
||||
input?: string,
|
||||
files?: Record<string, string>,
|
||||
hackTarget?: ObjectId,
|
||||
type: 'judge' | 'rejudge' | 'pretest' | 'hack' | 'generate',
|
||||
contest?: ObjectId;
|
||||
input?: string;
|
||||
files?: Record<string, string>;
|
||||
hackTarget?: ObjectId;
|
||||
type: 'judge' | 'rejudge' | 'pretest' | 'hack' | 'generate';
|
||||
} = { type: 'judge' },
|
||||
) {
|
||||
const data: RecordDoc = {
|
||||
|
||||
@@ -69,7 +69,7 @@ export const Setting = (
|
||||
|
||||
declare global {
|
||||
namespace Schemastery {
|
||||
interface Meta<T> { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
interface Meta<T> { // eslint-disable-line ts/no-unused-vars
|
||||
family?: string;
|
||||
secret?: boolean;
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@ export async function get(domainId: string, tid: ObjectId) {
|
||||
if (!tdoc) throw new TrainingNotFoundError(domainId, tid);
|
||||
for (const i in tdoc.dag) {
|
||||
for (const j in tdoc.dag[i].pids) {
|
||||
if (Number.isSafeInteger(parseInt(tdoc.dag[i].pids[j], 10))) {
|
||||
tdoc.dag[i].pids[j] = parseInt(tdoc.dag[i].pids[j], 10);
|
||||
if (Number.isSafeInteger(Number.parseInt(tdoc.dag[i].pids[j], 10))) {
|
||||
tdoc.dag[i].pids[j] = Number.parseInt(tdoc.dag[i].pids[j], 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { serializer } from '@hydrooj/framework';
|
||||
import { LoginError, UserAlreadyExistError, UserNotFoundError } from '../error';
|
||||
import {
|
||||
Authenticator, BaseUserDict, FileInfo, GDoc,
|
||||
ownerInfo, Udict, Udoc, VUdoc,
|
||||
OwnerInfo, Udict, Udoc, VUdoc,
|
||||
} from '../interface';
|
||||
import avatar from '../lib/avatar';
|
||||
import pwhash from '../lib/hash.hydro';
|
||||
@@ -116,9 +116,9 @@ export class User {
|
||||
return this;
|
||||
}
|
||||
|
||||
own<T extends ownerInfo>(doc: T, checkPerm: bigint): boolean;
|
||||
own<T extends ownerInfo>(doc: T, exact: boolean): boolean;
|
||||
own<T extends ownerInfo>(doc: T): boolean;
|
||||
own<T extends OwnerInfo>(doc: T, checkPerm: bigint): boolean;
|
||||
own<T extends OwnerInfo>(doc: T, exact: boolean): boolean;
|
||||
own<T extends OwnerInfo>(doc: T): boolean;
|
||||
own<T extends { owner: number, maintainer?: number[] }>(doc: T): boolean;
|
||||
own(doc: any, arg1: any = false): boolean {
|
||||
if (typeof arg1 === 'bigint' && !this.hasPerm(arg1)) return false;
|
||||
@@ -143,7 +143,7 @@ export class User {
|
||||
throw new LoginError(this.uname);
|
||||
}
|
||||
if (this.hashType !== 'hydro') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
// eslint-disable-next-line ts/no-use-before-define
|
||||
UserModel.setPassword(this._id, password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function iterateAllPsdoc(filter: Filter<ProblemStatusDoc>, cb: (psd
|
||||
}
|
||||
|
||||
interface PartialProblemDoc extends ProblemDoc {
|
||||
[key: string]: any,
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export async function iterateAllProblemInDomain(
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/* eslint-disable perfectionist/sort-exports */
|
||||
import pwsh from './lib/hash.hydro';
|
||||
import db from './service/db';
|
||||
|
||||
export { nanoid } from 'nanoid';
|
||||
export { default as moment, isMoment } from 'moment-timezone';
|
||||
export { isMoment, default as moment } from 'moment-timezone';
|
||||
|
||||
export {
|
||||
WebService, Router, HandlerCommon, httpServer,
|
||||
Query, Mutation, Subscription, Apis, APIS,
|
||||
Apis, APIS, HandlerCommon, httpServer,
|
||||
Mutation, Query, Router, Subscription, WebService,
|
||||
} from '@hydrooj/framework';
|
||||
|
||||
export * from './pipelineUtils';
|
||||
@@ -37,10 +38,10 @@ export { default as TaskModel } from './model/task';
|
||||
export * from './model/builtin';
|
||||
/** @deprecated */
|
||||
export * as JudgeHandler from './handler/judge';
|
||||
export { postJudge, JudgeResultCallbackContext } from './handler/judge';
|
||||
export { JudgeResultCallbackContext, postJudge } from './handler/judge';
|
||||
export { Collections } from './service/db';
|
||||
export { Handler, ConnectionHandler, requireSudo } from './service/server';
|
||||
export { Service, Context } from './context';
|
||||
export { ConnectionHandler, Handler, requireSudo } from './service/server';
|
||||
export { Context, Service } from './context';
|
||||
export { buildContent } from './lib/content';
|
||||
export { default as mime } from './lib/mime';
|
||||
export { default as difficultyAlgorithm } from './lib/difficulty';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
/* eslint-disable ts/no-use-before-define */
|
||||
import { ObjectId } from 'mongodb';
|
||||
import Schema from 'schemastery';
|
||||
import blacklist from '../model/blacklist';
|
||||
|
||||
@@ -14,7 +14,7 @@ async function getRemoteVersion(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function run(_: {}, report: Function) {
|
||||
export async function run(_: void, report: (data: any) => void) {
|
||||
const current = global.Hydro.version;
|
||||
const message = [''];
|
||||
for (const name in current) {
|
||||
|
||||
@@ -17,9 +17,10 @@ import db from '../service/db';
|
||||
export const description = 'Calculate rp of a domain, or all domains';
|
||||
|
||||
type ND = NumericDictionary<number>;
|
||||
type Report = (data: any) => void;
|
||||
|
||||
interface RpDef {
|
||||
run(domainIds: string[], udict: ND, report: Function): Promise<void>;
|
||||
run(domainIds: string[], udict: ND, report: Report): Promise<void>;
|
||||
hidden: boolean;
|
||||
base: number;
|
||||
}
|
||||
@@ -101,7 +102,7 @@ export const RpTypes: Record<string, RpDef> = {
|
||||
};
|
||||
global.Hydro.model.rp = RpTypes;
|
||||
|
||||
export async function calcLevel(domainId: string, report: Function) {
|
||||
export async function calcLevel(domainId: string, report: Report) {
|
||||
await domain.setMultiUserInDomain(domainId, {}, { level: 0, rank: null });
|
||||
let last = { rp: null };
|
||||
let rank = 0;
|
||||
@@ -135,7 +136,7 @@ export async function calcLevel(domainId: string, report: Function) {
|
||||
await bulk.execute();
|
||||
}
|
||||
|
||||
async function runInDomain(domainId: string, report: Function) {
|
||||
async function runInDomain(domainId: string, report: Report) {
|
||||
const results: Record<keyof typeof RpTypes, ND> = {};
|
||||
const udict = Counter();
|
||||
await db.collection('domain.user').updateMany({ domainId }, { $set: { rpInfo: {} } });
|
||||
@@ -160,7 +161,7 @@ async function runInDomain(domainId: string, report: Function) {
|
||||
await calcLevel(domainId, report);
|
||||
}
|
||||
|
||||
export async function run({ domainId }, report: Function) {
|
||||
export async function run({ domainId }, report: Report) {
|
||||
if (!domainId) {
|
||||
const domains = await domain.getMulti().toArray();
|
||||
await report({ message: `Found ${domains.length} domains` });
|
||||
|
||||
@@ -15,95 +15,95 @@ export type Disposable = () => void;
|
||||
export type VoidReturn = Promise<any> | any;
|
||||
|
||||
export interface EventMap {
|
||||
'app/listen': () => void
|
||||
'app/started': () => void
|
||||
'app/ready': () => VoidReturn
|
||||
'app/exit': () => VoidReturn
|
||||
'app/before-reload': (entries: Set<string>) => VoidReturn
|
||||
'app/reload': (entries: Set<string>) => VoidReturn
|
||||
'app/listen': () => void;
|
||||
'app/started': () => void;
|
||||
'app/ready': () => VoidReturn;
|
||||
'app/exit': () => VoidReturn;
|
||||
'app/before-reload': (entries: Set<string>) => VoidReturn;
|
||||
'app/reload': (entries: Set<string>) => VoidReturn;
|
||||
|
||||
'subscription/init': (h: ConnectionHandler<Context>, privileged: boolean) => VoidReturn
|
||||
'subscription/subscribe': (channel: string, user: User, metadata: Record<string, string>) => VoidReturn
|
||||
'subscription/init': (h: ConnectionHandler<Context>, privileged: boolean) => VoidReturn;
|
||||
'subscription/subscribe': (channel: string, user: User, metadata: Record<string, string>) => VoidReturn;
|
||||
'subscription/enable': (
|
||||
channel: string, h: ConnectionHandler<Context>, privileged: boolean, onDispose: (disposable: () => void) => void
|
||||
) => VoidReturn
|
||||
) => VoidReturn;
|
||||
|
||||
'app/watch/change': (path: string) => VoidReturn
|
||||
'app/watch/unlink': (path: string) => VoidReturn
|
||||
'app/watch/change': (path: string) => VoidReturn;
|
||||
'app/watch/unlink': (path: string) => VoidReturn;
|
||||
|
||||
'database/connect': (db: Db) => void
|
||||
'database/config': () => VoidReturn
|
||||
'database/connect': (db: Db) => void;
|
||||
'database/config': () => VoidReturn;
|
||||
|
||||
'system/setting': (args: Record<string, any>) => VoidReturn
|
||||
'bus/broadcast': (event: keyof EventMap, payload: any, trace?: string) => VoidReturn
|
||||
'monitor/update': (type: 'server' | 'judge', $set: any) => VoidReturn
|
||||
'monitor/collect': (info: any) => VoidReturn
|
||||
'system/setting': (args: Record<string, any>) => VoidReturn;
|
||||
'bus/broadcast': (event: keyof EventMap, payload: any, trace?: string) => VoidReturn;
|
||||
'monitor/update': (type: 'server' | 'judge', $set: any) => VoidReturn;
|
||||
'monitor/collect': (info: any) => VoidReturn;
|
||||
'api/update': () => void;
|
||||
'task/daily': () => void;
|
||||
'task/daily/finish': (pref: Record<string, number>) => void;
|
||||
|
||||
'user/message': (uid: number[], mdoc: Omit<MessageDoc, 'to'>) => void
|
||||
'user/get': (udoc: User) => void
|
||||
'user/delcache': (content: string | true) => void
|
||||
'user/message': (uid: number[], mdoc: Omit<MessageDoc, 'to'>) => void;
|
||||
'user/get': (udoc: User) => void;
|
||||
'user/delcache': (content: string | true) => void;
|
||||
|
||||
'user/import/parse': (payload: any) => VoidReturn
|
||||
'user/import/create': (uid: number, udoc: any) => VoidReturn
|
||||
'user/import/parse': (payload: any) => VoidReturn;
|
||||
'user/import/create': (uid: number, udoc: any) => VoidReturn;
|
||||
|
||||
'domain/create': (ddoc: DomainDoc) => VoidReturn
|
||||
'domain/before-get': (query: Filter<DomainDoc>) => VoidReturn
|
||||
'domain/get': (ddoc: DomainDoc) => VoidReturn
|
||||
'domain/before-update': (domainId: string, $set: Partial<DomainDoc>) => VoidReturn
|
||||
'domain/update': (domainId: string, $set: Partial<DomainDoc>, ddoc: DomainDoc) => VoidReturn
|
||||
'domain/delete': (domainId: string) => VoidReturn
|
||||
'domain/delete-cache': (domainId: string) => VoidReturn
|
||||
'domain/create': (ddoc: DomainDoc) => VoidReturn;
|
||||
'domain/before-get': (query: Filter<DomainDoc>) => VoidReturn;
|
||||
'domain/get': (ddoc: DomainDoc) => VoidReturn;
|
||||
'domain/before-update': (domainId: string, $set: Partial<DomainDoc>) => VoidReturn;
|
||||
'domain/update': (domainId: string, $set: Partial<DomainDoc>, ddoc: DomainDoc) => VoidReturn;
|
||||
'domain/delete': (domainId: string) => VoidReturn;
|
||||
'domain/delete-cache': (domainId: string) => VoidReturn;
|
||||
|
||||
'document/add': (doc: any) => VoidReturn
|
||||
'document/add': (doc: any) => VoidReturn;
|
||||
'document/set': <T extends keyof DocType>(
|
||||
domainId: string, docType: T, docId: DocType[T],
|
||||
$set: any, $unset: OnlyFieldsOfType<DocType[T], any, true | '' | 1>
|
||||
) => VoidReturn
|
||||
) => VoidReturn;
|
||||
|
||||
'discussion/before-add': (payload: Partial<DiscussionDoc>) => VoidReturn
|
||||
'discussion/add': (payload: Partial<DiscussionDoc>) => VoidReturn
|
||||
'discussion/before-add': (payload: Partial<DiscussionDoc>) => VoidReturn;
|
||||
'discussion/add': (payload: Partial<DiscussionDoc>) => VoidReturn;
|
||||
|
||||
'problem/before-add': (domainId: string, content: string, owner: number, docId: number, doc: Partial<ProblemDoc>) => VoidReturn
|
||||
'problem/add': (doc: Partial<ProblemDoc>, docId: number) => VoidReturn
|
||||
'problem/before-edit': (doc: Partial<ProblemDoc>, $unset: OnlyFieldsOfType<ProblemDoc, any, true | '' | 1>) => VoidReturn
|
||||
'problem/edit': (doc: ProblemDoc) => VoidReturn
|
||||
'problem/before-del': (domainId: string, docId: number) => VoidReturn
|
||||
'problem/del': (domainId: string, docId: number) => VoidReturn
|
||||
'problem/list': (query: Filter<ProblemDoc>, handler: any, sort?: string[]) => VoidReturn
|
||||
'problem/get': (doc: ProblemDoc, handler: any) => VoidReturn
|
||||
'problem/delete': (domainId: string, docId: number) => VoidReturn
|
||||
'problem/addTestdata': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn
|
||||
'problem/renameTestdata': (domainId: string, docId: number, name: string, newName: string) => VoidReturn
|
||||
'problem/delTestdata': (domainId: string, docId: number, name: string[]) => VoidReturn
|
||||
'problem/addAdditionalFile': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn
|
||||
'problem/renameAdditionalFile': (domainId: string, docId: number, name: string, newName: string) => VoidReturn
|
||||
'problem/delAdditionalFile': (domainId: string, docId: number, name: string[]) => VoidReturn
|
||||
'problem/before-add': (domainId: string, content: string, owner: number, docId: number, doc: Partial<ProblemDoc>) => VoidReturn;
|
||||
'problem/add': (doc: Partial<ProblemDoc>, docId: number) => VoidReturn;
|
||||
'problem/before-edit': (doc: Partial<ProblemDoc>, $unset: OnlyFieldsOfType<ProblemDoc, any, true | '' | 1>) => VoidReturn;
|
||||
'problem/edit': (doc: ProblemDoc) => VoidReturn;
|
||||
'problem/before-del': (domainId: string, docId: number) => VoidReturn;
|
||||
'problem/del': (domainId: string, docId: number) => VoidReturn;
|
||||
'problem/list': (query: Filter<ProblemDoc>, handler: any, sort?: string[]) => VoidReturn;
|
||||
'problem/get': (doc: ProblemDoc, handler: any) => VoidReturn;
|
||||
'problem/delete': (domainId: string, docId: number) => VoidReturn;
|
||||
'problem/addTestdata': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn;
|
||||
'problem/renameTestdata': (domainId: string, docId: number, name: string, newName: string) => VoidReturn;
|
||||
'problem/delTestdata': (domainId: string, docId: number, name: string[]) => VoidReturn;
|
||||
'problem/addAdditionalFile': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn;
|
||||
'problem/renameAdditionalFile': (domainId: string, docId: number, name: string, newName: string) => VoidReturn;
|
||||
'problem/delAdditionalFile': (domainId: string, docId: number, name: string[]) => VoidReturn;
|
||||
|
||||
'contest/before-add': (payload: Partial<Tdoc>) => VoidReturn
|
||||
'contest/add': (payload: Partial<Tdoc>, id: ObjectId) => VoidReturn
|
||||
'contest/edit': (payload: Tdoc) => VoidReturn
|
||||
'contest/list': (query: Filter<Tdoc>, handler: any) => VoidReturn
|
||||
'contest/scoreboard': (tdoc: Tdoc, rows: ScoreboardRow[], udict: BaseUserDict, pdict: ProblemDict) => VoidReturn
|
||||
'contest/balloon': (domainId: string, tid: ObjectId, bdoc: ContestBalloonDoc) => VoidReturn
|
||||
'contest/del': (domainId: string, tid: ObjectId) => VoidReturn
|
||||
'contest/before-add': (payload: Partial<Tdoc>) => VoidReturn;
|
||||
'contest/add': (payload: Partial<Tdoc>, id: ObjectId) => VoidReturn;
|
||||
'contest/edit': (payload: Tdoc) => VoidReturn;
|
||||
'contest/list': (query: Filter<Tdoc>, handler: any) => VoidReturn;
|
||||
'contest/scoreboard': (tdoc: Tdoc, rows: ScoreboardRow[], udict: BaseUserDict, pdict: ProblemDict) => VoidReturn;
|
||||
'contest/balloon': (domainId: string, tid: ObjectId, bdoc: ContestBalloonDoc) => VoidReturn;
|
||||
'contest/del': (domainId: string, tid: ObjectId) => VoidReturn;
|
||||
|
||||
'oplog/log': (type: string, handler: Handler<Context> | ConnectionHandler<Context>, args: any, data: any) => VoidReturn;
|
||||
|
||||
'training/list': (query: Filter<TrainingDoc>, handler: any) => VoidReturn
|
||||
'training/get': (tdoc: TrainingDoc, handler: any) => VoidReturn
|
||||
'training/list': (query: Filter<TrainingDoc>, handler: any) => VoidReturn;
|
||||
'training/get': (tdoc: TrainingDoc, handler: any) => VoidReturn;
|
||||
|
||||
'record/change': (rdoc: RecordDoc, $set?: any, $push?: any, body?: any) => void
|
||||
'record/judge': (rdoc: RecordDoc, updated: boolean, pdoc?: ProblemDoc, updater?: any) => VoidReturn
|
||||
'record/change': (rdoc: RecordDoc, $set?: any, $push?: any, body?: any) => void;
|
||||
'record/judge': (rdoc: RecordDoc, updated: boolean, pdoc?: ProblemDoc, updater?: any) => VoidReturn;
|
||||
}
|
||||
|
||||
export function apply(ctx: Context) {
|
||||
try {
|
||||
if (!process.send || !pm2 || process.env.exec_mode !== 'cluster_mode') throw new Error();
|
||||
if (!process.send || !pm2 || process.env.exec_mode !== 'cluster_mode') throw new Error('not in cluster mode');
|
||||
pm2.launchBus((err, bus) => {
|
||||
if (err) throw new Error();
|
||||
if (err) throw new Error('cannot launch pm2 bus');
|
||||
bus.on('hydro:broadcast', (packet) => {
|
||||
(app.parallel as any)(packet.data.event, ...BSON.EJSON.parse(packet.data.payload));
|
||||
});
|
||||
|
||||
@@ -14,16 +14,16 @@ const logger = new Logger('mongo');
|
||||
export interface Collections { }
|
||||
|
||||
interface MongoConfig {
|
||||
protocol?: string,
|
||||
username?: string,
|
||||
password?: string,
|
||||
host?: string,
|
||||
port?: string,
|
||||
name?: string,
|
||||
url?: string,
|
||||
uri?: string,
|
||||
prefix?: string,
|
||||
collectionMap?: Record<string, string>,
|
||||
protocol?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
host?: string;
|
||||
port?: string;
|
||||
name?: string;
|
||||
url?: string;
|
||||
uri?: string;
|
||||
prefix?: string;
|
||||
collectionMap?: Record<string, string>;
|
||||
}
|
||||
|
||||
declare module '../context' {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// This file was adapted from @koishijs, MIT licensed.
|
||||
/* eslint-disable consistent-return */
|
||||
/* eslint-disable import/no-dynamic-require */
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/* eslint-disable ts/no-shadow */
|
||||
import { readFileSync } from 'fs';
|
||||
import { relative } from 'path';
|
||||
import { codeFrameColumns } from '@babel/code-frame';
|
||||
|
||||
@@ -28,7 +28,7 @@ const ignoredLimit = `,${argv.options.ignoredLimit},`;
|
||||
const logger = new Logger('server');
|
||||
|
||||
declare module '@hydrooj/framework' {
|
||||
export interface HandlerCommon<C> { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
export interface HandlerCommon<C> { // eslint-disable-line ts/no-unused-vars
|
||||
domain: DomainDoc;
|
||||
|
||||
paginate<T>(cursor: FindCursor<T>, page: number, key: string): Promise<[docs: T[], numPages: number, count: number]>;
|
||||
@@ -39,9 +39,9 @@ declare module '@hydrooj/framework' {
|
||||
}
|
||||
}
|
||||
|
||||
export { Mutation, Query } from '@hydrooj/framework/api';
|
||||
export * from '@hydrooj/framework/decorators';
|
||||
export * from '@hydrooj/framework/validator';
|
||||
export { Query, Mutation } from '@hydrooj/framework/api';
|
||||
|
||||
/*
|
||||
* For security concern, some API requires sudo privilege to access.
|
||||
@@ -153,7 +153,7 @@ export async function apply(ctx: Context) {
|
||||
? (!host.includes(this.request.host))
|
||||
: this.request.host !== host)
|
||||
)) withDomainId ||= domainId;
|
||||
res = server.router.url.call(server.router, name, args, { query }).toString();
|
||||
res = server.router.url(name, args, { query }).toString();
|
||||
if (anchor) res = `${res}#${anchor}`;
|
||||
if (withDomainId) res = `/d/${withDomainId}${res}`;
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable consistent-return */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable ts/no-unused-vars */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
/* eslint-disable ts/naming-convention */
|
||||
import yaml from 'js-yaml';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { randomstring, sleep } from '@hydrooj/utils';
|
||||
@@ -51,7 +51,7 @@ export const coreScripts: MigrationScript[] = [
|
||||
return true;
|
||||
},
|
||||
// Init
|
||||
...new Array(47).fill(unsupportedUpgrade), // oxlint-disable-line no-new-array
|
||||
...Array.from({ length: 47 }).fill(unsupportedUpgrade) as any,
|
||||
async function _48_49() {
|
||||
await RecordModel.coll.updateMany({ input: { $exists: true } }, { $set: { contest: new ObjectId('000000000000000000000000') } });
|
||||
return true;
|
||||
@@ -221,7 +221,7 @@ export const coreScripts: MigrationScript[] = [
|
||||
config.answers[cnt] = l;
|
||||
}
|
||||
|
||||
function processSingleLanguage(content: string) { // eslint-disable-line no-inner-declarations
|
||||
function processSingleLanguage(content: string) {
|
||||
let text = '';
|
||||
try {
|
||||
let scnt = 0;
|
||||
|
||||
Reference in new issue
Block a user