Repository: pmcelhaney/counterfact (ts)

Issue:
ContextRegistry not finding closest path context, defaults to root due to Dispatcher bug
With an OpenApi v2 doc with a specific `basePath` the `contextRegistry.find` operation receives a path with the full `basePath` included. Since the contextRegistry entries do not include the basePath in their key it can't find any path-level contexts and defaults to the root context.

Pull request description:
fix(server): correct dispatcher request method to use matchedPath
fixes #585 where the dispatcher needs the matchedPath passed to the contextRegistry find method so it does not include the api basePath.

Patch:
diff --git a/.changeset/small-snakes-brush.md b/.changeset/small-snakes-brush.md
new file mode 100644
index 0000000..05f3cbf
--- /dev/null
+++ b/.changeset/small-snakes-brush.md
@@ -0,0 +1,5 @@
+---
+"counterfact": patch
+---
+
+Fixes issue #585 where dispatcher.ts needs to use the matchedPath when calling the contextRegistry.find method
diff --git a/src/server/dispatcher.ts b/src/server/dispatcher.ts
index f954ec6..19d4f07 100644
--- a/src/server/dispatcher.ts
+++ b/src/server/dispatcher.ts
@@ -245,7 +245,7 @@ export class Dispatcher {
       this.parameterTypes(operation?.parameters),
     )({
       body,
-      context: this.contextRegistry.find(path),
+      context: this.contextRegistry.find(matchedPath),
       headers,
 
       proxy: async (url: string) => {


Test patch:
diff --git a/test/server/dispatcher.test.ts b/test/server/dispatcher.test.ts
index 889811c..a0b5277 100644
--- a/test/server/dispatcher.test.ts
+++ b/test/server/dispatcher.test.ts
@@ -509,6 +509,34 @@ describe("a dispatcher", () => {
     expect(result.body).toBe("test context");
   });
 
+  it("passes a context object (not in the root)", async () => {
+    const registry = new Registry();
+    const contextRegistry = new ContextRegistry();
+
+    contextRegistry.add("/", { id: "test context" });
+
+    contextRegistry.add("/echo/{id}", { id: "echo context" });
+    registry.add("/echo/{id}", {
+      GET({ context }) {
+        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+        return { body: (context as { id: string }).id };
+      },
+    });
+
+    const dispatcher = new Dispatcher(registry, contextRegistry);
+
+    const result = await dispatcher.request({
+      body: "",
+      headers: {},
+      method: "GET",
+      path: "/echo/1",
+      query: {},
+      req: { path: "/echo/1" },
+    });
+
+    expect(result.body).toBe("echo context");
+  });
+
   it("converts query, path, and header parameters to numbers if necessary", async () => {
     const registry = new Registry();