core: allow empty pretest input

This commit is contained in:
undefined committed 2025-12-28 14:16:33 +08:00
1 parent 5f38d63866
commit 92e42db7b5
2 files changed
+13 -12

No files matched your search

+11 -11
View File
@@ -61,7 +61,7 @@ export interface Types {
CommaSeperatedArray: Type<string[]>; CommaSeperatedArray: Type<string[]>;
Set: Type<Set<any>>; Set: Type<Set<any>>;
Any: Type<any>; Any: Type<any>;
ArrayOf: <T extends Type<any>>(type: T) => (T extends Type<infer R> ? Type<R[]> : never); ArrayOf: <T extends Type<any>>(type: T, isOptional?: boolean) => (T extends Type<infer R> ? Type<R[]> : never);
AnyOf: <T extends Type<any>>(...type: T[]) => (T extends Type<infer R> ? Type<R> : never); AnyOf: <T extends Type<any>>(...type: T[]) => (T extends Type<infer R> ? Type<R> : never);
} }
@@ -175,15 +175,21 @@ export const Types = {
(v) => emojiRegex().test(v.toString()), (v) => emojiRegex().test(v.toString()),
], ],
Any: [(v) => v, null], Any: [(v) => v, null],
ArrayOf: (type) => [ ArrayOf: (type, isOptional = false) => [
(v) => { (v) => {
const arr = v instanceof Array ? v : [v]; const arr = v instanceof Array ? v : [v];
return arr.map((i) => type[0](i)); return arr.map((i) => {
if (isOptional && [undefined, null, ''].includes(i)) return undefined;
return type[0](i);
});
}, },
(v) => { (v) => {
if (!type[1]) return true; if (!type[1]) return true;
const arr = v instanceof Array ? v : [v]; const arr = v instanceof Array ? v : [v];
return arr.every((i) => type[1](i)); return arr.every((i) => {
if ([undefined, null, ''].includes(i)) return isOptional;
return type[1](i);
});
}, },
] as any, ] as any,
AnyOf: (...types) => [ AnyOf: (...types) => [
@@ -195,10 +201,4 @@ export const Types = {
try { try {
const { ObjectId } = require('mongodb'); const { ObjectId } = require('mongodb');
Types.ObjectId = [((v) => new ObjectId(v)) as any, ObjectId.isValid]; Types.ObjectId = [((v) => new ObjectId(v)) as any, ObjectId.isValid];
} catch (e) { } catch (e) { }
}
// @ts-ignore
Types.ObjectID = Types.ObjectId;
// backward compatibility
+2 -1
View File
@@ -483,7 +483,7 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
@param('lang', Types.Name) @param('lang', Types.Name)
@param('code', Types.String, true) @param('code', Types.String, true)
@param('pretest', Types.Boolean) @param('pretest', Types.Boolean)
@param('input', Types.ArrayOf(Types.String), true) @param('input', Types.ArrayOf(Types.String, true), true)
@param('tid', Types.ObjectId, true) @param('tid', Types.ObjectId, true)
async post(domainId: string, lang: string, code: string, pretest = false, input: string[] = [], tid?: ObjectId) { async post(domainId: string, lang: string, code: string, pretest = false, input: string[] = [], tid?: ObjectId) {
const config = this.pdoc.config; const config = this.pdoc.config;
@@ -499,6 +499,7 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
throw new ProblemNotAllowPretestError('type'); throw new ProblemNotAllowPretestError('type');
} }
if (!input.length) throw new ValidationError('input'); if (!input.length) throw new ValidationError('input');
input = input.map((i) => i || '');
} }
await this.limitRate('add_record', 60, system.get('limit.submission_user'), '{{user}}'); await this.limitRate('add_record', 60, system.get('limit.submission_user'), '{{user}}');
await this.limitRate('add_record', 60, pretest ? system.get('limit.pretest') : system.get('limit.submission')); await this.limitRate('add_record', 60, pretest ? system.get('limit.pretest') : system.get('limit.submission'));