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

@laioutr/app-b2bsellers

v0.3.0

Published

B2B Sellers connector app for Laioutr

Readme

B2B Sellers App for Laioutr

Laioutr npm version npm downloads License Nuxt

A Laioutr App for integrating B2B Sellers into the Laioutr platform.

It wraps the B2B Sellers Store API (a Shopware 6 plugin) as a typed operations map with thin query wrappers and a request-scoped client. Backend only — no sections, no blocks. Its consumer is app-boltze.

See laioutr.com for more information about Laioutr.

State of the integration — 2026-09-17

Verified against https://laioutr.demoshop.b2b-sellers.com (Shopware 6.7.6.2) with a live customer session. Full evidence in docs/reviews/2026-09-17-store-api-verification.md.

Reading works. 90 operations, zero missing paths; 27 return real data with a session — 12 customers, 10 orders, 17 employees, 3 cost centers, 2611 activity records. The map was corrected against the shop rather than against its OpenAPI document, which disagrees with it in a dozen places.

Writing does not, and that is not a code problem. Three independent routes into creating an offer are each closed:

| | | | --- | --- | | POST /offer then offer-add-products | the offer is created, then 403 B2B_OFFER__UPDATE_DENIED in every state, and PUT /offer/{id} is 405 — so it stays permanently empty | | POST /offer-request (cart → offer) | 403 B2B_OFFER__PERMISSION_DENIED for a B2B employee and for the B2B administrator. None of the 15 employee permissions the shop exposes concerns offers, so it is an admin-side setting | | any of them | the Headless sales channel our access key belongs to sells one product; everything on the existing orders belongs to another channel and the cart refuses it with product-not-found |

What unblocks it — Shopware admin work on the demo shop, by whoever provisioned it: assign the catalogue and its visibility to the Headless channel and enable the offer module for its B2B customers, or hand over the access key of the channel that already carries the catalogue (ee0ad685d0504d5f80730d9b53f794c8).

Also worth knowing: the shop rate-limits sign-ins hard (429 CHECKOUT__CUSTOMER_AUTH_THROTTLED) after a handful of attempts. A few mistyped passwords on stage will lock an account out for minutes.

Credentials

The demo shop publishes its own test accounts at /Benutzeruebersicht/. The sales app signs in as the Vertriebsmitarbeiter [email protected]. [email protected] is deliberately refused — the shop denies it B2B-platform access on every route.

Checking a shop yourself

pnpm verify:openapi     # the operations map against the shop's own OpenAPI document
pnpm verify:shop        # the operations map against the shop itself, read-only

Both read SHOPWARE_SHOP_URL and SHOPWARE_ACCESS_KEY from the environment, and both take flags straight through — pnpm verify:openapi -- --save=openapi3.json, pnpm verify:shop -- --user=… --password=….

export SHOPWARE_SHOP_URL=https://laioutr.demoshop.b2b-sellers.com
export SHOPWARE_ACCESS_KEY="$(node -p "require('./laioutrrc.json').apps[0].config.accessToken")"

Why this exists. src/runtime/server/client/operations.ts claims, for 95 operations, that a given name means a given method on a given path with a given response. Those claims were written without a live instance — and a wrong one is invisible: TypeScript is satisfied, the linter is quiet, and the unit tests mock the client away. It surfaces only at runtime, as a 404 that reads like "the plugin cannot do this" rather than "the path is misspelled". This script makes the shop the authority instead of the vendor's documentation, and turns a silent lie in the types into a non-zero exit code.

It has earned its keep: it found 29 operations missing the /store-api prefix and 11 more under an undocumented sales-representative one — forty dead routes — and later caught a body this repository declared optional where the shop requires it.

verify:openapi fetches GET /store-api/_info/openapi3.json and compares every entry. Verdicts: OK, MISMATCH (status, body or parameter names differ), WRONG_METHOD, PREFIX_MISSING (the path exists but the map omits the server prefix, so the call 404s), PATH_MISSING. --spec=openapi3.json runs it offline against a saved document, --fields prints the response's top-level fields, --all lists the spec paths the map does not cover, --json is machine-readable. Exit: 0 clean, 1 mismatches, 2 could not run. Today it exits 1: 16 mismatches and 2 wrong methods are still open, so treat the run as a report to read rather than a gate that has ever been green.

verify:shop is the stronger claim: it calls the shop rather than reading its document, because a route can match the document and still 404 — order-approval list and create did exactly that. It skips every mutating operation by name, so it stays read-only; with --user / --password it signs in and reads real data.

The name is about OpenAPI, the specification format Shopware serves about itself. Nothing here talks to OpenAI and no API key of that kind is involved — the only credential is the shop's own sales-channel access key.

Features

Backend only — a typed Store-API surface, not a storefront app. No Orchestr handlers, no sections, no blocks live here; the consumer (app-boltze) writes those and calls the client this module exposes.

  • 🔌  89 typed Store-API operations with thin query wrappers, verified against a live shop
  • 🔑  Request-scoped client that holds a customer session (useB2bSellersClient), the secret server-side only
  • 🧪  Two verification scripts — one against the shop's OpenAPI document, one against the shop itself

Quick Setup

Before installing dependencies, you need to create a copy of the .npmrc.config file called .npmrc and fill in the NPM_LAIOUTR_TOKEN with your npm token. You can find this token in your project settings.

  • pnpm i
  • npx @laioutr/cli project fetch-rc -p <organization slug>/<project slug> -s <project secret key> - This will load the laioutrrc.json file with the current remote project configuration.
  • pnpm dev:prepare
  • pnpm orchestr-dev

That's it! You can now use the B2B Sellers App in your Laioutr Frontend

You can find a thorough guide on getting started with Laioutr development in our developer guide.

Linting and Formatting

We use ESLint and Prettier to lint and format the code. This repository contains opinionated configurations for both tools. You can - of course - replace them with your own configurations.

Publishing

Releases are managed with Changesets and published to npmjs.org automatically by the release workflow.

To ship a change:

  1. In your PR, run pnpm changeset and follow the prompt to record the change and the version bump (patch/minor/major). Commit the generated file in .changeset/.
  2. Merge the PR to main. The release workflow opens (or updates) a "Version Packages" PR that applies the pending changesets to the version and CHANGELOG.md.
  3. Merge the "Version Packages" PR. The workflow builds the package and publishes it to npmjs.org, tags the commit, and creates a GitHub release.

Publishing uses npm OIDC trusted publishing, so no npm token is stored in the repository — the workflow needs id-token: write and a trusted publisher configured for the package on npmjs.org.

Contribution

Follow the setup guide to get started.