cloudant / nodejs-cloudant

Cloudant Node.js client library
Apache License 2.0
255 stars 90 forks source link

BasePlugin not exported #407

Closed wrumsby closed 4 years ago

wrumsby commented 4 years ago

Please read these guidelines before opening an issue.

Bug Description

1. Steps to reproduce and the simplest code sample possible to demonstrate the issue

I created my own plugin which works like this (simpler code than my plugin, but should prove the issue):

const BasePlugin = require('@cloudant/cloudant/plugins/base');

class MyPlugin extends BasePlugin {
  onRequest(state, request, callback) {
    console.log('request', request);
  }
  onResponse(state, response, callback) {
    console.log('response', response);
  }
  onError(state, error, callback) {
    console.log('error', error);
  }
}

MyPlugin.id = 'mine';

module.exports = MyPlugin;

Problem 1 is that BasePlugin is not described in the TypeScript types published with this module (i.e. types/index.d.ts) which means that it is difficult to write custom plugins in TypeScript or use VS Code with a jsconfig.json file with "checkJS": true.

Problem 2 is more subtle. When running my plugin via the terminal/CLI or in a web application (e.g. running in an Elastic Beanstalk Instance) require('@cloudant/cloudant/plugins/base') everything is fine (I can load my plugin). When running in AWS Lambda I get an error:

Runtime.ImportModuleError: Error: Cannot find module '@cloudant/cloudant/plugins/base'

The core issue here appears to be related to serverless/serverless#6529, but I believe the issues with this module could be resolved by changing how this module exports BasePlugin.

n.b. this issue is effectively #337 which was marked as fixed, but is not fixed as per the description given.

2. What you expected to happen

I expected to be able to write my custom plugin in TypeScript and to be able to use it in a Lambda function packaged by the Serverless Framework.

Essentially, I expect to be able to access BasePlugin by requiring @cloudant/cloudant and not needing to rely on a "submodule" path.

Having BasePlugin available via @cloudant/cloudant would effectively make it part of the public API of this module too, which I think would be a "good thing".

Also note that trying to use nano.basePlugin (added in #342) doesn't work because at the time my plugin is defined nano.basePlugin is undefined - i.e. I can't declare my class like this class MyPlugin extends nano.basePlugin because the Cloudant factory method needs to be created before nano.basePlugin is defined.

3. What actually happened

Could not use TypeScript. When trying to access BasePlugin via require('@cloudant/cloudant/plugins/base'); in a Lambda function packaged with the Serverless Framework I get the following error:

Runtime.ImportModuleError: Error: Cannot find module '@cloudant/cloudant/plugins/base'

Environment details

Version:

4.2.2

Node.js version:

10.16.3

n.b. I believe the changes outlined in https://gist.github.com/wrumsby/8a382bb21c5c02251490907d38845dc6 should be what is required to add BasePlugin to exports as described in this issue and #337.

bessbd commented 4 years ago

Hi @wrumsby !

Thank you for the ticket! The changes you've attached seem to be okay. Do you mind opening a pull request so that we can merge it?

wrumsby commented 4 years ago

@bessbd done! See #408