diff --git a/packages/hydrooj/src/handler/contest.ts b/packages/hydrooj/src/handler/contest.ts index d69334a9..1cdc4ccd 100644 --- a/packages/hydrooj/src/handler/contest.ts +++ b/packages/hydrooj/src/handler/contest.ts @@ -385,12 +385,12 @@ export class ContestEditHandler extends Handler { @param('pids', Types.Content) @param('rated', Types.Boolean) @param('code', Types.String, true) - @param('autoHide', Types.Boolean, true) + @param('autoHide', Types.Boolean) @param('assign', Types.CommaSeperatedArray, true) @param('lock', Types.UnsignedInt, true) @param('contestDuration', Types.Float, true) @param('maintainer', Types.NumericArray, true) - @param('allowViewCode', Types.Boolean, true) + @param('allowViewCode', Types.Boolean) async postUpdate( domainId: string, tid: ObjectID, beginAtDate: string, beginAtTime: string, duration: number, title: string, content: string, rule: string, _pids: string, rated = false, diff --git a/packages/hydrooj/src/handler/discussion.ts b/packages/hydrooj/src/handler/discussion.ts index 7f5bc451..ebc90ef8 100644 --- a/packages/hydrooj/src/handler/discussion.ts +++ b/packages/hydrooj/src/handler/discussion.ts @@ -358,7 +358,7 @@ class DiscussionRawHandler extends DiscussionHandler { @param('drid', Types.ObjectID, true) @param('drrid', Types.ObjectID, true) @param('time', Types.UnsignedInt, true) - @param('all', Types.Boolean, true) + @param('all', Types.Boolean) async get(domainId: string, did: ObjectID, drid: ObjectID, drrid: ObjectID, ts: number, all = false) { if (all) { this.response.body.history = await discussion.getHistory(domainId, drrid || drid || did); diff --git a/packages/hydrooj/src/handler/manage.ts b/packages/hydrooj/src/handler/manage.ts index 007a3898..cfa7cdba 100644 --- a/packages/hydrooj/src/handler/manage.ts +++ b/packages/hydrooj/src/handler/manage.ts @@ -297,7 +297,7 @@ class SystemUserPrivHandler extends SystemHandler { @requireSudo @param('uid', Types.Int) @param('priv', Types.UnsignedInt) - @param('system', Types.Boolean, true) + @param('system', Types.Boolean) async post(domainId: string, uid: number, priv: number, editSystem: boolean) { if (!editSystem) { const udoc = await user.getById(domainId, uid); diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index c1955678..b7fcbc79 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -379,7 +379,7 @@ export class ProblemDetailHandler extends ContestDetailBaseHandler { } @query('tid', Types.ObjectID, true) - @query('pjax', Types.Boolean, true) + @query('pjax', Types.Boolean) async get(...args: any[]) { // Navigate to current additional file download // e.g. ![img](a.jpg) will navigate to ![img](./pid/file/a.jpg) diff --git a/packages/hydrooj/src/handler/record.ts b/packages/hydrooj/src/handler/record.ts index 1c83334a..ea5b9b40 100644 --- a/packages/hydrooj/src/handler/record.ts +++ b/packages/hydrooj/src/handler/record.ts @@ -32,7 +32,7 @@ class RecordListHandler extends ContestDetailBaseHandler { @param('lang', Types.String, true) @param('status', Types.Int, true) @param('fullStatus', Types.Boolean) - @param('allDomain', Types.Boolean, true) + @param('allDomain', Types.Boolean) async get( domainId: string, page = 1, pid?: string | number, tid?: ObjectID, uidOrName?: string, lang?: string, status?: number, full = false, diff --git a/packages/hydrooj/src/lib/validator.ts b/packages/hydrooj/src/lib/validator.ts index 7875671e..9aca2d1d 100644 --- a/packages/hydrooj/src/lib/validator.ts +++ b/packages/hydrooj/src/lib/validator.ts @@ -8,7 +8,7 @@ import saslprep from 'saslprep'; type InputType = string | number | Record | any[]; export type Converter = (value: any) => T; export type Validator = (value: Loose extends true ? any : InputType) => boolean; -export type Type = readonly [Converter, Validator?, boolean?]; +export type Type = readonly [Converter, Validator?, (boolean | 'convert')?]; export interface Types { // String outputs @@ -95,7 +95,7 @@ export const Types: Types = { Float: [(v) => +v, (v) => Number.isFinite(+v)], ObjectID: [(v) => new ObjectID(v), ObjectID.isValid], - Boolean: [(v) => v && !['false', 'off'].includes(v), null, true], + Boolean: [(v) => !!(v && !['false', 'off'].includes(v)), null, 'convert'], Date: [ (v) => { const d = v.split('-'); diff --git a/packages/hydrooj/src/service/decorators.ts b/packages/hydrooj/src/service/decorators.ts index ba8fb62d..40151dc0 100644 --- a/packages/hydrooj/src/service/decorators.ts +++ b/packages/hydrooj/src/service/decorators.ts @@ -9,7 +9,7 @@ type ClassDecorator = any>(Class: T) => T ext export interface ParamOption { name: string, source: 'all' | 'get' | 'post' | 'route', - isOptional?: boolean, + isOptional?: boolean | 'convert', convert?: Converter, validate?: Validator, } @@ -60,6 +60,8 @@ function _descriptor(v: ParamOption) { if (item.validate && !item.validate(value)) throw new ValidationError(item.name); if (item.convert) c.push(item.convert(value)); else c.push(value); + } else if (item.isOptional === 'convert') { + c.push(item.convert ? item.convert(value) : value); } else c.push(undefined); } return originalMethod.call(this, ...c);