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

@porulle/adapter-shopify

v0.63.0

Published

Shopify ingress channel connector for Porulle.

Readme

@porulle/adapter-shopify

Shopify ingress channel connector for Porulle.

Catalog push and re-authorisation

Catalog push requires the write_products OAuth scope. The adapter advertises capabilities.pushCatalog: true, but effective push access is resolved per store from credentials.grantedScopes recorded during OAuth (completeAuth).

Stores connected before write_products was added to REQUIRED_SCOPES hold tokens without that scope. When push is attempted, the adapter returns SHOPIFY_WRITE_PRODUCTS_SCOPE_MISSING with retriable: false and a link to Porulle's OAuth start route (when appUrl is configured).

Operators can recover without disconnecting the store:

  1. Start Shopify OAuth again for the same store (/api/channels/oauth/shopify/start in a Porulle app with this adapter configured).
  2. Approve the updated scope list, which now includes write_products.
  3. Retry the catalog push job.

Use shopifyReauthorizeUrl(options, params) to build the authorize URL outside the push error path, or shopifyPushCatalogEnabled(store) to check scope coverage before enqueueing work.

Product images

pushCatalog writes item.images to the product's images through the Admin REST API (/products/{id}/images.json). Roles primary, gallery and thumbnail are written as images; video and document fail the item with SHOPIFY_IMAGE_ROLE_UNSUPPORTED. The primary image is written first and takes position 1, the rest follow sortOrder; alt and variantExternalIds map to the image's alt and variant_ids.

Each item outcome carries images[] with the Shopify image id as externalId. Persist it and send it back as image.externalId on the next push so the adapter updates that image in place. Without an id the adapter falls back to matching the uploaded file name against the CDN path Shopify keeps (boot.jpg matches boot.jpg and boot_a1b2c3.jpg); a file name that matches nothing creates a new image. Dry runs do not touch images.