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

@render-lab/tasks-shopify

v0.1.2

Published

Durable Shopify tasks for Render Workflows: shopify.getOrder/listOrders/fulfillOrder/updateInventory.

Downloads

204

Readme

@render-lab/tasks-shopify

⚠️ Experimental: proof of concept. This package is part of the Render Tasks POC and is published for testing only. It is not fully tested or production ready. Task names, inputs, outputs, and behavior can change or break in any release. Pin exact versions and expect breaking changes.

Durable Shopify tasks for Render Workflows.

import {
  getOrder,
  listOrders,
  fulfillOrder,
  refundOrder,
  cancelOrder,
  updateInventory,
  getProduct,
  listProducts,
  createProduct,
  updateProduct,
  getCustomer,
  searchCustomers,
} from "@render-lab/tasks-shopify";

| Task | Input | Output | | ------------------------- | ---------------------------------------------- | ----------------------- | | shopify.getOrder | { orderId } | Order | | shopify.listOrders | { status?, limit? } | Order[] | | shopify.fulfillOrder | { orderId, trackingNumber? } | FulfillResult | | shopify.refundOrder | { orderId, amount? } | RefundResult | | shopify.cancelOrder | { orderId, reason? } | Order | | shopify.updateInventory | { inventoryItemId, locationId, delta } | UpdateInventoryResult | | shopify.getProduct | { productId } | Product | | shopify.listProducts | { limit? } | Product[] | | shopify.createProduct | { title, status?, handle?, variants? } | Product | | shopify.updateProduct | { productId, title?, status?, handle?, variants? } | Product | | shopify.getCustomer | { customerId } | Customer | | shopify.searchCustomers | { query, limit? } | Customer[] |

listOrders defaults status to "any" and limit to 20; listProducts and searchCustomers default limit to 20.

All tasks return JSON-serializable DTOs (Order, OrderLineItem, FulfillResult, RefundResult, UpdateInventoryResult, Product, ProductVariant, Customer) — never raw Shopify API responses. Single resources are unwrapped from Shopify's { product: … } / { customer: … } envelope and lists from { products: [ … ] } / { customers: [ … ] }. The default port is fetch-backed against the Shopify Admin REST API at https://<store>/admin/api/2024-10, authenticated with the X-Shopify-Access-Token header.

Webhook adapter

Use @render-lab/tasks-shopify/webhooks from a trigger web service to verify Shopify webhooks and map verified events to Workflow task runs:

import { shopifyAdapter } from "@render-lab/tasks-shopify/webhooks";
import { serveDispatchServer } from "@render-lab/triggers";

serveDispatchServer({
  webhooks: {
    shopify: shopifyAdapter({
      onEvent: ({ topic, payload }) => {
        if (topic !== "orders/create") return null;
        if (typeof payload.id !== "number") return null;
        return { task: "fulfillment.run", args: [{ orderId: payload.id }] };
      },
    }),
  },
});

Shopify signs the raw body with X-Shopify-Hmac-Sha256 = BASE64(HMAC-SHA256(secret, rawBody)) (base64, not hex), which verify checks in constant time; map reads the event type from the X-Shopify-Topic header (e.g. orders/create). The /webhooks subpath does not import the package root, register shopify.* tasks, or read credentials at import time (the secret is read inside verify). Keep provider event mapping in the trigger service because task names are workflow-specific.

Install

pnpm add @render-lab/tasks-shopify @renderinc/sdk

@renderinc/sdk is a peer dependency. The package has no vendor dependency — it uses the global fetch. If you use the webhook adapter in a trigger web service, also install @render-lab/triggers.

Environment contract

Credentials are read lazily at the first API call, never at import (ADR-0007), so importing the package for one task never requires another's secret.

| Variable | Required | Purpose | | ---------------------- | -------- | ------------------------------------------------------------------------- | | SHOPIFY_STORE | yes | Store domain used as the API host, e.g. acme.myshopify.com. | | SHOPIFY_ACCESS_TOKEN | yes | Admin API access token, sent as X-Shopify-Access-Token: …. | | SHOPIFY_WEBHOOK_SECRET | for the Shopify webhook adapter | HMAC secret used by @render-lab/tasks-shopify/webhooks to verify X-Shopify-Hmac-Sha256 before dispatch. This belongs on the trigger web service, not the Workflow service. |

Extending & testing

Every operation exports the wrapped task and its raw *Impl. The impls depend on a small ShopifyPort interface, so they unit-test without touching the network:

import { getOrderImpl, type ShopifyPort } from "@render-lab/tasks-shopify";

const shopify: Partial<ShopifyPort> = {
  getOrder: async () => ({
    id: "450789469",
    name: "#1001",
    email: "[email protected]",
    financialStatus: "paid",
    fulfillmentStatus: null,
    totalPrice: "199.00",
    currency: "USD",
    lineItems: [{ id: "li-1", title: "Widget", quantity: 2, sku: "AW-01" }],
  }),
};
await getOrderImpl({ orderId: "450789469" }, { shopify } as any);

Run the tests with pnpm -C packages/tasks-shopify test.