From 7f51df236ab9902e3d27d3f7811e159b3e17dbc9 Mon Sep 17 00:00:00 2001 From: undefined Date: Fri, 6 Jan 2023 00:28:35 +0800 Subject: [PATCH] eslint: enable extra rules no-implicit-coercion, no-extra-boolean-cast, no-invalid-this, logical-assignment-operators, no-unmodified-loop-condition --- .eslintrc.yaml | 16 ++++++++++- packages/elastic/index.ts | 14 +++------- packages/hydrojudge/src/daemon.ts | 2 +- packages/hydrojudge/src/hosts/hydro.ts | 11 ++++---- packages/hydrooj/src/handler/contest.ts | 2 +- packages/hydrooj/src/handler/discussion.ts | 4 +-- packages/hydrooj/src/handler/home.ts | 12 ++++----- packages/hydrooj/src/handler/judge.ts | 2 +- packages/hydrooj/src/handler/manage.ts | 2 +- packages/hydrooj/src/handler/misc.ts | 2 +- packages/hydrooj/src/handler/problem.ts | 4 +-- packages/hydrooj/src/handler/status.ts | 2 +- packages/hydrooj/src/handler/training.ts | 2 +- packages/hydrooj/src/handler/user.ts | 4 +-- packages/hydrooj/src/init.ts | 2 +- packages/hydrooj/src/lib/avatar.ts | 2 +- packages/hydrooj/src/lib/i18n.ts | 2 +- packages/hydrooj/src/lib/ui.ts | 2 +- packages/hydrooj/src/model/contest.ts | 31 +++++++++++----------- packages/hydrooj/src/model/discussion.ts | 2 +- packages/hydrooj/src/model/domain.ts | 4 +-- packages/hydrooj/src/model/schedule.ts | 2 +- packages/hydrooj/src/model/user.ts | 2 +- packages/hydrooj/src/script/rating.ts | 2 +- packages/hydrooj/src/service/decorators.ts | 4 +-- packages/hydrooj/src/service/server.ts | 2 +- packages/hydrooj/src/settings.ts | 2 +- packages/login-with-github/index.ts | 4 +-- packages/login-with-google/index.ts | 6 ++--- packages/migrate/scripts/hustoj.ts | 2 +- packages/migrate/scripts/syzoj.ts | 2 +- packages/utils/lib/cases.ts | 2 +- packages/utils/lib/common.ts | 30 ++++++++++----------- packages/utils/lib/lang.ts | 12 ++++----- 34 files changed, 100 insertions(+), 96 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index f722166ee..6fbbffc15 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -24,6 +24,7 @@ overrides: '@typescript-eslint/indent': - warn - 2 + '@typescript-eslint/no-invalid-this': 0 env: browser: true es6: true @@ -44,7 +45,14 @@ rules: '@typescript-eslint/no-throw-literal': 0 '@typescript-eslint/return-await': 0 + no-implicit-coercion: + - warn + - allow: ["!!", "+"] + no-extra-boolean-cast: + - warn + - enforceForLogicalOperands: true no-multi-str: 0 + '@typescript-eslint/no-invalid-this': 1 '@typescript-eslint/type-annotation-spacing': 1 '@typescript-eslint/indent': - warn @@ -111,6 +119,10 @@ rules: import/no-extraneous-dependencies: 0 import/no-named-as-default: 0 import/prefer-default-export: 0 + logical-assignment-operators: + - warn + - always + - enforceForIfStatements: true max-classes-per-file: 0 max-len: - warn @@ -131,6 +143,7 @@ rules: no-return-await: 0 no-shadow: 0 no-underscore-dangle: 0 + no-unmodified-loop-condition: 1 prefer-destructuring: 0 function-paren-newline: 0 simple-import-sort/imports: @@ -153,7 +166,8 @@ settings: import/resolver: typescript: alwaysTryTypes: true -# parserOptions: +parserOptions: + sourceType: module # project: # - './tsconfig.json' # - './packages/**/tsconfig.json' \ No newline at end of file diff --git a/packages/elastic/index.ts b/packages/elastic/index.ts index 64936faab..fb6973cac 100644 --- a/packages/elastic/index.ts +++ b/packages/elastic/index.ts @@ -8,16 +8,10 @@ const client = new Client({ node: SystemModel.get('elastic-search.url') || 'http const indexOmit = ['_id', 'docType', 'data', 'additional_file', 'config', 'stats', 'assign']; const processDocument = (doc: Partial) => { - if (doc.content) { - doc.content = doc.content.replace(/[[\]【】()()]/g, ' '); - } - if (doc.title) { - doc.title = doc.title.replace(/[[\]【】()()]/g, ' ') - .replace(/([a-zA-Z]{2,})(\d+)/, '$1$2 $1 $2'); - } - if (doc.pid) { - doc.pid = doc.pid.replace(/([a-zA-Z]{2,})(\d+)/, '$1$2 $1 $2'); - } + doc.content &&= doc.content.replace(/[[\]【】()()]/g, ' '); + doc.title &&= doc.title.replace(/[[\]【】()()]/g, ' ') + .replace(/([a-zA-Z]{2,})(\d+)/, '$1$2 $1 $2'); + doc.pid &&= doc.pid.replace(/([a-zA-Z]{2,})(\d+)/, '$1$2 $1 $2'); return _.omit(doc, indexOmit); }; diff --git a/packages/hydrojudge/src/daemon.ts b/packages/hydrojudge/src/daemon.ts index d370502df..26396b24a 100644 --- a/packages/hydrojudge/src/daemon.ts +++ b/packages/hydrojudge/src/daemon.ts @@ -57,7 +57,7 @@ async function daemon() { const queue = new PQueue({ concurrency: Infinity }); queue.on('error', (e) => log.error(e)); for (const i in _hosts) { - _hosts[i].host = _hosts[i].host || i; + _hosts[i].host ||= i; hosts[i] = new HydroHost(_hosts[i]); await hosts[i].init(); } diff --git a/packages/hydrojudge/src/hosts/hydro.ts b/packages/hydrojudge/src/hosts/hydro.ts index 40c639d60..6cc78e4e8 100644 --- a/packages/hydrojudge/src/hosts/hydro.ts +++ b/packages/hydrojudge/src/hosts/hydro.ts @@ -24,9 +24,9 @@ export default class Hydro { language: Record; constructor(public config) { - this.config.detail = this.config.detail ?? true; - this.config.cookie = this.config.cookie || ''; - this.config.last_update_at = this.config.last_update_at || 0; + this.config.detail ??= true; + this.config.cookie ||= ''; + this.config.last_update_at ||= 0; if (!this.config.server_url.startsWith('http')) this.config.server_url = `http://${this.config.server_url}`; if (!this.config.server_url.endsWith('/')) this.config.server_url = `${this.config.server_url}/`; this.getLang = this.getLang.bind(this); @@ -91,11 +91,12 @@ export default class Hydro { files: filenames, }); if (!res.body.links) throw new FormatError('problem not exist'); + const that = this; // eslint-disable-next-line no-inner-declarations async function download(name: string) { if (name.includes('/')) await fs.ensureDir(path.join(filePath, name.split('/')[0])); const w = fs.createWriteStream(path.join(filePath, name)); - this.get(res.body.links[name]).pipe(w); + that.get(res.body.links[name]).pipe(w); await new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error(`DownloadTimeout(${name}, 60s)`)), 60000); w.on('error', (e) => { @@ -111,7 +112,7 @@ export default class Hydro { const tasks = []; const queue = new PQueue({ concurrency: 10 }); for (const name in res.body.links) { - tasks.push(queue.add(() => download.call(this, name))); + tasks.push(queue.add(() => download(name))); } queue.start(); await Promise.all(tasks); diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index d2f06b0fb..3d604cd97 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -546,7 +546,7 @@ export class ContestManagementHandler extends ContestManagementBaseHandler { if (size >= system.get('limit.contest_files_size')) { throw new FileLimitExceededError('size'); } - if (!filename) filename = file.originalFilename || String.random(16); + filename ||= file.originalFilename || String.random(16); if (filename.includes('/') || filename.includes('..')) throw new ValidationError('filename', null, 'Bad filename'); await storage.put(`contest/${domainId}/${tid}/${filename}`, file.filepath, this.user._id); const meta = await storage.getMeta(`contest/${domainId}/${tid}/${filename}`); diff --git a/packages/hydrooj/src/handler/discussion.ts b/packages/hydrooj/src/handler/discussion.ts index 7445d4609..919e81113 100644 --- a/packages/hydrooj/src/handler/discussion.ts +++ b/packages/hydrooj/src/handler/discussion.ts @@ -65,8 +65,8 @@ class DiscussionHandler extends Handler { } } if (this.ddoc) { - this.ddoc.parentType = this.ddoc.parentType || this.vnode.type; - this.ddoc.parentId = this.ddoc.parentId || this.vnode.id; + this.ddoc.parentType ||= this.vnode.type; + this.ddoc.parentId ||= this.vnode.id; } } } diff --git a/packages/hydrooj/src/handler/home.ts b/packages/hydrooj/src/handler/home.ts index 1db411bd2..74eef13c7 100644 --- a/packages/hydrooj/src/handler/home.ts +++ b/packages/hydrooj/src/handler/home.ts @@ -375,13 +375,11 @@ class HomeMessagesHandler extends Handler { const parsed = {}; for (const m of messages) { const target = m.from === this.user._id ? m.to : m.from; - if (!parsed[target]) { - parsed[target] = { - _id: target, - udoc: { ...udict[target], avatarUrl: avatar(udict[target].avatar) }, - messages: [], - }; - } + parsed[target] ||= { + _id: target, + udoc: { ...udict[target], avatarUrl: avatar(udict[target].avatar) }, + messages: [], + }; parsed[target].messages.push(m); } await user.setById(this.user._id, { unreadMsg: 0 }); diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 29e9eacdc..8fb44b3b8 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -115,7 +115,7 @@ export async function postJudge(rdoc: RecordDoc) { } export async function end(body: Partial) { - if (body.rid) body.rid = new ObjectID(body.rid); + body.rid &&= new ObjectID(body.rid); let rdoc = await record.get(body.rid); if (!rdoc) return; const $set: Partial = {}; diff --git a/packages/hydrooj/src/handler/manage.ts b/packages/hydrooj/src/handler/manage.ts index a94fbfb0d..188a886bc 100644 --- a/packages/hydrooj/src/handler/manage.ts +++ b/packages/hydrooj/src/handler/manage.ts @@ -242,7 +242,7 @@ class SystemUserImportHandler extends SystemHandler { try { const data = JSON.parse(extra); if (data.group) { - if (!groups[data.group]) groups[data.group] = []; + groups[data.group] ||= []; groups[data.group].push(email); } if (data.school) payload.school = data.school; diff --git a/packages/hydrooj/src/handler/misc.ts b/packages/hydrooj/src/handler/misc.ts index acbc0c4c4..0c79766a7 100644 --- a/packages/hydrooj/src/handler/misc.ts +++ b/packages/hydrooj/src/handler/misc.ts @@ -57,7 +57,7 @@ export class FilesHandler extends Handler { if (size >= system.get('limit.user_files_size')) { if (!this.user.hasPriv(PRIV.PRIV_UNLIMITED_QUOTA)) throw new FileLimitExceededError('size'); } - if (!filename) filename = file.originalFilename || String.random(16); + filename ||= file.originalFilename || String.random(16); if (filename.includes('/') || filename.includes('..')) throw new ValidationError('filename', null, 'Bad filename'); if (this.user._files.filter((i) => i.name === filename).length) throw new FileExistsError(filename); await storage.put(`user/${this.user._id}/${filename}`, file.filepath, this.user._id); diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 7b70caac7..9629037ea 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -161,7 +161,7 @@ export class ProblemMainHandler extends Handler { total = result.total; pcountRelation = result.countRelation; if (!result.hits.length) fail = true; - if (!query.$and) query.$and = []; + query.$and ||= []; query.$and.push({ $or: result.hits.map((i) => { const [did, docId] = i.split('/'); @@ -723,7 +723,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler { async postUploadFile(domainId: string, filename: string, type = 'testdata') { if (this.pdoc.reference) throw new ProblemIsReferencedError('edit files'); if (!this.request.files.file) throw new ValidationError('file'); - if (!filename) filename = this.request.files.file.originalFilename || String.random(16); + filename ||= this.request.files.file.originalFilename || String.random(16); if (filename.includes('/') || filename.includes('..')) throw new ValidationError('filename', null, 'Bad filename'); if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM); const files = []; diff --git a/packages/hydrooj/src/handler/status.ts b/packages/hydrooj/src/handler/status.ts index 06ae5e441..94fb0e762 100644 --- a/packages/hydrooj/src/handler/status.ts +++ b/packages/hydrooj/src/handler/status.ts @@ -15,7 +15,7 @@ async function getStatus() { let desc = ''; const online = new Date(stat.updateAt).getTime() > new Date().getTime() - 300000; if (!online) desc = 'Offline'; - desc = desc || 'Online'; + desc ||= 'Online'; stat.isOnline = online; stat.status = desc; } diff --git a/packages/hydrooj/src/handler/training.ts b/packages/hydrooj/src/handler/training.ts index 1a1a2f61e..dc7c19e1a 100644 --- a/packages/hydrooj/src/handler/training.ts +++ b/packages/hydrooj/src/handler/training.ts @@ -268,7 +268,7 @@ export class TrainingFilesHandler extends Handler { if (size >= system.get('limit.contest_files_size')) { throw new FileLimitExceededError('size'); } - if (!filename) filename = file.originalFilename || String.random(16); + filename ||= file.originalFilename || String.random(16); if (filename.includes('/') || filename.includes('..')) throw new ValidationError('filename', null, 'Bad filename'); await storage.put(`training/${domainId}/${tid}/${filename}`, file.filepath, this.user._id); const meta = await storage.getMeta(`training/${domainId}/${tid}/${filename}`); diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index d8c64ae52..43d148174 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -119,7 +119,7 @@ class UserLoginHandler extends Handler { async post(domainId: string, uname: string, password: string, rememberme = false, redirect = '', tfa = '') { if (!system.get('server.login')) throw new BuiltinLoginError(); let udoc = await user.getByEmail(domainId, uname); - if (!udoc) udoc = await user.getByUname(domainId, uname); + udoc ||= await user.getByUname(domainId, uname); if (!udoc) throw new UserNotFoundError(uname); await Promise.all([ this.limitRate('user_login', 60, 30, false), @@ -425,7 +425,7 @@ class OauthCallbackHandler extends Handler { } this.checkPriv(PRIV.PRIV_REGISTER_USER); let username = ''; - r.uname = r.uname || []; + r.uname ||= []; r.uname.push(String.random(16)); const mailDomain = r.email.split('@')[1]; if (await BlackListModel.get(`mail::${mailDomain}`)) throw new BlacklistedError(mailDomain); diff --git a/packages/hydrooj/src/init.ts b/packages/hydrooj/src/init.ts index c70b1a3cd..81810c2a2 100644 --- a/packages/hydrooj/src/init.ts +++ b/packages/hydrooj/src/init.ts @@ -18,7 +18,7 @@ if (!global.Hydro) { lib: {}, module: new Proxy({} as any, { get(self, key) { - if (!self[key]) self[key] = {}; + self[key] ||= {}; return self[key]; }, }), diff --git a/packages/hydrooj/src/lib/avatar.ts b/packages/hydrooj/src/lib/avatar.ts index 15b693535..887adf341 100644 --- a/packages/hydrooj/src/lib/avatar.ts +++ b/packages/hydrooj/src/lib/avatar.ts @@ -11,7 +11,7 @@ export const providers: Record = { }; function avatar(src: string, size = 64, fallback = '') { - src = src || fallback; + src ||= fallback; let index = src.indexOf(':'); if (index === -1) src = fallback; index = src.indexOf(':'); diff --git a/packages/hydrooj/src/lib/i18n.ts b/packages/hydrooj/src/lib/i18n.ts index 254b93e9d..6bd9b9f64 100644 --- a/packages/hydrooj/src/lib/i18n.ts +++ b/packages/hydrooj/src/lib/i18n.ts @@ -19,7 +19,7 @@ class I18nService extends Service { } load(lang: string, content: Record) { - if (!translations[lang]) translations[lang] = []; + translations[lang] ||= []; translations[lang].unshift(content); this.caller?.on('dispose', () => { translations[lang] = translations[lang].filter((i) => i !== content); diff --git a/packages/hydrooj/src/lib/ui.ts b/packages/hydrooj/src/lib/ui.ts index f4f8a0057..be9336b94 100644 --- a/packages/hydrooj/src/lib/ui.ts +++ b/packages/hydrooj/src/lib/ui.ts @@ -26,7 +26,7 @@ const buildChecker = (...permPrivChecker: PermPrivChecker) => { export const nodes = new Proxy({}, { get(self, key) { - if (!self[key]) self[key] = []; + self[key] ||= []; return self[key]; }, }); diff --git a/packages/hydrooj/src/model/contest.ts b/packages/hydrooj/src/model/contest.ts index 74318123c..4bf97152d 100644 --- a/packages/hydrooj/src/model/contest.ts +++ b/packages/hydrooj/src/model/contest.ts @@ -35,18 +35,17 @@ interface AcmDetail extends AcmJournal { function buildContestRule(def: ContestRule): ContestRule; function buildContestRule(def: Partial>, baseRule: ContestRule): ContestRule; -function buildContestRule(def: Partial>, { _originalRule: base }: ContestRule = { _originalRule: {} } as any) { - def._originalRule = { - scoreboard: def.scoreboard || base.scoreboard, - scoreboardRow: def.scoreboardRow || base.scoreboardRow, - scoreboardHeader: def.scoreboardHeader || base.scoreboardHeader, - stat: def.stat || base.stat, - }; - def.scoreboard = (def.scoreboard || base.scoreboard).bind(def); - def.scoreboardHeader = (def.scoreboardHeader || base.scoreboardHeader).bind(def); - def.scoreboardRow = (def.scoreboardRow || base.scoreboardRow).bind(def); - def.stat = (def.stat || base.stat).bind(def); - return def as ContestRule; +function buildContestRule(def: Partial>, baseRule: ContestRule = {} as any) { + const base = baseRule._originalRule || {}; + const funcs = ['scoreboard', 'scoreboardRow', 'scoreboardHeader', 'stat']; + const f = {}; + const rule = { ...baseRule, ...def }; + for (const key of funcs) { + f[key] = def[key] || base[key]; + rule[key] = f[key].bind(rule); + } + rule._originalRule = f; + return rule; } const acm = buildContestRule({ @@ -708,24 +707,24 @@ export async function unlockScoreboard(domainId: string, tid: ObjectID) { await edit(domainId, tid, { unlocked: true }); } -export function canViewHiddenScoreboard(tdoc: Tdoc<30>) { +export function canViewHiddenScoreboard(this: Handler, tdoc: Tdoc<30>) { if (tdoc.rule === 'homework') return this.user.hasPerm(PERM.PERM_VIEW_HOMEWORK_HIDDEN_SCOREBOARD); return this.user.hasPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD); } -export function canShowRecord(tdoc: Tdoc<30>, allowPermOverride = true) { +export function canShowRecord(this: Handler, tdoc: Tdoc<30>, allowPermOverride = true) { if (RULES[tdoc.rule].showRecord(tdoc, new Date())) return true; if (allowPermOverride && canViewHiddenScoreboard.call(this, tdoc)) return true; return false; } -export function canShowSelfRecord(tdoc: Tdoc<30>, allowPermOverride = true) { +export function canShowSelfRecord(this: Handler, tdoc: Tdoc<30>, allowPermOverride = true) { if (RULES[tdoc.rule].showSelfRecord(tdoc, new Date())) return true; if (allowPermOverride && canViewHiddenScoreboard.call(this, tdoc)) return true; return false; } -export function canShowScoreboard(tdoc: Tdoc<30>, allowPermOverride = true) { +export function canShowScoreboard(this: Handler, tdoc: Tdoc<30>, allowPermOverride = true) { if (RULES[tdoc.rule].showScoreboard(tdoc, new Date())) return true; if (allowPermOverride && canViewHiddenScoreboard.call(this, tdoc)) return true; return false; diff --git a/packages/hydrooj/src/model/discussion.ts b/packages/hydrooj/src/model/discussion.ts index a891b62e3..8e371da88 100644 --- a/packages/hydrooj/src/model/discussion.ts +++ b/packages/hydrooj/src/model/discussion.ts @@ -305,7 +305,7 @@ export async function getListVnodes(domainId: string, ddocs: any, getHidden = fa const res = {}; async function task(ddoc: DiscussionDoc) { const vnode = await getVnode(domainId, ddoc.parentType, ddoc.parentId.toString()); - if (!res[ddoc.parentType]) res[ddoc.parentType] = {}; + res[ddoc.parentType] ||= {}; if (!getHidden && vnode.hidden) return; if (vnode.assign?.length && Set.intersection(vnode.assign, assign).size) return; res[ddoc.parentType][ddoc.parentId] = vnode; diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index 389e07141..62dd9dca2 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -178,10 +178,10 @@ class DomainModel { static async getDomainUser(domainId: string, udoc: DomainUserArg) { let dudoc = await collUser.findOne({ domainId, uid: udoc._id }); - dudoc = dudoc || {}; + dudoc ||= {}; if (!(udoc.priv & PRIV.PRIV_USER_PROFILE)) dudoc.role = 'guest'; if (udoc.priv & PRIV.PRIV_MANAGE_ALL_DOMAIN) dudoc.role = 'root'; - dudoc.role = dudoc.role || 'default'; + dudoc.role ||= 'default'; const ddoc = await DomainModel.get(domainId); dudoc.perm = ddoc?.roles[dudoc.role] ? BigInt(ddoc?.roles[dudoc.role]) diff --git a/packages/hydrooj/src/model/schedule.ts b/packages/hydrooj/src/model/schedule.ts index 7804057d1..5d0917174 100644 --- a/packages/hydrooj/src/model/schedule.ts +++ b/packages/hydrooj/src/model/schedule.ts @@ -13,7 +13,7 @@ const coll = db.collection('schedule'); async function getFirst(query: FilterQuery) { if (process.env.CI) return null; const q = { ...query }; - q.executeAfter = q.executeAfter || { $lt: new Date() }; + q.executeAfter ||= { $lt: new Date() }; const res = await coll.findOneAndDelete(q); if (res.value) { logger.debug('%o', res.value); diff --git a/packages/hydrooj/src/model/user.ts b/packages/hydrooj/src/model/user.ts index 75a6f24e9..475aace3b 100644 --- a/packages/hydrooj/src/model/user.ts +++ b/packages/hydrooj/src/model/user.ts @@ -209,7 +209,7 @@ class UserModel { const unameLower = uname.trim().toLowerCase(); if (cache.has(`name/${unameLower}/${domainId}`)) return cache.get(`name/${unameLower}/${domainId}`) || null; let udoc = await coll.findOne({ unameLower }); - if (!udoc) udoc = await collV.findOne({ unameLower }); + udoc ||= await collV.findOne({ unameLower }); if (!udoc) return null; const dudoc = await domain.getDomainUser(domainId, udoc); const res = await new UserModel.User(udoc, dudoc).init(); diff --git a/packages/hydrooj/src/script/rating.ts b/packages/hydrooj/src/script/rating.ts index 35b7ec6d2..f4f132925 100644 --- a/packages/hydrooj/src/script/rating.ts +++ b/packages/hydrooj/src/script/rating.ts @@ -111,7 +111,7 @@ export async function calcLevel(domainId: string, report: Function) { let bulk = coll.initializeUnorderedBulkOp(); for await (const dudoc of ducur) { count++; - if (!dudoc.rp) dudoc.rp = null; + dudoc.rp ||= null; if (dudoc.rp !== last.rp) rank = count; bulk.find({ _id: dudoc._id }).updateOne({ $set: { rank } }); last = dudoc; diff --git a/packages/hydrooj/src/service/decorators.ts b/packages/hydrooj/src/service/decorators.ts index 3b8384c8c..9116740ac 100644 --- a/packages/hydrooj/src/service/decorators.ts +++ b/packages/hydrooj/src/service/decorators.ts @@ -166,8 +166,8 @@ function _buildParam(name: string, source: 'get' | 'post' | 'all' | 'route', ... function _descriptor(v: ParamOption) { return function desc(this: Handler, target: any, funcName: string, obj: any) { - if (!target.__param) target.__param = {}; - if (!target.__param[target.constructor.name]) target.__param[target.constructor.name] = {}; + target.__param ||= {}; + target.__param[target.constructor.name] ||= {}; if (!target.__param[target.constructor.name][funcName]) { target.__param[target.constructor.name][funcName] = [{ name: 'domainId', type: 'string', source: 'route' }]; const originalMethod = obj.value; diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 3414a982c..36c2b395d 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -194,7 +194,7 @@ export class Handler extends HandlerCommon { } async onerror(error: HydroError) { - if (!error.msg) error.msg = () => error.message; + error.msg ||= () => error.message; if (error instanceof UserFacingError && !process.env.DEV) error.stack = ''; if (!(error instanceof NotFoundError)) { // eslint-disable-next-line max-len diff --git a/packages/hydrooj/src/settings.ts b/packages/hydrooj/src/settings.ts index bc20d77d3..71a8cf546 100644 --- a/packages/hydrooj/src/settings.ts +++ b/packages/hydrooj/src/settings.ts @@ -71,7 +71,7 @@ export async function setConfig(key: string, value: any) { const t = path.pop(); let cursor = systemConfig; for (const p of path) { - if (!cursor[p]) cursor[p] = {}; + cursor[p] ||= {}; cursor = cursor[p]; } cursor[t] = value; diff --git a/packages/login-with-github/index.ts b/packages/login-with-github/index.ts index 377f822f2..a7cad1a01 100644 --- a/packages/login-with-github/index.ts +++ b/packages/login-with-github/index.ts @@ -1,5 +1,5 @@ import { - Context, ForbiddenError, superagent, SystemModel, + Context, ForbiddenError, Handler, superagent, SystemModel, TokenModel, UserFacingError, ValidationError, } from 'hydrooj'; @@ -11,7 +11,7 @@ declare module 'hydrooj' { } } -async function get() { +async function get(this: Handler) { const [appid, [state]] = await Promise.all([ SystemModel.get('login-with-github.id'), TokenModel.add(TokenModel.TYPE_OAUTH, 600, { redirect: this.request.referer }), diff --git a/packages/login-with-google/index.ts b/packages/login-with-google/index.ts index ff1da8ae0..23164886d 100644 --- a/packages/login-with-google/index.ts +++ b/packages/login-with-google/index.ts @@ -1,5 +1,5 @@ import { - Context, superagent, SystemModel, TokenModel, UserFacingError, + Context, Handler, superagent, SystemModel, TokenModel, UserFacingError, } from 'hydrooj'; declare module 'hydrooj' { @@ -9,7 +9,7 @@ declare module 'hydrooj' { } } -async function get() { +async function get(this: Handler) { const [appid, url, [state]] = await Promise.all([ SystemModel.get('login-with-google.id'), SystemModel.get('server.url'), @@ -42,7 +42,7 @@ function decodeJWT(idToken: string) { } } -async function callback({ +async function callback(this: Handler, { state, code, error, }) { if (error) throw new UserFacingError(error); diff --git a/packages/migrate/scripts/hustoj.ts b/packages/migrate/scripts/hustoj.ts index 423cc3a85..358f17273 100644 --- a/packages/migrate/scripts/hustoj.ts +++ b/packages/migrate/scripts/hustoj.ts @@ -94,7 +94,7 @@ export async function run({ for (const udoc of udocs) { if (randomMail) delete udoc.email; let current = await UserModel.getByEmail(domainId, udoc.email || `${udoc.user_id}@hustoj.local`); - if (!current) current = await UserModel.getByUname(domainId, udoc.user_id); + current ||= await UserModel.getByUname(domainId, udoc.user_id); if (current) { report({ message: `duplicate user with email ${udoc.email}: ${current.uname},${udoc.user_id}` }); uidMap[udoc.user_id] = current._id; diff --git a/packages/migrate/scripts/syzoj.ts b/packages/migrate/scripts/syzoj.ts index e6c91aa32..5cc86e4d9 100644 --- a/packages/migrate/scripts/syzoj.ts +++ b/packages/migrate/scripts/syzoj.ts @@ -116,7 +116,7 @@ export async function run({ for (const udoc of udocs) { if (randomMail) delete udoc.email; let current = await UserModel.getByEmail(domainId, udoc.email || `${udoc.username}@syzoj.local`); - if (!current) current = await UserModel.getByUname(domainId, udoc.username); + current ||= await UserModel.getByUname(domainId, udoc.username); if (current) { report({ message: `duplicate user with email ${udoc.email}: ${current.uname},${udoc.username}` }); uidMap[udoc.id] = current._id; diff --git a/packages/utils/lib/cases.ts b/packages/utils/lib/cases.ts index a4149d208..df91b0cc6 100644 --- a/packages/utils/lib/cases.ts +++ b/packages/utils/lib/cases.ts @@ -16,7 +16,7 @@ export default async function readYamlCases(cfg: Record = {}, check if (!cfg.checker.includes('.')) { config.checker = findFileSync(`@hydrooj/hydrojudge/vendor/testlib/checkers/${cfg.checker}.cpp`, false); } - if (!config.checker) config.checker = checkFile(cfg.checker, 'Cannot find checker {0}.'); + config.checker ||= checkFile(cfg.checker, 'Cannot find checker {0}.'); } if (cfg.interactor) config.interactor = checkFile(cfg.interactor, 'Cannot find interactor {0}.'); if (cfg.validator) config.validator = checkFile(cfg.validator, 'Cannot find validator {0}.'); diff --git a/packages/utils/lib/common.ts b/packages/utils/lib/common.ts index ccddb63e4..e28178245 100644 --- a/packages/utils/lib/common.ts +++ b/packages/utils/lib/common.ts @@ -28,23 +28,21 @@ String.random = function random(digit = 32, dict = defaultDict) { return str; }; -if (!String.prototype.format) { - String.prototype.format = function formatStr(...args) { - let result = this; - if (args.length) { - if (args.length === 1 && typeof args[0] === 'object') { - const t = args[0]; - for (const key in t) { - if (!key.startsWith('_') && t[key] !== undefined) { - const reg = new RegExp(`(\\{${key}\\})`, 'g'); - result = result.replace(reg, t[key]); - } +String.prototype.format ||= function formatStr(...args) { + let result = this; + if (args.length) { + if (args.length === 1 && typeof args[0] === 'object') { + const t = args[0]; + for (const key in t) { + if (!key.startsWith('_') && t[key] !== undefined) { + const reg = new RegExp(`(\\{${key}\\})`, 'g'); + result = result.replace(reg, t[key]); } - } else return this.formatFromArray(args); - } - return result; - }; -} + } + } else return this.formatFromArray(args); + } + return result; +}; String.prototype.formatFromArray = function formatStr(args) { let result = this; diff --git a/packages/utils/lib/lang.ts b/packages/utils/lib/lang.ts index 593b9233e..22bfeb858 100644 --- a/packages/utils/lib/lang.ts +++ b/packages/utils/lib/lang.ts @@ -34,13 +34,13 @@ export function parseLang(config: string): Record { } for (const key in file) { const entry = file[key]; - entry.highlight = entry.highlight || key; - entry.monaco = entry.monaco || entry.highlight; - entry.time_limit_rate = entry.time_limit_rate || 1; - entry.code_file = entry.code_file || `foo.${key}`; - entry.execute = entry.execute || '/w/foo'; + entry.highlight ||= key; + entry.monaco ||= entry.highlight; + entry.time_limit_rate ||= 1; + entry.code_file ||= `foo.${key}`; + entry.execute ||= '/w/foo'; entry.key = key; - entry.hidden = entry.hidden || false; + entry.hidden ||= false; } return file; }