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

@ab-ecosystem/aistore-admin

v0.1.0

Published

Headless ecommerce admin API SDK for AI Store - a typed TypeScript REST client for products, orders, customers, inventory, shipping, taxes, themes and webhooks, over the SSO /dashboard and api-key /api/dashboard endpoints.

Readme

@ab-ecosystem/aistore-admin

TypeScript SDK and REST API client for AI Store — the headless ecommerce admin API. Manage products, orders, customers, inventory, pricing, shipping, taxes, themes and webhooks from Node.js, the browser or an edge runtime, with full type safety and zero runtime dependencies.

Built for headless commerce: a merchant dashboard, a back-office tool, a storefront build pipeline, a WhatsApp or voice-AI sales bot, or any server-to-server ecommerce integration can drive the same typed admin API.

  • client.dashboard.* → the /dashboard router, authenticated with an SSO access token (JWT). This is the merchant dashboard surface.
  • client.api.* → the /api/dashboard router, authenticated with a store API key. This is the integration and automation surface.

Table of contents

Features

  • Complete admin API coverage — every client-facing route on both admin routers: catalog, orders, carts, customers, segments, pricing rules, taxes, shipping zones, custom fields, warehouses, themes, webhooks, media uploads, payment methods and plans.
  • Typed end to end — TypeScript definitions for every method, with generics so you can type each response payload: admin.api.products.fetch<MyProduct>().
  • Dual authentication — SSO JWT for dashboard routes and store API key for integration routes, resolved per request from a string or an async token provider.
  • Zero runtime dependencies — nothing but the platform fetch. Nothing to audit, nothing to patch.
  • ESM and CommonJS — dual build with import and require entry points, plus sideEffects: false for tree-shaking.
  • Multi-channel catalog sync — pull from WooCommerce, Shopify, Meta and Zid; push catalogs back to Meta.
  • Typed errors — distinguish API, configuration, network and timeout failures without string matching.
  • Cancellation and timeouts — per-client and per-call timeoutMs, plus AbortSignal support on every method.
  • Pluggable fetch — inject undici, a polyfill, or a wrapper that adds logging, tracing or retries.

Installation

npm install @ab-ecosystem/aistore-admin
pnpm add @ab-ecosystem/aistore-admin
yarn add @ab-ecosystem/aistore-admin

Quick start

import { AIStoreAdmin, AIStoreApiError } from "@ab-ecosystem/aistore-admin";

const admin = new AIStoreAdmin({
  baseUrl: "https://api.your-domain.com",
  accessToken: () => getSsoToken(),      // string or (async) function → used by client.dashboard.*
  apiKey: process.env.AISTORE_API_KEY,   // string or (async) function → used by client.api.*
  timeoutMs: 15_000,
});

// Merchant dashboard (SSO token)
const { data: products, total } = await admin.dashboard.products.fetch({ status: "publish", page: 1, size: 20 });
await admin.dashboard.orders.update({ orderId, order_status: "shipped" });

// Integrations and automations (API key)
const orders = await admin.api.orders.fetch({ page: 1, size: 50 });
await admin.api.products.create({ name: "Mug", price: 299, quantity: 10, image_urls: [url] });

try {
  await admin.dashboard.store.fetch();
} catch (err) {
  if (err instanceof AIStoreApiError) console.error(err.status, err.code, err.message, err.body);
}

CommonJS works the same way:

const { AIStoreAdmin } = require("@ab-ecosystem/aistore-admin");

Configuration options

| Option | Type | Default | Description | | --- | --- | --- | --- | | baseUrl | string | — | Required. Server origin, e.g. https://api.example.com. Router prefixes are added by the SDK. | | accessToken | string or token provider | — | SSO access token (JWT) for /dashboard routes. A function is resolved on every request, so token refresh needs no client rebuild. | | apiKey | string or token provider | — | Store API key for /api/dashboard routes. | | bearerPrefix | boolean | false | Prefix the Authorization value with Bearer . Off by default because the server verifies the raw header value as the JWT. | | fetch | typeof fetch | global fetch | Custom fetch implementation for logging, tracing, retries or polyfills. | | timeoutMs | number | none | Default per-request timeout. Overridable per call. | | headers | Record<string, string> | — | Extra headers sent with every request. |

A token provider is any () => string | Promise<string>. Read the current origin with admin.baseUrl.

Authentication

| Namespace | Header | Option | Notes | | --- | --- | --- | --- | | client.dashboard.* | Authorization: <jwt> | accessToken | Raw JWT, no Bearer prefix. Set bearerPrefix: true if your deployment expects one. | | client.api.* | api-key: <key> | apiKey | Issue a key with dashboard.account.refreshApiKey(); rotating invalidates the old one. |

Both credentials accept an async provider, which is the recommended pattern for short-lived SSO tokens:

