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

earbuds-http

v5.0.0

Published

An http module for Transplace web applications

Downloads

2

Readme

Earbuds Http

An HTTP library to standardize ajax requests to a Transplace API.

Installation

npm install earbuds-http

earbuds-http isn't currently pre-compiled, so you may need to modify your webpack config to deal with it.

// webpack.base.conf.js

module.exports = {
  entry: [ /* ... */ ],
  resolve: [ /* ... */ ],
  module: {
    rules: {
      { /* eslint rules */ },
      { /* vue-loader rules */ },
      {
        /* babel rules */
        test: /\.js$/,
        loader: 'babel-loader',
        include: [
          resolve('src'),
          resolve('test'),
          // transpile all packages named earbuds{whatever}
          new RegExp(resolve(['node_modules', 'earbuds.*']), 'i'),
        ]
      }
    }
  }
};

Axios

earbuds-http is built on top of axios. Anything that axios does Earbuds-http should do, too.

earbuds-http adds caching and custom server response handling to base axios.

https://github.com/mzabriskie/axios

Usage

Basics

  • ebHttp.get(url, [options])
  • ebHttp.post(url, data, [options])

Common Options

  • params - the URL parameters to be sent with the request. Must be a plain object or a URLSearchParams object params: { ID: 12345 },

  • data - the data to be sent as the request body Only applicable for request methods 'PUT', 'POST', and 'PATCH' When no transformRequest is set, must be of one of the following types:

    • string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
    • Browser only: FormData, File, Blob
    • Node only: Stream, Buffer data: { firstName: 'Fred' },
  • cache - whether or not to cache the response. boolean. {cache: true}

  • cacheTimeToLive - how long the data should be cached. the value is milliseconds until the cache should expire {cacheTimeToLive: 5000}

  • updateCache - if true, the current cached value is ignored and the new value is saved in it's place {cacheTimeToLive: true}

More Options

see https://github.com/mzabriskie/axios#request-config

Extension Points

Extend earbuds-http by using axios's extension points (which were inspired by angular's $http module) https://github.com/mzabriskie/axios#interceptors

Handling the server response

earbuds-http correctly handles api entity responses from the server.

An ApiEntity response looks like this:

{
  success: true,
  errors: [ ],
  tid: null,
  data: {
    domainId: null,
    accountId: -1,
    accountName: null,
    // ...
  }
}

earbuds-http handles automatically handles the success flag. If true, the promise is resolved with the contents of the data field. Otherwise, the promise is rejected with a list of errors.

Currently the tid (transaction-id) field is not managed.

Handling an AuthenticationError response

Add a response interceptor to catch the AuthenticationError and handle it

// signInRequiredResponseInterceptor.js

import AuthenticationError from 'earbuds-http/src/errors/AuthenticationError';

// todo - confirm that this is the best generic login URL to try
const LOGON_URL_BEST_GUESS = process.env.NODE_ENV !== 'production'
	? '/security/baseLogon.do'
	: '/00-tms-logon-redirect.php';

function handleSignInRequired(error) {
	// Returning a non-resolving promise prevents the api request from resolving
	// at all. E.g. if this happens in a beforeEnter navigation guard in the
	// router, it will stop the page from loading while waiting for the redirect
	// to resolve.
	return new Promise(() => {
		if (error.response && error.response.data && error.response.data.redirect) {
			window.location.href = error.response.data.redirect;
		} else {
			console.warn('ERROR - SIGN IN REQUIRED', 'No redirect url provided. Trying best guess.', LOGON_URL_BEST_GUESS);
			window.location.href = LOGON_URL_BEST_GUESS;
		}
	});
}

export default function rejectedHandler(err) {
	if (err && (err instanceof AuthenticationError || err.name === 'AuthenticationError')) {
		return handleSignInRequired(err);
	}

	return err;
}
// BaseApi.js
import ebHttp from 'earbuds-http';
import combineUrls from 'axios/lib/helpers/combineURLs';
import signInRequiredResponseInterceptor from './signInRequiredResponseInterceptor';

const TMS_API_URL = '/tms/api/v1/';

class BaseTmsApi {
	constructor(url) {
		const baseUrl = combineUrls(TMS_API_URL, url);
		this.ebHttp = ebHttp.create({
			baseURL: baseUrl,
			headers: { 'Content-Type': 'application/json', Accept: 'application/json' }
		});

		// Handle sign-in required errors
		this.ebHttp.interceptors.response.use(null, signInRequiredResponseInterceptor);
	}
}

export { BaseTmsApi };
export default BaseTmsApi;

Caching

Cached calls

Both get and post calls can be cached.

var url = '/user/123/details';
var a = instance.get(url, {cache:true});
var b = instance.get(url, {cache:true});
var c = instance.get(url, {params: {includeAddress: true}, cache: true});
var d = instance.get(url, {params: {includeAddress: true}, cache: true});

a === b; // true
c === d; // true
a === c; // false. Although the url is the same, the options are not.

Subsequent calls to that url with the same options will used cached data instead of hitting the server.

Time To Live

You can automatically expire cached data after a specified number of milliseconds by including the cacheTimeToLive parameter.

var url = '/user/123/details';
var a = instance.get(url, {cache:true, cacheTimeToLive: 10000});

setTimeout(function () {
  var c = instance.get(url, {cache:true, cacheTimeToLive: 10000});
  a === c; // true
}, 5000);

setTimeout(function () {
  var d = instance.get(url, {cache:true, cacheTimeToLive: 10000});
  a === d; // false
}, 20000);

Example

// userApi.js

import ebHttp from 'earbuds-http';

const BASE_URL = './api/user';

export default class Api {
  _httpInstance;

  constructor(url) {
    if (!url) {
      throw new Error('url must be provided');
    }

    this._httpInstance = ebHttp.create({
      baseURL: path.join(BASE_URL, url)
    });
  }

  get http() {
    return this._httpInstance;
  }

  getSecurityContext() {
    // url -> ./api/user/securityContext/
    // cached for the entirety of the javascript session
    return this.http.get('/securityContext', { cache: true });
  }

  getUserDetail(userId) {
    // url -> ./api/user/userDetail/userId
    // not cached at all
    return this.http.get(`/userDetail/${userId}`, { cache: false });
  }

  getMapData(showMapPaths, mapStyle) {
    // url -> ./api/user/getMapData/userId?showMapPaths=true&mapStyle=SQUARE
    // cached for 10 seconds
    return this.http.get('/userDetail/${userId}', {
      params: {showMapPaths, mapStyle},
      cache: true,
      cacheTimeToLive: 10000
    });
  }
}
// consumer.js

import userApi from './userApi';

userApi.getSecurityContext()
  .then(securityContext => console.log(securityContext))
  .catch(errors => toastr.danger(errors.join(', ')));

// ...

Development

You can develop npm packages locally without having to push to test your changes

https://docs.npmjs.com/cli/link

  1. Git clone this repository
  2. In earbuds-http, $ npm link
  3. In a project using earbuds-http, $ npm link earbuds-http

Once you're done developing, use npm version to push your changes

https://docs.npmjs.com/cli/version

  1. In earbuds-http, make sure everything is committed
  2. In earbuds-http, $ npm version [major|minor|patch]
  3. In a project using earbuds-http,
    • first time install: $ npm install earbuds-http
    • upgrade: $ npm upgrade earbuds-http