diff --git a/package.json b/package.json index 36d93bfcb..2c8eac6c6 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "lint:ui:ci": "yarn run --cwd=packages/ui-default eslint .", "pub": "node build/publish", "typedoc": "cross-env NODE_OPTIONS=--max_old_space_size=8192 typedoc", - "debug:all": "node --async-stack-traces --trace-deprecation build/start --debug --template", - "debug": "node --async-stack-traces --trace-deprecation node_modules/hydrooj/bin/hydrooj --debug --template", + "debug:all": "node --trace-warnings --async-stack-traces --trace-deprecation build/start --debug --template", + "debug": "node --trace-warnings --async-stack-traces --trace-deprecation node_modules/hydrooj/bin/hydrooj --debug --template", "start:all": "node build/start", "start": "node_modules/.bin/hydrooj", "postinstall": "node build/hack", @@ -28,15 +28,15 @@ "license": "AGPL-3.0-only", "devDependencies": { "@types/cross-spawn": "^6.0.2", - "@types/node": "^16.11.10", + "@types/node": "^16.11.13", "@types/semver": "^7.3.9", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", + "@typescript-eslint/eslint-plugin": "^5.7.0", + "@typescript-eslint/parser": "^5.7.0", "cac": "^6.7.12", "cross-env": "^7.0.3", "cross-spawn": "^7.0.3", - "esbuild": "^0.13.15", - "eslint": "^8.3.0", + "esbuild": "0.14.3", + "eslint": "^8.4.1", "eslint-config-airbnb-typescript": "12.3.1", "eslint-import-resolver-typescript": "^2.5.0", "eslint-plugin-import": "^2.25.3", diff --git a/packages/fps-importer/package.json b/packages/fps-importer/package.json index 52993aee6..5adc3f64a 100644 --- a/packages/fps-importer/package.json +++ b/packages/fps-importer/package.json @@ -8,7 +8,7 @@ "license": "SEE LICENSE IN LICENSE", "preferUnplugged": true, "dependencies": { - "adm-zip": "0.5.5", + "adm-zip": "0.5.9", "decode-html": "^2.0.0", "fs-extra": "^10.0.0", "mongodb": "^3.7.3", diff --git a/packages/hydrojudge/package.json b/packages/hydrojudge/package.json index 7a16dc253..0111003d6 100644 --- a/packages/hydrojudge/package.json +++ b/packages/hydrojudge/package.json @@ -1,15 +1,15 @@ { "name": "@hydrooj/hydrojudge", "bin": "bin/hydrojudge.js", - "version": "2.12.10", + "version": "2.12.11", "main": "package.json", "author": "undefined ", "repository": "https://github.com/hydro-dev/Hydro.git", "dependencies": { "@hydrooj/utils": "workspace:*", - "axios": "^0.21.4", + "axios": "^0.24.0", "cac": "^6.7.12", - "esbuild": "^0.13.15", + "esbuild": "0.14.3", "fs-extra": "^10.0.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", @@ -23,9 +23,9 @@ "devDependencies": { "@types/fs-extra": "^9.0.13", "@types/js-yaml": "^4.0.5", - "@types/lodash": "^4.14.177", + "@types/lodash": "^4.14.178", "@types/shell-quote": "^1.7.1", - "@types/ws": "^7.4.7" + "@types/ws": "^8.2.2" }, "peerDependencies": { "hydrooj": "*" diff --git a/packages/hydrojudge/src/hosts/hydro.ts b/packages/hydrojudge/src/hosts/hydro.ts index 728498604..419bbb9c8 100644 --- a/packages/hydrojudge/src/hosts/hydro.ts +++ b/packages/hydrojudge/src/hosts/hydro.ts @@ -250,8 +250,8 @@ export default class Hydro { : '{"key":"ping"}'; setInterval(() => this.ws.send(content), 30000); }); - this.ws.on('message', (data, isBinary) => { - const request = JSON.parse(isBinary ? data : data.toString()); + this.ws.on('message', (data) => { + const request = JSON.parse(data.toString()); if (request.language) this.language = request.language; if (request.task) queue.push(new JudgeTask(this, request.task, this.ws)); }); diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 54fd7f50d..ebac1574a 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.2.19", + "version": "3.2.20", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", @@ -14,15 +14,15 @@ "dependencies": { "@graphql-tools/schema": "^8.3.1", "@hydrooj/utils": "workspace:*", - "adm-zip": "0.5.5", + "adm-zip": "0.5.9", "ansi_up": "^5.1.0", "cac": "^6.7.12", "cookies": "^0.8.0", - "detect-browser": "^5.2.1", - "esbuild": "^0.13.15", + "detect-browser": "^5.3.0", + "esbuild": "0.14.3", "fs-extra": "^10.0.0", - "graphql": "^15.7.2", - "graphql-scalars": "1.13.6", + "graphql": "^16.1.0", + "graphql-scalars": "1.14.1", "js-yaml": "^4.1.0", "koa": "^2.13.4", "koa-body": "^4.2.0", @@ -33,16 +33,16 @@ "lodash": "^4.17.21", "lru-cache": "^6.0.0", "mime-types": "^2.1.34", - "minio": "7.0.19", + "minio": "7.0.25", "moment-timezone": "^0.5.34", "mongodb": "^3.7.3", "nanoid": "^3.1.30", - "nodemailer": "^6.7.1", + "nodemailer": "^6.7.2", "notp": "^2.0.3", "p-queue": "^7.1.0", "reflect-metadata": "^0.1.13", "serialize-javascript": "^6.0.0", - "sockjs": "^0.3.21", + "sockjs": "^0.3.24", "source-map-support": "^0.5.21", "superagent": "^6.1.0", "thirty-two": "^1.0.2", @@ -56,7 +56,7 @@ "@types/koa-compress": "^4.0.3", "@types/koa-router": "^7.4.4", "@types/koa-static-cache": "^5.1.1", - "@types/lodash": "^4.14.177", + "@types/lodash": "^4.14.178", "@types/lru-cache": "^5.1.1", "@types/mime-types": "^2.1.1", "@types/minio": "^7.0.11", @@ -67,7 +67,6 @@ "@types/sockjs": "^0.3.33", "@types/source-map-support": "^0.5.4", "@types/superagent": "^4.1.13", - "formidable": "^1.2.6", "moment": "^2.29.1", "pm2": "^5.1.2" }, diff --git a/packages/hydrooj/src/handler/api.ts b/packages/hydrooj/src/handler/api.ts index ddaf3f1ee..21a354925 100644 --- a/packages/hydrooj/src/handler/api.ts +++ b/packages/hydrooj/src/handler/api.ts @@ -94,9 +94,14 @@ bus.on('app/started', () => { }); class ApiHandler extends Handler { - async query(q: string, variables: any) { - // FIXME validation for fields like ObjectID doesn't work. - return graphql(schema, q, root, this, variables); + query(q: string, variables: any) { + return graphql({ + schema, + source: q, + rootValue: root, + contextValue: this, + variableValues: variables, + }); } async get() { diff --git a/packages/hydrooj/src/handler/domain.ts b/packages/hydrooj/src/handler/domain.ts index a082dc052..52d0e6ac4 100644 --- a/packages/hydrooj/src/handler/domain.ts +++ b/packages/hydrooj/src/handler/domain.ts @@ -105,14 +105,9 @@ class DomainUserHandler extends ManageHandler { rudocs[ud.role || 'default'].push(ud); } const rolesSelect = roles.map((role) => [role._id, role._id]); - const path = [ - ['Hydro', 'homepage'], - ['domain', null], - ['domain_user', null], - ]; this.response.template = 'domain_user.html'; this.response.body = { - roles, rolesSelect, rudocs, udict, path, domain: this.domain, + roles, rolesSelect, rudocs, udict, domain: this.domain, }; } @@ -134,14 +129,9 @@ class DomainUserHandler extends ManageHandler { class DomainPermissionHandler extends ManageHandler { async get({ domainId }) { const roles = await domain.getRoles(domainId); - const path = [ - ['Hydro', 'homepage'], - ['domain', null], - ['domain_permission', null], - ]; this.response.template = 'domain_permission.html'; this.response.body = { - roles, PERMS_BY_FAMILY, domain: this.domain, path, log2, + roles, PERMS_BY_FAMILY, domain: this.domain, log2, }; } @@ -179,10 +169,8 @@ class DomainRoleHandler extends ManageHandler { @param('roles', Types.Array) async postDelete(domainId: string, roles: string[]) { - for (const role of roles) { - if (['root', 'default', 'guest'].includes(role)) { - throw new ValidationError('role'); - } + if (Set.intersection(new Set(roles), new Set(['root', 'default', 'guest'])).size > 0) { + throw new ValidationError('role', null, 'You cannot delete root, default or guest roles'); } await domain.deleteRoles(domainId, roles); this.back(); diff --git a/packages/hydrooj/src/handler/status.ts b/packages/hydrooj/src/handler/status.ts index fa6de0522..82810263b 100644 --- a/packages/hydrooj/src/handler/status.ts +++ b/packages/hydrooj/src/handler/status.ts @@ -24,16 +24,12 @@ async function getStatus() { class StatusHandler extends Handler { async get() { - const path = [ - ['Hydro', 'homepage'], - ['status', null], - ]; const stats = await getStatus(); for (const stat of stats) { if (!stat.battery.hasBattery) stat.battery = 'No battery'; else stat.battery = `${stat.battery.type} ${stat.battery.model} ${stat.battery.percent}%${stat.battery.isCharging ? ' Charging' : ''}`; } - this.response.body = { stats, path }; + this.response.body = { stats }; this.response.template = 'status.html'; } } diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index f7f240c42..1b18bf568 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -1,5 +1,4 @@ import type fs from 'fs'; -import type * as Koa from 'koa'; import type { Dictionary, NumericDictionary } from 'lodash'; import type { ItemBucketMetadata } from 'minio'; import type { Cursor, ObjectID } from 'mongodb'; @@ -682,10 +681,3 @@ declare global { var Hydro: HydroGlobal; // eslint-disable-line var addons: string[]; // eslint-disable-line } - -declare module 'koa' { - interface Request extends Koa.BaseRequest { - body?: any; - files?: import('formidable').Files; - } -} diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index 1d74676a7..9d4390193 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -102,7 +102,6 @@ class DomainModel { @ArgMethod static async getList(domainIds: string[]) { const r: Record = {}; - // eslint-disable-next-line no-await-in-loop const tasks = []; for (const domainId of domainIds) tasks.push(DomainModel.get(domainId).then((ddoc) => { r[domainId] = ddoc; })); await Promise.all(tasks); @@ -146,12 +145,11 @@ class DomainModel { } } if (count) { - for (const role of roles) { - if (!['default', 'guest'].includes(role._id)) { - // eslint-disable-next-line no-await-in-loop - role.count = await DomainModel.countUser(ddoc._id, role._id); - } - } + await Promise.all(roles.map(async (role) => { + if (['default', 'guest'].includes(role._id)) return role; + role.count = await DomainModel.countUser(ddoc._id, role._id); + return role; + })); } return roles; } diff --git a/packages/hydrooj/src/typeutils.ts b/packages/hydrooj/src/typeutils.ts index 5ae6dcccf..5be09dc67 100644 --- a/packages/hydrooj/src/typeutils.ts +++ b/packages/hydrooj/src/typeutils.ts @@ -4,6 +4,9 @@ export type NumberKeys = { export type ArrayKeys = { [K in keyof O]: P[] extends O[K] ? K : never }[keyof O]; +export type NestKeys = O extends object ? O extends S ? never : { + [K in keyof O]: (O[K] extends T ? K : never) | `${K & string}.${NestKeys}` +}[keyof O] & string : never; export type Value = { [K in keyof O]: V }; diff --git a/packages/import-qduoj/package.json b/packages/import-qduoj/package.json index 69a0aba21..6b9891b67 100644 --- a/packages/import-qduoj/package.json +++ b/packages/import-qduoj/package.json @@ -8,7 +8,7 @@ "license": "AGPL-3.0-or-later", "preferUnplugged": true, "dependencies": { - "adm-zip": "0.5.5", + "adm-zip": "0.5.9", "decode-html": "^2.0.0", "fs-extra": "^10.0.0" } diff --git a/packages/login-with-qq/package.json b/packages/login-with-qq/package.json index 48e050ef3..b1ec8ab72 100644 --- a/packages/login-with-qq/package.json +++ b/packages/login-with-qq/package.json @@ -10,6 +10,6 @@ "ws": "^8.3.0" }, "devDependencies": { - "@types/ws": "^8.2.0" + "@types/ws": "^8.2.2" } } diff --git a/packages/ui-default/build/config/webpack.js b/packages/ui-default/build/config/webpack.js index ed510e195..81720fa7e 100644 --- a/packages/ui-default/build/config/webpack.js +++ b/packages/ui-default/build/config/webpack.js @@ -220,7 +220,9 @@ export default function (env = {}) { customInterpolateName: beautifyOutputUrl, }, }), + new webpack.NormalModuleReplacementPlugin(/\/(vscode-)?nls\.js/, require.resolve('../../components/monaco/nls')), new MonacoWebpackPlugin({ + filename: '[name].[hash:10].worker.js', customLanguages: [{ label: 'yaml', entry: require.resolve('@undefined-moe/monaco-yaml/lib/esm/monaco.contribution'), diff --git a/packages/ui-default/components/monaco/index.js b/packages/ui-default/components/monaco/index.js index 371846129..c84fab456 100644 --- a/packages/ui-default/components/monaco/index.js +++ b/packages/ui-default/components/monaco/index.js @@ -23,7 +23,7 @@ export function registerAction(editor, model, element) { if (element) { editor.addAction({ id: 'submit-form', - label: 'Use light', + label: 'Submit', keybindings: [ monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, monaco.KeyMod.WinCtrl | monaco.KeyCode.Enter, @@ -31,7 +31,7 @@ export function registerAction(editor, model, element) { run: () => $(element).closest('form').submit(), }); } - editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_P, () => { + editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyP, () => { editor.getAction('editor.action.quickCommand').run(); }); loadFormatter().then(([loaded, format]) => { @@ -41,7 +41,7 @@ export function registerAction(editor, model, element) { label: 'Format Code', contextMenuOrder: 0, contextMenuGroupId: 'operation', - keybindings: [monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F], + keybindings: [monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF], run: () => { if (!['cpp', 'c'].includes(model._languageIdentifier.language)) return; const [success, result] = format(editor.getValue(), `${UserContext.astyleOptions.trim()} mode=c`); @@ -49,7 +49,7 @@ export function registerAction(editor, model, element) { else Notification.warn(result); }, }); - editor.addCommand(monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F, () => { + editor.addCommand(monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF, () => { editor.getAction('hydro.format').run(); }); }); diff --git a/packages/ui-default/components/monaco/nls.js b/packages/ui-default/components/monaco/nls.js new file mode 100644 index 000000000..9594f40bf --- /dev/null +++ b/packages/ui-default/components/monaco/nls.js @@ -0,0 +1,60 @@ +/* eslint-disable camelcase */ +import en_GB from 'monaco-editor-nls/locale/en-gb.json'; +import zh_CN from 'monaco-editor-nls/locale/zh-hans.json'; +import zh_TW from 'monaco-editor-nls/locale/zh-hant.json'; +import ko from 'monaco-editor-nls/locale/ko.json'; +import i18n from 'vj/utils/i18n'; + +function _format(message, args) { + let result; + if (args.length === 0) { + result = message; + } else { + result = String(message).replace(/\{(\d+)\}/g, (match, rest) => { + const index = rest[0]; + return typeof args[index] !== 'undefined' ? args[index] : match; + }); + } + return result; +} + +let CURRENT_LOCALE_DATA = {}; + +function find(path, message) { + for (const key of Object.keys(CURRENT_LOCALE_DATA)) { + if (!CURRENT_LOCALE_DATA[key]) continue; + if (CURRENT_LOCALE_DATA[key][path] && en_GB[key][path] === message) { + return CURRENT_LOCALE_DATA[key][path]; + } + } + for (const key of Object.keys(CURRENT_LOCALE_DATA)) { + if (!CURRENT_LOCALE_DATA[key]) continue; + if (CURRENT_LOCALE_DATA[key][path]) { + return CURRENT_LOCALE_DATA[key][path]; + } + } + return message; +} + +export function localize(path, message, ...args) { + return _format(find(path.key || path, message), args); +} + +export function setLocaleData(data) { + CURRENT_LOCALE_DATA = data; +} + +export function loadMessageBundle(file) { + return localize; +} + +export function config(opt) { + return loadMessageBundle; +} + +const languages = { + zh_CN, + zh_TW, + ko, +}; +if (languages[i18n('timeago_locale')]) setLocaleData(languages[i18n('timeago_locale')]); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 637dd2e3e..d3324c0a0 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.27.7", + "version": "4.27.8", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", @@ -10,10 +10,10 @@ "lint": "eslint ." }, "devDependencies": { - "@blueprintjs/core": "^3.51.3", + "@blueprintjs/core": "^3.52.0", "@blueprintjs/icons": "^3.31.0", "@hydrooj/utils": "workspace:*", - "@types/jquery": "^3.5.9", + "@types/jquery": "^3.5.10", "@types/json-schema": "^7.0.9", "@types/katex": "^0.11.1", "@types/qrcode": "^1.4.1", @@ -31,8 +31,8 @@ "echarts": "^5.2.2", "emojis-keywords": "2.0.0", "emojis-list": "2.1.0", - "esbuild-loader": "^2.16.0", - "eslint": "^8.3.0", + "esbuild-loader": "^2.17.0", + "eslint": "^8.4.1", "eslint-config-airbnb": "^18.2.1", "eslint-import-resolver-webpack": "^0.13.2", "eslint-plugin-import": "^2.25.3", @@ -41,10 +41,10 @@ "fancy-log": "^1.3.3", "file-loader": "^6.2.0", "friendly-errors-webpack-plugin": "^1.7.0", - "graphiql": "^1.5.5", + "graphiql": "^1.5.16", "gulp": "^4.0.2", "gulp-cli": "^2.3.0", - "gulp-iconfont": "^11.0.0", + "gulp-iconfont": "^11.0.1", "gulp-if": "^3.0.0", "gulp-plumber": "^1.2.1", "gulp-svgmin": "^3.0.0", @@ -54,8 +54,9 @@ "jquery.transit": "^0.9.12", "mini-css-extract-plugin": "^1.6.2", "moment": "^2.29.1", - "monaco-editor": "^0.29.1", - "monaco-editor-webpack-plugin": "^4.2.0", + "monaco-editor": "^0.31.1", + "monaco-editor-nls": "^2.0.0", + "monaco-editor-webpack-plugin": "^7.0.1", "nanoid": "^3.1.30", "normalize.css": "^8.0.1", "nprogress": "^0.2.0", @@ -74,7 +75,7 @@ "redux": "^4.1.2", "redux-logger": "^3.0.6", "redux-promise-middleware": "^6.1.2", - "redux-thunk": "^2.4.0", + "redux-thunk": "^2.4.1", "rupture": "^0.7.1", "slideout": "^1.0.1", "sockjs-client": "^1.5.2", @@ -89,7 +90,7 @@ "through2": "^4.0.2", "timeago-react": "^3.0.4", "timeago.js": "^4.0.2", - "vditor": "^3.8.7", + "vditor": "^3.8.8", "vinyl-buffer": "^1.0.1", "wastyle": "^0.0.5", "web-streams-polyfill": "^3.2.0", @@ -99,13 +100,13 @@ "webpackbar": "^5.0.2" }, "dependencies": { - "esbuild": "^0.13.15", + "esbuild": "0.14.3", "fs-extra": "^10.0.0", "js-yaml": "^4.1.0", "jsesc": "^3.0.2", "katex": "^0.15.1", "lodash": "^4.17.21", - "markdown-it": "^12.2.0", + "markdown-it": "^12.3.0", "markdown-it-anchor": "^8.4.1", "markdown-it-footnote": "^3.0.3", "markdown-it-imsize": "^2.0.1", diff --git a/packages/utils/package.json b/packages/utils/package.json index c6a83b2e3..96a4b0f13 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/utils", - "version": "1.1.7", + "version": "1.1.8", "description": "hydrooj utils", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", @@ -12,7 +12,7 @@ "js-yaml": "^4.1.0", "moment": "^2.29.1", "mongodb": "^3.7.3", - "systeminformation": "^5.9.9" + "systeminformation": "^5.9.17" }, "devDependencies": { "@types/fs-extra": "^9.0.13", diff --git a/packages/vjudge/package.json b/packages/vjudge/package.json index 517f248a9..b390045a1 100644 --- a/packages/vjudge/package.json +++ b/packages/vjudge/package.json @@ -9,14 +9,14 @@ "preferUnplugged": true, "dependencies": { "@hydrooj/utils": "workspace:*", - "jsdom": "^16.7.0", + "jsdom": "^19.0.0", "lodash": "^4.17.21", "superagent": "^6.1.0", "superagent-proxy": "^2.1.0" }, "devDependencies": { "@types/jsdom": "^16.2.13", - "@types/lodash": "^4.14.177", + "@types/lodash": "^4.14.178", "@types/superagent": "^4.1.13", "@types/superagent-proxy": "^2.0.1" }