const admin = new AIStoreAdmin({
  baseUrl,
  accessToken: async () => (await session.getValidToken()).jwt,
});

Swap credentials at runtime without constructing a new client:

admin.setAccessToken(newJwt);
admin.setApiKey(rotatedKey);

A few /dashboard routes take the API key instead of the SSO token; they are marked api-key in their JSDoc (restaurant.createConfig, restaurant.fetchAvailability, restaurant.createBooking, restaurant.updateBooking). Public routes send no credential at all (account.searchAppCode, account.addWhitelistUrl, theme.fetchCss, theme.fetchStaticFile, theme.fetchDefaultThemes, theme.fetchAgencyTheme).

Calling a method without the credential it needs throws AIStoreConfigError before any request leaves the process.

API reference

client.dashboard — merchant dashboard endpoints (/dashboard)

| Resource | Methods | | --- | --- | | account | overview, refreshApiKey, createNewStore, searchAppCode, addWhitelistUrl | | warehouse | create, fetch, searchLocation, updateShippingCost | | pushTokens | register, remove | | products | fetch, create, update, delete, fetchVariants, createFromCsv, downloadFullCsv, fetchForBulkEdit, syncHistory | | categories | fetch, create, update, delete, moveAndDelete | | options | fetch, create, update, delete | | orders | fetch, getById, delete, update; orders.notes.{fetch,create,delete}; orders.disputes.{fetchByOrder,update,fetchPaymentStatus,updatePayment} | | carts | fetch | | store | create, fetch, update, loadDetails | | storeSettings | fetch, update, generateMcpApiKey, disableMcpApiKey | | theme | fetch, update, fetchSkeleton, fetchStaticFile, fetchCss, fetchAdminSkeleton, updateAiFeatures, fetchAgencyTheme, fetchSkeletonThemes, saveAsNewTheme, activate, fetchDefaultThemes | | webhooks | create, fetch, delete, updateStatus | | customers | fetch, create, uploadCsv, assignSegment; customers.segments.{create,fetch,edit}; customers.pricingRules.{create,update,fetch,fetchForProduct} | | taxes | create, fetch, edit, delete | | shipping | shipping.zones.{create,fetch,getById,edit,delete}; shipping.classes.{create,fetch,update} | | customFields | create, fetch, edit, delete; customFields.values.{create,fetch,edit,delete} | | location | getStreetAddress | | media | getPresignedUrl | | quickFilters | create, update, delete, fetch, fetchProductsForPicker, fetchProductsByFilters | | productSync | pullFromWooCommerce, pullFromMeta, pushToMeta, initShopifySync, pullFromZid | | connectors | fetch, connect, disconnect; connectors.meta.{getBusinessProfiles,getCatalogueLists,saveCatalogue}; connectors.shopify.{getAuthUrl,connect,subscribeWebhook,fetchDetails,update,deleteStore}; connectors.zid.redirect | | plans | upgrade | | paymentMethods | connect, fetch, updateStatus | | restaurant | createConfig, updateConfig, fetchConfig, fetchDailySlots, updateDailySlots, fetchAvailability, createBooking, updateBooking, fetchBookedTables | | aiChat | callLlm, fetchChats, fetchMessage |

client.api — integration endpoints (/api/dashboard)

| Resource | Methods | | --- | --- | | products | fetch, create, update, delete, fetchVariants, fetchByCategory, createFromCsvFile (multipart) | | carts | fetch | | categories | fetch, create, update, delete, moveAndDelete | | options | fetch, create, update, delete | | orders | fetch, getById, delete, create, update | | store | create, fetch, update, loadDetails | | theme | fetch, update, fetchSkeleton, fetchStaticFile, fetchCss | | webhooks | create, fetch, delete, updateStatus | | automation | imageSearch, textSearch | | media | paymentDisputePresignedUrl |

Each method's JSDoc names the exact server path, including the server's own spelling quirks such as /update-shpping-cost.

Response envelope and pagination

Every method returns the server's JSON envelope, typically { status, message?, data?, total? }. Pass a type argument to type data:

const { data, total } = await admin.api.products.fetch<MyProduct[]>({ page: 1, size: 50 });

List endpoints take page and size and report total, so paging is a plain loop:

const size = 100;
for (let page = 1; ; page++) {
  const { data, total } = await admin.api.orders.fetch({ page, size });
  if (!data?.length) break;
  await handle(data);
  if (page * size >= (total ?? 0)) break;
}

Per-call options

Every method accepts a trailing options object:

await admin.dashboard.products.fetch({ page: 1 }, {
  signal: controller.signal,       // AbortSignal
  timeoutMs: 5_000,                // overrides the client default
  headers: { "x-request-id": id }, // extra headers
  responseType: "text",            // "auto" (default) | "json" | "text" | "blob"
});

responseType: "blob" is the one you want for theme assets and CSV downloads such as dashboard.products.downloadFullCsv().

