mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
bug fixes
This commit is contained in:
12 files changed
+37
-26
No files matched your search
@@ -4,7 +4,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "base.mjs",
|
"main": "base.mjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-react/eslint-plugin": "^1.38.3",
|
"@eslint-react/eslint-plugin": "^1.38.4",
|
||||||
"@eslint/compat": "^1.2.7",
|
"@eslint/compat": "^1.2.7",
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
"@stylistic/eslint-plugin": "^4.2.0",
|
"@stylistic/eslint-plugin": "^4.2.0",
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,7 @@
|
|||||||
"@types/autocannon": "^7.12.6",
|
"@types/autocannon": "^7.12.6",
|
||||||
"@types/chai": "^5.2.1",
|
"@types/chai": "^5.2.1",
|
||||||
"@types/cross-spawn": "^6.0.6",
|
"@types/cross-spawn": "^6.0.6",
|
||||||
"@types/node": "22.13.8",
|
"@types/node": "22.13.14",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
"autocannon": "^8.0.0",
|
"autocannon": "^8.0.0",
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"cross-spawn": "^7.0.6",
|
"cross-spawn": "^7.0.6",
|
||||||
"esbuild": "0.25.0",
|
"esbuild": "0.25.0",
|
||||||
"eslint": "^9.23.0",
|
"eslint": "^9.23.0",
|
||||||
"eslint-import-resolver-typescript": "^4.2.5",
|
"eslint-import-resolver-typescript": "^4.3.1",
|
||||||
"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",
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ export interface LangConfig {
|
|||||||
hidden: boolean;
|
hidden: boolean;
|
||||||
isBinary?: boolean;
|
isBinary?: boolean;
|
||||||
analysis?: string;
|
analysis?: string;
|
||||||
/** @deprecated */
|
remote: boolean;
|
||||||
remote?: string;
|
|
||||||
validAs?: Record<string, string>;
|
validAs?: Record<string, string>;
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
pretest?: string | false;
|
pretest?: string | false;
|
||||||
@@ -51,6 +50,7 @@ export function parseLang(config: string): Record<string, LangConfig> {
|
|||||||
entry.code_file ||= `foo.${key}`;
|
entry.code_file ||= `foo.${key}`;
|
||||||
entry.execute ||= '/w/foo';
|
entry.execute ||= '/w/foo';
|
||||||
entry.key = key;
|
entry.key = key;
|
||||||
|
entry.remote = !!entry.remote;
|
||||||
entry.hidden ||= false;
|
entry.hidden ||= false;
|
||||||
entry.disabled ||= false;
|
entry.disabled ||= false;
|
||||||
entry.isBinary ||= false;
|
entry.isBinary ||= false;
|
||||||
|
|||||||
@@ -15,10 +15,9 @@ const locales = {
|
|||||||
function MonacoContainer({
|
function MonacoContainer({
|
||||||
config, setValue, setError, monaco, schema, editorCallback, size,
|
config, setValue, setError, monaco, schema, editorCallback, size,
|
||||||
}) {
|
}) {
|
||||||
const editorRef = React.useRef<HTMLDivElement>(null);
|
|
||||||
const [loading, setLoading] = React.useState(false);
|
|
||||||
const [editor, setEditor] = React.useState<any>(null);
|
const [editor, setEditor] = React.useState<any>(null);
|
||||||
const [model, setModel] = React.useState<any>(null);
|
const [model, setModel] = React.useState<any>(null);
|
||||||
|
const [initialized, setInitialized] = React.useState(false);
|
||||||
const { codeFontFamily } = React.useContext(ComponentsContext);
|
const { codeFontFamily } = React.useContext(ComponentsContext);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@@ -62,14 +61,14 @@ function MonacoContainer({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () => disposable.dispose(); // eslint-disable-line
|
return () => disposable.dispose(); // eslint-disable-line
|
||||||
}, [editor, model, setValue, setError]);
|
}, [editor, model, setValue, setError, schema]);
|
||||||
React.useEffect(() => {
|
const initializeEditor = React.useCallback((element) => {
|
||||||
if (!editorRef.current || loading) return;
|
if (!element || initialized) return;
|
||||||
setLoading(true);
|
setInitialized(true);
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const model = monaco.editor.createModel(config, 'yaml', monaco.Uri.parse('hydro://system/setting.yaml'));
|
const model = monaco.editor.createModel(config, 'yaml', monaco.Uri.parse('hydro://system/setting.yaml'));
|
||||||
setModel(model);
|
setModel(model);
|
||||||
const e = monaco.editor.create(editorRef.current, {
|
const e = monaco.editor.create(element, {
|
||||||
theme: 'vs-light',
|
theme: 'vs-light',
|
||||||
lineNumbers: 'off',
|
lineNumbers: 'off',
|
||||||
glyphMargin: true,
|
glyphMargin: true,
|
||||||
@@ -85,9 +84,9 @@ function MonacoContainer({
|
|||||||
ambiguousCharacters: true,
|
ambiguousCharacters: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
editorCallback(e, model, editorRef.current);
|
editorCallback(e, model, element);
|
||||||
setEditor(e);
|
setEditor(e);
|
||||||
}, [editorRef.current]);
|
}, [config, monaco, editorCallback, codeFontFamily, initialized]);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!editor) return;
|
if (!editor) return;
|
||||||
const current = editor.getValue({ lineEnding: '\n', preserveBOM: false });
|
const current = editor.getValue({ lineEnding: '\n', preserveBOM: false });
|
||||||
@@ -111,7 +110,7 @@ function MonacoContainer({
|
|||||||
model.pushEditOperations([], ops, undefined);
|
model.pushEditOperations([], ops, undefined);
|
||||||
}, [editor, config]);
|
}, [editor, config]);
|
||||||
return (
|
return (
|
||||||
<div ref={editorRef} style={{
|
<div ref={initializeEditor} style={{
|
||||||
width: '100%', height: '500px',
|
width: '100%', height: '500px',
|
||||||
}} />
|
}} />
|
||||||
);
|
);
|
||||||
@@ -120,10 +119,17 @@ function MonacoContainer({
|
|||||||
export default function ConfigEditor({
|
export default function ConfigEditor({
|
||||||
schema, config, monaco, Markdown, onSave, registerAction, sidebar,
|
schema, config, monaco, Markdown, onSave, registerAction, sidebar,
|
||||||
}) {
|
}) {
|
||||||
const [value, setValue] = React.useState(yaml.load(config));
|
const getValue = () => {
|
||||||
|
try {
|
||||||
|
return yaml.load(config);
|
||||||
|
} catch (e) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const [value, setValue] = React.useState(getValue);
|
||||||
const [info, setInfo] = React.useState('');
|
const [info, setInfo] = React.useState('');
|
||||||
const [stringConfig, setStringConfig] = React.useState(config);
|
const [stringConfig, setStringConfig] = React.useState(config);
|
||||||
const initial = React.useMemo(() => yaml.load(config), []);
|
const initial = React.useMemo(getValue, []);
|
||||||
const { i18n } = React.useContext(ComponentsContext);
|
const { i18n } = React.useContext(ComponentsContext);
|
||||||
|
|
||||||
const Form = React.useMemo(() => createSchemasteryReact({
|
const Form = React.useMemo(() => createSchemasteryReact({
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import moment from 'moment-timezone';
|
|||||||
import type { Context } from '../context';
|
import type { Context } from '../context';
|
||||||
import {
|
import {
|
||||||
CannotDeleteSystemDomainError, DomainJoinAlreadyMemberError, DomainJoinForbiddenError, ForbiddenError,
|
CannotDeleteSystemDomainError, DomainJoinAlreadyMemberError, DomainJoinForbiddenError, ForbiddenError,
|
||||||
InvalidJoinInvitationCodeError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
|
InvalidJoinInvitationCodeError, NotFoundError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
|
||||||
} from '../error';
|
} from '../error';
|
||||||
import type { DomainDoc } from '../interface';
|
import type { DomainDoc } from '../interface';
|
||||||
import avatar from '../lib/avatar';
|
import avatar from '../lib/avatar';
|
||||||
@@ -337,6 +337,7 @@ class DomainJoinHandler extends Handler {
|
|||||||
domain.get(target),
|
domain.get(target),
|
||||||
domain.collUser.findOne({ domainId: target, uid: this.user._id }),
|
domain.collUser.findOne({ domainId: target, uid: this.user._id }),
|
||||||
]);
|
]);
|
||||||
|
if (!dudoc) throw new NotFoundError(target);
|
||||||
const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN)
|
const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN)
|
||||||
? 'root'
|
? 'root'
|
||||||
: dudoc?.role || 'default';
|
: dudoc?.role || 'default';
|
||||||
|
|||||||
@@ -197,8 +197,12 @@ class SystemConfigHandler extends SystemHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
value = Schema.intersect(this.ctx.config.settings)(yaml.load(this.ctx.config.configSource));
|
value = Schema.intersect(this.ctx.config.settings)(yaml.load(this.ctx.config.configSource));
|
||||||
|
} catch (e) {
|
||||||
|
value = yaml.load(this.ctx.config.configSource);
|
||||||
|
}
|
||||||
for (const schema of this.ctx.config.settings) processNode(value, schema);
|
for (const schema of this.ctx.config.settings) processNode(value, schema);
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
this.response.body = {
|
this.response.body = {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export class ConfigService extends Service {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
let curValue = s(this.systemConfig);
|
let curValue = s(this.systemConfig);
|
||||||
if (dynamic) {
|
if (!dynamic) return curValue;
|
||||||
this.ctx.on('system/setting', () => {
|
this.ctx.on('system/setting', () => {
|
||||||
try {
|
try {
|
||||||
curValue = s(this.systemConfig);
|
curValue = s(this.systemConfig);
|
||||||
@@ -148,7 +148,6 @@ export class ConfigService extends Service {
|
|||||||
curValue = null;
|
curValue = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
const that = this;
|
const that = this;
|
||||||
const getAccess = (path: (string | symbol)[]) => {
|
const getAccess = (path: (string | symbol)[]) => {
|
||||||
if (path.some((p) => ConfigService.blacklist.includes(p.toString()))) throw new Error('Invalid path');
|
if (path.some((p) => ConfigService.blacklist.includes(p.toString()))) throw new Error('Invalid path');
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
"postinstall": "node -r @hydrooj/register install.ts"
|
"postinstall": "node -r @hydrooj/register install.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@xcpcio/board-app": "^0.54.0"
|
"@xcpcio/board-app": "^0.55.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"@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.0",
|
"@sentry/browser": "^9.10.1",
|
||||||
"@sentry/webpack-plugin": "^3.2.4",
|
"@sentry/webpack-plugin": "^3.2.4",
|
||||||
"@simplewebauthn/browser": "13.1.0",
|
"@simplewebauthn/browser": "13.1.0",
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const page = new NamedPage('manage_config', async () => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
display: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
.omnibar-toggle {
|
.omnibar-toggle {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -55,8 +55,9 @@
|
|||||||
<span class="icon icon-add"></span> {{ _('Login to Attend Contest') }}
|
<span class="icon icon-add"></span> {{ _('Login to Attend Contest') }}
|
||||||
</a>
|
</a>
|
||||||
{% elif not handler.user._dudoc.join %}
|
{% elif not handler.user._dudoc.join %}
|
||||||
<li class="menu__item"><a class="menu__link" href="/domain/join?target={{ pdoc.domainId }}">
|
<a class="menu__link" href="/domain/join?target={{ pdoc.domainId }}">
|
||||||
<span class="icon icon-add"></span> {{ _('Join Domain to Attend Contest') }}</a></li>
|
<span class="icon icon-add"></span> {{ _('Join Domain to Attend Contest') }}
|
||||||
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="menu__link disabled" href="javascript:;">
|
<a class="menu__link disabled" href="javascript:;">
|
||||||
<span class="icon icon-add"></span> {{ _('No Permission to Attend Contest') }}
|
<span class="icon icon-add"></span> {{ _('No Permission to Attend Contest') }}
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
"@types/react": "^19.0.12",
|
"@types/react": "^19.0.12",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@vitejs/plugin-react-swc": "^3.8.1",
|
"@vitejs/plugin-react-swc": "^3.8.1",
|
||||||
"vite": "^6.2.3"
|
"vite": "^6.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user