npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@comparaonline/mono-client

v1.6.0

Published

Soap and rest connector

Downloads

710

Readme

mono-client

Table of Contents

Features

  • Wrapper for SOAP and REST requests
  • Easy retry and successful response validation
  • Callback interceptor
  • Metrics and starts date always available
  • Reuse configuration for business units and services
  • TypeScript Support
  • body parser

Installing

Using npm:

$ npm i @comparaonline/mono-client

Using yarn:

$ yarn add @comparaonline/mono-client

Example

SOAP

import { MonoClient } from '@comparaonline/mono-client';

async function sum() {
  const soapClient = new MonoClient({
    type: 'soap',
    wsdl: 'http://www.dneonline.com/calculator.asmx?WSDL'
  });

  const response = await soapClient.request({
    method: 'Add',
    body: {
     intA: 1,
     intB: 2
    }
  });

  console.log(response.body);
  console.log(response.headers);
  console.log(response.statusCode);
}

REST

import { MonoClient } from '@comparaonline/mono-client';

async function getUser() {
  const restClient = new MonoClient({
    type: 'rest',
    baseUrl: 'https://gorest.co.in'
  });

  const response = await restClient.request({
    path: '/public/v1/users/{userId}',
    pathParams: {
      userId: 2
    }
  });

  console.log(response.body);
  console.log(response.headers);
  console.log(response.statusCode);
}

REST Stream

If you are receiving data as stream and it content is a group of JSONs then you can use streamRequest with responseType json-stream. This will return a simple event emitter with each object

import { MonoClient } from '@comparaonline/mono-client';

async function stream() {
  const restClient = new MonoClient({
    type: 'rest',
    baseUrl: 'https://gorest.co.in'
  });

  const data = await restClient.streamRequest({
    path: '/public/v1/users/{userId}',
    method: 'GET',
    responseType: 'json-stream'
  });

  data.body.on('data', (json) => {
    // JSON as object
  });

  data.body.on('end', () => {
    // End of stream (error included)
  });
}

Client advaced configuration

import { MonoClient, StatusCode, MonoClientGenerator } from '@comparaonline/mono-client';
import { randomUUID } from 'crypto';

async function testSoap() {
  const soapClient = new MonoClient({
    type: 'soap',
    wsdl: 'http://www.dneonline.com/calculator.asmx?WSDL',
    callback(request, response, info) {
      // Usefull for metrics
      console.log(request);
      console.log(response);
      console.log(info);
    },
    extra: {
      businessUnit: 'my-business-unit',
      requestId: randomUUID(),
      serviceId: 'my-service-id'
    },
    ssl: {
      // this overwrites default HttpsAgent
      type: 'ssl-security', // ssl-pfx-security | ssl-reject
      cert: Buffer.from(''),
      key: '/path',
      ca: '/path', // optional
      rejectUnauthorized: false // optional
    },
    isSuccessfulCallback(response) {
      // default validation is statusCode 200 or 201
      return response.body.Error == null; // custom validation inside client
    },
    retry: {
      maxRetry: 2,
      on: [StatusCode.S4XX], // Retry if error is 4XX
      notOn: [StatusCode.E400], // not retry if error is 400
      shouldRetryCallback(request, response) {
        // This will overwrite retry on and notOn
        return response.body.Error === 'server timeout';
      }
    },
    bodyParser<T>(body: any): T {
      //Allows you to parse any property inside the response body, and re-assign it
      return JSON.parse(body.clientData);
    }
  });
  const response = await soapClient.request({
    method: 'Add',
    body: {
      intA: 1,
      intB: 2
    },
    headers: {
      'my-header': 'test'
    },
    isSuccessfulCallback(response) {
      // overwrite client custom validation and 200/201 validation
      return response.body.Error == null && response.body.Success === 'yes'; // custom validation per request
    },
    overwriteWsdl: 'http://www.dneonline.com/calculator.asmx?WSDL', // Use a specific enpoint for a request but preserving client configuration
    requestTimeout: 3000, // default 120000 ms
    shouldRetryCallback(request, response) {
      // This will overwrite client shouldRetryCallback, retry on and retry notOn. maxAttempt must by set on client
      return (
        response.body.Error === 'server timeout' ||
        response.body.Error === 'server max attempts per minute'
      );
    }
  });
}

