workspace: update eslint rule (#1027)

This commit is contained in:
undefined authored and GitHub committed 2025-08-06 18:51:25 +01:00
1 parent 05c3b8f2bd
commit cee3c00ddb
150 files changed
+1069 -1043

No files matched your search

+5 -6
View File
@@ -11,20 +11,20 @@ const REDIRECT = Symbol.for('hydro.api.response.redirect');
type MaybePromise<T> = T | Promise<T>;
export type ApiType = 'Query' | 'Mutation' | 'Subscription';
export type ApiCall<Type extends ApiType, Arg, Res, Progress = never> = {
export interface ApiCall<Type extends ApiType, Arg, Res, Progress = never> {
readonly type: Type;
readonly input: Schema<Arg>;
readonly func: (Type extends 'Subscription'
? (context: any, args: Arg, emit: (payload: Res) => void) => (() => MaybePromise<void>)
: (context: any, args: Arg) => MaybePromise<Res | AsyncGenerator<Progress, Res, never>>);
readonly hooks: ApiCall<'Query', Arg, void>[];
};
}
export const _get = <Type extends ApiType>(type: Type) => <Arg, Res, Progress>(
schema: Schema<Arg>,
func: ApiCall<Type, Arg, Res, Progress>['func'],
hooks: ApiCall<'Query', Arg, void, never>[] = [],
): ApiCall<Type, Arg, Res, Progress> => ({ input: schema, func, hooks, type } as const); // eslint-disable-line
): ApiCall<Type, Arg, Res, Progress> => ({ input: schema, func, hooks, type } as const);
export const Query = _get('Query');
export const Mutation = _get('Mutation');
@@ -57,7 +57,7 @@ export interface Apis {
builtin: {
'query.batch': ApiCall<'Query', { op: string, args: any }[], { [key: string]: any }>;
'mutation.batch': ApiCall<'Mutation', { op: string, args: any }[], { [key: string]: any }>;
}
};
test: typeof TestApis;
}
export type FlattenedApis = Apis[keyof Apis];
@@ -68,8 +68,7 @@ type MKeyOf<T> = T extends any ? keyof T : never;
type MId<T> = { [K in MKeyOf<T>]: T[K] } & {};
type ProjectionSchema<T> = T extends Array<infer U>
? ProjectionSchema<U>
: | { [K in keyof T]?: ProjectionSchemaId | ProjectionSchema<T[K]> }
| Record<keyof any, ProjectionSchemaId | object>;
: { [K in keyof T]?: ProjectionSchemaId | ProjectionSchema<T[K]> } | Record<keyof any, ProjectionSchemaId | object>;
type AsKeys<T> = T extends Array<infer U extends string> ? Record<U, 1> : T;
type Projection<T, S> = S extends ProjectionSchemaId
? T : T extends Array<infer U> ? Array<MId<Projection<U, S>>> : {
+5 -5
View File
@@ -8,11 +8,11 @@ type MethodDecorator = (target: any, funcName: string, obj: any) => any;
type ClassDecorator = <T extends new (...args: any[]) => any>(Class: T) => T extends new (...args: infer R) => infer S
? new (...args: R) => S : never;
export interface ParamOption<T> {
name: string,
source: 'all' | 'get' | 'post' | 'route',
isOptional?: boolean | 'convert',
convert?: Converter<T>,
validate?: Validator,
name: string;
source: 'all' | 'get' | 'post' | 'route';
isOptional?: boolean | 'convert';
convert?: Converter<T>;
validate?: Validator;
}
const kSchema = Symbol.for('schemastery');
+2 -2
View File
@@ -1,5 +1,5 @@
interface IHydroError {
new(...args: any[]): HydroError
new(...args: any[]): HydroError;
}
export class HydroError extends Error {
@@ -32,7 +32,7 @@ const Err = (name: string, Class: IHydroError, ...info: Array<(() => string) | s
msg = item;
}
}
// eslint-disable-next-line @typescript-eslint/no-shadow
// eslint-disable-next-line ts/no-shadow
return class HydroError extends Class {
name = name;
constructor(...args: any[]) {
+7 -7
View File
@@ -1,8 +1,8 @@
export * from './server';
export { default as serializer } from './serializer';
export * from './decorators';
export * from './validator';
export * from './error';
export * from './router';
export * from './interface';
export * from './api';
export * from './decorators';
export * from './error';
export * from './interface';
export * from './router';
export { default as serializer } from './serializer';
export * from './server';
export * from './validator';
+14 -14
View File
@@ -3,7 +3,7 @@ import type { ApiHandler } from './api';
import type { ConnectionHandler, Handler, NotFoundHandler } from './server';
export interface KnownHandlers {
'NotFound': NotFoundHandler;
NotFound: NotFoundHandler;
}
type MapHandlerEvents<N extends string, H extends Handler<any>> =
@@ -24,19 +24,19 @@ export type Methods = 'get' | 'post' | 'put' | 'delete' | 'patch';
export type HookWithMethod = Exclude<HookType, 'before-operation'>;
export interface ServerEvents<C extends Context> extends KnownHandlerEvents, HandlerEvents<C> {
'handler/create': (thisArg: Handler<C> | ConnectionHandler<C>, type: 'ws' | 'http') => VoidReturn
'handler/create/http': (thisArg: Handler<C>) => VoidReturn
'handler/create/ws': (thisArg: ConnectionHandler<C>) => VoidReturn
'handler/init': (thisArg: Handler<C>) => VoidReturn
'handler/error': (thisArg: Handler<C> | ConnectionHandler<C>, e: Error) => VoidReturn
'handler/api/before': (thisArg: ApiHandler<C>) => VoidReturn
'api/before': (args: any) => VoidReturn
[k: `handler/${HookType}/${string}`]: (thisArg: any) => VoidReturn
[k: `handler/${HookWithMethod}/${string}/${Methods}`]: (thisArg: any) => VoidReturn
[k: `handler/register/${string}`]: (HandlerClass: new (...args: any[]) => any) => VoidReturn
[k: `handler/error/${string}`]: (thisArg: Handler<C>, e: Error) => VoidReturn
[k: `handler/api/before/${string}`]: (thisArg: ApiHandler<C>) => VoidReturn
[k: `api/before/${string}`]: (args: any) => VoidReturn
'handler/create': (thisArg: Handler<C> | ConnectionHandler<C>, type: 'ws' | 'http') => VoidReturn;
'handler/create/http': (thisArg: Handler<C>) => VoidReturn;
'handler/create/ws': (thisArg: ConnectionHandler<C>) => VoidReturn;
'handler/init': (thisArg: Handler<C>) => VoidReturn;
'handler/error': (thisArg: Handler<C> | ConnectionHandler<C>, e: Error) => VoidReturn;
'handler/api/before': (thisArg: ApiHandler<C>) => VoidReturn;
'api/before': (args: any) => VoidReturn;
[k: `handler/${HookType}/${string}`]: (thisArg: any) => VoidReturn;
[k: `handler/${HookWithMethod}/${string}/${Methods}`]: (thisArg: any) => VoidReturn;
[k: `handler/register/${string}`]: (HandlerClass: new (...args: any[]) => any) => VoidReturn;
[k: `handler/error/${string}`]: (thisArg: Handler<C>, e: Error) => VoidReturn;
[k: `handler/api/before/${string}`]: (thisArg: ApiHandler<C>) => VoidReturn;
[k: `api/before/${string}`]: (args: any) => VoidReturn;
}
declare module 'cordis' {
+1 -1
View File
@@ -10,7 +10,7 @@
"dependencies": {
"@hydrooj/utils": "workspace:^",
"emoji-regex": "^10.4.0",
"fs-extra": "^11.3.0",
"fs-extra": "^11.3.1",
"koa": "^3.0.1",
"koa-body": "^6.0.1",
"koa-compress": "^5.1.1",
+14 -11
View File
@@ -1,3 +1,4 @@
/* eslint-disable ts/no-unsafe-declaration-merging */
import http from 'http';
import { tmpdir } from 'os';
import { join } from 'path';
@@ -77,7 +78,8 @@ export interface HydroResponse {
type: string;
status: number;
template?: string;
/** If set, and pjax content was request from client,
/**
* If set, and pjax content was request from client,
* The template will be used for rendering.
*/
pjax?: string;
@@ -87,14 +89,14 @@ export interface HydroResponse {
attachment: (name: string, stream?: any) => void;
addHeader: (name: string, value: string) => void;
}
type HydroContext = {
interface HydroContext {
request: HydroRequest;
response: HydroResponse;
args: Record<string, any>;
UiContext: Record<string, any>;
domain: { _id: string };
user: { _id: number };
};
}
export type KoaContext = Koa.Context & {
HydroContext: HydroContext;
handler: any;
@@ -103,14 +105,14 @@ export type KoaContext = Koa.Context & {
holdFiles: (string | File)[];
};
export type TextRenderer = {
export interface TextRenderer {
output: 'html' | 'json' | 'text';
render: (name: string, args: Record<string, any>, context: Record<string, any>) => string | Promise<string>;
};
export type BinaryRenderer = {
}
export interface BinaryRenderer {
output: 'binary';
render: (name: string, args: Record<string, any>, context: Record<string, any>) => Buffer | Promise<Buffer>;
};
}
export type Renderer = (BinaryRenderer | TextRenderer) & {
name: string;
accept: readonly string[];
@@ -139,7 +141,7 @@ export interface UserModel {
_id: number;
}
export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars
export interface HandlerCommon<C> { } // eslint-disable-line ts/no-unused-vars
export class HandlerCommon<C> {
static [kHandler]: string | boolean = 'HandlerCommon';
session: Record<string, any>;
@@ -507,7 +509,8 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
this.activeHandlers.set(h, { start: Date.now(), name });
try {
const operation = (method === 'post' && ctx.request.body?.operation)
? `_${ctx.request.body.operation}`.replace(/_([a-z])/gm, (s) => s[1].toUpperCase())
// eslint-disable-next-line regexp/no-unused-capturing-group
? `_${ctx.request.body.operation}`.replace(/_([a-z])/g, (s) => s[1].toUpperCase())
: '';
// FIXME: should pass type check
@@ -777,7 +780,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
this.ctx.on(`handler/register/${name}`, callback as any);
}
// eslint-disable-next-line @typescript-eslint/naming-convention
// eslint-disable-next-line ts/naming-convention
public Route(name: string, path: string, RouteHandler: typeof Handler<C>, ...permPrivChecker) {
// if (name === 'contest_scoreboard') {
// console.log('+++', this.ctx);
@@ -786,7 +789,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
return this.register('route', name, path, RouteHandler, ...permPrivChecker);
}
// eslint-disable-next-line @typescript-eslint/naming-convention
// eslint-disable-next-line ts/naming-convention
public Connection(name: string, path: string, RouteHandler: typeof ConnectionHandler<C>, ...permPrivChecker) {
return this.register('conn', name, path, RouteHandler, ...permPrivChecker);
}
+8 -8
View File
@@ -90,23 +90,23 @@ const saslprepString = <T = string>(regex?: RegExp, cb?: (i: string) => boolean,
export const Types = {
Content: [(v) => v.toString().trim(), (v) => v?.toString()?.trim() && v.toString().trim().length < 65536],
Key: saslprepString(/^[a-zA-Z0-9-_]{1,255}$/),
Key: saslprepString(/^[\w-]{1,255}$/),
/** @deprecated */
Name: saslprepString(/^.{1,255}$/),
Filename: saslprepString(/^[^\\/?#~!|*]{1,255}$/, (i) => sanitize(i) === i),
UidOrName: saslprepString(/^(.{3,31}|[\u4e00-\u9fa5]{2}|-?[0-9]+)$/),
Username: saslprepString(/^(.{3,31}|[\u4e00-\u9fa5]{2})$/),
UidOrName: saslprepString(/^(?:.{3,31}|[\u4E00-\u9FA5]{2}|-?[0-9]+)$/),
Username: saslprepString(/^(?:.{3,31}|[\u4E00-\u9FA5]{2})$/),
Password: basicString(/^.{6,255}$/),
ProblemId: saslprepString(/^([a-zA-Z0-9]{1,10}-)?[a-zA-Z0-9]+$/i, () => true, (s) => (Number.isSafeInteger(+s) ? +s : s)),
Email: saslprepString(/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+$/i),
DomainId: saslprepString(/^[a-zA-Z][a-zA-Z0-9_]{3,31}$/),
Role: saslprepString(/^[_0-9A-Za-z\u4e00-\u9fa5]{1,31}$/i),
ProblemId: saslprepString(/^(?:[a-z0-9]{1,10}-)?[a-z0-9]+$/i, () => true, (s) => (Number.isSafeInteger(+s) ? +s : s)),
Email: saslprepString(/^[\w.+-]+@[a-z0-9-]+(?:\.[a-z0-9-]+)+$/i),
DomainId: saslprepString(/^[a-zA-Z]\w{3,31}$/),
Role: saslprepString(/^[\w\u4E00-\u9FA5]{1,31}$/),
Title: basicString(/^.{1,64}$/, (i) => !!i.trim()),
ShortString: basicString(/^.{1,255}$/),
String: basicString(),
Int: [(v) => +v, (v) => /^[+-]?[0-9]+$/.test(v.toString().trim()) && Number.isSafeInteger(+v)],
UnsignedInt: [(v) => +v, (v) => /^(-0|\+?[0-9]+)$/.test(v.toString().trim()) && Number.isSafeInteger(+v)],
UnsignedInt: [(v) => +v, (v) => /^(?:-0|\+?[0-9]+)$/.test(v.toString().trim()) && Number.isSafeInteger(+v)],
PositiveInt: [(v) => +v, (v) => /^\+?[1-9][0-9]*$/.test(v.toString().trim()) && Number.isSafeInteger(+v)],
Float: [(v) => +v, (v) => Number.isFinite(+v)],