@farthershore/farthershore-js 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +280 -187
  3. package/dist/bootstrap.js +3 -3
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/client.d.ts +79 -69
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +31 -79
  8. package/dist/client.js.map +1 -1
  9. package/dist/components/app.d.ts +7 -6
  10. package/dist/components/app.d.ts.map +1 -1
  11. package/dist/components/app.js +22 -9
  12. package/dist/components/app.js.map +1 -1
  13. package/dist/components/auth-guard.d.ts +44 -12
  14. package/dist/components/auth-guard.d.ts.map +1 -1
  15. package/dist/components/auth-guard.js +28 -12
  16. package/dist/components/auth-guard.js.map +1 -1
  17. package/dist/components/auth.d.ts +18 -0
  18. package/dist/components/auth.d.ts.map +1 -1
  19. package/dist/components/auth.js +167 -8
  20. package/dist/components/auth.js.map +1 -1
  21. package/dist/components/bill-estimator.js +1 -1
  22. package/dist/components/bill-estimator.js.map +1 -1
  23. package/dist/components/billing.d.ts +9 -1
  24. package/dist/components/billing.d.ts.map +1 -1
  25. package/dist/components/billing.js +3 -3
  26. package/dist/components/billing.js.map +1 -1
  27. package/dist/components/cancel-subscription.js +2 -2
  28. package/dist/components/cancel-subscription.js.map +1 -1
  29. package/dist/components/capability-usage-card.js +2 -2
  30. package/dist/components/capability-usage-card.js.map +1 -1
  31. package/dist/components/chrome.d.ts +3 -2
  32. package/dist/components/chrome.d.ts.map +1 -1
  33. package/dist/components/chrome.js +7 -3
  34. package/dist/components/chrome.js.map +1 -1
  35. package/dist/components/credit.js +2 -2
  36. package/dist/components/credit.js.map +1 -1
  37. package/dist/components/docs.css +7 -3
  38. package/dist/components/index.d.ts +3 -3
  39. package/dist/components/index.d.ts.map +1 -1
  40. package/dist/components/index.js +6 -2
  41. package/dist/components/index.js.map +1 -1
  42. package/dist/components/keys.js +2 -2
  43. package/dist/components/keys.js.map +1 -1
  44. package/dist/components/limit-boundary.d.ts +1 -1
  45. package/dist/components/limit-boundary.d.ts.map +1 -1
  46. package/dist/components/limit-boundary.js +1 -1
  47. package/dist/components/limit-boundary.js.map +1 -1
  48. package/dist/components/limit-notice.js +1 -1
  49. package/dist/components/limit-notice.js.map +1 -1
  50. package/dist/components/onboarding-view.js +5 -5
  51. package/dist/components/onboarding-view.js.map +1 -1
  52. package/dist/components/org-switcher.js +1 -1
  53. package/dist/components/org-switcher.js.map +1 -1
  54. package/dist/components/plans-table.d.ts +11 -1
  55. package/dist/components/plans-table.d.ts.map +1 -1
  56. package/dist/components/plans-table.js +14 -5
  57. package/dist/components/plans-table.js.map +1 -1
  58. package/dist/components/product-docs/fetch-product-docs.js +1 -1
  59. package/dist/components/product-docs/fetch-product-docs.js.map +1 -1
  60. package/dist/components/product-docs/product-docs.js +1 -1
  61. package/dist/components/product-docs/product-docs.js.map +1 -1
  62. package/dist/components/resources-panel.js +3 -3
  63. package/dist/components/resources-panel.js.map +1 -1
  64. package/dist/components/root.d.ts +43 -6
  65. package/dist/components/root.d.ts.map +1 -1
  66. package/dist/components/root.js +54 -15
  67. package/dist/components/root.js.map +1 -1
  68. package/dist/components/spend-cap-control.js +2 -2
  69. package/dist/components/spend-cap-control.js.map +1 -1
  70. package/dist/components/styles.css +11 -5
  71. package/dist/components/team-panel.js +2 -2
  72. package/dist/components/team-panel.js.map +1 -1
  73. package/dist/components/theme.d.ts +5 -2
  74. package/dist/components/theme.d.ts.map +1 -1
  75. package/dist/components/theme.js +7 -1
  76. package/dist/components/theme.js.map +1 -1
  77. package/dist/components/top-up-prompt.d.ts +1 -1
  78. package/dist/components/top-up-prompt.d.ts.map +1 -1
  79. package/dist/components/upgrade-prompt.d.ts +1 -1
  80. package/dist/components/upgrade-prompt.d.ts.map +1 -1
  81. package/dist/components/upgrade-prompt.js +1 -1
  82. package/dist/components/upgrade-prompt.js.map +1 -1
  83. package/dist/components/usage.d.ts +5 -1
  84. package/dist/components/usage.d.ts.map +1 -1
  85. package/dist/components/usage.js +20 -4
  86. package/dist/components/usage.js.map +1 -1
  87. package/dist/config.d.ts +49 -11
  88. package/dist/config.d.ts.map +1 -1
  89. package/dist/config.js +48 -13
  90. package/dist/config.js.map +1 -1
  91. package/dist/deny-codes.js +2 -2
  92. package/dist/deny-codes.js.map +1 -1
  93. package/dist/{errors.d.ts → errors/index.d.ts} +36 -3
  94. package/dist/errors/index.d.ts.map +1 -0
  95. package/dist/{errors.js → errors/index.js} +51 -3
  96. package/dist/errors/index.js.map +1 -0
  97. package/dist/fetch.d.ts +62 -0
  98. package/dist/fetch.d.ts.map +1 -0
  99. package/dist/fetch.js +195 -0
  100. package/dist/fetch.js.map +1 -0
  101. package/dist/format/index.d.ts +2 -0
  102. package/dist/format/index.d.ts.map +1 -0
  103. package/dist/format/index.js +19 -0
  104. package/dist/format/index.js.map +1 -0
  105. package/dist/generated/version.d.ts +2 -2
  106. package/dist/generated/version.d.ts.map +1 -1
  107. package/dist/generated/version.js +2 -2
  108. package/dist/generated/version.js.map +1 -1
  109. package/dist/http.js +8 -8
  110. package/dist/http.js.map +1 -1
  111. package/dist/index.d.ts +21 -6
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +19 -14
  114. package/dist/index.js.map +1 -1
  115. package/dist/permissions.d.ts +16 -0
  116. package/dist/permissions.d.ts.map +1 -0
  117. package/dist/permissions.js +29 -0
  118. package/dist/permissions.js.map +1 -0
  119. package/dist/react/hooks.d.ts +5 -1
  120. package/dist/react/hooks.d.ts.map +1 -1
  121. package/dist/react/hooks.js +81 -69
  122. package/dist/react/hooks.js.map +1 -1
  123. package/dist/react/index.d.ts +7 -1
  124. package/dist/react/index.d.ts.map +1 -1
  125. package/dist/react/index.js +13 -1
  126. package/dist/react/index.js.map +1 -1
  127. package/dist/react/organization-context.js +1 -1
  128. package/dist/react/organization-context.js.map +1 -1
  129. package/dist/react/query-adapter.d.ts +63 -0
  130. package/dist/react/query-adapter.d.ts.map +1 -0
  131. package/dist/react/query-adapter.js +117 -0
  132. package/dist/react/query-adapter.js.map +1 -0
  133. package/dist/react/scope.d.ts +41 -0
  134. package/dist/react/scope.d.ts.map +1 -0
  135. package/dist/react/scope.js +35 -0
  136. package/dist/react/scope.js.map +1 -0
  137. package/dist/react/use-async.d.ts +30 -7
  138. package/dist/react/use-async.d.ts.map +1 -1
  139. package/dist/react/use-async.js +23 -10
  140. package/dist/react/use-async.js.map +1 -1
  141. package/dist/react/use-limit-status.d.ts +1 -1
  142. package/dist/react/use-limit-status.d.ts.map +1 -1
  143. package/dist/react/use-limits.d.ts +1 -1
  144. package/dist/react/use-limits.d.ts.map +1 -1
  145. package/dist/react/use-limits.js +2 -2
  146. package/dist/react/use-limits.js.map +1 -1
  147. package/dist/react/use-upgrade.d.ts +1 -1
  148. package/dist/react/use-upgrade.d.ts.map +1 -1
  149. package/dist/react/use-upgrade.js +1 -1
  150. package/dist/react/use-upgrade.js.map +1 -1
  151. package/dist/resources/_shared.d.ts +2 -2
  152. package/dist/resources/_shared.d.ts.map +1 -1
  153. package/dist/resources/_shared.js +7 -7
  154. package/dist/resources/_shared.js.map +1 -1
  155. package/dist/resources/account.d.ts +64 -1
  156. package/dist/resources/account.d.ts.map +1 -1
  157. package/dist/resources/account.js +113 -18
  158. package/dist/resources/account.js.map +1 -1
  159. package/dist/resources/api.js +1 -1
  160. package/dist/resources/api.js.map +1 -1
  161. package/dist/resources/auth.js +4 -4
  162. package/dist/resources/auth.js.map +1 -1
  163. package/dist/resources/billing.d.ts.map +1 -1
  164. package/dist/resources/billing.js +22 -21
  165. package/dist/resources/billing.js.map +1 -1
  166. package/dist/resources/entitlements.js +5 -5
  167. package/dist/resources/entitlements.js.map +1 -1
  168. package/dist/resources/keys.js +10 -10
  169. package/dist/resources/keys.js.map +1 -1
  170. package/dist/resources/plans.d.ts +1 -1
  171. package/dist/resources/plans.d.ts.map +1 -1
  172. package/dist/resources/plans.js +19 -7
  173. package/dist/resources/plans.js.map +1 -1
  174. package/dist/resources/resources.d.ts.map +1 -1
  175. package/dist/resources/resources.js +4 -4
  176. package/dist/resources/resources.js.map +1 -1
  177. package/dist/resources/usage.js +4 -4
  178. package/dist/resources/usage.js.map +1 -1
  179. package/dist/retry-throttle.d.ts +1 -1
  180. package/dist/retry-throttle.d.ts.map +1 -1
  181. package/dist/retry-throttle.js +1 -1
  182. package/dist/retry-throttle.js.map +1 -1
  183. package/dist/test-utils/error-builders.d.ts +29 -0
  184. package/dist/test-utils/error-builders.d.ts.map +1 -0
  185. package/dist/test-utils/error-builders.js +36 -0
  186. package/dist/test-utils/error-builders.js.map +1 -0
  187. package/dist/test-utils/index.d.ts +4 -0
  188. package/dist/test-utils/index.d.ts.map +1 -0
  189. package/dist/test-utils/index.js +15 -0
  190. package/dist/test-utils/index.js.map +1 -0
  191. package/dist/test-utils/mock-client.d.ts +37 -0
  192. package/dist/test-utils/mock-client.d.ts.map +1 -0
  193. package/dist/test-utils/mock-client.js +366 -0
  194. package/dist/test-utils/mock-client.js.map +1 -0
  195. package/dist/test-utils/test-provider.d.ts +25 -0
  196. package/dist/test-utils/test-provider.d.ts.map +1 -0
  197. package/dist/test-utils/test-provider.js +22 -0
  198. package/dist/test-utils/test-provider.js.map +1 -0
  199. package/dist/top-up.js +1 -1
  200. package/dist/top-up.js.map +1 -1
  201. package/dist/types.d.ts +53 -2
  202. package/dist/types.d.ts.map +1 -1
  203. package/dist/use-fetch.d.ts +18 -0
  204. package/dist/use-fetch.d.ts.map +1 -0
  205. package/dist/use-fetch.js +51 -0
  206. package/dist/use-fetch.js.map +1 -0
  207. package/dist/variables-registry.d.ts +56 -0
  208. package/dist/variables-registry.d.ts.map +1 -0
  209. package/dist/variables-registry.js +172 -0
  210. package/dist/variables-registry.js.map +1 -0
  211. package/dist/vars.d.ts +9 -0
  212. package/dist/vars.d.ts.map +1 -0
  213. package/dist/vars.js +29 -0
  214. package/dist/vars.js.map +1 -0
  215. package/package.json +12 -2
  216. package/dist/errors.d.ts.map +0 -1
  217. package/dist/errors.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,62 @@
