-
-
Notifications
You must be signed in to change notification settings - Fork 427
fix: apply macros before merging hooks in group method #1624
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
base: main
Are you sure you want to change the base?
Conversation
The group method was merging hooks before expanding macro options, causing macro-defined beforeHandle hooks to run after nested plugin resolve hooks. This fix calls applyMacro() on the hook object before mergeHook() to ensure correct lifecycle ordering. Closes elysiajs#1586
WalkthroughApply macro expansion to the local group hook before computing standalone schema and merging hooks, and add tests validating macro and hook lifecycle ordering across grouped routes and nested plugins. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant GroupMacro as Group Macro (beforeHandle)
participant PluginResolve as Nested Plugin (resolve)
participant Handler as Route Handler
Client->>GroupMacro: request enters group
Note right of GroupMacro: macro expansion applied to local hook\n(before merging)
GroupMacro->>PluginResolve: (queue ordering) beforeHandle runs first
PluginResolve->>Handler: resolved context available
Handler-->>Client: response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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
🧹 Nitpick comments (1)
test/core/macro-lifecycle.test.ts (1)
95-141: Comprehensive test for authorized path.This test effectively validates the fix when authentication succeeds, ensuring all hooks execute in the correct order:
auth.resolve -> requireAuth.beforeHandle -> data.resolve. It nicely complements the unauthorized path test by confirming the fix works correctly in both success and failure scenarios.Minor suggestion: The test description "should demonstrate the issue with macro in group" might be clearer as "should run macro beforeHandle between auth and data resolves when authorized" to better reflect that it's testing the successful flow after the fix.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/index.ts(1 hunks)test/core/macro-lifecycle.test.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/core/macro-lifecycle.test.ts (1)
src/index.ts (2)
Elysia(190-8169)Elysia(8171-8171)
🔇 Additional comments (3)
src/index.ts (1)
4045-4047: LGTM! Correct fix for macro execution order.The placement of
applyMacro(hook)beforemergeHook()ensures that macro-defined hooks (e.g.,beforeHandlefrom a macro option likerequireAuth: true) are expanded and registered before merging with nested plugin hooks. This fixes the execution order issue where macrobeforeHandlewas running after nested pluginresolvehooks.This change aligns with the
guardmethod's behavior (which callsapplyMacroat line 4508), ensuring consistency across the API.test/core/macro-lifecycle.test.ts (2)
5-59: Well-designed test case for unauthorized path.This test effectively validates the core fix by verifying that:
authService.resolveruns firstisSignedIn.beforeHandle(macro-defined) runs next and throwsdbClient.resolvenever executes (preventing the "User ID is required" error)The execution order tracking and assertions correctly demonstrate that macro
beforeHandlenow executes before nested pluginresolvehooks, fixing the issue described in #1586.
61-93: Good validation of documented same-queue behavior.This test confirms that
resolveandbeforeHandlehooks share the same execution queue and run in registration order, which is the documented behavior that makes the fix possible. The clear execution order assertion (resolve1 -> beforeHandle1 -> resolve2 -> beforeHandle2) validates this fundamental assumption.
When a macro defines schema validation (body, headers, etc.), the standaloneValidator from applyMacro was being overwritten by the localHook's standaloneValidator during mergeHook. This fix properly merges all three sources: macro's standaloneValidator, localHook's standaloneValidator, and group's explicit schema. Added test case to verify macro schema is preserved when used with nested plugins.
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
🧹 Nitpick comments (4)
test/core/macro-lifecycle.test.ts (4)
50-51: Remove debug console.log statements.These debug statements should be removed before merging to keep test output clean.
- console.log('Execution order:', executionOrder) - console.log('Response:', body) -
83-83: Remove debug console.log statement.- console.log('Execution order:', executionOrder) -
131-132: Remove debug console.log statements.- console.log('Execution order:', executionOrder) - console.log('Error:', errorMessage) -
97-97: Unused variableerrorMessage.The variable is assigned but never used in assertions. Consider either removing it or adding an assertion that verifies no error occurred.
- let errorMessage = '' - const authPlugin = new Elysia({ name: 'auth' })Or add an assertion:
expect(executionOrder).toEqual([ 'auth.resolve', 'requireAuth.beforeHandle', 'data.resolve' ]) + expect(errorMessage).toBe('') })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/index.ts(2 hunks)test/core/macro-lifecycle.test.ts(1 hunks)
🔇 Additional comments (4)
src/index.ts (2)
4045-4047: LGTM - Fix correctly applies macros before merging hooks.This aligns the
group()method behavior withguard(), which already applies macros before processing. The comment clearly explains the rationale for the change.
4069-4091: LGTM - Proper three-way merge of standalone validators.The logic correctly combines validators from:
hook.standaloneValidator(from macro expansion)localHook.standaloneValidator(from nested plugin)- Inline schema object (if
hasStandaloneSchemais true)The conditional ensures the array is only created when at least one source has validators, avoiding unnecessary empty arrays.
test/core/macro-lifecycle.test.ts (2)
5-59: Well-structured test covering the core fix.This test effectively validates the fix from issue #1586 by verifying that:
- The macro's
beforeHandleruns before nested plugin'sresolve- When
beforeHandlethrows, the nestedresolveis never executed- The correct error message ("Unauthorized") is returned
The test setup with auth service, db client, and feature module mirrors real-world usage patterns.
143-191: Good coverage of schema preservation.This test validates an important edge case: ensuring macro-defined schemas (like
bodyvalidation) are preserved when merging with nested plugin hooks. The test correctly verifies both valid (200) and invalid (422) responses.
Summary
Fixes #1586 - macro-defined
beforeHandlehooks were running after nested pluginresolvehooks instead of before.Root Cause: The
groupmethod was merging hooks viamergeHook(hook, localHook)before expanding macro options. The macro expansion happened later inadd(), but by then the nested plugin hooks were already in the array, so macro hooks were appended at the end.Fix:
applyMacro(hook)beforemergeHook()in the group method (similar to howguardmethod already does this at line 4504)hook.standaloneValidator(from macro schema) withlocalHook.standaloneValidatorto prevent macro-defined schema validation from being lostTest Cases Added
Four test cases in
test/core/macro-lifecycle.test.ts:{ isSignedIn: true }macro, the macro'sbeforeHandleruns before any nested plugin'sresolvehookresolveandbeforeHandleshare the same queue and run in registration orderBefore Fix
After Fix
Test Results
stop.test.ts)Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.