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

@palmetto/media-sdk

v0.1.0

Published

Install the SDK and peer dependencies:

Readme

Media API SDK

Installation

Install the SDK and peer dependencies:

yarn add @palmetto/result @palmetto/base-sdk-client @palmetto/media-sdk

Usage

Create a client instance

import { MediaClient } from "@palmetto/media-sdk";

const client = new MediaClient({
  apiUrl: app.config("media.api.url"),
  authToken: app.config("media.api.userToken"),
});

Create a new media

Public media and private media work similar ways. Use the isPublic flag to indicate if the media can be access publicly by any internet user.

Properties of CreateMediaInput:

  • filename: name of the file to store. The name does not have to be unique. Media API creates unique names for all media.
  • contentType: the MIME type of the file. Valid types:
    • application/pdf
    • image/png
    • image/jpeg
    • image/gif
    • image/svg+xml
    • video/mp4
  • isPublic: true
    • the file is stored in a publicly accessible bucket
    • publicUrl is defined in the response with a URL that can be placed on any web page.
  • isPublic: false
    • the file is stored in a separate private bucket
    • publicUrl is undefined, and you must request a signed URL to access the media.
  • expiresAfter: (optional) the time after which the file should be deleted
    • the cleanup process isn't exact. Files may live several hours after the expiresAfter value
  • permissions: (optional) an array of Users API grants (entity permissions) allowing access to the media
    • eg: ["customer:customer"] grants access to any user with customer:customer grant.
  • associatedEntities: (optional) an array of associated entities for the media
import { CreateMediaInput } from "@palmetto/media-sdk";

const file: File = {}; // get a reference to the <input type="file"> from the browser form

const media: CreateMediaInput = {
  filename: file.name,
  contentType: file.type as CreateMediaInput["contentType"],
  isPublic: true,
  expiresAfter: new Date(Date.now() + 24 * 3600 * 1000), // this media is deleted after 24 hours
};

// create the media itself
const createdMedia = await client.createMedia(media);

if (!createdMedia.ok) {
  toast.error("Failed to create media:", createdMedia.error);
  return;
}

try {
  // next upload the media using the signed URL
  const fetchResponse = await fetch(
    new Request(createdMedia.data.signedUrlForUpload.url, {
      headers: createdMedia.data.signedUrlForUpload.headers,
      body: file,
      method: "PUT",
    }),
  );

  if (!fetchResponse.ok) {
    toast.error("Failed to upload media. Please try again.");
    return;
  }
} catch (error) {
  toast.error("Failed to upload media. Please try again.");
  return;
}

getMediaById

Use getMediaById to access the media details and get a URL to download the file. See examples below.

  • id the media ID
  • includeSignedUrl: set to true to return the signedUrlForDownload in the response. (default: false)
  • inline: set to true so that the download is done inline, false crafts the file download as an attachment. (default: false)

Opening the media in a browser

For public media, you can use the publicUrl property to access the media. Private media must use a signed URL to download.

Public media

Public media URLs never change. They are valid until the media is deleted.

const { publicUrl } = createdMedia.data;

window.location.href = publicUrl;

Private media

Private media you must access using a signed URL. The signed URL is only valid for a few minutes so you must download the file soon after requesting the URL.

const getMediaResult = await client.getMediaById({
  id: createdMedia.data.id,
  includeSignedUrl: true,
  inline: false,
});

if (!getMediaResult.ok) {
  toast.error("Failed to fetch media details:", getMediaResult.error);
  return;
}

const { signedUrlForDownload } = getMediaResult.data;

window.location.href = signedUrlForDownload;

Permissions

Media have permissions. By default, only the API user that created the media can update or delete the media. You can use the permissions property to allow other API users with that permission to modify or delete the media.

const media: CreateMediaInput = {
  filename: file.name,
  contentType: file.type as CreateMediaInput["contentType"],
  isPublic: false,
  permissions: ["customer:customer"],
};

This example allows any user with customer:customer entity grant to access the media. This access is global, it doesn't know that the media belongs to a specific customer, for example. [This feature may be improved later on].

Update Media

You can update a media's permissions, associatedEntities and expiresAfter using updatedMediaById. Your user must have created the media, or have the write operation for one of the permissions on the media.

Delete media

You can delete a media using deleteMediaById. Your user must have created the media, or have the delete operation for one of the permissions on the media.