0

I want to use the methods of the Minio class without specifying all their parameters, but substituting some of the parameters automatically. How do I do it...

  1. I get all the class methods from the prototype of the Minio class and dynamically create wrappers for them in my class.
  2. For each wrapper method, I get the parameter names from the original method of the Test class.
  3. If there is one in the list of parameters that I want to omit when calling my wrapper method, then I add it to the list of arguments and call originalMethod.apply(this.minioClient, args).

Everything was fine until there were methods that were already wrapped. I need to get the parameter list of the bucketExists method from outside the Minio class. Any idea how to get parameter names from such a wrapped method?

// minio/dist/main/helpers.js
exports function promisify(fn){
  return function(){
    const args = [...arguments];
    fn.apply(this, args);
  }
}

// minio/dist/main/minio.js
class Minio{
  bucketExists(bucketName){
    return bucketName;
  }
  methodThatNotWrappedByPromisifyAndWorksFine(bucketName){
    return bucketName;
  }
}

module.exports = Minio;
Minio.prototype.bucketExists = (0,helpers.promisify)(Minio.prototype.bucketExists)

I want to give an instance of my class with methods wrapped from the original class link the ability to work with only one bucket, that was passed to the my class constructor, without the ability to specify some other one after initialize.

My wrapper

    const proxyHandler = () => {
      return {
        apply: (target, thisArg, argumentsList) => {
          const funcParams = getMethodParamNames(target.source ? target.source.functionForWrap : target);
          const bucketNameIndex = funcParams.indexOf("bucketName");
          const regionNameIndex = funcParams.indexOf("region");

          if (bucketNameIndex >= 0) {
            argumentsList.splice(bucketNameIndex, 0, this.bucket.name);
          }
          if (regionNameIndex >= 0) {
            argumentsList.splice(regionNameIndex, 0, this.bucket.region);
          }
          try {
            return target.apply(this.minioClient, argumentsList);
          } catch (error) {
            logger.engine.error(`S3 '${this.bucket.name}' ${target} error: ${error.message}`, error.stack);
          }
        },
      }
    }

    getMethods(this.minioClient).forEach(func => {
      this[func] = new Proxy(this.minioClient[func], proxyHandler());
    })

Solved the problem by overriding the method wrapper like this.


const MinioHelpers = require('minio/dist/main/helpers');

const origMinioPromisify = MinioHelpers.promisify;

MinioHelpers.promisify = (functionForWrap) => {
    console.log("PATCHED!", functionForWrap);
    var fn = origMinioPromisify(functionForWrap);
    //from this i'll get all need information about wrapped function
    fn.source = {
        functionForWrap,
        promisify: origMinioPromisify,
    } 
    return fn
}

var Minio = require('minio');

  • Do you need to create wrappers, or can you modify the original functions? – Michael M. Dec 27 '22 at 16:01
  • @MichaelM.Test class is an external module [link](https://github.com/minio/minio-js/blob/master/src/main/minio.js), i can't modify it, I want to create wrappers. – TwistedMind Dec 27 '22 at 16:04
  • 1
    Since parameters in Javascript are always positional, it's not a good idea to look specifically for parameter *names*, as these are usually subject to change. Not only by the programmer, but by tools like minifiers. – deceze Dec 27 '22 at 16:04
  • @deceze I want to give an instance of my class with methods wrapped from the original class [link](https://github.com/minio/minio-js/blob/master/src/main/minio.js) the ability to work with only one bucket that was passed to the class constructor, without the ability to specify some other one. Most, but not all, methods accept a bucketName as a parameter. I can't just look at the position of the parameter, I also need its name because some methods don't accept bucketName. – TwistedMind Dec 27 '22 at 16:11
  • [Proxy/handler](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) ? – Ronnie Royston Dec 27 '22 at 16:52
  • @RonnieRoyston ```const handler = { apply: function(target, thisArg, argumentsList) {}}; ``` At target i'm still stuck in the wrapper ```return function(){ const args = [...arguments]; fn.apply(this, args); }``` and can't access original method... – TwistedMind Dec 27 '22 at 17:20
  • @twistedmind what this means? `(0,promisify)(Minio.prototype.bucketExists)`. I understand the promisify function but what does the (0, promisify) does? – hawks Dec 28 '22 at 12:40
  • @hawk https://stackoverflow.com/questions/42724776/strange-javascript-function-call-construct-0-function – TwistedMind Dec 28 '22 at 15:02

0 Answers0