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

@pevey/medusa

v2.14.2

Published

Extended Medusa JS SDK with custom plugin support

Downloads

37

Readme

@pevey/medusa

Extended Medusa JS SDK with support for custom plugins. Drop-in replacement for @medusajs/js-sdk that adds typed methods for Reviews, Content, Forms, and Analytics alongside all core Medusa functionality.

Installation

yarn add @pevey/medusa

Setup

import Medusa from '@pevey/medusa'

const sdk = new Medusa({
  baseUrl: 'http://localhost:9000',
  publishableKey: 'pk_...',
  auth: {
    type: 'session'
  }
})

All configuration options from @medusajs/js-sdk are supported, plus:

| Option | Type | Description | |--------|------|-------------| | analytics.salesChannelId | string | Default sales channel ID for analytics events | | analytics.cartId | string | Default actor ID (typically cart ID) | | analytics.batchSize | number | Flush when batch reaches this size (default: 10) | | analytics.flushInterval | number | Flush interval in ms (default: 2000) |

Store

All core store methods from @medusajs/js-sdk are available unchanged:

const regions = await sdk.store.region.list()
const cart = await sdk.store.cart.create({})
const products = await sdk.store.product.list()

Reviews

// List approved reviews for a product
const { reviews, count } = await sdk.store.review.list('prod_123')

// Submit a review (requires customer authentication)
const { review } = await sdk.store.review.create('prod_123', {
  rating: 5,
  body: 'Excellent quality',
  author_name: 'Alice',
  author_email: '[email protected]'
})

Content

// List content collections
const { content_collections } = await sdk.store.content.list()

// Get a specific collection
const { content_collection } = await sdk.store.content.retrieve('blog')

// List published items in a collection
const { content_items } = await sdk.store.content.listItems('blog', {
  tag: 'announcements',
  limit: 10
})

// Get a specific content item
const { content_item } = await sdk.store.content.retrieveItem('blog', 'hello-world')

Forms

// Submit a form
const { submitted } = await sdk.store.form.submit('contact', {
  data: {
    name: 'Alice',
    email: '[email protected]',
    message: 'Hello!'
  },
  cf_turnstile_response: 'token...'  // optional, if Turnstile is enabled
})

Products (Expanded Types)

sdk.store.product.list() and sdk.store.product.retrieve() return an expanded StoreProduct type that includes review data when the reviews plugin is installed:

const { products } = await sdk.store.product.list()

// products[0].reviews       — Review[]
// products[0].review_stats  — { average_rating: number, count: number }

Admin

All core admin methods from @medusajs/js-sdk are available unchanged:

const { orders } = await sdk.admin.order.list()
const { products } = await sdk.admin.product.list()

Reviews

// List reviews with filtering
const { reviews } = await sdk.admin.review.list({
  status: 'pending',
  product_id: 'prod_123'
})

// Get a single review
const { review } = await sdk.admin.review.retrieve('rev_123')

// Update a review
await sdk.admin.review.update('rev_123', { status: 'approved' })

// Delete a review
await sdk.admin.review.delete('rev_123')

// Bulk approve/reject
await sdk.admin.review.approve(['rev_123', 'rev_456'])
await sdk.admin.review.reject(['rev_789'])

Analytics

Privacy-focused event tracking with automatic batching. Events are sent to the Mildred analytics endpoint at /store/ping.

// Track an event
sdk.analytics.track('product_viewed', {
  properties: { product_id: 'prod_123' }
})

// Identify a customer
sdk.analytics.identify('cust_123', {
  anonymous_id: 'cart_abc'
})

// Set default actor/sales channel
sdk.analytics.setCartId('cart_abc')
sdk.analytics.setSalesChannelId('sc_123')

// Force flush queued events
await sdk.analytics.flush()

// Cleanup (flushes and stops timer)
await sdk.analytics.destroy()

Browser behavior: Events are queued and flushed in batches (default: 10 events or every 2 seconds). On page unload, remaining events are sent via navigator.sendBeacon for reliability.

Server behavior: Events are sent immediately with no batching.

Authentication

Authentication works exactly like @medusajs/js-sdk:

// Customer login
await sdk.auth.login('customer', 'emailpass', {
  email: '[email protected]',
  password: 'password'
})

// Customer registration
await sdk.auth.register('customer', 'emailpass', {
  email: '[email protected]',
  password: 'password'
})

// Logout
await sdk.auth.logout()

Raw Client

For endpoints not covered by the SDK, use sdk.client.fetch():

const result = await sdk.client.fetch('/admin/custom-endpoint', {
  method: 'POST',
  body: { key: 'value' }
})

Types

All types are exported for use in your application:

import type {
  // Custom plugin types
  Review,
  StoreCreateReviewInput,
  ContentCollection,
  ContentItem,
  FormSubmitInput,
  TrackOptions,

  // Expanded core types
  StoreProduct,
  AdminProduct,

  // SDK config types
  MedusaConfig,
  Config,
  ClientHeaders,
} from '@pevey/medusa'