File uploads and CSV import

// Browser
await admin.api.products.createFromCsvFile(fileInput.files[0]);

// Node 18+
import { openAsBlob } from "node:fs";
await admin.api.products.createFromCsvFile(await openAsBlob("./products.csv"), { fileName: "products.csv" });

For images and other media, request a presigned URL and upload directly to storage:

const { data } = await admin.dashboard.media.getPresignedUrl({ fileName: "hero.jpg", fileType: "image/jpeg" });

Error handling

| Class | When it is thrown | | --- | --- | | AIStoreApiError | Non-2xx response. Carries status, code (e.g. SESSION_EXPIRED, invalid_token), body, headers and request. | | AIStoreConfigError | Missing baseUrl, or a credential the route needs. Thrown before the request is sent. | | AIStoreNetworkError | Fetch itself failed — DNS, CORS, offline. | | AIStoreTimeoutError | timeoutMs elapsed. |

All four extend AIStoreError, so a single instanceof check catches everything this SDK throws:

import { AIStoreError, AIStoreApiError, AIStoreTimeoutError } from "@ab-ecosystem/aistore-admin";

try {
  await admin.dashboard.orders.fetch({ page: 1 });
} catch (err) {
  if (err instanceof AIStoreApiError && err.status === 401) return refreshSsoAndRetry();
  if (err instanceof AIStoreTimeoutError) return queueForLater();
  if (err instanceof AIStoreError) return report(err);
  throw err;
}

Calling unwrapped endpoints

New server routes are reachable before the SDK wraps them. path is relative to baseUrl and must include the router prefix:

await admin.request("POST", "/dashboard/some-new-route", { body: payload, auth: "sso" });
await admin.request("GET", "/api/dashboard/some-new-route", { auth: "apiKey" });

Use cases

  • Headless ecommerce storefronts — fetch catalog, categories and theme assets at build time or per request for Next.js, Nuxt, Astro, SvelteKit or a static site generator.
  • Custom merchant dashboards — build an admin panel on the SSO-authenticated /dashboard surface, the same API the first-party dashboard uses.
  • Conversational and voice commerce — back a WhatsApp catalog, chatbot or voice-AI agent with live products, carts and order creation.
  • ERP, POS and accounting sync — reconcile orders, inventory and customers from a scheduled job using a store API key.
  • Platform migration and multi-channel listing — import an existing catalog from WooCommerce, Shopify or Zid, and publish it to Meta commerce catalogs.
  • Bulk catalog operations — CSV import and export, bulk edit, quick filters and product variant management.
  • Restaurant and appointment booking — table configuration, daily slots, availability checks and reservations.
  • AI-assisted retail — image and text product search, AI chat, and MCP API keys for agent-driven store access.

Requirements and compatibility

| | | | --- | --- | | Node.js | 18 or newer (needs the built-in fetch) | | Browsers | Any modern browser; CORS must allow your origin | | Edge and serverless | Any runtime providing the WHATWG fetch, Headers and AbortSignal | | Module formats | ESM (import) and CommonJS (require) | | TypeScript | Types bundled; no @types package needed | | Runtime dependencies | None |

On Node 16 or an older browser target, pass a polyfill through the fetch option.

FAQ

Is this a headless ecommerce SDK? Yes. The storefront and the admin surface are fully decoupled from the API, so you can build any frontend — web, mobile, chat or voice — against these typed endpoints.

What is the difference between client.dashboard and client.api? client.dashboard maps to /dashboard and authenticates a logged-in merchant with an SSO JWT; use it for interactive dashboards. client.api maps to /api/dashboard and authenticates a store with a long-lived API key; use it for servers, cron jobs and third-party integrations.

Can I use it in the browser? Yes, and that is the intended setup for a dashboard UI. Keep the store API key out of browser bundles — it is a long-lived store-wide credential, so confine client.api to server-side code.

Does it retry failed requests? No. Retry policy is deliberately left to you, because the right behavior differs between an interactive dashboard and a background sync. Wrap the fetch option to add retries and backoff in one place.

How do I handle an expired SSO token? Pass accessToken as an async function. It is resolved on every request, so returning a freshly refreshed JWT is enough. Alternatively call setAccessToken() after a refresh.

How do I rotate the store API key? Call dashboard.account.refreshApiKey(), then admin.setApiKey(newKey). The previous key stops working immediately.

Is TypeScript required? No. The package ships compiled JavaScript for both ESM and CommonJS; the types are a bonus if you use them.

How do I type a response? Pass a type argument to any method: admin.api.orders.fetch<MyOrder[]>({ page: 1 }).

Known server quirks

  • dashboard.customFields.fetch({ type }) — the server reads type from the request body on a GET. The SDK sends it as a query parameter, so the list stays unfiltered until the server reads the query.
  • dashboard.products.fetchForBulkEdit has no auth middleware on the server.

License

ISC