Repository: cdimascio/express-openapi-validator
Pull request #675 (2021-11-28 10:48:35)

#671 default export in handler
Hi,

issue #671 

I wasn't sure whether to add the `x-eov-operation-handler` optional property in `OperationObject` interface (since it has an important meaning in the program).

If you think it does not belong, we could instead use a `// @ts-ignore` comment in my new test before line 21.

Thanks

cdimascio: @zzgab thanks. This looks good. Please add the tsignore and I’ll get this merged
zzgab: Updated.
Thanks.

Patch:
diff --git a/src/resolvers.ts b/src/resolvers.ts
index 7d7445f..68dd21b 100644
--- a/src/resolvers.ts
+++ b/src/resolvers.ts
@@ -33,18 +33,16 @@ export function defaultResolver(
     const modulePath = path.join(handlersPath, baseName);
     if (!tmpModules[modulePath]) {
       tmpModules[modulePath] = require(modulePath);
-      if (!tmpModules[modulePath][oId]) {
-        // if oId is not found only module, try the module's default export
-        tmpModules[modulePath] = tmpModules[modulePath].default;
-      }
     }
-    if (!tmpModules[modulePath][oId]) {
+
+    const handler = tmpModules[modulePath][oId] || tmpModules[modulePath].default;
+
+    if (!handler) {
       throw Error(
-        `Could not find 'x-eov-operation-handler' with id ${oId} in module '${modulePath}'. Make sure operation '${oId}' defined in your API spec exists as a handler function in '${modulePath}'.`,
+        `Could not find 'x-eov-operation-handler' with id ${oId} in module '${modulePath}'. Make sure operation '${oId}' defined in your API spec exists as a handler function (or module has a default export) in '${modulePath}'.`,
       );
     }
 
-    const handler = tmpModules[modulePath][oId];
     cache[cacheKey] = handler;
     return handler;
   }


Test patch:
diff --git a/test/default-export.spec.ts b/test/default-export.spec.ts
new file mode 100644
index 0000000..6b4cd2f
--- /dev/null
+++ b/test/default-export.spec.ts
@@ -0,0 +1,46 @@
+import * as express from 'express';
+import * as OpenApiValidator from '../src';
+import { expect } from 'chai';
+import * as request from 'supertest';
+import * as path from 'path';
+
+describe('default export resolver', () => {
+  let server = null;
+  let app = express();
+
+  before(async () => {
+    app.use(
+      OpenApiValidator.middleware({
+        apiSpec: {
+          openapi: '3.0.0',
+          info: { version: '1.0.0', title: 'test bug OpenApiValidator' },
+          paths: {
+            '/': {
+              get: {
+                operationId: 'anything',
+                // @ts-ignore
+                'x-eov-operation-handler': 'controller-with-default',
+                responses: { 200: { description: 'home api' } }
+              }
+            },
+          },
+        },
+        operationHandlers: path.join(__dirname, 'resources'),
+      }),
+    );
+
+    server = app.listen(3000);
+    console.log('server start port 3000');
+  });
+
+  after(async () => server.close());
+
+  it('should use default export operation', async () => {
+    return request(app)
+      .get(`/`)
+      .expect(200)
+      .then((r) => {
+        expect(r.body).to.have.property('success').that.equals(true);
+      });
+  });
+});
diff --git a/test/resources/controller-with-default.ts b/test/resources/controller-with-default.ts
new file mode 100644
index 0000000..b52090a
--- /dev/null
+++ b/test/resources/controller-with-default.ts
@@ -0,0 +1,3 @@
+export default function (req, res) {
+  res.json({success: true}).end();
+}