diff --git a/package.json b/package.json index 653bd1e7..826b2c55 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "jest": "node build/jest", "debug": "node --async-stack-traces --trace-deprecation --enable-source-maps build/start --debug", "start": "node build/start", - "clean": "zsh -c \"rm -rf tsconfig.build.tsbuildinfo ./packages/*/tsconfig.tsbuildinfo ./packages/*/dist ./**/tscofig.json ./.coverage\"" + "clean": "zsh -c \"rm -rf tsconfig.build.tsbuildinfo ./packages/*/tsconfig.tsbuildinfo ./packages/*/dist ./.coverage\"" }, "version": "1.0.0", "license": "AGPL-3.0-only", @@ -41,4 +41,4 @@ "fs-extra": "^9.0.1", "yargs": "^16.0.3" } -} +} \ No newline at end of file diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 9a39f181..77c151a8 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -3,6 +3,7 @@ import { Readable, Writable } from 'stream'; import { ObjectID } from 'mongodb'; import fs from 'fs'; import { Dictionary, NumericDictionary } from 'lodash'; +import type { Pdoc } from './model/problem'; type document = typeof import('./model/document'); @@ -155,31 +156,32 @@ export interface RemoteProblemConfig { export type ProblemConfig = LocalProblemConfig | RemoteProblemConfig; -export interface Pdoc { - _id: ObjectID, - domainId: string, - docType: 10, - docId: number, - pid: string, - owner: number, - title: string, - content: string, - nSubmit: number, - nAccept: number, - tag: string[], - category: string[], - data?: ProblemData, - hidden: boolean, - config: ProblemConfig, - acMsg?: string, - html?: boolean, - - difficulty?: number, - difficultyAlgo?: number, - difficultyAdmin?: number, - difficultySetting?: any, +declare module './model/problem' { + interface Pdoc { + domainId: string, + docType: 10, + docId: number, + pid: string, + owner: number, + title: string, + content: string, + nSubmit: number, + nAccept: number, + tag: string[], + category: string[], + data?: ProblemData, + hidden: boolean, + config: ProblemConfig, + acMsg?: string, + html?: boolean, + + difficulty?: number, + difficultyAlgo?: number, + difficultyAdmin?: number, + difficultySetting?: any, + } } - +export type { Pdoc } from './model/problem'; export type Pdict = NumericDictionary; export interface StatusDoc { diff --git a/packages/hydrooj/src/model/problem.ts b/packages/hydrooj/src/model/problem.ts index 9afa1709..a6f91ebe 100644 --- a/packages/hydrooj/src/model/problem.ts +++ b/packages/hydrooj/src/model/problem.ts @@ -5,13 +5,57 @@ import { STATUS } from './builtin'; import * as file from './file'; import * as document from './document'; import * as domain from './domain'; -import { - Pdoc, Pdict, ProblemDataSource, ProblemStatusDoc, -} from '../interface'; +import { ProblemStatusDoc, ProblemDataSource, Pdict } from '../interface'; import { NumberKeys, Projection } from '../typeutils'; import { ProblemNotFoundError } from '../error'; import * as testdataConfig from '../lib/testdataConfig'; +export interface Pdoc { + _id: ObjectID +} +export namespace Pdoc { + export type Field = keyof Pdoc; + export const fields: Field[] = []; + type Getter = (docId?: number, pid?: string) => Partial + const getters: Getter[] = []; + export function extend(getter: Getter) { + getters.push(getter); + fields.push(...Object.keys(getter(0, '0')) as any); + } + + extend((docId, pid) => ({ + _id: new ObjectID(), + domainId: 'system', + docType: document.TYPE_PROBLEM, + docId: docId || -1, + pid: pid || docId.toString(), + owner: 1, + title: '*', + content: '', + html: false, + nSubmit: 0, + nAccept: 0, + tag: [], + category: [], + data: null, + hidden: true, + config: {}, + acMsg: '', + difficulty: 0, + difficultyAlgo: 0, + difficultyAdmin: 0, + difficultySetting: null, + })); + + export function create(docId?: number, pid?: string) { + const result = {} as Pdoc; + for (const getter of getters) { + Object.assign(result, getter(docId, pid)); + } + return result; + } +} + export const SETTING_DIFFICULTY_ALGORITHM = 0; export const SETTING_DIFFICULTY_ADMIN = 1; export const SETTING_DIFFICULTY_AVERAGE = 2; @@ -22,34 +66,13 @@ export const SETTING_DIFFICULTY_RANGE = [ [SETTING_DIFFICULTY_AVERAGE, 'Use average of above'], ]; -export const pdocHidden: Pdoc = { - _id: new ObjectID(), - domainId: 'system', - docType: document.TYPE_PROBLEM, - docId: -1, - pid: '', - owner: 1, - title: '*', - content: '', - html: false, - nSubmit: 0, - nAccept: 0, - difficulty: 0, - tag: [], - category: [], - data: null, - hidden: true, - config: {}, - acMsg: '', -}; - -export const PROJECTION_LIST: Projection = [ +export const PROJECTION_LIST: Pdoc.Field[] = [ '_id', 'domainId', 'docType', 'docId', 'pid', 'owner', 'title', 'nSubmit', 'nAccept', 'difficulty', 'tag', 'category', 'hidden', ]; -export const PROJECTION_PUBLIC: Projection = [ +export const PROJECTION_PUBLIC: Pdoc.Field[] = [ ...PROJECTION_LIST, 'content', 'html', 'data', 'config', 'acMsg', ]; @@ -133,7 +156,7 @@ export async function getList( for (const pid of pids) { if (!(r[pid] || l[pid])) { if (doThrow) throw new ProblemNotFoundError(domainId, pid); - else r[pid] = pdocHidden; + else r[pid] = Pdoc.create(undefined, pid.toString()); } } } @@ -173,6 +196,8 @@ export async function setTestdata(domainId: string, _id: number, filePath: strin } global.Hydro.model.problem = { + Pdoc, + PROJECTION_LIST, PROJECTION_PUBLIC, @@ -181,7 +206,6 @@ global.Hydro.model.problem = { SETTING_DIFFICULTY_AVERAGE, SETTING_DIFFICULTY_RANGE, - pdocHidden, add, inc, get,