3
3
  All notable changes to `@farthershore/farthershore-js` are documented here.
4
4
  This project adheres to Semantic Versioning (pre-1.0: minors may break).
5
5
 
6
+ ## [0.10.0] - 2026-07-02
7
+
8
+ Frontend SDK ergonomics redesign — the headless client + hooks are now the
9
+ default surface and the styled portal is an opt-in layer.
10
+
11
+ ### Changed (BREAKING)
12
+
13
+ - **`productId` → `businessId`** across the public surface (config,
14
+ `ClientContext`, resources, hooks, params). No `productId` remains in the
15
+ public API.
16
+ - **Ecosystem hook shape:** every data hook returns
17
+ `{ data, error, isLoading, isError, isSuccess, refetch, queryKey }`. The bare
18
+ `loading` field and `refresh` alias are removed (use `isLoading` / `refetch`).
19
+ - **`/errors` subpath:** the full error taxonomy + parse/predicate helpers moved
20
+ to `@farthershore/farthershore-js/errors`. The root re-exports only
21
+ `FartherShoreError`, `FartherShoreApiError`, `LimitExceededError`,
22
+ `FartherShoreRateLimitedError`, and `FartherShoreConfigError`.
23
+ - **`format` namespace:** the catalog display/derivation helpers are grouped
24
+ under `format` (`import { format } from "@farthershore/farthershore-js"`);
25
+ they are no longer flat root exports.
26
+ - Removed the SSR/`createServerClient` surface (platform is browser-only).
27
+
28
+ ### Added
29
+
30
+ - **Zero-config client:** `createFartherShoreClient()` with no args on-platform
31
+ (lazy `window.__FS_CONFIG__`, `businessId` discovered from the portal host);
32
+ manual `{ coreUrl, portalHost, businessId, getToken }` is a documented
33
+ dev/test escape hatch.
34
+ - **`fs.fetch(url, opts)`** drop-in secure fetch with a client-side variable
35
+ registry + `PROVIDER_CATALOG` host inference.
36
+ - **`/react`:** prop-free `<FartherShoreProvider>`; `useReadScope()`;
37
+ `useFetch()`; a TanStack-Query / SWR adapter (`fsQueryOptions`,
38
+ `createFsFetcher`) with no runtime dependency on either library.
39
+ - **Composable components:** data components render under a bare
40
+ `<FartherShoreProvider>` (no forced `FartherShoreRoot`);
41
+ `PlansTable`/`UsageCard` gain `renderRow`, `BillingSummary` gains
42
+ `slots.actions`; themeable z-index via `--fs-*-z` CSS variables.
43
+ - **`FartherShoreRoot`** is now a composition of `FsBootGate` /
44
+ `FsAuthProvider` / `FsThemeProvider` with `skipAuth` / `skipTheme` /
45
+ `skipBootGate` flags.
46
+ - **`/test-utils` subpath:** `createMockFartherShoreClient`,
47
+ `<FartherShoreTestProvider>`, and typed error builders
48
+ (`mockLimitExceeded` / `mockRateLimited` / `mockApiError`).
49
+
50
+ ### Fixed
51
+
52
+ - `<OrgSwitcher>` read a non-existent `organizationName` field and showed raw
53
+ organization ids; it now reads the `name` field the platform actually sends.
54
+ - `fs.fetch` variable resolution no longer silently hands a lone host-less
55
+ variable to a call targeting a _different_ recognized provider host (e.g. a
56
+ sole `STRIPE_SECRET_KEY` against `api.openai.com`) — it throws
57
+ `FartherShoreConfigError` on that ambiguity, as documented.
58
+ - `sideEffects` now allowlists `*.css` (was `false`), so webpack-based
59
+ consumers no longer tree-shake away the `./components/styles.css` /
60
+ `./components/docs.css` side-effect imports in production builds.
61
+
6
62
  ## [0.9.0] - 2026-06-29
