From 79ec4d300c857830c25da27bb43f40f27eb33cba Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 24 Aug 2021 00:01:30 +0800 Subject: [PATCH] core: problem api --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/api.ts | 12 +++++++--- packages/hydrooj/src/handler/problem.ts | 31 +++++++++++++++++++++++++ packages/ui-default/package.json | 2 +- packages/ui-default/pages/api.page.styl | 10 +++++++- 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 29464258c..0e96717dc 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.33.5", + "version": "2.33.6", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/api.ts b/packages/hydrooj/src/handler/api.ts index 036258348..3f421699a 100644 --- a/packages/hydrooj/src/handler/api.ts +++ b/packages/hydrooj/src/handler/api.ts @@ -4,6 +4,7 @@ import { Handler, Route } from '../service/server'; import * as bus from '../service/bus'; const types: Record> = {}; +const unions: Record = {}; const descriptions: Record> = {}; const handlers: Record> = {}; let root: Record = {}; @@ -30,18 +31,23 @@ export function registerResolver(typeName: string, key: string, value: string, f bus.emit('api/update'); } +export function registerUnion(typeName: string, ...unionTypes: string[]) { + unions[typeName] = unionTypes.join(' | '); + bus.emit('api/update'); +} + function setDescription(desc: string) { if (desc.includes('\n')) return ['"""', desc, '"""'].join('\n'); return JSON.stringify(desc); } function buildSchemaStr() { - let res = `${typeDefs.join('\n')}\n`; + let res = `${Object.keys(unions).map((i) => `union ${i} = ${unions[i]}`)}\n${typeDefs.join('\n')}\n`; for (const key in types) { - if (descriptions[key]._description) res += `${setDescription(descriptions[key]._description)}\n`; + if (descriptions[key]?._description) res += `${setDescription(descriptions[key]._description)}\n`; res += `type ${key}{\n`; for (const k in types[key]) { - if (descriptions[key][k]) res += ` ${setDescription(descriptions[key][k])}\n`; + if (descriptions[key]?.[k]) res += ` ${setDescription(descriptions[key][k])}\n`; res += ` ${k}: ${types[key][k]}\n`; } res += '}\n'; diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index b848a118a..a99d5383a 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -3,6 +3,7 @@ import { FilterQuery, ObjectID } from 'mongodb'; import AdmZip from 'adm-zip'; import { sortFiles } from '@hydrooj/utils/lib/utils'; import { lookup } from 'mime-types'; +import { registerResolver, registerValue } from './api'; import { NoProblemError, PermissionError, ValidationError, SolutionNotFoundError, ProblemNotFoundError, BadRequestError, @@ -32,6 +33,36 @@ import { export const parseCategory = (value: string) => flatten(value.replace(/,/g, ',').split(',')).map((e) => e.trim()); export const parsePid = (value: string) => (isSafeInteger(value) ? +value : value); +registerValue('FileInfo', [ + ['_id', 'String!'], + ['name', 'String!'], + ['size', 'Int'], + ['lastModified', 'Date'], +]); +registerValue('Problem', [ + ['_id', 'ObjectID!'], + ['owner', 'Int!'], + ['domainId', 'String!'], + ['docId', 'Int!'], + ['docType', 'Int!'], + ['title', 'String!'], + ['content', 'String!'], + ['config', 'String!'], + ['data', '[FileInfo]'], + ['additional_file', '[FileInfo]'], + ['nSubmit', 'Int'], + ['nAccept', 'Int'], + ['difficulty', 'Int'], + ['tag', '[String]'], + ['hidden', 'Boolean'], +]); +registerResolver('Query', 'problem(id: Int, pid: String)', 'Problem', async (arg, ctx) => { + const pdoc = await problem.get(ctx.domainId, arg.pid || arg.id); + if (!pdoc) return null; + if (pdoc.hidden && !ctx.user.own(pdoc)) ctx.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN); + return pdoc; +}); + export class ProblemHandler extends Handler { async cleanup() { if (this.response.template === 'problem_main.html' && this.request.json) { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 7f061f9c5..779b79448 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.18.1", + "version": "4.18.2", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/api.page.styl b/packages/ui-default/pages/api.page.styl index f5729688d..7ec42c949 100644 --- a/packages/ui-default/pages/api.page.styl +++ b/packages/ui-default/pages/api.page.styl @@ -1,2 +1,10 @@ .graphiql-container .doc-explorer-title, .graphiql-container .history-title - padding: 2px !important \ No newline at end of file + overflow: hidden; + padding: 5px 40px 0px 0px !important + +.graphiql-container .docExplorerWrap + font-family: "Source Code Pro", "Consolas" !important + +.graphiql-container .doc-explorer-back + overflow: hidden; + padding: 8px 20px 0px 20px !important