mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-07 07:42:13 +03:00
Integrated into release/v3.8.12. Salvaged the emitHookBlocking payload-chaining fix from the now-closed plugins-v4 branch (#3221) and adapted it to the shipped release hooks.ts: each blocking handler now sees the body/metadata as mutated by previous handlers. TDD regression test included (RED before, GREEN after); existing plugins-hooks suites green (19+5), typecheck + lint clean.
This commit is contained in:
@@ -190,7 +190,11 @@ export async function emitHookBlocking(
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const result = await reg.handler(payload);
|
||||
// Chain the payload: each handler must see the body/metadata as mutated by
|
||||
// previous handlers, not the original static payload — otherwise plugin B
|
||||
// can't observe plugin A's changes. (#3286)
|
||||
const currentPayload = { ...ctx, body: mergedBody, metadata: mergedMetadata };
|
||||
const result = await reg.handler(currentPayload);
|
||||
if (result && typeof result === "object") {
|
||||
if ("body" in result) mergedBody = (result as Record<string, unknown>).body;
|
||||
if ("metadata" in result)
|
||||
|
||||
86
tests/unit/plugins-hook-payload-chaining-3286.test.ts
Normal file
86
tests/unit/plugins-hook-payload-chaining-3286.test.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* tests/unit/plugins-hook-payload-chaining-3286.test.ts
|
||||
*
|
||||
* Regression for #3286 — emitHookBlocking must CHAIN the payload between
|
||||
* handlers. Before the fix, every handler received the original static
|
||||
* `payload`, so plugin B could not observe plugin A's `body`/`metadata`
|
||||
* mutations (the accumulated mergedBody/mergedMetadata were only used for the
|
||||
* final return value, never fed forward to the next handler).
|
||||
*/
|
||||
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import {
|
||||
registerHook,
|
||||
emitHookBlocking,
|
||||
resetHooks,
|
||||
} from "../../src/lib/plugins/hooks.ts";
|
||||
|
||||
test.afterEach(() => {
|
||||
resetHooks();
|
||||
});
|
||||
|
||||
test("emitHookBlocking feeds each handler the body mutated by previous handlers", async () => {
|
||||
const seenByB: unknown[] = [];
|
||||
|
||||
// Plugin A: rewrites the body.
|
||||
registerHook(
|
||||
"onRequest",
|
||||
"plugin-a",
|
||||
(p: unknown) => {
|
||||
const ctx = p as { body?: { value?: number } };
|
||||
return { body: { value: (ctx.body?.value ?? 0) + 1 } };
|
||||
},
|
||||
10
|
||||
);
|
||||
|
||||
// Plugin B (lower priority → runs after A): records what body it received.
|
||||
registerHook(
|
||||
"onRequest",
|
||||
"plugin-b",
|
||||
(p: unknown) => {
|
||||
const ctx = p as { body?: { value?: number } };
|
||||
seenByB.push(ctx.body);
|
||||
return { body: { value: (ctx.body?.value ?? 0) + 1 } };
|
||||
},
|
||||
20
|
||||
);
|
||||
|
||||
const result = await emitHookBlocking("onRequest", { body: { value: 0 } });
|
||||
|
||||
// Plugin B must have seen plugin A's mutation ({value:1}), not the original {value:0}.
|
||||
assert.deepEqual(seenByB, [{ value: 1 }]);
|
||||
// Final merged body reflects BOTH handlers: 0 → 1 (A) → 2 (B).
|
||||
assert.deepEqual((result as { body?: { value?: number } }).body, { value: 2 });
|
||||
});
|
||||
|
||||
test("emitHookBlocking chains metadata across handlers", async () => {
|
||||
let metadataSeenByB: Record<string, unknown> | undefined;
|
||||
|
||||
registerHook(
|
||||
"onRequest",
|
||||
"meta-a",
|
||||
() => ({ metadata: { a: true } }),
|
||||
10
|
||||
);
|
||||
|
||||
registerHook(
|
||||
"onRequest",
|
||||
"meta-b",
|
||||
(p: unknown) => {
|
||||
metadataSeenByB = (p as { metadata?: Record<string, unknown> }).metadata;
|
||||
return { metadata: { b: true } };
|
||||
},
|
||||
20
|
||||
);
|
||||
|
||||
const result = await emitHookBlocking("onRequest", { body: {}, metadata: {} });
|
||||
|
||||
// Plugin B sees plugin A's metadata.
|
||||
assert.equal(metadataSeenByB?.a, true);
|
||||
// Final metadata carries both.
|
||||
const meta = (result as { metadata?: Record<string, unknown> }).metadata;
|
||||
assert.equal(meta?.a, true);
|
||||
assert.equal(meta?.b, true);
|
||||
});
|
||||
Reference in New Issue
Block a user