7
63
 
8
64
  ### Changed (BREAKING)
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The **Farther Shore Frontend SDK** — the browser + React integration layer for
4
4
  your product's subscriber portal.
5
5
 
6
- > **Status: `0.9.0`.** Pre-1.0 (`0.x`): a minor bump (e.g. `0.8.x` → `0.9.0`)
6
+ > **Status: `0.10.0`.** Pre-1.0 (`0.x`): a minor bump (e.g. `0.9.x` → `0.10.0`)
7
7
  > may include breaking changes, so a caret range is unsafe — **pin this package
8
8
  > exactly** (`0.9.0`) or use a patch-only tilde (`~0.9.0`). Changes are recorded
9
9
  > in [`CHANGELOG.md`](./CHANGELOG.md).
@@ -26,143 +26,28 @@ goes (Core for platform concerns like auth, plans, usage, and billing; the
26
26
  Gateway for your product's own features), **how** it's authenticated, and which
27
27
  host/environment scoping headers to attach.
28
28
 
29
- You can use it two ways: a framework-agnostic client (`createFartherShoreClient`)
30
- for any frontend, or the `react` subpath + the managed component kit
31
- (zero-config UI for plans, usage, billing, keys, docs, and more).
29
+ This guide walks through the five on-ramps for integrating the SDK into a real
30
+ app: the zero-config happy path, bringing your own auth, bringing your own
31
+ design system, bringing your own data layer, and writing org-scoped custom
32
+ hooks.
32
33
 
33
- ## Quickstart
34
+ ## 1. Zero-config happy path
34
35
 
35
- ```ts
36
- import { createFartherShoreClient } from "@farthershore/farthershore-js";
37
-
38
- // 1. Create the client. In the browser, `coreUrl` is usually the only required
39
- // field — `portalHost` defaults to `window.location.host`.
40
- const fs = createFartherShoreClient({
41
- coreUrl: "https://core.farthershore.com",
42
- });
43
-
44
- // 2. Discover the business / environment / plans for this host
45
- // (memoized; safe to re-call).
46
- const { business, plans } = await fs.bootstrap();
47
-
48
- // 3. Authenticate. In a preview/test environment, exchange a persona access key
49
- // for a session. (Clerk environments instead pass `getToken` in the config,
50
- // or call `fs.auth.setToken(token)`.)
51
- await fs.auth.signIn({ apiKey: "fsk_test_…" });
52
-
53
- // 4. Read platform state through the typed resources (→ Core).
54
- const keys = await fs.keys.list(); // ApiKey[]
55
- const usage = await fs.usage.snapshot(); // { summary, events, billingBasis }
56
-
57
- // 5. Call one of YOUR product features (→ Gateway). Set the consumer API key
58
- // once, then express intent by feature name + path — no Gateway URL in app
59
- // code.
60
- fs.setApiKey("fsk_live_…");
61
- const forecast = await fs.feature("weather").json("/forecast?city=NYC");
62
- ```
63
-
64
- ## Surface
65
-
66
- | Namespace | Routes to | Methods |
67
- | --------------------------------------------------------- | --------------------- | ----------------------------------------------------------------------- |
68
- | `fs.bootstrap()` | Core (public resolve) | discover business / environment / plans / branding |
69
- | `fs.business` | (bootstrap) | `get()` |
70
- | `fs.auth` | Core | `getSession()`, `signIn({apiKey})` (persona), `signOut()`, `setToken()` |
71
- | `fs.keys` | Core | `list()`, `create()`, `revoke()`, `rotate()` |
72
- | `fs.usage` | Core | `summary()`, `events()`, `snapshot()` |
73
- | `fs.billing` | Core | `subscription()`, `openBillingPortal()`, `creditBalance()` |
74
- | `fs.plans` | Core / (bootstrap) | `list()`, `subscribe()` |
75
- | `fs.entitlements` / `fs.features` | Core | plan entitlements + capability/feature gating |
76
- | `fs.me` / `fs.organizations` / `fs.team` / `fs.auditLogs` | Core | subscriber, org, team, and audit-log reads |
77
- | `fs.feature(name)` / `fs.invoke(path)` | **Gateway** | `fetch(path)`, `json(path)` |
78
-
79
- The package also ships typed domain models (`Business`, `Plan`, `Subscription`,
80
- `UsageSnapshot`, `ApiKey`, …), the gateway error/deny taxonomy
81
- (`FartherShoreApiError`, `LimitExceededError`, `FS_DENY_CODES`,
82
- `retryWhileThrottled`, …), and pure display helpers (`formatPlanPrice`,
83
- `estimateBill`, `usageToCsv`, …) so every frontend renders the catalog and usage
84
- identically.
85
-
86
- ## Auth
87
-
88
- - **Core** calls use the subscriber's **session token** as
89
- `Authorization: Bearer`. The host app owns the session:
90
- - _Clerk environments:_ pass `getToken` (from the Clerk browser SDK) in the
91
- config, or call `fs.auth.setToken(token)`.
92
- - _Persona / preview environments:_
93
- `fs.auth.signIn({ apiKey: "fsk_test_…" })` — the SDK exchanges the key for a
94
- session and manages the token itself.
95
- - **Gateway** (feature) calls use the consumer **API key** (`fsk_…`):
96
- `fs.setApiKey(key)` (or `fs.feature(name).fetch(path, { apiKey })`). The
97
- gateway host is discovered at bootstrap (the business's `gatewayHost`).
98
-
99
- ## Configuration
36
+ On a portal served by the Farther Shore edge, the client needs **no
37
+ arguments at all**. It reads `window.__FS_CONFIG__` (injected by the edge)
38
+ lazily — the first time a request actually needs it — and discovers the
39
+ `businessId` from the portal host.
100
40
 
101
41
  ```ts
102
- createFartherShoreClient({
103
- coreUrl, // platform Core base URL — optional on platform-served portals
104
- portalHost, // defaults to window.location.host
105
- productId, // optional — bootstrap() discovers it
106
- environmentId, // ephemeral/preview env scoping
107
- organizationId, // org-owned subscriptions
108
- gatewayUrl, // override (else derived from the business gatewayHost)
109
- apiKey, // consumer key for Gateway calls
110
- getToken, // () => session bearer (Clerk) | null
111
- fetch, // injectable (tests / SSR)
112
- });
113
- ```
114
-
115
- Portals served through the Farther Shore edge need **no config at all** —
116
- `createFartherShoreClient()` works on its own: the edge injects
117
- `window.__FS_CONFIG__` (the environment's `coreUrl` plus the Clerk connection)
118
- into the served HTML, and the SDK falls back to it. Explicit config always wins,
119
- and everywhere else (local dev, SSR, self-hosting) `coreUrl` is required.
120
-
121
- On Clerk **satellite** portals (the portal is on a different domain than the
122
- platform's sign-in domain), the managed auth layer also owns the cross-domain
123
- session handshake: public visits never redirect, and a `#fs-sso` URL fragment
124
- (appended by trusted surfaces like the dashboard's "Open portal" links) triggers
125
- an immediate redirect through the primary domain that lands back signed in.
126
-
127
- ### SSR / server usage
128
-
129
- On a server there is no `window`/`location` to infer the portal host from and no
130
- ambient browser session — so use `createServerClient`, an explicit alias for
131
- `createFartherShoreClient`. Pass `portalHost` and `fetch` instead of relying on
132
- globals, and resolve the per-request session via `getToken`.
133
-
134
- ```ts
135
- import { createServerClient } from "@farthershore/farthershore-js";
136
-
137
- const fs = createServerClient({
138
- coreUrl: process.env.FS_CORE_URL!,
139
- portalHost: "weather.farthershore.com", // no window.location on the server
140
- getToken: () => sessionTokenForThisRequest, // per-request bearer
141
- fetch, // Node global, or an injected impl
142
- });
42
+ import { createFartherShoreClient } from "@farthershore/farthershore-js";
143
43
 
144
- const sub = await fs.billing.subscription();
44
+ const fs = createFartherShoreClient();
145
45
  ```
146
46
 
147
- ## React (`@farthershore/farthershore-js/react`)
148
-
149
- The hooks live in a **subpath** of the same package — `react` is an _optional_
150
- peer dependency, so the core stays framework-agnostic and only React apps pull it
151
- in (no second package to version).
47
+ Wrap your tree in the provider:
152
48
 
153
49
  ```tsx
154
- import { createFartherShoreClient } from "@farthershore/farthershore-js";
155
- import {
156
- FartherShoreProvider,
157
- useBusiness,
158
- useApiKeys,
159
- useUsage,
160
- useBilling,
161
- useSession,
162
- useFeature,
163
- } from "@farthershore/farthershore-js/react";
164
-
165
- const fs = createFartherShoreClient({ coreUrl: import.meta.env.VITE_CORE_URL });
50
+ import { FartherShoreProvider } from "@farthershore/farthershore-js/react";
166
51
 
167
52
  function App() {
168
53
  return (
@@ -171,25 +56,32 @@ function App() {
171
56
  </FartherShoreProvider>
172
57
  );
173
58
  }
59
+ ```
60
+
61
+ Then read platform state through the hooks. Every read hook returns the same
62
+ ecosystem shape — `{ data, error, isLoading, isError, isSuccess, refetch,
63
+ queryKey }` — plus its mutations:
64
+
65
+ ```tsx
66
+ import { useApiKeys } from "@farthershore/farthershore-js/react";
174
67
 
175
68
  function ApiKeys() {
176
- const { data, loading, error, create, revoke } = useApiKeys();
177
- // …each read hook is { data, loading, error, refresh } plus its mutations.
69
+ const { data, isLoading, isError, error, refetch } = useApiKeys();
70
+ if (isLoading) return <p>Loading…</p>;
71
+ if (isError) return <p>Failed to load keys: {error?.message}</p>;
72
+ return (
73
+ <ul>
74
+ {data?.map((k) => (
75
+ <li key={k.id}>{k.label}</li>
76
+ ))}
77
+ </ul>
78
+ );
178
79
  }
179
80
  ```
180
81
 
181
- Read hooks return `{ data, loading, error, refresh }` and include their
182
- mutations: `useBootstrap`, `useBusiness`, `useSession` (+ `signIn`/`signOut`),
183
- `useApiKeys` (+ `create`/`revoke`/`rotate`), `useUsage`, `useBilling` (+
184
- `openBillingPortal`), `usePlans`, `useEntitlements`, `useFeature(name)`, plus
185
- team/org/audit/limit hooks and `useFartherShore()` for the raw client.
186
-
187
- ## Managed components
188
-
189
- Every product ships with a generic managed portal by default. The component kit
190
- is the same set of building blocks that portal is made of, available à la carte —
191
- every component works with **zero props** under `<FartherShoreRoot>` (it reads
192
- its data through the SDK; props are optional overrides).
82
+ Want a whole portal with almost no code? `<FartherShoreRoot>` is one wrapper —
83
+ provider + bootstrap gate + theme + managed auth — and the managed component
84
+ kit is self-fed under it:
193
85
 
194
86
  ```tsx
195
87
  import {
@@ -209,59 +101,260 @@ import "@farthershore/farthershore-js/components/styles.css";
209
101
  </FartherShoreRoot>;
210
102
  ```
211
103
 
212
- `<FartherShoreRoot>` is one wrapper: provider + bootstrap gate + theme + managed
213
- auth (Clerk satellite or persona, picked from the environment), with no host
214
- glue. Theming is a single `appearance` prop —
215
- `{ theme, brandColor, variables }` — that resolves to `--fs-*` CSS variables, so
216
- retheming (including dark ↔ light) is a state update with no rebuild.
104
+ **Escape hatch (dev/test only):** everywhere there's no injected
105
+ `window.__FS_CONFIG__` — local dev, self-hosting, tests — pass config
106
+ explicitly:
107
+
108
+ ```ts
109
+ const fs = createFartherShoreClient({
110
+ coreUrl: "http://localhost:4000", // dev/self-host only; injected on-platform
111
+ portalHost: "croncloud.example.com", // defaults to window.location.host
112
+ businessId: "biz_123", // usually omitted — bootstrap() discovers it
113
+ getToken: () => myAuthProvider.getToken(), // see "BYO auth" below
114
+ });
115
+ ```
116
+
117
+ Explicit config always wins over the injected channel. A request attempted
118
+ with no resolvable `coreUrl` throws an actionable `FartherShoreConfigError`.
119
+
120
+ ## 2. BYO auth
121
+
122
+ Feed the client your own session token instead of the managed Clerk/persona
123
+ layer, in one of two ways:
124
+
125
+ - **At construction**, via `getToken` in the config:
126
+
127
+ ```ts
128
+ const fs = createFartherShoreClient({
129
+ getToken: () => myAuthProvider.getToken(), // () => string | null | Promise<...>
130
+ });
131
+ ```
132
+
133
+ - **After construction**, via the client method (useful when the token
134
+ provider isn't ready yet at client-build time):
135
+
136
+ ```ts
137
+ fs.setTokenProvider(() => myAuthProvider.getToken());
138
+ ```
217
139
 
218
- To **customize** the portal, edit the product repo's `frontend/` tree (what the
219
- platform scaffolds) and push — the platform rebuilds it into a custom release and
220
- serves it instead of the default. Your product's _contract_ (plans, pricing,
221
- routes, meters) lives in `business/` and is managed as code; the UI lives in
222
- `frontend/`.
140
+ If you're using `<FartherShoreRoot>` but want to bring your own auth provider
141
+ entirely (skip the managed Clerk-satellite/persona layer), pass `skipAuth`:
223
142
 
224
- ### Docs and API reference
143
+ ```tsx
144
+ <FartherShoreRoot client={fs} skipAuth>
145
+ <MyOwnAuthProvider>
146
+ <Portal />
147
+ </MyOwnAuthProvider>
148
+ </FartherShoreRoot>
149
+ ```
225
150
 
226
- The docs kit renders a developer portal for your product. `<BusinessDocs/>` is
227
- the whole experience in one tag; it's composed from public primitives
228
- (sidebar/nav, search, version selector, markdown renderers, code cards) you can
229
- re-compose for a custom docs site, with a headless `useBusinessDocs()` underneath.
230
- `<BusinessApiReference/>` renders an OpenAPI 3.x document as a docs-styled API
231
- reference. `<CodeGroup>` is the multi-language fenced-code block used inside docs
232
- pages.
151
+ ## 3. BYO design system
152
+
153
+ The managed components work standalone under a **bare** `<FartherShoreProvider>`
154
+ — you don't need `<FartherShoreRoot>` to use them:
233
155
 
234
156
  ```tsx
157
+ import { FartherShoreProvider } from "@farthershore/farthershore-js/react";
235
158
  import {
236
- BusinessDocs,
237
- BusinessApiReference,
238
- type BusinessOpenApiDocument,
159
+ PlansTable,
160
+ ApiKeysPanel,
161
+ UsageCard,
162
+ BillingSummary,
163
+ CreditBalance,
164
+ TeamPanel,
165
+ AuditLogTable,
166
+ RateLimitDisplay,
167
+ BillEstimator,
168
+ CapabilityUsageCard,
169
+ UpgradePrompt,
170
+ TopUpPrompt,
171
+ DocsLegal,
172
+ ResourcesPanel,
173
+ FeaturePanel,
239
174
  } from "@farthershore/farthershore-js/components";
240
- import "@farthershore/farthershore-js/components/docs.css";
241
-
242
- const spec = {
243
- openapi: "3.1.0",
244
- info: { title: "Weather API", version: "2026-06-28" },
245
- servers: [{ url: "https://api.weather.example" }],
246
- paths: {
247
- "/v1/forecast": {
248
- get: {
249
- summary: "Get forecast",
250
- tags: ["Forecasts"],
251
- responses: { "200": { description: "Forecast returned." } },
252
- },
253
- },
254
- },
255
- } satisfies BusinessOpenApiDocument;
256
-
257
- <BusinessDocs />;
258
- <BusinessApiReference document={spec} />;
175
+ import "@farthershore/farthershore-js/components/styles.css";
176
+
177
+ <FartherShoreProvider client={fs}>
178
+ <PlansTable />
179
+ <ApiKeysPanel />
180
+ </FartherShoreProvider>;
181
+ ```
182
+
183
+ Recompose without forking. `PlansTable` takes `renderRow` for a fully custom
184
+ card, with context for the featured/pending/subscribe state:
185
+
186
+ ```tsx
187
+ <PlansTable
188
+ renderRow={(plan, { featured, pending, onSubscribe, index }) => (
189
+ <MyPlanCard
190
+ key={plan.id}
191
+ plan={plan}
192
+ highlighted={featured}
193
+ busy={pending}
194
+ onClick={onSubscribe}
195
+ rank={index}
196
+ />
197
+ )}
198
+ />
199
+ ```
200
+
201
+ `UsageCard` takes `renderRow` per metered dimension:
202
+
203
+ ```tsx
204
+ <UsageCard
205
+ renderRow={(row, index) => (
206
+ <MyUsageRow key={row.key} row={row} index={index} />
207
+ )}
208
+ />
209
+ ```
210
+
211
+ `BillingSummary` takes named `slots` (e.g. to replace the actions area):
212
+
213
+ ```tsx
214
+ <BillingSummary slots={{ actions: <MyBillingActions /> }} />
215
+ ```
216
+
217
+ Every component also accepts a plain `className` on its root for CSS-based
218
+ restyling.
219
+
220
+ To bring your own theming under `<FartherShoreRoot>` instead of the managed
221
+ theme root, pass `skipTheme`:
222
+
223
+ ```tsx
224
+ <FartherShoreRoot client={fs} skipTheme>
225
+ <MyThemeProvider>
226
+ <Portal />
227
+ </MyThemeProvider>
228
+ </FartherShoreRoot>
229
+ ```
230
+
231
+ ## 4. BYO data layer
232
+
233
+ Already run TanStack Query or SWR? The `/react` subpath ships a structural
234
+ adapter — no runtime dependency on either library, so it costs nothing unless
235
+ you import it.
236
+
237
+ **TanStack Query:**
238
+
239
+ ```tsx
240
+ import { useQuery } from "@tanstack/react-query";
241
+ import { fsQueryOptions } from "@farthershore/farthershore-js/react";
242
+
243
+ const q = fsQueryOptions(fs);
244
+ const { data } = useQuery(q.keys.list());
245
+ const { data: usage } = useQuery(q.usage.snapshot());
246
+ ```
247
+
248
+ **SWR:**
249
+
250
+ ```tsx
251
+ import useSWR from "swr";
252
+ import { createFsFetcher } from "@farthershore/farthershore-js/react";
253
+
254
+ const fetcher = createFsFetcher(fs);
255
+ const { data } = useSWR("https://api.example.com/v1/x", fetcher);
256
+ ```
257
+
258
+ `fsQueryOptions` covers the common reads (`keys`, `usage`, `billing`, `plans`,
259
+ `me`, `business`). For a product-declared resource beyond those, use the
260
+ generic escape hatch — both return a ready-to-use `{ queryKey, queryFn }`
261
+ object:
262
+
263
+ ```tsx
264
+ const { data: widgets } = useQuery(q.resource("widgets"));
265
+ const { data: widget } = useQuery(q.resourceItem("widgets", widgetId));
266
+ ```
267
+
268
+ ## 5. Org-scope custom hooks
269
+
270
+ Writing your own hook that reads org-scoped data (a product-declared resource,
271
+ say)? Use `useReadScope()` instead of `useFartherShore()` alone — it composes
272
+ the client with the **reactive** active-org id, so folding it into your query
273
+ key/dep array makes an org switch auto-refetch:
274
+
275
+ ```tsx
276
+ import { useReadScope } from "@farthershore/farthershore-js/react";
277
+ import { useAsync } from "@farthershore/farthershore-js/react";
278
+
279
+ function useMyResource() {
280
+ const { fs, businessId, organizationId } = useReadScope();
281
+ return useAsync(
282
+ (signal) => fs.resources("widgets").list({ signal }),
283
+ [fs, businessId, organizationId],
284
+ ["widgets", businessId, organizationId],
285
+ );
286
+ }
287
+ ```
288
+
289
+ `fs` alone is a stable reference and never reacts to an org switch on its
290
+ own — `businessId`/`organizationId` are what make the dep array and query key
291
+ scope-correct.
292
+
293
+ ## Errors
294
+
295
+ Reads and mutations throw typed errors you can `catch` and branch on. The root
296
+ package keeps the five most-caught classes:
297
+
298
+ ```ts
299
+ import {
300
+ FartherShoreError,
301
+ FartherShoreApiError,
302
+ LimitExceededError,
303
+ FartherShoreRateLimitedError,
304
+ FartherShoreConfigError,
305
+ } from "@farthershore/farthershore-js";
306
+
307
+ try {
308
+ await fs.keys.list();
309
+ } catch (err) {
310
+ if (err instanceof LimitExceededError) showUpgrade(err);
311
+ else if (err instanceof FartherShoreApiError && err.status === 401) {
312
+ // session expired — prompt re-auth
313
+ } else throw err;
314
+ }
315
+ ```
316
+
317
+ The full taxonomy — throttle subclasses (`ConcurrencyLimitError`,
318
+ `AdaptiveThrottleError`), deny-envelope parsers, `makeApiError`, secure-fetch
319
+ codes, and more — lives at the `@farthershore/farthershore-js/errors` subpath.
320
+
321
+ ## Display helpers
322
+
323
+ Pure catalog/pricing/usage formatting helpers are grouped under the `format`
324
+ namespace, so every frontend renders money, dates, and quotas identically:
325
+
326
+ ```ts
327
+ import { format } from "@farthershore/farthershore-js";
328
+
329
+ format.formatCents(1234); // "$12.34"
330
+ ```
331
+
332
+ ## Testing
333
+
334
+ `@farthershore/farthershore-js/test-utils` gives you a fully-typed mock client,
335
+ a provider wrapper, and typed-error builders — no network, no server:
336
+
337
+ ```tsx
338
+ import {
339
+ createMockFartherShoreClient,
340
+ FartherShoreTestProvider,
341
+ mockLimitExceeded,
342
+ } from "@farthershore/farthershore-js/test-utils";
343
+
344
+ const client = createMockFartherShoreClient({
345
+ keys: { list: async () => [{ id: "key_1", label: "Test key" }] },
346
+ });
347
+
348
+ render(
349
+ <FartherShoreTestProvider client={client}>
350
+ <ApiKeys />
351
+ </FartherShoreTestProvider>,
352
+ );
259
353
  ```
260
354
 
261
- The docs components are SSR-safe and host-agnostic (they run on apps not served
262
- by the platform too); `react-markdown` / `remark-gfm` are optional peers
263
- (lazy-loaded, with a plain-text fallback when absent), and the docs stylesheet
264
- ships separately as `@farthershore/farthershore-js/components/docs.css`.
355
+ `mockLimitExceeded`, `mockRateLimited`, and `mockApiError` build the typed
356
+ errors above for asserting your error-handling paths without a real deny from
357
+ Core or the Gateway.
265
358
 
266
359
  ## Learn more
267
360
 
package/dist/bootstrap.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Capability discovery. `bootstrap()` resolves the business the frontend is
2
2
  // running for from the portal host — the SAME public endpoint the portal renders
3
- // from — and caches productId / environmentId / gateway origin on the client so
3
+ // from — and caches businessId / environmentId / gateway origin on the client so
4
4
  // every later call knows where to go.
5
5
  //
6
6
  // The resolve DTO carries the business's full catalog: the plan list (the rich
@@ -11,7 +11,7 @@
11
11
  // subscribe flow — not just an account dashboard.
12
12
  import { coreFetch } from "./http.js";
13
13
  import { consumePrimedResolve } from "./boot-primer.js";
14
- import { FartherShoreNotReadyError } from "./errors.js";
14
+ import { FartherShoreNotReadyError } from "./errors/index.js";
15
15
  // ── Mappers ───────────────────────────────────────────────────────────────
16
16
  function mapMeter(m) {
17
17
  const key = m.key ?? m.dimension;
@@ -186,7 +186,7 @@ export async function resolveBootstrap(ctx) {
186
186
  const environment = raw.environment ? mapEnv(raw.environment) : null;
187
187
  const plans = (raw.plans ?? []).map(mapPlan);
188
188
  // Cache routing facts for subsequent calls (config values still win).
189
- ctx.productId = ctx.productId ?? business.id;
189
+ ctx.businessId = ctx.businessId ?? business.id;
190
190
  if (environment)
191
191
  ctx.environmentId = ctx.environmentId ?? environment.id;
192
192
  ctx.gatewayUrl = ctx.gatewayUrl ?? `https://${business.gatewayHost}`;
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}