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

medusa-export

v0.0.7

Published

A starter for Medusa plugins.

Readme

medusa-export

Medusa v2 admin export plugin that adds CSV export APIs and admin export buttons for core and extension pages.

Plugin Overview

medusa-export provides a generic admin export endpoint and UI integrations to download CSV files for Medusa entities.

Implemented behavior includes:

  • GET /admin/export/:model_name CSV export endpoint.
  • Special inventory export mode (inventory-item) with flattened location-level stock rows.
  • Generic remoteQuery-based export for arbitrary models.
  • Empty/fallback CSV handling to avoid hard failures in many cases.
  • Admin UI export buttons:
    • Widget-based buttons on selected list pages.
    • DOM-injected export button for selected extension pages.

It solves the need to quickly export operational/admin data from Medusa to spreadsheets.

Medusa Version

  • Built for Medusa v2 (@medusajs/framework, @medusajs/medusa 2.12.4).

Installation & Setup

1) Install

npm install medusa-export
yarn add medusa-export

2) Register plugin

import { defineConfig } from "@medusajs/framework/utils"

export default defineConfig({
  plugins: [
    {
      resolve: "medusa-export",
    },
  ],
})

3) Build / run

npx medusa plugin:build
npx medusa develop

4) Migrations

No custom models or migrations are implemented in this plugin; no plugin-specific migration is required.

Configuration (config.ts / plugin options)

No plugin options are read by the code.

| Option | Type | Required | Default | Description | |---|---|---|---|---| | None implemented | - | - | - | Plugin behavior is code-defined and route-driven; no runtime option parsing. |

Example registration:

{
  resolve: "medusa-export"
}

Environment Variables

No process.env.* variables are used in implemented plugin source files.

| Variable | Required | Purpose | Example | |---|---|---|---| | None | - | - | - |

REST APIs / Routes

1) GET /admin/export/:model_name

Exports CSV for the specified model.

  • Auth requirement: Admin route context.
  • Path params:

| Param | Type | Required | Description | |---|---|---|---| | model_name | string | Yes | Target model/entry point (for example product, order, customer, inventory-item). |

  • Query params:

| Param | Type | Required | Description | |---|---|---|---| | limit | string | No | Pagination limit (parsed integer). | | offset | string | No | Pagination offset (parsed integer). | | fields | string | No | Comma-separated fields; defaults to *. | | filter | string | No | JSON string for query filters. |

Special behavior: model_name=inventory-item

When model_name is inventory-item, the route:

  • Uses query.graph on inventory_item.
  • Resolves inventory levels via Modules.INVENTORY listInventoryLevels.
  • Resolves location names via stock_location.
  • Returns flattened CSV columns: id,title,location,instock.

Generic export behavior

For non-inventory-item models, route uses resolved remoteQuery with entryPoint and optional pagination/filter parameters.

Special mapping implemented:

  • contact-request path maps to remote query entry point contact_request.

Response

  • Content type: text/csv; charset=utf-8
  • Attachment filename: ${model_name}_${YYYY-MM-DD}.csv
  • Includes UTF-8 BOM for Excel compatibility.

Error/fallback behavior

  • 400 if model_name missing or filter is invalid JSON.
  • For certain extension models with no rows, returns 404 JSON message.
  • In outer catch fallback, returns HTTP 200 with empty CSV rather than 500.

cURL examples

curl -X GET "http://localhost:9000/admin/export/product" \
  -H "Authorization: Bearer <ADMIN_TOKEN>" \
  -o product.csv
curl -X GET "http://localhost:9000/admin/export/inventory-item?limit=500&offset=0" \
  -H "Authorization: Bearer <ADMIN_TOKEN>" \
  -o inventory-item.csv
curl -G "http://localhost:9000/admin/export/order" \
  -H "Authorization: Bearer <ADMIN_TOKEN>" \
  --data-urlencode "fields=id,status,email,created_at" \
  --data-urlencode "filter={\"status\":\"pending\"}" \
  -o order.csv

2) GET /store/plugin

Health endpoint.

  • Auth requirement: Public store route.
  • Response: HTTP 200.
curl -X GET "http://localhost:9000/store/plugin"

Services

No custom service classes are implemented.

The export route relies on container resources:

  • remoteQuery (resolved from scope)
  • ContainerRegistrationKeys.QUERY graph service
  • Modules.INVENTORY service (listInventoryLevels)

Workflows & Steps (Medusa v2)

No custom workflows or steps are implemented.

Subscribers / Event Hooks

No subscribers/event hooks are implemented.

Admin UI / Widgets

This plugin implements admin extension behavior via widgets and DOM initialization scripts.

Widget: Inventory export button

  • File: src/admin/widgets/inventory-export-widget.tsx
  • Zone: inventory_item.list.before
  • Placement behavior: Finds Create control on /app/inventory and injects export button beside it using portal + mutation observer.
  • Action: Calls /admin/export/inventory-item, downloads returned CSV.

Widget: Dynamic export button

  • File: src/admin/widgets/dynamic-export-widget.tsx
  • Zones: customer.list.before, order.list.before, promotion.list.before, location.list.before
  • Action: Resolves model from current URL mapping and calls /admin/export/:model.

Extension-page DOM injection utility

  • Files: src/admin/init-extension-exports.tsx, src/admin/utils/extension-export-buttons.ts
  • Behavior: Mutation observer detects page content header and injects export buttons for specific extension paths:
    • /app/returns -> return
    • /app/contact-requests -> contact-request
    • /app/contact-email-subscriptions -> contact-email-subscriptions
  • Note: stock-monitoring export button is intentionally excluded in utility comments.

Export hub page

  • File: src/admin/pages/export-hub.tsx
  • Renders: standalone page with manual export buttons for several models.
  • Status in codebase: present component, but no explicit defineRouteConfig route registration file in current plugin structure.

⚠️ Note: src/admin/widgets/zones/export-zones.tsx contains mappings for additional routes/models beyond widget zone registrations; these mappings are partially unused unless connected by surrounding extension code paths.

Models & Entities

No custom entities/models are defined.

Use Cases & Examples

  1. Export core commerce records

    • Use /admin/export/order or /admin/export/customer to download tabular operational data.
  2. Export inventory by location for reconciliation

    • Use /admin/export/inventory-item to get flattened rows with location and instock.
  3. Export filtered subsets

    • Use filter query JSON and fields selection to reduce output scope.
  4. One-click admin exports from list pages

    • Use built-in widget buttons on customer/order/promotion/location and inventory pages.
  5. Extension page export support

    • Use injected export buttons on configured extension routes (returns/contact-request/contact-email-subscriptions).

Troubleshooting

Empty CSV output

  • Cause: no matching rows or export fallback path.
  • Fix: verify model_name, remove overly restrictive filters, and retry without fields/filter.

404 for extension models

  • Cause: route explicitly returns 404 with message when no rows found for selected extension models.
  • Fix: ensure source plugin/module actually has data for that model.

Invalid filter JSON

  • Cause: malformed filter query value.
  • Fix: send valid JSON string (URL-encoded when needed).

Export button not appearing in admin

  • Cause: page DOM structure not matched by injection logic, or plugin bundle not loaded.
  • Fix: rebuild plugin, restart admin, hard refresh browser, and verify route/path matches supported paths.

Inventory export missing location names

  • Cause: location lookup query failure or missing location records.
  • Fix: verify stock location data exists and query service is functioning.