workspace: upgrade to cordis@4.0.0-beta.1, fix #975

This commit is contained in:
undefined committed 2025-04-11 21:21:47 +08:00
1 parent 5d5f6c69d7
commit bf51bd30c7
34 files changed
+87 -88

No files matched your search

+1
View File
@@ -159,6 +159,7 @@ Hydro 用户群:1085853538
- core: 移除 setting.yaml - core: 移除 setting.yaml
- core: oauth: 改为使用 ctx.oauth.provide() 注册 - core: oauth: 改为使用 ctx.oauth.provide() 注册
- framework: 移除 ready 与 dispose 事件 (使用 ctx.effect 代替) - framework: 移除 ready 与 dispose 事件 (使用 ctx.effect 代替)
- core: 最低要求 node 22
## Hydro 4.19.0 / UI 4.57.0 ## Hydro 4.19.0 / UI 4.57.0
+4 -4
View File
@@ -4,12 +4,12 @@
"license": "MIT", "license": "MIT",
"main": "base.mjs", "main": "base.mjs",
"dependencies": { "dependencies": {
"@eslint-react/eslint-plugin": "^1.40.1", "@eslint-react/eslint-plugin": "^1.45.0",
"@eslint/compat": "^1.2.8", "@eslint/compat": "^1.2.8",
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",
"@stylistic/eslint-plugin": "^4.2.0", "@stylistic/eslint-plugin": "^4.2.0",
"@typescript-eslint/eslint-plugin": "^8.29.0", "@typescript-eslint/eslint-plugin": "^8.29.1",
"@typescript-eslint/parser": "^8.29.0", "@typescript-eslint/parser": "^8.29.1",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-plugin-de-morgan": "^1.2.1", "eslint-plugin-de-morgan": "^1.2.1",
"eslint-plugin-github": "^6.0.0", "eslint-plugin-github": "^6.0.0",
@@ -24,6 +24,6 @@
"eslint": ">= 9" "eslint": ">= 9"
}, },
"optionalDependencies": { "optionalDependencies": {
"typescript": "^5.8.2" "typescript": "^5.8.3"
} }
} }
+1 -1
View File
@@ -1,4 +1,4 @@
import { Context } from '@cordisjs/core'; import { Context } from 'cordis';
import { ValidationError } from './error'; import { ValidationError } from './error';
import type { Handler } from './server'; import type { Handler } from './server';
import { Converter, Type, Validator } from './validator'; import { Converter, Type, Validator } from './validator';
+1 -1
View File
@@ -33,7 +33,7 @@ export interface ServerEvents<C> extends KnownHandlerEvents, HandlerEvents<C> {
[k: `handler/error/${string}`]: (thisArg: Handler<C>, e: Error) => VoidReturn [k: `handler/error/${string}`]: (thisArg: Handler<C>, e: Error) => VoidReturn
} }
declare module '@cordisjs/core' { declare module 'cordis' {
interface Events<C> extends ServerEvents<C> { interface Events<C> extends ServerEvents<C> {
} }
} }
+2 -2
View File
@@ -4,13 +4,13 @@
"main": "index.ts", "main": "index.ts",
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"@cordisjs/core": "*" "cordis": "*"
}, },
"dependencies": { "dependencies": {
"@hydrooj/utils": "workspace:^", "@hydrooj/utils": "workspace:^",
"emoji-regex": "^10.4.0", "emoji-regex": "^10.4.0",
"fs-extra": "^11.3.0", "fs-extra": "^11.3.0",
"koa": "^2.16.0", "koa": "^2.16.1",
"koa-body": "^6.0.1", "koa-body": "^6.0.1",
"koa-compress": "^5.1.1", "koa-compress": "^5.1.1",
"koa-router": "^13.0.1", "koa-router": "^13.0.1",
+3 -3
View File
@@ -2,7 +2,7 @@ import http from 'http';
import { tmpdir } from 'os'; import { tmpdir } from 'os';
import { join } from 'path'; import { join } from 'path';
import { PassThrough } from 'stream'; import { PassThrough } from 'stream';
import { Context as CordisContext, Service } from '@cordisjs/core'; import { Context as CordisContext, Service } from 'cordis';
import type { Files } from 'formidable'; import type { Files } from 'formidable';
import fs from 'fs-extra'; import fs from 'fs-extra';
import Koa from 'koa'; import Koa from 'koa';
@@ -625,7 +625,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
for (const { name, target } of h.__subscribe || []) sub.ctx.on(name, target.bind(h)); for (const { name, target } of h.__subscribe || []) sub.ctx.on(name, target.bind(h));
if (layer) { if (layer) {
let lastHeartbeat = Date.now(); let lastHeartbeat = Date.now();
sub.ctx.setInterval(() => { sub.ctx.interval(() => {
if (Date.now() - lastHeartbeat > 80000) { if (Date.now() - lastHeartbeat > 80000) {
clean(); clean();
conn.terminate(); conn.terminate();
@@ -841,7 +841,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
} }
} }
declare module '@cordisjs/core' { declare module 'cordis' {
interface Context { interface Context {
server: WebService<this>; server: WebService<this>;
Route: WebService<this>['Route']; Route: WebService<this>['Route'];
+1 -1
View File
@@ -7,7 +7,7 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"esbuild": "0.25.0", "esbuild": "0.25.2",
"source-map-support": "^0.5.21" "source-map-support": "^0.5.21"
}, },
"devDependencies": { "devDependencies": {
+5 -5
View File
@@ -42,9 +42,9 @@
"chai": "^5.2.0", "chai": "^5.2.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cross-spawn": "^7.0.6", "cross-spawn": "^7.0.6",
"esbuild": "0.25.0", "esbuild": "0.25.2",
"eslint": "^9.23.0", "eslint": "^9.24.0",
"eslint-import-resolver-typescript": "^4.3.1", "eslint-import-resolver-typescript": "^4.3.2",
"eslint-import-resolver-webpack": "^0.13.10", "eslint-import-resolver-webpack": "^0.13.10",
"fs-extra": "^11.3.0", "fs-extra": "^11.3.0",
"globals": "^16.0.0", "globals": "^16.0.0",
@@ -53,13 +53,13 @@
"mongodb-memory-server": "10.1.4", "mongodb-memory-server": "10.1.4",
"nyc": "^17.1.0", "nyc": "^17.1.0",
"ora": "^8.2.0", "ora": "^8.2.0",
"oxlint": "^0.16.4", "oxlint": "^0.16.5",
"package-json": "^10.0.1", "package-json": "^10.0.1",
"semver": "^7.7.1", "semver": "^7.7.1",
"simple-git": "^3.27.0", "simple-git": "^3.27.0",
"supertest": "^7.1.0", "supertest": "^7.1.0",
"supports-hyperlinks": "^3.2.0", "supports-hyperlinks": "^3.2.0",
"typescript": "5.8.2", "typescript": "5.8.3",
"wtfnode": "^0.10.0" "wtfnode": "^0.10.0"
} }
} }
+1 -1
View File
@@ -15,6 +15,6 @@
"@types/diff": "^7.0.2", "@types/diff": "^7.0.2",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.16", "@types/lodash": "^4.17.16",
"sass": "^1.86.1" "sass": "^1.86.3"
} }
} }
+2 -3
View File
@@ -16,18 +16,17 @@
"@aws-sdk/lib-storage": "3.726.1", "@aws-sdk/lib-storage": "3.726.1",
"@aws-sdk/s3-presigned-post": "3.726.1", "@aws-sdk/s3-presigned-post": "3.726.1",
"@aws-sdk/s3-request-presigner": "3.726.1", "@aws-sdk/s3-request-presigner": "3.726.1",
"@cordisjs/core": "4.0.0-alpha.8",
"@cordisjs/logger": "1.0.0-alpha.5", "@cordisjs/logger": "1.0.0-alpha.5",
"@cordisjs/plugin-timer": "1.0.0-alpha.0", "@cordisjs/plugin-timer": "1.1.1",
"@graphql-tools/schema": "^10.0.23", "@graphql-tools/schema": "^10.0.23",
"@hydrooj/common": "workspace:^", "@hydrooj/common": "workspace:^",
"@hydrooj/framework": "workspace:^", "@hydrooj/framework": "workspace:^",
"@hydrooj/utils": "workspace:^", "@hydrooj/utils": "workspace:^",
"@simplewebauthn/server": "13.1.1", "@simplewebauthn/server": "13.1.1",
"@undefined-moe/require-resolve-hook": "^1.1.0", "@undefined-moe/require-resolve-hook": "^1.1.0",
"@yarnpkg/libzip": "^3.1.1",
"adm-zip": "0.5.16", "adm-zip": "0.5.16",
"cac": "^6.7.14", "cac": "^6.7.14",
"cordis": "4.0.0-beta.1",
"csv-stringify": "^6.5.2", "csv-stringify": "^6.5.2",
"emoji-regex": "^10.4.0", "emoji-regex": "^10.4.0",
"emojis-list": "2.1.0", "emojis-list": "2.1.0",
+3 -13
View File
@@ -1,4 +1,4 @@
import * as cordis from '@cordisjs/core'; import * as cordis from 'cordis';
import LoggerService from '@cordisjs/logger'; import LoggerService from '@cordisjs/logger';
import { TimerService } from '@cordisjs/plugin-timer'; import { TimerService } from '@cordisjs/plugin-timer';
import Schema from 'schemastery'; import Schema from 'schemastery';
@@ -23,9 +23,9 @@ function provideModule<T extends keyof ModuleInterfaces>(type: T, id: string, mo
return () => delete global.Hydro.module[type][id]; return () => delete global.Hydro.module[type][id];
} }
export type EffectScope = cordis.EffectScope<Context>; export type Fiber = cordis.Fiber<Context>;
export { Disposable, Plugin, ScopeStatus } from '@cordisjs/core'; export { Disposable, Plugin, FiberState } from 'cordis';
export interface Context extends cordis.Context { export interface Context extends cordis.Context {
[Context.events]: EventMap & cordis.Events<Context>; [Context.events]: EventMap & cordis.Events<Context>;
@@ -74,13 +74,3 @@ export class Context extends cordis.Context {
this.plugin(LoggerService); this.plugin(LoggerService);
} }
} }
const old = cordis.Registry.prototype.inject;
// cordis.Registry.prototype.using = old;
cordis.Registry.prototype.inject = function wrapper(...args) {
if (typeof args[0] === 'string') {
console.warn('old functionality of ctx.inject is deprecated. please use ctx.injectUI instead.');
return T(inject).call(this, ...args as any) as any;
}
return old.call(this, ...args);
};
+1 -1
View File
@@ -142,7 +142,7 @@ class DomainUserHandler extends ManageHandler {
user: 1, user: 1,
role: 1, role: 1,
join: 1, join: 1,
displayName: this.user.hasPerm(PERM.PERM_VIEW_DISPLAYNAME), ...(this.user.hasPerm(PERM.PERM_VIEW_DISPLAYNAME) ? { displayName: 1 } : {}),
}, },
}, },
]).toArray(), ]).toArray(),
+1 -5
View File
@@ -13,7 +13,7 @@ declare module '../service/bus' {
} }
} }
class I18nService extends Service { export class I18nService extends Service {
constructor(ctx: Context) { constructor(ctx: Context) {
super(ctx, 'i18n'); super(ctx, 'i18n');
this.translate = this.translate.bind(this); this.translate = this.translate.bind(this);
@@ -55,10 +55,6 @@ class I18nService extends Service {
} }
export const name = 'i18n'; export const name = 'i18n';
export function apply(ctx: Context) {
ctx.provide('i18n', undefined, true);
ctx.i18n = new I18nService(ctx);
}
function collect(lang: string) { function collect(lang: string) {
const s = translations[lang]; const s = translations[lang];
+1 -3
View File
@@ -1,4 +1,3 @@
import { ZipFS, ZipOpenFS } from '@yarnpkg/libzip';
import AdmZip from 'adm-zip'; import AdmZip from 'adm-zip';
import _ from 'lodash'; import _ from 'lodash';
import { ObjectId as ObjectID } from 'mongodb'; import { ObjectId as ObjectID } from 'mongodb';
@@ -10,9 +9,8 @@ export { WebSocket, WebSocketServer } from '@hydrooj/framework';
export * from './utils'; export * from './utils';
export * from './interface'; export * from './interface';
export * from './typeutils'; export * from './typeutils';
export * as LibZip from '@yarnpkg/libzip';
export { export {
Schema, AdmZip, superagent, _, ObjectID, ZipFS, ZipOpenFS, Schema, AdmZip, superagent, _, ObjectID,
}; };
export const definePlugin = <T = never>(args: { export const definePlugin = <T = never>(args: {
using?: keyof Context[]; using?: keyof Context[];
+8 -8
View File
@@ -9,11 +9,11 @@ import child from 'child_process';
import './utils'; import './utils';
import cac from 'cac'; import cac from 'cac';
import './ui'; import './ui';
import * as I18n from './lib/i18n'; import { I18nService } from './lib/i18n';
import { Logger } from './logger'; import { Logger } from './logger';
import { import {
Context, Service, ScopeStatus, EffectScope, Context, Service, FiberState, Fiber,
} from './context'; } from './context';
// eslint-disable-next-line import/no-duplicates // eslint-disable-next-line import/no-duplicates
import { sleep, unwrapExports } from './utils'; import { sleep, unwrapExports } from './utils';
@@ -45,7 +45,7 @@ if (process.env.NIX_PROFILES) {
} }
export class Loader extends Service { export class Loader extends Service {
public state: Record<string, EffectScope> = Object.create(null); public state: Record<string, Fiber> = Object.create(null);
public suspend = false; public suspend = false;
public cache: Record<string, string> = Object.create(null); public cache: Record<string, string> = Object.create(null);
// public warnings: Record<string, string> = Object.create(null); // public warnings: Record<string, string> = Object.create(null);
@@ -56,8 +56,8 @@ export class Loader extends Service {
super(ctx, 'loader'); super(ctx, 'loader');
ctx.on('app/started', () => { ctx.on('app/started', () => {
ctx.setInterval(async () => { ctx.interval(async () => {
const pending = Object.entries(this.state).filter((v) => v[1].status === ScopeStatus.PENDING); const pending = Object.entries(this.state).filter((v) => v[1].state === FiberState.PENDING);
if (pending.length) { if (pending.length) {
logger.warn('Plugins are still pending: %s', pending.map((v) => v[0]).join(', ')); logger.warn('Plugins are still pending: %s', pending.map((v) => v[0]).join(', '));
for (const [key, value] of pending) { for (const [key, value] of pending) {
@@ -65,7 +65,7 @@ export class Loader extends Service {
console.log(value); console.log(value);
} }
} }
const loading = Object.entries(this.state).filter((v) => v[1].status === ScopeStatus.LOADING); const loading = Object.entries(this.state).filter((v) => v[1].state === FiberState.LOADING);
if (loading.length) { if (loading.length) {
logger.warn('Plugins are still loading: %s', loading.map((v) => v[0]).join(', ')); logger.warn('Plugins are still loading: %s', loading.map((v) => v[0]).join(', '));
for (const [key, value] of loading) { for (const [key, value] of loading) {
@@ -73,7 +73,7 @@ export class Loader extends Service {
console.log(value); console.log(value);
} }
} }
const failed = Object.entries(this.state).filter((v) => v[1].status === ScopeStatus.FAILED); const failed = Object.entries(this.state).filter((v) => v[1].state === FiberState.FAILED);
if (failed.length) { if (failed.length) {
logger.warn('Plugins failed to load: %s', failed.map((v) => v[0]).join(', ')); logger.warn('Plugins failed to load: %s', failed.map((v) => v[0]).join(', '));
for (const [key, value] of failed) { for (const [key, value] of failed) {
@@ -143,7 +143,7 @@ export class Loader extends Service {
} }
} }
app.plugin(I18n); app.plugin(I18nService);
app.plugin(Loader); app.plugin(Loader);
async function preload() { async function preload() {
+2 -2
View File
@@ -1,6 +1,6 @@
/* eslint-disable max-len */ /* eslint-disable max-len */
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import * as cordis from '@cordisjs/core'; import * as cordis from 'cordis';
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import { Dictionary } from 'lodash'; import { Dictionary } from 'lodash';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
@@ -356,7 +356,7 @@ SystemSetting(
export const langs: Record<string, LangConfig> = {}; export const langs: Record<string, LangConfig> = {};
declare module '@cordisjs/core' { declare module 'cordis' {
interface Context { interface Context {
setting: SettingService; setting: SettingService;
} }
+1 -1
View File
@@ -1,7 +1,7 @@
// TODO check more // TODO check more
import os from 'os'; import os from 'os';
import { DisposableList } from '@cordisjs/core'; import { DisposableList } from 'cordis';
import { Context, Service } from '../context'; import { Context, Service } from '../context';
import * as system from '../model/system'; import * as system from '../model/system';
import db from './db'; import db from './db';
+1 -1
View File
@@ -62,7 +62,7 @@ export class MongoService extends Service {
yield () => { this.client.close(); }; yield () => { this.client.close(); };
this.db = this.client.db(url.database || 'hydro'); this.db = this.client.db(url.database || 'hydro');
await bus.parallel('database/connect', this.db); await bus.parallel('database/connect', this.db);
yield this.ctx.setInterval(() => this.fixExpireAfter(), Time.hour); yield this.ctx.interval(() => this.fixExpireAfter(), Time.hour);
} }
public collection<K extends keyof Collections>(c: K) { public collection<K extends keyof Collections>(c: K) {
+1 -1
View File
@@ -209,7 +209,7 @@ export default class HMR extends Service {
const reload = async (plugin: any, runtime?: Plugin.Runtime) => { const reload = async (plugin: any, runtime?: Plugin.Runtime) => {
if (!runtime) return; if (!runtime) return;
for (const oldFiber of runtime.scopes) { for (const oldFiber of runtime.fibers) {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await oldFiber.parent.plugin(plugin, oldFiber.config); await oldFiber.parent.plugin(plugin, oldFiber.config);
} }
+17 -1
View File
@@ -1,8 +1,11 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import cac from 'cac';
import { Logger } from '@hydrooj/utils'; import { Logger } from '@hydrooj/utils';
import { Context, Service } from '../context'; import { Context, Service } from '../context';
import * as system from '../model/system'; import * as system from '../model/system';
const argv = cac().parse();
export type MigrationScript = null | ((ctx: Context) => Promise<boolean | void>); export type MigrationScript = null | ((ctx: Context) => Promise<boolean | void>);
const logger = new Logger('migration'); const logger = new Logger('migration');
@@ -43,6 +46,18 @@ export default class MigrationService extends Service {
await system.set(name, expected); await system.set(name, expected);
continue; continue;
} }
let upgraded = false;
if (dbVer > expected) {
logger.warn('Current database version for [%s] is %d, expected %d.', channel, dbVer, expected);
logger.warn('You are likely trying to apply a downgrade.');
logger.warn('This version of Hydro is not compatible with newer data version.');
if (!argv.options.ignoreVersion) {
logger.warn('To prevent data corruption, the startup has been aborted.');
logger.warn('If you want to continue, use --ignore-version on startup.');
logger.warn('Do it at your own risk.');
await new Promise(() => { });
}
}
while (dbVer < expected) { while (dbVer < expected) {
const func = scripts[dbVer]; const func = scripts[dbVer];
if (typeof func !== 'function') { if (typeof func !== 'function') {
@@ -62,8 +77,9 @@ export default class MigrationService extends Service {
} }
dbVer++; dbVer++;
await system.set(name, dbVer); await system.set(name, dbVer);
upgraded = true;
} }
logger.success('Database upgraded [%s]: current version %d', channel, dbVer); if (upgraded) logger.success('Database upgraded [%s]: current version %d', channel, dbVer);
} }
} }
} }
+1 -1
View File
@@ -107,5 +107,5 @@ export async function apply(ctx: Context) {
{ upsert: true }, { upsert: true },
); );
feedback(); feedback();
return ctx.setInterval(update, 1800 * 1000); // eslint-disable-line return ctx.interval(update, 1800 * 1000); // eslint-disable-line
} }
+1 -1
View File
@@ -425,7 +425,7 @@ export async function apply(ctx: Context, config: ReturnType<typeof FileSetting>
return await next(); return await next();
}); });
}); });
ctx.set('storage', service); ctx.provide('storage', service);
} }
declare module '../context' { declare module '../context' {
+1 -1
View File
@@ -11,7 +11,7 @@ async function terminate() {
}, 1000); }, 1000);
try { try {
await bus.parallel('app/exit'); await bus.parallel('app/exit');
await app.scope.dispose(); await app.fiber.dispose();
} catch (e) { } catch (e) {
hasError = true; hasError = true;
} }
+1 -1
View File
@@ -6,7 +6,7 @@
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"mariadb": "^3.4.0", "mariadb": "^3.4.1",
"mongodb": "^6.15.0", "mongodb": "^6.15.0",
"turndown": "^7.2.0", "turndown": "^7.2.0",
"xml2js": "^0.6.2" "xml2js": "^0.6.2"
+1 -1
View File
@@ -55,7 +55,7 @@ export function apply(ctx: Context) {
const registry = createRegistry(ctx); const registry = createRegistry(ctx);
ctx.on('metrics', (id, metrics) => { instances[id] = metrics; }); ctx.on('metrics', (id, metrics) => { instances[id] = metrics; });
let pushError = ''; let pushError = '';
ctx.setInterval(async () => { ctx.interval(async () => {
try { try {
const [gateway, name, pass] = SystemModel.getMany(['prom-client.gateway', 'prom-client.name', 'prom-client.password']); const [gateway, name, pass] = SystemModel.getMany(['prom-client.gateway', 'prom-client.name', 'prom-client.password']);
if (gateway) { if (gateway) {
+1 -1
View File
@@ -75,6 +75,6 @@ export function createRegistry(ctx: Context) {
collectDefaultMetrics({ register: registry }); collectDefaultMetrics({ register: registry });
ctx.set('metrics', registry); ctx.provide('metrics', registry);
return registry; return registry;
} }
@@ -66,7 +66,7 @@ export default function ScratchpadContainer() {
const store = useStore(); const store = useStore();
if (!scratchpad) { if (!scratchpad) {
scratchpad = new ScratchpadService(store); scratchpad = new ScratchpadService(store);
ctx.set('scratchpad', scratchpad); ctx.provide('scratchpad', scratchpad);
} }
const [, updateState] = React.useState<any>(); const [, updateState] = React.useState<any>();
const forceUpdate = React.useCallback(() => updateState({}), []); const forceUpdate = React.useCallback(() => updateState({}), []);
+3 -3
View File
@@ -1,9 +1,9 @@
import * as cordis from '@cordisjs/core'; import * as cordis from 'cordis';
import type { EventMap } from './api'; import type { EventMap } from './api';
export interface Events<C extends Context = Context> extends cordis.Events<C>, EventMap { } export interface Events<C extends Context = Context> extends cordis.Events<C>, EventMap { }
export type { Disposable, ScopeStatus, Plugin } from '@cordisjs/core'; export type { Disposable, FiberState, Plugin } from 'cordis';
export interface Context { export interface Context {
[Context.events]: Events<this>; [Context.events]: Events<this>;
@@ -11,7 +11,7 @@ export interface Context {
} }
export class Context extends cordis.Context { } export class Context extends cordis.Context { }
export type EffectScope = cordis.EffectScope<Context>; export type Fiber = cordis.Fiber<Context>;
export class Service<C extends Context = Context> extends cordis.Service<C> { export class Service<C extends Context = Context> extends cordis.Service<C> {
} }
+12 -12
View File
@@ -11,8 +11,7 @@
"cli": false "cli": false
}, },
"devDependencies": { "devDependencies": {
"@blueprintjs/core": "^5.17.6", "@blueprintjs/core": "^5.18.0",
"@cordisjs/core": "4.0.0-alpha.8",
"@fontsource/dm-mono": "^5.2.5", "@fontsource/dm-mono": "^5.2.5",
"@fontsource/fira-code": "^5.2.5", "@fontsource/fira-code": "^5.2.5",
"@fontsource/inconsolata": "^5.2.5", "@fontsource/inconsolata": "^5.2.5",
@@ -22,8 +21,8 @@
"@fontsource/source-code-pro": "^5.2.5", "@fontsource/source-code-pro": "^5.2.5",
"@fontsource/ubuntu-mono": "^5.2.5", "@fontsource/ubuntu-mono": "^5.2.5",
"@hydrooj/utils": "workspace:^", "@hydrooj/utils": "workspace:^",
"@sentry/browser": "^9.10.1", "@sentry/browser": "^9.12.0",
"@sentry/webpack-plugin": "^3.2.4", "@sentry/webpack-plugin": "^3.3.1",
"@simplewebauthn/browser": "13.1.0", "@simplewebauthn/browser": "13.1.0",
"@svgr/webpack": "^8.1.0", "@svgr/webpack": "^8.1.0",
"@types/html-to-text": "^9.0.4", "@types/html-to-text": "^9.0.4",
@@ -36,7 +35,7 @@
"@types/pickadate": "^3.5.35", "@types/pickadate": "^3.5.35",
"@types/qrcode": "^1.5.5", "@types/qrcode": "^1.5.5",
"@types/react": "^18.3.20", "@types/react": "^18.3.20",
"@types/react-dom": "^18.3.5", "@types/react-dom": "^18.3.6",
"@types/redux-logger": "^3.0.13", "@types/redux-logger": "^3.0.13",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/webpack-env": "^1.18.8", "@types/webpack-env": "^1.18.8",
@@ -50,6 +49,7 @@
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"copy-webpack-plugin": "^13.0.0", "copy-webpack-plugin": "^13.0.0",
"cordis": "4.0.0-beta.1",
"core-js": "^3.41.0", "core-js": "^3.41.0",
"core-js-compat": "^3.41.0", "core-js-compat": "^3.41.0",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
@@ -99,7 +99,7 @@
"redux-promise-middleware": "^6.2.0", "redux-promise-middleware": "^6.2.0",
"redux-thunk": "^3.1.0", "redux-thunk": "^3.1.0",
"rupture": "^0.7.1", "rupture": "^0.7.1",
"sass": "^1.86.1", "sass": "^1.86.3",
"sass-loader": "^16.0.5", "sass-loader": "^16.0.5",
"schemastery": "^3.16.1", "schemastery": "^3.16.1",
"schemastery-react": "^0.1.2", "schemastery-react": "^0.1.2",
@@ -108,15 +108,15 @@
"sticky-kit": "^1.1.3", "sticky-kit": "^1.1.3",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"stylus": "^0.64.0", "stylus": "^0.64.0",
"stylus-loader": "7.1.2", "stylus-loader": "7.1.3",
"svgtofont": "^6.3.1", "svgtofont": "^6.3.2",
"tether": "1.4.7", "tether": "1.4.7",
"tether-drop": "^1.4.2", "tether-drop": "^1.4.2",
"timeago-react": "^3.0.7", "timeago-react": "^3.0.7",
"timeago.js": "^4.0.2", "timeago.js": "^4.0.2",
"ts-loader": "^9.5.2", "ts-loader": "^9.5.2",
"web-streams-polyfill": "^4.1.0", "web-streams-polyfill": "^4.1.0",
"webpack": "^5.98.0", "webpack": "^5.99.5",
"webpack-bundle-analyzer": "^4.10.2", "webpack-bundle-analyzer": "^4.10.2",
"webpack-dev-server": "^5.2.1", "webpack-dev-server": "^5.2.1",
"webpack-manifest-plugin": "^5.0.1", "webpack-manifest-plugin": "^5.0.1",
@@ -124,14 +124,14 @@
}, },
"dependencies": { "dependencies": {
"@hydrooj/common": "workspace:^", "@hydrooj/common": "workspace:^",
"ansi_up": "^6.0.2", "ansi_up": "^6.0.5",
"cssfilter": "^0.0.11", "cssfilter": "^0.0.11",
"esbuild": "0.25.0", "esbuild": "0.25.2",
"fs-extra": "^11.3.0", "fs-extra": "^11.3.0",
"html-to-text": "^9.0.5", "html-to-text": "^9.0.5",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"jsesc": "^3.1.0", "jsesc": "^3.1.0",
"katex": "^0.16.21", "katex": "^0.16.22",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.2.0", "markdown-it-anchor": "^9.2.0",
+1 -1
View File
@@ -21,7 +21,7 @@ export default new NamedPage('api', async () => {
} as any; } as any;
createRoot(document.getElementById('main')!).render( createRoot(document.getElementById('main')!).render(
<GraphiQL <GraphiQL
fetcher={(body, opts = {}) => request.post('/api', body, pick(opts, 'headers'))} fetcher={(body, opts = {}) => request.post(`/d/${UiContext.domain._id}/api`, body, pick(opts, 'headers'))}
defaultQuery={defaultQuery} defaultQuery={defaultQuery}
variables='{"name": "Hydro"}' variables='{"name": "Hydro"}'
/>, />,
@@ -43,7 +43,7 @@ const page = new NamedPage('home_messages', () => {
reduxStore = store; reduxStore = store;
(window as any).store = reduxStore; (window as any).store = reduxStore;
ctx.set('messagepad', new MessagePadService(store, WebSocket)); ctx.provide('messagepad', new MessagePadService(store, WebSocket));
const sock = new WebSocket(`${UiContext.ws_prefix}home/messages-conn`); const sock = new WebSocket(`${UiContext.ws_prefix}home/messages-conn`);
sock.onmessage = (message) => { sock.onmessage = (message) => {
@@ -1,6 +1,5 @@
import { browserSupportsWebAuthn, platformAuthenticatorIsAvailable, startRegistration } from '@simplewebauthn/browser'; import { browserSupportsWebAuthn, platformAuthenticatorIsAvailable, startRegistration } from '@simplewebauthn/browser';
import $ from 'jquery'; import $ from 'jquery';
import { escape } from 'lodash';
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import { ActionDialog } from 'vj/components/dialog'; import { ActionDialog } from 'vj/components/dialog';
import Notification from 'vj/components/notification'; import Notification from 'vj/components/notification';
@@ -28,7 +27,7 @@ async function changeMail() {
<input className="textbox" type="text" name="mail" required></input> <input className="textbox" type="text" name="mail" required></input>
</div> </div>
</label> </label>
</div> </div>,
), ),
onDispatch(action) { onDispatch(action) {
if (action === 'ok') { if (action === 'ok') {
@@ -199,7 +198,7 @@ export default new NamedPage('home_security', () => {
</MenuLink> </MenuLink>
</>)} </>)}
</ol> </ol>
</div> </div>,
); );
const action = await new ActionDialog({ $body, $action: [] }).open(); const action = await new ActionDialog({ $body, $action: [] }).open();
if (!action || action === 'cancel') return; if (!action || action === 'cancel') return;
+3 -3
View File
@@ -13,9 +13,9 @@
"react-dom": "^18.3.1" "react-dom": "^18.3.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^19.0.12", "@types/react": "^19.1.0",
"@types/react-dom": "^19.0.4", "@types/react-dom": "^19.1.2",
"@vitejs/plugin-react-swc": "^3.8.1", "@vitejs/plugin-react-swc": "^3.8.1",
"vite": "^6.2.4" "vite": "^6.2.6"
} }
} }
+1 -1
View File
@@ -193,7 +193,7 @@ class VJudgeService extends Service {
if (process.env.NODE_APP_INSTANCE !== '0') return; if (process.env.NODE_APP_INSTANCE !== '0') return;
if (process.env.HYDRO_CLI) return; if (process.env.HYDRO_CLI) return;
this.accounts = await coll.find().toArray(); this.accounts = await coll.find().toArray();
this.ctx.setInterval(this.sync.bind(this), Time.week); this.ctx.interval(this.sync.bind(this), Time.week);
} }
addProvider(type: string, provider: BasicProvider, override = false) { addProvider(type: string, provider: BasicProvider, override = false) {