-
-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hydro v5 #951
base: master
Are you sure you want to change the base?
Hydro v5 #951
Conversation
WalkthroughThe pull request involves comprehensive refactoring across the project. A new Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 ESLint
framework/framework/decorators.tsOops! Something went wrong! :( ESLint: 9.23.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@hydrooj/eslint-config' imported from /eslint.config.mjs framework/framework/server.tsOops! Something went wrong! :( ESLint: 9.23.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@hydrooj/eslint-config' imported from /eslint.config.mjs packages/hydrooj/src/service/server.tsOops! Something went wrong! :( ESLint: 9.23.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@hydrooj/eslint-config' imported from /eslint.config.mjs
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (15)
framework/framework/serializer.ts (1)
3-3
: Enhanced type safety with generic parameter.Adding the generic type parameter
<T>
to the serializer function improves type safety by allowing the HandlerCommon parameter to be properly typed. This ensures better type checking and IDE support when working with different handler types.Consider adding a JSDoc comment to explain the purpose of the generic parameter:
+ /** + * Creates a serializer function for JSON.stringify with support for specialized handlers + * @template T Type parameter for the handler context + * @param ignoreSerializeFunction Whether to ignore serialize functions on objects + * @param h Optional handler common instance with type context + * @returns A replacer function for JSON.stringify + */ export default function serializer<T>(ignoreSerializeFunction = false, h?: HandlerCommon<T>) {packages/hydrooj/package.json (1)
19-21
:❓ Verification inconclusive
Update to new @cordisjs modularity architecture
The PR introduces dependencies on alpha versions of the modular
@cordisjs
packages (core
,logger
, andplugin-timer
), replacing the previous monolithiccordis
package. This aligns with the broader codebase update to use the namespaced packages.Since these are alpha versions, let's verify their stability and compatibility:
🏁 Script executed:
#!/bin/bash # Check the latest versions of these cordis packages and any relevant release notes echo "Checking the latest versions of cordis packages:" npm view @cordisjs/core versions --json | jq '.[-5:]' npm view @cordisjs/logger versions --json | jq '.[-5:]' npm view @cordisjs/plugin-timer versions --json | jq '.[-5:]' # Check if there are any github repos with release notes echo "Looking for related GitHub repositories:" gh search repos --owner cordisjs --limit 3 --json name,urlLength of output: 612
Modular @cordisjs Dependencies Verified
The PR now correctly adopts the new modular architecture by replacing the monolithic package with the namespaced packages. Verification via
npm view
confirms that:
- @cordisjs/core is updated to "4.0.0-alpha.1" (with earlier releases up to "4.0.0-alpha.0").
- @cordisjs/logger is updated to "1.0.0-alpha.1" (following the previous 0.3.x cycle).
- @cordisjs/plugin-timer remains at "1.0.0-alpha.0" (the only available version).
Since all these are alpha releases, additional stability and compatibility testing is advised before wider adoption.
framework/framework/decorators.ts (1)
38-40
: Enhanced type safety with generic ContextThe function signature now uses generics with
<T extends Context>
, allowing for more specific typing of the handler context. This is a significant improvement to type safety across the framework.Consider adding a type guard or documentation clarifying how these generic handlers should be implemented. This would be helpful for developers creating custom handlers.
packages/hydrooj/src/loader.ts (1)
142-150
: Enhanced asynchronous context initializationThe
preload
function has been updated to be asynchronous, ensuring proper initialization of the application context with required plugins before continuing execution. This is a good improvement for handling asynchronous operations.There's a missing semicolon at the end of line 150, which was flagged by static analysis. Fix it to maintain code consistency:
- }) + });🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 150-150: Semicolon insertion
Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).packages/hydrooj/src/context.ts (1)
12-13
: Fix the TODO comment grammar.
There's a minor typo in the comment: "this is an broken declaration" should be "this is a broken declaration."-// TODO: this is an broken declaration +// TODO: this is a broken declarationframework/framework/server.ts (10)
186-188
: Remove usage ofany
for server renderers.
Casting(this.ctx as any).server.renderers
can be replaced with proper type definitions for your server instance to ensure type safety.-const renderers = Object.values((this.ctx as any).server.renderers as Record<string, Renderer>) +const renderers = Object.values(this.ctx.server.renderers) .filter((r) => r.accept.includes(templateName) || r.asFallback);
246-246
: Ensure consistent generics.
ConnectionHandler<C>
extendsHandlerCommon<C>
similarly. If you anticipate a narrower generic type than anyC
, consider a more constrained approach to avoid confusion in usage sites.
481-483
: Address repeated type casting.
You’re using(this.ctx.parallel as any)
with a// FIXME: should pass type check
. Recommend updating the type definitions to remove reliance onany
.
535-536
: Similar pattern withthis.ctx.serial
.
Likewise, you are castingthis.ctx.serial
asany
. Consider refining your context or plugin types for improved type safety.
551-552
: Parallel usage in WS handling.
Again,(this.ctx.parallel as any)
is used when creating a connection. Try to unify type definitions to avoid these repeated workarounds.
594-594
: Emit usage withas any
.
Emitting'connection/close'
with(this.ctx.emit as any)
also bypasses type checks. Suggest properly defining or augmenting your event emitter.
705-705
: Event registration withas any
.
this.ctx.on(…)
is again cast toany
for the callback. Type definitions for the event system can remove the need for such casts.
709-710
: Refine handler parameters.
A TODO comment notes this should betypeof Handler<Context>
instead ofany
. Updating it would enhance type safety.
715-715
: Ensure typed connection handlers.
Similar to theRoute
method, switch fromany
to a well-defined handler type once your framework interface is stable.
720-724
: Type the registered layers.
Storing all layers asany
is flexible but loses type safety. Consider refining the signature ofregisterLayer
to clarify the shape of each layer.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (34)
.gitattributes
(1 hunks)framework/framework/decorators.ts
(3 hunks)framework/framework/interface.ts
(1 hunks)framework/framework/package.json
(1 hunks)framework/framework/serializer.ts
(1 hunks)framework/framework/server.ts
(21 hunks)package.json
(1 hunks)packages/hydrooj/package.json
(1 hunks)packages/hydrooj/src/context.ts
(4 hunks)packages/hydrooj/src/entry/worker.ts
(1 hunks)packages/hydrooj/src/handler/judge.ts
(1 hunks)packages/hydrooj/src/loader.ts
(3 hunks)packages/hydrooj/src/model/contest.ts
(1 hunks)packages/hydrooj/src/model/discussion.ts
(1 hunks)packages/hydrooj/src/model/document.ts
(1 hunks)packages/hydrooj/src/model/domain.ts
(1 hunks)packages/hydrooj/src/model/message.ts
(1 hunks)packages/hydrooj/src/model/oplog.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/setting.ts
(2 hunks)packages/hydrooj/src/model/solution.ts
(1 hunks)packages/hydrooj/src/model/system.ts
(1 hunks)packages/hydrooj/src/model/task.ts
(1 hunks)packages/hydrooj/src/model/token.ts
(1 hunks)packages/hydrooj/src/model/user.ts
(1 hunks)packages/hydrooj/src/service/bus.ts
(4 hunks)packages/hydrooj/src/service/db.ts
(1 hunks)packages/hydrooj/src/service/hmr.ts
(2 hunks)packages/hydrooj/src/service/monitor.ts
(1 hunks)packages/hydrooj/src/service/server.ts
(7 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/onsite-toolkit/index.ts
(1 hunks)packages/scoreboard-xcpcio/index.ts
(1 hunks)packages/ui-default/package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (9)
- packages/hydrooj/src/model/discussion.ts
- packages/scoreboard-xcpcio/index.ts
- packages/hydrooj/src/model/domain.ts
- packages/ui-default/package.json
- packages/hydrooj/src/model/system.ts
- packages/onsite-toolkit/index.ts
- .gitattributes
- packages/hydrooj/src/model/setting.ts
- packages/hydrooj/src/service/monitor.ts
🧰 Additional context used
🪛 GitHub Check: CodeQL
packages/hydrooj/src/loader.ts
[notice] 150-150: Semicolon insertion
Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).
framework/framework/server.ts
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
🪛 Biome (1.9.4)
packages/hydrooj/src/service/server.ts
[error] 79-79: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
[error] 119-119: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
framework/framework/server.ts
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (49)
package.json (1)
23-24
: Expanded linting coverage to include the framework directory.The linting script now includes the framework directory, ensuring that all TypeScript and JSX files there are also subject to the same linting rules as the rest of the project. This makes sense given that "framework/*" is already part of the project's workspaces (line 6).
framework/framework/package.json (1)
7-7
:✅ Verification successful
Package dependency updated from "cordis" to "@cordisjs/core".
The peer dependency has been changed from a non-namespaced package to a namespaced one. This change is likely part of a broader migration to using the namespaced version of the package throughout the project.
🏁 Script executed:
#!/bin/bash # Check if there are any remaining imports or dependencies for the old "cordis" package echo "Checking for remaining references to the old 'cordis' package..." grep -r "import.*from.*cordis['\"]" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" . grep -r "\"cordis\":" --include="package.json" .Length of output: 303
I'll run an additional, deeper search to ensure no lingering references to the old "cordis" package exist. This new script searches broadly for any occurrence of the string "cordis" (excluding common vendored directories) to provide a higher-confidence result.
Please run this script and share the output so we can proceed with a high-confidence verification of the update from "cordis" to "@cordisjs/core."
🏁 Script executed:
#!/bin/bash echo "Performing deep search for any occurrence of 'cordis' (case-insensitive) excluding node_modules, dist, and build directories..." rg -i "cordis" --glob "!node_modules/*" --glob "!dist/*" --glob "!build/*" .Length of output: 3784
Dependency migration verified – Namespaced package "@cordisjs/core" correctly in use
The deep search confirms that the dependency update in
framework/framework/package.json
is correctly applied. We see that all usages now reference@cordisjs/core
, and no lingering references to the old non-namespaced "cordis" remain in package dependencies. Minor mentions of "cordis" in comments and documentation are acceptable as they do not affect functionality.
- Location verified:
framework/framework/package.json
now correctly includes"@cordisjs/core": "*"
- Other code references: All module imports across the codebase consistently use the namespaced package.
packages/hydrooj/src/service/db.ts (1)
10-10
:✅ Verification successful
Import style updated from namespace to default import.
The import statement has been changed from a namespace import (
import * as bus from './bus'
) to a default import (import bus from './bus'
). This change suggests that the bus module now exports a default value, or has been refactored to do so. This change is consistent with similar changes in other files mentioned in the summary.
🏁 Script executed:
#!/bin/bash # Check the export style of the bus module cat packages/hydrooj/src/service/bus.ts | grep -E "export default|module.exports ="Length of output: 105
Import update verified:
The import change inpackages/hydrooj/src/service/db.ts
from a namespace import (import * as bus from './bus'
) to a default import (import bus from './bus'
) is correct. The module atpackages/hydrooj/src/service/bus.ts
indeed exports a default value (export default app;
), confirming the intended refactor. There are no additional issues to address.packages/hydrooj/src/model/token.ts (1)
3-3
: Import style updated from namespace to default import.The import statement has been changed from a namespace import (
import * as bus from '../service/bus'
) to a default import (import bus from '../service/bus'
). This change is consistent with the project-wide refactoring to use default imports for the bus module.packages/hydrooj/src/entry/worker.ts (1)
45-49
: Context handling enhancement with asynchronous injectionThe introduction of an asynchronous context injection mechanism ensures that the server dependency is fully integrated into the context before proceeding with subsequent operations. This is a good practice for proper dependency management.
This change addresses potential race conditions where
ctx
might not have the fully initialized server dependency when needed by code executed after line 44. The Promise-based approach ensures everything proceeds in the correct order.packages/hydrooj/src/ui.ts (1)
3-3
: Updated import style for bus moduleThe change from namespace import (
import * as bus
) to default import (import bus
) indicates a refactoring of the module export strategy in the bus service.This change aligns with modern JavaScript module practices and likely part of a broader effort to standardize import styles across the codebase, as similar changes appear in multiple files.
packages/hydrooj/src/model/contest.ts (1)
12-12
: Updated import style for bus moduleChanging from namespace import (
import * as bus
) to default import (import bus
) aligns with the project-wide standardization of how the bus service is imported.This is consistent with similar changes in other files, indicating a systematic refactoring of import statements across the codebase.
packages/hydrooj/src/model/solution.ts (1)
3-3
: Updated import style for bus moduleThe import statement has been changed from namespace import to default import, consistent with other files in the project.
This change is part of a broader refactoring effort to standardize how the bus service is imported throughout the codebase, improving consistency.
packages/hydrooj/src/model/task.ts (1)
9-9
: Import change from namespace to default is appropriate.The change from
import * as bus from '../service/bus'
toimport bus from '../service/bus'
aligns with the broader refactoring effort across the codebase to standardize import patterns.packages/hydrooj/src/model/document.ts (1)
12-12
: Import change from namespace to default is appropriate.The change from
import * as bus from '../service/bus'
toimport bus from '../service/bus'
aligns with the broader refactoring effort across the codebase to standardize import patterns.packages/hydrooj/src/model/message.ts (1)
3-3
: Import change from namespace to default is appropriate.The change from
import * as bus from '../service/bus'
toimport bus from '../service/bus'
aligns with the broader refactoring effort across the codebase to standardize import patterns.packages/hydrooj/src/model/oplog.ts (1)
4-4
:✅ Verification successful
Import style updated for the bus module.
The import has been updated from a namespace import (
import * as bus
) to a default import (import bus
). This change is consistent with the same pattern applied across multiple files in the codebase.
🏁 Script executed:
#!/bin/bash # Check how bus is exported in the source file cat packages/hydrooj/src/service/bus.ts | grep -n "export default" || echo "No default export found in bus.ts"Length of output: 92
Verification complete: The import change for the bus module is correct.
The default import (
import bus from '../service/bus';
) is now consistent with the export inpackages/hydrooj/src/service/bus.ts
, where the default export is defined (export default app;
). No further changes are needed.packages/hydrooj/src/model/user.ts (1)
12-12
:✅ Verification successful
Import style updated for the bus module.
The import statement has been changed from a namespace import (
import * as bus
) to a default import (import bus
). This is consistent with the changes made across other files in the codebase and indicates that the bus module is now using a default export pattern.
🏁 Script executed:
#!/bin/bash # Check if bus is consistently imported as default across the codebase echo "Files using default import for bus:" rg "import bus from '../service/bus'" packages/hydrooj/src/ echo -e "\nFiles still using namespace import for bus:" rg "import \* as bus from '../service/bus'" packages/hydrooj/src/Length of output: 1254
Import style update verified across the codebase
All files, including
packages/hydrooj/src/model/user.ts
, now consistently use the default import for the bus module; no namespace import remains.packages/hydrooj/src/handler/judge.ts (1)
26-26
:✅ Verification successful
Import style updated for the bus module.
The import has been standardized from namespace import (
import * as bus
) to default import (import bus
). This is part of a broader refactoring pattern across the codebase.
🏁 Script executed:
#!/bin/bash # Check how the bus module is structured and what it exports cat packages/hydrooj/src/service/bus.ts | head -20Length of output: 732
I'll run an additional check to verify that the
bus.ts
module indeed provides a default export as expected.
🏁 Script executed:
rg "export default" packages/hydrooj/src/service/bus.ts
Length of output: 77
Import statement verified: Default export found and used correctly.
The code change from a namespace import to a default import is correct since
packages/hydrooj/src/service/bus.ts
exports a default export (export default app;
). No further modifications are necessary for this update.packages/hydrooj/src/model/problem.ts (1)
19-19
:✅ Verification successful
Import style updated for the bus module.
The import statement has been updated from a namespace import to a default import. This change is consistent with the same pattern applied across the entire codebase for the bus module.
🏁 Script executed:
#!/bin/bash # Examine how bus is used in this file to ensure the import change is appropriate rg -A 1 "bus\.(parallel|emit|broadcast|on)" packages/hydrooj/src/model/problem.tsLength of output: 1427
Import style update for the bus module verified.
The default import from../service/bus
is being used consistently (e.g.,bus.parallel
andbus.emit
) in the filepackages/hydrooj/src/model/problem.ts
as confirmed by the grep output. This change aligns with the overall codebase pattern, and no issues remain.framework/framework/decorators.ts (2)
1-1
: Import from new namespaced @cordisjs packageThe import has been updated to use the new modular
@cordisjs/core
package, which is consistent with the dependency changes in package.json.
48-48
: Propagated generic type to validate functionThe nested
validate
function properly maintains the generic type parameter from the outer function, ensuring consistent typing throughout the descriptor.packages/hydrooj/src/loader.ts (2)
169-170
: Proper async handling in load functionThe
load
function now properly awaits the completion ofpreload()
, ensuring that all dependencies are initialized before proceeding with the application startup.
207-209
: Consistent async handling in CLI loaderThe
loadCli
function now properly awaits the completion ofpreload()
, matching the pattern used in the mainload
function. This ensures consistent behavior across different entry points.packages/hydrooj/src/service/hmr.ts (4)
151-151
: Simplified plugin tracking in HMRThe pending map type has been changed from
Map<string, Plugin.Runtime<Context>>
toMap<string, Plugin>
, focusing on storing the plugin objects directly rather than their runtime instances. This aligns with the broader changes in the codebase.
164-165
: Direct plugin storage and side effect checkingThe code now properly stores the plugin object directly and checks its
sideEffect
property. This is a cleaner approach than handling the runtime.
181-184
: Improved reloads map associationThe reloads map now correctly associates the plugin with its filename and runtime, matching the updated structure of the pending map.
168-173
:❓ Verification inconclusive
Refactored plugin validation loop
The loop now correctly iterates over plugins and retrieves the runtime separately. The side effect check has been moved to use the plugin object directly.
Let's verify that sideEffect access is consistent throughout the codebase:
🏁 Script executed:
#!/bin/bash # Check for consistent access patterns to the sideEffect property on plugins echo "Checking sideEffect property access patterns across the codebase:" rg --type typescript "sideEffect" -A 1 -B 1Length of output: 219
Verify SideEffect Access Consistency
The refactored plugin validation loop correctly retrieves the runtime and checks the plugin’s sideEffect property using bracket notation. However, our initial verification script failed due to an unrecognized file type error. Please manually verify that the sideEffect property is accessed consistently across the codebase by running the revised script above.
🏁 Script executed:
#!/bin/bash echo "Searching sideEffect in TypeScript files (.ts and .tsx):" rg -g '*.ts' -g '*.tsx' "sideEffect" -A 1 -B 1Length of output: 854
Plugin Validation Loop Refactor & SideEffect Consistency Check
The refactored plugin validation loop inpackages/hydrooj/src/service/hmr.ts
(lines 168–173) now iterates over plugins and retrieves the runtime separately while using the simpler check (if (!plugin['sideEffect'])
) as intended.However, our codebase search also revealed another instance in the same file using a more defensive pattern (
if (!plugin || !('sideEffect' in plugin) || !plugin['sideEffect'])
). Please verify whether this discrepancy is intentional or if the conditions should be unified for consistency.
- Refactored loop (lines 168–173) correctly uses
if (!plugin['sideEffect'])
.- An earlier block in the file uses the additional existence check on
plugin
and itssideEffect
.packages/hydrooj/src/service/api.ts
exportssideEffect
consistently.packages/hydrooj/src/service/bus.ts (4)
5-5
: Import usage looks good.
Using a type import from the framework is a clean approach, ensuring we don't bring in unnecessary code.
17-18
: Interface definition clarity.
DeclaringEventMap
in a single interface consolidates event definitions and streamlines event-related logic. Ensure that any dynamic or external events are also typed or otherwise handled gracefully to avoid runtime errors.
88-88
: Explicit handler type is consistent.
UsingHandler<Context>
for theoplog/log
event is consistent with the generics introduced elsewhere, improving type clarity for event subscribers.
33-33
:❓ Verification inconclusive
Confirm external references to broadcast events.
Switching fromkeyof ServerEvents
tokeyof EventMap
restricts the valid events that can be broadcast. Please verify and update any external code referencing events outside ofEventMap
.
🏁 Script executed:
#!/bin/bash # Verify references to the old 'bus/broadcast' usage to ensure they match the new signature rg -A 3 "bus/broadcast"Length of output: 1879
Action: Validate ‘bus/broadcast’ Event Keys Against the Updated EventMap
The change from
keyof ServerEvents
tokeyof EventMap
now restricts broadcast events to only those defined inEventMap
. Our repository search found the following usages:
- packages/prom-client/metrics.ts – The event is received as
name
for incrementing counters.- packages/hydrooj/src/model/task.ts – The event is handled with
(event, payload, trace)
.- packages/hydrooj/src/context.ts – The event is emitted via
ctx.emit
.Please confirm that each of these usages only references event keys present in
EventMap
. If any external code relies on events outside of this mapping, update either the event references or extendEventMap
accordingly.framework/framework/interface.ts (6)
1-5
: Modular approach to known handlers.
DefiningKnownHandlers
with specific handler entries, such as'NotFound': NotFoundHandler
, simplifies maintenance and ensures type safety. Good job.
7-14
: Flexible mapped event types.
Combining template literal types with yourMapHandlerEvents
andKnownHandlerEvents
provides powerful typing for your events. Just be sure that any downstream usage is thoroughly tested to catch any subtle type mismatches.
[approve]
15-17
: Generic handler events.
Extending event signatures with<C>
allows context-specific event hooks. This pattern is beneficial for large systems requiring specialized context handling.
21-23
: Restricting hook types.
UsingExclude<HookType, 'before-operation'>
forHookWithMethod
is a neat technique to disallow certain hook combinations. This approach prevents accidental usage of hooks in unsupported scenarios.
24-34
: Expanded ServerEvents interface.
The extendedServerEvents<C>
captures both known handler events and generic handler events, covering a wide range of scenarios. This provides a robust event system while maintaining strong typing.
36-38
: Extending third-party modules with generic events.
DeclaringEvents<C>
to extendServerEvents<C>
in@cordisjs/core
is a solid pattern. Confirm in your build/compilation steps that the augmentation merges properly and doesn't conflict with other type definitions in the same module.packages/hydrooj/src/service/server.ts (3)
8-10
: Generic imports from the framework.
Switching toHandlerOriginal<Context>
andConnectionHandlerOriginal<Context>
aligns with the new typed approach introduced throughout the codebase. This ensures context-aware handlers for both HTTP and WebSocket connections.
33-33
: Ensuring generics are fully utilized.
DeclaringHandlerCommon<C>
is a good step. Confirm that all usage sites either specify<Context>
or additional custom contexts as needed, to avoid unintentionalany
resolution.
135-135
: Framework plugin usage.
Replacing the direct import ofrequire('@hydrooj/framework')
withWebService
is a clean, modular approach. This clarified import fosters better maintainability and avoids bundling the entire framework when only the web service is needed.packages/hydrooj/src/context.ts (5)
1-3
: Imports look good.
These imports from@cordisjs/core
,@cordisjs/logger
, and@cordisjs/plugin-timer
appear consistent with the usage ofthis.plugin(TimerService);
andthis.plugin(Logger);
. No issues detected here.
29-29
: Confirm usage of re-exported entities.
You’re re-exportingDisposable
,Plugin
, andScopeStatus
from@cordisjs/core
. Ensure they’re actually used in this file or other files importing from here, otherwise they might be extraneous.
31-32
: Validate the property signature.
Using[Context.events]: EventMap & cordis.Events<Context>
is unusual. Verify thatContext.events
is indeed a valid property or symbol on thecordis.Context
. If it's meant to be a Symbol, ensure you have the correct reference to avoid type mismatches.
54-54
: Class extension looks coherent.
DefiningApiMixin
to extendcordis.Service<Context>
is consistent with other services. No immediate issues found.
75-75
: Logger plugin usage is fine.
Registering theLogger
plugin afterTimerService
is valid. Ensure your logging configuration is properly initialized so logs appear in the expected format/output.framework/framework/server.ts (8)
5-5
: Imports updated correctly.
ImportingContext as CordisContext
andService
from@cordisjs/core
aligns with the new context structures and type usage.
138-146
: Question the usage of.extend({})
.
Inside the constructor,this.ctx
is being re-assigned to(ctx as any).extend({})
. Verify that yourctx
is indeed an object or class with anextend
method. Otherwise, this can trigger runtime errors ifctx
does not meet that contract.
200-200
: Class extension is consistent.
Handler<C>
extendsHandlerCommon<C>
with additional methods. Recommend specifying constraints onC
if you rely on specific properties from context. Otherwise, good to proceed.
283-283
: ExplicitCordisContext
type.
Usingextends Handler<CordisContext>
is a valid approach for theNotFoundHandler
if you specifically only handle aCordisContext
. Looks consistent.
322-322
: GenericWebService
definition is sound.
Providing<C extends CordisContext = CordisContext>
is a flexible default. This should help with type safety across extended contexts.
337-338
: Initialize with config and context.
The constructor properly callssuper(ctx, 'server')
and mixes in server features. No immediate issues detected.
655-680
: Useless conditional onperm
Static analysis indicates thatif (perm)
may always evaluate to false under certain usage becauseperm
appears not to be set by typical flows. This is the same concern flagged in previous reviews or scanning tools.🧰 Tools
🪛 GitHub Check: CodeQL
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
766-771
: Module augmentation for@cordisjs/core
.
Augmentinginterface Context
withserver
,Route
, and others is a standard TypeScript approach. Make sure each property is set or at least defined at runtime to avoid undefined references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
framework/framework/server.ts (2)
128-129
:⚠️ Potential issueFix unsafe declaration merging
The empty interface
HandlerCommon<C>
followed by a class with the same name causes unsafe declaration merging. The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Use a type alias instead of an empty interface export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
655-679
:⚠️ Potential issueFix conditional logic in Checker function
The
Checker
function has been refactored to properly handle permission and privilege checking, but there's an issue in the returned checking function.The condition on line 676 is flagged by static analysis as always evaluating to false. This is because
perm
is initialized asundefined
and doesn't get properly assigned in some code paths.return function check(this: Handler<C>) { checker(); - if (perm) this.checkPerm(perm); + if (perm !== undefined) this.checkPerm(perm); if (priv) this.checkPriv(priv); };🧰 Tools
🪛 GitHub Check: CodeQL
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
🧹 Nitpick comments (5)
packages/hydrooj/src/plugin-api.ts (1)
56-58
: Use explicit side-effect import instead of empty export.
While this approach can load side effects from'./handler/contest'
, it's more conventional to use a side-effect import statement for clarity.Use this diff to switch to a side-effect import:
- // to load ctx.scoreboard - export { } from './handler/contest'; + // to load ctx.scoreboard + import './handler/contest';packages/hydrooj/src/model/user.ts (1)
468-486
: Consider adding error handling or logging for index creation.
Although creating these indexes in parallel is fine, you might want to handle or log possible failures to aid debugging.Example of adding minimal error handling:
export async function apply() { await Promise.all([ db.ensureIndexes( coll, { key: { unameLower: 1 }, name: 'uname', unique: true }, { key: { mailLower: 1 }, name: 'mail', unique: true }, ).catch(err => console.error('Error ensuring coll indexes:', err)), db.ensureIndexes( collV, { key: { unameLower: 1 }, name: 'uname', unique: true }, { key: { mailLower: 1 }, name: 'mail', unique: true }, ).catch(err => console.error('Error ensuring collV indexes:', err)), db.ensureIndexes( collGroup, { key: { domainId: 1, name: 1 }, name: 'name', unique: true }, { key: { domainId: 1, uids: 1 }, name: 'uid' }, ).catch(err => console.error('Error ensuring collGroup indexes:', err)), ]); }packages/hydrooj/src/model/domain.ts (1)
288-308
: Add optional logging to the new apply function.
Invokingctx.on('domain/delete-cache', ...)
is a good pattern. For improved observability, consider logging on domain cache deletion or whenever index creation completes.export async function apply(ctx: Context) { ctx.on('domain/delete-cache', async (domainId: string) => { const ddoc = await DomainModel.get(domainId); if (!ddoc) return; for (const host of ddoc.hosts || []) { cache.delete(`host::${host}`); } cache.delete(`id::${domainId}`); + console.info(`[domain/apply] Cache entries cleared for domain: ${domainId}`); }); await Promise.all([ db.ensureIndexes( coll, { key: { lower: 1 }, name: 'lower', unique: true }, ), db.ensureIndexes( collUser, { key: { domainId: 1, uid: 1 }, name: 'uid', unique: true }, { key: { domainId: 1, rp: -1, uid: 1 }, name: 'rp', sparse: true }, ), ]); + console.info('[domain/apply] Domain indexes ensured successfully'); }framework/framework/server.ts (2)
138-146
: Proper generic type implementation in HandlerCommon constructorThe constructor now accepts a generic context type parameter, improving type safety. However, there's an unsafe type cast on line 146 that could be improved with a proper type definition.
- this.ctx = (ctx as any).extend({}); + // Consider using a more specific type instead of 'any' + this.ctx = ctx.extend({});
708-710
: Fix TypeScript type annotation for Route methodThe
Route
method currently has a FIXME comment indicating it should use a more specific type rather thanany
for theRouteHandler
parameter.- // FIXME: should be typeof Handler<Context> instead of any - // eslint-disable-next-line @typescript-eslint/naming-convention - public Route(name: string, path: string, RouteHandler: any, ...permPrivChecker) { + // eslint-disable-next-line @typescript-eslint/naming-convention + public Route(name: string, path: string, RouteHandler: typeof Handler<C>, ...permPrivChecker) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
framework/framework/server.ts
(21 hunks)packages/hydrooj/src/handler/judge.ts
(2 hunks)packages/hydrooj/src/loader.ts
(3 hunks)packages/hydrooj/src/model/domain.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(2 hunks)packages/hydrooj/src/plugin-api.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/hydrooj/src/handler/judge.ts
🧰 Additional context used
🪛 Biome (1.9.4)
framework/framework/server.ts
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🪛 GitHub Check: CodeQL
framework/framework/server.ts
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (9)
packages/hydrooj/src/model/domain.ts (2)
4-4
: Importing Context is valid.
This new import correctly aligns with the addedapply
function’s signature.
6-6
: Default import from bus is consistent with other refactors.
Switching from a namespace import to a default import is in line with the broader shift in this update.packages/hydrooj/src/loader.ts (3)
142-150
: Good use of async/await for application initializationThe conversion of
preload()
to an async function using a Promise-based initialization pattern is a significant improvement. This ensures proper sequencing of the initialization steps and prevents potential race conditions when setting up the application context.
169-170
: Properly awaiting preload for sequential executionConverting the
load
function to async and awaiting thepreload()
function ensures the application is properly initialized before proceeding with additional setup steps.
207-209
: Appropriate async CLI initializationThe
loadCli
function correctly uses async/await pattern to ensure proper initialization sequence, matching the changes in theload
function.framework/framework/server.ts (4)
5-5
: Updated import to use new package structureThe change from importing
Context
to importingContext as CordisContext
from@cordisjs/core
aligns with the package structure changes mentioned in the PR summary.
200-200
: Good use of generic defaults in Handler classUsing
<C = CordisContext>
provides a sensible default while allowing for custom context types when needed, enhancing flexibility without sacrificing type safety.
246-246
: Generic type parameter added to ConnectionHandlerThe
ConnectionHandler
class now properly accepts a generic context type, aligning with the other handler classes for type consistency.
766-772
: Well-structured module declaration augmentationThe module declaration extends the
Context
interface to include the server-related properties with proper generic type handling, ensuring type safety when accessing these properties from a context instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/hydrooj/src/service/server.ts (2)
79-79
:⚠️ Potential issueAddress unsafe interface-class merge [noUnsafeDeclarationMerging].
The interface
Handler
(line 76) and classHandler
(line 79) share the same name, potentially causing issues with uninitialized interface fields. To avoid confusion and ensure full type checking, consider renaming the interface or incorporating its fields into the class.-export interface Handler { - domain: DomainDoc; -} -export class Handler extends HandlerOriginal<Context> { +interface IHandler { + domain: DomainDoc; +} +export class Handler extends HandlerOriginal<Context> implements IHandler { constructor(_, ctx) { super(_, ctx); ...🧰 Tools
🪛 Biome (1.9.4)
[error] 79-79: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
119-119
:⚠️ Potential issueLikewise address interface-class merge.
Same issue as above for
ConnectionHandler
. Interface and class share the same name, leading to potential confusion and partial type checks. Rename or integrate the interface into the class.-export interface ConnectionHandler { - domain: DomainDoc; -} -export class ConnectionHandler extends ConnectionHandlerOriginal<Context> { +interface IConnectionHandler { + domain: DomainDoc; +} +export class ConnectionHandler extends ConnectionHandlerOriginal<Context> implements IConnectionHandler { constructor(_, ctx) { super(_, ctx); ...🧰 Tools
🪛 Biome (1.9.4)
[error] 119-119: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🧹 Nitpick comments (1)
packages/hydrooj/src/context.ts (1)
75-75
: Added LoggerService to the Context constructor.The addition of LoggerService to the Context constructor ensures that logging capabilities are available throughout the application. This is a good enhancement for observability.
Consider documenting what features the LoggerService provides and how it should be used by developers working on the application.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/hydrooj/src/context.ts
(4 hunks)packages/hydrooj/src/service/server.ts
(8 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/hydrooj/src/service/server.ts
[error] 79-79: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
[error] 119-119: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (12)
packages/hydrooj/src/service/server.ts (7)
8-10
: Import statement updated to support generic typed framework components.The imports have been updated to use the original Handler and ConnectionHandler with generic typing, and WebService has been added as a new direct import. This supports the generic type improvements throughout the codebase.
33-33
: Good type enhancement to the HandlerCommon interface.Adding the generic type parameter
<C>
to the HandlerCommon interface improves type safety by making the interface more flexible and allowing it to work with different context types.
80-80
: Good simplification of constructor signature.The constructor signature has been simplified by removing explicit type declarations, as TypeScript can now infer the types from the generic parameter
<Context>
provided to the parent class.
120-120
: Good simplification of constructor signature.Similar to the Handler class, the constructor signature has been simplified by removing explicit type declarations which are now inferred from the generic parameter.
135-135
: Updated to use WebService directly instead of requiring the framework.The change from
require('@hydrooj/framework')
to directly using the importedWebService
is a good practice as it makes the dependency more explicit and can help with tree-shaking during builds.
222-222
: Minor improvement to router URL call.This change appears to be a slight modification to the method call but maintains the same functionality. It's a minor improvement to the code style.
283-296
: Enhanced error handling with new event handlers for HTTP and WebSocket connections.The addition of event handlers for 'handler/create/http' and 'handler/create/ws' with error checking logic is a good improvement. It ensures that any pending errors are properly thrown and handled early in the request lifecycle.
The implementation properly checks for
pendingError
in the context and throws it if present, which will trigger the appropriate error handling flow.packages/hydrooj/src/context.ts (5)
1-3
: Updated imports to use dedicated packages instead of a monolithic import.The import changes from 'cordis' to '@cordisjs/core' and addition of LoggerService and TimerService from their respective packages indicate a move towards a more modular architecture. This is a good practice that can lead to better tree-shaking and more explicit dependencies.
12-13
: TODO needs to be addressed for broken declaration.The comment acknowledges a broken declaration, and the code exports EventMap as Events. This should be prioritized for fixing since it could lead to type-related bugs.
Could you clarify what makes this declaration "broken"? Is it related to:
- EventMap compatibility with the rest of the system?
- A transition period during refactoring?
Consider either fixing the issue or adding more details about the problem in the TODO comment to help future developers.
29-29
: Updated exports to match new import sources.The exports have been updated to match the new import path from '@cordisjs/core' instead of 'cordis', which is consistent with the import changes at the top of the file.
31-32
: Improved type definition for Context interface.The Context interface has been simplified and improved by:
- Removing the Pick dependency
- Using EventMap with cordis.Events to properly type the events
This change enhances type safety while making the code more maintainable.
54-54
: Enhanced type safety with generic parameter on ApiMixin.Adding the generic type parameter
<Context>
to the ApiMixin class improves type safety by ensuring that the service correctly works with the Context type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
packages/hydrooj/src/service/server.ts (1)
76-78
: 🛠️ Refactor suggestionAddress unsafe interface-class merge.
The code has an unsafe interface-class merge issue where interfaces and classes share the same name. This pattern is flagged by TypeScript's linter as it may lead to uninitialized interface fields not being checked by the compiler.
Consider implementing the interface in the class definition instead:
-export class Handler extends HandlerOriginal<Context> { - domain: DomainDoc; -} +export class Handler extends HandlerOriginal<Context> implements { domain: DomainDoc } { + // The domain property is already implemented through inheritance +} -export class ConnectionHandler extends ConnectionHandlerOriginal<Context> { - domain: DomainDoc; -} +export class ConnectionHandler extends ConnectionHandlerOriginal<Context> implements { domain: DomainDoc } { + // The domain property is already implemented through inheritance +}This approach makes it explicit that the class is implementing these properties and avoids the interface-class merge warning.
Also applies to: 79-81
framework/framework/server.ts (2)
128-129
: 🛠️ Refactor suggestionResolve unsafe declaration merging.
There's an unsafe declaration merging issue with an empty interface and class sharing the same name. This pattern is flagged by TypeScript's linter as potentially problematic.
Replace the empty interface with a type alias or remove it completely:
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars -export class HandlerCommon<C> { +export class HandlerCommon<C> {Since the interface is empty, there's no need to keep it. If the intention was to allow for module augmentation, consider using a different approach or documentation to indicate this.
🧰 Tools
🪛 Biome (1.9.4)
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
481-483
: 🛠️ Refactor suggestionAddress type-checking TODOs/FIXMEs.
Several TODOs/FIXMEs have been added related to type checking issues, particularly with event emission. These should be properly addressed to maintain type safety throughout the codebase.
Instead of using type assertions to
any
, consider creating proper type definitions for the event handlers:// Define an interface for events interface ServerEvents<T> { 'handler/create': [handler: T, type: 'http' | 'ws']; 'handler/create/http': [handler: T]; 'handler/create/ws': [handler: T]; 'handler/error': [handler: T, error: Error]; 'handler/error/${string}': [handler: T, error: Error]; 'connection/create': [handler: T]; 'connection/active': [handler: T]; 'connection/close': [handler: T]; } // Update the Context interface interface Context { // Update methods to use typed events parallel<K extends keyof ServerEvents<T>, T>(event: K, ...args: ServerEvents<T>[K]): Promise<void>; serial<K extends keyof ServerEvents<T>, T>(event: K, ...args: ServerEvents<T>[K]): Promise<void>; }This would allow for proper type checking of event emissions without resorting to
any
casts.Also applies to: 535-536, 550-551, 579-582, 593-594, 632-633, 704-705
🧹 Nitpick comments (4)
packages/utils/lib/common.ts (1)
214-214
: Improved type safety in sortFiles function signature.The addition of a generic type parameter
T
that extends{ _id: string }
enhances type safety by preserving the full type of the input objects when they're returned. This change ensures that consumers of this function retain all type information about their objects, rather than getting back only objects with the minimal{ _id: string }
structure.Consider making the key parameter more type-safe as well by using a mapped type to ensure it's a key of T:
-export function sortFiles<T extends { _id: string }>(files: T[], key?: '_id'): T[]; +export function sortFiles<T extends { _id: string }>(files: T[], key?: keyof T & '_id'): T[];This would ensure that when a key is provided, it exists on the type T and is specifically the '_id' property.
packages/migrate/index.ts (1)
10-16
: Improved function signature to accept and forward multiple argumentsThis change enhances the flexibility of the
checkLock
function by using rest parameters and argument spreading, allowing it to accept an arbitrary number of arguments. The modification improves the function's adaptability for use with various script runners that might require different parameter signatures.function checkLock(innerCall) { - return async (args) => { + return async (...args) => { const cur = await SystemModel.get('migrate.lock'); if (cur) throw new SystemError(`migrate lock already exists: ${cur}, possible another migration is running`); - return innerCall(args); + return innerCall(...args); }; }packages/hydrooj/src/entry/cli.ts (1)
126-130
: Introduced asynchronous context modification with server dependency injectionThis change adds an important asynchronous step in the application initialization flow, ensuring the server dependency is properly injected into the context before proceeding with the remainder of the startup process. The context is reassigned after the dependency injection to ensure subsequent code uses the updated context.
The pattern used here (creating a new Promise and resolving it with the updated context) is appropriate for ensuring proper sequencing in the initialization process.
While this approach works, consider examining whether this initialization pattern could be standardized across other similar dependency injection flows in the application for consistency. You might also benefit from a more formalized dependency resolution system if similar patterns appear elsewhere.
packages/hydrooj/src/entry/common.ts (1)
45-45
: Simplified plugin loading API by removing redundant context parameterThe call to
ctx.loader.reloadPlugin
has been updated to remove thectx
parameter, which was redundant since the context is already available through the method's object. This change is part of a broader refactoring to simplify the plugin loading mechanism.The code now passes fewer parameters, making it cleaner, but verify that this pattern is consistently applied across the codebase.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
README.md
(1 hunks)framework/eslint-config/package.json
(1 hunks)framework/framework/package.json
(2 hunks)framework/framework/server.ts
(20 hunks)package.json
(4 hunks)packages/elastic/package.json
(1 hunks)packages/hydrojudge/package.json
(1 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/entry/cli.ts
(1 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/worker.ts
(2 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/service/server.ts
(6 hunks)packages/migrate/index.ts
(1 hunks)packages/ui-default/package.json
(4 hunks)packages/utils/lib/common.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/elastic/package.json
- packages/hydrojudge/package.json
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/hydrooj/src/entry/worker.ts
- package.json
- framework/framework/package.json
- packages/hydrooj/src/loader.ts
- packages/ui-default/package.json
🧰 Additional context used
🪛 Biome (1.9.4)
framework/framework/server.ts
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🪛 GitHub Check: CodeQL
framework/framework/server.ts
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (27)
packages/migrate/index.ts (5)
32-32
: Consistent use of rest parameter patternThis migration script runner is correctly updated to use the spread operator, aligning with the change in the
checkLock
function.
46-46
: Consistent use of rest parameter patternThis migration script runner is correctly updated to use the spread operator, matching the new implementation of the
checkLock
function.
57-57
: Consistent use of rest parameter patternThis migration script runner is correctly updated to use the spread operator, matching the new implementation of the
checkLock
function.
70-70
: Consistent use of rest parameter patternThis migration script runner is correctly updated to use the spread operator, matching the new implementation of the
checkLock
function.
85-85
: Consistent use of rest parameter patternThis migration script runner is correctly updated to use the spread operator, matching the new implementation of the
checkLock
function.packages/hydrooj/src/entry/cli.ts (1)
134-134
:✅ Verification successful
Updated plugin reload method signature
The call to
reloadPlugin
has been modified to remove thectx
parameter, consistent with changes in the plugin loading mechanism across the codebase. This suggests the method now relies on an internally stored context rather than requiring it to be passed explicitly.
🏁 Script executed:
#!/bin/bash # Verify how reloadPlugin is defined and used elsewhere in the codebase # Check the definition of reloadPlugin method to confirm it no longer expects the context parameter rg -A 5 "reloadPlugin.*?\(" --glob "*.ts" | grep -v "ctx, " || echo "No instances of old-style reloadPlugin calls found" # Check for any remaining instances of the old method signature that might need updating rg "reloadPlugin.*?\(ctx," --glob "*.ts" || echo "No remaining instances of old-style method calls found"Length of output: 2959
Plugin Reload Method Signature Verified as Updated
The usage in
packages/hydrooj/src/entry/cli.ts
is now aligned with the new method signature—only the plugin key, configuration, and an optional name are passed. Verification across the codebase confirmed that all invocations (incli.ts
,common.ts
, andworker.ts
) have removed the extraneous context parameter, and thereloadPlugin
definition inpackages/hydrooj/src/loader.ts
reflects this update.
- The call in
cli.ts
now correctly uses:ctx.loader.reloadPlugin(path.resolve(scriptDir, h), {}, `hydrooj/script/${h.split('.')[0]}`);- No occurrences of the old pattern (passing
ctx
as an argument) were found.framework/eslint-config/package.json (4)
11-11
: Updated De Morgan plugin to latest versionThe eslint-plugin-de-morgan has been updated to version 1.2.0, which may include improvements to logical expression handling.
16-16
: Updated React Hooks plugin to latest versionThe eslint-plugin-react-hooks has been updated to version 5.2.0, which likely includes improvements for detecting React Hooks issues and supporting newer React features.
22-25
:✅ Verification successful
Added TypeScript as an optional dependency
TypeScript has been added as an optional dependency with version ^5.8.2. This is a good practice as it ensures a compatible TypeScript version is available for the ESLint plugins without making it a strict requirement.
🌐 Web query:
Is TypeScript 5.8.2 the latest version, and what are its key features?
💡 Result:
TypeScript 5.8 is the latest stable version as of March 2025, with TypeScript 5.8.2 likely representing a minor patch within this release. This update introduces significant improvements to type safety, module interoperability, and developer tooling. Below are the key features and enhancements:
1. Granular Return Expression Checks
TypeScript 5.8 adds stricter checks for conditional expressions in return statements. Each branch of a return expression is now validated against the function's declared return type, catching errors where mismatched types might otherwise go unnoticed. For example:
declare const cache: Map<any, any>; function getURL(url: string): URL { return cache.has(url) ? cache.get(url) : url; // Error: 'string' not assignable to 'URL'[1][4][10]2. Improved CommonJS/ESM Interoperability
With Node.js 22+ support under the
--module nodenext
flag, CommonJS modules can nowrequire()
ECMAScript modules (ESM), simplifying library development and eliminating the need for dual publishing. This resolves long-standing compatibility issues between module systems[1][6][10].3.
--erasableSyntaxOnly
FlagThis new compiler option enforces syntax that can be fully erased during compilation, ensuring compatibility with Node.js’ experimental TypeScript execution mode. It disallows runtime-impacting TypeScript features like enums, namespaces, and parameter properties in classes[1][5][10].
4. Performance Optimizations
- Faster program loads/updates: Reduced path normalization overhead and avoided redundant configuration checks (e.g.,
tsconfig.json
validation) improve responsiveness in large projects[8][10].- Watch mode/editor efficiency: Updates to files now skip unnecessary revalidation steps when project structure remains unchanged[8][10].
5. Declaration File Improvements
Computed property names in classes are now preserved in declaration files instead of being rewritten as index signatures. This enhances predictability for consumers of
.d.ts
files[5][10].6. Module and Library Enhancements
--libReplacement
flag: Disables automatic lookup for@typescript/lib-*
packages, reducing overhead for projects not using custom type libraries[5][10].- Import assertion restrictions: The
assert
keyword for imports is deprecated in favor ofwith
under--module nodenext
, aligning with Node.js 22+ standards[10].7. Deferred Features
A planned feature for conditional return type checking was moved to TypeScript 5.9 due to implementation complexities. However, preparatory work enabled the granular return checks in 5.8[1][4][10].
TypeScript 5.8 focuses on refining type safety, modernizing module workflows, and optimizing tooling performance. Developers can install it via
npm install typescript
or explore nightly builds for upcoming 5.9 features[1][10].Citations:
- 1: https://www.infoworld.com/article/3836957/typescript-5-8-reaches-general-availability.html
- 2: https://www.youtube.com/watch?v=vcVoyLQMCxU
- 3: https://javascript.plainenglish.io/typescript-5-8-smarter-faster-and-more-efficient-30b5ea678ede
- 4: https://visualstudiomagazine.com/Articles/2025/03/04/TypeScript-5-8-Improves-Type-Checking-Conditional-Feature-Delayed-to-5-9.aspx
- 5: https://devblogs.microsoft.com/typescript/announcing-typescript-5-8-beta/
- 6: https://www.heise.de/en/news/TypeScript-5-8-improves-interoperability-between-CommonJS-and-ECMAScript-10301871.html
- 7: https://angular.dev/reference/versions
- 8: https://visualstudiomagazine.com/Articles/2025/01/29/TypeScript-5-8-Beta-Speeds-Program-Loads-Updates.aspx
- 9: https://en.wikipedia.org/wiki/TypeScript
- 10: https://devblogs.microsoft.com/typescript/announcing-typescript-5-8/
Approved: TypeScript ^5.8.2 is Correctly Configured
The
optionalDependencies
update inframework/eslint-config/package.json
now correctly specifies TypeScript version ^5.8.2. Our verification confirms that TypeScript 5.8 (with patch 5.8.2) is the latest stable release as of March 2025, and it brings useful improvements in type safety, module interoperability, and tooling performance. This optional dependency ensures that ESLint plugins have access to a compatible TypeScript without enforcing a strict requirement.
- Location:
framework/eslint-config/package.json
, lines 22-25- Snippet:
}, "optionalDependencies": { "typescript": "^5.8.2" }
8-9
:✅ Verification successful
Updated TypeScript ESLint dependencies to latest versions
The TypeScript ESLint plugin and parser have been updated to version 8.26.0, which likely includes bug fixes, new rule sets, and improved TypeScript language support.
🌐 Web query:
What are the major changes in @typescript-eslint/eslint-plugin version 8.26.0 compared to previous versions?
💡 Result:
The @typescript-eslint/eslint-plugin version 8.26.0 introduces several significant changes and enhancements. Here's a breakdown of the major updates:
🚀 Key Features and Enhancements
TypeScript 5.8 Support
- Full compatibility with TypeScript 5.8, ensuring accurate linting for new syntax and type-checking features[1][2].
Project Service Stabilization
- The experimental
projectService
option is now stable, replacingparserOptions.project
in many cases. It simplifies configuration and improves performance by leveraging TypeScript's editor-like project management[2][3].// Example configuration parserOptions: { projectService: true, // Automatically finds tsconfig.json tsconfigRootDir: import.meta.dirname, }New Rules and Rule Updates
- Added Rules:
no-empty-object-type
: Bans the{}
type in ambiguous contexts[2].no-require-imports
: Replaces the deprecatedno-var-requires
rule[2][3].no-unsafe-function-type
: Flags unsafeFunction
type usage[2].no-wrapper-object-types
: BansObject
,Number
, etc., in favor of primitives[2].- Enhanced Rules:
no-unnecessary-type-parameters
: Improved handling of tuples and array parameter locations[1].no-unused-var
: Now detects unused variables in declaration files with implicit exports[1].
🩹 Fixes and Optimizations
- Dependency Updates: Compatibility with ESLint v9 and other tooling improvements[1][4].
- Scope Manager: Reduced redundant
Object.entries
calls for type libs, improving performance[1].- Rule Fixes:
no-invalid-void-type
: Reports invalidvoid
types inaccessor
properties[1].no-unnecessary-type-assertion
: Handlesunknown
types correctly[1].unified-signatures
: Ignores overloads with differing JSDoc comments[1].
⚠️ Breaking Changes and Deprecations
- Deprecated Rules:
ban-types
was split into more targeted rules (no-empty-object-type
,no-unsafe-function-type
, etc.)[2][3].no-throw-literal
replaced byonly-throw-error
[3].- Configuration Presets Updated:
eslint:recommended
andrecommended-type-checked
now include stricter defaults[2][3].- Removed rules:
ban-types
,no-loss-of-precision
,no-var-requires
[2].
🛠️ Migration Steps
- Update Dependencies:
npm install @typescript-eslint/[email protected] @typescript-eslint/[email protected] --save-dev- Adopt
projectService
: Replaceproject: true
withprojectService: true
for faster, more reliable type-aware linting[2][3].- Review Rule Changes: Disable new rules if necessary or adjust configurations for stricter defaults.
For a full list of changes, see the v8.26.0 release notes[1].
Citations:
- 1: https://github.com/typescript-eslint/typescript-eslint/releases
- 2: https://typescript-eslint.io/blog/announcing-typescript-eslint-v8/
- 3: https://typescript-eslint.io/blog/announcing-typescript-eslint-v8-beta/
- 4: https://www.npmjs.com/package/eslint/v/8.26.0
- 5: https://forge.libre.sh/libre.sh/keycloak-scim/commit/ec54a065f7d719e838652d5d3d2bb1a312bc40ed
- 6: https://eslint.org/docs/latest/use/migrating-to-5.0.0
- 7: https://typescript-eslint.io/packages/eslint-plugin/
- 8: https://typescript-eslint.io/users/releases/
- 9: Bug: can not find flat file config eslint/eslint#16485
- 10: https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/aem-cloud-typescript-dependencies/m-p/657665
Updated TypeScript ESLint Dependencies to v8.26.0 – Leveraging TypeScript 5.8 and Enhanced Linting Capabilities
- The dependency upgrade in
framework/eslint-config/package.json
now sets both the ESLint plugin and parser to version 8.26.0.- This version brings full support for TypeScript 5.8, stable
projectService
configuration (which simplifiestsconfig.json
management), and introduces several new and enhanced rules (e.g., improved handling of empty object types, unsafe function types, and more).- The changes ensure better performance, improved configuration defaults, and overall more robust TypeScript linting without any visible removal or replacement in the diff snippet.
packages/hydrooj/src/entry/common.ts (1)
72-72
: Simplified plugin loading API by removing redundant context parameterSimilar to the change in the getLoader function, this call to
ctx.loader.reloadPlugin
has been updated to remove the redundantctx
parameter. This maintains consistency with the plugin loading mechanism changes throughout the codebase.README.md (2)
125-125
: Documentation improvement for installation warning.Good addition of a warning about shared memory (shm) space size during installation. This is important information for users, especially when deploying in containerized environments where shared memory limitations can cause issues.
127-134
: Good documentation of major architectural changes.The documentation clearly outlines important architectural changes:
- Upgrade to cordis@4
- Support for multiple renderers
- Separation of HMR and Watcher components
- Enhanced i18n with interface options
- New checker support
- Removal of legacy bus calls
- Enforced dependency declarations
These notes will be helpful for users upgrading from previous versions.
packages/hydrooj/package.json (2)
19-21
: Migration to namespaced cordis packages.Good transition from the monolithic
cordis
package to the modular@cordisjs/*
packages. This follows modern JavaScript packaging practices and should provide better maintainability and potentially reduced bundle sizes through more granular imports.
22-22
: Dependency updates to newer versions.Keeping dependencies updated is good practice for security and performance. Make sure to test the application thoroughly with these new versions to ensure compatibility.
Also applies to: 28-28, 46-46, 52-52, 67-67
packages/hydrooj/src/service/server.ts (7)
8-10
: Improved imports with type-safety.Good improvement on imports using type imports and adding
WebService
from the framework. This makes the dependencies clearer and will provide better type checking.
33-33
: Enhanced type-safety with generic interface.Converting
HandlerCommon
to a generic interface with type parameter<C>
improves type safety and flexibility. This allows the interface to adapt to different context types throughout the application.
84-93
: Improved plugin architecture.Great improvement to use
WebService
directly as a plugin instead of requiring the entire framework module. This follows better dependency injection practices and makes the code more maintainable.
222-245
: Well-structured error handling for HTTP handlers.The addition of the
httpHandlerMixin
with detailed error handling logic is a good improvement. It properly handles different error types, provides appropriate responses, and includes useful logging.The special handling for unauthenticated users encountering permission errors by redirecting to the login page is a nice UX touch.
247-255
: Consistent error handling for WebSocket connections.Good addition of error handling for WebSocket connections. The implementation properly logs errors while excluding common errors like NotFoundError when the user is not authenticated, which helps keep logs clean.
262-268
: Enhanced template rendering with domain support.The implementation of domain-specific template rendering is a good improvement. It attempts to load a domain-specific template first (
${s[0]}.${args.domainId}.${s[1]}
) and falls back to the generic template if not found.
270-283
: Improved error handling in handler creation.The addition of error checking for pending errors in the handler creation process is a good safety feature. This ensures that any errors that occurred during earlier stages of request processing are properly propagated.
framework/framework/server.ts (5)
5-5
: Migration to @cordisjs/core.Good update to import
Context as CordisContext
from@cordisjs/core
instead of using a local Context. This aligns with the package.json changes and moves toward using the namespaced cordis packages.
200-200
: Enhanced type safety with generics.Good improvement to make the
Handler
,ConnectionHandler
,NotFoundHandler
, andWebService
classes generic. This allows for better type checking and more flexible composition across the application.Also applies to: 246-246, 283-283, 322-322
655-679
: Improved permission and privilege checking logic.The reworked
Checker
function is a significant improvement. It properly handles different types of inputs (objects, numbers, bigints) and returns a function that checks permissions and privileges based on the provided arguments. This makes the code more maintainable and reduces duplication.🧰 Tools
🪛 GitHub Check: CodeQL
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
749-763
: Well-structured mixin implementation with effect hooks.The implementation of the mixin methods using
ctx.effect()
is excellent. This approach:
- Properly registers and unregisters the mixins when components are activated/deactivated
- Separates concerns between HTTP and WebSocket handlers
- Provides clean warnings when attempting to override existing methods
- Uses type-safe generics to ensure compatibility with the target classes
This implementation follows modern React-like patterns for managing side effects and cleanup.
Also applies to: 765-779, 781-794
807-814
: Enhanced type declarations for framework integration.The module augmentation for
@cordisjs/core
is well implemented. It ensures that theserver
,Route
,Connection
, andwithHandlerClass
properties are properly typed in the extendedContext
interface, providing proper type checking for users of the framework.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (17)
packages/migrate/scripts/hustoj.ts (2)
291-296
: Improved numeric handling with BigInt for large datasetsThe change to use BigInt for pagination logic is a good improvement that prevents potential numeric overflow when dealing with large datasets in migration scenarios.
However, be cautious about the conversion between BigInt and Number types in the progress reporting code.
Consider adding a comment explaining why BigInt is used here to help future maintainers understand the rationale:
- const [{ 'count(*)': _rcount }] = await query('SELECT count(*) FROM `solution`'); - const rcount = BigInt(_rcount); + // Using BigInt to handle potentially large solution counts that exceed Number.MAX_SAFE_INTEGER + const [{ 'count(*)': _rcount }] = await query('SELECT count(*) FROM `solution`'); + const rcount = BigInt(_rcount);
332-337
: Ensure safe conversion from BigInt to NumberWhen reporting progress, you're converting BigInt values to Number which could lead to precision loss with extremely large values.
Consider adding a safety check before the conversion:
- if (pageId % 10n === 0n) { - const progress = Math.round(((Number(pageId) * step) / Number(rcount)) * 100); - report({ - message: `record finished ${Number(pageId * BigInt(step))} / ${Number(rcount)} (${progress}%)`, - }); - } + if (pageId % 10n === 0n) { + // Safe conversion - ensure values don't exceed MAX_SAFE_INTEGER + const pageIdNum = pageId <= Number.MAX_SAFE_INTEGER ? Number(pageId) : Infinity; + const rcountNum = rcount <= Number.MAX_SAFE_INTEGER ? Number(rcount) : Infinity; + const processedNum = (pageId * BigInt(step)) <= Number.MAX_SAFE_INTEGER ? + Number(pageId * BigInt(step)) : Infinity; + + const progress = Math.round(((pageIdNum * step) / rcountNum) * 100); + report({ + message: `record finished ${processedNum} / ${rcountNum} (${progress}%)`, + }); + }packages/ui-default/index.ts (1)
77-77
: Configuration source updated to use context-specific settingsThis change moves from using a static configuration source to a context-specific one, aligning with the broader refactoring toward using the new ConfigService.
Add error handling to ensure the code doesn't break if the config settings are missing:
- const schema = convert(Schema.intersect(this.ctx.config.settings) as any, true); + const settings = this.ctx.config?.settings || {}; + const schema = convert(Schema.intersect(settings) as any, true);packages/import-qduoj/index.ts (1)
31-37
: Improved type safety for optional SPJ fieldThe change to make
spj
a union type withSchema.never()
increases type safety by explicitly modeling the absence of SPJ information. This is better than just making the field optional.Consider adding a comment to explain this pattern for clarity:
spj: Schema.union([ + // Using Schema.never() to explicitly represent cases where SPJ doesn't exist, + // providing better type safety than a simple optional field Schema.never(), Schema.object({ language: Schema.string().required(), code: Schema.string().required(), }), ]),packages/hydrooj/src/entry/worker.ts (2)
41-45
: Avoid reassigningctx
.
Reassigningctx
inside a promise may cause confusion. Considering a different variable name can improve clarity.- ctx = await new Promise((resolve) => { + const updatedCtx = await new Promise((resolve) => {
50-54
: Same overshadowing concern.
Similarly, reassigningctx
in another promise can hamper readability. A distinct variable name is preferable.packages/hydrooj/src/service/db.ts (1)
188-193
: Deprecated fallback proxy.
Thisdb
proxy depends on a globalapp
reference and could create unexpected behavior ifapp
is unavailable. Consider removing or gating usage more explicitly.packages/hydrooj/src/service/storage.ts (1)
391-415
: Security check for proxy route.
The rewrite logic and proxy usage are fine. However, consider adding security or rate-limiting to avoid exposing files unintentionally.packages/hydrooj/src/loader.ts (4)
50-50
: Consider specifying a more descriptive type forstate
UsingRecord<string, EffectScope>
is acceptable. However, static analysis warns against using{}
(observed in the subsequent line forpublic config
). If feasible, define a more robust interface or at least aRecord<string, unknown>
to improve clarity and enforce type safety.
58-62
: Handle interval cleanup
You are establishing a repeating check withctx.setInterval(...)
to log plugin states. Consider clearing this interval if the service is disposed or if the app shuts down, to avoid potential memory leaks or calls after the context is no longer valid.
100-108
: Returning an empty object if no schema
The logic to return{}
for plugins without a schema is convenient but may hide silent misconfigurations. Consider logging a warning or providing a default config to improve debuggability.
147-152
: Assigningglobal.app
Usingglobal.app
might introduce maintainability issues. If your codebase standardizes around it, that's acceptable, but stay mindful if multiple modules attempt to modifyglobal.app
concurrently.packages/hydrooj/src/settings.ts (4)
17-20
: Type definitions for configurations
UsingSchema[]
andany
might limit type safety. If possible, refinesystemConfig
to a structured type instead ofany
to reduce potential runtime errors.
29-39
: Error handling for config loading
This function parses YAML, logs on failure, and emits an event on success. Consider providing a fallback to default settings if parsing fails, to prevent partial system functionality.
77-83
: Configuration getter
Dot-notation traversal is handy but can fail silently if any subpath is undefined. Consider optional safety checks or default return values for more robust behavior.
85-119
: Dynamic config proxy
Providing aProxy
for config updates is powerful but can be harder to debug and can add overhead. Still, this pattern fosters a neat, reactive approach to configuration management.packages/hydrooj/src/model/setting.ts (1)
82-119
: Well-structured schema conversion functionThe
schemaToSettings
function is well implemented with proper error handling for unsupported structures. It correctly processes schema metadata and maps schema types to corresponding setting types.Consider adding a type guard or assertion for the return value of
schemaToSettings
to ensure type safety when used in the settings functions:-function schemaToSettings(schema: Schema<any>) { +function schemaToSettings(schema: Schema<any>): _Setting[] {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
README.md
(1 hunks)packages/hydrooj/src/entry/cli.ts
(3 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/worker.ts
(4 hunks)packages/hydrooj/src/handler/manage.ts
(1 hunks)packages/hydrooj/src/handler/misc.ts
(1 hunks)packages/hydrooj/src/interface.ts
(0 hunks)packages/hydrooj/src/loader.ts
(7 hunks)packages/hydrooj/src/model/setting.ts
(9 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/server.ts
(6 hunks)packages/hydrooj/src/service/storage.ts
(7 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/upgrade.ts
(2 hunks)packages/hydrooj/src/utils.ts
(2 hunks)packages/import-qduoj/index.ts
(1 hunks)packages/migrate/scripts/hustoj.ts
(2 hunks)packages/ui-default/index.ts
(2 hunks)
💤 Files with no reviewable changes (1)
- packages/hydrooj/src/interface.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/hydrooj/src/entry/common.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/manage.ts
[error] 198-198: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/loader.ts
[error] 51-51: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
🪛 GitHub Check: CodeQL
packages/hydrooj/src/settings.ts
[warning] 51-51: Prototype-polluting assignment
This assignment may alter Object.prototype if a malicious 'proto' string is injected from library input.
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (76)
README.md (1)
125-139
: Well-documented changes in the updateGood job documenting all the major changes in this update, especially architectural changes like the upgrade to cordis@4, the removal of global services, and the support for Schemastery in Settings.
These changes provide users with clear information about what to expect in this version.
packages/import-qduoj/index.ts (1)
108-115
:✅ Verification successful
Verify SPJ language check
The current code only handles SPJ in C++. After making
spj
optional with the union type, ensure this conditional still behaves as expected.
🏁 Script executed:
#!/bin/bash # Find all places where spj.language is checked to verify consistency rg "spj.*language" -A 5 -B 5Length of output: 3257
SPJ language conditional verified
I've confirmed via a repository-wide search that the only check on
spj.language
in the qduoj import code is on line 108 ofpackages/import-qduoj/index.ts
, where it evaluatesif (pdoc.spj?.language === 'C++')
. This optional chaining ensures that ifspj
is undefined (as allowed by the new union type), the condition safely returns false, thereby avoiding any unintended execution of the SPJ-related logic.Please double-check that supporting only the C++ SPJ is intentional. If additional SPJ languages should be supported in the future, adjustments to this conditional might be necessary.
packages/hydrooj/src/handler/misc.ts (1)
112-112
: Improved configuration management approach.The change to retrieve the file secret from context configuration instead of a static import is a good improvement. This promotes better dependency injection and makes the code more testable and configurable.
packages/hydrooj/src/entry/cli.ts (5)
9-11
: Updated imports for service-based architecture.Good restructuring to support the new service-based approach.
114-116
: Improved service initialization with dependency injection.The refactoring from direct service calls to plugin-based initialization improves modularity and follows better dependency injection practices.
117-122
: Enhanced dependency handling with Promise-based injection.This change ensures that the loader dependency is properly injected before proceeding. This is a good pattern for managing asynchronous dependencies.
133-137
: Consistent implementation of Promise-based dependency injection.Similar to the loader injection, this ensures the server dependency is available before proceeding with addon operations.
141-142
: Simplified plugin reloading.The removal of the ctx parameter from reloadPlugin call simplifies the function signature while maintaining functionality.
packages/hydrooj/src/upgrade.ts (2)
425-435
: Centralized configuration management.The migration from
setBuiltinConfig
toapp.get('config').setConfig
aligns with the project's move toward a service-based architecture for configuration management. This makes configuration handling more consistent and maintainable.
704-704
: Version marker added.The comment indicating the start of Hydro v5 provides useful versioning information for future reference.
packages/hydrooj/src/utils.ts (2)
1-2
: Added import for enhanced null checking.Good addition of the
isNullable
utility from cosmokit for more robust null/undefined checks.
22-29
: Improved module export handling logic.The refactored
unwrapExports
function is more readable and explicit in handling different cases. The updated structure with individual condition checks improves maintainability and the added comments about ESBuild interoperability provide helpful context.packages/hydrooj/src/entry/worker.ts (6)
10-11
: Smooth import additions.
No issues found here; the new imports forMongoService
andConfigService
appear straightforward.
26-26
: Verify null or empty string scenarios.
IfMongoService.getUrl()
returns''
orundefined
, ensureif (!url)
correctly handles that case.
37-38
: Registration order looks fine.
Plugging inMongoService
andConfigService
is consistent with the new approach.
46-46
: Plugin reload looks correct.
No problems found with reloading thestorage
service plugin.
69-69
: Plugin reload usage.
Reloading the handler plugin is consistent with your pattern.
76-76
: No issues found.
The script plugin reload mirrors the handler pattern with no evident problems.packages/hydrooj/src/handler/manage.ts (4)
186-186
: Circumvent direct config usage.
Referencingthis.ctx.config.configSource
is in line with the newConfigService
; no immediate concerns.
188-188
: Verify schema intersection behavior.
Ensure partial or invalid YAML doesn't yield downstream errors, though the try/catch is likely sufficient.
191-191
: Publicly exposing schema.
Generating a JSON representation of the intersected schema is a clean approach.
205-205
: Saving config seamlessly.
The call tothis.ctx.config.saveConfig(config)
fits the new config system well.packages/hydrooj/src/service/db.ts (9)
7-7
: New import is consistent.
Bringing inContext
andService
aligns well with the updated architecture.
11-11
: No concerns withbus
import.
Using this default import is a standard approach.
29-33
: Typed context extension.
Addingdb: MongoService
toContext
improves type safety and clarity.
35-35
: MongoService class hierarchy.
ExtendingService
is a straightforward design to group DB logic.
39-41
: Constructor pattern looks good.
super(ctx, 'db')
is consistent with naming for the service.
43-49
: Behavior in CI environment.
getUrl()
is managing in-memory Mongo for CI. Verify that production builds never setCI
inadvertently.
58-59
: Service setup method.
Using[Service.setup]
neatly triggers the initialization. Looks correct.
64-64
: Periodic collection maintenance.
fixExpireAfter()
each hour is generally fine, but watch out for performance overhead on large sets.
68-70
: Custom collection mapping.
LeveragingcollectionMap
is a clean solution for flexible naming.packages/hydrooj/src/service/storage.ts (10)
15-15
: Introduction ofkoa-proxies
.
Importingproxy
is reasonable for the new approach to file routing.
17-17
:nanoid
usage is appropriate.
A short, unique secret is a solid approach for config defaults.
18-18
: Schemastery import.
Ensures typed validation for storage configuration.
63-65
: Check default path logic.
Usingprocess.env.CI
plus a fallback is sensible. Confirm environment variables won't break references.
66-96
: ComprehensiveFileSetting
schema.
Good job unifying local and S3 storage definitions viaSchema.intersect()
.
98-99
: ExportingConfig
.
Re-exportingFileSetting
underConfig
is clear enough.
110-111
: RemoteStorageService constructor.
Injecting typed config fosters clarity for S3 usage.
307-308
: LocalStorageService constructor.
Similarly adopting typed config for local storage is consistent.
383-389
: Adaptive storage instantiation.
Falling back to local iftype === 'file'
is logical. You may want to guard against unknown types.
419-425
: Deprecated proxy retained.
Keeping a fallback export is fine but do encourage consumers to usectx.storage
.packages/hydrooj/src/loader.ts (8)
17-19
: Imports of context types are consistent.
These imports appear appropriate, and all the symbols (Context
,Service
,ScopeStatus
,EffectScope
) are indeed used in the file.
24-24
: Schemastery import usage
Using theschemastery
import for configuration schema handling is appropriate. Looks good.
56-56
: Dependency injection array
This injection array (['config', 'timer', 'i18n', 'logger']
) matches your usage. No issues found.
110-114
:reloadPlugin
method reuses the plugin object
The method updates the plugin config and optionally overridesplugin.name
. Ensure that overwritingplugin.name
does not disrupt other references or logging flows. Overall, the approach for retrieving and applying the plugin config is sound.
121-121
: Initialize plugin with resolved config
This is a straightforward call to initialize the plugin. Verify that each plugin can properly handle the passed-in config object to avoid unexpected runtime errors.
135-136
: Verbose error logging
Logging errors when plugin resolution fails is helpful for debugging. Ensure thaterr
does not contain sensitive information that might be exposed in logs.
172-172
: Synchronous loading
Callingawait preload()
ensures required dependencies and data are fully loaded before proceeding. This improves reliability of the loading process.
211-211
: Ensuring CLI preload
Awaitingpreload()
inloadCli()
helps unify the initialization path for CLI usage, maintaining consistency with the mainload()
method.packages/hydrooj/src/service/server.ts (6)
7-9
: Modular import from@hydrooj/framework
ImportingConnectionHandlerOriginal
,HandlerOriginal
, and related types from the framework improves clarity and modular design.
31-31
: Introducing generic parameter C
ExtendingHandlerCommon
to accept a generic context type fosters greater type flexibility. Ensure that downstream references use the new parameter consistently.
74-74
: Generic class extension forHandler
SwitchingHandler
to extendHandlerOriginal<Context>
clarifies the expected context type, enhancing type safety.
77-77
: Consistent usage of typedContext
inConnectionHandler
UsingConnectionHandlerOriginal<Context>
aligns with the approach inHandler
, ensuring uniform type handling.
82-82
: RegisteringWebService
Replacing direct framework usage with theWebService
plugin helps maintain a modular structure. Verify that prior functionality remains accessible through this plugin integration.
259-260
: Early error throw in WS handler
Immediately rejecting ifh.context.pendingError
is set prevents initiating any incomplete WebSocket operations. This “fail fast” method is beneficial for robust error handling.packages/hydrooj/src/settings.ts (9)
3-3
: Context and Service import
Importing these for the new settings architecture appears consistent with the overall service approach.
8-10
: Augmenting the Context interface
Addingconfig: ConfigService
ensures configuration logic is conveniently accessible across the application.
14-15
: NewConfigService
with DB injection
Deriving fromService
while injecting the DB dependency centralizes config logic. This is a cohesive design choice.
21-21
: Constructor ensures naming
Usingsuper(ctx, 'config')
clearly identifies this service. Maintains consistency with your injection pattern.
25-27
: Service setup ensures config loading
Overriding[Service.setup]
to invokeloadConfig()
ensures early retrieval of settings, aligning with service lifecycle expectations.
55-63
: Validation synergy
isPatchValid
reusesapplyDelta
andSchema.intersect
to verify patches. Ensure all update flows call this method to avoid bypassing checks.
65-71
: Schema intersection before saving
PerformingSchema.intersect(this.settings)(config)
ensures the config adheres to expected schemas before persistence. Nice defensive measure.
72-75
: Granular config updates
UsingapplyDelta
for partial config changes is flexible. Validate that multi-level paths are tested, especially if keys or sub-keys are missing.
120-121
: No additional functional changes
These lines appear to close out the class with no further modifications.packages/hydrooj/src/model/setting.ts (12)
3-3
: Package dependency update from 'cordis' to '@cordisjs/core'This change aligns with the broader project update to use the namespaced
@cordisjs/core
package instead of the originalcordis
package.
7-7
: Added Schema import from 'schemastery'The addition of Schema import is necessary to support the new schema-based settings functionality in this file.
74-80
: Good implementation of Schemastery namespace declarationThe global declaration for Schemastery namespace properly defines the Meta interface with a family property, which will be used for schema metadata.
121-122
: Improved settings function to support Schema objectsThe
PreferenceSetting
function now accepts both _Setting arrays and Schema objects, using the newschemaToSettings
function to convert Schema objects to _Setting arrays when needed.
141-142
: Improved AccountSetting function to support Schema objectsSimilar to PreferenceSetting, the AccountSetting function now supports Schema objects as input.
161-162
: Improved DomainUserSetting function to support Schema objectsDomainUserSetting now accepts Schema objects and converts them to _Setting objects appropriately.
177-178
: Improved DomainSetting function to support Schema objectsDomainSetting function now handles Schema objects, consistent with the other setting functions.
193-194
: Improved SystemSetting function to support Schema objectsSystemSetting now supports Schema objects, completing the consistent pattern across all setting functions.
351-351
: Updated module declaration to use '@cordisjs/core'This change is consistent with the import update at the top of the file, ensuring type compatibility with the new package.
380-380
: Added dependency injection specificationThe addition of the 'inject' export specifies that the 'db' service is a dependency for this module, making dependencies explicit.
388-388
: Improved database access with context-aware approachChanged from using the global database service to using the context-bound database service, improving modularity and testability.
412-413
: Updated model export to include the inject propertyThis ensures that the dependency requirements are properly exposed in the global model object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
framework/framework/server.ts (3)
128-129
:⚠️ Potential issueFix unsafe declaration merging and empty interface
The empty interface followed by a class with the same name creates unsafe declaration merging in TypeScript. The compiler won't check if properties defined in the interface are initialized in the class.
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Use a type alias instead if needed, or remove entirely as the class already defines the structure export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
481-483
: 🛠️ Refactor suggestionCreate proper type definitions for event handlers
Multiple type casts to
any
with FIXME comments indicate a need for proper typing of event handlers.Consider creating a proper event definition interface:
interface HandlerEvents<T> { 'handler/create': [handler: T, type: 'http' | 'ws']; 'handler/create/http': [handler: T]; // Define other event types similarly } // Then extend the Context interface to include typed events
676-676
:⚠️ Potential issueFix condition that always evaluates to false
The condition
if (perm)
is flagged by static analysis as always evaluating to false.The issue might be that
perm
is initialized asundefined
and the type checking logic doesn't properly assign it. Consider checking ifperm
is being assigned correctly in the loop above:- if (perm) this.checkPerm(perm); + if (perm !== undefined) this.checkPerm(perm);Alternatively, initialize
perm
with a falsy value that's not undefined:- let perm: bigint; + let perm: bigint | undefined;🧰 Tools
🪛 GitHub Check: CodeQL
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
🧹 Nitpick comments (3)
framework/framework/server.ts (3)
146-146
: Remove explicit any type assertionType assertions to
any
defeat TypeScript's type checking. Consider creating a proper type definition for the context extension method.- this.ctx = (ctx as any).extend({}); + this.ctx = ctx.extend({});If the
extend
method isn't properly typed in the context type, consider enhancing the type definition instead of usingany
.
187-188
: Avoid type assertions to any for renderersInstead of using
any
, properly typethis.ctx.server.renderers
.- const renderers = Object.values((this.ctx as any).server.renderers as Record<string, Renderer>) + const renderers = Object.values(this.ctx.server.renderers as Record<string, Renderer>)
708-710
: Address FIXME comment with proper type definitionThe FIXME comment indicates a need for proper typing of the
Route
method parameter.Define a proper type for RouteHandler instead of using
any
:- // FIXME: should be typeof Handler<Context> instead of any - // eslint-disable-next-line @typescript-eslint/naming-convention - public Route(name: string, path: string, RouteHandler: any, ...permPrivChecker) { + // eslint-disable-next-line @typescript-eslint/naming-convention + public Route<T extends CordisContext = C>(name: string, path: string, RouteHandler: typeof Handler<T>, ...permPrivChecker) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
framework/framework/server.ts
(21 hunks)packages/hydrooj/src/entry/cli.ts
(3 hunks)packages/hydrooj/src/entry/worker.ts
(4 hunks)packages/hydrooj/src/model/setting.ts
(10 hunks)packages/hydrooj/src/model/user.ts
(3 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/hydrooj/src/plugin-api.ts
🧰 Additional context used
🪛 Biome (1.9.4)
framework/framework/server.ts
[error] 128-128: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 129-129: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🪛 GitHub Check: CodeQL
framework/framework/server.ts
[warning] 676-676: Useless conditional
This use of variable 'perm' always evaluates to false.
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (31)
packages/hydrooj/src/model/user.ts (3)
12-12
: Updated bus import patternThe import statement for bus has been changed from namespace import to default import, which aligns with the broader pattern change across the codebase mentioned in the PR summary.
212-214
: Added static references to utility functionsAdding static references to existing functions enhances the class interface by making these utilities accessible through the UserModel class directly. This improves code organization and follows good OOP principles.
471-489
: Introduced async initialization patternThe new
apply
function replaces the previous event listener approach with a more explicit initialization pattern. This is a good architectural improvement that:
- Makes the initialization sequence more deterministic
- Uses Promise.all for efficient parallel database index creation
- Aligns with the asynchronous initialization pattern mentioned in the PR summary
This approach provides better control over the application startup sequence.
packages/hydrooj/src/entry/cli.ts (5)
9-11
: Updated imports to support the new service architecture.The imports have been updated to align with the new architecture, introducing
loadOptions
,MongoService
, andConfigService
. This is part of the broader refactoring to improve dependency management.
114-115
: Services now initialized as plugins rather than direct calls.The direct calls to database initialization and config loading have been replaced with a more modular plugin-based approach. This improves testability and allows for better dependency management.
117-122
: Added async context injection for the loader.This Promise-based pattern ensures that the loader dependency is available before proceeding, which is a more robust approach to handling dependencies. This aligns with the async refactoring across the codebase.
133-137
: Added async context injection for the server component.Similar to the loader injection, this ensures the server component is fully initialized before proceeding with addon loading and other operations that might depend on it.
141-142
: Simplified plugin reloading call.The plugin reloading call has been simplified by removing the explicit ctx parameter, which is now handled internally. This is a cleaner approach that reduces parameter passing.
packages/hydrooj/src/entry/worker.ts (7)
10-11
: Updated imports for the new service architecture.Similar to cli.ts, imports have been updated to support the new plugin-based service architecture with
MongoService
andConfigService
.
26-30
: Improved database URL retrieval with async pattern.Now uses an async approach to retrieve the MongoDB URL before initializing the setup process if needed. This provides better flow control and error handling.
37-38
: Services now initialized as plugins.Consistent with the changes in cli.ts, database and configuration services are now initialized as plugins, enhancing modularity.
41-48
: Added async context injection and improved plugin initialization.The code now ensures the loader is fully initialized before proceeding and introduces better plugin management. The addition of HMR service with a watch option enhances development capabilities.
50-54
: Added async context injection for the server component.Similar to the loader injection, this ensures proper initialization sequencing for components that depend on the server.
69-70
: Simplified plugin reloading for handlers.Removed unnecessary ctx parameter in the reloadPlugin call, consistent with other similar changes in the codebase.
76-77
: Simplified plugin reloading for scripts.Similar simplification as with handlers, maintaining consistency in the plugin loading approach across the codebase.
packages/hydrooj/src/model/setting.ts (13)
3-8
: Updated imports to use namespaced package and added Schema support.The import from 'cordis' has been updated to '@cordisjs/core', and Schema from 'schemastery' has been added to support the new declarative settings approach.
74-80
: Added global declaration for Schemastery namespace.This extends the global type definitions to include the Schemastery namespace with a Meta interface that includes a 'family' property. This enables type safety when working with schema metadata.
82-119
: Added schemaToSettings function for converting Schema to Setting objects.This utility function enables a more declarative approach to defining settings using Schema objects. It correctly handles various schema types and includes appropriate error handling for unsupported structures.
121-123
: Updated PreferenceSetting to support Schema objects.The function now accepts both _Setting arrays and Schema objects, with conversion handled through the new schemaToSettings function. This provides more flexibility in how settings are defined.
141-143
: Updated AccountSetting to support Schema objects.Similar to PreferenceSetting, this function now supports both traditional setting arrays and schema-based definitions.
161-163
: Updated DomainUserSetting to support Schema objects.Consistent with other setting functions, this now supports schema-based definitions.
177-179
: Updated DomainSetting to support Schema objects.Consistent with other setting functions, this now supports schema-based definitions.
193-195
: Updated SystemSetting to support Schema objects.Consistent with other setting functions, this now supports schema-based definitions.
290-317
: Added Schema-based setting definition example.This showcases the new declarative approach to defining settings using Schema objects. The approach provides better type safety and structure compared to the previous array-based approach.
359-363
: Updated module declaration to reference @cordisjs/core.This aligns with the import change at the top of the file, maintaining consistency in the module references.
388-388
: Added inject property to specify database dependency.This explicitly declares the database dependency, improving clarity around required services.
396-397
: Updated database access to use context.Changed from using the global Hydro service to ctx.db, which is more aligned with the context-based approach used throughout the codebase.
420-421
: Added inject property to global model.Ensures the dependency information is available to the global model, maintaining consistency with the service-based approach.
framework/framework/server.ts (3)
719-725
: Nice improvement with effect-based registrationUsing
ctx.effect()
for layer registration is a good pattern as it automatically handles cleanup when the context is disposed.
749-763
: Good implementation of handler mixins with proper cleanupThe implementation of mixins using
ctx.effect()
ensures proper registration and cleanup of prototype modifications, enhancing the maintainability of the codebase.
807-813
: Good use of module augmentation for type safetyThe module declaration enhances type safety by properly typing the context extensions, ensuring correct types are used throughout the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (4)
framework/framework/server.ts (4)
129-130
: 🛠️ Refactor suggestionFix unsafe declaration merging.
The empty interface
HandlerCommon<C>
followed by a class with the same name creates an unsafe declaration merging pattern in TypeScript. The linter also flags this as problematic.Consider using a type alias instead of an empty interface:
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Use a type alias if you need to augment the class type +export type HandlerCommonType<C> = HandlerCommon<C>; export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 129-129: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 130-130: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
487-489
: 🛠️ Refactor suggestionAddress type checking TODOs for event emission.
Several type casts to
any
have been added withFIXME
comments for event-related methods.Create proper type definitions for the event handlers to maintain type safety throughout the codebase:
// Add to your interface file interface HandlerEvents<T> { 'handler/create': [handler: T, type: 'http' | 'ws']; 'handler/create/http': [handler: T]; // Add other event types } // Then update the Context interface to include these typed events
662-686
:⚠️ Potential issueFix condition that always evaluates to false.
In the
Checker
function, theperm
variable is being initialized incorrectly, causing theif (perm)
condition at line 683 to always evaluate to false.The issue is that you're using assignment without updating the variable correctly:
const Checker = (args) => { - let perm: bigint; - let priv: number; + let perm: bigint | undefined; + let priv: number | undefined; let checker = () => { }; for (const item of args) { if (typeof item === 'object') { if (typeof item.call !== 'undefined') { checker = item; } else if (typeof item[0] === 'number') { - priv = item; + priv = item[0]; } else if (typeof item[0] === 'bigint') { - perm = item; + perm = item[0]; } } else if (typeof item === 'number') { priv = item; } else if (typeof item === 'bigint') { perm = item; } } return function check(this: Handler<C>) { checker(); if (perm) this.checkPerm(perm); if (priv) this.checkPriv(priv); }; };🧰 Tools
🪛 GitHub Check: CodeQL
[warning] 683-683: Useless conditional
This use of variable 'perm' always evaluates to false.
794-796
:⚠️ Potential issueFix wsHandlerMixin implementation.
The
wsHandlerMixin
method warns about existing properties but doesn't actually assign the new properties, making it ineffective.All the other mixin methods use
_applyMixin
which properly assigns properties, but this method doesn't:public wsHandlerMixin(MixinClass: Partial<ConnectionHandler<C>>) { - return this._applyMixin(ConnectionHandler, MixinClass); + this._applyMixin(ConnectionHandler, MixinClass); + return; }
🧹 Nitpick comments (1)
framework/framework/server.ts (1)
147-147
: Avoid type casting when extending context.The use of
as any
when calling.extend()
on the context circumvents type checking, which contradicts the PR's goal of improving type safety.Consider creating a proper type for the context's extend method:
-this.ctx = (ctx as any).extend({}); +this.ctx = ctx.extend({});Add proper type definitions for the extend method in the CordisContext interface if needed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
build/prepare.js
(1 hunks)framework/framework/server.ts
(21 hunks)
✅ Files skipped from review due to trivial changes (1)
- build/prepare.js
🧰 Additional context used
🪛 Biome (1.9.4)
framework/framework/server.ts
[error] 129-129: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 130-130: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🪛 GitHub Check: CodeQL
framework/framework/server.ts
[warning] 683-683: Useless conditional
This use of variable 'perm' always evaluates to false.
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (3)
framework/framework/server.ts (3)
809-816
: Good use of TypeScript module augmentation.The module declaration correctly extends the
@cordisjs/core
Context interface with the WebService methods using thethis
type to maintain type relationships.This is a good pattern for extending external types while preserving type safety and self-referential relationships.
756-778
: Great implementation of the _applyMixin method.The new
_applyMixin
method is well-designed, featuring:
- Type checking for the target
- Clean setup and teardown through the effect pattern
- Proper warning messages for existing properties
- Restoration of original values during cleanup
This represents a significant improvement over the previous implementation.
201-203
: Good use of generic defaults.The Handler class now properly uses generics with default types, improving both flexibility and backward compatibility.
export class Handler<C = CordisContext> extends HandlerCommon<C> {This approach allows existing code to work without changes while enabling new code to specify custom context types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (10)
packages/ui-default/locales/zh.yaml (1)
492-493
: New Localization Entries for Domain Actions Added
The entries"Join Domain to Create a Discussion: 加入域后创建讨论"
and"Join Domain to Submit: 加入域后递交"
are newly added. These phrases provide clear instructions to users about the actions required before participating in discussions or submissions within a domain. Please verify that these keys are referenced consistently throughout the UI.packages/ui-default/templates/partials/problem_sidebar_normal.html (2)
20-22
: Enhanced Discussion Creation Prompt
The conditional branch that checksnot handler.user._dudoc.join
to render the "Join Domain to Create a Discussion" link is a user-friendly enhancement. Ensure that the property_dudoc.join
accurately reflects the user’s current domain membership, and that thejoinDomain()
JavaScript function is implemented to handle the join flow seamlessly.
52-55
: Consistent Submission Prompt
For the problem submission section, the template now shows a disabled link prompting users to "Join Domain to Submit" when they are not members. Verify that using a disabled link in this context meets your accessibility standards and that thejoinDomain()
function is available to guide the user through the joining process.packages/ui-default/templates/domain_user.html (1)
85-87
: User Join Status Indicator
Introducing a conditional check to display “(Not joined yet)” next to a user’s name (whenudoc.join
is false) provides users with immediate feedback about membership status. Please verify that the styling with thetext-orange
class meets your interface’s accessibility contrast requirements.packages/hydrooj/src/model/setting.ts (2)
122-141
: Refactor duplicate setting key handling
Now thatPreferenceSetting
accepts both_Setting
objects andSchema
objects, consider stronger collision management beyond just logging a warning.
291-319
: Role-based validation
For.role('url')
or other roles, ensure you have custom validation (if needed) to avoid unexpected user input.packages/hydrooj/src/handler/home.ts (1)
471-471
: Fix the empty object destructuring pattern.The code uses an empty object destructuring pattern which is flagged by static analysis. Consider using a proper parameter name or remove the destructuring if not needed.
-async get({ }, all: boolean) { +async get(_: any, all: boolean) {🧰 Tools
🪛 Biome (1.9.4)
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/domain.ts (1)
136-138
: Use Array.isArray() instead of instanceof Array.The
instanceof Array
check can be unreliable when dealing with arrays from different frames or contexts. UsingArray.isArray()
is more reliable.-if (!(uid instanceof Array)) { +if (!Array.isArray(uid)) {🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
packages/hydrooj/src/handler/domain.ts (2)
153-160
: Consider using performance-friendly alternatives to delete.The static analysis tool flags the use of
delete u.user
which can impact performance. Consider using assignment to undefined instead.- delete u.user; + u.user = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
338-339
: Consider using performance-friendly alternatives to delete.Similar to the previous comment, the use of
delete this.joinSettings
can impact performance. Consider using assignment to undefined instead.- if (assignedRole !== 'default') delete this.joinSettings; + if (assignedRole !== 'default') this.joinSettings = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/home.ts
(3 hunks)packages/hydrooj/src/model/domain.ts
(8 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/user.ts
(4 hunks)packages/hydrooj/src/service/server.ts
(8 hunks)packages/hydrooj/src/upgrade.ts
(4 hunks)packages/ui-default/locales/zh.yaml
(5 hunks)packages/ui-default/templates/domain_join.html
(2 hunks)packages/ui-default/templates/domain_join_applications.html
(0 hunks)packages/ui-default/templates/domain_permission.html
(0 hunks)packages/ui-default/templates/domain_user.html
(2 hunks)packages/ui-default/templates/home_domain.html
(1 hunks)packages/ui-default/templates/partials/problem_sidebar_normal.html
(2 hunks)
💤 Files with no reviewable changes (2)
- packages/ui-default/templates/domain_join_applications.html
- packages/ui-default/templates/domain_permission.html
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/hydrooj/src/model/user.ts
- packages/hydrooj/src/service/server.ts
🧰 Additional context used
🧬 Code Definitions (3)
packages/hydrooj/src/handler/home.ts (1)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(307-315)
packages/hydrooj/src/model/domain.ts (3)
packages/hydrooj/src/service/bus.ts (1) (1)
apply
(97-114)packages/hydrooj/src/service/db.ts (1) (1)
apply
(180-183)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)
packages/hydrooj/src/model/setting.ts (3)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/db.ts (1) (1)
apply
(180-183)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/home.ts
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/hydrooj/src/handler/domain.ts
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (48)
packages/ui-default/locales/zh.yaml (2)
608-608
: Added Status Indicator for Unjoined Users
The new entry"Not joined yet: 暂未加入"
offers a clear status message for users who have not yet joined a domain. Confirm that this text is used consistently in contexts where a user's join status is displayed.
909-909
: New Entry for Domain Ownership Label
The addition of"The domain owner: 域所有者:"
enhances clarity by explicitly denoting the ownership of a domain. Ensure that this translation aligns with the design guidelines and is applied wherever domain ownership is presented in the interface.packages/hydrooj/src/upgrade.ts (4)
39-40
: Good addition: MongoDB read preference setting for consistencyAdding the
onPrimary
constant withreadPreference: 'primary'
ensures data is read from the primary node, which is important for data consistency during migration operations.
56-56
: Linting comment addedThe lint directive
// oxlint-disable-line no-new-array
is properly added to suppress warnings about using thenew Array()
constructor.
427-428
: Configuration management refactoredThe change from
setBuiltinConfig
toapp.get('config').setConfig
indicates a shift to a more modular approach using dependency injection for configuration management.
706-723
: Well-structured migration script for Hydro v5This migration script properly:
- Sets
join: true
for all users in domains- Configures default
_join
settings for domains that lack them- Ensures users with ID > 1 are added to the 'system' domain
- Uses
onPrimary
read preference for data consistencyThe migration handles both updating existing records and inserting new ones with the upsert option.
packages/ui-default/templates/home_domain.html (1)
40-40
: Context Variable Validation for 'role'
The expression{{ role[ddoc._id]|default('default') }}
now replaces the previous lookup viadudict
. Please ensure that the variablerole
is reliably provided in the template context and that its structure aligns with the expected data keys (i.e. domain IDs).packages/ui-default/templates/domain_join.html (4)
8-12
: Dynamic Title Rendering Based on Join Settings
The conditional title rendering—choosing between “Join {domain name}” and “You are invited to join {domain name}” based on the presence ofjoinSettings
—is clear and effective. Please confirm thatjoinSettings
is consistently defined in the template context for all scenarios.
18-21
: Display of Domain Owner Information
Rendering the domain owner with{{ user.render_inline(domainInfo['owner']) }}
provides important context for the user. Just ensure that the helper function properly escapes content to avoid any potential XSS issues.
22-26
: Conditional Rendering for Domain Bulletin
The new block that renders the domain bulletin (with markdown filtering) enriches the page content. Verify that themarkdown
filter is configured securely and does not inadvertently allow unsafe HTML.
40-41
: Hidden Input Fields for Navigation
The additions of hidden input fields fortarget
andredirect
are useful for maintaining proper navigation after form submission. Ensure that these parameters are validated server-side to prevent open redirect vulnerabilities.packages/ui-default/templates/domain_user.html (1)
105-107
: Consistent User Status in Listings
The similarly applied check forrudoc.join
in the second user loop helps maintain a consistent UI. Confirm that the inline rendering of user information alongside the join status message is uniform across the application.packages/hydrooj/src/model/setting.ts (12)
3-3
: Switching to@cordisjs/core
for cordis imports
No issues noticed. This change aligns with the updated package references throughout the PR.
7-7
: Addschemastery
to your project dependencies
This is the same concern raised in a past review. Please confirm that you've includedschemastery
in eitherdependencies
ordevDependencies
to avoid runtime errors.
74-81
: Global declaration for Schemastery
DeclaringMeta<T>
within theSchemastery
namespace is appropriate, and your optional fields look properly typed.
142-161
: Same feedback as PreferenceSetting
Look into more robust collision resolution when combining_Setting
andSchema
expansions.
162-177
: Same feedback as PreferenceSetting
Ensure collisions are handled gracefully, preventing perpetual warnings.
178-193
: Same feedback as PreferenceSetting
Domain setting expansions would benefit from a more consistent collision strategy.
194-209
: Same feedback as PreferenceSetting
Enhanced collision detection flows are recommended as you introduce schema-based settings.
279-279
: New DomainUserSetting field
No functional issues spotted with this addition.
361-365
: Augmenting theContext
interface
Addingsetting
toContext
neatly integrates theSettingService
into the existing framework.
390-390
: Dependency injection
Introducing'db'
ininject
cleanly hooks up the required database resource for the service.
398-401
: Consider fallback or error handling for database interaction
Ifctx.db
is ever undefined or unavailable, this could raise exceptions. It's good practice to handle potential failures or provide a fallback path.Would you like me to generate a script to verify
ctx.db
initialization throughout the lifecycle?
422-423
: Exportinginject
Exposinginject
in the globalHydro.model.setting
object ensures consistency with the injection pattern used in other services.packages/hydrooj/src/handler/home.ts (8)
184-184
: Good extraction of context dependencies.Extracting the geoip service from context makes the code more maintainable and follows the dependency injection pattern.
192-195
: Improved code readability and maintainability.Using the extracted geoip variable makes the code cleaner and more readable.
205-205
: Consistent usage of the extracted dependency.Good consistency in using the extracted geoip variable throughout the handler.
472-474
: Good type definitions for variables.The new code provides explicit typing with
DomainDoc[]
for ddocs andRecord<string, string>
for role, which improves type safety.
475-476
: Consider centralizing domain user retrieval logic.The method
domain.getDictUserByDomainId
is now usingjoin: true
filtering in its implementation, which is why it's used here in the if block. This is a good refactoring, but make sure this change is consistent with all usages of this method.
477-481
: Clear variable naming and usage.Renaming from
res
toddocs
makes the code more self-documenting about what the variable contains.
483-488
: Logical simplification of role assignment.The code now directly assigns 'root' role for users with PRIV_MANAGE_ALL_DOMAIN privilege, which is cleaner than the previous implementation.
497-497
: Simplified response body structure.The response now directly includes the role mapping rather than including the entire dudict, which is more efficient and cleaner.
packages/hydrooj/src/model/domain.ts (7)
137-137
: Good use of conditional spread operator.Using the spread operator with a conditional is a clean way to optionally include the
join
property in the update object.
148-148
: Improved updateMany operation.The updateMany operation now applies the same update logic as the single document update, maintaining consistency.
131-132
: Added join filtering to user counting.The countUser method now correctly filters by users who have joined the domain, which is consistent with the overall changes in this PR.
209-209
: Enhanced permission check for domain role.The added condition ensures that users who haven't joined the domain are treated as guests unless they have the VIEW_ALL_DOMAIN privilege, which improves security.
255-255
: Consistent join filtering for user queries.The getDictUserByDomainId method now filters for users who have joined the domain, which is consistent with other changes in this PR.
62-62
: Improved user role setting with autojoin.Setting autojoin to true when adding a domain owner is a logical enhancement to ensure the owner is properly joined to their domain.
288-308
: Well-structured context application function.The new apply function follows a consistent pattern for service registration and initialization. It centralizes event handling and index creation in one place, which is a good practice.
packages/hydrooj/src/handler/domain.ts (9)
105-150
: Improved MongoDB aggregation pipeline for user retrieval.The refactoring to use MongoDB's aggregation pipeline is a significant improvement. It:
- More efficiently fetches user data in a single query instead of separate lookups
- Properly filters users based on both role and join status
- Projects only the necessary fields, reducing data transfer
This is a good optimization for performance and maintainability.
161-163
: Simplified rudocs construction.The code now creates the rudocs object more directly from the filtered users array, which is cleaner and more efficient.
261-261
: Broader role inclusion for domain applications.Changing the filter to only exclude 'guest' (instead of both 'default' and 'guest') makes more roles available for domain join applications, which is likely the intended behavior.
325-340
: Enhanced domain join preparation with target parameter.Adding the target parameter provides more flexibility in the domain join process, allowing users to join domains other than the current one. The role assignment logic is also improved to handle privileged users appropriately.
🧰 Tools
🪛 Biome (1.9.4)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
343-345
: Improved parameter handling with defaults.Adding the target and redirect parameters with sensible defaults improves the flexibility of the API without breaking existing functionality.
347-354
: Enhanced domain information for join page.The code now provides more comprehensive domain information for the join page, improving the user experience.
367-371
: Clearer error handling for invitation codes.The conditional check for the join method and the subsequent validation of the invitation code is now more explicit and easier to follow.
373-376
: Improved domain join with conditional role assignment.Using the spread operator to conditionally include the role setting based on joinSettings is a clean pattern.
379-379
: Enhanced redirect handling after joining domain.The redirect parameter provides more flexibility in the UI flow after joining a domain, and the improved redirect URL includes a notification message for better user feedback.
function schemaToSettings(schema: Schema<any>) { | ||
const result: _Setting[] = []; | ||
const processNode = (key: string, s: Schema<number> | Schema<string> | Schema<boolean>, defaultFamily = 'setting_basic') => { | ||
if (s.dict) throw new Error('Dict is not supported here'); | ||
let flag = (s.meta?.hidden ? FLAG_HIDDEN : 0) | ||
| (s.meta?.disabled ? FLAG_DISABLED : 0); | ||
const type = s.type === 'number' ? 'number' | ||
: s.type === 'boolean' ? 'checkbox' | ||
: s.meta?.role === 'textarea' ? 'textarea' : 'text'; | ||
if (s.meta?.role === 'password') flag |= FLAG_SECRET; | ||
const options = {}; | ||
for (const item of s.list || []) { | ||
if (item.type !== 'const') throw new Error('List item must be a constant'); | ||
options[item.value] = item.meta?.description || item.value; | ||
} | ||
return { | ||
family: s.meta?.family || defaultFamily, | ||
key, | ||
value: s.meta?.default, | ||
name: key, | ||
desc: s.meta?.description, | ||
flag, | ||
subType: '', | ||
type: s.list ? 'select' : type, | ||
range: s.list ? options : null, | ||
} as _Setting; | ||
}; | ||
if (!schema.dict) return []; | ||
for (const key in schema.dict) { | ||
const value = schema.dict[key]; | ||
if (value.dict) { | ||
for (const subkey in value.dict) { | ||
result.push(processNode(`${key}.${subkey}`, value.dict[subkey], value.meta?.family)); | ||
} | ||
} else result.push(processNode(key, value)); | ||
} | ||
return result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Potential coverage gap for complex schemas
Currently, the function handles only a limited subset of data types (string, number, boolean) and single-level nesting. Any deeper or more complex schema structures may not be fully processed.
Would you like help refining the function to recursively handle nested objects and arrays, ensuring complete schema coverage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/hydrooj/src/service/server.ts (2)
74-76
:⚠️ Potential issueFix the unsafe interface-class merge issue.
The interface
Handler
and classHandler
share the same name, potentially causing issues with uninitialized interface fields. This is a TypeScript anti-pattern flagged by linters.Apply this change to address the unsafe interface-class merge:
-export class Handler extends HandlerOriginal<Context> { - domain: DomainDoc; -} +interface IHandler { + domain: DomainDoc; +} +export class Handler extends HandlerOriginal<Context> implements IHandler { + domain: DomainDoc; +}
77-79
:⚠️ Potential issueFix the unsafe interface-class merge for ConnectionHandler.
Same issue as with the Handler class - the interface and class share the same name, leading to potential type checking issues.
Apply this fix:
-export class ConnectionHandler extends ConnectionHandlerOriginal<Context> { - domain: DomainDoc; -} +interface IConnectionHandler { + domain: DomainDoc; +} +export class ConnectionHandler extends ConnectionHandlerOriginal<Context> implements IConnectionHandler { + domain: DomainDoc; +}
🧹 Nitpick comments (9)
packages/hydrooj/src/handler/home.ts (1)
471-471
: Fix the empty object patternThe empty object pattern
{}
is unnecessary when no parameters are being destructured. This also triggered a lint error.- async get({ }, all: boolean) { + async get(_: unknown, all: boolean) {🧰 Tools
🪛 Biome (1.9.4)
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/setting.ts (1)
291-291
: Consider migrating more settings to the Schema-based approachThe comment on line 320 indicates that the old settings format is being maintained temporarily. For consistency, consider planning the migration of the remaining settings (lines 321-356) to use the Schema-based approach once the new setting UI is ready.
Also applies to: 320-320
packages/hydrooj/src/service/server.ts (2)
109-109
: Consider clarifying the reverse order of addons processing.The code now uses spread with reverse on the addon values. If there's a specific reason for processing addons in reverse order, consider adding a comment explaining this design decision.
200-232
: Comprehensive HTTP error handling implementation.The HTTP handler mixin provides a thorough error handling mechanism with different paths for various error types and user states. This is a good addition that centralizes error handling logic.
Consider adding some additional comments within this complex function to explain the different handling paths, particularly for the redirect logic.
packages/hydrooj/src/upgrade.ts (2)
711-711
: Consider batch processing for large collections.The update operation on potentially large collections might benefit from batch processing to avoid timeouts and reduce memory usage.
// Start Hydro v5 async function _91_92() { try { await domain.collUser.updateMany({}, { $set: { join: true } }); + + // Process large collections in batches + const batchSize = 1000; + let processed = 0; + + while (true) { + const result = await domain.coll.updateMany( + { + $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }], + _id: { $gt: lastId } + }, + { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, + { limit: batchSize } + ); + + if (result.modifiedCount === 0) break; + processed += result.modifiedCount; + logger.info(`Processed ${processed} documents`); + } - await domain.coll.updateMany( - { $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }] }, - { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, - ); // Rest of the function... } catch (error) { logger.error(`Migration to Hydro v5 failed: ${error.message}`); throw error; } }
713-715
: Add logging for migration progress.Adding logging statements would help track the progress of the migration and aid in troubleshooting if issues occur.
try { await domain.collUser.updateMany({}, { $set: { join: true } }); + logger.info('Updated all users in collUser with join:true'); await domain.coll.updateMany( { $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }] }, { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, ); + logger.info('Updated domain collection documents with _join field'); const domainUser = await domain.coll.find({ domainId: 'system', join: true }, onPrimary) .project({ uid: 1 }).toArray(); + logger.info(`Found ${domainUser.length} users in system domain with join:true`);packages/hydrooj/src/model/domain.ts (1)
135-149
: UseArray.isArray()
for robust checks.
Change:- if (!(uid instanceof Array)) { + if (!Array.isArray(uid)) {to avoid false negatives for arrays from different contexts.
🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
packages/hydrooj/src/handler/domain.ts (2)
153-160
: Consider avoiding the delete operator for performance.
You can setu.user = undefined;
instead of usingdelete u.user;
. For example:- delete u.user; + u.user = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
326-340
: Domain join preparation logic.
Handles domain retrieval, role assignment, and membership checks. However, consider the same caution about the delete operator:- delete this.joinSettings; + this.joinSettings = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/home.ts
(3 hunks)packages/hydrooj/src/model/domain.ts
(8 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/user.ts
(4 hunks)packages/hydrooj/src/service/server.ts
(8 hunks)packages/hydrooj/src/upgrade.ts
(4 hunks)packages/ui-default/locales/zh.yaml
(5 hunks)packages/ui-default/templates/domain_join.html
(2 hunks)packages/ui-default/templates/domain_join_applications.html
(0 hunks)packages/ui-default/templates/domain_permission.html
(0 hunks)packages/ui-default/templates/domain_user.html
(2 hunks)packages/ui-default/templates/home_domain.html
(1 hunks)packages/ui-default/templates/partials/problem_sidebar_normal.html
(2 hunks)
💤 Files with no reviewable changes (2)
- packages/ui-default/templates/domain_join_applications.html
- packages/ui-default/templates/domain_permission.html
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/hydrooj/src/model/user.ts
🧰 Additional context used
🧬 Code Definitions (3)
packages/hydrooj/src/service/server.ts (1)
framework/framework/server.ts (5) (5)
HandlerCommon
(129-129)HandlerCommon
(130-199)Handler
(201-247)ConnectionHandler
(249-286)WebService
(328-828)
packages/hydrooj/src/model/domain.ts (3)
packages/hydrooj/src/service/bus.ts (1) (1)
apply
(97-114)packages/hydrooj/src/service/db.ts (1) (1)
apply
(180-183)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)
packages/hydrooj/src/model/setting.ts (5)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/worker.ts (1) (1)
apply
(89-92)packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/service/db.ts (1) (1)
apply
(180-183)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/home.ts
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/hydrooj/src/handler/domain.ts
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (49)
packages/hydrooj/src/handler/home.ts (7)
184-184
: Good improvement: Better context handling with dependency injectionThe code now explicitly extracts the geoip context from
this.ctx.get('geoip')
instead of accessing it directly as a property. This aligns with dependency injection patterns and makes the code more maintainable.
192-195
: Good refactoring: Using local variable improves readabilityUsing the local
geoip
variable instead of repeatedly accessingthis.ctx.geoip
improves code readability and follows the DRY principle.
205-205
: Consistent usage of the extracted geoip variableThis change maintains consistency with the earlier changes, utilizing the local
geoip
variable.
472-474
: Good refactoring: Better type definition and role managementExplicitly typing
ddocs
asDomainDoc[]
and introducing arole
object to manage user roles improves type safety and makes the code's intent clearer.
475-481
: Improved code structure and readabilityThe refactored code maintains the same logic but with clearer variable names and data flow. Using
ddocs
consistently throughout the method improves readability.
483-495
: Better role management with explicit role assignmentThe code now explicitly assigns roles for each domain, making it easier to understand permission handling. The refactoring from
dudict
to a dedicatedrole
object improves clarity and maintainability.
497-497
: Updated response with explicit role informationThe response structure has been improved by including the explicit
role
object instead of the less descriptivedudict
.packages/hydrooj/src/model/setting.ts (9)
3-3
: Update library import for consistencyThe import statement has been updated from 'cordis' to '@cordisjs/core', which aligns with the new module declaration on line 361. This change is part of the broader framework update.
7-7
: Action Required: Add "schemastery" to project dependenciesThe import of
Schema
fromschemastery
is appropriate given its usage in the file. However, verification shows thatschemastery
is not currently listed under eitherdependencies
ordevDependencies
in yourpackage.json
.
74-81
: Well-structured type extension for Schema metadataThe global declaration extends the Schemastery namespace with metadata options that enable setting-specific properties like 'family' and 'secret', allowing for better integration with the existing settings system.
83-120
: Robust Schema to Settings conversion implementationThe
schemaToSettings
function effectively bridges the gap between schema-based configuration and the existing settings system. It correctly handles:
- Type mapping between Schema types and setting types
- Metadata extraction for descriptions and flags
- Nested dictionaries with proper key path creation
- Error handling for unsupported structures
The error handling for unsupported schema types (line 86 and 95) is particularly well-implemented.
122-123
: Clean implementation of Schema support in setting registration functionsThe modification to accept both traditional
_Setting[]
and newSchema<any>[]
provides backward compatibility while enabling the new schema-based approach. The flatMap implementation efficiently handles the conversion.Also applies to: 142-143, 162-163, 178-179, 194-195
291-319
: Excellent Schema-based settings definition showcaseThis implementation demonstrates a more structured, type-safe way to define settings with:
- Hierarchical organization (smtp, server)
- Strongly typed properties with validation rules
- Default values and descriptions
- Specialized input types via the 'role' property
This approach is more maintainable and less error-prone than the traditional approach used elsewhere in the file.
398-398
: Improved context-based DB accessReplacing
global.Hydro.service.db
withctx.db
is a good change that:
- Makes database access more predictable through dependency injection
- Improves testability by removing global state dependency
- Aligns with modern service architecture patterns
This change is consistent with the dependency injection pattern established by the
inject
array on line 390.
390-390
: Properly declared service dependenciesAdding the
inject = ['db']
export ensures that the DB service is available before this service initializes, which is necessary for the updatedapply
function to work correctly.
361-365
: Updated module declaration to match new importThe module declaration has been correctly updated to reference '@cordisjs/core' instead of 'cordis', maintaining type consistency with the updated import on line 3.
packages/hydrooj/src/service/server.ts (9)
7-9
: Improved importing strategy with explicit names.The changes to import statements provide more clarity by explicitly importing the original handler classes and the new WebService component. This approach improves readability and makes dependencies more explicit.
31-31
: Good addition of generic type parameter.Adding the generic type parameter
<C>
to theHandlerCommon
interface improves type safety by allowing the interface to work with different context types. This change aligns with modern TypeScript best practices.
82-82
: Good use of WebService import instead of require.Using the imported
WebService
directly instead of requiring the entire framework is a cleaner approach that follows better module practices and improves maintainability.
149-149
: Good explicit conversion to string.Explicitly calling
toString()
on the URL result ensures type consistency and prevents potential issues with non-string values.
163-164
: Improved translation logic.The changes to the translation logic provide better handling of language preferences, first checking the user's view language before falling back to accepted languages from the request.
233-248
: Well-structured WebSocket error handling.The WebSocket handler mixin properly handles errors by logging them, sending error information to the client, and cleanly closing the connection. This implementation follows good practices for WebSocket error management.
255-256
: Improved context extension approach.Using
extend()
to create a new context with the domain is a cleaner approach than direct assignment, promoting immutability and preventing unintended side effects.
257-267
: Good addition of HTTP handler creation event.The HTTP handler creation event includes important checks such as rate limiting and permission verification. The addition of checking for pending errors is a valuable safeguard.
268-270
: Proper error checking for WebSocket handlers.Adding error checking during WebSocket handler creation ensures errors are caught early in the connection lifecycle, improving reliability.
packages/hydrooj/src/upgrade.ts (2)
39-40
: Good addition of read preference setting.Adding the
onPrimary
constant with a primary read preference ensures that critical database operations will always read from the primary node, avoiding potential stale data issues in replica set configurations.
56-56
: Proper linting override for array initialization.The added comment correctly disables the oxlint rule for this specific line, maintaining code quality while addressing a necessary pattern.
packages/ui-default/locales/zh.yaml (3)
492-493
: Translations look consistent.
The newly added strings for creating and submitting after joining a domain are clear.
608-608
: Good phrasing for indicating a user has not yet joined.
The translation “暂未加入” accurately conveys the status.
910-910
: Proper addition of '域所有者' label.
The newly introduced entry for “The domain owner” helps clarity.packages/hydrooj/src/model/domain.ts (5)
4-6
: Imports look good.
ImportingContext
andbus
is aligned with the new event-based structure.
63-63
: Auto-join parameter usage.
Assigning the'root'
role withtrue
for autojoin ensures proper domain owner setup.
131-133
: Filter byjoin: true
is correct.
Requiringjoin: true
when counting users matches the updated logic of only considering domain members.
253-255
: User domain dictionary retrieval looks good.
No issues with filtering on{ uid, join: true }
.
288-308
: Consolidated event handling and index setup.
This newapply(ctx: Context)
function properly manages cache deletion logic and ensures database indexes.packages/hydrooj/src/handler/domain.ts (4)
105-151
: Aggregation pipeline approach.
Using$match
and$lookup
to retrieve user details is a powerful, centralized solution. The logic to exclude non-joined users or default/guest roles looks coherent.
257-257
: Excluding only 'guest' is consistent.
This ensures users with 'default' role remain visible.
345-361
: Flexible GET method with redirect support.
This additional parameter set (code, target, redirect) increases the handler’s usefulness without apparent issues.
367-380
: Secure domain join process.
Verifies invitation code when needed and updates membership. This logic is clear and straightforward.packages/ui-default/templates/home_domain.html (1)
40-40
: Refactoring Role Retrieval in Template
The new change directly accesses the role usingrole[ddoc._id]|default('default')
, which is clearer and more concise than using an intermediary variable (e.g.,dudict
). Just ensure that therole
variable is always defined and passed to the template context.packages/ui-default/templates/domain_user.html (2)
85-87
: Conditional Indication for Unjoined Users (First Occurrence)
The addition of a conditional block to display a “Not joined yet” message for users (usingudoc.join
) is clear and improves user feedback. Verify that the styling (e.g., thetext-orange
class) is consistent with the rest of the UI.
105-107
: Conditional Indication for Unjoined Users (Second Occurrence)
Similarly, the change for rendering the inline user representation with an additional “Not joined yet” badge forrudoc
cases is well implemented. This helps users quickly identify unjoined statuses.packages/ui-default/templates/partials/problem_sidebar_normal.html (2)
20-22
: Prompting Domain Join for Discussion Creation
The new conditional (usingnot handler.user._dudoc.join
) to prompt the user to join the domain before creating a discussion is a smart UX touch. Ensure that the condition correctly reflects the user’s join status and that thejoinDomain()
function is well integrated.
52-55
: Prompting Domain Join for Problem Submission
Likewise, adding a condition to display a “Join Domain to Submit” option for users lacking domain membership adds useful guidance. Confirm that the disabled styling and active state logic (using{% if page_name == 'problem_submit' %}
) behave as intended across various scenarios.packages/ui-default/templates/domain_join.html (5)
8-12
: Dynamic Title Based on Join Settings
Using a conditional to change the title—displaying either “Join {0}” or “You are invited to join {0}” based on the presence ofjoinSettings
—enhances clarity in the user prompt. This dynamic approach helps inform the user accurately about the context of their join action.
16-16
: Clear Join Process Description
The updated paragraph now clearly explains that clicking the button will make the user a member of the domain. This explicit description improves usability by setting clear expectations.
18-21
: Display of Domain Owner Information
Rendering the domain owner's details with a header adds valuable context, allowing users to quickly verify the domain’s legitimacy. Ensure the output fromuser.render_inline(domainInfo['owner'])
is secure and formatted consistently.
22-26
: Rendering Domain Bulletin (Markdown Conversion)
The conditional block for the bulletin now converts its content to markdown, which is useful for rich text formatting. Make sure that the markdown rendering is securely sanitized to mitigate any potential XSS risks if the bulletin content is user-generated.
40-41
: Passing Additional Context with Hidden Inputs
Adding hidden inputs fortarget
andredirect
ensures that necessary navigation context is preserved during the join process. This approach is effective; just double-check that these values are properly validated on the server side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/hydrooj/src/handler/domain.ts (2)
153-160
: Consider optimizing the object transformationThe code transforms the aggregation results with a property deletion operation that could impact performance.
-const users = dudocs.map((dudoc) => { - const u = { - ...dudoc, - ...dudoc.user, - }; - delete u.user; - return u; -}); +const users = dudocs.map((dudoc) => { + const { user: userData, ...rest } = dudoc; + return { ...rest, ...userData }; +});This approach uses object destructuring to create a new object without the
user
property, avoiding thedelete
operator that was flagged by static analysis.🧰 Tools
🪛 Biome (1.9.4)
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
338-338
: Performance consideration in conditional property deletionThe
delete this.joinSettings
operation may impact performance as flagged by static analysis.-if (assignedRole !== 'default') delete this.joinSettings; +if (assignedRole !== 'default') this.joinSettings = undefined;Setting to
undefined
instead of using thedelete
operator is generally more performant while achieving the same result.🧰 Tools
🪛 Biome (1.9.4)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/ui-default/pages/problem_submit.page.tsx
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/domain.ts
[error] 158-158: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (6)
packages/hydrooj/src/handler/domain.ts (6)
105-150
: Complex aggregation pipeline improves user data retrievalThe refactoring of the user retrieval logic using MongoDB's aggregation pipeline is a significant improvement. This approach:
- Efficiently filters users based on membership criteria
- Uses
$lookup
to join with the user collection in a single database operation- Projects only necessary fields, reducing data transfer
- Properly handles permissions for viewing display names
This implementation is more performant than separate queries and reduces round trips to the database.
261-261
: Simplified role filtering logicThe role filtering has been simplified to exclude only the 'guest' role, making the code more maintainable and easier to understand.
344-361
: Improved response body with detailed domain informationThe
get
method now returns a more comprehensive response that includes domain details such as name, owner, avatar, and bulletin information. This provides a better user experience by presenting all relevant domain information in one response.
364-380
: Enhanced post method with dynamic role assignmentThe
post
method now handles user role assignment more dynamically based on join settings, making the domain join process more flexible. The addition of a redirect parameter also improves navigation flow after joining a domain.
373-376
: Clean conditional role assignmentThe conditional assignment of the role using the spread operator is a clean and elegant solution:
{ join: true, ...(this.joinSettings ? { role: this.joinSettings.role } : {}), }This pattern effectively conditionally adds the role property only when joinSettings is available.
325-340
:✅ Verification successful
Enhanced domain join functionality with target parameter
The addition of the
target
parameter to theprepare
method significantly improves flexibility in the domain join process. This change:
- Allows joining a different domain than the current one
- Properly checks membership status in the target domain
- Correctly handles role assignment based on privileges
- Improves error handling with specific error conditions
The implementation is solid and adds valuable functionality to the application.
Consider running this test to ensure all routes using this handler properly pass the target parameter:
🏁 Script executed:
#!/bin/bash # Check if all routes that use DomainJoinHandler pass target parameter rg -A 3 -B 3 "Route\(.*?DomainJoinHandler" --glob "*.ts"Length of output: 827
Domain Join Enhancement Verified
The updated
prepare
method in the DomainJoinHandler now accepts atarget
parameter, which enhances domain flexibility by allowing a user to join a domain different from their current one. This update:
- Enables joining an alternate domain by defaulting to the current domain when no target is provided.
- Checks the membership status against the passed target domain.
- Assigns roles based on user privileges, defaulting appropriately unless the user has the management privilege.
- Improves error scenarios by throwing specific errors when the user is already a member or when joining is forbidden.
A quick search confirms that the DomainJoinHandler is used for the
/domain/join
endpoint, ensuring that the initialization now correctly supports incoming target parameters.The implementation is solid and no further changes are required.
🧰 Tools
🪛 Biome (1.9.4)
[error] 338-338: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (10)
packages/elastic/index.ts (3)
111-116
: 🛠️ Refactor suggestionAdd error handling to the problem/del event handler.
The event handler doesn't include error handling, which could lead to unhandled promise rejections. Consider adding a try-catch block.
this.ctx.on('problem/del', async (domainId, docId) => { + try { await this.client.delete({ index: 'problem', id: `${domainId}/${docId}`, }); + } catch (error) { + this.ctx.logger.error(`Error deleting problem from index: ${error.message}`); + } });
104-110
: 🛠️ Refactor suggestionAdd error handling to the problem/edit event handler.
The event handler doesn't include error handling, which could lead to unhandled promise rejections. Consider adding a try-catch block.
this.ctx.on('problem/edit', async (pdoc) => { + try { await this.client.index({ index: 'problem', id: `${pdoc.domainId}/${pdoc.docId}`, document: processDocument(pdoc), }); + } catch (error) { + this.ctx.logger.error(`Error updating problem index: ${error.message}`); + } });
97-103
: 🛠️ Refactor suggestionAdd error handling to the problem/add event handler.
The event handler doesn't include error handling, which could lead to unhandled promise rejections. Consider adding a try-catch block.
this.ctx.on('problem/add', async (doc, docId) => { + try { await this.client.index({ index: 'problem', id: `${doc.domainId}/${docId}`, document: processDocument(doc), }); + } catch (error) { + this.ctx.logger.error(`Error indexing problem: ${error.message}`); + } });packages/ui-default/backendlib/template.ts (3)
121-121
:⚠️ Potential issueAvoid using
eval
if possible.
eval()
exposes your application to security risks and performance issues.Consider refactoring to use safer alternatives such as:
- Function constructors if you need dynamic code execution
- JSON.parse for data parsing
- Template literals for string interpolation
🧰 Tools
🪛 Biome (1.9.4)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().(lint/security/noGlobalEval)
122-128
:⚠️ Potential issueSecurity Concern: Limit Global Exposure in Template Engine
Exposing complete global objects (Date, Object, String, process, global) to templates creates significant security risks like prototype pollution, remote code execution, and information disclosure.
Replace with limited, controlled interfaces:
- this.addGlobal('Date', Date); - this.addGlobal('Object', Object); - this.addGlobal('String', String); - this.addGlobal('Array', Array); - this.addGlobal('Math', Math); - this.addGlobal('process', process); - this.addGlobal('global', global); + // Provide limited date functionality + this.addGlobal('Date', { + now: Date.now, + parse: Date.parse, + format: (date) => new Date(date).toLocaleString(), + }); + // Provide safer Math operations + this.addGlobal('Math', { + abs: Math.abs, + ceil: Math.ceil, + floor: Math.floor, + max: Math.max, + min: Math.min, + round: Math.round, + }); + // Safe string utilities + this.addGlobal('stringUtils', { + trim: (s) => String(s).trim(), + toLowerCase: (s) => String(s).toLowerCase(), + toUpperCase: (s) => String(s).toUpperCase(), + });
221-242
: 🛠️ Refactor suggestionAdd timeout handling to prevent long-running renders
While there's logging for slow renders (>5000ms), there's no timeout mechanism to prevent extremely long-running renders from blocking the server.
Add a timeout mechanism:
const render = (name: string, state: any) => new Promise<string>((resolve, reject) => { const start = Date.now(); + const renderTimeout = setTimeout(() => { + reject(new Error(`Render timeout for template ${name}`)); + }, 10000); // 10 seconds timeout + env.render(name, { page_name: name.split('.')[0], ...state, formatJudgeTexts: (texts) => texts.map((text) => { if (typeof text === 'string') return text; return state._(text.message).format(...text.params || []) + ((process.env.DEV && text.stack) ? `\n${text.stack}` : ''); }).join('\n'), datetimeSpan: (arg0, arg1, arg2) => misc.datetimeSpan(arg0, arg1, arg2, state.handler.user?.timeZone), ctx: state.handler?.ctx, perm: PERM, PRIV, STATUS, UiContext: state.handler?.UiContext || {}, }, (err, res) => { + clearTimeout(renderTimeout); const end = Date.now(); if (end - start > 5000) console.error(`Render of ${name} took ${end - start}ms`); if (err) reject(err); else resolve(res || ''); }); });packages/ui-default/index.ts (1)
56-56
:⚠️ Potential issueRemove the empty object pattern.
Static analysis flags
{ }
as an unexpected empty pattern. Consider removing it as it doesn't serve any purpose.- async get({ }, legacy = false, nohint = false) { + async get(legacy = false, nohint = false) {🧰 Tools
🪛 Biome (1.9.4)
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/settings.ts (1)
159-169
:⚠️ Potential issueSilent failure in Proxy setter could hide errors.
The
set
trap doesn't await the asynchronoussetConfig
operation, potentially hiding database write failures.set(self, p: string | symbol, newValue: any) { - that.setConfig(path.concat(p).join(','), newValue); - return true; + // Since this is a Proxy trap, we can't make it async directly + // but we can capture and log errors + that.setConfig(path.concat(p).join(','), newValue) + .catch(err => { + logger.error('Failed to set config property:', path.concat(p).join(','), err.message); + }); + return true; },A better long-term solution would be to redesign the proxy pattern to properly handle asynchronous operations.
build/prepare.js (1)
163-167
:⚠️ Potential issuePotential file system race condition
tryUpdate
logic may fail if the file is altered between existence check and write. Consider a try-catch for robust error handling.- const current = fs.existsSync(location) ? fs.readFileSync(location, 'utf-8') : ''; - const expected = ... - if (expected !== current) fs.writeFileSync(location, expected); + try { + const current = fs.readFileSync(location, 'utf-8'); + const expected = ... + ... + } catch (err) { + ... + }🧰 Tools
🪛 GitHub Check: CodeQL
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.framework/framework/server.ts (1)
139-141
: 🛠️ Refactor suggestionAvoid empty interface merging
DefiningHandlerCommon<C>
as both interface and class can lead to unsafe declaration merging.-export interface HandlerCommon<C> { } // ... -export class HandlerCommon<C> { +// Remove empty interface or convert it to a type alias +export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🧹 Nitpick comments (20)
.github/workflows/build.yml (1)
62-69
: Clarify Parallel Task Invocation in “Build And Lint” Step
The updated command on line 66 now runs:parallel --tty -j+0 yarn ::: lint:ci build build:ui:production:webpack test
This change omits the previously used
lint:ui:ci
task and instead runslint:ci
,build
,build:ui:production:webpack
, andtest
in parallel when UI-related files have changed or when the UI package version differs. Please verify that this removal oflint:ui:ci
is intentional and that its functionality is now correctly addressed (either merged intolint:ci
or handled elsewhere). Additionally, ensure that the new command order aligns with your CI expectations and that no required lint checks on UI code are inadvertently skipped.packages/hydrooj/src/handler/misc.ts (2)
110-110
: Consider using a more standard parameter pattern instead of an empty objectThe empty object pattern
{ }
is flagged by static analysis as unconventional. While it works, it reduces readability and may confuse developers.Instead of an empty object, consider using one of these alternatives:
- async get({ }, target: string, filename = '', expire: number, secret: string) { + async get(_: unknown, target: string, filename = '', expire: number, secret: string) {Or if the first parameter is intentionally being removed:
- async get({ }, target: string, filename = '', expire: number, secret: string) { + async get(target: string, filename = '', expire: number, secret: string) {🧰 Tools
🪛 Biome (1.9.4)
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
124-124
: Consider using a more standard parameter pattern instead of an empty objectSimilar to line 110, the empty object pattern
{ }
is flagged by static analysis as unconventional. It reduces readability and may confuse other developers.Instead of an empty object, consider:
- async get({ }, uid: number) { + async get(_: unknown, uid: number) {Or if the first parameter is intentionally being removed:
- async get({ }, uid: number) { + async get(uid: number) {🧰 Tools
🪛 Biome (1.9.4)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/setting.ts (1)
290-318
: Excellent schema-based approach for system settingsThis implementation showcases the power of the new Schema-based approach, providing strong typing, validation, and metadata for system settings. The organization by functional groups (smtp, server) makes the code more maintainable and self-documenting.
Consider adding validation for email format to the
smtp.from
andsmtp.user
fields using regex patterns to ensure valid email addresses are provided.eslint.config.mjs (2)
1-2
: Consider limiting or scoping these disabled rules.
Disablingmax-len
and@typescript-eslint/naming-convention
globally may hide potential readability and naming issues across the entire codebase. If these rules are only problematic in certain directories or files, consider disabling them more selectively.
107-109
: Address theFIXME
comment.
The'template-curly-spacing'
rule is commented out due to a known parser bug. Let me know if you’d like further help in resolving or tracking this in a new issue.packages/elastic/index.ts (1)
29-29
: Remove console.log statement.The console.log statement should be removed or replaced with proper logging using the context's logger.
- console.log('elastic-search', config); + this.ctx.logger.info('Initializing elastic-search service', { url: config.url });packages/utils/lib/utils.ts (2)
15-28
: Consider additional configuration options for logging.While this factory-based setup is flexible, you might want to parameterize options like
showDiff
,timestamp
, andlevels
to better adapt to different environments (test, production, etc.).
33-34
: Check the cast approach when exporting Logger.Casting
createLogger
toLogger
viaas any as Logger
might limit type safety. Consider a more direct factory pattern or a safer type assertion if possible.packages/hydrooj/src/service/db.ts (1)
35-41
: Extending theService
class forMongoService
.This constructor approach neatly initializes service properties. Ensure that any error handling (e.g., invalid config) is also addressed in case the
MongoService
fails to initialize.packages/hydrooj/src/loader.ts (1)
49-49
: Consider replacing empty object type with a more specific typeDon't use
{}
as a type. It means "any non-nullable value" and could lead to unexpected behavior. Consider defining a more specific type for the config property.- public config: {}; + public config: Record<string, unknown>;🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/model/record.ts (2)
213-216
: Consider removingreturn await
.
Returning a Promise directly vs. usingawait
here generally performs the same. Removingawait
could reduce minor overhead.
235-264
: Risk of partial operations inreset
.
Multiple asynchronous calls in a singlePromise.all
may lead to inconsistent state if an operation fails midway. Consolidating or using transactions could help prevent partial updates/inserts/deletions.packages/ui-default/backendlib/template.ts (1)
46-46
: Use optional chaining to simplify null checkThe code can be simplified using optional chaining.
- if ((obj || {})._original) obj = obj._original; + if (obj?._original) obj = obj._original;🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
packages/hydrooj/src/handler/domain.ts (1)
104-160
: Enhanced user query with MongoDB aggregation pipeline.The implementation has been completely refactored to use MongoDB's aggregation framework, which provides significant improvements.
Benefits of this change:
- Reduces database round-trips by joining user data in a single query
- Uses projection to only retrieve needed fields for better performance
- Properly filters users based on role and domain membership
- Adds proper structure to the returned data with nested user information
The code could be further improved by extracting the aggregation pipeline to a reusable function:
async get({ domainId }, format = 'default') { + const getUserAggregation = (domainId) => [ + { + $match: { + role: { + $nin: ['default', 'guest'], + $ne: null, + }, + domainId, + }, + }, + // ... rest of the pipeline + ]; const [dudocs, roles] = await Promise.all([ - domain.collUser.aggregate([/* ... */]).toArray(), + domain.collUser.aggregate(getUserAggregation(domainId)).toArray(), domain.getRoles(domainId), ]); // ... }🧰 Tools
🪛 Biome (1.9.4)
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
framework/framework/server.ts (5)
484-492
: RefactorhandleHttp
UtilizingforkContextWithScope(savedContext)
ensures a sub-scope for each request.
Likewise, parallel event calls'handler/create'
&'handler/create/http'
are typed asany
. Consider stronger type-safety if possible.
536-537
: Ignore TS for steps
The// @ts-ignore
approach forhandler/
calls may hide type issues. Evaluate a typed approach if possible.
684-708
: Checker function
Dynamically collectsperm
orpriv
from arguments. The approach is flexible but might be hard to maintain.Consider using a more structured method of providing permission/priv options.
744-748
: Debug code
Commented-out debug lines. If not needed, consider removing.
787-810
: Mixin system
Applying mixins dynamically with disposal is advanced. This design might further benefit from strong type constraints.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (94)
.eslintrc.yaml
(0 hunks).github/workflows/build.yml
(1 hunks)build/prepare.js
(5 hunks)eslint.config.mjs
(1 hunks)framework/eslint-config/base.mjs
(1 hunks)framework/eslint-config/base.yaml
(0 hunks)framework/eslint-config/package.json
(1 hunks)framework/eslint-config/react.yaml
(0 hunks)framework/eslint-config/typescript.js
(0 hunks)framework/framework/error.ts
(0 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrojudge/src/cases.ts
(0 hunks)packages/hydrojudge/src/checkers.ts
(4 hunks)packages/hydrojudge/src/daemon.ts
(0 hunks)packages/hydrojudge/src/hosts/hydro.ts
(0 hunks)packages/hydrojudge/src/hosts/vj4.ts
(1 hunks)packages/hydrojudge/src/judge/hack.ts
(4 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/commands/install.ts
(1 hunks)packages/hydrooj/src/entry/cli.ts
(2 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/setup.ts
(0 hunks)packages/hydrooj/src/entry/worker.ts
(3 hunks)packages/hydrooj/src/handler/contest.ts
(0 hunks)packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/misc.ts
(3 hunks)packages/hydrooj/src/handler/problem.ts
(1 hunks)packages/hydrooj/src/interface.ts
(6 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/blacklist.ts
(1 hunks)packages/hydrooj/src/model/contest.ts
(7 hunks)packages/hydrooj/src/model/document.ts
(11 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/hydrooj/src/model/message.ts
(3 hunks)packages/hydrooj/src/model/oauth.ts
(1 hunks)packages/hydrooj/src/model/opcount.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/record.ts
(8 hunks)packages/hydrooj/src/model/schedule.ts
(2 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/storage.ts
(6 hunks)packages/hydrooj/src/model/system.ts
(3 hunks)packages/hydrooj/src/model/task.ts
(3 hunks)packages/hydrooj/src/model/token.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(8 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)packages/hydrooj/src/script/problemStat.ts
(0 hunks)packages/hydrooj/src/script/storageUsage.ts
(0 hunks)packages/hydrooj/src/service/bus.ts
(5 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/worker.ts
(2 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/migrate/package.json
(1 hunks)packages/onlyoffice/frontend/office.page.ts
(0 hunks)packages/onsite-toolkit/frontend/resolver.page.tsx
(2 hunks)packages/ui-default/.eslintignore
(0 hunks)packages/ui-default/.eslintrc.js
(0 hunks)packages/ui-default/api.ts
(0 hunks)packages/ui-default/backendlib/builder.ts
(4 hunks)packages/ui-default/backendlib/markdown-it-imsize.ts
(1 hunks)packages/ui-default/backendlib/markdown-it-media.ts
(0 hunks)packages/ui-default/backendlib/misc.ts
(1 hunks)packages/ui-default/backendlib/template.ts
(3 hunks)packages/ui-default/build/config/webpack.ts
(1 hunks)packages/ui-default/build/main.ts
(1 hunks)packages/ui-default/components/autocomplete/components/AutoComplete.tsx
(3 hunks)packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
(1 hunks)packages/ui-default/components/calendar/index.js
(2 hunks)packages/ui-default/components/message/worker.ts
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
(1 hunks)packages/ui-default/components/problemconfig/reducer/config.ts
(1 hunks)packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/Testcase.tsx
(1 hunks)packages/ui-default/components/scratchpad/DataInputComponent.jsx
(0 hunks)packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
(0 hunks)packages/ui-default/index.ts
(6 hunks)packages/ui-default/package.json
(5 hunks)packages/ui-next/package.json
(1 hunks)packages/ui-next/src/App.tsx
(1 hunks)packages/utils/lib/locate-pm2.ts
(1 hunks)packages/utils/lib/utils.ts
(1 hunks)packages/utils/package.json
(2 hunks)packages/vjudge/src/index.ts
(3 hunks)packages/vjudge/src/providers/codeforces.ts
(0 hunks)packages/vjudge/src/providers/hduoj.ts
(0 hunks)packages/vjudge/src/providers/poj.ts
(0 hunks)packages/vjudge/src/providers/spoj.ts
(0 hunks)packages/vjudge/src/providers/uoj.ts
(0 hunks)packages/vjudge/src/providers/yacs.ts
(0 hunks)
💤 Files with no reviewable changes (25)
- packages/ui-default/.eslintignore
- packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
- packages/hydrooj/src/script/storageUsage.ts
- packages/ui-default/backendlib/markdown-it-media.ts
- packages/hydrooj/src/entry/setup.ts
- packages/hydrojudge/src/cases.ts
- packages/vjudge/src/providers/hduoj.ts
- packages/vjudge/src/providers/spoj.ts
- packages/hydrojudge/src/daemon.ts
- packages/hydrooj/src/script/problemStat.ts
- packages/hydrojudge/src/hosts/hydro.ts
- packages/onlyoffice/frontend/office.page.ts
- packages/vjudge/src/providers/poj.ts
- framework/framework/error.ts
- framework/eslint-config/react.yaml
- packages/vjudge/src/providers/yacs.ts
- packages/vjudge/src/providers/codeforces.ts
- packages/vjudge/src/providers/uoj.ts
- packages/ui-default/api.ts
- packages/ui-default/components/scratchpad/DataInputComponent.jsx
- packages/ui-default/.eslintrc.js
- .eslintrc.yaml
- packages/hydrooj/src/handler/contest.ts
- framework/eslint-config/base.yaml
- framework/eslint-config/typescript.js
✅ Files skipped from review due to trivial changes (14)
- packages/ui-default/components/problemconfig/tree/Testcase.tsx
- packages/ui-default/components/problemconfig/reducer/config.ts
- packages/utils/lib/locate-pm2.ts
- packages/ui-default/build/config/webpack.ts
- packages/ui-default/backendlib/markdown-it-imsize.ts
- packages/hydrojudge/src/hosts/vj4.ts
- packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
- packages/ui-default/backendlib/misc.ts
- packages/ui-default/components/message/worker.ts
- packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
- packages/ui-default/build/main.ts
- packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
- packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
- packages/ui-default/components/calendar/index.js
🚧 Files skipped from review as they are similar to previous changes (27)
- packages/ui-next/src/App.tsx
- packages/hydrooj/src/model/token.ts
- packages/hydrooj/src/ui.ts
- packages/hydrojudge/src/judge/hack.ts
- packages/ui-next/package.json
- packages/hydrooj/src/model/message.ts
- packages/hydrooj/src/entry/cli.ts
- packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
- packages/hydrooj/src/model/system.ts
- packages/hydrooj/src/model/problem.ts
- packages/hydrooj/src/model/contest.ts
- packages/hydrooj/src/handler/problem.ts
- packages/hydrooj/src/commands/install.ts
- packages/ui-default/backendlib/builder.ts
- packages/hydrooj/src/model/storage.ts
- packages/ui-default/components/autocomplete/components/AutoComplete.tsx
- packages/utils/package.json
- packages/onsite-toolkit/frontend/resolver.page.tsx
- packages/migrate/package.json
- packages/hydrooj/src/plugin-api.ts
- packages/vjudge/src/index.ts
- packages/hydrooj/src/model/user.ts
- packages/hydrooj/src/model/task.ts
- packages/hydrooj/src/service/bus.ts
- package.json
- packages/hydrooj/package.json
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (14)
packages/hydrooj/src/entry/worker.ts (4)
packages/hydrooj/src/service/db.ts (1) (1)
MongoService
(35-180)packages/hydrooj/src/options.ts (1) (1)
load
(24-37)packages/hydrooj/src/entry/setup.ts (1) (1)
load
(9-38)packages/hydrooj/src/settings.ts (1) (1)
ConfigService
(14-172)
packages/hydrooj/src/service/db.ts (1)
packages/hydrooj/src/options.ts (1) (1)
load
(24-37)
packages/hydrooj/src/model/record.ts (8)
packages/hydrooj/src/model/schedule.ts (1) (1)
apply
(62-101)packages/hydrooj/src/service/api.ts (1) (1)
apply
(217-220)packages/hydrooj/src/model/document.ts (1) (1)
apply
(413-447)packages/hydrooj/src/model/task.ts (1) (1)
apply
(145-191)packages/hydrooj/src/model/user.ts (1) (1)
apply
(477-495)packages/hydrooj/src/model/blacklist.ts (1) (1)
apply
(34-40)packages/hydrooj/src/model/opcount.ts (1) (1)
apply
(23-27)packages/hydrooj/src/model/message.ts (1) (1)
apply
(88-94)
packages/hydrooj/src/interface.ts (1)
packages/common/types.ts (1) (1)
RecordJudgeInfo
(84-96)
packages/elastic/index.ts (4)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/hydrooj/src/settings.ts (1) (1)
Context
(30-34)packages/hydrooj/src/interface.ts (1) (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1) (1)
ProblemModel
(74-675)
packages/hydrooj/src/settings.ts (4)
packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/elastic/index.ts (1) (1)
Context
(95-125)packages/vjudge/src/index.ts (1) (1)
Context
(191-196)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/ui-default/backendlib/template.ts (3)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/api.ts (3) (3)
Service
(5-5)ctx
(5-5)Context
(5-5)packages/hydrooj/src/model/builtin.ts (2) (2)
PERM
(9-102)PRIV
(240-267)
packages/hydrooj/src/model/setting.ts (5)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
framework/framework/server.ts (4)
packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)packages/hydrooj/src/plugin-api.ts (3) (3)
Handler
(40-40)Service
(41-41)Context
(41-41)framework/framework/interface.ts (1) (1)
KnownHandlers
(3-5)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
packages/hydrooj/src/loader.ts (1)
packages/hydrooj/src/context.ts (3) (3)
EffectScope
(27-27)Context
(31-41)Context
(68-77)
packages/hydrooj/src/entry/common.ts (4)
packages/ui-default/api.ts (2) (2)
ctx
(5-5)Context
(5-5)packages/hydrooj/src/plugin-api.ts (1) (1)
Context
(41-41)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/utils.ts (1) (1)
unwrapExports
(21-29)
packages/hydrooj/src/model/document.ts (7)
packages/hydrooj/src/model/user.ts (1) (1)
coll
(22-22)packages/hydrooj/src/model/oplog.ts (1) (1)
coll
(8-8)packages/hydrooj/src/model/discussion.ts (1) (1)
coll
(43-43)packages/hydrooj/src/model/problem.ts (1) (1)
incStatus
(431-436)packages/hydrooj/src/model/token.ts (1) (1)
update
(53-71)packages/hydrooj/src/model/record.ts (1) (1)
update
(195-219)packages/hydrooj/src/service/monitor.ts (1) (1)
update
(76-89)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/ui-default/index.ts (1)
packages/ui-default/backendlib/template.ts (1) (1)
TemplateService
(161-276)
🪛 Biome (1.9.4)
packages/ui-default/backendlib/template.ts
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().
(lint/security/noGlobalEval)
framework/framework/server.ts
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
packages/hydrooj/src/loader.ts
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/handler/domain.ts
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/handler/misc.ts
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/document.ts
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/ui-default/index.ts
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🪛 GitHub Check: CodeQL
build/prepare.js
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
🔇 Additional comments (150)
packages/hydrooj/src/handler/misc.ts (1)
112-112
: Verify fallback behavior for storage validationThe new validation logic uses optional chaining (
?.
) which could lead to undefined behavior if the storage provider or itsisLinkValid
method is not available.Ensure that there's proper fallback behavior or error handling if
this.ctx.get('storage')
returns null or ifisLinkValid
is not implemented by the storage provider.packages/hydrooj/src/model/setting.ts (8)
3-3
: Updated dependencies and added Schemastery schema supportThe dependency update from 'cordis' to '@cordisjs/core' and the addition of the Schemastery schema library improve the codebase architecture by providing stronger typing and schema validation capabilities.
The import of
Schema
fromschemastery
was previously flagged as missing from your project dependencies. Please verify it has been added:#!/bin/bash # Check if schemastery is properly listed in dependencies cd packages/hydrooj && cat package.json | jq '.dependencies.schemastery, .devDependencies.schemastery'Also applies to: 7-7
73-80
: Well-structured namespace declaration for Schemastery metadataThe global namespace declaration for Schemastery adds type support for the schema metadata, particularly the 'family' and 'secret' properties that will be used in the settings system.
82-119
: Robust schema conversion implementation but with coverage limitationsThe
schemaToSettings
function effectively transforms Schema objects into _Setting arrays, providing a bridge between the new schema-based approach and the existing settings system. The error handling for unsupported structures (like Dict and non-constant list items) is appropriate.Consider enhancing the function to handle deeper nested objects and more complex schema structures. Currently, it only supports one level of nesting (through the
value.dict
check) and limited data types. Adding support for arrays, nested objects beyond one level, and additional schema types would make this function more robust.
121-122
: Enhanced type safety and schema support in setting functionsThe updates to the setting functions (PreferenceSetting, AccountSetting, DomainUserSetting, DomainSetting, SystemSetting) now accept both traditional _Setting arrays and Schema objects, making the transition to schema-based definitions smoother while maintaining backward compatibility.
Also applies to: 141-142, 161-162, 177-178, 193-194
359-359
: Updated module declaration to reflect package name changeThis correctly updates the module declaration to match the new package name '@cordisjs/core', ensuring type definitions are properly associated.
388-388
: Added dependency injection for database accessThe addition of the
inject = ['db']
export properly declares the database dependency, which is a good practice for dependency management.
395-395
: Improved context-aware database accessThe change from using the global database service to context-based DB access (
ctx.db
) improves testability and aligns with modern dependency injection practices.
419-420
: Added inject property to global modelThe addition of the
inject
property to the global Hydro model ensures proper dependency registration.eslint.config.mjs (6)
8-15
: Verify why certain files are fully ignored.
The currentglobalIgnores
includes.d.ts
files, which could prevent type definitions from being linted. Make sure you actually want to skip linting those, as they can benefit from basic checks.
19-21
: ecmaVersion 5 may be restrictive.
You might miss out on newer JavaScript features. If your codebase doesn’t need to target ES5 specifically, consider bumping this version to ES6 or higher.
32-32
: Confirm necessity of '.vue' extension.
The config includes.vue
in the resolver, but there was no mention of Vue in the summary. Verify if.vue
files are actually in use.
60-86
: Inconsistent ECMAScript versions across configurations.
Here,ecmaVersion
is set to 2020, whereas the top-level config is set to ES5. Ensure that this dual setup is intentional and won’t cause confusing lint behaviors.
104-105
: Double-check disabled ESLint rules.
'github/array-foreach'
and'@typescript-eslint/no-invalid-this'
are fully disabled. Verify if you need these rules for improved code quality standards.
110-114
: Align indentation rule settings.
The first block sets'@stylistic/indent'
with{ SwitchCase: 1 }
, while the last block omits this. Confirm if this difference in switch-case indentation style is intentional across different file patterns.Also applies to: 147-148
packages/elastic/index.ts (4)
34-34
: Add proper type annotation for the opts parameter.The
opts
parameter is missing a type annotation. Consider defining an interface for the options or using a more specific type to improve type safety.- async problemSearch(domainId: string, q: string, opts): ReturnType<ProblemSearch> { + async problemSearch(domainId: string, q: string, opts: { limit?: number; skip?: number }): ReturnType<ProblemSearch> {
72-72
: Add proper type annotations for the run method parameters.The parameters in the
run
method lack proper type annotations, which reduces type safety. Consider defining interfaces for these parameters.- async run({ domainId }, report) { + async run({ domainId }: { domainId?: string }, report: (status: { message: string }) => void) {
117-123
: Handle potential errors in script execution.The script registration doesn't include error handling for the
run
method when used as a callback. Consider wrapping it in a try-catch or using a higher-order function to catch and handle errors appropriately.- this.run.bind(this), + async (...args) => { + try { + return await this.run.bind(this)(...args); + } catch (error) { + this.ctx.logger.error(`Error in ensureElasticSearch script: ${error.message}`); + throw error; + } + },
20-126
: Overall good refactoring to class-based architecture.The refactoring from global functions to a class-based approach with proper dependency injection and configuration management is a significant improvement. The code is now more maintainable, testable, and adheres to better OOP principles. The service properly encapsulates the Elasticsearch functionality and follows a consistent pattern with other services in the codebase.
packages/hydrooj/src/model/oauth.ts (1)
18-18
: Confirm the updated return value.Previously,
findOneAndUpdate
would place the updated document inres.value
. Changing the return tores?.uid
might reference the overall result rather than the actual updated document. Please verify thatres?.uid
is indeed the correct property for the updateduid
.packages/utils/lib/utils.ts (2)
10-10
: New import from 'reggol' is introduced.Importing types and classes from
reggol
looks okay. No immediate issues spotted.
29-31
: Good approach for creating named loggers.The
createLogger
function is straightforward and promotes consistent logging usage across modules.packages/hydrooj/src/service/db.ts (6)
7-11
: Revising imports to integrateContext
andService
.The switch to a context-based service injection aligns with the new modular design. All references to
bus
look correct, but ensure thatbus
usage is consistent with the rest of the codebase.
29-33
: Context augmentation confirmed.Augmenting
Context
to includedb: MongoService
is consistent with the new pattern. Make sure all other services that depend ondb
are updated accordingly.
43-49
: Dynamic MongoDB URL generation.Using
mongodb-memory-server
in CI improves test reliability. Verify that it doesn’t inadvertently run in non-CI environments. If fallback logic is needed, confirm thatopts
fromload()
always yields a valid URL ornull
.
58-65
: Generator-based initialization.Yielding a cleanup function fits well with a lifecycle-based approach. Ensure that your service orchestrator consistently calls this generator and properly invokes the returned cleanup for graceful shutdown.
69-70
: Prefix andcollectionMap
usage.This logic correctly remaps collection names. Double-check if
prefix
includes trailing dots or other edge cases, and confirm thatcollectionMap
is always updated ifprefix
changes.
183-189
: Proxying thedb
export.Wrapping the service with a proxy referencing
app.get('db')
can obscure debugging ifapp
is not set or is changed late in startup. Confirm that all code paths reliably setapp
before calling anydb
methods.packages/hydrooj/src/interface.ts (6)
2-2
: Added import forParsedAuthenticatorData
.This import broadens type coverage for authentication details. Nothing problematic here.
7-8
: Extended usage ofRecordJudgeInfo
.Exporting
RecordJudgeInfo
from@hydrooj/common/types
is consistent with shared definitions. The reference seems properly aligned.
83-83
: RefinedauthenticatorExtensionResults
type.Switching to
ParsedAuthenticatorData['extensionsData']
ensures accurate typing. Be sure any code referencingAuthenticationExtensionsAuthenticatorOutputs
is updated accordingly.
226-229
: NewRecordHistoryDoc
interface.Extending
RecordJudgeInfo
and adding_id
/rid
is a clear way to store historical record data. Confirm that existing code or migrations account for this new structure.
637-637
: Restored or updatedproblemSearch
definition.This indicates a shift back to a module-based search function rather than a global reference; confirm that all consumers of
problemSearch
point here instead of any deprecated global or direct references.
663-663
: Switchedaddons
to a record structure.Changing
addons
from an array to aRecord<string, string>
might impact code expecting array semantics. Verify that all array-style accesses have been migrated to the new record-based approach.packages/hydrooj/src/loader.ts (14)
15-17
: Updated imports for enhanced type safetyThe import statement now includes additional types from the context module, including
Context
,Service
,ScopeStatus
, andEffectScope
. This improves type safety when working with these entities.
22-22
: Added Schema import for config validationThis import is necessary for the new
resolveConfig
method which uses schema validation.
48-48
: Enhanced type safety for state propertyThe
state
property now has a more specific type definition usingRecord<string, EffectScope>
instead of a generic object type, improving type safety and code clarity.
54-55
: Added static inject property for dependency injectionThis property explicitly declares the dependencies needed by the Loader service, making the dependency injection mechanism more transparent.
56-57
: Updated constructor to use Context parameterThe constructor now takes a
ctx
parameter rather than relying on global state, improving encapsulation and testability.
59-60
: Updated event handler to use ctx directlyThe event handler now uses the provided
ctx
parameter instead of accessing a global context, enhancing code clarity and maintainability.
98-107
: Added async resolveConfig method for schema-based configurationThis new method provides a structured approach to resolving plugin configurations using Schema validation. It handles both scoped and non-scoped configurations, and includes migration support.
109-117
: Updated reloadPlugin to use async/await patternThe reloadPlugin method has been updated to be async and now uses the new resolveConfig method. It has a cleaner approach to handling the plugin configuration.
121-121
: Simplified plugin application by directly using ctx.pluginThe method now directly uses
this.ctx.plugin
rather than relying on a parent context, improving code clarity and reducing dependencies.
135-136
: Improved error logging in resolvePluginError logging has been enhanced to provide more context when a plugin fails to resolve, which should aid in debugging.
147-152
: Converted preload to async function with Promise-based initializationThe
preload
function has been updated to use async/await syntax, with a Promise to ensureglobal.app
is properly initialized before proceeding. This enables better control flow and error handling.
161-161
: Make sure the semicolon is consistently appliedEnsure consistent use of semicolons to avoid potential issues with automatic semicolon insertion.
- global.addons[name] = modulePath + global.addons[name] = modulePath;
170-171
: Updated load function to use async/await syntaxThe
load
function has been updated to properly await the completion of thepreload
function, ensuring that initialization is complete before proceeding.
208-210
: Updated loadCli function to use async/await syntaxThe
loadCli
function has been updated to properly await the completion of thepreload
function, ensuring that initialization is complete before proceeding with CLI operations.packages/hydrojudge/src/checkers.ts (4)
12-12
: Added code property to CheckConfig interfaceAdded a new
code
property of typeCopyInFile
to theCheckConfig
interface, allowing user code to be passed to checkers. This enhancement enables checkers to access and potentially validate against the submitted code.
179-180
: Updated syzoj checker documentationDocumentation for the
syzoj
checker has been updated to reflect that thecode
property is now supported, removing the "(not impl)" notation.
190-190
: Implemented code property in syzoj checkerThe
syzoj
checker now properly implements thecode
property, allowing it to access the user's submitted code during the checking process.
206-206
: Added user_code mapping in testlib checkerThe
testlib
checker now maps theconfig.code
touser_code
in its sandbox configuration, enabling testlib checkers to access the submitted code.packages/hydrooj/src/model/opcount.ts (1)
16-16
: Updated property access to match MongoDB driver response structureThe return statement has been modified to access
opcount
directly from the response object, rather than from a nestedvalue
property. This change aligns with MongoDB driver's behavior when usingreturnDocument: 'after'
option.packages/hydrooj/src/model/blacklist.ts (1)
16-21
: Simplified return pattern for database operationThe method now directly returns the result of
findOneAndUpdate
without unnecessary intermediate variable assignment. This simplifies the code and aligns with the pattern used in other model methods.packages/hydrooj/src/model/record.ts (3)
2-2
: Usingsum
from lodash is appropriate.
Your addition ofsum
is consistent with the usage in this file.
23-23
: NewcollHistory
collection looks good.
Well-defined collection name and consistent naming scheme. Index creation forcollHistory
is included, so no immediate concerns.
283-328
: Verify indexing needs forcollHistory
.
Currently, only{ rid: 1, _id: -1 }
is indexed. If domain-based queries on historical records become necessary, consider including adomainId
field and index.packages/hydrooj/src/entry/worker.ts (13)
9-10
: Imports ofMongoService
andConfigService
acknowledged.
No conflicts identified.
12-12
: Addssetting
to the destructured imports.
This supports the subsequent usage of the settings plugin.
24-25
: Conditionally running setup for missing MongoDB URL.
Neat approach to streamline local onboarding.
31-33
: Plugin registration forlocale
,MongoService
, andConfigService
.
Good modular approach for loading services.
37-41
: Asynchronous injection ofloader
andconfig
.
No issues found.
43-46
: Reloading plugins in parallel.
Consistent with Hydro's modular plugin system.
48-50
: Chaining additional context injection.
Continues the pattern used above.
52-52
: Invokingapi.apply
directly.
Straightforward approach; no concerns.
60-65
: Applying settings viasetting(pending, fail, require('../model/setting'))
.
Maintains consistent plugin flow.
69-69
: Reloading handlers in a loop.
Clean approach to ensuring handler updates.
75-76
: Reloading scripts similarly.
Consistent usage with other reload patterns.
92-92
: Copying addon assets into static directory.
No flags here; safe to skip additional commentary.
97-102
: Inject server and listen.
Proper placement of server startup logic.packages/hydrooj/src/model/schedule.ts (2)
7-7
: ImportingWorkerService
type is fine.
Matches usage patterns in this file.
18-24
: Verify usage ofres
fromfindOneAndDelete
.
MongoDB’sfindOneAndDelete
typically stores the document inres.value
, which may benull
when no record is found. Relying onres
directly might introduce logic errors.framework/eslint-config/base.mjs (2)
1-14
: Initial ESLint config setup is valid.
Imports are properly declared andFlatCompat
usage is straightforward.
15-483
: Comprehensive ruleset aligns with best practices.
Your approach extends multiple rule sets, merges them properly, and configures advanced TypeScript rules. No major conflicts or redundancy noted.packages/hydrooj/src/service/worker.ts (2)
12-12
:❓ Verification inconclusive
Export style changed: Consider updating all imports
The class export has been changed from named export to default export, which will require updates to any imports of this service throughout the codebase.
Run this script to find usages that need to be updated:
🏁 Script executed:
#!/bin/bash # Find all imports of WorkerService that might need updating echo "Checking for imports that need updating..." rg "import.*WorkerService.*from '.*service/worker'" --type tsLength of output: 255
Action Required: Update Import in Model Schedule
The script found one import in
packages/hydrooj/src/model/schedule.ts
:
import type WorkerService from '../service/worker';
Since the service now uses a default export, the type-import here might not be ideal if it’s later used as a runtime value. Please verify if this import is solely for type purposes. If a runtime instantiation is performed, update the import to a value import (i.e. remove the
type
keyword):- import type WorkerService from '../service/worker'; + import WorkerService from '../service/worker';If the usage is exclusively for type checking, no changes are needed.
32-38
:❓ Verification inconclusive
DB result handling changed: potential breaking change
The function now directly checks and returns
res
instead ofres.value
, which indicates a change in the database layer response format. This could break code that expects the old structure.Let's check if there are any other places in the codebase that might be expecting the old structure:
🏁 Script executed:
#!/bin/bash # Search for other places using findOneAndDelete and expecting .value rg "findOneAndDelete.*\.value" --type tsLength of output: 42
Action Required: Verify DB Result Format Dependency
The updated code in
packages/hydrooj/src/service/worker.ts
(lines 32–38) now directly returnsres
instead of usingres.value
. Our automated search for usages of patterns likefindOneAndDelete
expecting a.value
(e.g., via the commandrg "findOneAndDelete.*\.value" --type ts
) did not locate any such references. However, since the search produced no output—which might be due to limitations in the inference—we need manual verification to ensure that no part of the codebase still depends on the old structure.Please confirm that:
- Any modules or services handling database responses are updated to work with the complete result object (
res
).- There are no residual expectations of a
.value
property elsewhere in the application.packages/ui-default/backendlib/template.ts (2)
25-34
: Good implementation of file traversalThe recursive
getFiles
function effectively handles directory traversal and correctly normalizes path separators for cross-platform compatibility.
161-275
: Well-structured TemplateService with dependency injectionThe
TemplateService
class follows good service-oriented design principles with clear separation of concerns, proper initialization, and error handling. The use of static injection points and context registration improves maintainability.framework/eslint-config/package.json (2)
7-21
:❓ Verification inconclusive
Dependency updates: Review for compatibility
Several dependencies have been updated to newer versions, including major version upgrades. Ensure these are compatible with your codebase.
🏁 Script executed:
#!/bin/bash # Check for any peer dependency warnings or errors npm ls --depth=0Length of output: 8122
Action Required: Manually Verify ESLint Dependency Compatibility
The dependency updates in
framework/eslint-config/package.json
(e.g., updates to@typescript-eslint/*
,eslint-config-airbnb
, etc.) look intentional. However, thenpm ls --depth=0
output reveals several unmet dependency errors related to the monorepo’s local packages, which may be obscuring any subtle compatibility problems.Before merging, please ensure that:
- The updated ESLint plugins, parser, and related packages work seamlessly with the overall codebase.
- There are no new peer dependency issues or runtime conflicts when the monorepo’s linked packages are fully installed.
- An end-to-end linting and integration test is performed to confirm that these dependency updates behave as expected in context.
5-5
:❓ Verification inconclusive
Main entry point changed: Update dependent packages
The main entry has changed from
react.yaml
tobase.mjs
, which may require updates in packages that import this config.
🏁 Script executed:
#!/bin/bash # Find packages that might need updates due to the changed entry point echo "Checking for packages using the old entry point..." rg -l "require.*@hydrooj/eslint-config/react" --type jsLength of output: 168
Action Required: Confirm External Dependency Updates for New Main Entry
The update in
framework/eslint-config/package.json
changes the package’s main entry fromreact.yaml
tobase.mjs
. Our initial script search for references matching the old entry did not return any local hits. However, because the automated output was inconclusive, please manually verify that no external packages or documentation still depend on the legacyreact.yaml
entry.
- File Affected:
framework/eslint-config/package.json
(line 5)- Verification Needed: Check for any dependent code, documentation, or configuration (possibly external to this repository) that references
@hydrooj/eslint-config/react
or the stringreact.yaml
.packages/ui-default/index.ts (3)
77-77
: System settings reference updatedThe change from
SystemSettings
tothis.ctx.config.settings
aligns with the broader refactoring to use context-based configuration.
3-4
: Good architecture change: Service dependency injectionReplacing the direct import with proper service injection via
ctx.plugin(TemplateService)
improves modularity and testability.Also applies to: 167-167
25-25
: Improved type safety with explicit type annotationsAdding explicit type annotation for the
sections
array enhances code reliability and IDE support.packages/hydrooj/src/settings.ts (1)
55-67
: Security improvement needed for prototype pollution prevention.The
applyDelta
method includes a blacklist check for dangerous property names, but the implementation in line 65 could still be vulnerable to prototype pollution through other attack vectors.While the blacklist approach in line 57 helps prevent common prototype pollution attacks, consider implementing a more comprehensive solution:
applyDelta(source: any, key: string, value: any) { const path = key.split('.'); if (path.some((i) => ConfigService.blacklist.includes(i))) return false; const t = path.pop(); const root = JSON.parse(JSON.stringify(source)); let cursor = root; for (const p of path) { cursor[p] ??= {}; + // Additional safety check for properties with __proto__ in them + if (Object.prototype.hasOwnProperty.call(cursor, p) && + typeof cursor[p] !== 'object') return false; cursor = cursor[p]; } + // Prevent setting properties that might lead to prototype pollution + if (t && (t === '__proto__' || t === 'constructor' || t === 'prototype')) return false; cursor[t] = value; return root; }packages/hydrooj/src/model/domain.ts (3)
213-213
: Logical change to domain user role authorization.Line 213 introduces a new condition requiring
join: true
for users without thePRIV_VIEW_ALL_DOMAIN
privilege to access domains with roles other than 'guest'.This change improves access control by ensuring users can only access domains they've explicitly joined or have appropriate privileges for.
258-260
: Query modification to only return users who have joined the domain.The
getDictUserByDomainId
method now filters for users withjoin: true
, ensuring only active domain members are returned.This change ensures consistency with the join-based access control model being implemented throughout the codebase.
292-312
: Well-structured event handling with proper Context integration.The new
apply
function properly integrates with the context system for event handling and database initialization.The function correctly:
- Sets up a domain cache invalidation event handler
- Ensures necessary database indexes are created
- Follows the service pattern using the Context parameter
This aligns with the broader refactoring effort toward better context-based dependency injection throughout the application.
packages/hydrooj/src/entry/common.ts (3)
24-45
: Simplified loader system with improved type safety.The function signature has changed from accepting an array of strings to a record mapping, and the loader now properly uses the Context parameter.
The new implementation:
- Uses
Object.entries()
for cleaner iteration over the mapping- Correctly passes the plugin name during reloading
- Properly integrates with the context system for logging
This aligns with the broader refactoring of the application toward better type safety and context-based dependency injection.
60-81
: Improved locale loading with better type safety.The function signature has changed to accept a Record instead of an array, and uses
Object.values()
for iteration.The change maintains functionality while providing better type safety and integration with the new module loading patterns.
83-122
: Consistent refactoring of settings loader.Similar to other loader functions, this has been updated to use a Record parameter and Object.values() for iteration.
The implementation maintains the same functionality while adhering to the new loading patterns established throughout the codebase.
packages/hydrooj/src/handler/domain.ts (4)
258-258
: Improved role filtering in domain join applications.The code now only excludes the 'guest' role instead of both 'default' and 'guest', simplifying role management.
This change allows the 'default' role to be offered as a join option, which is more flexible and consistent with the domain access model.
322-337
: Enhanced domain join preparation with target parameter.The
prepare
method now supports joining a different domain than the current context through the target parameter.This change adds flexibility to the domain join process and properly handles authorization checks, ensuring users can only join domains they're allowed to access.
🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
339-358
: Improved domain join page with detailed domain information.The
get
method now includes comprehensive domain information in the response, enhancing the user experience.The added domain information provides users with more context when joining a domain, including owner details, avatar, and bulletin information when available.
369-376
: Flexible role assignment during domain join.The
post
method now conditionally assigns the role from join settings, improving the domain onboarding flow.This implementation correctly:
- Sets the
join: true
flag to mark the user as an explicit member- Only assigns a role if join settings specify one
- Properly redirects to the target domain homepage with success notification
packages/hydrooj/src/model/document.ts (18)
12-12
: Switching to default import for bus
No concerns. This adoption of default import from thebus
module is consistent.
18-18
: Refine type definitions
UsingExclude<ArrayKeys<O, P>, symbol>
is a solid approach to isolate valid string-based keys. No issues found.
23-33
: Enhance TypeScript inference withas const
Declaring constants withas const
fosters better type inference. Good improvement over explicit type assignments.
112-112
: Return statements
Returningawait coll.findOneAndUpdate(...)
is consistent with your approach.
No immediate issues.
152-152
: Same pattern of returning fromfindOneAndUpdate()
Maintaining consistency across the codebase. Looks good.
162-162
: Refactoring incAndSet
No issues with theawait coll.findOneAndUpdate(...)
; consider verifying null results.
211-211
: Pull subdocuments
No concerns. The code is aligned with the other findOneAndUpdate usage.
224-224
: Return statement for deleteSub
Consistent usage of findOneAndUpdate.
253-253
: Setting subdocument
Returning the updated document. No issues found.
267-267
: Add to set operation
Checking your usage of$addToSet
is consistent. All good.
279-279
: DefinegetStatus
function
No issues. This new function to retrieve status fromcollStatus
is straightforward.
293-293
: Returning doc.value and generated ID
This is a convenient approach to pass both the updated doc snapshot and the newly created_id
.
329-329
: Conditional status update
No immediate issues with calling findOneAndUpdate. Validate usage results if needed.
359-359
: Capped increment
Ensuring the usage of$inc
with boundary checks is beneficial. Approved.
370-370
: Increment status
No concerns. The logic is consistent with the rest of the doc.
386-386
: Fallback withres ||=
This approach to setres
from findOneAndUpdate if it’s falsy is a neat pattern.
398-398
: Initialize revision
Returning the updated doc from collStatus is consistent.
411-411
: Set revision
Approach looks good. Potentially verify doc not null.build/prepare.js (10)
18-22
: Update TS compiler options
Switchingtarget
to'es2022'
,lib
to['es2022']
,module
to'preserve'
, andmoduleResolution
to'bundler'
is beneficial for advanced features. No concerns.
37-37
: Add reference to tsconfig.ui-next.json
No issues. This helps unify the build config.
78-78
: Exclude directories
Filtering out'ui-default'
and'ui-next'
is consistent with the new architecture.
83-87
: Add excludes for UI default
Excluding'packages/ui-default/index.ts'
,'backendlib/builder.ts'
,'misc.ts'
,'template.ts'
,'markdown.js'
.
No immediate concerns.
100-121
: Enhanced UIConfig
Adoptingreact-jsx
, bundler mode,noEmit
, and other TS checks improves the build. Looks consistent.
123-155
: Add UINextConfig
Creating a separate config forui-next
fosters modular development. Looks good.
197-197
: Patch invocation
No issues withtryUpdate
usage ontsconfig.json
.
199-210
: Iterate modules
This block ensures dynamic TS config creation for each package. Good approach.
219-219
: Generate default index
Writing a fallbackmodule.exports
is a neat convenience for Node resolution.
223-225
: Update root TS config
ApplyingUIConfig
,UINextConfig
, and the main config systematically. Looks correct.framework/framework/server.ts (28)
5-5
: Use of CordisContext & Service
ImportingContext as CordisContext
from@cordisjs/core
for extended type usage is a good design choice.
22-22
: KnownHandlers type import
No immediate issues with referencingKnownHandlers
.
44-53
: IntroducingforkContextWithScope
Creating a scoped plugin context fosters better disposal. This pattern is beneficial for lifecycle management.
149-149
: Constructor receives typed context
PassingC
for the second constructor param is consistent with generic usage.
197-198
: Renderer selection
Filtering valid renderers by extension or fallback. Good approach to combine.
210-211
: Extended Handler
Handler<C = CordisContext>
extendsHandlerCommon<C>
clarifies general usage. This is a consistent pattern.
258-259
: ConnectionHandler
Similarly extendsHandlerCommon<C>
. Good use of generics.
337-337
: Generic WebService
AllowingC extends CordisContext
for better type coverage. Approved.
351-351
: ExposeHandler
ExposingHandlerCommon
,Handler
,ConnectionHandler
as class properties ensures consistent usage.
450-450
: 404 fallback
CallinghandleHttp
withNotFoundHandler
is a straightforward approach to handle unknown routes.
478-478
: Log success
Neat usage oflogger.success
to display listening address.
564-569
: RefactorhandleWS
Creating a sub scope again is consistent, with the same event pattern'connection/create'
.
599-611
: Cleanup routine
Encapsulating the disposal logic inclean()
is robust. Good approach.
635-637
: Tracking heartbeats
Usingpong
event to refreshlastHeartbeat
. No issues.
642-644
: Reply to ping
Sending'pong'
on'ping'
keeps the connection active.
646-646
: Close invalid connection
If JSON parse fails, forcibly close. Straightforward approach.
649-649
:message?.()
usage
Optional chaining is concise, re-check for null or undefined if needed.
712-714
: Shadow context
Conditionally retrieving parent context fromSymbol.for('cordis.shadow')
. No immediate issues.
716-716
: Route binding
Passing theChecker(permPrivChecker)
tohandleHttp
for route-based perms is consistent.
719-722
: WebSocket route
Similarly passinghandleWS
for a new route ensures parallel approach for WS. Good job.
734-739
:withHandlerClass
Allows dynamic usage of the registry. The fallback logic with.on('handler/register/<name>')
is clever.
754-754
: Connection method
MirrorsRoute
method withhandleWS
. No issues.
757-763
: registerLayer
Applying effect to add or remove layers is a neat pattern.
812-816
: applyMixin
Your approach is consistent with the rest of the dynamic architecture. Approved.
818-820
: handlerMixin
Applying partial or functional mixins toHandlerCommon
. No issues found.
822-824
: httpHandlerMixin
Same pattern for HTTP handlers.
826-827
: wsHandlerMixin
Assigning properties from partial mixins for WS. Straightforward approach.
841-847
: Augment@cordisjs/core
Context
Declaringserver
,Route
,Connection
,withHandlerClass
on the CordisContext
interface for better integration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (6)
build/prepare.js (1)
163-167
:⚠️ Potential issueFix potential file system race condition
The
tryUpdate
function has a potential race condition between checking if a file exists and reading it. If the file is deleted between these operations, it could cause errors.Consider using a try-catch approach instead:
const tryUpdate = (location, content) => { - const current = fs.existsSync(location) ? fs.readFileSync(location, 'utf-8') : ''; + let current = ''; + try { + current = fs.readFileSync(location, 'utf-8'); + } catch (err) { + // File doesn't exist or cannot be read + } const expected = typeof content === 'string' ? content : JSON.stringify(content, null, 2); if (expected !== current) fs.writeFileSync(location, expected); };🧰 Tools
🪛 GitHub Check: CodeQL
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.packages/hydrooj/src/settings.ts (1)
164-167
: 🛠️ Refactor suggestionFire-and-forget in Proxy setter may swallow DB write errors
The
set
trap in the proxy does not awaitthat.setConfig(...)
, which can result in silent failures if the database call rejects.Consider making the proxy setter async or otherwise surfacing error handling:
- set(self, p: string | symbol, newValue: any) { - that.setConfig(path.concat(p).join(','), newValue); - return true; - }, + async set(self, p: string | symbol, newValue: any) { + try { + await that.setConfig(path.concat(p).join(','), newValue); + } catch (err) { + logger.error('Failed to set config property:', err.message); + return false; + } + return true; + },packages/ui-default/index.ts (1)
56-56
:⚠️ Potential issueRemove the empty object pattern.
The empty object pattern
{ }
is unnecessary and flagged by static analysis. This parameter doesn't serve any purpose and should be removed.- async get({ }, legacy = false, nohint = false) { + async get(legacy = false, nohint = false) {🧰 Tools
🪛 Biome (1.9.4)
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
framework/framework/server.ts (3)
139-140
:⚠️ Potential issueAddress unsafe declaration merging in HandlerCommon
Declaring both
export interface HandlerCommon<C>
(empty) andexport class HandlerCommon<C>
under the same name can lead to unsafe declaration merging in TypeScript, as flagged by the linter.Consider removing or renaming the empty interface, or using a type alias if you need to augment the class's shape:
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Consider removing or a type alias if needed: +// type HandlerCommonProps<C> = {} export class HandlerCommon<C> { // ... }🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
498-501
:⚠️ Potential issueAddress FIXME comments for type checking
Multiple locations use type assertions to
any
with FIXME comments about passing type checks. These should be properly typed rather than bypassing TypeScript's type system.Create proper type definitions for the event handlers to avoid type assertions:
// In your interfaces file: interface HandlerEvents<T> { 'handler/create': [handler: T, type: 'http' | 'ws']; 'handler/create/http': [handler: T]; 'handler/create/ws': [handler: T]; 'handler/error': [handler: T, error: Error]; 'connection/create': [handler: T]; 'connection/active': [handler: T]; 'connection/close': [handler: T]; } // Then update your context interface to include these typed events interface C extends CordisContext { parallel<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>; serial<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>; }Also applies to: 536-537, 551-554, 568-570, 603-605, 655-657, 739-741
676-709
:⚠️ Potential issueImproved checker function with better variable handling
The inline definition of the
Checker
function within theregister
method improves encapsulation and code organization. However, there's a potential issue with the condition in line 705.The condition
if (perm)
at line 705 is flagged by static analysis as always evaluating to false. Investigate whyperm
is not being properly set or detected in this context:- if (perm) this.checkPerm(perm); + if (perm !== undefined && perm !== null) this.checkPerm(perm);
🧹 Nitpick comments (19)
eslint.config.mjs (2)
40-40
: Unify or justify different@typescript-eslint/no-invalid-this
values.The rule is set to
1
(warning) under one config block and disabled (0
) under another. If this is to allow different behaviors in distinct parts of the code, that’s fine. Otherwise, consider applying a single, consistent rule value to avoid confusion.Also applies to: 105-105
42-52
: Consolidate or differentiate repeatedsimple-import-sort/imports
rules.You have two different grouping configurations for
simple-import-sort/imports
. If they’re meant for separate contexts, keep them. Otherwise, merging or clarifying their usage can prevent collisions or confusion.Also applies to: 121-135
framework/eslint-config/base.mjs (2)
64-83
: Check multiline comma usage.The rule
'@stylistic/comma-dangle'
is set to'always-multiline'
, which is fine for readability but can feel strict in smaller code snippets. If it’s a team preference, no issue. Otherwise, consider making it optional.
401-401
:github/array-foreach
: usage caution.Setting
'github/array-foreach': 1
to warn can help devs avoid potential side effects of arrayforEach
. Ensure your team is aware of the reasons behind this setting, like potential performance or using more explicit loops.framework/eslint-config/package.json (1)
24-25
: ESLint peer dependency requires version >= 9.Bumping the peer dependency might break older setups. Ensure contributing developers have ESLint 9+ installed, or provide instructions to upgrade.
.github/workflows/build.yml (1)
26-26
: Note on Deprecatedset-output
Usage
The command on line 26 uses the now-deprecated::set-output
syntax. Consider updating this step to use the recommended$GITHUB_OUTPUT
approach. For example:- run: echo "::set-output name=dir::$(yarn config get cacheFolder)" + run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUTThis update will help future-proof the workflow against breaking changes in GitHub Actions.
🧰 Tools
🪛 actionlint (1.7.4)
26-26: workflow command "set-output" was deprecated. use
echo "{name}={value}" >> $GITHUB_OUTPUT
instead: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions(deprecated-commands)
packages/ui-default/backendlib/template.ts (4)
25-34
: Consider adding robust error handling or concurrency.While this recursive file reader works, adding try-catch blocks or concurrency could help avoid potential I/O bottlenecks or crashes if an error occurs (e.g., permission issues, missing directories).
36-42
: Switch to asynchronous operations if performance is critical.Currently,
fs.existsSync
is a synchronous check. Switching to an async check, or at least handling potential errors, can improve performance and resiliency under heavy loads.
44-56
: Use optional chaining in lookup.Instead of
(obj || {})._original
, consider leveraging optional chaining (obj?._original
) to reduce verbosity and guard against null or undefined values more cleanly.🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
59-59
: Enhance type safety for the constructor.
constructor(Loader: any)
could be strengthened by introducing a proper type/interface forLoader
to improve maintainability and catch potential errors at compile time.packages/utils/lib/utils.ts (1)
33-35
: Type safety concerns with Logger type castingThe type declaration and export statement use type casting (
as any as Logger
) which may reduce type safety. Consider implementing a proper constructor signature that matches the declared type without needing the unsafe casting.-export type Logger = Reggol & { new(name: string): Reggol & Logger }; -export const Logger = createLogger as any as Logger; +export type Logger = Reggol; +export const Logger = createLogger;Alternatively, if the constructor signature is required for backward compatibility, consider implementing a proper factory class that satisfies both the function call and constructor patterns.
packages/hydrooj/src/service/db.ts (1)
182-189
: Added backward compatibility proxy with deprecation noticeThe implementation of a proxy object with a deprecation notice provides backward compatibility while encouraging migration to the context-based approach. Consider adding a timeline for when this compatibility layer will be removed.
You might want to add a more visible deprecation warning that appears at runtime:
/** @deprecated use ctx.db instead */ const db = new Proxy({} as MongoService, { get(target, prop) { + console.warn('Warning: Direct db access is deprecated. Use ctx.db instead.'); return app.get('db')?.[prop]; }, });
packages/hydrooj/src/handler/misc.ts (2)
110-110
: Empty object pattern used as parameterThe domainId parameter has been replaced with an empty object pattern. This is flagged by static analysis as potentially problematic. Consider using a more descriptive parameter structure or a proper options object with named properties.
-async get({ }, target: string, filename = '', expire: number, secret: string) { +async get(_: Record<string, never>, target: string, filename = '', expire: number, secret: string) {Or if this is part of a broader refactoring to use destructuring:
-async get({ }, target: string, filename = '', expire: number, secret: string) { +async get({}: { domainId?: string }, target: string, filename = '', expire: number, secret: string) {🧰 Tools
🪛 Biome (1.9.4)
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
124-124
: Empty object pattern used as parameterSimilar to line 110, the domainId parameter has been replaced with an empty object pattern, which is flagged by static analysis. Consider using a more meaningful parameter structure.
-async get({ }, uid: number) { +async get(_: Record<string, never>, uid: number) {Or if this is part of a broader refactoring to use destructuring:
-async get({ }, uid: number) { +async get({}: { domainId?: string }, uid: number) {🧰 Tools
🪛 Biome (1.9.4)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/ui-default/index.ts (1)
119-119
: Added explicit typing for better code readability.Adding the
any[]
type annotation tores
improves code clarity, though consider using a more specific type thanany
if possible.packages/hydrooj/src/loader.ts (1)
49-49
: Improve type safety by using a more specific type.Don't use
{}
as a type as it means "any non-nullable value". Prefer explicitly defining the object shape or use a more specific type.- public config: {}; + public config: Record<string, unknown>;🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/model/domain.ts (1)
138-138
: Use Array.isArray() for more reliable type checking.Replace
instanceof Array
withArray.isArray()
as it's more reliable, especially with arrays from different execution contexts.- if (!(uid instanceof Array)) { + if (!Array.isArray(uid)) {🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
packages/hydrooj/src/handler/domain.ts (2)
155-155
: Consider using undefined assignment instead of delete operatorThe
delete
operator can have performance implications in JavaScript. Consider using undefined assignment instead.- delete u.user; + u.user = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
335-335
: Consider using undefined assignment instead of delete operatorSimilar to the earlier issue, using the
delete
operator can impact performance. Consider using undefined assignment instead.- else if (!this.joinSettings) throw new DomainJoinForbiddenError(target); + if (assignedRole !== 'default') this.joinSettings = undefined; + else if (!this.joinSettings) throw new DomainJoinForbiddenError(target);🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (94)
.eslintrc.yaml
(0 hunks).github/workflows/build.yml
(1 hunks)build/prepare.js
(5 hunks)eslint.config.mjs
(1 hunks)framework/eslint-config/base.mjs
(1 hunks)framework/eslint-config/base.yaml
(0 hunks)framework/eslint-config/package.json
(1 hunks)framework/eslint-config/react.yaml
(0 hunks)framework/eslint-config/typescript.js
(0 hunks)framework/framework/error.ts
(0 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrojudge/src/cases.ts
(0 hunks)packages/hydrojudge/src/checkers.ts
(4 hunks)packages/hydrojudge/src/daemon.ts
(0 hunks)packages/hydrojudge/src/hosts/hydro.ts
(0 hunks)packages/hydrojudge/src/hosts/vj4.ts
(1 hunks)packages/hydrojudge/src/judge/hack.ts
(4 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/commands/install.ts
(1 hunks)packages/hydrooj/src/entry/cli.ts
(2 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/setup.ts
(0 hunks)packages/hydrooj/src/entry/worker.ts
(3 hunks)packages/hydrooj/src/handler/contest.ts
(0 hunks)packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/misc.ts
(3 hunks)packages/hydrooj/src/handler/problem.ts
(1 hunks)packages/hydrooj/src/interface.ts
(6 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/blacklist.ts
(1 hunks)packages/hydrooj/src/model/contest.ts
(7 hunks)packages/hydrooj/src/model/document.ts
(11 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/hydrooj/src/model/message.ts
(3 hunks)packages/hydrooj/src/model/oauth.ts
(1 hunks)packages/hydrooj/src/model/opcount.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/record.ts
(8 hunks)packages/hydrooj/src/model/schedule.ts
(2 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/storage.ts
(6 hunks)packages/hydrooj/src/model/system.ts
(3 hunks)packages/hydrooj/src/model/task.ts
(3 hunks)packages/hydrooj/src/model/token.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(8 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)packages/hydrooj/src/script/problemStat.ts
(0 hunks)packages/hydrooj/src/script/storageUsage.ts
(0 hunks)packages/hydrooj/src/service/bus.ts
(5 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/worker.ts
(2 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/migrate/package.json
(1 hunks)packages/onlyoffice/frontend/office.page.ts
(0 hunks)packages/onsite-toolkit/frontend/resolver.page.tsx
(2 hunks)packages/ui-default/.eslintignore
(0 hunks)packages/ui-default/.eslintrc.js
(0 hunks)packages/ui-default/api.ts
(0 hunks)packages/ui-default/backendlib/builder.ts
(4 hunks)packages/ui-default/backendlib/markdown-it-imsize.ts
(1 hunks)packages/ui-default/backendlib/markdown-it-media.ts
(0 hunks)packages/ui-default/backendlib/misc.ts
(1 hunks)packages/ui-default/backendlib/template.ts
(3 hunks)packages/ui-default/build/config/webpack.ts
(1 hunks)packages/ui-default/build/main.ts
(1 hunks)packages/ui-default/components/autocomplete/components/AutoComplete.tsx
(3 hunks)packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
(1 hunks)packages/ui-default/components/calendar/index.js
(2 hunks)packages/ui-default/components/message/worker.ts
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
(1 hunks)packages/ui-default/components/problemconfig/reducer/config.ts
(1 hunks)packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/Testcase.tsx
(1 hunks)packages/ui-default/components/scratchpad/DataInputComponent.jsx
(0 hunks)packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
(0 hunks)packages/ui-default/index.ts
(6 hunks)packages/ui-default/package.json
(5 hunks)packages/ui-next/package.json
(1 hunks)packages/ui-next/src/App.tsx
(1 hunks)packages/utils/lib/locate-pm2.ts
(1 hunks)packages/utils/lib/utils.ts
(1 hunks)packages/utils/package.json
(2 hunks)packages/vjudge/src/index.ts
(3 hunks)packages/vjudge/src/providers/codeforces.ts
(0 hunks)packages/vjudge/src/providers/hduoj.ts
(0 hunks)packages/vjudge/src/providers/poj.ts
(0 hunks)packages/vjudge/src/providers/spoj.ts
(0 hunks)packages/vjudge/src/providers/uoj.ts
(0 hunks)packages/vjudge/src/providers/yacs.ts
(0 hunks)
💤 Files with no reviewable changes (25)
- packages/hydrooj/src/script/problemStat.ts
- packages/hydrojudge/src/daemon.ts
- packages/ui-default/.eslintignore
- packages/ui-default/api.ts
- packages/ui-default/components/scratchpad/DataInputComponent.jsx
- packages/ui-default/backendlib/markdown-it-media.ts
- packages/hydrooj/src/entry/setup.ts
- packages/hydrojudge/src/hosts/hydro.ts
- packages/vjudge/src/providers/poj.ts
- packages/hydrojudge/src/cases.ts
- packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
- packages/vjudge/src/providers/yacs.ts
- packages/vjudge/src/providers/spoj.ts
- packages/vjudge/src/providers/hduoj.ts
- packages/hydrooj/src/script/storageUsage.ts
- framework/eslint-config/typescript.js
- packages/onlyoffice/frontend/office.page.ts
- packages/vjudge/src/providers/uoj.ts
- packages/vjudge/src/providers/codeforces.ts
- framework/eslint-config/base.yaml
- packages/hydrooj/src/handler/contest.ts
- framework/eslint-config/react.yaml
- framework/framework/error.ts
- .eslintrc.yaml
- packages/ui-default/.eslintrc.js
✅ Files skipped from review due to trivial changes (14)
- packages/ui-default/components/message/worker.ts
- packages/ui-default/components/problemconfig/reducer/config.ts
- packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
- packages/utils/lib/locate-pm2.ts
- packages/ui-default/build/config/webpack.ts
- packages/ui-default/build/main.ts
- packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
- packages/ui-default/components/problemconfig/tree/Testcase.tsx
- packages/ui-default/backendlib/misc.ts
- packages/ui-default/backendlib/markdown-it-imsize.ts
- packages/hydrojudge/src/hosts/vj4.ts
- packages/ui-default/components/calendar/index.js
- packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
- packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
🚧 Files skipped from review as they are similar to previous changes (25)
- packages/ui-next/src/App.tsx
- packages/migrate/package.json
- packages/hydrooj/src/ui.ts
- packages/hydrooj/src/model/storage.ts
- packages/hydrooj/src/handler/problem.ts
- packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
- packages/hydrooj/src/model/message.ts
- packages/ui-next/package.json
- packages/hydrooj/src/model/system.ts
- packages/hydrooj/src/model/token.ts
- packages/hydrojudge/src/checkers.ts
- packages/hydrojudge/src/judge/hack.ts
- packages/ui-default/components/autocomplete/components/AutoComplete.tsx
- packages/onsite-toolkit/frontend/resolver.page.tsx
- packages/ui-default/backendlib/builder.ts
- packages/hydrooj/src/entry/cli.ts
- packages/hydrooj/src/model/problem.ts
- packages/hydrooj/src/model/contest.ts
- packages/utils/package.json
- packages/hydrooj/src/commands/install.ts
- packages/hydrooj/src/plugin-api.ts
- packages/hydrooj/src/model/user.ts
- packages/vjudge/src/index.ts
- package.json
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (12)
packages/hydrooj/src/entry/worker.ts (2)
packages/hydrooj/src/service/db.ts (1) (1)
MongoService
(35-180)packages/hydrooj/src/settings.ts (1) (1)
ConfigService
(14-172)
packages/hydrooj/src/model/record.ts (2)
packages/hydrooj/src/model/document.ts (1) (1)
apply
(413-447)packages/hydrooj/src/model/task.ts (1) (1)
apply
(145-191)
packages/hydrooj/src/service/db.ts (1)
packages/hydrooj/src/options.ts (1) (1)
load
(24-37)
packages/hydrooj/src/service/bus.ts (6)
packages/hydrooj/src/context.ts (3) (3)
EventMap
(13-13)Context
(31-41)Context
(68-77)packages/hydrooj/src/plugin-api.ts (3) (3)
EventMap
(57-57)Handler
(40-40)Context
(41-41)framework/framework/interface.ts (1) (1)
VoidReturn
(19-19)packages/hydrooj/src/service/server.ts (1) (1)
Handler
(74-76)packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/ui-default/context.ts (2) (2)
Context
(8-11)Context
(13-13)
packages/ui-default/backendlib/template.ts (3)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/api.ts (3) (3)
Service
(5-5)ctx
(5-5)Context
(5-5)packages/hydrooj/src/model/builtin.ts (2) (2)
PERM
(9-102)PRIV
(240-267)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/model/setting.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/interface.ts (1)
packages/common/types.ts (1) (1)
RecordJudgeInfo
(84-96)
packages/hydrooj/src/entry/common.ts (4)
packages/ui-default/api.ts (2) (2)
ctx
(5-5)Context
(5-5)packages/hydrooj/src/plugin-api.ts (1) (1)
Context
(41-41)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/utils.ts (1) (1)
unwrapExports
(21-29)
packages/elastic/index.ts (4)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/hydrooj/src/settings.ts (1) (1)
Context
(30-34)packages/hydrooj/src/interface.ts (1) (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1) (1)
ProblemModel
(74-675)
framework/framework/server.ts (8)
packages/ui-default/context.ts (4) (4)
ctx
(18-18)Service
(16-17)Context
(8-11)Context
(13-13)packages/hydrooj/src/service/layers/base.ts (1) (1)
ctx
(20-72)packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)packages/hydrooj/src/service/layers/domain.ts (1) (1)
ctx
(6-35)packages/hydrooj/src/service/server.ts (2) (2)
HandlerCommon
(31-39)Handler
(74-76)packages/hydrooj/src/plugin-api.ts (4) (4)
HandlerCommon
(7-7)Handler
(40-40)Service
(41-41)Context
(41-41)framework/framework/interface.ts (1) (1)
KnownHandlers
(3-5)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
packages/hydrooj/src/model/document.ts (7)
packages/hydrooj/src/model/user.ts (1) (1)
coll
(22-22)packages/hydrooj/src/model/oplog.ts (1) (1)
coll
(8-8)packages/hydrooj/src/model/discussion.ts (1) (1)
coll
(43-43)packages/hydrooj/src/model/problem.ts (1) (1)
incStatus
(431-436)packages/hydrooj/src/model/token.ts (1) (1)
update
(53-71)packages/hydrooj/src/model/record.ts (1) (1)
update
(195-219)packages/hydrooj/src/service/monitor.ts (1) (1)
update
(76-89)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/misc.ts
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/ui-default/backendlib/template.ts
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().
(lint/security/noGlobalEval)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/hydrooj/src/loader.ts
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
framework/framework/server.ts
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
packages/hydrooj/src/handler/domain.ts
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/model/document.ts
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/ui-default/index.ts
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🪛 GitHub Check: CodeQL
build/prepare.js
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
🔇 Additional comments (125)
eslint.config.mjs (2)
19-21
: Confirm the intended ECMAScript version.Here,
ecmaVersion
is set to5
, but in the second block (lines 75-76), it’s set to2020
. If you’re expecting modern syntax features, please verify that this dual setting is intentional and doesn’t lead to contradictory linting outcomes.
110-114
: Two-space indentation looks consistent.Using two spaces across your project is a popular and readable convention. Great job keeping it consistent in this block.
framework/eslint-config/base.mjs (2)
243-249
: Consistent use of quotes and semicolons.Enforcing single quotes via
'@stylistic/quotes'
and requiring semicolons through'@stylistic/semi'
ensures consistency across the codebase. This is a solid style choice.
279-343
: Thorough naming-convention rules.Your
@typescript-eslint/naming-convention
configuration is quite detailed, covering many selectors and patterns. This level of specificity can help keep a large, fast-moving codebase consistent.framework/eslint-config/package.json (2)
5-5
: Entry point updated.Changing
"main"
from a YAML file to"base.mjs"
aligns with your new JavaScript-based configuration approach. This is a straightforward improvement.
7-21
: Verify compatibility of new dependencies.Several new or upgraded ESLint plugins (
@eslint-react/eslint-plugin
,@eslint/compat
,@eslint/eslintrc
,@stylistic/eslint-plugin
, etc.) may come with new rules or behaviors. Confirm they integrate well with pre-existing settings..github/workflows/build.yml (1)
66-66
:❓ Verification inconclusive
Updated Parallel Build Command
The change on line 66 removes the separatelint:ui:ci
task in favor of runninglint:ci
,build
,build:ui:production:webpack
, andtest
in parallel when UI changes are detected (or the package version differs). Please verify that this adjustment aligns with the intended linting strategy for UI components and that no essential UI-specific linting is inadvertently skipped.
I'll run a shell script to verify that references to the removed
lint:ui:ci
task are indeed gone from the repository and to check that the remaining linting commands (specificallylint:ci
) are correctly defined (for example, in the package.json file). This will help confirm that the updated parallel build command is in line with the intended linting strategy without accidentally skipping essential UI linting.Please run these scripts and share the outputs to confirm the intended changes before finalizing the review comment.
🏁 Script executed:
#!/bin/bash # Verify that references to "lint:ui:ci" have been removed from the repository. echo "Searching for references to 'lint:ui:ci' in repository:" rg "lint:ui:ci" -n . # Check package.json for lint command definitions. echo "Searching for 'lint:ci' in package.json:" rg '"lint:ci":' package.json -n . echo "Searching for 'lint:ui:ci' in package.json:" rg '"lint:ui:ci":' package.json -n .Length of output: 738
UI Linting Strategy Verification
The updated parallel build command on line 66 consolidates tasks by runninglint:ci
,build
,build:ui:production:webpack
, andtest
concurrently while removing the separatelint:ui:ci
task. Our verification confirms that no references tolint:ui:ci
exist in the repository and thatlint:ci
is defined inpackage.json
. However, please ensure that the consolidatedlint:ci
adequately covers UI-specific linting checks so that no essential UI quality controls are missed.
- Action Items:
- Double-check that
lint:ci
now includes or does not omit critical linting for UI components.- Confirm that the parallel execution strategy aligns with your overall build and testing requirements.
packages/ui-default/backendlib/template.ts (9)
1-1
: Imports look good.These import statements are clear and organized, and they accurately reflect the required modules for this file.
Also applies to: 5-5, 7-7
119-129
: Usage ofeval
is a known security risk.
This concern was previously raised. Reassess ifeval
is truly necessary, as it can open severe security vulnerabilities.🧰 Tools
🪛 Biome (1.9.4)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().(lint/security/noGlobalEval)
130-157
: Exposing global objects in templates poses security risks.
This issue has been discussed previously. Consider limiting which objects and methods are available in the template environment to reduce the attack surface.
161-182
: Handler creation logic appears sound.The approach to customizing
renderHTML
based ondomainId
in the registry is well-structured. No immediate concerns.
183-215
: Loader class handles template source resolution well.The fallback to
this.registry[templateName]
and usage of.source
references looks robust, especially in DEV mode where no-cache is enforced.
217-220
: Sensible template existence checks.Adding globals
findSubModule
andtemplateExists
provides clarity on registry usage.
221-242
: Consider implementing a real render timeout.
This recommendation was made in prior feedback—relying on logging slow renders can still block the server if rendering stalls for an extended time. A timeout could reject or abort rendering after a threshold.
244-252
: Renderer registrationRegistering “ui-default” as a fallback renderer is straightforward. The code is concise and ties neatly into the
render
promise.
254-275
: Initialization logic is well-structured.Templates are iterated from
global.addons
, read, and stored inthis.registry
with a safeguard in a try-catch block. This is a clean, maintainable approach.packages/elastic/index.ts (8)
4-4
: Imports are correct.No issues found with these imports; they match the usage within the file.
20-24
: Configuration schema is well-defined.The
Config
object captures essential properties (url, indexSize) and defaults, providing clarity and type constraints.
26-26
: Client property initialization is clear.Defining
client
at the class level adds clarity to how Elasticsearch will be accessed.
28-32
: Avoid logging full config in production environments.
console.log('elastic-search', config);
may inadvertently expose secrets ifconfig
holds sensitive info (e.g., credentials). Consider masking or removing logs in production.
33-70
: Search logic looks consistent.The query with
simple_query_string
and domain-based post_filter is thorough. The fallback insertion of direct problem references is a good user-friendly touch.
34-34
: Add proper type annotation for the “opts” parameter.This was mentioned previously, ensuring
opts
has a well-defined structure (e.g.,{ limit?: number; skip?: number }
) can help with clarity and reduce errors.
72-93
: Refine the type definitions for the run method’s parameters.Previously flagged. Adding explicit types for the destructured object and the
report
callback would enhance clarity.
95-125
: Initialization method is solid.Registering event listeners for problem changes and reindexing is logical. The usage of
addScript
to re-index is a convenient approach for admins.packages/hydrooj/src/model/setting.ts (11)
3-3
: Imports from@cordisjs/core
andschemastery
look appropriate.Ensure
schemastery
is properly declared in your package dependencies to avoid any runtime import issues.Also applies to: 7-7
73-81
: Global declaration usage is clear.Attaching
family
andsecret
to Schemastery’s meta interface can be helpful when generating specialized settings.
82-119
: Potential coverage gap for nested or complex schemas.Similar feedback was given before. The current logic does not handle deeper nested structures or arrays beyond simple cases.
121-160
: User-facing setting registration.Dynamically flattening
Schema<any>
or_Setting[]
ensures flexibility. This code systematically merges them into the global arrays.
161-192
: Domain-specific setting registration appears consistent.No obvious issues; code merges domain and domain-user settings into dedicated arrays with minimal overhead.
193-210
: System-level settings extended with schema or arrays.Adopts the same pattern as preferences, account, and domain settings, maintaining consistency.
278-278
: “join” setting usage.This numeric “join” setting is hidden and disabled, indicating it’s used internally. Looks consistent with other hidden/disabled settings.
291-319
: Schema-based system settings provide a robust example.Using
.extra('family', 'setting_smtp' or 'setting_server')
effectively categorizes these settings, aiding organization.
359-359
: Module augmentation for@cordisjs/core
.This extension allows the
setting
property to be typed onContext
. The approach is standard.
388-388
: Dependency injection for DB.Exporting
inject = ['db']
is consistent with the framework’s pattern, cleanly declaring the required dependencies.
395-395
: Additional check for existing records.Retrieving the current entry before creating a new setting avoids overwriting user changes. The fallback logic is straightforward.
packages/hydrooj/package.json (4)
3-3
: Major version increment to 5.0.0-alpha.0This represents a significant update marking the transition to Hydro v5. Ensure that all breaking changes are properly documented and that migration guides are available for users upgrading from v4.
19-21
: Migrating from cordis to @cordisjs packagesThe removal of the
cordis
dependency and addition of multiple@cordisjs/*
packages represents a significant architectural change. This modular approach likely provides better separation of concerns and more flexibility.
22-22
: Dependency updates across multiple packagesMultiple dependencies have been updated to newer versions, which may include bug fixes, performance improvements, and possibly API changes. These updates are generally good practice to maintain security and take advantage of improvements.
Also applies to: 28-28, 36-36, 46-46, 52-52, 55-55, 58-58, 67-67
44-44
:❓ Verification inconclusive
Major MongoDB version upgrade (5.x to 6.x)
The upgrade from MongoDB 5.9.2 to 6.15.0 is a major version change that may include breaking changes. Ensure all database interactions have been thoroughly tested with the new version.
🏁 Script executed:
#!/bin/bash # Check for MongoDB driver version-specific API usage that might need updates echo "Searching for MongoDB-specific API usage that might need updates:" rg "db\.(collection|createCollection|createIndex|ensureIndex|dropIndex|dropCollection)" --type tsLength of output: 10073
Attention: Verify MongoDB Driver Compatibility
The upgrade to MongoDB 6.15.0 introduces potential breaking changes that could affect our widespread use of MongoDB API calls. In particular, note the following:
- Legacy Methods: Multiple files (e.g., in
packages/hydrooj/src/upgrade.ts
,packages/hydrooj/src/handler/status.ts
,packages/hydrooj/src/model/document.ts
, andpackages/hydrooj/src/model/user.ts
) use methods likeensureIndexes
andinitializeUnorderedBulkOp
. Verify that these custom or legacy wrappers remain compatible with MongoDB 6.x APIs.- Bulk and Collection Operations: Since many modules rely on
db.collection()
and various bulk operations, ensure that all database interactions (including index creation, updating, and deletion) work as expected under the new driver version.Please thoroughly test all database interactions and review any deprecated or modified API behaviors to prevent runtime issues.
build/prepare.js (7)
18-22
: Updated JavaScript/TypeScript target and module settingsThe changes to target (es2022), lib, module (preserve), and moduleResolution (bundler) settings reflect modernized build configuration. This enables the use of newer JavaScript features and better aligns with current bundling practices. The change from 'node' to 'bundler' moduleResolution is significant and matches the industry trend toward more sophisticated module bundling.
37-37
: Added support for new UI-Next packageThe addition of references to 'tsconfig.ui-next.json' and the new UINextConfig object suggests the introduction of a new UI package, likely using newer React patterns or an alternative framework. This separation allows for gradual migration or A/B testing of the new UI alongside the existing one.
Also applies to: 123-161
100-100
: React JSX Transform UpdateChanging from 'react' to 'react-jsx' enables the new JSX transform from React 17+, which no longer requires explicitly importing React in every component file. This aligns with modern React development practices.
103-120
: Enhanced compiler options for modern web developmentThe additional compiler options such as useDefineForClassFields, moduleDetection, and various linting settings enhance type safety and code quality. The bundler mode settings are particularly relevant for modern web applications that use build tools like Vite or Webpack.
197-197
: Improved file write operationsUsing the new
tryUpdate
function for file operations reduces unnecessary writes by only updating files when their content has changed. This optimization can significantly improve build performance, especially in large projects with many configuration files.Also applies to: 211-211, 219-219, 223-225
78-78
: Simplified module filtering logicThe updated filtering logic for modules is more concise while maintaining the same functionality. It uses the
some
method to check if any of the exclusion patterns match, which is a more idiomatic JavaScript approach.
189-189
: Added skipLibCheck option to pluginsConfigThe addition of
skipLibCheck: true
can improve build performance by skipping type checking of declaration files in dependencies. This is particularly useful for large projects with many dependencies, but be aware that it may hide type errors from third-party libraries.packages/hydrooj/src/model/oauth.ts (1)
18-18
: Updated database result access patternThe change from
res.value?.uid
tores?.uid
suggests an update in the MongoDB driver's return value structure or a change in how findOneAndUpdate is configured. This is consistent with MongoDB 6.x behavior when using thereturnDocument: 'after'
option.Ensure this pattern is updated consistently across all database operations in the codebase. The MongoDB driver upgrade (from 5.x to 6.x) likely changes how results are structured.
packages/hydrooj/src/model/opcount.ts (1)
16-16
: Updated database result access patternSimilar to the change in oauth.ts, this updates how the result from MongoDB operations is accessed. The pattern has changed from
res.value.opcount
tores.opcount
, which is consistent with MongoDB 6.x behavior.This confirms a systematic update throughout the codebase to accommodate changes in the MongoDB driver API.
packages/hydrooj/src/model/blacklist.ts (1)
16-20
:❓ Verification inconclusive
API change:
add
method now returns the full MongoDB response.The method now directly returns the result of
findOneAndUpdate
instead of just returningres.value
. This change might affect code that expects only the document value rather than the full response object.
🏁 Script executed:
#!/bin/bash # Search for usages of BlackListModel.add to check if any code relies on the return value rg "BlackListModel\.add" --type tsLength of output: 36
Action: Verify consumers of BlackListModel.add for correct handling of the full MongoDB response
The
add
method inpackages/hydrooj/src/model/blacklist.ts
now returns the entire response from MongoDB rather than just the document (i.e., it returns the value offindOneAndUpdate
without extracting.value
). This change may impact any consumers that expect only the updated document.
- Please double-check that none of the consumers expect just the document value (as they might have been written to work with
res.value
previously).- Even though our initial search for direct usages of
BlackListModel.add
returned no results, a manual verification is recommended to ensure there are no indirect dependencies.packages/hydrooj/src/model/record.ts (6)
23-23
: Good addition of record history collection.Adding a dedicated collection for record history is a good practice for maintaining the history of record changes.
236-237
: Replaceinstanceof Array
withArray.isArray()
.Using
instanceof Array
may return false for array-like objects and arrays from different execution contexts. This can lead to unexpected behavior.-const rids = rid instanceof Array ? rid : [rid]; +const rids = Array.isArray(rid) ? rid : [rid];
250-262
: Well-implemented record history preservation.The implementation correctly fetches records before deletion, extracts relevant fields using
pick
from lodash, and stores them in the history collection with a new ObjectId.
283-283
: Changedapply
to be async.The function signature has been updated to make
apply
asynchronous. This is appropriate since it now handles async operations like database index creation.
324-327
: Added proper index for the newcollHistory
collection.A suitable index has been added for the new collection, which will optimize queries filtering by
rid
and sorting by_id
.
212-217
:❓ Verification inconclusive
API change:
update
method now returns the full MongoDB response.The method now directly returns the result of
findOneAndUpdate
instead of an intermediate variable. This change might affect code that expects a specific return value structure.
🏁 Script executed:
#!/bin/bash # Search for usages of RecordModel.update to check if any code relies on the return value structure rg "RecordModel\.update.*await" --type tsLength of output: 43
I'll run a follow-up shell script to search for any occurrences of the
RecordModel.update(
pattern in the codebase to verify if there are any usages that could be impacted by the API change.
🏁 Script executed:
#!/bin/bash rg "RecordModel\.update\(" --type tsLength of output: 226
Attention: Verify Consumers of the Updated API Return Type
The
RecordModel.update
method inpackages/hydrooj/src/model/record.ts
now directly returns the full MongoDB response fromfindOneAndUpdate
instead of an intermediate variable. This change could affect code that expects just the updated document. Notably, our search found calls toRecordModel.update
in both:
packages/hydrooj/src/model/record.ts
(line 212, where it callsreturn RecordModel.update(domainId, rid, upd);
)packages/hydrooj/src/upgrade.ts
(usage within an upgrade operation)Please verify these usages to ensure they handle the full MongoDB response correctly. Adjust the consuming code if expectations about the returned structure have changed.
packages/hydrooj/src/model/schedule.ts (2)
7-7
: Import statement updated to match export type.The import has been changed to match the default export pattern of the WorkerService. This ensures type consistency.
18-25
:❓ Verification inconclusive
API change: Direct MongoDB response object usage.
The code now uses the MongoDB response object directly instead of accessing the
.value
property. This simplifies the code but changes the function's return behavior.-if (res.value) { - logger.debug('%o', res.value); - if (res.value.interval) { - const executeAfter = moment(res.value.executeAfter).add(...res.value.interval).toDate(); - await coll.insertOne({ ...res.value, executeAfter }); - } - return res.value; +if (res) { + logger.debug('%o', res); + if (res.interval) { + const executeAfter = moment(res.executeAfter).add(...res.interval).toDate(); + await coll.insertOne({ ...res, executeAfter }); + } + return res;
🏁 Script executed:
#!/bin/bash # Search for usages of ScheduleModel.getFirst to check if any code relies on the return value structure rg "ScheduleModel\.getFirst|getFirst" --type tsLength of output: 603
API Change: Verify Consumers for Direct MongoDB Response Usage
- The code now directly returns the MongoDB response object (i.e.,
res
) instead of extractingres.value
. This simplifies the code, but it changes the function's return behavior.- Please confirm that all consumers of
ScheduleModel.getFirst
(for example, inpackages/hydrooj/src/service/worker.ts
andpackages/hydrooj/src/model/task.ts
) have been evaluated to ensure they correctly handle the full response object, rather than expecting just the document data.packages/hydrooj/src/entry/worker.ts (4)
9-10
: Improved service imports using named imports.The code now imports specific service classes rather than the entire module, improving code clarity and potentially reducing bundle size.
24-34
: Enhanced database initialization with dependency injection.The worker now uses the
MongoService.getUrl()
method to get the database URL asynchronously and registers services as plugins. This is a cleaner approach than direct database initialization.
36-52
: Improved dependency management with Promise-based injection.The code now uses Promises to ensure dependencies are properly initialized before proceeding, enhancing the reliability of the startup sequence.
92-102
: Streamlined server startup with dependency injection.Server initialization is now handled through dependency injection, making the code more maintainable and testable. The previous imperative approach has been replaced with a more declarative pattern.
packages/utils/lib/utils.ts (3)
10-10
: Import statement updated to include factory pattern componentsThis change updates the import statement to include
Exporter
andFactory
from 'reggol', and renames the importedLogger
toReggol
. This prepares for the implementation of a factory pattern for logger creation.
15-27
: Added factory pattern for logger configurationThe implementation of a factory pattern for logger creation improves modularity and allows for centralized configuration. The factory is configured with specific display settings (showDiff, showTime, label formatting) and a timestamp.
29-31
: Added createLogger function for consistent logger instancesThis function encapsulates logger creation logic, promoting consistent logger instantiation throughout the application.
packages/hydrooj/src/service/db.ts (7)
7-7
: Enhanced service integration with Context importImporting the Context and Service classes allows for proper dependency injection and service registration.
11-11
: Simplified bus importChanged from namespace import to default import, matching the updated export pattern of the bus module.
29-33
: Added proper Context type extensionThis module declaration properly extends the Context interface to include the database service, enhancing type safety throughout the application.
35-41
: Improved service architecture with inheritanceThe MongoService now extends the Service base class and properly registers itself with the context, following the dependency injection pattern.
43-56
: Extracted MongoDB URL resolution to static methodThe getUrl static method encapsulates the logic for obtaining the MongoDB connection URL, including special handling for CI environments. This improves code organization and reusability.
58-66
: Enhanced lifecycle management with Context.initReplaced the start method with an async generator that yields a cleanup function, allowing for proper resource management during application lifecycle. The interval setting has been updated to use the context instead of direct setTimeout.
69-71
: Improved configuration handlingCollection names now properly respect the configuration settings, including prefix and collection mapping, providing more flexibility for database configuration.
packages/hydrooj/src/model/task.ts (4)
9-9
: Updated bus import patternChanged from namespace import to default import, aligning with the updated export pattern.
22-25
: Simplified database result handlingThe database result structure has been simplified, so the code now directly uses the result object instead of accessing a specific property. This change aligns with updates to the database service.
184-184
: Updated event logging to match new result structureEvent logging now uses the simplified result object structure.
186-186
: Updated event handling conditionThe await condition now checks for the presence of the result directly rather than accessing the value property, matching the updated database response structure.
packages/hydrooj/src/handler/misc.ts (2)
17-17
: Updated import for sortFiles utilityImport statement refined to specifically import only the required sortFiles function.
112-112
: Enhanced security with dynamic link validationReplaced static secret validation with a dynamic context-based validation through the storage service. This improves security by delegating validation to the appropriate service and removing hardcoded validation logic.
packages/hydrooj/src/service/worker.ts (1)
12-12
:❓ Verification inconclusive
Updated class export to use default export
The class declaration has been changed from a named export to a default export. This is a breaking change that requires updating import statements throughout the codebase.
🏁 Script executed:
#!/bin/bash # Find all imports of WorkerService to verify they've been updated to use default import rg "import.*WorkerService.*from ['|\"].*worker" --type=tsLength of output: 152
Action: Verify All Default Import Usages for WorkerService
I confirmed that in packages/hydrooj/src/model/schedule.ts the WorkerService import is now using a default import (via a type-only import:
import type WorkerService from '../service/worker'; ```) which is consistent with the change in *packages/hydrooj/src/service/worker.ts*. Please double-check that there are no remaining named import statements (e.g., using curly braces) anywhere else in the codebase—especially for runtime usages—as this change to a default export is breaking. </details> <details> <summary>packages/hydrooj/src/service/bus.ts (4)</summary> `4-4`: **Updated import to use explicit type import** The import statement now explicitly imports only the `Handler` type from the framework package, which improves code clarity. --- `17-17`: **Simplified EventMap interface definition** The `EventMap` interface no longer extends `KnownHandlerEvents`, which reduces coupling and simplifies the event handling structure. --- `87-87`: **Improved type safety for oplog/log event handler** The `oplog/log` event's handler type has been refined to specify `Handler<Context>` instead of a generic `Handler`, providing better type safety and context specificity. --- `32-32`: <details> <summary>✅ Verification successful</summary> **Refined bus/broadcast event type signature** The type signature for the `bus/broadcast` event has been updated to only reference `keyof EventMap` instead of also including `keyof ServerEvents`. This change simplifies the event type system. --- 🏁 Script executed: ```shell #!/bin/bash # Check for potential type errors in bus/broadcast event calls # Look for any usage of bus/broadcast with events that might not be in EventMap rg "bus/broadcast.*" --type=ts -A 1 -B 1Length of output: 1671
Verified: Bus Broadcast Event Signature Update is Consistent Across the Codebase
The refinement to use only
keyof EventMap
for thebus/broadcast
event is consistent with its usages across the repository. The search output confirms that all relevant call sites pass the appropriate parameters according to the updated signature, and there is no evidence of type conflicts or misusage introduced by removingkeyof ServerEvents
.
packages/hydrooj/src/interface.ts (3)
2-2
: Updated import for WebAuthn types
The import statement has been updated to include ParsedAuthenticatorData
from the SimpleWebAuthn server helpers, supporting the improved type definition for authenticator extensions.
83-83
: Enhanced type precision for authenticator extensions
The authenticatorExtensionResults
property type has been changed from AuthenticationExtensionsAuthenticatorOutputs
to ParsedAuthenticatorData['extensionsData']
, providing more accurate typing.
226-229
: Added RecordHistoryDoc interface for record history tracking
A new interface for historical record documents has been added, extending RecordJudgeInfo
with identifiers. This interface is properly referenced in the database collections type definitions.
packages/hydrooj/src/settings.ts (3)
14-172
: Introduced ConfigService class for improved configuration management
The new ConfigService
class encapsulates all configuration-related functionality, replacing previous standalone functions and global variables. This change aligns with the broader refactoring to reduce global assignments and improve modularity.
This is a significant architectural improvement that:
- Enhances encapsulation of configuration data
- Provides structured methods for configuration operations
- Implements schema validation for configuration values
- Includes blacklisting to prevent prototype pollution
- Supports configuration migration between formats
153-171
: Improved logic in getAccess function
Line 159 now correctly checks if currentValue
is falsy, addressing a previous issue where it would return the entire config object instead of the specific value.
55-67
:
❓ Verification inconclusive
Potential prototype pollution concern in applyDelta
While the code includes blacklist checks to prevent prototype pollution, the assignment at line 65 could still be vulnerable if malicious property names make it past the check.
Even though there's a blacklist check at line 57, consider implementing additional safeguards or using a specialized library like lodash.set
to safely apply property updates.
🏁 Script executed:
#!/bin/bash
# Check if the prototype pollution issue has been addressed elsewhere
rg "__proto__" --type=ts
rg "hasOwnProperty" --type=ts
Length of output: 153
Action Required: Revisit Prototype Pollution Safeguards
- The function
applyDelta
(packages/hydrooj/src/settings.ts, lines 55–67) already checks for blacklisted keys ('__proto__'
,'prototype'
, and'constructor'
) across the entire property path. However, the assignment at line 65 is executed after the check, which means that if a malicious key slips through a potential gap (e.g., via a non-exact string bypass or other edge cases), the update could still trigger prototype pollution. - Although the blacklist exists—as confirmed by the grep result—we currently do not see additional checks (e.g., using
hasOwnProperty
or a trusted library), which might further reduce risk. - Recommendation: Reassess whether relying solely on the blacklist is sufficient. Consider incorporating extra safeguards, such as employing a secure property update method (for example, using
lodash.set
or a similar utility) to perform the deep update safely.
packages/ui-default/index.ts (4)
77-77
: Good refactoring to use context-based configuration.
Switching from SystemSettings
to this.ctx.config.settings
improves dependency management by using the context-provided configuration.
3-7
: Good architectural improvements to imports and dependencies.
Removing the direct SystemSettings
import and adding TemplateService
as a proper injectable service improves the architecture and modularity of the code.
25-25
: Improved type safety with explicit type annotation.
Adding an explicit type for the sections
array enhances code readability and type safety.
167-167
: Good transition to plugin-based architecture.
Using ctx.plugin(TemplateService)
instead of requiring the module directly improves dependency management and follows a better architectural pattern.
packages/hydrooj/src/loader.ts (6)
147-153
: Good conversion to async for improved control flow.
Converting preload
to an async function enhances error handling and provides better control over the initialization sequence. Using await
for promises is a solid improvement.
98-107
: Well-structured configuration management.
Adding the resolveConfig
method as part of the class provides better encapsulation and a more consistent API. The use of Schema for configuration management is a good practice.
109-126
: Improved plugin reload mechanism.
The updated reloadPlugin
method simplifies the API and provides better error handling. Using this.ctx.plugin
directly is cleaner than the previous approach.
15-17
: Improved import structure for better type safety.
The structured imports from context.ts improve code readability and type checking capabilities.
170-172
: Good async/await pattern adoption.
Making load
and loadCli
functions async and awaiting preload
ensures proper sequencing of initialization steps, which is especially important for application startup.
Also applies to: 208-211
59-86
: Improved event listener implementation.
The event listener now consistently uses ctx
instead of mixing global access patterns, which improves code maintainability and testability.
packages/hydrooj/src/model/domain.ts (6)
136-137
: Good enhancement to support user auto-joining.
Adding the autojoin
parameter with a default value preserves backward compatibility while extending functionality. The conditional spread operator usage is clean and efficient.
292-312
: Excellent restructuring with apply pattern.
The new apply
function centralizes event handling and database index setup, improving the organization of initialization code. This pattern makes the code more maintainable and testable.
131-132
: Improved query filtering with join condition.
Adding the join: true
condition to queries ensures only users who have actually joined the domain are counted or returned, which is more accurate.
104-108
: Simplified return value for better API consistency.
Directly returning the result from the database operation simplifies the API and makes it more consistent with other methods.
119-120
: Cleaner return statement for field value.
Directly returning the updated field value makes the API more intuitive and easier to use.
259-259
: Improved query filtering for domain users.
Adding join: true
to the query ensures only users who have actually joined domains are returned, providing more accurate results.
packages/hydrooj/src/entry/common.ts (6)
24-25
: Improved type safety with more specific type definitions.
Simplifying the LoadTask
type and using Record<string, string>
for the pending parameter provides better type safety and self-documentation.
26-30
: Enhanced iteration with object entries.
Changing from array iteration to Object.entries
and renaming variables improves code readability and makes the relationship between keys and values clearer.
32-32
: Simplified plugin loading API.
The updated API call to ctx.loader.reloadPlugin
with simplified parameters makes the code more maintainable and aligns with the updated Loader implementation.
56-56
: Consistent plugin loading approach.
Using the same simplified reloadPlugin
API in builtinModel
ensures consistency across the codebase.
60-61
: Improved parameter typing in locale function.
Changing the pending
parameter to Record<string, string>
and using Object.values
for iteration provides better type safety and aligns with the overall refactoring.
83-90
: Consistent parameter typing in setting function.
Similar to the locale
function, the setting
function now uses consistent parameter typing, which improves the overall code quality.
packages/hydrooj/src/handler/domain.ts (5)
105-147
: Good optimization by using MongoDB aggregation pipeline
The refactoring of the query to use an aggregation pipeline is a significant improvement. This approach allows for more efficient data retrieval by filtering users and joining with the user collection in a single database operation, reducing the need for additional queries.
258-258
: Simplified role filtering logic
The filtering logic has been optimized to only exclude the 'guest' role instead of both 'default' and 'guest'. This makes the role management process more flexible by allowing users with the 'default' role to be displayed.
322-337
: Enhanced flexibility with target parameter
Adding the target
parameter to the prepare
method enhances flexibility by allowing operations on a different domain than the current one. The implementation correctly checks if the user is already a member of the target domain and retrieves roles based on the specified target domain document.
🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
340-357
: Improved domain join GET handler with target parameter
The get
method has been enhanced to accept target
and redirect
parameters, which improves flexibility when handling domain join requests. The response body now includes detailed domain information, providing a better user experience.
361-376
: Dynamic role assignment in domain join POST handler
The post
method now includes the target
and redirect
parameters, improving the redirect functionality and making the user role assignment more dynamic based on the target domain's join settings.
packages/hydrooj/src/model/document.ts (4)
12-12
: Updated import syntax for bus module
Changed from importing all exports to importing the default export, which aligns with modern ES module practices and indicates that bus
is likely exported as a default export in the source module.
23-33
: Enhanced type safety with const assertions
Changing from explicit type annotations to using TypeScript's as const
assertion enhances type safety and provides better inference for const objects. This change also makes the code more maintainable by ensuring the type is derived from the value automatically.
112-117
: Simplified return statements for database operations
Functions have been streamlined by directly returning the result of database operations rather than storing them in intermediate variables. This makes the code more concise and easier to follow without affecting functionality.
Also applies to: 152-157, 163-168, 211-217, 224-230, 255-265, 271-277, 301-311, 328-333, 358-363, 369-374, 397-402
385-391
: Improved null handling with nullish coalescing assignment
The use of the nullish coalescing assignment operator (||=
) is a modern JavaScript feature that simplifies the code and makes it more readable. Good improvement!
framework/framework/server.ts (6)
5-5
: Updated import to use CordisContext
Renaming the imported Context
to CordisContext
helps clarify the source of the context type and avoids potential naming conflicts with local context implementations.
44-52
: New async function for context scope management
The forkContextWithScope
function is a good addition that provides a clean way to create and manage context scopes with automatic cleanup using the Symbol.asyncDispose
pattern. This helps prevent memory leaks and ensures proper resource management.
210-212
: Enhanced type safety with generic parameters
The addition of generic type parameters to Handler
, ConnectionHandler
, NotFoundHandler
, and WebService
classes significantly improves type safety across the framework. This allows for better integration with varying context types while maintaining core functionality.
Also applies to: 258-260, 297-297, 337-352
478-478
: Improved server startup logging
Using the logger.success
method with a template string is a small but good improvement that makes the server startup message more visible and informative.
487-612
: Improved HTTP and WebSocket request handling
The refactoring of the handleHttp
and handleWS
methods with proper context scoping and cleanup operations enhances resource management and error handling. The use of using
with the new forkContextWithScope
ensures resources are properly disposed of.
841-848
: Improved type declarations with module augmentation
The module augmentation for @cordisjs/core
enhances type safety by properly typing the methods added to the Context
interface. This ensures that TypeScript can correctly check the usage of these methods throughout the codebase.
"optionalDependencies": { | ||
"typescript": "^5.8.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optional typescript
dependency.
Bundling typescript
as optional may lead to confusion if linting TypeScript files is a core usage scenario. If you expect TS usage across all teams, consider making it a direct or peer dependency instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (8)
packages/ui-default/backendlib/template.ts (2)
120-128
:⚠️ Potential issueAvoid using
eval
and exposing global objects.Using
eval()
and exposing JavaScript's global objects likeDate
,Object
,String
, etc. to templates can introduce significant security risks including remote code execution, prototype pollution, and information disclosure.🧰 Tools
🪛 Biome (1.9.4)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().(lint/security/noGlobalEval)
221-242
: 🛠️ Refactor suggestionAdd timeout handling to prevent long-running renders.
While there's logging for slow renders (>5000ms), there's no actual timeout mechanism to prevent extremely long-running renders from blocking the server.
packages/elastic/index.ts (2)
97-116
: 🛠️ Refactor suggestionAdd error handling to event handlers
The event handlers in the Context.init method don't include error handling, which could lead to unhandled promise rejections if operations fail.
this.ctx.on('problem/add', async (doc, docId) => { + try { await this.client.index({ index: 'problem', id: `${doc.domainId}/${docId}`, document: processDocument(doc), }); + } catch (error) { + this.ctx.logger.error(`Error indexing problem: ${error.message}`); + } });Apply similar error handling to the other event handlers as well.
122-123
: 🛠️ Refactor suggestionAdd error handling to script execution
The script registration doesn't include error handling for the
run
method when used as a callback.- this.run.bind(this), + async (...args) => { + try { + return await this.run.bind(this)(...args); + } catch (error) { + this.ctx.logger.error(`Error in ensureElasticSearch script: ${error.message}`); + throw error; + } + },packages/hydrooj/src/settings.ts (1)
55-67
:⚠️ Potential issuePotential prototype pollution still possible in applyDelta
While the code checks for blacklisted properties, the assignment at line 65 (
cursor[t] = value
) could still be vulnerable to prototype pollution ift
contains malicious values that bypass the blacklist check.Consider using a safer property assignment method:
- cursor[t] = value; + Object.defineProperty(cursor, t, { + value, + writable: true, + enumerable: true, + configurable: true + });Or use an established library like Lodash's
_.set()
which has protection against prototype pollution.framework/framework/server.ts (3)
139-140
: 🛠️ Refactor suggestionFix unsafe declaration merging.
Declaring both an interface and a class with the same name can lead to unsafe declaration merging in TypeScript. The linter correctly flags this pattern.
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Consider removing or using a type alias if needed: +// type HandlerCommonProps<C> = {} export class HandlerCommon<C> { // ... }🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
498-501
: 🛠️ Refactor suggestionAddress FIXME comments for type checking.
Multiple locations use type assertions to
any
with FIXME comments about passing type checks. These should be properly typed rather than bypassing TypeScript's type system.Create proper type definitions for the event handlers to avoid type assertions:
// In your interfaces file: interface HandlerEvents<T> { 'handler/create': [handler: T, type: 'http' | 'ws']; 'handler/create/http': [handler: T]; 'handler/create/ws': [handler: T]; 'handler/error': [handler: T, error: Error]; 'connection/create': [handler: T]; 'connection/active': [handler: T]; 'connection/close': [handler: T]; } // Then update your context interface to include these typed events interface C extends CordisContext { parallel<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>; serial<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>; }Also applies to: 537-538, 552-554, 569-570, 604-605, 616-618, 656-657
676-678
:⚠️ Potential issueFix condition that always evaluates to false.
The static analysis tool flags that the condition
if (perm)
at line 705 always evaluates to false, indicating a potential logic error in the function.In the
check
function, the condition appears to not work as intended. Verify the initialization and type of theperm
variable to ensure it can properly evaluate to true when permissions exist:return function check(this: Handler<C>) { checker(); - if (perm) this.checkPerm(perm); + // Fix the condition to properly check for permissions + if (perm !== undefined && perm !== null) this.checkPerm(perm); if (priv) this.checkPriv(priv); };Also applies to: 705-705
🧹 Nitpick comments (23)
.github/workflows/build.yml (2)
64-69
: Parallel Execution Command Update: Verify UI Linting CoverageThe updated parallel command (line 66) now runs the tasks
lint:ci
,build
,build:ui:production:webpack
, andtest
—thereby omitting the previously includedlint:ui:ci
step. Please confirm that UI-specific linting is either no longer required or is covered by another mechanism to ensure overall code quality remains intact.
64-64
: UI Iconfont Build Step: Confirm Expected BehaviorThe
yarn build:ui:iconfont
command (line 64) runs when UI-related files have changed. Verify that this step correctly generates the icon fonts and that its output integrates as expected with the downstream UI build and production processes.packages/ui-default/backendlib/template.ts (4)
46-46
: Enhance code safety with optional chaining.The current code checks for
obj
being undefined or null, but still accessesobj._original
directly. Use optional chaining to make this access safer.- if ((obj || {})._original) obj = obj._original; + if (obj?._original) obj = obj._original;🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
25-34
: Optimize file discovery for large directory structures.The recursive
getFiles
function could become inefficient for large directory structures. Consider adding pagination or limiting the depth of recursion for better performance.-async function getFiles(folder: string, base = ''): Promise<string[]> { +async function getFiles(folder: string, base = '', maxDepth = 10): Promise<string[]> { const files: string[] = []; const f = await fs.readdir(folder); for (const i of f) { if ((await fs.stat(path.join(folder, i))).isDirectory()) { + // Skip recursion if we've reached maximum depth + if (maxDepth <= 0) continue; - files.push(...await getFiles(path.join(folder, i), path.join(base, i))); + files.push(...await getFiles(path.join(folder, i), path.join(base, i), maxDepth - 1)); } else files.push(path.join(base, i)); } return files.map((item) => item.replace(/\\/gmi, '/')); }
36-42
: Improve error message in file location function.The
locateFile
function returnsnull
without any context on why the file wasn't found. Consider returning a more descriptive error or adding logging.function locateFile(basePath: string, filenames: string[]) { for (const i of filenames) { const p = path.resolve(basePath, i); if (fs.existsSync(p)) return p; } + // Log which files were attempted + console.debug(`Could not locate any of the following files in ${basePath}:`, filenames); return null; }
254-275
: Consider adding graceful template fallback.When templates fail to load, the current code logs errors and injects a notification, but there's no fallback mechanism. Consider implementing a default template system that can be used when custom templates fail.
Would you like me to suggest a fallback implementation that ensures the system remains functional even when templates fail to load?
packages/hydrooj/src/model/oauth.ts (1)
12-19
: Consider adding type annotations and improved error handling.The
set
method would benefit from explicit return type annotations and error handling. Sinceres?.uid
could returnundefined
when no document is created or when the returned document structure is unexpected, it would be more consistent to returnnull
like theget
method does.- static async set(_id: string, uid: number) { + static async set(_id: string, uid: number): Promise<number | null> { const res = await coll.findOneAndUpdate( { _id }, { $set: { uid } }, { upsert: true, returnDocument: 'after' }, ); - return res?.uid; + return res?.uid || null; }packages/elastic/index.ts (1)
30-30
: Remove debugging console.logThere's a console.log statement that should be replaced with proper logging using the service's logger.
- console.log('elastic-search', config); + this.logger.debug('Initializing elastic-search service', config);packages/hydrooj/src/handler/domain.ts (2)
150-157
: Performance concern with delete operatorUsing the delete operator on
u.user
might impact performance. Consider using object destructuring with rest parameters instead.- const u = { - ...dudoc, - ...dudoc.user, - }; - delete u.user; - return u; + const { user: userData, ...rest } = dudoc; + return { ...rest, ...userData };🧰 Tools
🪛 Biome (1.9.4)
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
334-336
: Simplify conditional logic for joinSettingsThe conditional logic for setting joinSettings could be simplified for better readability.
- if (assignedRole !== 'default') delete this.joinSettings; - else if (!this.joinSettings) throw new DomainJoinForbiddenError(target); + if (assignedRole !== 'default') { + this.joinSettings = undefined; + } else if (!this.joinSettings) { + throw new DomainJoinForbiddenError(target); + }🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/model/blacklist.ts (1)
16-20
: Function simplified by removing intermediate variable.The
add
method has been simplified to directly return the result offindOneAndUpdate
instead of storing it in a temporary variable and returningres.value
. This changes the return type fromPromise<{ value: any }>
toPromise<any>
.Consider documenting this return type change in JSDoc to ensure consumers of this API are aware of the change:
@ArgMethod + /** + * Add an entry to the blacklist. + * @returns The complete result object from the findOneAndUpdate operation + */ static async add(id: string, expire?: Date | number) {eslint.config.mjs (4)
1-2
: Check the necessity of disabling rules globally.Disabling
max-len
and@typescript-eslint/naming-convention
at the file level may be too broad. Instead, consider selectively disabling or customizing these rules to accommodate specific project needs.
8-15
: Refine ignore patterns if needed.The provided ignore patterns may skip linting for files that should remain under lint coverage (e.g., transpiled
.js
files in certain directories). Confirm that they accurately target only unneeded files.
39-53
: Evaluate warning vs. error levels.
@typescript-eslint/no-invalid-this
is set to a warning. Decide if upgrading to an error level better suits your codebase, reducing potential runtime issues.
138-149
: Extend or unify UI config if desired.The UI config block is narrower, which might lead to inconsistent lint rules. Consider extending the base config or ensuring partial coverage is intentional.
framework/eslint-config/base.mjs (3)
30-43
: Ensure correct TypeScript path resolution.Your
'import/resolver'
includes.mjs
and.ts
among others. Confirm that TypeScript path aliases and resolution logic are fully satisfied.
54-63
: Confirm required TypeScript settings.
@typescript-eslint/parser
is specified, but ensure the TS version meets or exceeds the minimum needed for new language features.
455-482
: Defer checks to TSC.Turning off many base rules for
.ts
files is common when letting the TypeScript compiler handle them. Ensuretsconfig.json
enforces stricter checks as needed.packages/hydrooj/src/settings.ts (1)
164-169
: Fire-and-forget pattern in Proxy setterThe set method doesn't await the setConfig call, which could lead to silent failures if the database update fails.
Consider making the proxy setter handle async operations properly:
- set(self, p: string | symbol, newValue: any) { - that.setConfig(path.concat(p).join(','), newValue); - return true; - }, + set(self, p: string | symbol, newValue: any) { + // Return true immediately but trigger the async update + that.setConfig(path.concat(p).join(','), newValue) + .catch((err) => that.ctx.logger.error('Failed to set config:', err)); + return true; + },packages/hydrooj/src/model/domain.ts (1)
138-138
: Use Array.isArray() instead of instanceof ArrayUsing
instanceof Array
can return false for arrays from other execution contexts or for array-like objects. This could lead to unexpected behavior.- if (!(uid instanceof Array)) { + if (!Array.isArray(uid)) {🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
packages/hydrooj/src/loader.ts (1)
49-49
: Avoid using {} as a typeUsing
{}
as a type means "any non-nullable value" which is too loose and can lead to type safety issues.- public config: {}; + public config: Record<string, unknown>;🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/model/document.ts (1)
223-223
: Use Array.isArray() instead of instanceof Array.The
instanceof Array
check can return false for array-like objects and arrays from other execution contexts, making it less reliable for type checking.- subId = (subId instanceof Array) ? subId : [subId]; + subId = Array.isArray(subId) ? subId : [subId];🧰 Tools
🪛 Biome (1.9.4)
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
framework/framework/server.ts (1)
744-749
: Fix the type signature for Route handlers.The route handler type has been improved, but there are commented out console.log statements that should be removed.
public Route(name: string, path: string, RouteHandler: typeof Handler<C>, ...permPrivChecker) { - // if (name === 'contest_scoreboard') { - // console.log('+++', this.ctx); - // console.log(this.ctx.scoreboard); - // } return this.register('route', name, path, RouteHandler, ...permPrivChecker); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (94)
.eslintrc.yaml
(0 hunks).github/workflows/build.yml
(1 hunks)build/prepare.js
(5 hunks)eslint.config.mjs
(1 hunks)framework/eslint-config/base.mjs
(1 hunks)framework/eslint-config/base.yaml
(0 hunks)framework/eslint-config/package.json
(1 hunks)framework/eslint-config/react.yaml
(0 hunks)framework/eslint-config/typescript.js
(0 hunks)framework/framework/error.ts
(0 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrojudge/src/cases.ts
(0 hunks)packages/hydrojudge/src/checkers.ts
(4 hunks)packages/hydrojudge/src/daemon.ts
(0 hunks)packages/hydrojudge/src/hosts/hydro.ts
(0 hunks)packages/hydrojudge/src/hosts/vj4.ts
(1 hunks)packages/hydrojudge/src/judge/hack.ts
(4 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/commands/install.ts
(1 hunks)packages/hydrooj/src/entry/cli.ts
(2 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/setup.ts
(0 hunks)packages/hydrooj/src/entry/worker.ts
(3 hunks)packages/hydrooj/src/handler/contest.ts
(0 hunks)packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/misc.ts
(3 hunks)packages/hydrooj/src/handler/problem.ts
(1 hunks)packages/hydrooj/src/interface.ts
(6 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/blacklist.ts
(1 hunks)packages/hydrooj/src/model/contest.ts
(7 hunks)packages/hydrooj/src/model/document.ts
(11 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/hydrooj/src/model/message.ts
(3 hunks)packages/hydrooj/src/model/oauth.ts
(1 hunks)packages/hydrooj/src/model/opcount.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/record.ts
(8 hunks)packages/hydrooj/src/model/schedule.ts
(2 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/storage.ts
(6 hunks)packages/hydrooj/src/model/system.ts
(3 hunks)packages/hydrooj/src/model/task.ts
(3 hunks)packages/hydrooj/src/model/token.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(8 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)packages/hydrooj/src/script/problemStat.ts
(0 hunks)packages/hydrooj/src/script/storageUsage.ts
(0 hunks)packages/hydrooj/src/service/bus.ts
(5 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/worker.ts
(2 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/migrate/package.json
(1 hunks)packages/onlyoffice/frontend/office.page.ts
(0 hunks)packages/onsite-toolkit/frontend/resolver.page.tsx
(2 hunks)packages/ui-default/.eslintignore
(0 hunks)packages/ui-default/.eslintrc.js
(0 hunks)packages/ui-default/api.ts
(0 hunks)packages/ui-default/backendlib/builder.ts
(4 hunks)packages/ui-default/backendlib/markdown-it-imsize.ts
(1 hunks)packages/ui-default/backendlib/markdown-it-media.ts
(0 hunks)packages/ui-default/backendlib/misc.ts
(1 hunks)packages/ui-default/backendlib/template.ts
(3 hunks)packages/ui-default/build/config/webpack.ts
(1 hunks)packages/ui-default/build/main.ts
(1 hunks)packages/ui-default/components/autocomplete/components/AutoComplete.tsx
(3 hunks)packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
(1 hunks)packages/ui-default/components/calendar/index.js
(2 hunks)packages/ui-default/components/message/worker.ts
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
(1 hunks)packages/ui-default/components/problemconfig/reducer/config.ts
(1 hunks)packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/Testcase.tsx
(1 hunks)packages/ui-default/components/scratchpad/DataInputComponent.jsx
(0 hunks)packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
(0 hunks)packages/ui-default/index.ts
(6 hunks)packages/ui-default/package.json
(5 hunks)packages/ui-next/package.json
(1 hunks)packages/ui-next/src/App.tsx
(1 hunks)packages/utils/lib/locate-pm2.ts
(1 hunks)packages/utils/lib/utils.ts
(1 hunks)packages/utils/package.json
(2 hunks)packages/vjudge/src/index.ts
(3 hunks)packages/vjudge/src/providers/codeforces.ts
(0 hunks)packages/vjudge/src/providers/hduoj.ts
(0 hunks)packages/vjudge/src/providers/poj.ts
(0 hunks)packages/vjudge/src/providers/spoj.ts
(0 hunks)packages/vjudge/src/providers/uoj.ts
(0 hunks)packages/vjudge/src/providers/yacs.ts
(0 hunks)
💤 Files with no reviewable changes (25)
- packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
- packages/hydrooj/src/script/storageUsage.ts
- packages/ui-default/backendlib/markdown-it-media.ts
- framework/eslint-config/base.yaml
- packages/vjudge/src/providers/uoj.ts
- packages/vjudge/src/providers/yacs.ts
- packages/hydrojudge/src/hosts/hydro.ts
- packages/ui-default/.eslintignore
- packages/hydrojudge/src/cases.ts
- packages/onlyoffice/frontend/office.page.ts
- framework/eslint-config/react.yaml
- packages/ui-default/api.ts
- framework/framework/error.ts
- packages/ui-default/components/scratchpad/DataInputComponent.jsx
- packages/vjudge/src/providers/codeforces.ts
- packages/hydrooj/src/script/problemStat.ts
- packages/vjudge/src/providers/hduoj.ts
- packages/vjudge/src/providers/poj.ts
- packages/hydrooj/src/entry/setup.ts
- packages/hydrojudge/src/daemon.ts
- framework/eslint-config/typescript.js
- packages/vjudge/src/providers/spoj.ts
- packages/hydrooj/src/handler/contest.ts
- packages/ui-default/.eslintrc.js
- .eslintrc.yaml
✅ Files skipped from review due to trivial changes (14)
- packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
- packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
- packages/ui-default/build/main.ts
- packages/ui-default/components/problemconfig/reducer/config.ts
- packages/ui-default/build/config/webpack.ts
- packages/ui-default/backendlib/markdown-it-imsize.ts
- packages/ui-default/components/problemconfig/tree/Testcase.tsx
- packages/ui-default/components/calendar/index.js
- packages/ui-default/backendlib/misc.ts
- packages/hydrojudge/src/hosts/vj4.ts
- packages/ui-default/components/message/worker.ts
- packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
- packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
- packages/utils/lib/locate-pm2.ts
🚧 Files skipped from review as they are similar to previous changes (28)
- packages/ui-next/package.json
- packages/hydrooj/src/ui.ts
- packages/hydrooj/src/model/message.ts
- packages/hydrooj/src/model/token.ts
- packages/hydrojudge/src/judge/hack.ts
- packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
- packages/onsite-toolkit/frontend/resolver.page.tsx
- packages/hydrooj/src/handler/problem.ts
- packages/hydrooj/src/model/contest.ts
- packages/hydrooj/src/commands/install.ts
- packages/utils/package.json
- packages/hydrooj/src/model/problem.ts
- packages/migrate/package.json
- packages/ui-default/backendlib/builder.ts
- packages/ui-default/components/autocomplete/components/AutoComplete.tsx
- packages/hydrooj/src/model/system.ts
- packages/hydrooj/src/model/storage.ts
- packages/ui-next/src/App.tsx
- packages/hydrooj/src/plugin-api.ts
- packages/hydrooj/src/entry/cli.ts
- packages/hydrooj/src/service/bus.ts
- packages/vjudge/src/index.ts
- packages/hydrooj/src/model/user.ts
- packages/hydrooj/package.json
- packages/hydrooj/src/model/task.ts
- packages/hydrooj/src/entry/common.ts
- package.json
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (11)
packages/hydrooj/src/model/record.ts (10)
packages/hydrooj/src/model/schedule.ts (1) (1)
apply
(62-101)packages/hydrooj/src/handler/record.ts (1) (1)
apply
(458-463)packages/hydrooj/src/handler/user.ts (1) (1)
apply
(506-580)packages/hydrooj/src/handler/problem.ts (1) (1)
apply
(1020-1097)packages/hydrooj/src/model/document.ts (1) (1)
apply
(413-447)packages/hydrooj/src/model/task.ts (1) (1)
apply
(145-191)packages/hydrooj/src/model/user.ts (1) (1)
apply
(477-495)packages/hydrooj/src/model/blacklist.ts (1) (1)
apply
(34-40)packages/hydrooj/src/model/message.ts (1) (1)
apply
(88-94)packages/hydrooj/src/model/storage.ts (1) (1)
apply
(181-211)
packages/hydrooj/src/entry/worker.ts (4)
packages/hydrooj/src/service/db.ts (1) (1)
MongoService
(35-180)packages/hydrooj/src/options.ts (1) (1)
load
(24-37)packages/hydrooj/src/entry/setup.ts (1) (1)
load
(9-38)packages/hydrooj/src/settings.ts (1) (1)
ConfigService
(14-172)
packages/ui-default/backendlib/template.ts (3)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/api.ts (3) (3)
Service
(5-5)ctx
(5-5)Context
(5-5)packages/hydrooj/src/model/builtin.ts (2) (2)
PERM
(9-102)PRIV
(240-267)
packages/hydrooj/src/service/db.ts (1)
packages/hydrooj/src/options.ts (1) (1)
load
(24-37)
packages/hydrooj/src/interface.ts (1)
packages/common/types.ts (1) (1)
RecordJudgeInfo
(84-96)
packages/hydrooj/src/settings.ts (4)
packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/elastic/index.ts (1) (1)
Context
(95-125)packages/vjudge/src/index.ts (1) (1)
Context
(191-196)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/model/setting.ts (3)
packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
framework/framework/server.ts (7)
packages/ui-default/context.ts (4) (4)
ctx
(18-18)Service
(16-17)Context
(8-11)Context
(13-13)packages/hydrooj/src/service/layers/base.ts (1) (1)
ctx
(20-72)packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)packages/hydrooj/src/service/server.ts (2) (2)
HandlerCommon
(31-39)Handler
(74-76)packages/hydrooj/src/plugin-api.ts (4) (4)
HandlerCommon
(7-7)Handler
(40-40)Service
(41-41)Context
(41-41)framework/framework/interface.ts (1) (1)
KnownHandlers
(3-5)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
packages/hydrooj/src/model/document.ts (7)
packages/hydrooj/src/model/user.ts (1) (1)
coll
(22-22)packages/hydrooj/src/model/oplog.ts (1) (1)
coll
(8-8)packages/hydrooj/src/model/discussion.ts (1) (1)
coll
(43-43)packages/hydrooj/src/model/problem.ts (1) (1)
incStatus
(431-436)packages/hydrooj/src/model/token.ts (1) (1)
update
(53-71)packages/hydrooj/src/model/record.ts (1) (1)
update
(195-219)packages/hydrooj/src/service/monitor.ts (1) (1)
update
(76-89)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/ui-default/index.ts (1)
packages/ui-default/backendlib/template.ts (1) (1)
TemplateService
(161-276)
🪛 Biome (1.9.4)
packages/ui-default/backendlib/template.ts
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().
(lint/security/noGlobalEval)
packages/hydrooj/src/loader.ts
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
framework/framework/server.ts
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
packages/hydrooj/src/handler/domain.ts
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/handler/misc.ts
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/document.ts
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/ui-default/index.ts
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🪛 GitHub Check: CodeQL
build/prepare.js
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
🔇 Additional comments (113)
build/prepare.js (8)
18-22
: TypeScript configuration modernization looks goodUpgrading to ES2022 with bundler-oriented module configuration is a sensible choice for the project. These changes align with modern development practices and enable newer JavaScript features like class fields and top-level await.
37-37
: UI-Next reference added correctlyAdding the reference to the new UI-Next TypeScript configuration aligns with the introduction of the new UI package later in this file.
78-78
: Module filtering improvementThe updated filtering logic elegantly excludes both UI packages using a more concise approach.
83-120
: React JSX Transform Update – Address Unnecessary React ImportsThe build configuration now uses the new
react-jsx
transform (React 17+), which means explicitimport React from 'react'
statements are generally no longer required for JSX to work. The enhanced configuration also includes improved bundler mode settings and stronger linting rules.
123-161
: New UI-Next TypeScript configuration properly structuredThe configuration for the new UI-Next package is well-structured with appropriate compiler options, including strict type checking and modern module settings. The path aliasing with
@/*
will provide a clean import structure for the new React/Vite package.
163-167
: Fix potential file system race conditionThe
tryUpdate
function has a potential race condition between checking if a file exists and reading it. If the file is deleted between these operations, it could cause errors.🧰 Tools
🪛 GitHub Check: CodeQL
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
189-190
: Skip type checking declaration files for performanceAdding
skipLibCheck: true
is a good performance optimization that avoids type checking declaration files (*.d.ts) in node_modules, which can significantly speed up compilation.
197-225
: Improved file writing logic with optimizationReplacing direct file writes with the
tryUpdate
function is a good optimization that only writes files when their content has changed. This reduces unnecessary disk operations during development and builds.packages/ui-default/index.ts (5)
56-56
: Remove the empty object pattern.Static analysis flags
{ }
as an unexpected empty pattern. Consider removing it as it doesn't serve any purpose.- async get({ }, legacy = false, nohint = false) { + async get(legacy = false, nohint = false) {🧰 Tools
🪛 Biome (1.9.4)
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
25-25
: Good type definition improvement.Adding explicit type annotation for the
sections
array enhances code clarity and type safety. This is a positive change.
77-77
: Improve configuration management.Using
this.ctx.config.settings
instead of the globalSystemSettings
is a good architectural change that enhances modularity and testability.
119-119
: Enhanced type clarity.Adding the explicit type annotation for
res
asany[]
improves code readability and maintainability.
167-167
: Good integration of the new TemplateService.The integration of the new
TemplateService
usingctx.plugin()
properly follows the service-oriented architecture pattern, enhancing modularity.packages/hydrooj/src/model/oauth.ts (1)
18-18
:❓ Verification inconclusive
Verify MongoDB return value structure.
The change from
res.value?.uid
tores?.uid
assumes a different structure from the MongoDBfindOneAndUpdate
operation. This might be correct if you're using a newer MongoDB driver version or if your DB adapter normalizes results, but it's worth verifying that this change aligns with the actual structure returned by your MongoDB implementation.
🏁 Script executed:
#!/bin/bash # Check if other MongoDB operations in the codebase follow the same pattern echo "Checking for other findOneAndUpdate usage patterns in the codebase:" rg "findOneAndUpdate" -A 3 --glob "*.ts" | grep -E "res\.value|res\?" | head -n 15 echo "Checking if there's a MongoDB client configuration or wrapper:" fd "db\.ts|mongo\.ts" --type f --exec cat {} \; | grep -A 10 -B 10 "findOneAndUpdate"Length of output: 454
MongoDB Return Structure Verification Needed
The change from using
res.value?.uid
tores?.uid
suggests an assumption that the MongoDB driver (or a custom adapter) now returns the document directly rather than wrapping it in a{ value: ... }
object. Our automated search did not uncover any additional usage patterns or configuration files that clarify this change in behavior. To proceed safely, please manually verify the following:
- Driver/Adapter Version: Check the
mongodb
driver version inpackages/hydrooj/package.json
(or the relevant package manifest) to confirm that its documentation supports returning the document directly.- Expected Return Structure: Consult the MongoDB driver documentation (or verify through runtime tests) to confirm whether
findOneAndUpdate
now returns the updated document directly rather than asres.value
.- Code Consistency: Ensure that any dependent code has been reviewed for consistency with this change, especially if other parts of the codebase reference properties like
value
.Please double-check these points to ensure that the change is valid for your project's environment.
packages/hydrooj/src/handler/misc.ts (3)
17-17
: Added the sortFiles import from utils.The addition of
sortFiles
import is used appropriately in the FilesHandler class on line 38.
131-137
: Ensure routes are updated if method signatures have changed.With the changes to the method signatures in StorageHandler and SwitchAccountHandler, verify that the routes defined in the
apply
function are still passing the correct parameters.Check if any of the route handlers need updates to match the new parameter structure, particularly for StorageHandler and SwitchAccountHandler routes.
112-112
:❓ Verification inconclusive
Verify the security of the new validation approach.
The validation logic has been changed to use a context-based approach with
this.ctx.get('storage')?.isLinkValid?
. This is a significant change in how security validation is performed.Make sure that:
- The
isLinkValid
method is properly implemented in the storage context- It provides the same or better level of security as the previous approach
- All edge cases are handled correctly
🏁 Script executed:
#!/bin/bash # Check if the isLinkValid method is properly implemented rg "isLinkValid" --type tsLength of output: 341
Action: Confirm the security and consistency of the
isLinkValid
implementation in storageThe search output confirms that the
isLinkValid
method is defined in the storage context (in packages/hydrooj/src/service/storage.ts). However, two similar definitions (one with an unused parameter_: string
and another withlink: string
) were found. As this change modifies the validation approach by relying onthis.ctx.get('storage')?.isLinkValid
, please ensure the following:
- Correct Implementation in Use: Verify that the intended
isLinkValid
implementation is used (and any duplicate or placeholder version is removed or clearly segregated).- Robust Security Measures: Ensure that the chosen implementation performs all necessary security checks—such as sanitizing inputs, verifying expiration and secret validity—to maintain or improve upon the previous security level.
- Comprehensive Edge Case Handling: Confirm that all potential edge cases (e.g., missing, malformed, or unexpected input parameters) are properly managed and that optional chaining (
?.
) does not inadvertently bypass validation.Please review the internal implementation details in packages/hydrooj/src/service/storage.ts and confirm that the above points are addressed.
packages/hydrooj/src/model/opcount.ts (1)
16-16
:✅ Verification successful
Data structure access pattern has changed
The return statement has been updated to access
opcount
directly from theres
object instead of fromres.value.opcount
. This suggests a breaking change in the MongoDB driver response structure or an adaptation to a recent MongoDB update.I recommend verifying that this change aligns with the version of MongoDB driver being used:
🏁 Script executed:
#!/bin/bash # Check MongoDB driver version and documentation about findOneAndUpdate return structure grep -r "mongodb" --include="package.json" . | grep versionLength of output: 57
I'll run a new shell script to search for any explicit references to the MongoDB dependency in all package.json files. This should help us determine the driver version in use (if specified):
Once we have this output, we can verify whether the change in data access (from
res.value.opcount
tores.opcount
) aligns with the documented behavior of the MongoDB driver version in use. Please share the result of this script execution or verify it manually.
🏁 Script executed:
#!/bin/bash # Search all package.json files for the "mongodb" dependency reference and its version find . -type f -name "package.json" -exec grep -H '"mongodb":' {} \;Length of output: 510
Verified: MongoDB Driver Structure Change Consistent with v6.15.0
The updated return statement now accesses
opcount
directly from theres
object. Our verification confirmed that the project uses MongoDB driver version ^6.15.0 (as seen in the package.json files), which aligns with this new response structure. No further action is needed here, but please ensure that any other parts of the code interfacing with the driver follow the updated data structure consistently.packages/hydrojudge/src/checkers.ts (4)
12-12
: Good addition to enhance checker capabilitiesAdding the
code
property to theCheckConfig
interface allows checkers to access the submitted code, enabling more sophisticated validation strategies.
179-180
: Documentation updated to reflect implemented featureThe comment has been updated to remove "(not impl)" for the
code
property, correctly reflecting that the feature is now implemented.
190-190
: Implementation of code property in syzoj checkerThe checker now uses
config.code
directly, allowing access to the submitted code. This matches the interface update and enhances the checker's capabilities.
206-206
: Added code access to testlib checkerThe testlib checker now includes
user_code: config.code
in itscopyIn
configuration, ensuring the submitted code is available for more thorough validation.packages/utils/lib/utils.ts (4)
10-10
: Enhanced logger import for more modularityThe import has been expanded to include
Exporter
andFactory
from 'reggol', enabling a more configurable logging system.
15-27
: Improved logger configuration with factory patternThis change implements a factory pattern for logger creation with detailed configuration options. The new approach provides better encapsulation and customization of logging behavior.
29-31
: Added logger factory function for consistencyThe
createLogger
function provides a clean interface for creating new logger instances, ensuring consistent logger configuration throughout the application.
33-35
: Updated Logger export with appropriate type castingThe export statement has been modified to use the new factory-based approach while maintaining backward compatibility through type casting.
packages/hydrooj/src/service/db.ts (9)
7-7
: Updated imports to use context and service base classImporting the
Context
andService
from the context module aligns with the new context-based architecture.
11-11
: Simplified bus importChanged from namespace import to default import for the bus service, which is a cleaner approach if only using the default export.
29-34
: Added MongoDB service to Context interfaceThis module declaration extends the Context interface to include the database service, enabling type-safe access to the MongoDB service through the context.
35-35
: MongoService now extends Service base classThe MongoDB service now properly extends the Service base class, following a more consistent inheritance pattern for services.
39-41
: Updated constructor to use Context and proper initializationThe constructor now accepts a Context parameter and calls the parent class constructor with appropriate parameters, enabling proper integration with the context system.
43-56
: Added static method for URL generationThe
getUrl
static method encapsulates the logic for generating the MongoDB connection URL, supporting CI environments with an in-memory MongoDB server and configuration from loaded options.
58-66
: Replaced start method with async generator for proper lifecycle managementThe method has been updated to an async generator using
[Context.init]
symbol, which better integrates with the context lifecycle management and yields a cleanup function for proper resource disposal.
69-70
: Improved collection name handling with configurationThe collection method now uses configuration properties for prefix and collection mapping, allowing more flexible collection naming strategies.
182-189
: Added backward compatibility with a deprecation noticeA proxy object is used to maintain backward compatibility while encouraging migration to the context-based approach with a deprecation notice.
packages/hydrooj/src/interface.ts (5)
226-229
: Good addition of RecordHistoryDoc interface with proper extensionThe new RecordHistoryDoc interface correctly extends RecordJudgeInfo and adds the essential tracking fields (_id and rid) needed for the record history functionality. This provides good type safety for historical record tracking.
83-83
: Type improvement for authenticator extensionsChanging the type from AuthenticationExtensionsAuthenticatorOutputs to ParsedAuthenticatorData['extensionsData'] provides better alignment with the underlying library types and improves type safety.
637-637
: Properly moved problemSearch to ModuleInterfacesThe problemSearch property has been moved to the ModuleInterfaces as recommended in previous reviews, which aligns with the refactoring to reduce global assignments and encapsulate functionality within the module system.
663-663
: Improved addons data structureChanging addons from an array to a Record<string, string> improves lookup performance and allows associating metadata with each addon. Make sure all code that previously accessed addons as an array has been updated.
552-552
: Proper database collection definition for record historyGood job registering the record.history collection with the RecordHistoryDoc type in the database collections. This ensures type safety when accessing this collection throughout the application.
packages/elastic/index.ts (3)
20-32
: Good refactoring to service-based architectureThe refactoring of ElasticSearch functionality into a proper service class with configuration schema is a great improvement over the previous global function approach. This enhances maintainability and modularity.
34-34
: Add proper type annotation for the opts parameterThe
opts
parameter is missing a type annotation. Consider defining an interface for the options or using a more specific type to improve type safety.- async problemSearch(domainId: string, q: string, opts): ReturnType<ProblemSearch> { + async problemSearch(domainId: string, q: string, opts: { limit?: number; skip?: number }): ReturnType<ProblemSearch> {
72-72
: Add proper type annotations for the run method parametersThe parameters in the
run
method lack proper type annotations, which reduces type safety. Consider defining interfaces for these parameters.- async run({ domainId }, report) { + async run({ domainId }: { domainId?: string }, report: (status: { message: string }) => void) {packages/hydrooj/src/model/setting.ts (6)
7-7
: Action Required: Add "schemastery" to project dependenciesThe import of
Schema
fromschemastery
is appropriate given its usage in the file. However, according to a previous verification,schemastery
is not currently listed in your project dependencies.#!/bin/bash # Check if schemastery is in dependencies grep -r "schemastery" package.json
73-80
: Good addition of Schemastery namespace declarationThe global declaration for the Schemastery namespace provides proper typing for schema metadata, which enhances type safety when working with schemas.
82-119
: Potential coverage gap for complex schemasThe
schemaToSettings
function handles only basic data types (string, number, boolean) and single-level nesting. More complex schema structures like arrays, tuples, or deeply nested objects might not be fully processed.Consider enhancing the function to handle more complex schema types and deeper nesting levels:
function schemaToSettings(schema: Schema<any>) { const result: _Setting[] = []; - const processNode = (key: string, s: Schema<number> | Schema<string> | Schema<boolean>, defaultFamily = 'setting_basic') => { + const processNode = (key: string, s: Schema<any>, defaultFamily = 'setting_basic') => { if (s.dict) throw new Error('Dict is not supported here'); + // Handle array type + if (s.array) { + return { + family: s.meta?.family || defaultFamily, + key, + value: s.meta?.default || [], + name: key, + desc: s.meta?.description, + flag: (s.meta?.hidden ? FLAG_HIDDEN : 0) | (s.meta?.disabled ? FLAG_DISABLED : 0), + subType: 'json', + type: 'json', + range: null, + } as _Setting; + } // Rest of the function...
290-318
: Excellent use of schema-based configurationThe Schema-based system settings provide a more robust and typed approach to configuration. This is a great improvement over the string-based approach, providing better validation and documentation of settings.
388-388
: Good service dependency declarationAdding the inject property properly declares the dependencies required by the setting service, which is important for the dependency injection system to work correctly.
121-143
: Good enhancement to support both Schema and raw settingsThe modification to handle both Schema objects and raw _Setting objects improves flexibility while maintaining backward compatibility. The flatMap approach is an elegant way to handle the conversion.
packages/hydrooj/src/handler/domain.ts (5)
105-147
: Improved DomainUserHandler with aggregation pipelineReplacing direct MongoDB queries with an aggregation pipeline is a good improvement that:
- Efficiently filters users by role in a single query
- Uses $lookup to join with the user collection for better data access
- Applies proper field projection to include only necessary data
This approach is more efficient and maintainable than separate queries and manual joining.
258-258
: Simplified role filtering logicGood improvement to only exclude the 'guest' role rather than both 'default' and 'guest'. This allows for more flexible role management where users with the 'default' role can still be shown in the interface.
322-337
: Enhanced DomainJoinHandler with target parameterThe addition of a target parameter to prepare makes the handler more flexible, allowing users to join a different domain than the current one. This is a good improvement for cross-domain functionality.
🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
340-358
: Improved DomainJoinHandler.get with additional parametersAdding target and redirect parameters to the get method enhances the flexibility of the domain join process, allowing for better navigation flows. The inclusion of more domain information in the response body also improves the user experience.
361-376
: Improved DomainJoinHandler.post with better role assignmentThe post method now properly handles the target parameter and conditionally sets the role based on joinSettings, which is a more robust approach to role assignment during domain joining.
packages/hydrooj/src/model/record.ts (7)
2-2
: Added lodash's pick utility for history implementation.Good addition -
pick
is the appropriate utility for extracting specific fields for the new history feature.
23-23
: Added new static collection for storing record history.Great addition for record history tracking, which enables auditing and system debugging.
212-217
: Function simplified by returning findOneAndUpdate result directly.Similar to other model changes, this eliminates an intermediate variable for a cleaner implementation.
236-236
: Fixed instance check for arrays.Replaced
instanceof Array
with the more reliableArray.isArray()
method, which works correctly across different execution contexts.
250-262
: Implemented record history preservation.The implementation correctly fetches records before deletion, extracts relevant fields using
pick
, and stores them in the history collection. This enables valuable historical tracking of record changes.The implementation is well-designed, preserving only the essential fields needed for history tracking.
283-283
: Made apply function async for proper promise handling.Changed the
apply
function to be async to better support async operations within it.
307-328
: Added appropriate indexes to the new collHistory collection.The implementation adds proper indexing for the new
collHistory
collection, which is essential for performance as this collection grows.The index on
{ rid: 1, _id: -1 }
supports efficient queries for record history by record ID and chronological order.packages/hydrooj/src/model/schedule.ts (2)
7-7
: Changed import statement for WorkerService.Modified from importing
WorkerService
as a type to importing it as a default export with a type annotation.This change aligns with how the WorkerService is likely exported from its module.
18-25
: Simplified result handling in getFirst method.The code now works directly with the returned document from
findOneAndDelete
instead of accessing it through a nested.value
property, making the code cleaner and more direct.This change is likely part of a broader standardization of how database operation results are handled across the application.
packages/hydrooj/src/entry/worker.ts (5)
9-10
: Updated imports for dependency injection pattern.Added imports for
MongoService
andConfigService
to support the new dependency injection approach.
24-34
: Improved database initialization with async URL retrieval.The implementation now:
- Asynchronously retrieves the MongoDB URL
- Handles the setup process if URL is not found
- Applies plugins for MongoDB and Config services
This is a more robust initialization process compared to the previous implementation.
36-52
: Implemented proper dependency injection pattern.Added structured dependency injection using promises and context injection to ensure dependencies are loaded in the correct order before continuing initialization.
This approach makes the code more maintainable and ensures that services are properly initialized before they're used.
61-65
: Added additional dependency injection for worker and settings.Similar to the previous injection pattern, this ensures worker and settings services are properly initialized.
96-102
: Improved server initialization with dependency injection.Server initialization and listening now use the dependency injection pattern, which:
- Ensures the server is properly initialized before listening
- Provides better organization of startup sequence
- Makes the code more testable
eslint.config.mjs (2)
16-37
: Confirm React ESLint config alignment.You're extending from a custom React config (
@hydrooj/eslint-config
). Ensure it addresses your project’s React-specific requirements and does not conflict with other ESLint rules.
55-86
: Check parser features consistency.The
ecmaVersion
aligns with 2020 in this block. If newer JavaScript features appear in other parts of the code, ensure the global config matches.framework/eslint-config/base.mjs (5)
1-14
: Imports and compatibility look fine.No immediate concerns with these imports. The
FlatCompat
usage is straightforward and appears well-integrated.
15-21
: Validate ignore patterns.Ignoring
.git
is typically inconsequential. However, confirm it does not mask checks for submodules or hidden files that might contain relevant lintable code.
22-28
: Check overlapping style guides.Extending both
airbnb-base
andairbnb/hooks
in conjunction with additional plugins can create conflicting rules. Confirm that no conflicts remain unresolved.
45-52
: Cross-check plugin compatibility.Using
@stylistic/eslint-plugin
,@eslint-react/eslint-plugin
, etc., is beneficial. Verify versions are up to date for smooth interoperability.
64-453
: Review extended rule overrides.Disabling certain defaults in favor of
@stylistic/*
may omit essential checks (e.g.,no-extra-parens
). Confirm you do not lose coverage on critical lint rules.packages/hydrooj/src/service/worker.ts (2)
12-12
: Switching to default export may break imports.Renaming or converting
WorkerService
to a default export can cause issues for modules importing it by name. Verify references are updated.
32-38
: Validateres
structure fromfindOneAndDelete
.Returning
res
instead ofres.value
might break downstream usage if other parts of the code rely on the old property. Confirm that this updated return aligns with consumption patterns.framework/eslint-config/package.json (5)
5-5
: Main entry point changed from YAML to JavaScript moduleThe main entry point has been changed from
react.yaml
tobase.mjs
, which indicates a shift to JavaScript modules for ESLint configuration. This aligns with current best practices for ESLint 9 configuration.
7-12
: Added new ESLint 9 compatible plugins and updated dependenciesThe addition of
@eslint-react/eslint-plugin
,@eslint/compat
, and@eslint/eslintrc
along with updated TypeScript ESLint packages indicates proper preparation for ESLint 9 compatibility. The TypeScript ESLint plugins have been updated to the latest versions (8.27.0).
14-21
: Updated plugin versions and added new utility pluginsThe updates to plugin versions and addition of new utility plugins like
eslint-plugin-de-morgan
and updates toeslint-plugin-simple-import-sort
will improve linting capabilities.
26-27
: Added TypeScript as an optional dependencyAdding TypeScript as an optional dependency with a specific version requirement (^5.8.2) improves type checking capabilities while keeping it optional for non-TypeScript projects.
24-24
:❓ Verification inconclusive
Upgraded ESLint peer dependency to version 9+
The peer dependency for ESLint has been updated from ">= 8" to ">= 9", which is a major version change. Make sure all dependent packages are compatible with ESLint 9.
🏁 Script executed:
#!/bin/bash # Check for any packages that might have incompatibility with ESLint 9 fd -e json package.json --exec grep -l "eslint.*\":" {} \; | xargs grep -l "\"eslint\""Length of output: 143
ESLint 9+ Upgrade – Verify Dependent Package Compatibility
The ESLint peer dependency in
framework/eslint-config/package.json
is now updated to"eslint": ">= 9"
. A quick search across the repository confirms that only two files reference ESLint: the top-levelpackage.json
andframework/eslint-config/package.json
. Please double-check that the ESLint version specified in the top-levelpackage.json
is also aligned with version 9 requirements, ensuring that all dependent packages remain compatible with ESLint 9.
- Action Items:
- Confirm that any ESLint reference in the top-level
package.json
does not conflict with the upgrade.- Validate that all packages relying on ESLint are compatible with version 9.
packages/hydrooj/src/settings.ts (5)
8-12
: Added ConfigService to Context module declarationThe module declaration extends the Context interface with the ConfigService, ensuring proper type safety when accessing the config service throughout the application.
14-24
: New ConfigService class with proper dependency injectionThe new ConfigService class properly extends Service, declares its dependencies with static inject, and uses proper class encapsulation for configuration state. The blacklist is appropriately defined to prevent prototype pollution.
30-34
: Improved Context initialization with database integrationThe Context.init method properly initializes the configuration by fetching from the database and loading initial values before calling loadConfig().
69-77
: Well-implemented schema validation in isPatchValidThe isPatchValid method correctly creates a temporary configuration object with the changes and validates it against the schema before applying it to the actual config, preventing invalid configurations.
159-159
: Fixed null check in getAccess functionThe function now correctly checks if currentValue is both not an object and not null, fixing a potential issue where null values might be incorrectly handled.
packages/hydrooj/src/model/domain.ts (4)
136-137
: Enhanced setUserRole with autojoin parameterThe setUserRole method now includes an autojoin parameter defaulting to false, which conditionally includes a join property in the update operation, improving flexibility.
130-132
: Added join criteria to countUser queriesThe countUser method now includes a join: true property in its queries, ensuring only joined users are counted, which aligns with the domain membership model.
258-260
: Added join criteria to getDictUserByDomainId queryThe getDictUserByDomainId method now adds join: true to its query, ensuring only domains where the user has joined are returned, which aligns with the domain membership model.
292-312
: New apply function properly encapsulates initialization logicThe new apply function centralizes domain model initialization, setting up the cache deletion event listener and ensuring database indexes. This follows the service pattern seen in other files, making initialization more consistent and modular.
This approach aligns with the service initialization pattern seen in other modules (like DB service, Template service) where the Context.init lifecycle hook is used for setup. Good refactoring.
packages/hydrooj/src/loader.ts (8)
15-17
: Updated imports for Context-related typesThe import statement now includes more specific imports from './context', making dependencies clearer and improving code readability.
48-48
: Public state property with improved type definitionThe state property is now better typed with Record<string, EffectScope>, but the next line has a potential issue.
54-57
: Improved dependency injection with static injectThe Loader class now properly declares its dependencies with static inject and uses a more appropriate constructor parameter name (ctx instead of app).
98-107
: Enhanced resolveConfig method with schema handlingThe new resolveConfig method properly handles configuration scopes and schema validation, with good error handling and fallback behavior. It also integrates with the new config service for migration and request handling.
109-126
: Simplified reloadPlugin with async/await patternThe reloadPlugin method has been updated to use async/await and integrates with the new resolveConfig method, improving error handling and making the code more maintainable.
147-168
: Improved preload function with proper async handlingThe preload function now uses async/await with a Promise-based approach to reliably initialize the global app, ensuring dependencies are properly injected before continuing.
170-206
: Updated load function to use await for preloadThe load function now properly awaits the preload function, ensuring initialization completes before continuing with the application startup sequence.
208-213
: Updated loadCli function to use await for preloadSimilar to the load function, loadCli now properly awaits the preload function, ensuring initialization completes before executing CLI commands.
packages/hydrooj/src/model/document.ts (5)
12-12
: Updated import style for the bus module.The import style has been updated from namespace import to default import, which is consistent with modern JavaScript practices and indicates that the bus module now exports a default.
18-18
: Added utility type to exclude symbol keys.Good addition of the
NormalArrayKeys
utility type that excludes symbol keys from array keys, which helps improve type safety when dealing with array properties.
23-33
: Enhanced type safety withas const
assertions.The constants have been updated to use TypeScript's
as const
assertion instead of explicit type annotations. This is a beneficial change that enhances type safety by ensuring the constants are treated as literal types, allowing for better type inference in TypeScript.
112-117
: Simplified return statements for database operations.The functions now directly return the results of database operations instead of storing them in intermediate variables. This reduces unnecessary variable declarations and makes the code more concise.
Also applies to: 152-157, 163-168, 211-217, 224-230, 255-265, 271-277, 301-311, 327-336, 358-374, 385-391, 397-402
385-391
: Improved code with nullish assignment operator.The function has been refactored to use the newer
||=
nullish assignment operator, which is a cleaner and more concise way to handle conditional assignment.framework/framework/server.ts (9)
5-5
: Updated import to use CordisContext.The import has been updated to use CordisContext instead of Context, indicating a shift in the underlying framework or a rename to avoid conflicts with other Context classes.
44-52
: Added utility function for context scoping.This new utility function provides a clean way to create isolated context scopes with proper resource cleanup through the async disposable pattern, which is a modern approach to resource management.
210-211
: Improved class hierarchy with generics.The Handler classes now use generic type parameters for better type safety, allowing them to work with different context types. The static kHandler property also provides a cleaner way to identify handler types.
Also applies to: 258-260, 297-300
337-352
: Enhanced WebService with generic context support.The WebService class now accepts a generic context type, improving type safety and allowing for more flexible context handling throughout the application.
487-488
: Improved resource management with scoped contexts.Using the new forkContextWithScope utility ensures proper resource cleanup when handlers are no longer needed. This prevents potential memory leaks and resource exhaustion.
Also applies to: 566-568
599-612
: Enhanced error handling and resource cleanup.The refactored cleanup logic in handleWS provides more robust error handling and ensures all resources are properly released, regardless of how the connection is terminated.
787-810
: Added robust mixin implementation.The new
_applyMixin
method provides a clean and reliable way to extend class prototypes, with proper cleanup on disposal. This allows for more flexible composition of functionality.
812-828
: Introduced type-safe mixin application methods.The new mixin application methods (
applyMixin
,handlerMixin
,httpHandlerMixin
,wsHandlerMixin
) provide a consistent and type-safe way to extend handler classes with additional functionality.The implementation of
wsHandlerMixin
now correctly applies the mixins to the prototype, fixing the issue where it would previously only warn about existing properties.
841-848
: Enhanced type definitions with module augmentation.The module augmentation for the Context interface ensures that TypeScript properly recognizes the server-related properties and methods, improving type safety throughout the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
packages/hydrooj/src/model/domain.ts (1)
136-153
:⚠️ Potential issueUse Array.isArray check
Replacinguid instanceof Array
withArray.isArray(uid)
avoids issues with arrays from different contexts.- if (!(uid instanceof Array)) { + if (!Array.isArray(uid)) {🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
♻️ Duplicate comments (6)
packages/hydrooj/src/interface.ts (1)
637-637
:⚠️ Potential issueProblemSearch moved to ModuleInterfaces
The problemSearch property is correctly added to ModuleInterfaces, but there's still a duplicate global property definition that needs to be removed.
Remove the line with the global problemSearch property to fully encapsulate problemSearch within the module system, as mentioned in previous review comments.
build/prepare.js (1)
163-167
:⚠️ Potential issueFix potential file system race condition
The
tryUpdate
function has a potential race condition between checking if a file exists and reading it. If the file is deleted between these operations, it could cause errors.Apply this fix to handle the race condition more safely:
const tryUpdate = (location, content) => { - const current = fs.existsSync(location) ? fs.readFileSync(location, 'utf-8') : ''; + let current = ''; + try { + current = fs.readFileSync(location, 'utf-8'); + } catch (err) { + // File doesn't exist or cannot be read + } const expected = typeof content === 'string' ? content : JSON.stringify(content, null, 2); if (expected !== current) fs.writeFileSync(location, expected); };🧰 Tools
🪛 GitHub Check: CodeQL
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.packages/ui-default/backendlib/template.ts (2)
121-121
:⚠️ Potential issueSecurity risk: Use of eval() in template engine.
The use of
eval()
exposes the application to security risks including code injection vulnerabilities. Attackers could potentially execute arbitrary code if they can influence template content.Replace eval with a safer alternative such as a sandboxed evaluation library or a restricted expression parser. Consider using a library like
vm
with proper sandboxing or implementing a custom expression evaluator with limited capabilities.🧰 Tools
🪛 Biome (1.9.4)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().(lint/security/noGlobalEval)
122-138
:⚠️ Potential issueSecurity concern: Exposing global objects to templates.
Exposing complete global objects (Date, Object, String, etc.) in the template environment creates a significant attack surface for template injection attacks. This allows template authors to access potentially dangerous methods or properties.
Consider limiting exposure to only needed functionality rather than the entire global objects. For example, expose only specific methods from Date rather than the entire Date constructor.
framework/framework/server.ts (2)
139-140
:⚠️ Potential issueRemove unsafe interface-class declaration merging.
The empty interface
HandlerCommon<C>
is unsafely merged with the class of the same name. This pattern is flagged by TypeScript as problematic because properties defined in the interface aren't checked for initialization in the class.-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Remove empty interface and only keep the class definition export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
684-708
:⚠️ Potential issueFix condition that always evaluates to false.
The condition
if (perm)
in thecheck
function at line 705 is likely not working as intended. This was flagged in previous reviews as a condition that always evaluates to false.public check(this: Handler<C>) { checker(); - if (perm) this.checkPerm(perm); + if (perm !== undefined && perm !== null) this.checkPerm(perm); if (priv) this.checkPriv(priv); }
🧹 Nitpick comments (18)
.github/workflows/build.yml (1)
65-67
: Streamline the Build and Lint CommandThe updated command now omits the
lint:ui:ci
step, which simplifies the workflow and potentially reduces redundant linting. Please verify that this removal does not skip any critical linting on the UI code that was previously covered.- parallel --tty -j+0 yarn ::: lint:ci lint:ui:ci build build:ui:production:webpack test + parallel --tty -j+0 yarn ::: lint:ci build build:ui:production:webpack testpackages/hydrooj/src/handler/misc.ts (2)
110-110
: Replace empty object pattern with proper parameter skippingThe empty object pattern
{ }
is flagged by the linter and doesn't follow TypeScript best practices for ignoring parameters.Consider using one of these alternatives instead:
- async get({ }, target: string, filename = '', expire: number, secret: string) { + async get(_: any, target: string, filename = '', expire: number, secret: string) {or
- async get({ }, target: string, filename = '', expire: number, secret: string) { + async get(_domainId: unknown, target: string, filename = '', expire: number, secret: string) {🧰 Tools
🪛 Biome (1.9.4)
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
124-124
: Replace empty object pattern with proper parameter skippingSimilar to line 110, the empty object pattern
{ }
is flagged by the linter and should be replaced with a proper parameter naming convention.- async get({ }, uid: number) { + async get(_: any, uid: number) {or
- async get({ }, uid: number) { + async get(_domainId: unknown, uid: number) {🧰 Tools
🪛 Biome (1.9.4)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/setting.ts (1)
82-119
: Enhance schemaToSettings function to handle more complex schemasThe new
schemaToSettings
function converts Schema objects to _Setting objects, which is a good approach for supporting the schema-based configuration. However, the function currently handles only a limited subset of data types (string, number, boolean) and single-level nesting. More complex schema structures might not be fully processed.Consider enhancing the function to handle:
- More complex nested structures (beyond one level)
- Arrays and other data types
- More robust error handling for unsupported types
function schemaToSettings(schema: Schema<any>) { const result: _Setting[] = []; - const processNode = (key: string, s: Schema<number> | Schema<string> | Schema<boolean>, defaultFamily = 'setting_basic') => { + const processNode = (key: string, s: Schema<any>, defaultFamily = 'setting_basic') => { if (s.dict) throw new Error('Dict is not supported here'); let flag = (s.meta?.hidden ? FLAG_HIDDEN : 0) | (s.meta?.disabled ? FLAG_DISABLED : 0); const type = s.type === 'number' ? 'number' : s.type === 'boolean' ? 'checkbox' + : s.type === 'array' ? 'json' : s.meta?.role === 'textarea' ? 'textarea' : 'text'; if (s.meta?.role === 'password') flag |= FLAG_SECRET; const options = {}; for (const item of s.list || []) { if (item.type !== 'const') throw new Error('List item must be a constant'); options[item.value] = item.meta?.description || item.value; } return { family: s.meta?.family || defaultFamily, key, value: s.meta?.default, name: key, desc: s.meta?.description, flag, subType: '', type: s.list ? 'select' : type, range: s.list ? options : null, } as _Setting; }; if (!schema.dict) return []; for (const key in schema.dict) { const value = schema.dict[key]; if (value.dict) { for (const subkey in value.dict) { result.push(processNode(`${key}.${subkey}`, value.dict[subkey], value.meta?.family)); } + } else if (value.type === 'array') { + // Handle array type + result.push(processNode(key, value)); } else result.push(processNode(key, value)); } return result; }eslint.config.mjs (2)
1-2
: Remove or refine these global rule disables.Disabling
max-len
and@typescript-eslint/naming-convention
at the top level can reduce code clarity and consistency across the project. Consider selectively allowing exceptions only where needed rather than disabling both rules entirely.
19-21
: Evaluate ECMAScript version compatibility.The configuration sets
ecmaVersion: 5
, but also specifiessourceType: "module"
. If you plan to leverage modern ES features, you may wish to increaseecmaVersion
beyond 5 for more accurate linting and better alignment with current JavaScript capabilities.framework/eslint-config/base.mjs (4)
200-206
: Consider enforcing the “no-magic-numbers” rule.By disabling
@typescript-eslint/no-magic-numbers
, your code may accumulate “magic” constants scattered throughout. Enabling this rule can help maintain clarity and reduce the risk of hardcoded values introducing bugs.
366-366
: Review the max line length.Currently,
'max-len': ['warn', 150]
can still lead to unwieldy lines. Consider lowering it for better readability and to prevent large amounts of horizontal scrolling, especially on smaller screens.
377-377
: Caution with async operations in loops.
no-await-in-loop
is set towarn
. While occasionally necessary, awaiting within a loop can degrade performance if parallelization is possible. Ensure you have considered alternatives (e.g.,Promise.all
) for tasks that can run concurrently.
430-430
: Checkreact-hooks/exhaustive-deps
usage.This rule is completely disabled, which might hide potential useEffect dependency errors in React components. Consider at least warning developers about incomplete dependency arrays to avoid subtle state management bugs.
framework/eslint-config/package.json (1)
7-21
: Ensure plugin version compatibility.Multiple new plugins and upgraded versions (e.g.,
@eslint-react/eslint-plugin
,@eslint/compat
,@stylistic/eslint-plugin
, etc.) may have peer constraints. Confirm that these versions interoperate correctly, especially for React 18 and modern TypeScript usage.packages/elastic/index.ts (2)
26-32
: Avoid using console.log in production
Use a dedicated logger instead ofconsole.log
to ensure consistent log formatting and better log management.- console.log('elastic-search', config); + this.ctx.logger.info('Initializing Elasticsearch with config: %j', config);
80-92
: Consider using bulk indexing for performance
Instead of indexing documents one by one, consider using Elasticsearch's bulk API to improve performance when indexing a large number of documents.packages/hydrooj/src/settings.ts (2)
14-25
: Strengthen the prototype pollution safeguard
Although you maintain a list of blacklisted properties (__proto__
,prototype
, andconstructor
), consider using a more complete library or approach to mitigate prototype pollution comprehensively.
86-107
: Potential performance improvement
Consider storing partial migration updates to batch them instead of updating the database individually for each node.packages/hydrooj/src/model/domain.ts (1)
292-312
: Unified event and index management
This function cleanly centralizes cache invalidation and index creation. Consider logging any index creation errors for troubleshooting.packages/ui-default/index.ts (1)
119-119
: Added explicit type definition for better clarity.The
res
variable has been explicitly typed asany[]
, which improves code readability. Consider using a more specific type thanany
if possible for better type safety.- const res: any[] = []; + const res: Array<string> = [];packages/hydrooj/src/handler/domain.ts (1)
150-160
: Restructured user data processing for better organization.The code now maps and transforms the aggregation results to create a cleaner structure, removing nested objects and organizing data more logically. However, there's a potential performance issue with the use of the
delete
operator.- delete u.user; + u.user = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (94)
.eslintrc.yaml
(0 hunks).github/workflows/build.yml
(1 hunks)build/prepare.js
(5 hunks)eslint.config.mjs
(1 hunks)framework/eslint-config/base.mjs
(1 hunks)framework/eslint-config/base.yaml
(0 hunks)framework/eslint-config/package.json
(1 hunks)framework/eslint-config/react.yaml
(0 hunks)framework/eslint-config/typescript.js
(0 hunks)framework/framework/error.ts
(0 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrojudge/src/cases.ts
(0 hunks)packages/hydrojudge/src/checkers.ts
(4 hunks)packages/hydrojudge/src/daemon.ts
(0 hunks)packages/hydrojudge/src/hosts/hydro.ts
(0 hunks)packages/hydrojudge/src/hosts/vj4.ts
(1 hunks)packages/hydrojudge/src/judge/hack.ts
(4 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/commands/install.ts
(1 hunks)packages/hydrooj/src/entry/cli.ts
(2 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/setup.ts
(0 hunks)packages/hydrooj/src/entry/worker.ts
(3 hunks)packages/hydrooj/src/handler/contest.ts
(0 hunks)packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/misc.ts
(3 hunks)packages/hydrooj/src/handler/problem.ts
(1 hunks)packages/hydrooj/src/interface.ts
(6 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/blacklist.ts
(1 hunks)packages/hydrooj/src/model/contest.ts
(7 hunks)packages/hydrooj/src/model/document.ts
(11 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/hydrooj/src/model/message.ts
(3 hunks)packages/hydrooj/src/model/oauth.ts
(1 hunks)packages/hydrooj/src/model/opcount.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/record.ts
(8 hunks)packages/hydrooj/src/model/schedule.ts
(2 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/storage.ts
(6 hunks)packages/hydrooj/src/model/system.ts
(3 hunks)packages/hydrooj/src/model/task.ts
(3 hunks)packages/hydrooj/src/model/token.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(8 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)packages/hydrooj/src/script/problemStat.ts
(0 hunks)packages/hydrooj/src/script/storageUsage.ts
(0 hunks)packages/hydrooj/src/service/bus.ts
(5 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/worker.ts
(2 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/migrate/package.json
(1 hunks)packages/onlyoffice/frontend/office.page.ts
(0 hunks)packages/onsite-toolkit/frontend/resolver.page.tsx
(2 hunks)packages/ui-default/.eslintignore
(0 hunks)packages/ui-default/.eslintrc.js
(0 hunks)packages/ui-default/api.ts
(0 hunks)packages/ui-default/backendlib/builder.ts
(4 hunks)packages/ui-default/backendlib/markdown-it-imsize.ts
(1 hunks)packages/ui-default/backendlib/markdown-it-media.ts
(0 hunks)packages/ui-default/backendlib/misc.ts
(1 hunks)packages/ui-default/backendlib/template.ts
(3 hunks)packages/ui-default/build/config/webpack.ts
(1 hunks)packages/ui-default/build/main.ts
(1 hunks)packages/ui-default/components/autocomplete/components/AutoComplete.tsx
(3 hunks)packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
(1 hunks)packages/ui-default/components/calendar/index.js
(2 hunks)packages/ui-default/components/message/worker.ts
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
(1 hunks)packages/ui-default/components/problemconfig/reducer/config.ts
(1 hunks)packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/Testcase.tsx
(1 hunks)packages/ui-default/components/scratchpad/DataInputComponent.jsx
(0 hunks)packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
(0 hunks)packages/ui-default/index.ts
(6 hunks)packages/ui-default/package.json
(5 hunks)packages/ui-next/package.json
(1 hunks)packages/ui-next/src/App.tsx
(1 hunks)packages/utils/lib/locate-pm2.ts
(1 hunks)packages/utils/lib/utils.ts
(1 hunks)packages/utils/package.json
(2 hunks)packages/vjudge/src/index.ts
(3 hunks)packages/vjudge/src/providers/codeforces.ts
(0 hunks)packages/vjudge/src/providers/hduoj.ts
(0 hunks)packages/vjudge/src/providers/poj.ts
(0 hunks)packages/vjudge/src/providers/spoj.ts
(0 hunks)packages/vjudge/src/providers/uoj.ts
(0 hunks)packages/vjudge/src/providers/yacs.ts
(0 hunks)
💤 Files with no reviewable changes (25)
- packages/ui-default/components/scratchpad/DataInputComponent.jsx
- packages/vjudge/src/providers/yacs.ts
- packages/vjudge/src/providers/hduoj.ts
- packages/ui-default/api.ts
- packages/hydrooj/src/script/problemStat.ts
- packages/onlyoffice/frontend/office.page.ts
- packages/hydrojudge/src/daemon.ts
- framework/eslint-config/react.yaml
- packages/hydrojudge/src/hosts/hydro.ts
- packages/hydrojudge/src/cases.ts
- packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
- packages/ui-default/backendlib/markdown-it-media.ts
- packages/ui-default/.eslintignore
- packages/vjudge/src/providers/spoj.ts
- framework/framework/error.ts
- packages/vjudge/src/providers/uoj.ts
- packages/hydrooj/src/script/storageUsage.ts
- packages/hydrooj/src/handler/contest.ts
- packages/hydrooj/src/entry/setup.ts
- packages/vjudge/src/providers/codeforces.ts
- framework/eslint-config/typescript.js
- packages/vjudge/src/providers/poj.ts
- packages/ui-default/.eslintrc.js
- framework/eslint-config/base.yaml
- .eslintrc.yaml
✅ Files skipped from review due to trivial changes (14)
- packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
- packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
- packages/ui-default/components/message/worker.ts
- packages/ui-default/components/problemconfig/tree/Testcase.tsx
- packages/ui-default/backendlib/misc.ts
- packages/ui-default/build/main.ts
- packages/ui-default/build/config/webpack.ts
- packages/ui-default/components/problemconfig/reducer/config.ts
- packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
- packages/ui-default/backendlib/markdown-it-imsize.ts
- packages/utils/lib/locate-pm2.ts
- packages/ui-default/components/calendar/index.js
- packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
- packages/hydrojudge/src/hosts/vj4.ts
🚧 Files skipped from review as they are similar to previous changes (24)
- packages/ui-next/src/App.tsx
- packages/hydrojudge/src/checkers.ts
- packages/hydrooj/src/model/message.ts
- packages/hydrooj/src/entry/cli.ts
- packages/ui-next/package.json
- packages/onsite-toolkit/frontend/resolver.page.tsx
- packages/migrate/package.json
- packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
- packages/hydrooj/src/model/system.ts
- packages/hydrooj/src/model/token.ts
- packages/hydrooj/src/model/storage.ts
- packages/ui-default/components/autocomplete/components/AutoComplete.tsx
- packages/hydrojudge/src/judge/hack.ts
- packages/utils/package.json
- packages/hydrooj/src/model/problem.ts
- packages/hydrooj/src/ui.ts
- packages/hydrooj/src/commands/install.ts
- packages/hydrooj/src/handler/problem.ts
- package.json
- packages/vjudge/src/index.ts
- packages/hydrooj/src/plugin-api.ts
- packages/hydrooj/src/model/user.ts
- packages/ui-default/backendlib/builder.ts
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (13)
packages/hydrooj/src/model/record.ts (2)
packages/hydrooj/src/model/document.ts (1) (1)
apply
(413-447)packages/hydrooj/src/model/task.ts (1) (1)
apply
(145-191)
packages/ui-default/backendlib/template.ts (3)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/api.ts (3) (3)
Service
(5-5)ctx
(5-5)Context
(5-5)packages/hydrooj/src/model/builtin.ts (2) (2)
PERM
(9-102)PRIV
(240-267)
packages/hydrooj/src/service/db.ts (1)
packages/hydrooj/src/options.ts (1) (1)
load
(24-37)
packages/hydrooj/src/loader.ts (5)
packages/hydrooj/src/context.ts (3) (3)
EffectScope
(27-27)Context
(31-41)Context
(68-77)packages/ui-default/api.ts (2) (2)
ctx
(5-5)Context
(5-5)packages/hydrooj/src/plugin-api.ts (1) (1)
Context
(41-41)packages/hydrooj/src/lib/i18n.ts (1) (1)
name
(56-56)packages/hydrooj/src/options.ts (1) (1)
getAddons
(39-42)
packages/elastic/index.ts (4)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/hydrooj/src/settings.ts (1) (1)
Context
(30-34)packages/hydrooj/src/interface.ts (1) (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1) (1)
ProblemModel
(74-675)
packages/hydrooj/src/settings.ts (4)
packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/elastic/index.ts (1) (1)
Context
(95-125)packages/vjudge/src/index.ts (1) (1)
Context
(191-196)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/service/bus.ts (6)
packages/hydrooj/src/context.ts (3) (3)
EventMap
(13-13)Context
(31-41)Context
(68-77)packages/hydrooj/src/plugin-api.ts (3) (3)
EventMap
(57-57)Handler
(40-40)Context
(41-41)framework/framework/interface.ts (1) (1)
VoidReturn
(19-19)packages/hydrooj/src/service/server.ts (1) (1)
Handler
(74-76)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)packages/ui-default/context.ts (2) (2)
Context
(8-11)Context
(13-13)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/interface.ts (1)
packages/common/types.ts (1) (1)
RecordJudgeInfo
(84-96)
packages/hydrooj/src/model/setting.ts (5)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/entry/common.ts (4)
packages/ui-default/api.ts (2) (2)
ctx
(5-5)Context
(5-5)packages/ui-default/context.ts (3) (3)
ctx
(18-18)Context
(8-11)Context
(13-13)packages/hydrooj/src/plugin-api.ts (1) (1)
Context
(41-41)packages/hydrooj/src/utils.ts (1) (1)
unwrapExports
(21-29)
framework/framework/server.ts (4)
packages/ui-default/context.ts (3) (3)
ctx
(18-18)Context
(8-11)Context
(13-13)packages/hydrooj/src/service/layers/base.ts (1) (1)
ctx
(20-72)packages/hydrooj/src/service/layers/user.ts (1) (1)
ctx
(5-18)framework/framework/interface.ts (1) (1)
KnownHandlers
(3-5)
packages/hydrooj/src/model/document.ts (7)
packages/hydrooj/src/model/user.ts (1) (1)
coll
(22-22)packages/hydrooj/src/model/oplog.ts (1) (1)
coll
(8-8)packages/hydrooj/src/model/discussion.ts (1) (1)
coll
(43-43)packages/hydrooj/src/model/problem.ts (1) (1)
incStatus
(431-436)packages/hydrooj/src/model/token.ts (1) (1)
update
(53-71)packages/hydrooj/src/model/record.ts (1) (1)
update
(195-219)packages/hydrooj/src/service/monitor.ts (1) (1)
update
(76-89)
🪛 Biome (1.9.4)
packages/ui-default/backendlib/template.ts
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().
(lint/security/noGlobalEval)
packages/hydrooj/src/loader.ts
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/handler/misc.ts
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
framework/framework/server.ts
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
packages/hydrooj/src/handler/domain.ts
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/model/document.ts
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/ui-default/index.ts
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🪛 GitHub Check: CodeQL
build/prepare.js
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
🔇 Additional comments (148)
packages/hydrooj/src/handler/misc.ts (2)
17-17
: Added import reflects implementation detailsThe newly imported
sortFiles
function from '../utils' is correctly used in theFilesHandler.get()
method at line 38.
111-112
: Enhanced security with context-based link validationThe secret validation logic has been improved to use a dynamic context-based approach via
this.ctx.get('storage')?.isLinkValid?
, rather than a static calculation. This is a good architectural change that allows for more flexible security validation implementations.Ensure the
storage
service properly implements theisLinkValid
method with appropriate security measures.packages/hydrooj/src/interface.ts (6)
2-2
: Import for ParsedAuthenticatorData addedThis import is correctly added to support the updated type definition for authenticatorExtensionResults on line 83.
7-7
: RecordJudgeInfo import correctly addedThe RecordJudgeInfo import is now included to support the new RecordHistoryDoc interface definition. This change provides proper type safety.
83-83
: Type definition updated for Authenticator interfaceThe authenticatorExtensionResults property's type has been changed from AuthenticationExtensionsAuthenticatorOutputs to ParsedAuthenticatorData['extensionsData'], which provides more specificity and better type alignment with the library.
226-229
: New RecordHistoryDoc interface addedThe new interface extends RecordJudgeInfo and adds ObjectId properties for tracking record history. This is aligned with the addition to the Collections interface on line 552 and provides proper typing for the record history collection.
552-552
: New record.history collection added to Collections interfaceThis addition properly registers the record.history collection in the database schema, using the newly defined RecordHistoryDoc interface.
663-663
: Changed addons from array to Record structureThe type of the global addons variable has been changed from string[] to Record<string, string>, which improves lookup performance and allows associating metadata with each addon.
Make sure all code that previously accessed addons as an array has been updated. In particular:
- Check arrays accesses like
addons[i]
- Check loops like
for (const i of addons)
- Check methods like
addons.forEach
Run this script to verify:
#!/bin/bash # Find all places in the codebase where addons is accessed as an array rg "addons\[" --type=ts rg "\.forEach\(.*addons" --type=ts rg "for.*of.*addons" --type=tsbuild/prepare.js (8)
18-22
: Modernized TypeScript configuration for ES2022 and bundler modeThe compiler options have been updated to use newer JavaScript features (ES2022) and a different module resolution strategy ('bundler'). These changes align with modern development practices and will allow using newer JavaScript features.
37-37
: New UI-next reference addedThe addition of the 'tsconfig.ui-next.json' reference indicates support for a new UI package, which is consistent with the later addition of the UINextConfig.
78-78
: Improved filter condition for modulesThe filter condition has been updated to exclude both 'ui-default' and 'ui-next' directories using a more concise approach with
some()
.
83-87
: Additional file exclusions for UI-defaultThese specific file exclusions suggest a reorganization of the UI package structure, possibly moving functionality to the new UI-next package or refactoring the codebase.
100-120
: Updated React JSX transform and bundler configurationThe JSX transform has been updated from 'react' to 'react-jsx', which uses React 17's new JSX transform. This change, along with the bundler mode options and additional linting rules, modernizes the build configuration.
123-161
: New UI-next TypeScript configurationA comprehensive configuration for the new UI-next package has been added with appropriate settings for a modern React application, including strict type checking and path aliases.
189-189
: Added skipLibCheck to plugins configurationAdding
skipLibCheck: true
to the plugins configuration will improve build performance by skipping type checking of declaration files in dependencies.
197-225
: Optimized file updates with tryUpdate functionThe script now uses the new
tryUpdate
function consistently throughout the file to only write configuration files when their content has changed. This improves performance by avoiding unnecessary file writes.packages/hydrooj/src/model/setting.ts (9)
3-3
: Update import path from cordis to @cordisjs/coreThe import path has been updated from 'cordis' to '@cordisjs/core', which reflects a framework upgrade. This change appears consistent with the module declaration update on line 359.
7-7
: Action Required: Add "schemastery" to project dependenciesThe import of
Schema
fromschemastery
is appropriate given its usage in the file. However, our verification shows thatschemastery
is not currently listed under eitherdependencies
ordevDependencies
in yourpackage.json
(both returnednull
). To ensure best practices and avoid potential runtime errors, please addschemastery
as a dependency in your project.#!/bin/bash # Verify if schemastery is included in the package dependencies cat packages/hydrooj/package.json | jq '.dependencies.schemastery, .devDependencies.schemastery'
73-80
: Added type declaration for Schemastery namespaceGood addition of the global namespace declaration for Schemastery with the Meta interface. This provides proper type information for the schema metadata used throughout the file.
121-122
: Enhanced setting functions to accept Schema objectsGood refactoring of setting functions to accept either traditional
_Setting
arrays or newSchema
objects. This provides flexibility while maintaining backward compatibility with existing code.The use of
flatMap
to process the settings is clean and efficient. This change makes it easier to define settings with the new Schema-based approach.Also applies to: 141-142, 161-162, 177-178, 193-194
290-318
: Well-implemented Schema-based setting definitionsThe new Schema-based approach for defining system settings is a good improvement over the previous approach. It provides better type safety, structure, and self-documentation through the schema metadata.
This implementation serves as a good example for how other settings can be migrated to use the Schema-based approach in the future.
359-359
: Updated module declaration pathThe module declaration has been updated from 'cordis' to '@cordisjs/core', which is consistent with the import change on line 3.
388-388
: Added dependency injection for dbGood practice adding explicit dependency injection for the database dependency. This makes the dependencies clearer and easier to manage.
395-395
: Switched to context-based db accessGood change from using the global database reference (
global.Hydro.service.db
) to using the context-based reference (ctx.db
). This improves modularity and testability by making the database dependency explicit.
419-420
: Added inject to the exported modelProperly exported the inject constant in the global model, maintaining consistency with the dependency injection pattern introduced earlier.
packages/utils/lib/utils.ts (6)
10-10
: Updated import structure for logger implementationThe import statement has been modified to bring in
Exporter
,Factory
, and renameLogger
toReggol
from the 'reggol' package. This aligns with the new factory-based approach to logger creation.
15-16
: Factory implementation for logger creationIntroducing a factory pattern for logger creation is a good design choice that improves modularity and configurability.
17-27
: Centralized logger configurationThe implementation properly configures the logger with specific settings like time format, label width, and appropriate log levels based on the environment. This is more maintainable than directly manipulating logger properties.
29-31
: Added logger creation functionThe
createLogger
function encapsulates the factory usage, which is a good abstraction that simplifies logger creation throughout the codebase.
35-35
: Export statement preservedPreserving the moment export is appropriate since it wasn't targeted for refactoring.
33-34
:❓ Verification inconclusive
Verify the circular type definition and type assertion
The
Logger
type definition appears circular (it references itself), and the export uses a double type assertion (as any as Logger
), which bypasses TypeScript's type checking.While this may work as intended, consider if a cleaner type structure could be implemented to avoid potential type-related issues.
🏁 Script executed:
#!/bin/bash # Search for usages of Logger to ensure this type definition works correctly echo "Checking Logger usage patterns..." rg "new Logger\(" --type ts rg "Logger\(" --type ts rg "import.*Logger.*from.*utils" --type tsLength of output: 8671
Action: Revisit the Logger type definition for potential refactoring
The usage of
Logger
across the codebase (e.g., via expressions likenew Logger(...)
) confirms that its current structure is working as intended. However, note that:
- The type definition is self-referential—
Logger
extendsReggol
and includes a constructor signature that returns aReggol & Logger
. While this pattern enables the factory behavior, it is inherently circular.- The export uses a double type assertion (
as any as Logger
), which bypasses TypeScript’s type checking and may obscure potential type mismatches.Although these approaches function currently, consider whether you can refactor to a cleaner type structure. For instance, explicitly separating the instance type from its constructor signature (or properly typing
createLogger
) might improve type safety and maintainability.packages/hydrooj/src/loader.ts (13)
15-17
: Improved imports from context moduleThe import has been updated to include more specific entities from the context module:
Context
,Service
,ScopeStatus
, andEffectScope
. This change improves type safety by explicitly importing the required types.
22-22
: Added Schema import for configuration handlingThe import of the Schema library from 'schemastery' was added to support the new schema-based configuration resolution implemented in the
resolveConfig
method.
48-48
: Enhanced type safety for state propertyThe state property type has been properly defined as
Record<string, EffectScope>
using the imported EffectScope type, improving type safety.
54-55
: Explicit dependency declarationThe static inject property now explicitly declares all required dependencies: 'config', 'timer', 'i18n', and 'logger'. This is good practice for dependency injection and makes the dependencies clearer.
56-57
: Updated constructor to use Context parameterThe constructor now takes a
ctx
parameter of typeContext
instead ofapp
, and passes both the context and service name to the superclass constructor. This aligns with the dependency injection pattern and makes the service name explicit.
59-60
: Updated event listener to use ctx directlyThe event listener for 'app/started' now uses
ctx
directly and provides an async callback for the interval function. This is consistent with the constructor changes and properly handles asynchronous operations.
98-107
: Added schema-based configuration resolutionThe new async
resolveConfig
method properly implements schema-based configuration resolution using the Schema library. It creates a schema request based on the providedconfigScope
, attempts to migrate the configuration, and returns the appropriate config object.This implementation is more robust than the previous approach and provides better validation for configurations.
109-117
: Improved plugin reloading with async supportThe
reloadPlugin
method has been updated to be async and now takes aconfigScope
parameter. It uses the newresolveConfig
method to retrieve the plugin configuration and properly handles the plugin application throughthis.ctx.plugin
.The template string for logging has been updated to conditionally include the configScope information, which improves log readability.
135-136
: Enhanced error loggingError logging in the
resolvePlugin
method has been improved to provide more detailed error information, which will be helpful for debugging plugin resolution issues.
147-152
: Async preload function with proper dependency injectionThe
preload
function has been updated to be async and now initializesglobal.app
by awaiting a promise that resolves after injecting the necessary dependencies. This ensures that the app is fully initialized before proceeding.
161-161
: Updated global addons assignmentThe assignment to
global.addons
has been simplified but maintains the same functionality.
170-171
: Proper awaiting of preload functionThe
load
function now properly awaits thepreload
function, ensuring that all initialization is complete before proceeding with the rest of the loading process.
208-210
: Consistent async handling in loadCliThe
loadCli
function now also awaits thepreload
function, maintaining consistency with theload
function and ensuring proper initialization before CLI operations.eslint.config.mjs (2)
42-52
: Good practice usingsimple-import-sort/imports
.This plugin effectively enforces a standardized import order. Ensure developers are aware of this sorting convention and consider adding an auto-fix script or CI check to maintain consistent import sorting across the codebase.
110-120
: Confirm the correctness of disabled rules.Options like
'function-paren-newline': 'off'
,'no-lonely-if': 'off'
, and'no-await-in-loop': 'off'
can hide potential readability or performance pitfalls. If any of these rules is relevant to your codebase (e.g., avoiding blocking awaits in loops), you may want to re-enable them or enforce them with a warning level for better maintainer awareness.framework/eslint-config/package.json (2)
5-5
: Validate new main entry.Switching
"main": "base.mjs"
is sensible if you intend to load this ESLint configuration by default. Verify that all references and import paths that relied on the oldreact.yaml
entry are updated to avoid broken references.
26-27
:❓ Verification inconclusive
Confirm TypeScript 5.8.2 stability.
You’ve introduced
"typescript": "^5.8.2"
as an optional dependency. If the codebase relies on features unique to that version, ensure your CI pipeline covers TypeScript 5.8.2–specific tests. For a deeper review:
🏁 Script executed:
#!/bin/bash # Attempting to verify if TypeScript 5.8.2 is compatible with the rest of the codebase. # We'll parse any references to "typescript" in the repository and see if conflicting versions exist. fd -t f --exec rg "typescript" {}Length of output: 4873
Confirm TypeScript 5.8.2 Compatibility in CI
Your package now lists
"typescript": "^5.8.2"
as an optional dependency. The repository output shows multiple references using version strings like^5.8.2
,~5.8.2
, and even an explicit"5.8.2"
, which appear consistent. However, it's not clear whether the CI pipeline is set up to exercise tests that specifically target TypeScript 5.8.2 features. Please ensure that:
- The CI configuration explicitly covers scenarios where TypeScript 5.8.2–specific behavior is exercised.
- No conflicting version constraints exist elsewhere that might inadvertently pull a different TypeScript release.
Reviewing the CI settings for TypeScript-related tests will help safeguard stability.
packages/hydrooj/src/model/opcount.ts (1)
16-16
: MongoDB driver result access pattern updatedThis change updates how the operation count is accessed from MongoDB's findOneAndUpdate result. The code now directly accesses
res.opcount
instead of the previousres.value.opcount
, aligning with newer MongoDB driver versions (4.x+) where documents are returned directly rather than nested in avalue
property.packages/hydrooj/src/model/task.ts (3)
9-9
: Updated bus import to use default importThe import statement has been changed from namespace import to default import, aligning with module refactoring across the codebase.
22-24
: Updated MongoDB result handling patternThe code now checks
res
directly instead ofres.value
, matching the updated MongoDB driver pattern. This change ensures consistency with other model files and newer MongoDB driver behavior.
184-186
: Updated event handling logicThe event logging and handling has been simplified to directly check
res
instead ofres.value
. This maintains consistent MongoDB result handling across the codebase.packages/hydrooj/src/model/oauth.ts (1)
18-18
: MongoDB result access pattern updatedChanged from accessing
res.value?.uid
to directly accessingres?.uid
, aligning with the MongoDB driver update pattern seen across the codebase. This ensures consistent handling of database operation results.packages/hydrooj/src/model/blacklist.ts (1)
16-21
: Simplified return statement for MongoDB operationThe method now directly returns the result of the database operation instead of storing it in an intermediate variable and returning
res.value
. This change is consistent with the updated MongoDB driver result handling pattern throughout the codebase.packages/hydrooj/src/model/record.ts (5)
2-2
: Added lodash.pick for record history implementation.The
pick
function from lodash is imported to selectively extract specific fields from record documents before storing them in the history collection. This is a good practice for optimizing storage by keeping only the essential data in history records.
23-23
: New collection for record history tracking.Adding a static
collHistory
collection to store historical versions of records is a good design for maintaining an audit trail of changes. This enables features like viewing previous submissions or tracking record modifications.
235-237
: Replacedinstanceof Array
withArray.isArray()
.This is an important safety improvement.
Array.isArray()
is the preferred method as it correctly detects arrays from different execution contexts, whileinstanceof Array
may return false for array-like objects or arrays from different contexts.
250-264
: Implemented record history preservation.Good implementation of record history preservation that fetches records before deletion, extracts relevant fields using
pick()
, and stores them in the history collection with a new ObjectId. This approach ensures that important record data is preserved even after resets or rejudges.
283-283
: Updated apply function to async and added index for record history.The function has been correctly updated to be asynchronous, and proper indexes have been created for the new
collHistory
collection to optimize query performance. The index on{ rid: 1, _id: -1 }
will efficiently support queries filtering by record ID and sorting by insertion time.Also applies to: 307-327
packages/hydrooj/src/model/contest.ts (4)
12-12
: Changed bus import to default import.Switched from namespace import (
import * as bus
) to default import (import bus
), which indicates the module has been refactored to use a default export pattern. This is part of the broader codebase modernization effort.
292-294
: Improved object immutability with spread operator.Using the spread operator to create shallow copies of objects instead of direct assignment prevents unintended modifications to the original objects. This is a good practice for maintaining immutability and avoiding side effects.
360-360
: Enhanced tsddict condition to account for locked contests.The condition for determining
tsddict
now includes a check for whether the contest is locked, which improves the logic for handling contest states. This ensures correct display of contest details based on the current state.
388-388
: Added optional chaining for timestamps.The code now uses optional chaining for
startAt
andbeginAt
, ensuring that the code safely handles cases where these properties might be undefined. This improves robustness and prevents potential runtime errors.Also applies to: 405-406
packages/ui-default/backendlib/template.ts (6)
25-42
: Added async file utilities for template management.The new
getFiles
andlocateFile
functions provide better file handling capabilities with async/await patterns. ThegetFiles
function recursively collects files from directories, whilelocateFile
efficiently finds files from a list of possible filenames. These utilities improve the file discovery and management process.
44-57
: Enhanced Nunjucks runtime with improved member lookup.The custom implementation of
memberLookup
adds support for original function references and proper handling of undefined/null objects. This improves the template engine's ability to access object properties and methods safely.🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
161-177
: Good implementation of service-oriented architecture.The new
TemplateService
class follows good service-oriented design practices with dependency injection and proper event handling. The staticinject
property clearly defines dependencies, and the constructor properly sets up event handlers for template rendering.
183-218
: Well-designed custom Loader implementation.The Loader class efficiently handles template resolution with fallback mechanisms. It first checks the registry for cached templates and then checks the filesystem in development mode. The error handling is appropriate with clear error messages when templates cannot be found.
221-252
: Missing timeout handling in render function.The render function logs slow renders (>5000ms) but lacks a timeout mechanism to prevent long-running renders from blocking the server.
Add a timeout mechanism to prevent extremely long-running renders:
const render = (name: string, state: any) => new Promise<string>((resolve, reject) => { const start = Date.now(); + const renderTimeout = setTimeout(() => { + reject(new Error(`Render timeout for template ${name}`)); + }, 10000); // 10 seconds timeout + env.render(name, { page_name: name.split('.')[0], ...state, formatJudgeTexts: (texts) => texts.map((text) => { if (typeof text === 'string') return text; return state._(text.message).format(...text.params || []) + ((process.env.DEV && text.stack) ? `\n${text.stack}` : ''); }).join('\n'), datetimeSpan: (arg0, arg1, arg2) => misc.datetimeSpan(arg0, arg1, arg2, state.handler.user?.timeZone), ctx: state.handler?.ctx, perm: PERM, PRIV, STATUS, UiContext: state.handler?.UiContext || {}, }, (err, res) => { + clearTimeout(renderTimeout); const end = Date.now(); if (end - start > 5000) console.error(`Render of ${name} took ${end - start}ms`); if (err) reject(err); else resolve(res || ''); }); });
254-275
: Good error handling for template initialization.The
[Context.init]
method properly handles template loading with good error handling. It notifies users of template loading failures, which improves user experience and helps with debugging. The use of a logger for both successful and failed operations provides good visibility into the initialization process.packages/hydrooj/src/entry/worker.ts (5)
9-10
: Improved service imports with specific service classes.Using explicit imports of
MongoService
andConfigService
instead of importing entire modules improves code readability and can lead to better tree-shaking by bundlers.
24-34
: Enhanced database initialization with async/await pattern.The refactored code uses an async/await pattern to get the MongoDB URL and initialize services. This is a better approach than the previous synchronous loading, as it allows for proper error handling and ensures that components are initialized in the correct order.
36-51
: Improved dependency management with Promise-based injection.Using Promises with the dependency injection system ensures that required dependencies are fully loaded before proceeding. This prevents issues where code might try to use services that aren't fully initialized.
61-76
: Consistent use of dependency injection pattern.The consistent application of the dependency injection pattern throughout the initialization process improves code maintainability and ensures proper service lifecycle management. The approach of waiting for dependencies to be available before proceeding with initialization is good practice.
96-102
: Streamlined server startup with dependency injection.The server startup process is now managed through the dependency injection system, which provides a cleaner and more maintainable approach compared to direct function calls. The proper sequencing of events (
listen
→app/listen
→app/ready
) ensures that all components are properly initialized.packages/hydrooj/src/service/db.ts (7)
7-7
: Good job updating imports for better clarity and organization.The change from importing bus as a namespace to a default import aligns with modern ES module practices and improves code readability.
29-33
: Excellent type enhancement to Context interface.Adding
db: MongoService
property to the Context interface improves type safety and makes database dependencies explicit throughout the application.
35-41
: Good restructuring with dependency injection pattern.The change to extend Service and accept a Context parameter in the constructor follows proper dependency injection patterns, making the code more testable and modular.
43-56
: Well-implemented static method for URL resolution.The static
getUrl
method nicely encapsulates the logic for retrieving the MongoDB connection URL, with special handling for CI environments using in-memory MongoDB.
58-66
: Excellent use of generator functions for resource management.The async generator method with
[Context.init]
that yields a cleanup function is a great pattern for resource management. The client.close() callback ensures proper cleanup when the service is shut down.
69-70
: Good refactoring of collection method.Using the config properties for prefix and collection mapping provides more flexibility in how collections are named and accessed.
182-189
: Appropriate use of deprecation pattern with proxy.The deprecated proxy object provides backward compatibility while guiding users to use the new context-based approach. This is a good transitional pattern.
packages/hydrooj/src/model/schedule.ts (2)
7-7
: Good update to import type from default export.Updated import statement for WorkerService reflects the change to a default export in the worker.ts file.
18-25
: Simplified result handling logic.The updated code directly uses the result object rather than accessing through
.value
property, which aligns with the updated MongoDB driver response format.packages/hydrooj/src/service/worker.ts (2)
12-12
: Good conversion to default export.Converting to a default export simplifies imports and is consistent with the module pattern being adopted across the codebase.
32-39
: Consistent result handling with schedule.ts.The result handling has been updated consistently with the changes in schedule.ts, properly accessing properties directly from the result object.
packages/hydrooj/src/service/bus.ts (5)
4-5
: Improved type import for better type safety.Importing the Handler type from framework package improves type consistency across the codebase.
17-17
: Simplified EventMap interface definition.Removing extension from KnownHandlerEvents simplifies the event typing system and makes it more maintainable.
32-32
: Enhanced type safety for broadcast event.Updating the 'bus/broadcast' event type to reference only 'keyof EventMap' improves type checking when broadcasting events.
87-87
: Improved handler type specificity.Specifying 'Handler' for the oplog/log event handler type ensures handlers have the appropriate context access.
115-116
: Simplified export structure.Exporting only the app simplifies the module interface and aligns with the single responsibility principle.
packages/elastic/index.ts (5)
4-4
: No immediate concerns.
The import statement is correct and helps define the necessary types needed for the service.
20-25
: Configuration schema is well-defined
This helps ensure consistent usage of theurl
andindexSize
properties across the service.
34-69
: Add explicit type annotations for theopts
parameter
Explicit type annotations for theopts
parameter will enhance type safety and code readability.
72-79
: Add proper type annotation for therun
method parameters
Consider specifying types fordomainId
andreport
to enhance readability and ensure type safety.
95-125
: Add error handling for event-driven operations
Consider wrapping each of these event callbacks in a try-catch to handle potential exceptions, preventing unhandled promise rejections.packages/hydrooj/src/settings.ts (13)
3-3
: Import statements are fine.
No issues with the new import.
8-10
: Context augmentation seems correct
This ensures thatconfig
is accessible onContext
.
26-29
: No concerns
Constructor is straightforward.
30-34
: Ensure config documents exist
If there's no 'config' document, handle the case gracefully. Currently, your code logs an error but won't break the flow, which is good.
36-38
: Valid usage of schema intersection
Ensures the system config is validated against all registered settings.
40-53
: Robust error handling
The try-catch block ensures you handle parsing errors gracefully.
55-67
: Double-check deep object merges
The logic here clones the source and modifies the path. For more complex merges, be sure this approach does not inadvertently override nested properties.
69-77
: Leverage set-level validations
This approach is fine, but consider referencing any additional constraints (e.g., type constraints or custom validation logic).
79-84
: Effective approach to persist & reload config
This helps ensure the config changes are validated and persisted consistently.
109-112
: Sequential migration chain is well-handled
Ensures migrations don't overlap and cause inconsistent states.
114-123
: Defensive checks look good
Rejecting blacklisted paths helps prevent prototype pollution.
125-128
: Method is straightforward
CombinesapplyDelta
andsaveConfig
for easy property updates.
130-171
: Surface DB write errors in the Proxy setter
Consider an asynchronous approach or error handling to ensure DB write errors are not silently ignored.packages/hydrooj/src/model/domain.ts (5)
4-4
: Import of Context
No issues with adding the new import.
6-6
: No issue with bus import
This is consistent with other references to bus in the file.
62-62
: Ensuring owners are assigned root role by default
This is a reasonable approach for domain creation.
130-133
: Filtering byjoin: true
This ensures only actively joined domain users are counted.
257-259
: Usingjoin: true
This logic ensures only domain entries with joined status are retrieved.packages/hydrooj/src/entry/common.ts (4)
25-45
: API migration from array to Record improves type safety.The
getLoader
function has been refactored to:
- Remove the
dontLoad
parameter- Change
pending
from an array of strings to a Record of string key-value pairs- Update iteration logic to use
Object.entries
instead of directly iterating over the arrayThese changes improve type safety and clarity in how plugins are loaded and referenced.
56-57
: Simplified reloadPlugin call signature.The call to
ctx.loader.reloadPlugin
has been updated to remove the empty object parameter, which aligns with the similar change in theloader
function. This simplifies the API surface.
60-81
: Updated locale function to use Record instead of array.The
locale
function has been updated to accept a Record instead of an array for thepending
parameter, and iteration has been updated to useObject.values
. This is consistent with the changes to thegetLoader
function.
83-122
: Updated setting function to use Record instead of array.The
setting
function has been updated similar tolocale
, accepting a Record instead of an array for thepending
parameter and updating iteration to useObject.values
. This maintains consistency across the codebase.packages/ui-default/index.ts (5)
3-4
: Dependency replacement for better modularity.The import of
SystemSettings
has been removed in favor of using context-based settings, and a new import forTemplateService
has been added. This change improves modularity by leveraging dependency injection.Also applies to: 7-7
25-25
: Added explicit type for improved type safety.The
sections
variable now has an explicit type definition, enhancing code readability and type safety.
56-56
: Remove the empty object pattern.Static analysis flags
{ }
as an unexpected empty pattern. Consider removing it as it doesn't serve any purpose.- async get({ }, legacy = false, nohint = false) { + async get(legacy = false, nohint = false) {🧰 Tools
🪛 Biome (1.9.4)
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
77-78
: Updated schema generation to use context-based settings.The schema is now generated using
this.ctx.config.settings
instead of the previously importedSystemSettings
, which aligns with the dependency changes and context-based architecture.
167-168
: Replaced dynamic import with direct service reference.The dynamic import of the template module has been replaced with direct use of
TemplateService
, which improves code readability and performance.packages/hydrooj/package.json (3)
3-3
: Major version bump for Hydro v5.The version has been updated from
4.19.1
to5.0.0-alpha.0
, indicating a major version change with breaking API changes. This aligns with the PR title "Hydro v5".
19-21
: Migrated from monolithic to modular dependencies.Replaced
cordis
dependency with more modular@cordisjs/*
packages:
@cordisjs/core
@cordisjs/logger
@cordisjs/plugin-timer
This promotes better architecture by using more granular, focused packages.
22-58
:✅ Verification successful
Updated multiple dependency versions.
Multiple dependencies have been updated to newer versions, which may include bug fixes, performance improvements, and new features. Note that some versions are alpha/beta releases, which is consistent with the package itself being marked as alpha.
🏁 Script executed:
#!/bin/bash # Check for any potentially incompatible dependency updates echo "Checking graphql-scalars update from <1.24.2:" npm view graphql-scalars@^1.24.2 version echo -e "\nChecking mongodb update from <6.15.0:" npm view mongodb@^6.15.0 version echo -e "\nChecking nanoid update from <5.1.5:" npm view nanoid@^5.1.5 version echo -e "\nChecking superagent update from <10.2.0:" npm view superagent@^10.2.0 versionLength of output: 559
Dependency Updates Verified
- The dependency versions in
packages/hydrooj/package.json
have been successfully updated.- Verification confirms that:
graphql-scalars
is now at 1.24.2mongodb
is now at 6.15.0nanoid
is now at 5.1.5superagent
is now at 10.2.0- These updates align with expectations, and the note regarding alpha/beta releases remains applicable given the package's alpha status.
packages/hydrooj/src/handler/domain.ts (5)
105-147
: Refactored to use MongoDB aggregation pipeline for more efficient queries.The user retrieval logic has been improved with an aggregation pipeline that:
- Filters users by role (excluding 'default' and 'guest')
- Joins with user collection to retrieve essential user data (username, avatar)
- Projects only necessary fields
This approach is more efficient than separate queries and reduces the amount of data transferred.
258-258
: Simplified role filtering logic.The filter has been updated to exclude only the 'guest' role, rather than both 'default' and 'guest'. This allows users with the 'default' role to be considered in role assignments.
322-337
: Enhanced domain join preparation with target parameter.The
prepare
method has been updated to:
- Accept a
target
parameter, making it more flexible- Check if the user is already a member of the domain
- Retrieve roles based on the specified target domain
- Determine assigned role based on user privileges
This improves flexibility and makes the domain joining process more robust.
🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
339-358
: Improved domain join flow with redirect support.The
get
method now:
- Accepts
target
andredirect
parameters for more flexible navigation- Includes detailed domain information in the response
- Improves the user experience by providing more context about the domain being joined
This enhances usability and provides a clearer joining experience.
360-377
: Enhanced post-join behavior with flexible targeting and redirection.The
post
method has been updated to:
- Support joining a specific target domain rather than just the current domain
- Conditionally assign roles based on join settings
- Redirect to a specified URL after successful join
This provides a more configurable and user-friendly domain joining workflow.
packages/hydrooj/src/model/document.ts (6)
12-12
: Default import used instead of namespace import.The import statement has been changed from
import * as bus from '../service/bus'
toimport bus from '../service/bus'
. This suggests that the bus module now exports a default value instead of multiple named exports.
18-18
: New type utility added to exclude symbol keys.The
NormalArrayKeys<O, P = any>
type utility has been introduced to exclude symbol keys from array keys, enhancing type safety when working with array properties.
23-33
: Enhanced type safety with const assertions.The constant declarations have been updated to use TypeScript's
as const
assertion instead of explicit type annotations. This change ensures that the constants are treated as literal types, providing better type inference and type safety throughout the codebase.
112-117
: Code simplified by directly returning promise.The function now directly returns the result of the database operation instead of using an intermediate variable. This is a good simplification without changing behavior.
152-157
: Consistently returning database operation promises directly.Multiple methods in the file have been updated to directly return database operation promises instead of using intermediate variables. This pattern is applied consistently throughout the file, making the code more concise and easier to read.
Also applies to: 163-168, 211-217, 224-230, 255-265, 301-311, 328-333, 358-363, 369-374, 385-392, 397-402, 410-411
385-392
: Improved conditional assignment with nullish assignment operator.The code now uses the nullish assignment operator (
||=
) instead of a separate conditional block, which is a more concise way to handle the fallback case while maintaining the same behavior.framework/framework/server.ts (12)
5-5
: Updated import to use CordisContext.The import has been changed from Context to CordisContext from the @cordisjs/core package, indicating a shift in the underlying framework architecture.
44-52
: Added utility for context isolation and lifecycle management.The new
forkContextWithScope
function creates an isolated context with its own lifecycle, which enhances the ability to manage resources and handle cleanup properly. The function uses the newerSymbol.asyncDispose
feature for asynchronous resource management.
140-141
: Enhanced type safety with generic context type parameters.The handler classes and service now use generic type parameters for context, which allows for more flexible context handling while maintaining type safety. The static handler identifier is also consistently initialized.
Also applies to: 210-212, 258-260, 297-300, 337-338, 352-353
🧰 Tools
🪛 Biome (1.9.4)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
487-489
: Using structured binding and resource management with 'using' declaration.The code now uses the
using
declaration withawait forkContextWithScope
to ensure proper resource cleanup through theSymbol.asyncDispose
interface, which is a safer way to manage asynchronous resources.
491-492
: More robust handler name detection.The handler name detection now uses
Object.hasOwn
and proper type checking to safely access the handler identifier, improving reliability when working with prototype chains.
599-613
: Improved connection cleanup logic.The connection cleanup logic has been significantly improved with better error handling, resource cleanup, and state management. The function now checks for the closed state to prevent multiple cleanup attempts and properly handles various cleanup scenarios.
635-653
: Enhanced WebSocket message handling.The WebSocket message handling has been improved with better error handling and proper JSON parsing with error recovery. The code now properly handles ping/pong messages and ensures that connection state is maintained.
744-750
: Updated type signature for Route handlers.The Route method now correctly specifies that RouteHandler should be of type
typeof Handler<C>
instead ofany
, improving type safety for route registration.
753-755
: Updated type signature for Connection handlers.The Connection method now correctly specifies that RouteHandler should be of type
typeof ConnectionHandler<C>
instead ofany
, improving type safety for WebSocket connection handlers.
787-810
: Added robust mixin application utility.The new
_applyMixin
method provides a more structured approach to extending handler functionalities with proper lifecycle management. It correctly handles property existence checks, restoration of original values on cleanup, and warning about potential conflicts.
812-828
: Added specialized mixin methods for different handler types.The new specialized mixin methods (
applyMixin
,handlerMixin
,httpHandlerMixin
,wsHandlerMixin
) provide type-safe ways to extend different handler types, enhancing the extensibility of the framework.However, the implementation for
wsHandlerMixin
previously had an issue where it wasn't actually assigning properties. Verify that this is now correctly using the_applyMixin
method which properly assigns properties.
841-848
: Updated module declaration with proper generic types.The module declaration has been updated to reflect the generic context type used throughout the file, ensuring that type safety is maintained when extending the Context interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (8)
build/prepare.js (1)
163-167
:⚠️ Potential issueFix potential file system race condition
The
tryUpdate
function has a potential race condition between checking if a file exists and reading it. If the file is deleted between these operations, it could cause errors.Consider using a try-catch approach instead:
const tryUpdate = (location, content) => { - const current = fs.existsSync(location) ? fs.readFileSync(location, 'utf-8') : ''; + let current = ''; + try { + current = fs.readFileSync(location, 'utf-8'); + } catch (err) { + // File doesn't exist or cannot be read + } const expected = typeof content === 'string' ? content : JSON.stringify(content, null, 2); if (expected !== current) fs.writeFileSync(location, expected); };🧰 Tools
🪛 GitHub Check: CodeQL
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.framework/framework/server.ts (2)
139-140
:⚠️ Potential issueFix unsafe declaration merging.
The empty interface
HandlerCommon<C>
followed by a class with the same name creates unsafe declaration merging, which TypeScript doesn't fully validate. This pattern is flagged by static analysis tools.Either remove the empty interface or convert it to a type alias:
-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars +// Use a type alias if you need to extend the class externally +export type HandlerCommonProps<C> = {}; export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
705-705
:⚠️ Potential issueFix condition that always evaluates to false.
Static analysis indicates the
if (perm)
condition always evaluates to false.Verify the initialization of
perm
in theChecker
function:return function check(this: Handler<C>) { checker(); - if (perm) this.checkPerm(perm); + if (perm !== undefined) this.checkPerm(perm); if (priv) this.checkPriv(priv); };packages/hydrooj/src/handler/misc.ts (1)
124-124
:⚠️ Potential issueAddress the empty object pattern in parameter list.
Similar to the previous instance, the empty object pattern in the parameter list should be addressed to improve code clarity and avoid static analysis warnings.
🧰 Tools
🪛 Biome (1.9.4)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/elastic/index.ts (2)
34-34
:⚠️ Potential issueAdd proper type annotation for the opts parameter.
The
opts
parameter is missing a type annotation. Without proper typing, this reduces type safety and makes the code more prone to errors.Consider defining an interface or using a more specific type:
-async problemSearch(domainId: string, q: string, opts): ReturnType<ProblemSearch> { +async problemSearch(domainId: string, q: string, opts: { limit?: number; skip?: number }): ReturnType<ProblemSearch> {
72-72
:⚠️ Potential issueAdd proper type annotations for the run method parameters.
The parameters in the
run
method lack proper type annotations, which reduces type safety and makes the code more difficult to understand and maintain.packages/hydrooj/src/settings.ts (2)
55-67
:⚠️ Potential issuePotential prototype pollution risk persists
While you've implemented a blacklist check on line 57, there's still a potential prototype pollution risk at line 65 when setting
cursor[t] = value
. The blacklist approach helps but static analysis tools still flag this as a risk.Consider using a safer approach with a specialized library like lodash's
_.set()
or implementing additional checks:- cursor[t] = value; + if (Object.prototype.hasOwnProperty.call(cursor, t) || !Object.prototype.hasOwnProperty.call(Object.prototype, t)) { + cursor[t] = value; + }
164-167
:⚠️ Potential issueFire-and-forget in Proxy setter still exists
The
set
trap is not awaiting the asyncsetConfig
method, which means errors in the database operation will be silently ignored.- set(self, p: string | symbol, newValue: any) { - that.setConfig(path.concat(p).join(','), newValue); - return true; - }, + async set(self, p: string | symbol, newValue: any) { + try { + await that.setConfig(path.concat(p).join(','), newValue); + return true; + } catch (err) { + console.error('Failed to update config:', err); + return false; + } + },
🧹 Nitpick comments (11)
packages/utils/lib/utils.ts (2)
15-27
: Consider addressing potential issues in logger factory configurationThe factory pattern implementation is a good improvement for logger management, but there are a couple of concerns:
- The timestamp is set using
Date.now()
which will be evaluated once when the module loads, creating a static timestamp rather than a dynamic one.- There's a magic number in
factory.exporters.get(1)
- is this intentional? The exporter was just added, so normally it would be at index 0.factory.addExporter(new Exporter.Console({ showDiff: false, showTime: 'dd hh:mm:ss', label: { align: 'right', width: 9, margin: 1, }, - timestamp: Date.now(), + timestamp: () => Date.now(), // Make timestamp dynamic if that's the intention })); -factory.exporters.get(1).levels = { default: process.env.DEV ? 3 : 2 }; +// Get the exporter by reference or use an explicit index with a comment explaining why index 1 +const consoleExporter = factory.exporters.get(factory.exporters.size - 1); // Get the exporter we just added +consoleExporter.levels = { default: process.env.DEV ? 3 : 2 };
33-34
: Consider avoiding the use ofany
type assertionThe type definition for Logger is well structured to support both instance methods and constructor usage. However, the double type assertion with
any
bypasses TypeScript's type checking, which could hide potential type errors.export type Logger = Reggol & { new(name: string): Reggol & Logger }; -export const Logger = createLogger as any as Logger; +// Consider a more type-safe approach if possible +export const Logger = createLogger as unknown as Logger;Using
unknown
instead ofany
requires an explicit type check before using the value, which can help catch potential type errors. If this cast is necessary due to TypeScript limitations, consider adding a comment explaining why.packages/hydrooj/src/handler/domain.ts (2)
150-157
: Consider performance impact of the delete operatorThe
delete
operator at line 155 may have a small performance impact. While functionally correct, consider an alternative approach for better performance.const users = dudocs.map((dudoc) => { - const u = { - ...dudoc, - ...dudoc.user, - }; - delete u.user; - return u; + const { user: userData, ...rest } = dudoc; + return { ...rest, ...userData }; });🧰 Tools
🪛 Biome (1.9.4)
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
335-335
: Consider performance impact of the delete operatorSimilar to the earlier instance, the
delete
operator may have a performance impact. Consider using conditional assignment instead.- if (assignedRole !== 'default') delete this.joinSettings; + if (assignedRole !== 'default') this.joinSettings = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/ui-default/backendlib/template.ts (3)
46-47
: Use optional chaining for cleaner code.The current null check could be simplified with optional chaining for better readability.
-if ((obj || {})._original) obj = obj._original; +if (obj?._original) obj = obj._original;🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
25-34
: Consider optimizing file search for large directoriesThe
getFiles
function recursively scans directories which can be inefficient for large directory structures. Consider implementing a more efficient approach using streams or by limiting recursion depth.async function getFiles(folder: string, base = ''): Promise<string[]> { const files: string[] = []; const f = await fs.readdir(folder); + // Consider adding a depth limit to prevent excessive recursion + const MAX_DEPTH = 10; + const currentDepth = base.split('/').length; + + if (currentDepth > MAX_DEPTH) { + console.warn(`Maximum directory depth reached at ${folder}`); + return files; + } for (const i of f) { if ((await fs.stat(path.join(folder, i))).isDirectory()) { files.push(...await getFiles(path.join(folder, i), path.join(base, i))); } else files.push(path.join(base, i)); } return files.map((item) => item.replace(/\\/gmi, '/')); }
164-165
: Add explicit type for registry propertyThe
registry
property should have a more explicit type definition to improve code maintainability and type safety.- registry: Record<string, string> = {}; + registry: Record<string, string | undefined> = {};packages/hydrooj/src/model/document.ts (1)
223-223
: UseArray.isArray()
instead ofinstanceof Array
.
instanceof Array
can return false for arrays from different execution contexts and for array-like objects.Array.isArray()
is more reliable.- subId = (subId instanceof Array) ? subId : [subId]; + subId = Array.isArray(subId) ? subId : [subId];🧰 Tools
🪛 Biome (1.9.4)
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
packages/hydrooj/src/loader.ts (2)
48-49
: Type improvement needed for config propertyWhile you've properly typed the state property with Record<string, EffectScope>, the config property uses an empty object type {}, which is considered a bad practice.
- public config: {}; + public config: Record<string, any>;🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
128-141
: Use Array.isArray() for better compatibilityThe use of
instanceof Array
on line 138 can lead to false negatives with arrays from different contexts.- this.cache[name] ||= require.resolve(name); + this.cache[name] = this.cache[name] || require.resolve(name);This ensures compatibility with older JavaScript environments that may not support the ||= operator.
packages/hydrooj/src/model/domain.ts (1)
138-138
: Replace instanceof Array with Array.isArray()Using instanceof Array can lead to false negatives when dealing with arrays from different JavaScript contexts.
- if (!(uid instanceof Array)) { + if (!Array.isArray(uid)) {This ensures proper array detection across all JavaScript contexts.
🧰 Tools
🪛 Biome (1.9.4)
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.(lint/suspicious/useIsArray)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (94)
.eslintrc.yaml
(0 hunks).github/workflows/build.yml
(1 hunks)build/prepare.js
(5 hunks)eslint.config.mjs
(1 hunks)framework/eslint-config/base.mjs
(1 hunks)framework/eslint-config/base.yaml
(0 hunks)framework/eslint-config/package.json
(1 hunks)framework/eslint-config/react.yaml
(0 hunks)framework/eslint-config/typescript.js
(0 hunks)framework/framework/error.ts
(0 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrojudge/src/cases.ts
(0 hunks)packages/hydrojudge/src/checkers.ts
(4 hunks)packages/hydrojudge/src/daemon.ts
(0 hunks)packages/hydrojudge/src/hosts/hydro.ts
(0 hunks)packages/hydrojudge/src/hosts/vj4.ts
(1 hunks)packages/hydrojudge/src/judge/hack.ts
(4 hunks)packages/hydrooj/package.json
(3 hunks)packages/hydrooj/src/commands/install.ts
(1 hunks)packages/hydrooj/src/entry/cli.ts
(2 hunks)packages/hydrooj/src/entry/common.ts
(2 hunks)packages/hydrooj/src/entry/setup.ts
(0 hunks)packages/hydrooj/src/entry/worker.ts
(3 hunks)packages/hydrooj/src/handler/contest.ts
(0 hunks)packages/hydrooj/src/handler/domain.ts
(3 hunks)packages/hydrooj/src/handler/misc.ts
(3 hunks)packages/hydrooj/src/handler/problem.ts
(1 hunks)packages/hydrooj/src/interface.ts
(6 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/blacklist.ts
(1 hunks)packages/hydrooj/src/model/contest.ts
(7 hunks)packages/hydrooj/src/model/document.ts
(11 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/hydrooj/src/model/message.ts
(3 hunks)packages/hydrooj/src/model/oauth.ts
(1 hunks)packages/hydrooj/src/model/opcount.ts
(1 hunks)packages/hydrooj/src/model/problem.ts
(1 hunks)packages/hydrooj/src/model/record.ts
(8 hunks)packages/hydrooj/src/model/schedule.ts
(2 hunks)packages/hydrooj/src/model/setting.ts
(11 hunks)packages/hydrooj/src/model/storage.ts
(6 hunks)packages/hydrooj/src/model/system.ts
(3 hunks)packages/hydrooj/src/model/task.ts
(3 hunks)packages/hydrooj/src/model/token.ts
(2 hunks)packages/hydrooj/src/model/user.ts
(8 hunks)packages/hydrooj/src/plugin-api.ts
(2 hunks)packages/hydrooj/src/script/problemStat.ts
(0 hunks)packages/hydrooj/src/script/storageUsage.ts
(0 hunks)packages/hydrooj/src/service/bus.ts
(5 hunks)packages/hydrooj/src/service/db.ts
(3 hunks)packages/hydrooj/src/service/worker.ts
(2 hunks)packages/hydrooj/src/settings.ts
(1 hunks)packages/hydrooj/src/ui.ts
(1 hunks)packages/migrate/package.json
(1 hunks)packages/onlyoffice/frontend/office.page.ts
(0 hunks)packages/onsite-toolkit/frontend/resolver.page.tsx
(2 hunks)packages/ui-default/.eslintignore
(0 hunks)packages/ui-default/.eslintrc.js
(0 hunks)packages/ui-default/api.ts
(0 hunks)packages/ui-default/backendlib/builder.ts
(4 hunks)packages/ui-default/backendlib/markdown-it-imsize.ts
(1 hunks)packages/ui-default/backendlib/markdown-it-media.ts
(0 hunks)packages/ui-default/backendlib/misc.ts
(1 hunks)packages/ui-default/backendlib/template.ts
(3 hunks)packages/ui-default/build/config/webpack.ts
(1 hunks)packages/ui-default/build/main.ts
(1 hunks)packages/ui-default/components/autocomplete/components/AutoComplete.tsx
(3 hunks)packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
(1 hunks)packages/ui-default/components/calendar/index.js
(2 hunks)packages/ui-default/components/message/worker.ts
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
(1 hunks)packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
(1 hunks)packages/ui-default/components/problemconfig/reducer/config.ts
(1 hunks)packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
(1 hunks)packages/ui-default/components/problemconfig/tree/Testcase.tsx
(1 hunks)packages/ui-default/components/scratchpad/DataInputComponent.jsx
(0 hunks)packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
(0 hunks)packages/ui-default/index.ts
(6 hunks)packages/ui-default/package.json
(5 hunks)packages/ui-next/package.json
(1 hunks)packages/ui-next/src/App.tsx
(1 hunks)packages/utils/lib/locate-pm2.ts
(1 hunks)packages/utils/lib/utils.ts
(1 hunks)packages/utils/package.json
(2 hunks)packages/vjudge/src/index.ts
(3 hunks)packages/vjudge/src/providers/codeforces.ts
(0 hunks)packages/vjudge/src/providers/hduoj.ts
(0 hunks)packages/vjudge/src/providers/poj.ts
(0 hunks)packages/vjudge/src/providers/spoj.ts
(0 hunks)packages/vjudge/src/providers/uoj.ts
(0 hunks)packages/vjudge/src/providers/yacs.ts
(0 hunks)
💤 Files with no reviewable changes (25)
- packages/ui-default/api.ts
- packages/hydrooj/src/script/storageUsage.ts
- packages/ui-default/backendlib/markdown-it-media.ts
- framework/framework/error.ts
- packages/hydrooj/src/entry/setup.ts
- packages/hydrojudge/src/cases.ts
- packages/hydrojudge/src/daemon.ts
- packages/ui-default/components/scratchpad/DataInputComponent.jsx
- packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx
- packages/hydrooj/src/script/problemStat.ts
- packages/vjudge/src/providers/poj.ts
- packages/hydrojudge/src/hosts/hydro.ts
- packages/vjudge/src/providers/codeforces.ts
- packages/vjudge/src/providers/hduoj.ts
- packages/ui-default/.eslintignore
- packages/onlyoffice/frontend/office.page.ts
- packages/hydrooj/src/handler/contest.ts
- framework/eslint-config/typescript.js
- .eslintrc.yaml
- framework/eslint-config/react.yaml
- packages/vjudge/src/providers/yacs.ts
- packages/vjudge/src/providers/uoj.ts
- framework/eslint-config/base.yaml
- packages/vjudge/src/providers/spoj.ts
- packages/ui-default/.eslintrc.js
✅ Files skipped from review due to trivial changes (14)
- packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
- packages/ui-default/components/problemconfig/reducer/config.ts
- packages/ui-default/components/problemconfig/tree/Testcase.tsx
- packages/ui-default/components/problemconfig/ProblemConfigTree.tsx
- packages/ui-default/components/problemconfig/tree/AddTestcase.tsx
- packages/ui-default/backendlib/misc.ts
- packages/ui-default/backendlib/markdown-it-imsize.ts
- packages/utils/lib/locate-pm2.ts
- packages/ui-default/components/problemconfig/ProblemConfigEditor.tsx
- packages/ui-default/build/config/webpack.ts
- packages/ui-default/components/message/worker.ts
- packages/ui-default/components/calendar/index.js
- packages/ui-default/build/main.ts
- packages/hydrojudge/src/hosts/vj4.ts
🚧 Files skipped from review as they are similar to previous changes (27)
- packages/ui-next/src/App.tsx
- packages/hydrojudge/src/judge/hack.ts
- packages/hydrooj/src/ui.ts
- packages/onsite-toolkit/frontend/resolver.page.tsx
- packages/hydrojudge/src/checkers.ts
- packages/ui-default/components/autocomplete/components/UserSelectAutoComplete.tsx
- packages/hydrooj/src/model/user.ts
- packages/hydrooj/src/service/bus.ts
- packages/ui-next/package.json
- packages/migrate/package.json
- packages/hydrooj/src/model/token.ts
- packages/hydrooj/src/model/contest.ts
- packages/hydrooj/src/entry/worker.ts
- packages/ui-default/components/autocomplete/components/AutoComplete.tsx
- packages/hydrooj/src/model/message.ts
- packages/ui-default/backendlib/builder.ts
- packages/hydrooj/src/model/storage.ts
- packages/utils/package.json
- packages/hydrooj/src/handler/problem.ts
- packages/hydrooj/src/model/problem.ts
- packages/hydrooj/src/plugin-api.ts
- packages/vjudge/src/index.ts
- packages/hydrooj/src/model/system.ts
- packages/hydrooj/src/commands/install.ts
- packages/hydrooj/src/model/task.ts
- package.json
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (11)
packages/hydrooj/src/service/db.ts (3)
packages/hydrooj/src/entry/cli.ts (1) (1)
load
(105-141)packages/hydrooj/src/loader.ts (1) (1)
load
(170-206)packages/hydrooj/src/options.ts (1) (1)
load
(24-37)
packages/ui-default/backendlib/template.ts (3)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/api.ts (3) (3)
Service
(5-5)ctx
(5-5)Context
(5-5)packages/hydrooj/src/model/builtin.ts (2) (2)
PERM
(9-102)PRIV
(240-267)
packages/hydrooj/src/model/record.ts (2)
packages/hydrooj/src/model/document.ts (1) (1)
apply
(413-447)packages/hydrooj/src/model/task.ts (1) (1)
apply
(145-191)
packages/hydrooj/src/entry/common.ts (4)
packages/ui-default/api.ts (2) (2)
ctx
(5-5)Context
(5-5)packages/hydrooj/src/plugin-api.ts (1) (1)
Context
(41-41)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/utils.ts (1) (1)
unwrapExports
(21-29)
packages/elastic/index.ts (4)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/hydrooj/src/settings.ts (1) (1)
Context
(30-34)packages/hydrooj/src/interface.ts (1) (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1) (1)
ProblemModel
(74-675)
packages/hydrooj/src/interface.ts (1)
packages/common/types.ts (1) (1)
RecordJudgeInfo
(84-96)
packages/hydrooj/src/settings.ts (4)
packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/elastic/index.ts (1) (1)
Context
(95-125)packages/vjudge/src/index.ts (1) (1)
Context
(191-196)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/model/setting.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
Setting
(46-56)packages/hydrooj/src/service/check.ts (1) (1)
apply
(77-80)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
framework/framework/server.ts (4)
packages/hydrooj/src/service/layers/base.ts (1) (1)
ctx
(20-72)packages/hydrooj/src/plugin-api.ts (3) (3)
Handler
(40-40)Service
(41-41)Context
(41-41)framework/framework/interface.ts (1) (1)
KnownHandlers
(3-5)packages/hydrooj/src/context.ts (2) (2)
Context
(31-41)Context
(68-77)
packages/hydrooj/src/model/document.ts (7)
packages/hydrooj/src/model/user.ts (1) (1)
coll
(22-22)packages/hydrooj/src/model/oplog.ts (1) (1)
coll
(8-8)packages/hydrooj/src/model/discussion.ts (1) (1)
coll
(43-43)packages/hydrooj/src/model/problem.ts (1) (1)
incStatus
(431-436)packages/hydrooj/src/model/token.ts (1) (1)
update
(53-71)packages/hydrooj/src/model/record.ts (1) (1)
update
(195-219)packages/hydrooj/src/service/monitor.ts (1) (1)
update
(76-89)
🪛 Biome (1.9.4)
packages/ui-default/backendlib/template.ts
[error] 46-46: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().
(lint/security/noGlobalEval)
packages/hydrooj/src/handler/misc.ts
[error] 110-110: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 124-124: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/loader.ts
[error] 49-49: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/hydrooj/src/model/domain.ts
[error] 138-138: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
framework/framework/server.ts
[error] 139-139: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 140-140: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
packages/hydrooj/src/handler/domain.ts
[error] 155-155: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
packages/hydrooj/src/model/document.ts
[error] 223-223: Use Array.isArray() instead of instanceof Array.
instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.
(lint/suspicious/useIsArray)
packages/ui-default/index.ts
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🪛 GitHub Check: CodeQL
build/prepare.js
[failure] 166-166: Potential file system race condition
The file may have changed since it was checked.
🔇 Additional comments (124)
packages/utils/lib/utils.ts (2)
10-10
: Good refactoring of logger importsThe import has been updated to include additional components from the 'reggol' package, which enables a more configurable logging approach.
29-31
: LGTM: Good encapsulation of logger creationThe
createLogger
function nicely encapsulates the factory usage and provides a clean interface for creating loggers.packages/hydrooj/src/handler/domain.ts (5)
105-147
: Good refactoring using MongoDB aggregation pipelineThis change improves data retrieval efficiency by replacing direct queries with an aggregation pipeline. The
$lookup
stage elegantly joins user details from the 'user' collection, reducing the need for separate queries.
259-259
: LGTM: Improved role filtering logicGood change to only filter out 'guest' role instead of both 'default' and 'guest', which aligns with the comment on line 108-109 about displaying users with the default role.
340-358
: Good enhancement to domain joining processThe updated
get
method now properly handles target domains and redirects, with comprehensive domain information in the response. This improves the user experience when joining domains.
322-337
:✅ Verification successful
Good enhancement for cross-domain functionality
The updated
prepare
method now supports specifying a target domain, enhancing flexibility. The role determination logic is also improved with cleaner privilege checking.Check if all calling sites have been updated to handle the new parameter:
🏁 Script executed:
#!/bin/bash # Check for methods that call the prepare method without providing a target parameter rg -A 2 "prepare\(\s*\{\s*domainId\s*\}\s*\)" --type tsLength of output: 305
Cross-Domain Functionality Verified: Parameter Handling is Consistent
The enhancedprepare
method now supports an optional target domain parameter that defaults todomainId
, ensuring that legacy call sites continue to work as expected. Our search only returned the method definition (i.e., the line using{ domainId }
), with no evidence of call sites omitting necessary updates. All usage appears consistent with the intended behavior.🧰 Tools
🪛 Biome (1.9.4)
[error] 335-335: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
361-377
:❓ Verification inconclusive
Enhanced domain join post handler
The updated
post
method properly handles domain joining with target and redirect parameters. The role assignment is now more flexible based on join settings.Check for any frontend code that might need updating for the new parameters:
🏁 Script executed:
#!/bin/bash # Look for client-side code that calls the domain join endpoint rg -A 2 "domain_join" --type js --type ts --type jsx --type tsx | grep -v "ctx.Route"Length of output: 111
Domain join post handler update – please verify frontend integrations
The updated
post
method correctly handles domain-join logic with flexible target and redirect parameters, and applies role assignment as intended based on join settings. However, our initial automated client-side search encountered a file type issue (with JSX files). Although no references were found in the.js
,.ts
, or.tsx
files, please manually verify any.jsx
usages that might call this endpoint to ensure they’re updated as needed.
- Server-side: Changes in
packages/hydrooj/src/handler/domain.ts
(lines 361-377) properly implement the new default behavior.- Client-side: Confirm that any code invoking the domain join endpoint (especially in
.jsx
files) correctly passes or accommodates the optionaltarget
andredirect
parameters.build/prepare.js (10)
18-20
: TypeScript compilation target and module updatedThe TypeScript compilation configuration has been updated to use ES2022 target and features, while changing the module strategy from 'commonjs' to 'preserve'. This represents a modernization of the JavaScript output, enabling newer language features.
22-22
: Module resolution strategy updated to 'bundler'The change from 'node' to 'bundler' moduleResolution aligns with modern TypeScript practices for projects using bundlers like Webpack, Rollup, or Vite. This allows TypeScript to better understand imports in a bundled environment.
37-37
: UI-Next reference added to project configurationA new reference to 'tsconfig.ui-next.json' has been added, indicating the introduction of a new UI component to the project architecture.
78-78
: Fixed module filtering logicThe module filtering logic has been improved to properly exclude 'ui-default' and 'ui-next' directories using a more consistent approach with the
some()
method.
83-87
: Extended UI exclusion patternsAdditional exclusion patterns have been added for specific files in the ui-default package, ensuring that these backend-related files are not processed by the UI TypeScript configuration.
123-161
: Added new UI-Next TypeScript configurationA new TypeScript configuration for the 'ui-next' package has been introduced with modern settings:
- ES2022 features
- React JSX transform
- Strict type checking
- Path aliases for '@/*'
- Bundler mode optimizations
This properly sets up the development environment for the new UI package.
189-189
: Added skipLibCheck to plugins configurationThe
skipLibCheck: true
option has been added to the plugins configuration, which will speed up TypeScript compilation by skipping type-checking of declaration files (*.d.ts).
197-212
: Improved configuration file update logicThe script now uses the new
tryUpdate
function to update configuration files only when their content has changed. This improves build performance by avoiding unnecessary file writes.
219-219
: Refactored module export creationThe module export creation now uses the
tryUpdate
function, maintaining consistency with the rest of the file and only writing when content has changed.
223-225
: Configuration file generation with improved efficiencyAll TypeScript configuration files are now generated using the
tryUpdate
function, including the newtsconfig.ui-next.json
file. This ensures consistent behavior and improves build efficiency.packages/hydrooj/src/model/opcount.ts (1)
16-16
: Confirm object structure forres
.By returning
res.opcount
rather thanres.value.opcount
, you're assuming the updated document is exposed at the top level. Verify thatres
andres.opcount
are always defined (e.g.,res
is never null) based on your Mongo driver or wrapper's behavior. Otherwise, you may need to handle potential undefined cases.Would you like a script to scan references of
inc
calls and confirm all call sites handle potential errors?eslint.config.mjs (1)
1-150
: Overall ESLint configuration looks solid!Below are a few considerations:
Rule Overrides
You’re replacing built-in ESLint rules (e.g.,no-unused-vars
,no-shadow
) with their TypeScript equivalents, which is recommended. Confirm that disabling base rules everywhere matches your entire codebase’s needs.No-Await-In-Loop
Setting'no-await-in-loop'
to'warn'
(line 377) is common, but be aware of possible performance bottlenecks for large loops. Consider parallelizing or refactoring if you see slowdowns in practice.Import Validation
Turning off rules like'import/no-unresolved'
(line 79 in the second config block) can hide genuine import path mistakes. If feasible, keep them on (with adjustments) to catch broken or missing imports.Max Length
'max-len': ['warn', 150]
(line 366) is purely stylistic. Ensuring different teams or repos follow the same limit fosters consistency.These points don’t block merging; everything else looks well-structured.
framework/eslint-config/base.mjs (1)
1-483
: Nicely organized ESLint config with broad TypeScript support!
Extensive Overrides
You’ve silenced several core ESLint checks (e.g.,'no-undef'
,'no-redeclare'
) in favor of TypeScript. Generally correct, but confirm that this covers all team usage scenarios, especially if some JS files aren’t transpiled.Import Rules
Disabling'import/no-unresolved'
,'import/no-extraneous-dependencies'
, etc., can let unresolved or extraneous imports slip by. Consider enabling them in CI or selective directories to protect from broken paths or dependency mismatches.No-Await-In-Loop
The'no-await-in-loop'
rule also appears here (if added). Keeping it as'warn'
is fine, but watch for unexpected performance hits in loops.Potential for Duplicate or Conflicting Config
Because you’re mixing multiple plugins (@eslint-react
,jsx-a11y
,github
, etc.) and layering them with TypeScript plugin rules, keep an eye on any conflicting or redundant rules. Periodic upgrades or merges might alter rule sets in ways you don’t expect.Otherwise, the plugin usage, naming conventions, and extended rules appear consistent with typical TS + React projects.
packages/ui-default/backendlib/template.ts (3)
121-121
: Avoid usingeval
if possible.
eval()
can introduce serious security and performance risks. Consider refactoring to safer alternatives.🧰 Tools
🪛 Biome (1.9.4)
[error] 121-121: eval() exposes to security risks and performance issues.
See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().(lint/security/noGlobalEval)
122-128
: Security Concern: Limit Global Exposure in Template EngineExposing complete global objects (such as
Date
,Object
,String
, etc.) creates significant security risks like remote code execution, prototype pollution, and XSS. Instead of exposing these full objects, it's safer to limit the available methods to only those needed.
221-242
: Add timeout handling to prevent long-running rendersWhile there's logging for slow renders (>5000ms), there's no actual timeout mechanism to prevent extremely long-running renders from blocking the server.
packages/hydrooj/src/interface.ts (4)
226-229
: Well-structured interface definition.Good job creating the
RecordHistoryDoc
interface that extendsRecordJudgeInfo
and adds the necessary ID fields. This provides good type safety for the record history collection.
663-663
: Verify that all accesses toaddons
have been updated for the new structureThe change from array to Record structure improves lookup performance and allows associating metadata with each addon, but ensure all usages of
addons
have been updated across the codebase.#!/bin/bash # Find all places in the codebase where addons is accessed, to verify they've been updated rg "addons\[" --type=ts rg "\.forEach\(.*addons" --type=ts rg "for.*of.*addons" --type=ts
83-83
: Good typing improvement for authenticator extension results.The type update to use
ParsedAuthenticatorData['extensionsData']
provides more precise typing for the authenticator extension results.
552-552
: Good database collection definition for record history.Adding the 'record.history' entry to the Collections interface properly registers the new collection type in the type system.
packages/ui-default/index.ts (6)
7-7
: Good import update for new TemplateService.The import of
TemplateService
aligns with the refactoring in the template handling system.
25-25
: Explicit type annotation improves code clarity.Adding an explicit type annotation for
sections
improves code readability and type checking.
56-56
: Remove the empty object pattern.Static analysis flags
{ }
as an unexpected empty pattern. Consider removing it as it doesn't serve any purpose.- async get({ }, legacy = false, nohint = false) { + async get(legacy = false, nohint = false) {🧰 Tools
🪛 Biome (1.9.4)
[error] 56-56: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
77-77
: Good update to use context-derived configuration.Using
this.ctx.config.settings
instead ofSystemSettings
is a good practice that leverages the context object and reduces global dependencies.
119-119
: Explicit typing of array improves code clarity.Adding an explicit type annotation for the
res
array improves code readability and type checking.
167-167
: Good transition to using TemplateService.The update to use the new
TemplateService
class aligns with the architectural changes in the template handling system.packages/hydrooj/src/model/document.ts (5)
12-12
: Updated import style for bus module.The import style has changed from
import * as bus from '../service/bus'
toimport bus from '../service/bus'
, indicating that the module now uses a default export. This is consistent with the broader refactoring approach.
18-18
: Correct type usage for TypeScript primitives.Changing from
Symbol
tosymbol
is correct for TypeScript type declarations as it should use the lowercase primitive name.
23-33
: Improved type safety withas const
assertions.Using
as const
for constant declarations creates more precise literal types instead of just number types. This improves type safety throughout the application.
385-391
: Good use of nullish coalescing operator.The refactoring of
revPushStatus
to use the nullish coalescing operator (||=
) is a good use of modern JavaScript features that improves code readability and reduces verbosity.
112-117
: Consistent use ofawait
operators improves code readability.Adding explicit
await
operators to all returned promises makes async code behavior clearer and improves maintainability. This is a good practice.Also applies to: 152-157, 163-168, 211-217, 224-230, 255-265, 271-277, 301-311, 328-333, 358-363, 369-374, 397-402, 410-411
framework/framework/server.ts (7)
552-553
: Fix FIXME comments for event handler type assertions.Similar to the previous issue, these event emissions use type assertions that bypass TypeScript's type checking.
569-569
: Fix FIXME comments for event handler type assertions.Similar to the previous issue, these event emissions use type assertions that bypass TypeScript's type checking.
604-604
: Fix FIXME comments for event handler type assertions.Similar to the previous issue, these event emissions use type assertions that bypass TypeScript's type checking.
656-656
: Fix FIXME comments for event handler type assertions.Similar to the previous issue, these event emissions use type assertions that bypass TypeScript's type checking.
44-52
: Clean up resources properly with asyncDispose.The
forkContextWithScope
function uses the Symbol.asyncDispose protocol, which is great for resource management.Good use of the async disposable pattern to ensure context resources are properly cleaned up.
787-810
: Verify proper cleanup in _applyMixin implementation.The _applyMixin method correctly stores the original values and restores them during cleanup.
The implementation of _applyMixin properly handles both adding properties and cleaning them up when disposing of the effect.
826-828
: Consistent handling of mixins across handler types.The wsHandlerMixin method is now consistently implemented like other mixin methods.
This implementation properly applies the mixin to the ConnectionHandler prototype and cleans up when done, fixing previous issues.
packages/hydrooj/src/model/oauth.ts (1)
18-18
:❓ Verification inconclusive
Verify database result structure change.
The return value changed from
res.value?.uid
tores?.uid
, suggesting a change in the MongoDB driver or result structure.Make sure this change is consistent with other model updates in the codebase. Verify that your MongoDB result structure no longer includes a
value
property or that you're handling both formats correctly.
🏁 Script executed:
#!/bin/bash # Find other occurrences of MongoDB result handling with value property echo "Checking other MongoDB result handling patterns:" rg -A 1 "await coll\.findOneAndUpdate" | rg "\.value"Length of output: 162
Double-check MongoDB result handling consistency.
It looks like the OAuth model now returns
res?.uid
instead of the previousres.value?.uid
, suggesting an update in how the MongoDB results are structured. Our initial automated search for occurrences of the outdated.value
property didn’t return any results, which is encouraging. However, since the grep output was empty—and an output was expected for a conclusive automated check—it’s advisable to manually verify that no other parts of the code still depend on the older result structure.
- Please review MongoDB update operations (such as those using
findOneAndUpdate
) to confirm that they no longer expect avalue
property.- Ensure that the updated driver behavior is uniformly applied across all related models.
packages/hydrooj/src/model/blacklist.ts (1)
16-20
: Update result handling pattern to match MongoDB response structure.Changed from assigning the result to a variable and returning
res.value
to directly returning the await result.This change aligns with the updated MongoDB result structure handling seen in oauth.ts, improving consistency across the codebase.
packages/hydrooj/src/entry/cli.ts (4)
112-114
: Improved service initialization using plugins.Switching from direct service initialization to the plugin system enhances modularity.
Using plugins for MongoDB and Config services improves the application's architecture by leveraging the dependency injection system.
115-119
: Ensure dependencies are available through promise-based injection.Using promises to wait for dependencies to be injected ensures services are available when needed.
This pattern ensures the loader and config services are fully initialized before proceeding, which prevents potential race conditions.
130-134
: Consistent dependency injection pattern.Using the same promise-based dependency injection pattern for server, setting, and worker services.
Consistently using this pattern improves code predictability and ensures services are properly initialized.
138-138
: Simplified plugin loading.The call to ctx.loader.reloadPlugin has been simplified to remove the unnecessary ctx parameter.
This change correctly reflects that the context is already available within the loader service, reducing redundant parameters.
.github/workflows/build.yml (1)
66-66
:❓ Verification inconclusive
Verify the removal of UI linting in CI workflow.
The
lint:ui:ci
task has been removed from the parallel execution in the workflow. This change could potentially speed up the CI process, but it might also lead to UI-related code quality issues being missed.
🏁 Script executed:
#!/bin/bash # Check if UI linting is incorporated elsewhere in the project # Look for UI linting tasks in package.json scripts echo "Checking package.json for UI linting scripts:" jq '.scripts | with_entries(select(.key | contains("lint") and contains("ui")))' package.json # Check if there are other workflow files that might include UI linting echo "Checking other workflow files for UI linting tasks:" rg --type yaml "lint:ui" .github/workflows/Length of output: 356
Attention: The current changes in the CI workflow now omit the
lint:ui:ci
task (as seen in the commandparallel --tty -j+0 yarn ::: lint:ci build build:ui:production:webpack test
). Our inspection—searching for UI lint tasks in bothpackage.json
and the other workflow files—yielded no indications of any UI linting elsewhere in the repository. This suggests that the UI linting step is no longer executed in CI.Please verify that this removal is intentional or that UI-related quality checks are being handled by an alternate mechanism. If the omission is deliberate, consider updating the documentation to reflect this change, ensuring that potential UI issues are not inadvertently overlooked in future CI runs.
packages/hydrooj/src/model/record.ts (6)
2-2
: Good addition of thepick
utility from lodash.This import will be used for selectively copying fields from record documents into history records.
23-23
: Well-implemented record history collection.Adding the
collHistory
collection is a good design choice for maintaining record history before resets, allowing for historical auditing and tracking of changes over time.
236-236
: Good replacement ofinstanceof Array
withArray.isArray()
.This change follows best practices for array type checking.
Array.isArray()
is more reliable across different execution contexts and handles array-like objects properly.
250-262
: Well-implemented record history preservation.The implementation correctly:
- Fetches records before deletion
- Extracts relevant fields using lodash's
pick
- Preserves the original record ID reference
- Creates new ObjectIds for history entries
This enables proper tracking of record changes over time.
283-283
: Good conversion ofapply
function to async.This change correctly makes the function asynchronous, which is appropriate since it's handling database operations and other asynchronous tasks.
324-327
: Good addition of index for collHistory collection.This properly implements the index creation for the new
collHistory
collection, which will improve query performance for history lookups. The index is defined on therid
field with descending_id
for efficient retrieval.packages/hydrooj/src/model/schedule.ts (2)
18-25
: Improved result handling in getFirst function.The function now directly checks for the existence of
res
instead ofres.value
, simplifying the code. This change also ensures that the entire result object is returned, maintaining consistency with MongoDB's findOneAndDelete operation which returns the entire document.
7-7
:✅ Verification successful
Changed import type for WorkerService.
The import statement has been changed from importing a named type to importing a default type. Ensure this matches the export pattern in the worker service module.
🏁 Script executed:
#!/bin/bash # Check the export pattern in the worker service module rg "export default|export class WorkerService" packages/hydrooj/src/service/worker.tsLength of output: 140
Default Import Verified for WorkerService
The worker service module correctly uses a default export (
export default class WorkerService extends Service { ... }
), which confirms that the updated import statement inpackages/hydrooj/src/model/schedule.ts
is correct.
- Confirmed that
WorkerService
is exported as a default class.packages/hydrooj/src/service/db.ts (7)
7-11
: Good refactoring of imports for dependency management.The imports have been updated to include the
Context
andService
classes, and bus is now imported as a default import. This aligns with modern module import patterns and supports the new service-based architecture.
29-34
: Well-structured Context interface extension.This module declaration properly extends the Context interface to include a db property of type MongoService, enabling typed access to the database service through the context.
35-41
: Good implementation of service-based architecture.The MongoService class now extends Service and accepts a context in its constructor, following a consistent pattern for service initialization and integration with the application's dependency injection system.
43-56
: Well-designed static URL retrieval method.The static
getUrl()
method effectively encapsulates the logic for retrieving the MongoDB connection URL, handling CI environments and configuration loading. This improves testability and separation of concerns.
58-66
: Good implementation of async generator for initialization.The
[Context.init]
method replaces the previousstart
method with an async generator that:
- Retrieves the connection URL
- Establishes the MongoDB connection
- Yields a cleanup function for proper resource management
- Sets up a periodic task for index maintenance
This follows modern patterns for asynchronous initialization and cleanup.
69-71
: Improved collection name configuration.The collection method now properly references the config object for prefix and collection mapping, enhancing configurability and flexibility.
182-188
: Good backward compatibility with deprecated notice.This proxy implementation provides backward compatibility for code still directly accessing the
db
object, while clearly marking it as deprecated in favor of usingctx.db
. This facilitates a smooth transition to the new context-based approach.packages/hydrooj/src/service/worker.ts (2)
12-12
: Conversion to default export enhances module import flexibility.The class has been changed from a named export to a default export, which is more aligned with modern ES module usage patterns. This change enhances module import flexibility, allowing cleaner imports in consuming code.
32-38
: Direct property access pattern improves code clarity.The refactoring now directly accesses properties on the
res
object instead of going through an intermediatevalue
property. This change aligns with the broader codebase refactoring to simplify data access patterns.packages/hydrooj/src/handler/misc.ts (2)
17-17
: LGTM: Added import for sortFiles utility.Adding the import for
sortFiles
function from the utils module is appropriate and ensures the proper organization of dependencies.
112-112
: Switch to context-based link validation improves modularity.The validation logic now uses a dynamic context-based check through
this.ctx.get('storage')?.isLinkValid?()
instead of a static approach, which is a positive improvement for dependency injection and testability.packages/elastic/index.ts (5)
4-5
: Enhanced imports improve type safety.The addition of typed imports from 'hydrooj' represents a good refinement in the code organization, enhancing type safety and making dependencies explicit.
20-32
: Well-structured service class with schema-based configuration.The conversion to a service class with explicit schema-based configuration is a significant architectural improvement. The class extends Service and properly declares its configuration schema with appropriate defaults and type constraints.
73-78
: Improved error handling for Elasticsearch operations.The error handling for Elasticsearch operations is properly implemented, only throwing errors that aren't related to the "index_not_found_exception", which is a common and often expected case.
117-124
: Add error handling to the script registration callback.The script registration doesn't include error handling for the
run
method when used as a callback, which could lead to unhandled promise rejections.
95-117
: Add error handling to event listeners.The event listeners for problem operations don't have try-catch blocks to handle potential errors, which could lead to unhandled promise rejections and affect system stability.
framework/eslint-config/package.json (4)
5-5
: Updated main entry point to reflect new ESLint configuration structure.The main entry point has been updated from "react.yaml" to "base.mjs", which reflects the transition to a more modern ESLint configuration format using JavaScript modules instead of YAML.
7-21
: Comprehensive update of ESLint dependencies to support newer features.The dependencies have been updated to include newer ESLint plugins and tools, particularly for React, TypeScript, and code style enforcement. This is a positive change that will enable better linting capabilities.
26-28
: Added TypeScript as an optional dependency.Adding TypeScript as an optional dependency is a good practice as it allows for flexible integration with projects that may or may not use TypeScript, while still ensuring a specific compatible version is recommended.
24-25
:✅ Verification successful
Upgraded minimum ESLint peer dependency to version 9.
The minimum ESLint version requirement has been increased from 8 to 9, which is appropriate given the updated plugins that may depend on newer ESLint features.
Please verify that all dependent projects are compatible with ESLint 9:
🏁 Script executed:
#!/bin/bash # Find all package.json files and check their eslint dependencies find . -name "package.json" -not -path "*/node_modules/*" -exec jq -r 'if .dependencies.eslint then .dependencies.eslint else empty end' {} \; find . -name "package.json" -not -path "*/node_modules/*" -exec jq -r 'if .devDependencies.eslint then .devDependencies.eslint else empty end' {} \;Length of output: 305
Compatibility with ESLint 9 confirmed in dependent projects.
Our verification shows that the only ESLint dependency found in the codebase is specified as "^9.22.0", which is compatible with the updated minimum requirement of ">= 9" in
framework/eslint-config/package.json
. No further changes are needed.packages/hydrooj/src/settings.ts (6)
3-3
: Good change: Improved import clarity for Context and ServiceThe import has been updated to explicitly import both Context and Service from the context module, making dependencies clearer.
8-12
: Well-structured module augmentationNice addition of the module declaration to augment the Context interface with the new ConfigService. This ensures proper type safety throughout the application.
14-25
: Good architecture: Service-based approachThe new ConfigService class follows good OOP principles by extending the Service base class. The static properties (inject, name, blacklist) clearly define dependencies and behavior rules. This is a good improvement over global variables.
69-77
: Good validation: Schema-based configuration verificationThe
isPatchValid
method ensures that configuration changes comply with the defined schema, which is a great approach to maintain configuration integrity.
159-160
: Fixed null check in getAccess functionThis properly fixes the previously identified logical issue by checking both for object type and null/undefined values.
86-107
: Well-implemented migration logicThe
_actualMigrate
method handles migrating existing configuration values to the new schema-based approach with good error handling and proper type conversion.packages/hydrooj/src/model/setting.ts (9)
3-3
: Updated import from cordis to @cordisjs/coreThe import statement has been updated to use the newer @cordisjs/core package instead of cordis.
7-7
: Missing dependency in package.jsonThe Schema import from 'schemastery' is appropriate, but the package may not be declared in dependencies.
Let's verify if schemastery is properly included in your dependencies:
#!/bin/bash # Check if schemastery is in package.json dependencies grep -r "\"schemastery\":" --include="package.json" .
73-80
: Good type enhancement: Schema metadata extensionThe addition of the Schemastery namespace with Meta interface provides a clean way to add domain-specific metadata to schema definitions.
82-119
: Potential coverage gap for complex schemasThe schemaToSettings function only handles specific primitive types (number, string, boolean) and has limited support for nested structures (one level of dictionaries).
Consider enhancing the function to support more complex nested structures and additional types to ensure complete schema coverage. The current implementation will throw errors for unsupported schema structures.
121-123
: Good refactoring: Setting functions enhanced for schema supportAll setting registration functions (PreferenceSetting, AccountSetting, etc.) have been updated to accept both traditional _Setting arrays and Schema objects, using flatMap with the schemaToSettings function for conversion. This provides a nice backward compatibility while enabling the new schema-based approach.
Also applies to: 141-142, 161-162, 177-178, 193-194
291-318
: Great showcase of schema-based settingsThis is an excellent example of the new schema-based approach to defining settings. It's more structured, type-safe, and provides better developer experience compared to the previous array-based approach.
359-359
: Updated module declaration for new package nameThe module declaration has been updated to match the new package name @cordisjs/core.
388-388
: Good practice: Explicit dependency injectionThe explicit injection of database dependency is a good practice for service registration.
395-395
: Enhanced context usage: Using ctx.db instead of globalThe code now uses the context-based db reference (ctx.db) instead of a global variable, which is a better architectural approach.
packages/hydrooj/src/loader.ts (7)
15-17
: Enhanced imports with specific named importsThe imports have been updated to include specific named imports from the context module, improving code clarity.
22-22
: Added schemastery importThis import enables schema-based configuration validation in the loader.
54-58
: Good practice: Explicit dependency injection and constructorThe static inject property clearly specifies dependencies, and the constructor is properly using the context parameter to initialize the service.
98-107
: Well-implemented configuration resolutionThe new resolveConfig method properly handles schema-based configuration with support for scoped configurations. The integration with the ConfigService's migration and request methods ensures configuration consistency.
109-126
: Improved plugin managementThe reloadPlugin method has been updated to use the new resolveConfig method and properly handles plugin application through the context system.
147-153
: Enhanced asynchronous initializationThe preload function has been correctly converted to async and now properly awaits the application initialization through the Promise-based approach.
170-172
: Consistent async/await usageThe load and loadCli functions now correctly await the preload function's completion, ensuring the application is properly initialized before proceeding.
Also applies to: 209-211
packages/hydrooj/src/model/domain.ts (6)
4-4
: Updated import to use direct Context importThe import has been changed to directly import Context from the context module rather than from a service, which is a better approach for clarity.
131-132
: Added join filter to countUser queriesThe countUser method now includes a join:true filter in both queries, ensuring only users who have explicitly joined the domain are counted.
136-137
: Enhanced setUserRole with autojoin parameterThe setUserRole method now includes an optional autojoin parameter that controls whether to set the join property, providing more flexibility.
213-213
: Added join check for guest role assignmentThis change ensures that users are assigned the guest role if they haven't explicitly joined the domain, improving access control.
259-259
: Added join filter to getDictUserByDomainIdThe query now only returns domain user records where join is true, ensuring consistency with the domain membership model.
292-312
: Good practice: Context-based initializationThe new apply function properly sets up the domain module within the context system. It registers an event handler for cache deletion and ensures database indexes are created, encapsulating initialization logic in a clean way.
The handling of domain cache deletion is well implemented, with proper checks and cleanup of both id and host-based cache entries.
packages/hydrooj/src/entry/common.ts (7)
24-24
: Simplified LoadTask type definitionThe
LoadTask
type has been simplified to only include 'model', 'addon', and 'service', removing other options like 'handler', 'lib', and 'script'. This is part of the larger API cleanup in the v5 refactoring.
25-26
: Function signature and parameter handling improvementsThe
getLoader
function has been updated to use a more structured approach withRecord<string, string>
instead of an array of strings, which provides better type safety and key-value mapping. The iteration pattern usingObject.entries()
makes the code more explicit about handling both names and paths.
29-30
: Improved variable naming for better readabilityRenamed
name
toloadType
to better reflect its purpose, avoiding confusion with the parametername
now extracted from the entries.
32-33
: Simplified plugin reloadingThe reloadPlugin call has been simplified by removing unnecessary parameters. This is consistent with the context handling improvements throughout the codebase.
56-57
: Consistent plugin loading patternUpdated
builtinModel
to follow the same pattern as other loader functions, simplifying the reloadPlugin call by using an empty string instead of an empty object.
60-61
: Updated locale function parameter handlingThe
locale
function now accepts aRecord<string, string>
and usesObject.values()
to iterate through the paths, providing a more structured approach to locale loading.
83-90
: Improved settings function signature and iterationThe
setting
function signature has been updated to use aRecord<string, string>
type for better type safety, and the iteration has been updated to useObject.values()
. This is consistent with the changes in other functions.packages/hydrooj/package.json (9)
3-3
: Major version upgrade to v5.0.0-alpha.0The version has been updated from 4.19.1 to 5.0.0-alpha.0, indicating a major version upgrade with breaking changes. This aligns with the significant architectural changes throughout the codebase.
19-21
: Cordis framework migrationAdded new dependencies from the Cordis framework ecosystem, replacing the monolithic "cordis" package with more modular components. This suggests a transition to a more modular architecture with better separation of concerns.
22-28
: Updated dependencies for better compatibilityThe GraphQL tools and libzip dependencies have been updated to newer versions for better compatibility and potentially addressing security issues.
36-36
: Updated GraphQL scalars dependencyUpdated graphql-scalars to the latest version for improved GraphQL schema support.
46-46
: Updated nanoid dependencyUpdated nanoid to the latest version for improved ID generation capabilities.
52-52
: Updated schemastery dependencyUpdated schemastery to the latest version for improved schema validation.
55-58
: Updated networking and user-agent dependenciesUpdated superagent and ua-parser-js for better HTTP request handling and user agent parsing. These updates may include security fixes and performance improvements.
67-67
: Updated TypeScript type definitionsUpdated Lodash type definitions for better TypeScript support.
44-44
:❓ Verification inconclusive
Major MongoDB driver upgrade
The MongoDB driver has been upgraded from version 5.x to 6.x, which is a major version change that might introduce breaking changes. Ensure that all MongoDB operations have been tested with the new driver version.
🏁 Script executed:
#!/bin/bash # Search for MongoDB API usages that might be affected by the driver upgrade echo "Checking for MongoDB API usages that might need updates..." rg -A 2 -B 2 "mongodb|Collection\.|Db\.|MongoClient" --type tsLength of output: 23062
Action Required: Validate MongoDB API Compatibility with v6.x
The
mongodb
dependency has been upgraded from v5.x to ^6.15.0. A repository-wide search shows that core MongoDB interfaces (e.g.,MongoClient
,ObjectId
,Db
, andCollection
) are still being used in the same way across multiple files (for example, inpackages/hydrooj/src/service/db.ts
andpackages/hydrooj/src/entry/setup.ts
). However, given the major driver upgrade, please ensure that all MongoDB operations—especially connection handling and query methods—are thoroughly tested against the new v6.x driver to catch any subtle behavioral changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (2)
packages/hydrooj/src/handler/home.ts (1)
483-494
:⚠️ Potential issueCritical: Handle potential null from getById
In line 491, the code uses a non-null assertion
!
on the result ofawait user.getById(ddoc._id, this.user._id)
, which assumes that a valid user document is always returned. To prevent potential runtime errors ifgetById
returnsnull
, explicitly handle the null case.- const udoc = await user.getById(ddoc._id, this.user._id); - canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); - role[ddoc._id] = udoc.role; + const udoc = await user.getById(ddoc._id, this.user._id); + if (!udoc) { + canManage[ddoc._id] = false; + role[ddoc._id] = ''; + continue; + } + canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); + role[ddoc._id] = udoc.role;packages/hydrooj/src/model/domain.ts (1)
138-138
:⚠️ Potential issueUse Array.isArray() instead of instanceof Array.
The
instanceof Array
check can be unreliable when dealing with arrays from different contexts or frames.- if (!(Array.isArray(uid))) { + if (!Array.isArray(uid)) {
🧹 Nitpick comments (6)
packages/hydrooj/src/model/domain.ts (1)
108-108
: Return the complete result object.Instead of returning undefined, the method now returns the complete result object from MongoDB, providing more information to callers.
Consider adding a return type annotation to clarify what callers should expect.
packages/hydrooj/src/handler/domain.ts (2)
333-348
: Enhanced domain join preparation with target parameterThe addition of the
target
parameter makes the prepare method more flexible. The implementation properly checks membership status and role assignment based on privileges.For line 346, consider using an assignment instead of the delete operator for better performance:
- if (assignedRole !== 'default') delete this.joinSettings; + if (assignedRole !== 'default') this.joinSettings = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 346-346: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
156-156
: Performance: Avoid using delete operatorThe delete operator can impact performance. Consider using an assignment instead.
- delete u.user; + u.user = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 156-156: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
README.md (3)
124-138
: Clarify and Enhance Update Log EntriesThe new update log entries in the “Unreleased” section (lines 124–138) introduce several important changes—such as adding a warning about shm space, upgrading to cordis@4, supporting multiple renderers, separating HMR and Watcher components, and more. Please verify that each bullet point is clearly written for end users and that any necessary upgrade or migration instructions are provided (especially for breaking or major dependency changes).
🧰 Tools
🪛 LanguageTool
[uncategorized] ~136-~136: 动词的修饰一般为‘形容词(副词)+地+动词’。您的意思是否是:新"地"加
Context: ...修复文件复制 - core: 支持存储并显示提交记录重测历史 - core: 新的加域逻辑 - ui: UserSelect.Multi: 支持批量粘贴用户名 ...(wb4)
137-137
: Refine Changelog DescriptionOn line 137, the entry “core: 新的加域逻辑” could benefit from more specificity. It may help users better understand the impact if the description details what aspect of the domain logic is being updated (for example, specifying “优化后的加域策略” or similar).
142-149
: Review Breaking API ChangesThe entries under “Breaking API Changes” (lines 142–149) include several removals and enforced changes (e.g. no longer supporting code reading during checker compilation, mandatory use of dependency injection, removal of legacy bus calls, global assignments, and an upgrade to the Mongo Driver 6). It’s critical to ensure that these breaking changes are well-documented in your migration guides so that downstream users can adapt their integrations without surprises.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
README.md
(1 hunks)packages/hydrooj/locales/ko.yaml
(1 hunks)packages/hydrooj/locales/zh.yaml
(1 hunks)packages/hydrooj/locales/zh_TW.yaml
(1 hunks)packages/hydrooj/src/handler/domain.ts
(5 hunks)packages/hydrooj/src/handler/home.ts
(4 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/ui-default/locales/ko.yaml
(2 hunks)packages/ui-default/locales/zh.yaml
(7 hunks)packages/ui-default/locales/zh_TW.yaml
(2 hunks)packages/ui-default/pages/domain_user.page.js
(4 hunks)packages/ui-default/pages/home_domain.page.styl
(1 hunks)packages/ui-default/templates/home_domain.html
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/ui-default/templates/home_domain.html
- packages/ui-default/locales/zh.yaml
🧰 Additional context used
🧬 Code Definitions (2)
packages/hydrooj/src/handler/home.ts (3)
framework/framework/server.ts (1) (1)
all
(299-299)packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)framework/framework/validator.ts (2) (2)
Types
(13-52)Types
(77-190)
packages/hydrooj/src/model/domain.ts (4)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/home.ts
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 509-509: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/handler/domain.ts
[error] 156-156: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 168-168: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 346-346: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🪛 LanguageTool
README.md
[uncategorized] ~136-~136: 动词的修饰一般为‘形容词(副词)+地+动词’。您的意思是否是:新"地"加
Context: ...修复文件复制 - core: 支持存储并显示提交记录重测历史 - core: 新的加域逻辑 - ui: UserSelect.Multi: 支持批量粘贴用户名 ...
(wb4)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (37)
packages/hydrooj/src/handler/home.ts (5)
184-185
: Good refactor: Extracting geoip from contextThe introduction of a local variable
geoip
improves code readability by avoiding repeated access tothis.ctx.get('geoip')
throughout the method.
192-195
: Consistent with refactoring patternThe change to use the extracted
geoip
variable instead of directly accessingthis.ctx.geoip
makes the code more consistent and readable.
205-205
: Consistent with refactoring patternUsing the extracted
geoip
variable for accessing the provider property maintains consistency with the earlier changes.
472-474
: Good refactor: Improved data structure organizationRenaming
res
to the more descriptiveddocs
and introducing a separaterole
record improves code organization and readability.
497-497
: Good refactor: Consistent response structureUpdating the response body to include
role
instead ofdudict
provides a more consistent and clearer response structure.packages/hydrooj/src/model/domain.ts (13)
4-4
: Updated import to include Context.The import of
Context
from '../context' has been added to support the newapply
function.
62-62
: Improved user role assignment with automatic join capability.The call to
setUserRole
has been updated to includetrue
for the newautojoin
parameter, ensuring that domain owners are automatically marked as joined when the domain is created.
104-106
: Enhanced result handling in edit method.The code now properly uses the result from
findOneAndUpdate
in subsequent operations and event broadcasting.
114-115
: Improved return value handling.The code now uses optional chaining to safely access the field property when returning from the
inc
method.Also applies to: 120-120
130-132
: Enhanced user counting with join property.The
countUser
method now includes thejoin: true
filter to only count users who have officially joined the domain, rather than all users with any association.
136-138
: Improved role assignment with join property support.The
setUserRole
method now supports an optionalautojoin
parameter which allows conditionally setting thejoin
property when assigning roles.
139-146
: Enhanced user role update operation.The role setting operation now provides detailed information by using the MongoDB options
returnDocument: 'after'
andincludeResultMetadata: true
.
152-153
: Updated bulk user role assignment.The role update operation now correctly uses the newly defined
update
variable which includes the autojoin condition.
155-162
: Added method to control domain membership.The new
setJoin
method provides a dedicated way to manage the join status of users, allowing for leaving/joining domains without changing roles.
183-185
: Role filtering improvement in getRoles.By filtering directly in the array instead of using a loop, the code is more concise and readable.
222-222
: Enhanced role determination logic.Users who haven't joined the domain (
!dudoc.join
) are now assigned the 'guest' role, unless they have the privilege to view all domains.
268-268
: Query filtering enhancement in getDictUserByDomainId.The method now includes the
join: true
filter to only retrieve domains that the user has actively joined.
301-321
: Added context-based initialization function.A new
apply
function has been introduced to handle domain-related initialization tasks:
- Setting up an event listener for cache invalidation when domains are deleted
- Ensuring database indexes for domain collections
This follows a dependency injection pattern, enabling better testability and modular design.
packages/ui-default/pages/home_domain.page.styl (1)
14-14
: Increased action column width.The width of the
.col--action
column has been increased from 135px to 200px, providing more space for UI elements like the new "Leave" button.packages/hydrooj/locales/ko.yaml (1)
812-812
: Added Korean localization for domain kick notification.A new message has been added to inform users when they've been kicked from a domain, showing both the domain name and the user who performed the action.
packages/ui-default/locales/ko.yaml (2)
683-683
: Added Korean localization for Leave action.A new translation entry for "Leave" has been added as "나가기", which will be used for the UI button to leave a domain.
692-692
: Updated messaging for domain membership status.The message has been updated to clarify that users removed from a domain will have the "guest" role (instead of "default") until they rejoin, aligning with the code changes in the DomainModel.
packages/hydrooj/locales/zh_TW.yaml (1)
553-553
: Consistent user notification when kicked from a domain.This new message provides clear feedback to users when they're removed from a domain, showing both the domain name and who performed the action. This improves user experience by providing explicit context for the state change.
packages/ui-default/locales/zh_TW.yaml (2)
241-241
: LGTM! New "Leave" translation added.The addition of "Leave: 離開" provides a translation for a user action, maintaining language consistency in the Traditional Chinese localization.
466-466
: Clearer messaging for domain role transitions.The message now specifically states that removed users will have a "guest role" rather than a "default role" until they rejoin the domain. This provides more precise information about the state transition when users are removed.
packages/hydrooj/locales/zh.yaml (1)
936-936
: Consistent user notification when kicked from a domain.This new message provides clear feedback to users when they're removed from a domain, showing both the domain name and who performed the action. This matches the similar addition in zh_TW.yaml for language consistency.
packages/ui-default/pages/domain_user.page.js (5)
63-65
: Updated API for adding users to use plural endpoint.The operation has been changed from 'set_user' to 'set_users' and now accepts an array of user IDs instead of a single ID. This change maintains consistency with other user management operations that have been pluralized.
94-94
: Updated message for user removal confirms guest role assignment.The confirmation message now specifies that removed users will have the "guest role" until they rejoin, which aligns with the updated localization strings and provides clearer information to administrators.
100-102
: Improved semantics for user removal operation.The operation has been renamed from 'set_users' to 'kick', which better describes the action being performed. The parameter has also been updated from 'uid' to 'uids' to handle multiple users, making the API more consistent.
123-126
: Updated to support bulk role assignment.The API call now uses 'uids' as a parameter name, which accepts an array of user IDs for bulk role updates. This change makes the code more consistent and efficient for managing multiple users simultaneously.
140-142
: Updated single user role change to use plural endpoint.The individual user role change now uses the 'set_users' operation with an array containing a single user ID, maintaining consistency with the updated API pattern used throughout the file.
packages/hydrooj/src/handler/domain.ts (6)
106-160
: Improved data aggregation approach with MongoDB pipelineThe refactoring to use MongoDB's aggregation pipeline is a significant improvement over the previous implementation. This approach efficiently joins user details from the user collection, properly filters roles, and produces a cleaner response structure.
🧰 Tools
🪛 Biome (1.9.4)
[error] 156-156: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
175-175
: Method renamed to reflect batch processing capabilityChanged from
postSetUser
topostSetUsers
to better reflect that it now handles multiple users at once.
185-198
: New kick functionality with proper user notificationThe new postKick method is well-implemented with:
- Proper filtering of users that need updates
- Batch processing support
- User notifications through the message system
269-269
: Role filtering adjustmentChanged to exclude only the 'guest' role instead of both 'default' and 'guest', allowing default role to be selectable.
352-369
: Improved domain join interface with detailed domain informationThe enhanced response structure now includes comprehensive domain information, making the UI more informative for users trying to join a domain.
373-388
: More flexible domain join process with target and redirect parametersThe enhanced post method provides better flexibility for redirects and target domain specification, with proper role assignment based on join settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (7)
packages/elastic/index.ts (4)
34-55
:⚠️ Potential issueOptional parameter access needs safer handling.
While you've provided a default value for the
opts
parameter in the function signature, the direct access toopts.skip
without optional chaining could cause runtime errors.- if (!opts.skip) { + if (!opts?.skip) {
72-72
: 🛠️ Refactor suggestionAdd proper type annotations for the run method parameters.
The parameters in the
run
method lack proper type annotations, which reduces type safety.- async run({ domainId }, report) { + async run({ domainId }: { domainId?: string }, report: (status: { message: string }) => void) {
95-116
: 🛠️ Refactor suggestionAdd proper error handling to event listeners.
The event handlers for problem operations don't include error handling, which could lead to unhandled promise rejections.
this.ctx.on('problem/add', async (doc, docId) => { + try { await this.client.index({ index: 'problem', id: `${doc.domainId}/${docId}`, document: processDocument(doc), }); + } catch (error) { + this.ctx.logger.error(`Error indexing problem: ${error.message}`); + } });Similarly for the other event handlers.
117-124
: 🛠️ Refactor suggestionHandle potential errors in script execution.
The script registration doesn't include error handling for the
run
method when used as a callback.- this.run.bind(this), + async (...args) => { + try { + return await this.run.bind(this)(...args); + } catch (error) { + this.ctx.logger.error(`Error in ensureElasticSearch script: ${error.message}`); + throw error; + } + },packages/hydrooj/src/handler/home.ts (3)
471-471
:⚠️ Potential issueFix empty object pattern in function parameter.
The empty object pattern
{ }
is flagged by the static analysis tool. This appears to be part of a larger pattern change in the codebase, but you should use a named parameter for clarity.- async get({ }, all: boolean) { + async get({ domainId }: Record<string, never>, all: boolean) {🧰 Tools
🪛 Biome (1.9.4)
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
483-494
:⚠️ Potential issueCritical: Handle potential null from getById
In lines 489-494, the code uses a non-null assertion on the result of
user.getById(ddoc._id, this.user._id)
, which assumes that a valid user document is always returned. Our verification shows that elsewhere in the codebase (e.g., in packages/ui-default/index.ts), conditional logic is applied aroundgetById
calls when necessary. To prevent potential runtime errors ifgetById
returnsnull
, it is strongly recommended to explicitly handle the null case.- const udoc = await user.getById(ddoc._id, this.user._id); - canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); - role[ddoc._id] = udoc.role; + const udoc = await user.getById(ddoc._id, this.user._id); + if (!udoc) { + canManage[ddoc._id] = false; + role[ddoc._id] = ''; + continue; + } + canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); + role[ddoc._id] = udoc.role;
508-514
:⚠️ Potential issueFix empty object pattern in function parameter
Similar to the previous issue, the empty object pattern
{ }
is flagged by the static analysis tool. Use a named parameter for clarity.- async postLeave({ }, id: string) { + async postLeave({ domainId }: Record<string, never>, id: string) {The implementation of this new method is clean and appropriately handles domain leaving functionality.
🧰 Tools
🪛 Biome (1.9.4)
[error] 509-509: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🧹 Nitpick comments (2)
packages/elastic/index.ts (2)
20-32
: Consider removing the console.log statement in the constructor.The constructor includes a debug console.log statement which should be removed or replaced with proper logging using the context logger.
- console.log('elastic-search', config); + // If logging is needed, use the context logger + // this.ctx.logger.debug('elastic-search initialized with config', config);
124-124
: Add documentation comments for the provided module.Adding JSDoc comments to the module provision would help other developers understand what the module does and how to use it.
+ /** + * Provides the problemSearch functionality through the elastic search implementation. + * @param domainId - The domain ID to search in + * @param q - The query string to search for + * @param opts - Optional parameters for pagination + * @returns A promise resolving to search results + */ this.ctx.provideModule('problemSearch', 'elastic', this.problemSearch.bind(this));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
framework/eslint-config/package.json
(1 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrooj/src/handler/discussion.ts
(1 hunks)packages/hydrooj/src/handler/home.ts
(4 hunks)packages/hydrooj/src/loader.ts
(6 hunks)packages/hydrooj/src/model/document.ts
(13 hunks)packages/hydrooj/src/model/domain.ts
(9 hunks)packages/scoreboard-xcpcio/package.json
(1 hunks)packages/ui-default/package.json
(4 hunks)packages/ui-next/package.json
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- packages/ui-next/package.json
- framework/eslint-config/package.json
- package.json
- packages/hydrooj/src/model/document.ts
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (3)
packages/elastic/index.ts (7)
packages/hydrooj/src/plugin-api.ts (2) (2)
Service
(41-41)Context
(41-41)packages/ui-default/backendlib/template.ts (1) (1)
Context
(254-275)packages/hydrooj/src/settings.ts (1) (1)
Context
(30-34)packages/vjudge/src/index.ts (1) (1)
Context
(191-196)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)packages/hydrooj/src/interface.ts (1) (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1) (1)
ProblemModel
(74-675)
packages/hydrooj/src/handler/home.ts (3)
framework/framework/server.ts (1) (1)
all
(299-299)packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)framework/framework/validator.ts (2) (2)
Types
(13-52)Types
(77-190)
packages/hydrooj/src/model/domain.ts (5)
packages/hydrooj/src/interface.ts (1) (1)
DomainDoc
(306-314)packages/hydrooj/src/model/user.ts (2) (2)
deleteUserCache
(28-47)apply
(477-495)packages/hydrooj/src/service/bus.ts (1) (1)
apply
(96-113)packages/hydrooj/src/plugin-api.ts (2) (2)
Context
(41-41)db
(58-58)packages/hydrooj/src/service/db.ts (1) (1)
Context
(58-66)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/home.ts
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 509-509: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
🔇 Additional comments (29)
packages/hydrooj/src/handler/home.ts (6)
184-184
: Good refactoring: Extracted geoip context.Extracting the geoip context into a local variable improves readability and follows the principle of single responsibility. This change simplifies the code by reducing repeated access to
this.ctx.geoip
.
192-195
: Clean code: Consistent use of extracted geoip variable.The code now uses the extracted
geoip
variable consistently when settingsession.updateGeoip
, which improves readability and maintains the code's consistency.
205-205
: Consistent refactoring: Using extracted geoip variable.Using the extracted
geoip
variable for thegeoipProvider
property maintains consistency with the earlier changes and improves code readability.
472-473
: Better type safety with explicit declarations.Replacing untyped arrays and objects with explicit type declarations (
DomainDoc[]
andRecord<string, string>
) improves type safety and makes the code more self-documenting.
475-477
: Improved variable naming with role instead of dudict.The refactoring replaces
dudict
with a more descriptiverole
object, which better represents its purpose of storing user roles in domains.
497-497
: Consistent use of role instead of dudict in response.The response body now uses
role
instead ofdudict
, which is consistent with the variable renaming earlier in the method. This makes the code more readable and maintainable.packages/hydrooj/src/loader.ts (11)
15-17
: Enhanced type imports from context.The imports from './context' now include more specific types like
ScopeStatus
andEffectScope
, which improves code clarity and type safety.
22-22
: Added Schema for configuration validation.Importing Schema from 'schemastery' enables stronger configuration validation, improving the reliability of the configuration system.
53-54
: Explicit dependency injection.The static inject property clearly defines the dependencies required by the Loader service, which enhances maintainability and testability.
55-57
: Constructor now accepts Context properly.The constructor now correctly accepts a Context parameter instead of using the global app, making dependency injection more explicit and improving testability.
58-59
: Async event listener for app/started.The event listener for 'app/started' is now correctly attached to ctx and uses an async callback function, which allows for better async operations handling.
97-106
: Well-designed resolveConfig method.The new resolveConfig method provides a clean way to handle plugin configurations with proper schema validation. It correctly handles configScope and falls back to the root schema when needed.
108-116
: Improved reloadPlugin with configuration scope.The reloadPlugin method now handles configuration scopes and uses the new resolveConfig method, providing better flexibility when loading plugins.
134-136
: Better error logging in resolvePlugin.The error logging in resolvePlugin has been improved to provide more context when a plugin fails to resolve.
146-152
: Key improvement: Async preload function with proper Promise handling.Converting preload to an async function with proper Promise handling for initializing global.app improves the startup sequence and error handling. This ensures that all asynchronous operations are completed before proceeding.
169-171
: Load function now properly awaits preload.The load function is now async and properly awaits the preload function, ensuring that all initialization is completed before continuing.
207-210
: LoadCli function now properly awaits preload.Similar to the load function, loadCli is now async and properly awaits preload, ensuring consistent initialization.
packages/scoreboard-xcpcio/package.json (1)
10-10
:✅ Verification successful
Version update for
@xcpcio/board-app
dependency.The dependency version has been updated from
^0.53.2
to^0.54.0
. This is a minor version update that likely introduces new features while maintaining backward compatibility according to semantic versioning principles.
🏁 Script executed:
#!/bin/bash # Check for any breaking changes or significant updates in the release notes or changelog # Try to find changelog or release notes for the package curl -s https://registry.npmjs.org/@xcpcio/board-app | jq '.versions["0.54.0"].dist.tarball' | xargs curl -sL | tar -xzf - -O --wildcards "*/CHANGELOG.md" 2>/dev/null || echo "No CHANGELOG.md found" # Look for GitHub repository in package info to check releases curl -s https://registry.npmjs.org/@xcpcio/board-app | jq -r '.repository.url' | sed 's/git+//;s/.git$//' | xargs -I{} curl -s {}/releases/tag/v0.54.0 2>/dev/null | grep -o '<div class="markdown-body">.*</div>' || echo "No release notes found"Length of output: 467
Dependency Update Approved: @xcpcio/board-app
- The dependency was updated from
^0.53.2
to^0.54.0
, which is a minor version bump.- Verification via the release notes/changelog script returned no changelog or explicit release notes; however, according to semantic versioning, minor updates typically introduce new features without breaking backward compatibility.
- No further concerns were identified. Please ensure regular testing as usual.
packages/hydrooj/src/handler/discussion.ts (1)
75-75
:✅ Verification successful
Performance optimization added through database hint.
Adding
.hint('discussionSort')
to the MongoDB query is a good performance optimization that forces the query to use a specific index named 'discussionSort', which should improve the efficiency of discussion listing operations.
🏁 Script executed:
#!/bin/bash # Check if the discussionSort index is properly defined in the codebase # Look for index definition in the discussion model rg -A 3 -B 3 "discussionSort" --glob "*.ts" packages/hydrooj/src/model/discussion.ts # Check for any createIndex calls related to discussions rg -A 3 "createIndex.*discussion" --glob "*.ts" # Look for any schema definitions or migrations that might define this index rg -A 5 "discussionSort|discussion.*index" --glob "*.ts" packages/hydrooj/src/model/Length of output: 964
Index 'discussionSort' confirmed and properly applied in the query.
The grep results show that the index named'discussionSort'
is defined in the model (inpackages/hydrooj/src/model/document.ts
), which validates that using.hint('discussionSort')
in the query is a proper and effective performance optimization for discussion listings.
- Location verified:
packages/hydrooj/src/model/document.ts
contains the index definition.- Handler reference:
packages/hydrooj/src/handler/discussion.ts
correctly applies the hint in the query.No further modifications are necessary.
packages/hydrooj/src/model/domain.ts (10)
4-6
: Good: Improved module import patterns.The changes to the import statements are appropriate - importing the Context type for use in the new
apply
function and switching from namespace import to default import for the bus service aligns with modern JavaScript/TypeScript module patterns.
104-108
: Good: Enhanced return value in the edit method.The edit method now returns the complete result object from findOneAndUpdate instead of just a specific field, providing more information to callers.
120-120
: Simplified return value in inc method.Returning
value?.[field]
directly provides a cleaner API by returning exactly the incremented field value. The optional chaining correctly handles null cases.
136-138
: Use Array.isArray() instead of instanceof Array.The
instanceof Array
check can be unreliable when dealing with arrays from different contexts or frames.- if (!(uid instanceof Array)) { + if (!(Array.isArray(uid))) {
136-153
: Good: Enhanced setUserRole with autojoin capability.The addition of the
autojoin
parameter with a default value offalse
provides a clean way to optionally set thejoin
property when setting a user's role, maintaining backward compatibility.
155-162
: Good: Added dedicated method for join management.The new
setJoin
method provides a clean API for managing domain membership, appropriately handling both single users and arrays of users with optimized batch updates for arrays.
301-309
: Critical: Mismatch Between Interface and Usage of Host PropertyThe DomainDoc interface (in
packages/hydrooj/src/interface.ts
) defines the property ashost?: string[]
, but the code inpackages/hydrooj/src/model/domain.ts
is accessingddoc.host
. This discrepancy can lead to runtime issues (such as missed cache invalidation) because the expected property name in the interface does not match its usage in the code.
- Update the code at line 305 in
packages/hydrooj/src/model/domain.ts
to useddoc.host
instead ofddoc.hosts
(or update the interface if the plural form is intended).
301-321
: Good: Consolidated initialization into apply function.The new
apply
function provides a clean way to initialize all domain-related event handlers and database indexes in one place, improving code organization and maintainability.
268-268
:❓ Verification inconclusive
Verify impact of adding
join: true
filter condition.Similar to the change in
countUser
, this modifies the behavior to only include users who have explicitly joined the domain. This could break existing code that expects to get all domain users regardless of join status.
🏁 Script executed:
#!/bin/bash # Search for calls to getDictUserByDomainId to verify that callers handle the new behavior echo "Finding all calls to DomainModel.getDictUserByDomainId:" rg -A 2 "getDictUserByDomainId" --type tsLength of output: 1086
Action: Confirm that call sites properly handle the new "joined-only" behavior.
The change to
const dudocs = await collUser.find({ uid, join: true }).toArray();now filters out users who have not explicitly joined the domain. Our search shows that the only direct consumers of
getDictUserByDomainId
are in:
packages/hydrooj/src/handler/home.ts
packages/hydrooj/src/handler/domain.ts
Both call sites currently invoke this method and then process the returned dictionary by extracting the keys. Please verify that neither location expects to include users that haven’t joined the domain. If any caller needs to access all domain users regardless of join status, additional adjustments may be required.
131-132
:✅ Verification successful
Verify impact of adding
join: true
filter condition.Adding the
join: true
condition to the query changes the behavior to only count users who have explicitly joined the domain. This is a behavioral change that might affect existing code that relies on counting all users regardless of their join status.
🏁 Script executed:
#!/bin/bash # Search for calls to countUser to verify that callers handle the new behavior echo "Finding all calls to DomainModel.countUser:" rg -A 2 "countUser" --type tsLength of output: 678
Action: Confirm the intended behavior of counting only joined users
After verifying the call sites, it appears that the only invocation of
DomainModel.countUser
is within the same file where a role is always passed (e.g.,role.count = await DomainModel.countUser(ddoc._id, role._id);
). This means both branches of the method now consistently count only users withjoin: true
. There are no other callers expecting a full count of users regardless of their join status.
- Location:
packages/hydrooj/src/model/domain.ts
(both the method definition and its call site)- Impact: The filtering condition applies uniformly. If there’s any future need to count all users (including those not joined), a distinct query or changes to this method might be necessary.
- Next Step: Ensure that the business logic indeed requires counting only joined users in all cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
packages/hydrooj/src/upgrade.ts (2)
427-427
:⚠️ Potential issueMissing import for 'app' dependency.
The code references
app.get('config')
but there's no import statement for theapp
object in the file imports.import yaml from 'js-yaml'; import { pick } from 'lodash'; import moment from 'moment-timezone'; import { ObjectId } from 'mongodb'; import { sleep } from '@hydrooj/utils'; +import { app } from './loader'; import { buildContent } from './lib/content';
706-723
: 🛠️ Refactor suggestionAdd error handling to the migration function.
The new migration function for Hydro v5 lacks error handling for database operations, which could lead to incomplete migrations if any operations fail.
// Start Hydro v5 async function _91_92() { + try { await domain.collUser.updateMany({}, { $set: { join: true } }); await domain.coll.updateMany( { $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }, { '_join.method': domain.JOIN_METHOD_NONE }] }, { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, ); const domainUser = await domain.coll.find({ domainId: 'system', join: true }, onPrimary) .project({ uid: 1 }).toArray(); const otherUsers = await user.coll.find({ _id: { $gt: 1, $nin: domainUser.map((u) => u.uid) } }, onPrimary) .project({ _id: 1 }).toArray(); await domain.collUser.updateMany( { uid: { $in: otherUsers.map((u) => u._id) }, domainId: 'system' }, { $set: { join: true } }, { upsert: true }, ); return true; + } catch (error) { + logger.error(`Migration to Hydro v5 failed: ${error.message}`); + throw error; + } }Also consider adding documentation about the purpose of this migration function to improve maintainability.
packages/hydrooj/src/handler/home.ts (1)
483-494
:⚠️ Potential issueCritical: Handle potential null from getById
The code uses a non-null assertion on the result of
user.getById(ddoc._id, this.user._id)
, which assumes that a valid user document is always returned. This could lead to runtime errors if the user is not found in a domain.- const udoc = await user.getById(ddoc._id, this.user._id); - canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); - role[ddoc._id] = udoc.role; + const udoc = await user.getById(ddoc._id, this.user._id); + if (udoc) { + canManage[ddoc._id] = udoc.hasPerm(PERM.PERM_EDIT_DOMAIN); + role[ddoc._id] = udoc.role; + } else { + canManage[ddoc._id] = false; + role[ddoc._id] = ''; + }
🧹 Nitpick comments (3)
packages/hydrooj/src/handler/home.ts (1)
471-471
: Fix empty object pattern in function parameterThe empty object pattern
{ }
is flagged by the static analysis tool. Use a named parameter for clarity.- async get({ }, all: boolean) { + async get({ domainId }: Record<string, never>, all: boolean) {- async postLeave({ }, id: string) { + async postLeave({ domainId }: Record<string, never>, id: string) {Also applies to: 509-509
🧰 Tools
🪛 Biome (1.9.4)
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/handler/domain.ts (2)
151-158
: Consider avoiding the delete operator for better performanceWhile the transformation of user data is clean and effective, using the
delete
operator on line 156 may impact performance.- const u = { - ...dudoc, - ...dudoc.user, - }; - delete u.user; - return u; + const { user: userData, ...rest } = dudoc; + return { + ...rest, + ...userData, + };🧰 Tools
🪛 Biome (1.9.4)
[error] 156-156: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
334-349
: Enhanced domain join flexibility with target parameterThe addition of the
target
parameter increases flexibility by allowing users to join domains other than the current one. The implementation correctly handles role assignment based on privileges and performs proper validation.On line 347, consider using a more performance-friendly approach than the
delete
operator:- if (assignedRole !== 'default') delete this.joinSettings; + if (assignedRole !== 'default') this.joinSettings = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 347-347: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
packages/hydrooj/locales/zh.yaml
(2 hunks)packages/hydrooj/locales/zh_TW.yaml
(2 hunks)packages/hydrooj/src/error.ts
(1 hunks)packages/hydrooj/src/handler/domain.ts
(7 hunks)packages/hydrooj/src/handler/home.ts
(5 hunks)packages/hydrooj/src/model/document.ts
(13 hunks)packages/hydrooj/src/upgrade.ts
(4 hunks)packages/ui-default/locales/ko.yaml
(4 hunks)packages/ui-default/locales/zh.yaml
(8 hunks)packages/ui-default/locales/zh_TW.yaml
(3 hunks)packages/ui-default/templates/domain_join_applications.html
(1 hunks)packages/ui-default/templates/home_domain.html
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/ui-default/templates/domain_join_applications.html
- packages/ui-default/templates/home_domain.html
- packages/ui-default/locales/zh_TW.yaml
- packages/ui-default/locales/ko.yaml
- packages/ui-default/locales/zh.yaml
- packages/hydrooj/src/model/document.ts
🧰 Additional context used
🧬 Code Definitions (1)
packages/hydrooj/src/error.ts (1)
framework/framework/error.ts (1) (1)
ForbiddenError
(50-50)
🪛 Biome (1.9.4)
packages/hydrooj/src/handler/home.ts
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 509-509: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/handler/domain.ts
[error] 156-156: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 168-168: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
[error] 347-347: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (17)
packages/hydrooj/src/upgrade.ts (1)
39-39
: Good addition of read preference configuration.The
onPrimary
constant explicitly sets the read preference to primary, which is appropriate for ensuring consistent reads during migration operations.packages/hydrooj/src/error.ts (1)
45-45
: Enhanced error message format for DomainJoinForbiddenErrorThe error message has been updated to use a more flexible format with placeholders, which will provide users with more specific information about why they cannot join a domain.
packages/hydrooj/locales/zh_TW.yaml (1)
466-467
: Added localized messages for domain membership managementThese new localization entries provide users with more specific feedback about domain access issues, which is a good improvement to the user experience.
Also applies to: 549-550, 556-556
packages/hydrooj/locales/zh.yaml (1)
790-790
: Added localized messages for domain membership managementThese new localization entries provide users with more specific feedback about domain access issues, which is a good improvement to the user experience.
Also applies to: 929-930, 938-938
packages/hydrooj/src/handler/home.ts (4)
184-185
: Improved code readability with local variable for geoipGood refactoring by extracting
this.ctx.geoip
into a local variable, which reduces repetition and makes the code more maintainable.Also applies to: 192-193, 205-206
471-481
: Improved domain retrieval and variable namingGood change to use more descriptive variable names (
ddocs
instead ofres
) and simplify the domain retrieval logic.🧰 Tools
🪛 Biome (1.9.4)
[error] 471-471: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
497-498
: Improved response structure with role informationThe response now includes
role
instead ofdudict
, which is a more descriptive and focused property name.
507-515
: Added functionality for users to leave domainsThis new method provides a way for users to leave domains through the UI, which is a good addition to the user experience. The implementation correctly:
- Validates the domain is not 'system'
- Checks that the domain exists
- Sets the user's join status to false
- Redirects back to the previous page
🧰 Tools
🪛 Biome (1.9.4)
[error] 509-509: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
packages/hydrooj/src/handler/domain.ts (9)
106-148
: Improved data retrieval with MongoDB aggregation pipelineThe refactoring to use MongoDB's aggregation pipeline with
$lookup
is a significant improvement. This approach efficiently joins user details from theuser
collection in a single database operation, reducing the need for additional queries and improving performance for domain user listing.
167-170
: Security Check: Update Parameter DestructuringThe security check preventing modification of the domain owner's role is correctly implemented. However, for consistency with other handler methods (e.g., see other methods in
domain.ts
), the empty object destructuring should be replaced with explicit extraction ofdomainId
.-async post({ }, uids: number[]) { +async post({ domainId }, uids: number[]) {🧰 Tools
🪛 Biome (1.9.4)
[error] 168-168: Unexpected empty object pattern.
(lint/correctness/noEmptyPattern)
173-175
: Enhanced batch processing with array parameterRenaming the method to
postSetUsers
and changing the parameter from a single UID to an array enhances the API's consistency and enables batch processing of user roles.
184-198
: Well-implemented user removal with notificationThe
postKick
method is a robust implementation for removing users from a domain:
- It checks which users actually need updates before proceeding
- It handles both single and multiple user IDs
- It properly notifies kicked users with a formatted message
269-269
: Streamlined role filteringThe change to only exclude the 'guest' role instead of both 'default' and 'guest' streamlines the role management process and allows default users to be included in role selection.
283-286
: Added group assignment capabilityAdding the group parameter enhances domain join functionality by allowing users to be automatically assigned to specific groups upon joining, which simplifies user onboarding.
295-295
: Group parameter included in join settingsThe group parameter is properly incorporated into the join settings structure.
353-370
: Improved response with detailed domain informationThe enhanced response body now includes comprehensive domain information (name, owner, avatar, bulletin), improving the user experience by providing context about the domain being joined.
374-395
: Robust domain join process with group assignmentThe updated implementation properly handles:
- Invitation code validation
- Group assignment when specified
- Dynamic role assignment based on join settings
- Appropriate redirection after successful join
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (7)
packages/hydrooj/src/upgrade.ts (2)
427-427
:⚠️ Potential issueMissing import for 'app' dependency.
The code references
app.get('config')
but there's no import statement for theapp
object in the file imports.import yaml from 'js-yaml'; import { pick } from 'lodash'; import moment from 'moment-timezone'; import { ObjectId } from 'mongodb'; import { sleep } from '@hydrooj/utils'; +import { app } from './loader'; import { buildContent } from './lib/content';
706-723
: 🛠️ Refactor suggestionAdd error handling to the migration function.
The new migration function for Hydro v5 lacks error handling for database operations, which could lead to incomplete migrations if any operations fail.
// Start Hydro v5 async function _91_92() { + try { await domain.collUser.updateMany({}, { $set: { join: true } }); await domain.coll.updateMany( { $or: [{ _join: { $exists: false } }, { _join: { $eq: null } }, { '_join.method': domain.JOIN_METHOD_NONE }] }, { $set: { _join: { method: domain.JOIN_METHOD_ALL, role: 'default', expire: null }, _migratedJoin: true } }, ); const domainUser = await domain.collUser.find({ domainId: 'system', join: true }, onPrimary) .project({ uid: 1 }).toArray(); const otherUsers = await user.coll.find({ _id: { $gt: 1, $nin: domainUser.map((u) => u.uid) } }, onPrimary) .project({ _id: 1 }).toArray(); await domain.collUser.updateMany( { uid: { $in: otherUsers.map((u) => u._id) }, domainId: 'system' }, { $set: { join: true } }, { upsert: true }, ); return true; + } catch (error) { + logger.error(`Migration to Hydro v5 failed: ${error.message}`); + throw error; + } }packages/elastic/index.ts (4)
54-54
:⚠️ Potential issuePotential null/undefined access still exists.
The code still accesses
opts.skip
without a safety check, which could lead to runtime errors ifopts
is undefined.Apply this fix to ensure safe property access:
-if (!opts.skip) { +if (!opts?.skip) {
71-77
: 🛠️ Refactor suggestionMissing type annotations for the run method parameters.
The method parameters lack proper type annotations, which was mentioned in a previous review comment. Consider adding proper types to improve type safety.
-async run({ domainId }, report) { +async run({ domainId }: { domainId?: string }, report: (status: { message: string }) => void) {
94-115
: 🛠️ Refactor suggestionMissing error handling in event listeners.
The event handlers for 'problem/add', 'problem/edit', and 'problem/del' don't include proper error handling. If these operations fail, the errors will propagate as unhandled promise rejections.
Example fix for one of the handlers:
this.ctx.on('problem/add', async (doc, docId) => { + try { await this.client.index({ index: 'problem', id: `${doc.domainId}/${docId}`, document: processDocument(doc), }); + } catch (error) { + this.ctx.logger.error(`Error indexing problem: ${error.message}`); + } });Apply similar error handling to the other event handlers.
116-122
: 🛠️ Refactor suggestionError handling missing in script registration.
The script registration doesn't include error handling for the
run
method when used as a callback.- this.run.bind(this), + async (...args) => { + try { + return await this.run.bind(this)(...args); + } catch (error) { + this.ctx.logger.error(`Error in ensureElasticSearch script: ${error.message}`); + throw error; + } + },framework/framework/server.ts (1)
141-142
:⚠️ Potential issueFix unsafe interface-class declaration merging.
The empty interface
HandlerCommon<C>
followed by a class with the same name is a TypeScript anti-pattern that bypasses type checking for interface properties. When you merge an interface and class declaration, TypeScript won't verify that the class properly initializes interface properties.-export interface HandlerCommon<C> { } // eslint-disable-line @typescript-eslint/no-unused-vars -export class HandlerCommon<C> { +// Use a type alias or rename the interface if you need additional properties later +export class HandlerCommon<C> {🧰 Tools
🪛 Biome (1.9.4)
[error] 141-141: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 142-142: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
framework/eslint-config/package.json
(1 hunks)framework/framework/decorators.ts
(5 hunks)framework/framework/server.ts
(22 hunks)package.json
(2 hunks)packages/elastic/index.ts
(2 hunks)packages/hydrooj/src/service/server.ts
(9 hunks)packages/hydrooj/src/upgrade.ts
(4 hunks)packages/ui-default/package.json
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- framework/framework/decorators.ts
- framework/eslint-config/package.json
- package.json
- packages/ui-default/package.json
🧰 Additional context used
🧬 Code Definitions (3)
packages/elastic/index.ts (3)
packages/hydrooj/src/plugin-api.ts (2)
Service
(41-41)Context
(41-41)packages/hydrooj/src/interface.ts (1)
ProblemSearch
(619-619)packages/hydrooj/src/model/problem.ts (1)
ProblemModel
(74-675)
packages/hydrooj/src/service/server.ts (4)
packages/hydrooj/src/plugin-api.ts (5)
HandlerCommon
(7-7)Handler
(40-40)Context
(41-41)ConnectionHandler
(40-40)WebService
(7-7)packages/hydrooj/src/context.ts (2)
Context
(31-41)Context
(68-77)packages/hydrooj/src/service/bus.ts (1)
apply
(96-113)packages/hydrooj/src/error.ts (2)
PermissionError
(22-27)PrivilegeError
(28-33)
framework/framework/server.ts (4)
packages/hydrooj/src/service/layers/user.ts (1)
ctx
(5-18)packages/hydrooj/src/plugin-api.ts (3)
Handler
(40-40)Service
(41-41)Context
(41-41)framework/framework/interface.ts (1)
KnownHandlers
(3-5)packages/hydrooj/src/context.ts (2)
Context
(31-41)Context
(68-77)
🪛 Biome (1.9.4)
framework/framework/server.ts
[error] 141-141: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
[error] 142-142: This class is unsafely merged with an interface.
The interface is declared here.
The TypeScript compiler doesn't check whether properties defined in the interface are initialized in the class.
(lint/suspicious/noUnsafeDeclarationMerging)
🔇 Additional comments (19)
packages/hydrooj/src/upgrade.ts (1)
39-40
: Good addition of MongoDB read preference.The
onPrimary
constant ensures database operations are directed to the primary node in a replica set, which is important for write operations and consistency in read operations.packages/elastic/index.ts (5)
4-4
: Good improvement: Added missing imports from hydrooj.The import statement has been expanded to include necessary types and classes like
ProblemSearch
,Schema
, andService
, which are used in the refactored code. This improves code readability and type safety.
20-25
: Well-structured class with proper configuration schema.The refactoring from global functions to a class-based approach with
ElasticSearchService
is a significant improvement. The static configuration schema properly defines and validates the required settings with sensible defaults.
26-31
: Constructor properly initializes the Elasticsearch client.The constructor appropriately initializes the client using the configuration URL and stores the config for later use. The use of private modifier for the config parameter is a good practice.
33-33
: Improved type safety with proper parameter typing.The method signature now uses
Parameters<ProblemSearch>[2]
to ensure type compatibility with the original interface, resolving the previous review comment about missing type annotations.
123-123
: Good modularization with module provider.The use of
provideModule
to make theproblemSearch
functionality available to other parts of the application is a good practice. This promotes loose coupling and makes the code more maintainable.framework/framework/server.ts (8)
339-339
: LGTM: Generic context type improves type safety.The WebService class now accepts a generic type parameter that extends CordisContext, which enables better type checking throughout the application.
489-490
: Good use of resource management with newusing
statement.Using the new
forkContextWithScope
utility with theusing
statement ensures proper cleanup of resources after the HTTP request completes.
598-615
: Good improvement in WebSocket cleanup logic.The new cleanup function for WebSocket connections ensures proper resource cleanup, error handling, and connection termination in all scenarios.
688-712
: Fixed condition that always evaluated to false.The Checker function has been properly refactored to fix the condition that previously always evaluated to false in the
check
function. This addresses the CodeQL warning reported in the static analysis.
748-748
: Good improvement in type safety for Route and Connection handlers.The Route and Connection methods now correctly use proper type constraints for handler parameters, improving type safety and preventing potential runtime errors.
Also applies to: 757-757
791-814
: Well-implemented mixin functionality with proper cleanup.The new
_applyMixin
method properly handles applying mixins to class prototypes with appropriate cleanup when the context is disposed. It also properly preserves old values when a property already exists.
830-832
: Fixed wsHandlerMixin implementation.The
wsHandlerMixin
method now correctly applies mixins to theConnectionHandler
prototype, fixing the previous issue where it would warn about existing properties but not actually assign the new properties.
845-852
: Good use of module augmentation for type safety.The module declaration for
@cordisjs/core
ensures that the TypeScript compiler knows about the additions to theContext
interface, enabling proper type checking for the methods added by theWebService
class.packages/hydrooj/src/service/server.ts (5)
82-91
: LGTM: Clean transition to WebService plugin.The apply function now correctly uses the WebService as a plugin with appropriate configuration settings.
203-234
: Good addition of HTTP error handling.The new httpHandlerMixin properly handles different error scenarios with improved redirection logic for authentication and permission errors. The error handling is more comprehensive and user-friendly.
236-251
: Improved WebSocket error handling.The wsHandlerMixin provides better error handling for WebSocket connections, with appropriate logging and error reporting based on the error type and user state.
258-259
: Good domain context extension.Adding the domain to the handler's context improves the availability of domain-specific information throughout the request lifecycle.
260-270
: Good addition of handler creation lifecycle hooks.The new event handlers for 'handler/create/http' and 'handler/create/ws' provide proper initialization and error handling for both HTTP and WebSocket handlers, enhancing the robustness of the application.
Also applies to: 271-273
// FIXME: should pass type check | ||
await (this.ctx.parallel as any)('handler/create', h, 'http'); | ||
await (this.ctx.parallel as any)('handler/create/http', h); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add proper type definitions for event handlers instead of type assertions.
Multiple locations use type assertions to any
with FIXME comments to bypass TypeScript's type system. This decreases type safety and should be properly addressed.
Create proper type definitions for the event handlers to avoid type assertions:
// In your interfaces file:
interface HandlerEvents<T> {
'handler/create': [handler: T, type: 'http' | 'ws'];
'handler/create/http': [handler: T];
'handler/create/ws': [handler: T];
'handler/error': [handler: T, error: Error];
'connection/create': [handler: T];
'connection/active': [handler: T];
'connection/close': [handler: T];
}
// Then update the Context interface to include these typed events
interface C extends CordisContext {
parallel<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>;
serial<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): Promise<void>;
emit<E extends keyof HandlerEvents<T>, T>(event: E, ...args: HandlerEvents<T>[E]): void;
}
This also applies to similar FIXME comments at lines 553-555, 603-605, 659-659.
export interface HandlerCommon<C> { // eslint-disable-line @typescript-eslint/no-unused-vars | ||
domain: DomainDoc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix unsafe interface-class declaration merging in Handler classes.
Similar to the issue in framework/framework/server.ts
, there's an unsafe interface-class declaration merging pattern for both Handler
and ConnectionHandler
.
-export interface HandlerCommon<C> { // eslint-disable-line @typescript-eslint/no-unused-vars
- domain: DomainDoc;
+// Move interface properties to class implementation
-export class Handler extends HandlerOriginal<Context> {
- domain: DomainDoc;
+export class Handler extends HandlerOriginal<Context> {
+ declare domain: DomainDoc;
-export class ConnectionHandler extends ConnectionHandlerOriginal<Context> {
- domain: DomainDoc;
+export class ConnectionHandler extends ConnectionHandlerOriginal<Context> {
+ declare domain: DomainDoc;
Alternative solution: Convert interfaces to type aliases or implement the interfaces in the classes:
// Alternative solution using implements
interface IHandler {
domain: DomainDoc;
}
export class Handler extends HandlerOriginal<Context> implements IHandler {
domain: DomainDoc;
}
Also applies to: 74-78
Summary by CodeRabbit
Release Notes
New Features
I18nService
.ConfigService
class for better configuration management.procPeak
property to theSandboxVersion
andSandboxResult
interfaces for tracking process peaks.Improvements
RecordModel
class for better data tracking.ScoreboardService
initialization for better context management.apply
function in theGeoIPService
class for streamlined service registration.DiscussionMainHandler
class with optimized database query performance through index hints.blacklist
handling to return complete results from operations, improving functionality.