async function restTest() {
  const restClient = new MonoClient({
    type: 'rest',
    baseUrl: 'https://gorest.co.in',
    callback(request, response, info) {
      console.log(request);
      console.log(response);
      console.log(info);
    },
    extra: {
      businessUnit: 'my-business-unit',
      requestId: randomUUID(),
      serviceId: 'my-service-id'
    },
    ssl: {
      type: 'ssl-security', // ssl-pfx-security | ssl-reject
      cert: Buffer.from(''),
      key: '/path',
      ca: '/path', // optional
      rejectUnauthorized: false // optional
    },
    isSuccessfulCallback(response) {
      // default validation is statusCode 200 or 201
      return response.body.Error == null; // custom validation inside client
    },
    retry: {
      maxRetry: 2,
      on: [StatusCode.S4XX], // Retry if error is 4XX
      notOn: [StatusCode.E400], // not retry if error is 400
      shouldRetryCallback(request, response) {
        // This will overwrite retry on and notOn
        return response.body.Error === 'server timeout';
      },
      delayInSeconds: 5 // time in seconds between retries
    },
    bodyParser<T>(body: any): T {
      //Allows you to parse any property inside the response body, and re-assign it
      return JSON.parse(body.clientData);
    }
  });

  const response = await restClient.request({
    method: 'get', // Default
    path: '/public/v1/users/{userId}',
    pathParams: {
      userId: 2
    },
    body: {
      someParam: 1
    },
    headers: {
      'test-header': 'test'
    },
    queryParams: {
      page: 1,
      limit: 40
    },
    isSuccessfulCallback(response) {
      // overwrite client custom validation and 200/201 validation
      return response.body.Error == null && response.body.Success === 'yes'; // custom validation per request
    },
    overwriteBaseUrl: 'https://gorest.co.in', // Use a specific baseUrl for a request but preserving client configuration
    requestTimeout: 3000, // default 120000 ms
    shouldRetryCallback(request, response) {
      // This will overwrite client shouldRetryCallback, retry on and retry notOn. maxAttempt must by set on client
      return (
        response.body.Error === 'server timeout' ||
        response.body.Error === 'server max attempts per minute'
      );
    }
  });
}


async function generatorTest() {
  const generator = new MonoClientGenerator({
    businessUnit: 'my-business-unit', // Every client generated with this generator will have the same businessUnit
    callback(request, response, info) {
      // Every client generated with this generator will have the same callback
      console.log(request);
      console.log(response);
      console.log(info);
    },
    bodyParser<T>(body: any): T {
      //Allows you to parse any property inside the response body, and re-assign it
      return JSON.parse(body.clientData);
  });

  const restClient = generator.get({
    type: 'rest',
    baseUrl: 'https://gorest.co.in'
    // you can setup all the params for this client as any other REST client except for businessUnit and callback
  }, 'my-service-id-1', 'my-request-id-1');

  const soapClient = generator.get({
    type: 'soap'
    // you can setup all the params for this client as any other SOAP client except for businessUnit and callback
  }, 'my-service-id-2', 'my-request-id-2');
}

Change SSL security options

After upgrade to Node18 or higher HTTPS agent will disable unsafe legacy TLS renegotiation. So if you are setting rejectUnauthorized or ssl is self signed then you need to specify secureOptions. This won't be as default because lower versions of node won't need it

import crypto from 'crypto';

const client = new MonoClient({
  ssl: {
      // this overwrites default HttpsAgent
      type: 'ssl-reject', // ssl-pfx-security | ssl-security
      rejectUnauthorized: false, // optional
      secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT
    }
})

Debug

MONO_CLIENT_DEBUG=true

Mono Client API

TODO

Mono Client Generator API

TODO