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

aws4fetch

v1.0.20

Published

A compact AWS client for modern JS environments

Downloads

475,274

Readme

aws4fetch

A compact (6.4kb minified, 2.5kb gzipped) AWS client for environments that support fetch and SubtleCrypto – that is, modern web browsers and JS platforms like Cloudflare Workers. Also retries requests with an exponential backoff with full jitter strategy by default.

Example

import { AwsClient } from 'aws4fetch'

const aws = new AwsClient({ accessKeyId: MY_ACCESS_KEY, secretAccessKey: MY_SECRET_KEY })

// https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html
const LAMBDA_FN_API = 'https://lambda.us-east-1.amazonaws.com/2015-03-31/functions'

async function invokeMyLambda(event) {
  const res = await aws.fetch(`${LAMBDA_FN_API}/my-lambda/invocations`, { body: JSON.stringify(event) })

  // `res` is a standard Response object: https://developer.mozilla.org/en-US/docs/Web/API/Response
  return res.json()
}

invokeMyLambda({my: 'event'}).then(json => console.log(json))

You can see a more detailed example, a Cloudflare Worker script you can use as a replacement for API Gateway, in the example directory.

API

aws4fetch exports two classes: AwsClient and AwsV4Signer

new AwsClient(options)

You can use the same instance of AwsClient for all your service calls as the service and region will be determined at fetch time – or you can create separate instances if you have different needs, eg no retrying for some service.

import { AwsClient } from 'aws4fetch'

const aws = new AwsClient({
  accessKeyId,     // required, akin to AWS_ACCESS_KEY_ID
  secretAccessKey, // required, akin to AWS_SECRET_ACCESS_KEY
  sessionToken,    // akin to AWS_SESSION_TOKEN if using temp credentials
  service,         // AWS service, by default parsed at fetch time
  region,          // AWS region, by default parsed at fetch time
  cache,           // credential cache, defaults to `new Map()`
  retries,         // number of retries before giving up, defaults to 10, set to 0 for no retrying
  initRetryMs,     // defaults to 50 – timeout doubles each retry
})

Promise<Response> aws.fetch(input[, init])

Has the same signature as the global fetch function

import { AwsClient } from 'aws4fetch'

const aws = new AwsClient(opts)

async function doFetch() {

  const response = await aws.fetch(url, {

    method,  // if not supplied, will default to 'POST' if there's a body, otherwise 'GET'
    headers, // standard JS object literal, or Headers instance
    body,    // optional, String or ArrayBuffer/ArrayBufferView – ie, remember to stringify your JSON

    // and any other standard fetch options, eg keepalive, etc

    // optional, largely if you want to override options in the AwsClient instance
    aws: {
      signQuery,          // set to true to sign the query string instead of the Authorization header
      accessKeyId,        // same as in AwsClient constructor above
      secretAccessKey,    // same as in AwsClient constructor above
      sessionToken,       // same as in AwsClient constructor above
      service,            // same as in AwsClient constructor above
      region,             // same as in AwsClient constructor above
      cache,              // same as in AwsClient constructor above
      datetime,           // defaults to now, to override use the form '20150830T123600Z'
      appendSessionToken, // set to true to add X-Amz-Security-Token after signing, defaults to true for iot
      allHeaders,         // set to true to force all headers to be signed instead of the defaults
      singleEncode,       // set to true to only encode %2F once (usually only needed for testing)
    },
  })

  console.log(await response.json())
}

NB: Due to the way bodies are handled in Request instances, it's faster to invoke the function as above – using a URL as the input argument and passing the body in the init argument – instead of the form of invocation that uses a Request object directly as input.

If you don't know which URL to call for the AWS service you want, the full list of AWS endpoints can be found here: https://docs.aws.amazon.com/general/latest/gr/rande.html

And the APIs are documented here: https://docs.aws.amazon.com/ (the REST APIs are usually documented under "API Reference" for each service)

Promise<Request> aws.sign(input[, init])

Returns a Promise that resolves to an AWS4 signed Request – has the same signature as fetch. Use this to create a Request you can send using fetch() yourself.

import { AwsClient } from 'aws4fetch'

const aws = new AwsClient(opts)

async function doFetch() {

  const request = await aws.sign(url, {

    method,  // if not supplied, will default to 'POST' if there's a body, otherwise 'GET'
    headers, // standard JS object literal, or Headers instance
    body,    // optional, String or ArrayBuffer/ArrayBufferView – ie, remember to stringify your JSON

    // and any other standard fetch options, eg keepalive, etc

    // optional, largely if you want to override options in the AwsClient instance
    aws: {
      signQuery,          // set to true to sign the query string instead of the Authorization header
      accessKeyId,        // same as in AwsClient constructor above
      secretAccessKey,    // same as in AwsClient constructor above
      sessionToken,       // same as in AwsClient constructor above
      service,            // same as in AwsClient constructor above
      region,             // same as in AwsClient constructor above
      cache,              // same as in AwsClient constructor above
      datetime,           // defaults to now, to override use the form '20150830T123600Z'
      appendSessionToken, // set to true to add X-Amz-Security-Token after signing, defaults to true for iot
      allHeaders,         // set to true to force all headers to be signed instead of the defaults
      singleEncode,       // set to true to only encode %2F once (usually only needed for testing)
    },
  })

  const response = await fetch(request)

  console.log(await response.json())
}

new AwsV4Signer(options)

The underlying signing class for a request – use this if you just want to deal with the raw AWS4 signed method/url/headers/body.

import { AwsV4Signer } from 'aws4fetch'

const signer = new AwsV4Signer({
  url,                // required, the AWS endpoint to sign
  accessKeyId,        // required, akin to AWS_ACCESS_KEY_ID
  secretAccessKey,    // required, akin to AWS_SECRET_ACCESS_KEY
  sessionToken,       // akin to AWS_SESSION_TOKEN if using temp credentials
  method,             // if not supplied, will default to 'POST' if there's a body, otherwise 'GET'
  headers,            // standard JS object literal, or Headers instance
  body,               // optional, String or ArrayBuffer/ArrayBufferView – ie, remember to stringify your JSON
  signQuery,          // set to true to sign the query string instead of the Authorization header
  service,            // AWS service, by default parsed at fetch time
  region,             // AWS region, by default parsed at fetch time
  cache,              // credential cache, defaults to `new Map()`
  datetime,           // defaults to now, to override use the form '20150830T123600Z'
  appendSessionToken, // set to true to add X-Amz-Security-Token after signing, defaults to true for iot
  allHeaders,         // set to true to force all headers to be signed instead of the defaults
  singleEncode,       // set to true to only encode %2F once (usually only needed for testing)
})

Promise<{ method, url, headers, body }> signer.sign()

Actually perform the signing of the request and return a Promise that resolves to an object containing the signed method, url, headers and body.

method will be a String, url will be an instance of URL, headers will be an instance of Headers and body will unchanged from the argument you supply to the constructor.

import { AwsV4Signer } from 'aws4fetch'

const signer = new AwsV4Signer(opts)

async function sign() {
  const { method, url, headers, body } = await signer.sign()

  console.log(method, url, [...headers], body)
}

Promise<String> signer.authHeader()

Returns a Promise that resolves to the signed string to use in the Authorization header

Used by the sign() method – you shouldn't need to access this directly unless you're constructing your own requests.

Promise<String> signer.signature()

Returns a Promise that resolves to the hex signature

Used by the sign() method – you shouldn't need to access this directly unless you're constructing your own requests.

Installation

With npm do:

npm install aws4fetch