diff --git a/framework/framework/server.ts b/framework/framework/server.ts index c24ccfc76..b6fcbb561 100644 --- a/framework/framework/server.ts +++ b/framework/framework/server.ts @@ -23,7 +23,7 @@ import serializer from './serializer'; export { WebSocket, WebSocketServer } from 'ws'; -const kHandler = Symbol.for('hydro.handler'); +export const kHandler = Symbol.for('hydro.handler'); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent export function encodeRFC5987ValueChars(str: string) { @@ -111,7 +111,7 @@ export interface UserModel { export interface HandlerCommon { } export class HandlerCommon { - static [kHandler] = true; + static [kHandler]: string | boolean = true; session: Record; args: Record; request: HydroRequest; @@ -459,6 +459,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); const h = new HandlerClass(ctx, this.ctx); ctx.handler = h; const method = ctx.method.toLowerCase(); + const name = (typeof HandlerClass[kHandler] === 'string' ? HandlerClass[kHandler] : HandlerClass.name).replace(/Handler$/, ''); try { const operation = (method === 'post' && ctx.request.body?.operation) ? `_${ctx.request.body.operation}`.replace(/_([a-z])/gm, (s) => s[1].toUpperCase()) @@ -479,7 +480,6 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); throw new MethodNotAllowedError(method); } - const name = HandlerClass.name.replace(/Handler$/, ''); const steps = [ 'log/__init', 'init', 'handler/init', `handler/before-prepare/${name}#${method}`, `handler/before-prepare/${name}`, 'handler/before-prepare', @@ -516,7 +516,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); } } catch (e) { try { - await this.ctx.serial(`handler/error/${HandlerClass.name.replace(/Handler$/, '')}`, h, e); + await this.ctx.serial(`handler/error/${name}`, h, e); await this.ctx.serial('handler/error', h, e); await h.onerror(e); } catch (err) { @@ -596,7 +596,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); private register(type: 'route' | 'conn', routeName: string, path: string, HandlerClass: any, ...permPrivChecker) { if (!HandlerClass?.[kHandler] || !isClass(HandlerClass)) throw new Error('Invalid registration.'); - const name = HandlerClass.name; + const name = typeof HandlerClass[kHandler] === 'string' ? HandlerClass[kHandler] : HandlerClass.name; if (this.registrationCount[name] && this.registry[name] !== HandlerClass) { logger.warn('Route with name %s already exists.', name); } diff --git a/packages/hydrooj/src/service/db.ts b/packages/hydrooj/src/service/db.ts index 6dee3f3fd..7693aa0ff 100644 --- a/packages/hydrooj/src/service/db.ts +++ b/packages/hydrooj/src/service/db.ts @@ -124,12 +124,12 @@ class MongoService { return [pageDocs, numPages, count]; } - async ranked>(cursor: FindCursor, equ: (a: T, b: T) => boolean): Promise<[number, T][]> { + async ranked>(cursor: T[] | FindCursor, equ: (a: T, b: T) => boolean): Promise<[number, T][]> { let last = null; let r = 0; let count = 0; const results = []; - const docs = await cursor.toArray(); + const docs = cursor instanceof Array ? cursor : await cursor.toArray(); for (const doc of docs) { if ((doc as any).unrank) { results.push([0, doc]); diff --git a/packages/ui-default/templates/contest_manage.html b/packages/ui-default/templates/contest_manage.html index 829a7bad9..a7af2a9a9 100644 --- a/packages/ui-default/templates/contest_manage.html +++ b/packages/ui-default/templates/contest_manage.html @@ -2,6 +2,7 @@ {% import "components/contest.html" as contest with context %} {% import "components/problem.html" as problem with context %} {% block content %} +{{ set(UiContext, 'tdoc', tdoc) }}