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 🙏

© 2026 – Pkg Stats / Ryan Hefner

fileaway-sdk

v0.5.0

Published

Official Fileaway SDK — create upload links, upload & download files, and verify webhooks in a few lines.

Downloads

77

Readme

fileaway-sdk

The official Fileaway SDK. Create branded upload links, upload & download files, and verify webhooks — in a few lines, with no bucket credentials and no two-phase upload dance to wire up yourself.

npm i fileaway-sdk

Requirements: Node ≥ 18 (or any runtime with global fetch/crypto — Bun, Deno, Cloudflare Workers, browsers). You need a Fileaway plan with API access (a Business pack) and an API key + an integration created in the dashboard at app.fileaway.io.

Setup (one time, ~5 min in the dashboard)

  1. Create an API keyapp.fileaway.io → API Keys → New. Copy it immediately; the plaintext is shown once.
  2. Copy an integration idapp.fileaway.io → Integrations → your S3/R2 bucket → copy the id.
  3. Put them in your environment:
FILEAWAY_API_KEY=fa_live_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FILEAWAY_INTEGRATION_ID=65f0a1b2c3d4e5f6a7b8c9d0

Quickstart

import { Fileaway } from "fileaway-sdk";

const fileaway = new Fileaway({ apiKey: process.env.FILEAWAY_API_KEY! });

// 1. Create an upload link (one call) → hand link.uploadUrl to your end-user
const link = await fileaway.links.create({
  integrationId: process.env.FILEAWAY_INTEGRATION_ID!,
  label: "Acme Conf — photo wall",
  allow: "images",          // friendly preset (or raw MIME array)
  maxFileSize: "25MB",      // friendly string (or maxFileSizeBytes)
  uploadMode: "multiple",   // accept multiple files per upload
  webhook: { url: "https://acme.com/hooks/fileaway", secret: process.env.WH_SECRET! },
});

// 2. Upload a file (presign → PUT to bucket → complete, all internal)
const receipt = await fileaway.upload({
  link: link.id,
  file: "./IMG_8423.jpg",   // path | File/Blob | Uint8Array | stream
  uploader: { name: "Jane", email: "[email protected]" },
});

// 3. Download it back later — no bucket creds, no extra wiring
await fileaway.uploads.download(receipt.uploadId, { to: "./out.jpg" });

Receiving webhooks

Every upload fires an HMAC-signed webhook. The adapters capture the raw body and verify the signature for you (the #1 webhook footgun).

// Express — mount BEFORE express.json()
import { fileawayWebhook } from "fileaway-sdk/express";

app.post("/hooks/fileaway", fileawayWebhook({
  secret: process.env.WH_SECRET!,
  onEvent: async (e) => {
    if (e.type === "upload.created") await enqueue(e.data); // process out-of-band
  },
}));
// Next.js App Router — app/hooks/fileaway/route.ts
import { handleFileawayWebhook } from "fileaway-sdk/next";

export const POST = handleFileawayWebhook({
  secret: process.env.WH_SECRET!,
  onEvent: async (e) => { if (e.type === "upload.created") await enqueue(e.data); },
});

Framework-agnostic core (any runtime):

const event = await fileaway.webhooks.verify({
  payload: rawBody,                                  // RAW bytes, not parsed JSON
  signature: headers["x-webhook-signature"],
  timestamp: headers["x-webhook-timestamp"],
  secret: process.env.WH_SECRET!,
});

Typed errors

Branch on meaning, not status codes:

import { QuotaExceededError, RateLimitError, FeatureNotAvailableError } from "fileaway-sdk";

try {
  await fileaway.upload({ link, file });
} catch (e) {
  if (e instanceof QuotaExceededError)      return upsell(e.message);     // upgrade plan
  if (e instanceof RateLimitError)          return retryAfter(e.resetAt); // 429
  if (e instanceof FeatureNotAvailableError) return needBranding();
  throw e;
}

All errors extend FileawayError with .code, .status, .requestId, .details. RateLimitError adds .resetAt/.retryAfter/.remaining.

API at a glance

| Call | Does | |------|------| | fileaway.upload({ link, file }) | presign → PUT → complete, in one call | | fileaway.uploadMany({ link, files }) | many files, bounded concurrency | | fileaway.links.create / list / listAll / get / update / delete / enable / disable | manage links | | fileaway.links.uploads(linkId) / uploadsAll(linkId) | a link's uploads | | fileaway.uploads.download(id, { to \| as }) | save / buffer / stream a file | | fileaway.uploads.getDownloadUrl(id) | short-lived URL for a frontend | | fileaway.webhooks.verify(...) | verify + parse a webhook |

See RECIPES.md for task-oriented examples and llms.txt for an AI-optimized digest.

License

MIT