Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

Release branches update this file with the user-visible changes included in each package version.

## 2.0.0

- Built on `@fleetbase/sdk` 2 as a regular dependency instead of a bundled copy of 1.2.13. Requests use the core SDK's Fetch transport, and axios is no longer included.
- Resources follow core SDK 2 behaviour; for example, `getAttribute(name, fallback)` returns the fallback for `null` values as well as missing ones.
- Signed-out customer requests no longer send an empty `Customer-Token` header.
- Added `customer.socketToken()` for authenticated realtime channels.

## 1.2.0

- Modernized the maintained SDK source with strict TypeScript while preserving the v1.1.14 public and request contracts.
Expand Down
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ yarn add @fleetbase/storefront
bun add @fleetbase/storefront
```

It is built on the core [`@fleetbase/sdk`](https://github.com/fleetbase/fleetbase-js) 2, which installs with it. Applications that use both should keep them on the same major version so they share one copy.

The package supports Node.js 22 and 24, native ECMAScript modules (ESM), CommonJS, browsers, server-side rendering, and TypeScript `node16`, `nodenext`, and `bundler` resolution. See the [compatibility policy](docs/compatibility.md) for the tested matrix.

## Quick start
Expand Down Expand Up @@ -168,6 +170,47 @@ const orders = await customer.getOrderHistory({ limit: 20 });

SMS, Apple, Facebook, and Google login helpers remain available. Authorized requests attach `Customer-Token` per request instead of mutating shared adapter headers.

## Realtime order updates

Realtime channels require a short-lived socket token. A signed-in customer can mint one with `customer.socketToken()` (`POST customers/socket-token`, sent with the customer's `Customer-Token`). It resolves to `{ token, expires_in, expires_at }`; the token only authorizes that customer's own channels, such as `order.{order id}` for their orders.

```js
import { create } from 'socketcluster-client';

const customer = await storefront.customers.login('person@example.com', 'password');

// Keep the token in memory only; SocketCluster calls loadToken() before every (re)connect.
let current = null;
const remember = ({ token, expires_in }) => {
current = { token, refreshAt: Date.now() + (expires_in - 60) * 1000 };
return token;
};
const authEngine = {
saveToken: async (_name, token) => token,
removeToken: async () => {
const token = current?.token ?? null;
current = null;
return token;
},
loadToken: async () => (current && Date.now() < current.refreshAt ? current.token : remember(await customer.socketToken())),
};

const socket = create({ hostname: 'socket.example.com', secure: true, port: 443, authEngine });

// Refresh about 60 seconds before the token expires.
setInterval(async () => {
if (current && Date.now() >= current.refreshAt) {
await socket.authenticate(remember(await customer.socketToken()));
}
}, 15_000);

for await (const event of socket.subscribe(`order.${order.id}`)) {
console.log(event.event, event.data);
}
```

`checkout.initialize()` responses also carry a `socket_token` scoped to that checkout's `checkout.{checkout id}` channel. A server without realtime authentication configured answers `customers/socket-token` with `404`; in that case connect without a token as before.

## Adapter replacement

```js
Expand Down
19 changes: 10 additions & 9 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
> v1.2.0 ~ "Modern Storefront SDK"
> v2.0.0 ~ "Built on the core SDK v2, with realtime socket tokens"

---

## Highlights

- Modernizes the SDK implementation with strict TypeScript while preserving the existing public API and request contracts.
- Adds current marketplace and network helpers documented by the Storefront and Core APIs.
- Ships verified ESM, CommonJS, browser, and TypeScript entry points with smaller, cleaner package contents.
- Adds complete behavioral test coverage, mutation testing, dependency review, CodeQL, and packed-package validation.
- Verifies consumers using npm, pnpm, Yarn, Bun, Vite, webpack, Next.js, and Ember.
- Adds automated, protected npm publishing with provenance and checksummed GitHub release artifacts.
- Builds on `@fleetbase/sdk` 2 as a regular dependency instead of a bundled copy of 1.2.13. Requests use the core SDK's Fetch transport; axios is no longer included.
- Applications that also use the core SDK share one copy of it, so resources, adapters and `instanceof` checks match on both sides.
- `customer.socketToken()` mints a customer-scoped realtime token (`POST customers/socket-token`) for authenticated socket channels.

This release is intended to remain compatible with applications using `v1.1.14`. See the
README and migration guide for the supported runtime matrix and packaging details.
## Breaking changes

- Resources follow core SDK 2 behaviour. For example, `getAttribute(name, fallback)` returns the fallback for `null` values as well as missing ones, and `Point` serializes as GeoJSON `[longitude, latitude]`.
- Signed-out customer requests no longer send an empty `Customer-Token` header.

