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

@cellajs/imado

v0.1.6

Published

File handling with TUS for public and private files using AWS Lambda and S3.

Downloads

329

Readme

Imado (+ TUS + AWS Lambda + S3)

Imado is built as a configure-once solution for file handling with the TUS protocol, for public as well as for private files. It supports images and files such as PDF and DOCX and runs on AWS Lambda. Data - including cache - is stored on your own S3 bucket. Optionally it also supports videos.

This repo is a helper to use Imado and is currently being used by CellaJS. The required AWS lambda repo is currently private.

Contact us here if you are interested in using it or email us at [email protected].

Server

Wrap tus + s3-store and the Imado API to start uploading to your api.

import { ImadoTus } from "imado";
import { env } from "env"; // or wherever you store your env variables

const tus = ImadoTus({
  secret: env.TUS_UPLOAD_API_SECRET,
  credentials: {
    bucket: env.AWS_S3_UPLOAD_BUCKET,
    region: env.AWS_S3_UPLOAD_REGION,
    accessKeyId: env.AWS_S3_UPLOAD_ACCESS_KEY_ID,
    secretAccessKey: env.AWS_S3_UPLOAD_SECRET_ACCESS_KEY,
  },
});

tus.listen({
  host: "0.0.0.0",
  port: Number(env.TUS_PORT ?? "1080"),
});

Signed (private) URLs

Generate signed URLs for your private CDN (if the url does not include the signUrl it will just pass through).

import { ImadoUrl } from "imado";
import { env } from "env";

export const getImadoUrl = new ImadoUrl({
  signUrl: env.PRIVATE_CDN_ROOT,
  cloudfrontKeyId: env.AWS_CLOUDFRONT_KEY_ID,
  cloudfrontPrivateKey: env.AWS_CLOUDFRONT_PRIVATE_KEY,
});

const thumbnailUrl = `${env.PRIVATE_CDN_ROOT}/thumbnail.jpg`;

const signedThumbnailUrl = getImadoUrl.generate(thumbnailUrl, {
  width: 100,
  format: "avif",
});

What to do on your application

Backend

  • Create an endpoint with a JWT including a public boolean and sub in the payload. Recommended would also to define a expiresIn (exp). For example:
const jwt = require("jsonwebtoken");

async function getUploadToken(ctx) {
  const isPublic = ctx.req.query("public");
  const user = ctx.get("user");

  const token = jwt.sign(
    { sub: user.id, public: isPublic === "true" },
    process.env.TUS_UPLOAD_API_SECRET
  );

  return ctx.json({
    success: true,
    data: token,
  });
}

Frontend

You would include something like Uppy and uppy/tus.

import Uppy from "@uppy/core";
import Tus from "@uppy/tus";

// Get the JWT from your server
const { token } = await (await fetch("/api/upload/token?public=true")).json();

// Convience method to read out JWT (base64) string
const readJwt = (token: string) => JSON.parse(atob(token.split(".")[1]));

// Read out JWT
const { public: isPublic, sub } = readJwt(token);

const uppy = new Uppy({
  meta: {
    public: isPublic,
  },
})
  .use(Tus, {
    endpoint: "http://localhost:1080", // endpoint for tus
    removeFingerprintOnSuccess: true,
    headers: {
      authorization: `Bearer ${token}`, // pass the JWT to tus
    },
  })
  .on("complete", (result) => {
    if (result.successful) {
      const urls = result.successful.map((file) => {
        const uploadKey = file.uploadURL.split("/").pop();
        return new URL(`https://path_to_your_cdn.com/${sub}/${uploadKey}`);
      });

      // Do something with the urls!
    }
  });