The Storefront API surface (constructor, stores, actions and resource methods) is unchanged. Applications that also import `@fleetbase/sdk` should use v2.

---

Expand Down
2 changes: 1 addition & 1 deletion dist/@storefront.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/@storefront.min.js.map

Large diffs are not rendered by default.

191 changes: 96 additions & 95 deletions dist/cjs/storefront.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/cjs/storefront.cjs.map

Large diffs are not rendered by default.

189 changes: 94 additions & 95 deletions dist/esm/storefront.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/esm/storefront.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/api-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The executable wire assertions are in `tests/actions.test.js`; the frozen JavaSc

## Customer routes

The static customer-store actions cover creation, email/password login, SMS login, verification codes, and Apple/Facebook/Google login. A hydrated `Customer` supplies request-scoped `Customer-Token` authentication for device registration, places, orders, Stripe helpers, account closure, phone verification, and the compatibility `contacts/{id}` update alias.
The static customer-store actions cover creation, email/password login, SMS login, verification codes, and Apple/Facebook/Google login. A hydrated `Customer` supplies request-scoped `Customer-Token` authentication for device registration, places, orders, realtime socket tokens (`POST customers/socket-token` via `customer.socketToken()`), Stripe helpers, account closure, phone verification, and the compatibility `contacts/{id}` update alias.

The SDK deliberately passes the token in each request's options instead of mutating adapter-global headers. This preserves the server contract while preventing one customer session from leaking into another request.

Expand All @@ -59,5 +59,5 @@ The SDK deliberately passes the token in each request's options instead of mutat
- `src/cart-store` and `src/customer-store` were unreachable duplicate implementations. The historical package had an `exports` map containing only `"."`, so these paths were not supported deep imports. They were removed after their active action-based replacements reached parity.
- `Product.getReviews()` continues sending the product identifier in the legacy `store` parameter. The server route accepts the request and changing it silently could break consumers; any corrected product-review query should be introduced as a separately reviewed API.
- Customer-authorized requests retain the existing public method and header name but now use request-local options rather than adapter-global mutation.
- The package-local `@fleetbase/sdk` declaration shim exists because upstream `@fleetbase/sdk@1.2.13` ships no TypeScript declarations. The shim is strict, contains no public `any`, and is verified by Node16, NodeNext, and Bundler resolution fixtures.
- ESM and CommonJS temporarily bundle the build-time-only `@fleetbase/sdk`. Its current ESM target is reported as having no exports by webpack, while its `.js` CommonJS target sits inside a `type: module` package and fails clean CommonJS consumers when externalized. The vulnerable upstream dependency graph is therefore not installed in consuming applications; patched build-time overrides are compiled into the verified artifacts. Vite, webpack, Next.js, and clean CommonJS fixtures prevent removing this boundary before upstream publishes standards-compliant entries. `countries-list` and `date-fns` remain externalized from the module builds.
- The core SDK, `@fleetbase/sdk` 2, is a regular dependency. It ships its own declarations, ESM and CommonJS entries, and a Fetch transport with no dependencies, so the ESM and CommonJS builds import it instead of bundling a copy. An application that also uses the core SDK shares that copy, so resources, adapters, and `instanceof` checks are the same objects on both sides. Only the self-contained browser bundle inlines it. `countries-list` and `date-fns` stay external as before.
- Listing endpoints (`findAll`, `query`) keep resolving to collections in Storefront's types, although the core SDK types them as a single record or a collection.
8 changes: 2 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/storefront",
"version": "1.2.0",
"version": "2.0.0",
"description": "Official JavaScript SDK for the Fleetbase Storefront API",
"license": "AGPL-3.0-or-later",
"author": "Ronald A. Richardson <ron@fleetbase.io> (https://ron.dev)",
Expand Down Expand Up @@ -93,6 +93,7 @@
"prepack": "pnpm run build"
},
"dependencies": {
"@fleetbase/sdk": "^2.1.0",
"countries-list": "^3.4.1",
"date-fns": "^4.4.0"
},
Expand All @@ -103,7 +104,6 @@
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-terser": "^1.0.0",
"@rollup/plugin-typescript": "^12.3.0",
"@fleetbase/sdk": "1.2.13",
"@stryker-mutator/core": "10.0.0",
"@stryker-mutator/vitest-runner": "10.0.0",
"@vitest/coverage-v8": "^4.0.0",
Expand All @@ -125,10 +125,6 @@
},
"pnpm": {
"overrides": {
"@babel/runtime": "7.28.4",
"axios": "1.20.0",
"follow-redirects": "1.16.0",
"form-data": "4.0.6",
"qs": "6.16.0"
}
}
Expand Down
Loading
Loading