@farthershore/farthershore-js exports
Every public export and declaration from @farthershore/farthershore-js.
Every public export and declaration from @farthershore/farthershore-js.
Import from @farthershore/farthershore-js. This reference is extracted from the published declaration surface for version 0.32.0. Read the collection's guides for workflows, prerequisites and failure handling.
Public export AccountSurface.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L179.
export interface AccountSurface {
/** The full subscriber context (`GET /me`): lifecycle, trial, scheduled
* transition, and the eligibility-scoped `availablePlans`. Null when signed
* out / no subscriber for the selected org — never throws for those.
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle); the read is unmount-safe
* via the hook's active-flag and bounded by the cache TTL. */
me(opts?: {
signal?: AbortSignal;
/**
* `null` intentionally reads the user's default subscription without an
* organization header. `undefined` preserves the selected workspace.
*/
organizationId?: string | null;
}): Promise<SubscriberContext | null>;
acceptLegal(acceptances: LegalAcceptance__cc2291cc0442[]): Promise<void>;
organizations: OrganizationsResource;
team: TeamResource;
rbac: RbacResource;
notifications: NotificationsResource;
auditLogs: AuditLogsResource;
}
Public export ActiveServiceAccountCreateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L465.
export interface ActiveServiceAccountCreateResponse {
status: "ACTIVE";
serviceAccountId: string;
apiKeyId: string;
keyPrefix: string;
/** One-time plaintext secret. */
plaintext: string;
requestedPermissions: string[];
grantedPermissions: string[];
}
Public export ActiveServiceAccountUpdateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L486.
export interface ActiveServiceAccountUpdateResponse {
status: "ACTIVE";
serviceAccountId: string;
requestedPermissions: string[];
grantedPermissions: string[];
}
Public export ApiKey.
Declaration source: packages/farthershore-js/dist/types.d.ts#L347.
export interface ApiKey {
id: string;
keyPrefix: string;
label: string | null;
/** Normalized lowercase, e.g. "active" | "revoked". */
status: string;
createdAt: string;
lastUsedAt: string | null;
revokedAt: string | null;
/** Consumer-principal (D2): the key's subject kind — a PERSONAL key mints a
* member subject, a SERVICE key an org-owned service account. Always present
* (Core's `ApiKey.kind` is a NOT NULL column). */
kind: ApiKeyKind;
/** PERSONAL — the bound member's stable `Membership.id` (identity + permission
* source). Null for service keys / when the API omits it. */
memberId: string | null;
/** SERVICE — the org-owned `ServiceAccount.id` the key attaches to. Null for
* personal keys / when the API omits it. */
serviceAccountId: string | null;
/** SERVICE — the bound service account's display name, when the API returns
* it (the list groups service keys by account under this label). */
serviceAccountName: string | null;
/** Provenance: which member MINTED the key (audit only; may differ from the
* bound member when an admin mints a personal key for someone — D2a). Null
* for pre-attribution keys. */
createdBy: string | null;
}
Consumer-principal (D2): which stable identity an API key credentials.
`PERSONAL` binds to a member (perms = the member's live roles ∩ the key's
restrictions; auto-revoked when the member leaves). `SERVICE` attaches to a
named org-owned service account (admin-gated; survives offboarding).
Declaration source: packages/farthershore-js/dist/types.d.ts#L346.
export type ApiKeyKind = "PERSONAL" | "SERVICE";
Public export ApprovedServiceAccountCreateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L493.
export interface ApprovedServiceAccountCreateResponse {
status: "ACTIVE";
operation: "CREATE";
serviceAccountId: string;
apiKeyId: string;
/** One-time plaintext secret. */
plaintext: string;
grantedPermissions: string[];
}
Public export ApprovedServiceAccountUpdateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L502.
export interface ApprovedServiceAccountUpdateResponse {
status: "ACTIVE";
operation: "UPDATE";
serviceAccountId: string;
grantedPermissions: string[];
}
Public export ApproveServiceAccountInput.
Declaration source: packages/farthershore-js/dist/types.d.ts#L451.
export interface ApproveServiceAccountInput {
/** Omit to approve the complete original request. */
grantedPermissions?: string[];
}
Public export AuditLogEntry.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1074.
export interface AuditLogEntry {
id: string;
createdAt: string;
action: string;
decision?: "ALLOW" | "DENY" | null;
actorType?: string | null;
actorUserId?: string | null;
/** Friendly display name for a user actor (subscriber / builder / maker),
* resolved server-side from the actor's Clerk user id. Null for non-user
* actors (gateway / admin_service) or unknown ids — render `actorUserId`
* as the fallback. */
actorName?: string | null;
payloadJson?: Record<string, unknown> | null;
[k: string]: unknown;
}
Public export AuditLogPage.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1089.
export interface AuditLogPage {
items: AuditLogEntry[];
nextCursor: string | null;
}
Public export AuditLogsResource.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L142.
export interface AuditLogsResource {
/** Cursor-paged subscriber audit log (decision ALLOW|DENY, limit ≤ 200).
* Degrades to an empty page on error, like the SSR page. */
list(filters?: {
action?: string;
actorUserId?: string;
decision?: "ALLOW" | "DENY";
from?: string;
to?: string;
cursor?: string;
limit?: number;
signal?: AbortSignal;
/**
* `null` intentionally reads the user's default subscription without an
* organization header. `undefined` preserves the selected workspace.
*/
organizationId?: string | null;
}): Promise<AuditLogPage>;
}
Public export AuthResource.
Declaration source: packages/farthershore-js/dist/resources/auth.d.ts#L3.
export interface AuthResource {
/** The current session (authenticated identity + a light subscriber slice).
* Resolves to `{ authenticated: false }` on 401/403 rather than throwing.
* Test-persona identity comes from Core's verified HttpOnly cookie; no
* persona bearer is exposed to browser JavaScript. */
getSession(opts?: {
signal?: AbortSignal;
}): Promise<Session>;
/** Revoke the server-owned persona browser session and clear local auth
* caches. Clerk-strategy environments continue to sign out via Clerk. */
signOut(): Promise<void>;
/** Set a session bearer directly (for example, Clerk's session token). */
setToken(token: string | null): void;
/** Mint a short-lived Gateway bearer from the current authenticated browser
* session. In persona environments Core authenticates this with the
* same-origin HttpOnly cookie. */
gatewayContextToken(opts?: {
signal?: AbortSignal;
refresh?: boolean;
}): Promise<GatewayContextToken>;
}
Public export AuthStrategy.
Declaration source: packages/farthershore-js/dist/types.d.ts#L59.
export type AuthStrategy = "clerk" | "test-personas";
A partial-success auto-key failure: the subscriber activated but Core could
not mint the first API key. Mirrors core's `autoApiKeyError` ({@code
checkout.ts}). The caller should prompt the user to create a key manually
rather than silently dropping the signal.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1097.
export interface AutoApiKeyError {
code: string;
message: string;
}
Public export BillingResource.
Declaration source: packages/farthershore-js/dist/resources/billing.d.ts#L13.
export interface BillingResource {
/** The consumer's current subscription for this product, or null.
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle); the read is unmount-safe
* via the hook's active-flag and bounded by the cache TTL. */
subscription(opts?: {
signal?: AbortSignal;
}): Promise<Subscription | null>;
/** Open the Stripe-hosted billing portal (payment method + invoices). Returns
* the URL to navigate to. This is also how invoices are viewed in V0. */
openBillingPortal(input?: {
returnUrl?: string;
}): Promise<{
url: string;
}>;
/** Cancel the current subscription. Free subs cancel inline; paid subs are
* scheduled on the provider for the end of the current billing period and
* the result carries the `cancelsAt` boundary. `reason` is recorded for
* churn analytics. */
cancelSubscription(input?: {
reason?: string;
}): Promise<CancelSubscriptionResult>;
/** Buy more prepaid balance. Starts a provider checkout for `amountCents`
* and returns the URL to send the subscriber to. Core gates this on
* `invoice:pay` and refuses (`INVALID_STATE`) for a plan that declares no
* prepaid funding. `requestId` is the idempotency handle — pass the SAME
* uuid to retry one intent; omit it and the SDK mints one per call. */
addFunds(input: {
amountCents: number;
requestId?: string;
successUrl?: string;
cancelUrl?: string;
}): Promise<{
checkoutUrl: string;
}>;
/** Reverse a scheduled cancel — the platform lifts `cancel_at_period_end`
* on the provider (paid) or flips a CANCELLED free sub back to ACTIVE. The
* result carries the platform's POST-restore `cancelAtPeriodEnd` so a
* caller can render the outcome instead of assuming it. */
restoreSubscription(): Promise<RestoreSubscriptionResult>;
/** Change an existing subscription to another plan. Core applies or
* schedules the transition according to the product's policy. */
changePlan(input: {
compiledPlanId: string;
}): Promise<ChangePlanResult>;
/** Set (or clear, with `null`) the subscriber's monthly spend cap (in cents).
* PATCHes `/me/spend-cap`. CAVEAT: the cap is currently STORED-not-ENFORCED
* (held in subscription metadata pending the rate-limit migration) — do NOT
* present this as a hard spend limit in UI copy. */
setSpendCap(input: {
maxMonthlySpendCents: number | null;
}): Promise<SpendCapResult>;
/** Read the subscriber's current monthly spend cap (in cents), or null when
* none is set / signed out. P-SPENDCAP-READ — reads the additive
* `subscriber.maxMonthlySpendCents` surfaced on the `/me` context (no new
* route). Joins the memoized `/me` read.
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached `/me` fetch (the cache owns the fetch lifecycle); the read is
* unmount-safe via the hook's active-flag and bounded by the cache TTL. */
getSpendCap(opts?: {
signal?: AbortSignal;
}): Promise<number | null>;
/** The subscriber's current-window bill preview (`GET /me/bill-preview`) —
* computed by Core through the SAME rating engine + ledger state as
* invoicing, so preview === invoice by construction. Honors the plan's
* `spendPolicy.disclosure`: `transparent` carries windows / totals /
* nanodollar allowance balances; `opaque` carries allowance shape only (no
* amounts). Nanodollar fields are decimal STRINGS — format them with
* `format.formatNanos`, never `Number()`. Read-through cached; every
* entitlement mutation (subscribe / change plan / cancel / restore /
* migrate) busts it. Signed-out / no subscription → Core serves an empty
* transparent preview.
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle). */
getBillPreview(opts?: {
signal?: AbortSignal;
}): Promise<BillPreview>;
}
Public export BillPreview.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1284.
export type BillPreview = TransparentBillPreview | OpaqueBillPreview;
A funding allowance (balance bucket) with nanodollar balances —
transparent disclosure only.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1198.
export interface BillPreviewAllowance {
/** Bucket source kind (e.g. `included`, `prepaid`, `promo`). */
kind: string;
/** Bucket lifecycle state — Core's `BucketState`, verbatim. */
state: BucketState;
/** Nanodollars, decimal strings (null = unavailable). */
remainingNanos: NanosAmount;
heldNanos: NanosAmount;
consumedNanos: NanosAmount;
/** ISO timestamp, or null when the allowance does not expire. */
expiresAt: string | null;
}
One rating window's engine-exact recognized total.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1186.
export interface BillPreviewWindow {
windowId: string;
/** ISO timestamps. */
windowStart: string;
windowEnd: string;
/** Rated charges the engine recognized in this window. */
chargeCount: number;
/** Nanodollars, decimal string (null = unavailable). */
ratedNanos: NanosAmount;
}
What `fs.bootstrap()` returns — everything a generated/managed frontend needs
to discover the business it's running for AND render its catalog: the full
plan list (pricing model and included quotas), business meters, docs /
legal origins, and the featured-plan pointer.
Declaration source: packages/farthershore-js/dist/types.d.ts#L294.
export interface Bootstrap {
/** Wire schema version of the resolve DTO this bootstrap was decoded from
* (CC5). Additive negotiation hook; legacy payloads (no version) decode as
* `1`. Informational today — the SDK reads every shape tolerantly. */
schemaVersion: number;
business: Business;
environment: EnvironmentInfo | null;
branding: Branding;
/** The business's available/purchasable plans (empty when none are
* published). The single source the plans/pricing UI renders from. */
plans: Plan[];
/** The business's active custom-frontend release hash, or null. Informational
* (diagnostics) — V0 serving is host-keyed at the edge. */
frontendReleaseHash: string | null;
/** Available module keys derived from the plan set (non-empty once plans exist):
* e.g. "billing", "usage-quota", "docs", "legal". */
availableModules: string[];
/** The business's declared counted-resource catalog (W5.1). Empty when the
* business declares none. */
declaredResources: DeclaredResource[];
}
Public export Branding.
Declaration source: packages/farthershore-js/dist/types.d.ts#L2.
export interface Branding {
displayName: string;
/** Square brand mark (favicon / nav mark). */
iconUrl: string | null;
/** Horizontal text logo (wordmark) — rendered in place of the displayName
* text when set. Most products only have an icon. */
logoUrl: string | null;
/** Marketing/header description for the business, when set. */
description: string | null;
}
Lifecycle state of a funding allowance (balance bucket) — mirrors Core's
`BucketState` (Prisma) verbatim. `AVAILABLE` is the live, spendable
state; `EXPIRY_PENDING` is still spendable but about to expire; `PENDING`
is not yet spendable; `FROZEN` / `EXPIRED` / `CANCELLED` are not spendable.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1184.
export type BucketState = "PENDING" | "AVAILABLE" | "EXPIRY_PENDING" | "FROZEN" | "EXPIRED" | "CANCELLED";
Public export Business.
Declaration source: packages/farthershore-js/dist/types.d.ts#L23.
export interface Business {
id: string;
/** Subdomain slug (the first label of the gateway/portal host). */
slug: string;
name: string;
description: string | null;
branding: Branding;
/** Gateway origin host for builder-feature calls (the business `runtimeHostname`). */
gatewayHost: string;
/** Public portal host. */
portalHost: string;
/** R2 public origin + business prefix where MDX docs live, or null when the
* platform has no docs origin configured (local dev). The `/docs` view
* concatenates the doc filename onto this. */
docsBaseUrl: string | null;
/** R2 public origin + business prefix for per-business legal MDX
* (terms / privacy), or null. The legal view falls back to the platform
* terms notice when null. */
legalBaseUrl: string | null;
/** Versioned legal documents declared by the business, keyed by extensible
* kind (`terms`, `privacy`, custom kinds). URLs are public CDN MDX objects. */
legal?: {
documents: Record<string, LegalDocumentReference__0e8dba55b6a6>;
};
/** Platform-owned docs visibility flag. When `false` the portal /docs
* surface is suppressed (nav item hidden, route 404s) regardless of
* whether `docsBaseUrl` is set. Absent on older Core payloads — the SDK
* defaults this to `true` (backward-compatible). */
docsEnabled: boolean;
/** Immutable `CompiledPlan.id` of the featured plan, or null. Used to render
* the "Most Popular" treatment in the plans UI. */
featuredCompiledPlanId: string | null;
/** Business-level meter definitions — the dimension catalog used to label
* usage rows. Empty when the business declares no meters. */
meters: Meter[];
}
Public export BusinessResource.
Declaration source: packages/farthershore-js/dist/resources/business.d.ts#L2.
export interface BusinessResource {
/** The business this frontend is running for (resolved via bootstrap). */
get(): Promise<Business>;
/** The business's declared counted-resource catalog (W5.1) — name + label +
* scope + per-plan cap. The same list `bootstrap()` resolves. */
resources(): Promise<DeclaredResource[]>;
}
`POST /me/cancel` — the platform performs the cancel: free subs end
immediately, paid subs are scheduled on the provider for the end of the
current billing period. There is no hosted-page hand-off: the caller gets
a typed result back, and `cancelsAt` is the boundary the provider
answered with (null when it reported none, or for an immediate free
cancel). NEVER invented client-side.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1122.
export interface CancelSubscriptionResult {
subscription?: unknown;
/** ISO instant the subscription ends, or null. */
cancelsAt: string | null;
raw: unknown;
}
`POST /me/change-plan` — Core decides inline-apply vs checkout vs portal
redirect; all three surfaces normalized onto one shape.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1144.
export interface ChangePlanResult {
subscription?: unknown;
checkoutUrl?: string | null;
portalRedirect?: {
url: string;
} | null;
raw: unknown;
}
Classify a usage-limit deny into its {@link FsLimitClass}, or `null` when the
deny is NOT a usage-limit affordance. PURE + total. Hand-mirror of the
contracts `classifyLimit(wireCode, limitCode, status)` — the same switch,
same status guard. A class added/dropped or a mapping changed in contracts is
caught by the per-class sweep in `test/deny-codes-drift.test.ts`.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L75.
export declare function classifyFsLimit(wireCode: string, limitCode: string | null, status: number): FsLimitClass | null;
The single gate-mode vocabulary — a faithful copy of the contracts
`COMPONENT_GATE_MODES` (vocabulary-equality-tested in test/).
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L4.
declare const COMPONENT_GATE_MODES: readonly ["hide", "disable", "readOnly", "denied"];
One per-subscriber component-gate override row (`GET /me`
`componentAccessPolicies`) — shape-matches the contracts
`ComponentAccessPolicyDto`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L945.
export interface ComponentAccessPolicyRow {
/** A managed component id or a `custom:<slug>` key. */
componentKey: string;
/** Override render-gate permission, or null → component default. */
requiredPermission: string | null;
/** Override deny render (`hide|disable|readOnly|denied`), or null →
* component default. */
gateMode: string | null;
}
Public export ComponentGateMode.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L5.
export type ComponentGateMode = (typeof COMPONENT_GATE_MODES)[number];
A managed default entry — faithful copy of the contracts
`ComponentPermissionDefault` shape.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L10.
export interface ComponentPermissionDefault {
permission: string | null;
writePermission?: string;
presentational?: true;
}
Public export ComponentRegistration.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L47.
export interface ComponentRegistration {
/** A `custom:<slug>` key (builder components) or a managed id (to override
* a managed default host-side). */
id: string;
/** Render-gate permission. Omit to fall through to overlay/managed/derived
* resolution. */
permission?: string;
/** Mutating-affordance permission; derived `<subject>:write` otherwise. */
writePermission?: string;
/** Default deny render for this component. */
gateMode?: ComponentGateMode;
/** Renders ungated by design. Explicit only — never inferred. */
presentational?: boolean;
}
Public export CoreRequest.
Declaration source: packages/farthershore-js/dist/http.d.ts#L3.
export interface CoreRequest {
method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
path: string;
query?: Record<string, string | number | undefined | null>;
body?: unknown;
/** Caller-stable retry identity for durable mutation replay. */
idempotencyKey?: string;
/** "session" attaches the consumer session bearer; "none" is for public
* endpoints (resolve/discover). Defaults to "session". */
auth?: "session" | "none";
/** When `false`, a tolerated `401` on this (authed) read does NOT trigger the
* managed auth-layer recovery (`onUnauthorizedManaged` — the hosted-sign-in
* redirect / persona sign-out). Use for best-effort `/me` reads that already
* swallow a 401 and render a signed-out/unsubscribed surface: re-authing an
* already signed-in user can't clear an authorization 401, so the redirect is
* futile and loops. `onUnauthorized` (config hook) + `onError` still fire.
* Defaults to `true` (a lapsed authed session still bounces to recovery). */
recoverAuth?: boolean;
/** Abort signal — when it fires (e.g. a React hook unmounts or its deps
* change), the in-flight read rejects with {@link FartherShoreAbortError}. */
signal?: AbortSignal;
/**
* Per-request organization scope. `undefined` inherits the client selection;
* `null` deliberately omits the organization header without changing that
* shared selection. Use this for APIs whose documented default-subscription
* read is intentionally independent of the workspace currently shown in the
* rest of the portal.
*/
organizationId?: string | null;
}
Returned ONLY by create/rotate — carries the full secret, shown once.
Declaration source: packages/farthershore-js/dist/types.d.ts#L375.
export interface CreatedApiKey extends ApiKey {
/** The full key. The platform never returns it again — store it now. */
secret: string;
}
Create a {@link FartherShoreClient}. Zero-config: on a platform-served portal
no config is needed at all — the edge injects `window.__FS_CONFIG__` with the
environment's Core URL (and Clerk connection), `portalHost` defaults to
`window.location.host`, and the business is discovered at
{@link FartherShoreClient.bootstrap}. Those reads are LAZY (never at
construction — only when something is actually resolved, e.g. the first
request), so `createFartherShoreClient()` never throws.
The optional `config` carries only builder-facing options
({@link FartherShoreConfig}: `getToken`, `organizationId`, `mock`, `fetch`,
`retry`, the error hooks). Platform-infrastructure knobs
(coreUrl/portalHost/businessId/gatewayUrl/environmentId) are intentionally NOT
accepted here — the platform supplies them at the edge. They are STRIPPED at
runtime (not merely rejected by TypeScript, which only catches object
literals), so a plain-JS or `as any` caller physically cannot set them through
this entry point. A harness that must target a non-prod environment uses
`createFartherShoreClientWithPlatformConfig` from
`@farthershore/farthershore-js/internal`.
Declaration source: packages/farthershore-js/dist/client.d.ts#L211.
export declare function createFartherShoreClient(config?: FartherShoreConfig): FartherShoreClient;
Public export CreateServiceAccountInput.
Declaration source: packages/farthershore-js/dist/types.d.ts#L441.
export interface CreateServiceAccountInput {
name: string;
requestedPermissions: NonEmptyPermissionList__ca911cbb6fa0;
scopes?: string[];
usageLimit?: ServiceAccountUsageLimitRequest__f255b800fa4e;
}
Strict POST body: immutable subject + quantity, one value lane, and a
coherent BLOCK/NOTIFY threshold.
Declaration source: packages/farthershore-js/dist/types.d.ts#L604.
export type CreateUsageLimitInput = UsageLimitSubject & UsageLimitValue & UsageLimitCreateMode__f16ef2d50497 & {
quantity: string;
};
Faithful copy of the contracts `CUSTOM_COMPONENT_KEY_PATTERN` — the slug
budget matches the custom-subject grammar (≤32) so the derived permission
subject is always declarable.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L44.
declare const CUSTOM_COMPONENT_KEY_PATTERN: RegExp;
Optional date-formatting options. Defaults: en-US, medium date style.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L146.
export interface DateFormatOptions {
/** BCP-47 locale. Default "en-US". */
locale?: string;
/** `Intl.DateTimeFormat` date style. Default "medium". */
dateStyle?: "full" | "long" | "medium" | "short";
/** `Intl.DateTimeFormat` time style. Omitted by default (date only). */
timeStyle?: "full" | "long" | "medium" | "short";
}
A product-declared counted resource (W5.1 / P-RESCATALOG). The product's
catalog of `product.resource(...)` declarations, surfaced so a generated /
managed frontend can discover what resources exist and render their usage
WITHOUT a per-plan lookup.
- `scope: 'subscription'` — counted once per subscription (the common case).
- `scope: 'subject'` — counted per subject (e.g. per `project`), with
`subjectType` naming the subject; pass `{ subjectId }` to the resource
verbs so the count keys on that subject.
`cap` is the per-plan ceiling read from the active plan's
`resourceLimits[name]` (the bare resource name — NOT prefixed). It's
`number` (a numeric cap), `true` is treated as unlimited (left undefined),
and `null`/absent means uncapped/unknown.
Declaration source: packages/farthershore-js/dist/types.d.ts#L282.
export interface DeclaredResource {
name: string;
display?: string;
scope: "subscription" | "subject";
subjectType?: string;
/** Per-plan cap for this resource, when a plan declares one (numeric only). */
cap?: number | null;
}
FAITHFUL COPY of contracts `defaultGateModeFor` (Subscriber-RBAC R5) — the
gate mode used when NOTHING configured one. Non-sensitive components render
an explicit AccessDenied (`"denied"`) instead of silently vanishing; the
sensitive set keeps `"hide"` (their existence is the confidential fact).
Parity is pinned in test/component-policy-parity.test.ts.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L38.
export declare function defaultGateModeFor(componentId: string): "hide" | "denied";
Trigger a browser download of `csv` as `filename`. DOM side-effect — a no-op
outside the browser (SSR-safe). Components call this; pure callers stick to
the string builders above.
Declaration source: packages/farthershore-js/dist/csv.d.ts#L43.
export declare function downloadCsv(csv: string, filename: string): void;
Public export EntitlementSnapshot.
Declaration source: packages/farthershore-js/dist/resources/entitlements.d.ts#L3.
export interface EntitlementSnapshot {
/** True when an ACTIVE subscriber context backed this snapshot. */
hasSubscriber: boolean;
/** Resource limits on the current subscriber's pinned plan. */
resourceLimits: Record<string, number>;
}
Public export EntitlementsResource.
Declaration source: packages/farthershore-js/dist/resources/entitlements.d.ts#L16.
export interface EntitlementsResource {
/** Read the current subscriber's entitlement maps. Signed-out users get
* empty maps so app code can render disabled/upsell states without a
* separate auth guard. */
snapshot(): Promise<EntitlementSnapshot>;
/** Numeric resource limit, or null when absent. */
resourceLimit(key: string): Promise<number | null>;
/** Per-resource `{ limit, current }` for the pinned plan (`N of M`). The
* LIMIT side lives in the `/me` snapshot, but `current` is a live count, so
* this reads the dedicated `/me/resource-limit-usage` route. Read-through cached
* (the cache owns the fetch lifecycle, like the other `/me` reads — no
* per-caller signal). Signed-out / no subscription → an empty map. */
resourceLimitUsage(): Promise<ResourceLimitUsageMap>;
}
Public export EnvironmentInfo.
Declaration source: packages/farthershore-js/dist/types.d.ts#L85.
export interface EnvironmentInfo {
id: string;
name: string;
slug: string;
/** Which sign-in flow the portal should drive: Clerk (production) or a
* platform-owned persona browser session (preview/test envs). */
authStrategy: AuthStrategy;
/** Env branch name (preview/test envs), or null for production scope. */
branch: string | null;
/** Billing provider mode for the env: "test" (no real money) or "live".
* Null when the resolve was production-scoped (no env block). The plans UI
* surfaces a "Test mode" badge when this is "test". */
stripeMode: string | null;
}
Escape one CSV cell — with the spreadsheet formula-injection guard.
Only primitive scalars carry meaning in a CSV cell; objects coerce to a
misleading `[object Object]`, so non-primitives (and null/undefined) render as
an empty cell.
FORMULA-INJECTION (OWASP): a value that LEADS with a formula trigger
(`= + -
Declaration source: packages/farthershore-js/dist/csv.d.ts#L23.
export declare function escapeCsvCell(value: unknown): string;
A non-2xx response from Core or the Gateway. Exposes:
- `.status` — the HTTP status code;
- `.code` — the platform error code from the `{ error: { code, message } }`
envelope (or a fallback when the envelope is absent);
- `.body` — the parsed response body, for richer error detail.
Callers commonly branch on `.status` — e.g. `401`/`403` (re-auth), `404`
(treat as absent), `409` (conflict/retry) — rather than parsing the message.
Every instance also carries the throttle hints the gateway attaches when
present: `.retryAfterSeconds` (from `Retry-After`) and `.rateLimit` (from
`X-RateLimit-Remaining` / `-Reset`). Both are null when the headers are
absent — a developer who does nothing still gets them transparently.
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L49.
export declare class FartherShoreApiError extends FartherShoreError {
readonly status: number;
readonly code: string;
readonly body: unknown;
/** Seconds to wait before retrying, parsed from `Retry-After`; null when the
* response carried no `Retry-After`. */
readonly retryAfterSeconds: number | null;
/** The `X-RateLimit-Remaining` / `-Reset` snapshot, or null when absent. */
readonly rateLimit: RateLimitSnapshot__934527ed940b | null;
/**
* Whether the request that produced this error actually carried an auth
* credential (a bearer was attached). Set by the transport AFTER the error is
* minted. A `401` with `authed === false` is a NEVER-authenticated visitor (a
* signed-out `/me` read sent no bearer) — the managed auth layer must treat it
* as a no-op, NOT a lapsed-session redirect. Defaults to `true` so any caller
* that doesn't thread the flag keeps the prior (always-fire) behaviour.
*/
authed: boolean;
/**
* Whether a `401` on this request should trigger the MANAGED auth-layer
* recovery (the hosted-sign-in redirect / persona sign-out). Best-effort `/me`
* reads that already swallow a 401 (and render a signed-out/unsubscribed
* surface) set this `false`: re-authenticating an already signed-in user can
* never clear an authorization 401, so the redirect is futile and loops. Set
* by the transport from `CoreRequest.recoverAuth`. The config-level
* `onUnauthorized` + `onError` hooks STILL fire (observability is unaffected);
* only the managed reaction is gated. Defaults to `true` (always recover).
*/
recoverAuth: boolean;
constructor(status: number, code: string, message: string, body: unknown, retryAfterSeconds?: number | null, rateLimit?: RateLimitSnapshot__934527ed940b | null);
}
Public export FartherShoreClient.
Declaration source: packages/farthershore-js/dist/client.d.ts#L36.
export interface FartherShoreClient {
/** The client's resolved runtime context (coreUrl, portalHost, businessId,
* auth/scoping state, …). `coreUrl`/`portalHost` are LAZY getters — reading
* them performs the `window.__FS_CONFIG__`/`location.host` resolution
* (`coreUrl` falls back to the production platform); everything else is a
* live snapshot of the client's current state. Mainly for
* introspection/tests — prefer the typed resources for actual calls. */
readonly context: ClientContext__d9dbf3313290;
/** Resolve + cache the business/env/gateway for the current portal host. Safe
* to call repeatedly (memoized). */
bootstrap(): Promise<Bootstrap>;
/** Set the consumer API key used for Gateway feature calls. */
setApiKey(key: string | null): void;
/** Set the Core session bearer directly (e.g. from the Clerk browser SDK). */
setSessionToken(token: string | null): void;
/** Install/replace a live token source resolved per request (short-lived
* Clerk JWTs). `<FartherShoreRoot>` wires this automatically in Clerk
* environments; pass null to uninstall. */
setTokenProvider(provider: (() => string | null | Promise<string | null>) | null): void;
/** Rescope subsequent Core calls to an owning org (the multi-org
* subscription-context switcher) — sets the `x-fs-organization-id` header.
* Pass null to return to the user's default subscription. Self-persists the
* choice (restored at the next client creation). */
setOrganizationId(organizationId: string | null): void;
/** The active org id scoping Core calls, or null (the user's default
* subscription). At boot this reflects the persisted choice restored from
* storage; the React org provider seeds its reactive state from it. */
getOrganizationId(): string | null;
/** Imperative organization scope as an external store. This keeps a mounted
* React provider in sync when an application calls `setOrganizationId()`
* directly rather than using the managed org switcher. */
readonly organizationScope?: {
subscribe(listener: () => void): () => void;
};
/** Install/replace the global 401 reaction (fired by the transport on a 401
* for an authed call). `<FartherShoreRoot>` / `<FsAuthProvider>` wire this
* automatically for managed mid-session recovery (persona sign-out / Clerk
* refresh); pass null to uninstall. A config-level `onUnauthorized` still
* fires first. */
setOnUnauthorized(handler: ((err: FartherShoreApiError) => void) | null): void;
/** Drop every cached Core read (and the short-lived gateway context token), so
* the next `me()` / list call goes to the network. Use after an out-of-band
* state change the SDK can't observe — e.g. polling `me()` for webhook lag to
* settle after returning from a Stripe Checkout (see `reconcileAfterCheckout`). */
invalidate(): void;
/** The last `X-RateLimit-*` snapshot observed on any `fs.route` gateway call,
* with a subscribe primitive — the external store behind `useRouteRateLimit()`
* (W8.5). `get()` is null until the first gateway response carried the
* headers; `subscribe` notifies on every change. */
readonly rateLimit: {
get(): RateLimitSnapshot__934527ed940b | null;
subscribe(listener: () => void): () => void;
};
/** A5-amend (T11) — the last LIMIT/throttle deny observed leaving the
* transport, with a subscribe primitive — the external store behind
* `useLimitStatus()`. ADVISORY (the freshest known RECENT deny, not a live
* poll — the gateway stays authoritative). `get()` is null until the first
* limit deny is observed; `subscribe` notifies on every change. */
readonly limitState: {
get(): ObservedLimitDeny__ff379deca309 | null;
subscribe(listener: () => void): () => void;
};
/** Read-cache invalidation as an external store. `subscribe` fires when a
* change invalidates what is ALREADY on screen: a new session/identity
* (`setSessionToken`, sign-in/sign-out) or a moved entitlement (any billing
* or plan action, and `invalidate()`).
*
* It deliberately does NOT fire on an org switch (org-scoped hooks refetch
* from their own deps) or on an ordinary resource mutation (the hook that
* performed it refetches itself).
*
* Every `useAsync`-backed hook subscribes automatically, so built-in hooks
* and custom ones written against `useAsync` already refetch. Use this
* directly only for state held OUTSIDE a hook (a store, an imperative cache
* of your own) that must be invalidated in step with ours. */
readonly readCache: {
subscribe(listener: () => void): () => void;
};
/** The business this frontend runs for (resolved via bootstrap). */
readonly business: BusinessResource;
/** Consumer session: current identity, server-owned persona logout, and
* short-lived Gateway context-token minting. */
readonly auth: AuthResource;
/** The consumer's API keys (list / create / revoke / rotate). */
readonly keys: KeysResource;
/** Per-dimension usage totals + recent events for this business. */
readonly usage: UsageResource;
/** Subscriber-managed per-actor usage limits. */
readonly usageLimits: UsageLimitsResource;
/** The consumer's subscription and Stripe billing portal. */
readonly billing: BillingResource;
/** The business's plan catalog + the subscribe/checkout flow. */
readonly plans: PlansResource;
/** Full subscriber context (`GET /me`): lifecycle, trial, scheduled
* transition, eligibility-scoped plans. Null when signed out / no
* subscriber. */
me(opts?: {
signal?: AbortSignal;
/** `null` omits the organization header without changing the shared
* client selection; `undefined` uses that selection. */
organizationId?: string | null;
}): Promise<SubscriberContext | null>;
/** Record legal-document acceptances for the current subscriber/org. */
acceptLegal(acceptances: LegalAcceptance__cc2291cc0442[]): Promise<void>;
/** Multi-org subscription contexts (the org switcher's data). */
readonly organizations: OrganizationsResource;
/** Team management on the current subscription. */
readonly team: TeamResource;
/** Managed-RBAC management on the current subscription (settings, the
* derived permission catalog, role CRUD) — team-org OWNER/ADMIN only.
* Configures UX + minted-token claims; the EDGE `permission` constraint
* is the security boundary. */
readonly rbac: RbacResource;
/** The subscriber's per-category notification preferences (opt-out model):
* `get` the current state, `update` a partial patch. */
readonly notifications: NotificationsResource;
/** The subscriber-side audit log (cursor-paged). */
readonly auditLogs: AuditLogsResource;
/** Current subscriber entitlement maps from the pinned plan version. */
readonly entitlements: EntitlementsResource;
/** Navigation-intent data warmers — see {@link PrefetchSurface}. */
readonly prefetch: PrefetchSurface__2b22bd2b6c45;
/**
* One-line, zero-config calls to your business's enforced gateway — host,
* auth, surface, and businessId all auto-resolved from the hosted context.
* `fs.route.post("/forecast", { city })`. Limit responses surface as
* `LimitExceededError` so the upgrade prompt works on any call.
*/
readonly route: RouteResource;
/**
* Typed CRUD over a product-declared, quota-counted resource. Rides the
* gateway (which diverts to core, the system of record); `create` throws
* `LimitExceededError` at the plan cap. `fs.resources("widgets").list()`.
*/
resources<T = unknown>(name: string): ResourcesResource<T>;
/** Bound named-integration helper: `fs.integration("clerk-admin").fetch(...)`. */
integration(id: string): ManagedIntegration;
/**
* Generic authenticated Core call — the escape hatch for platform endpoints
* the typed resources don't model yet (e.g. a product's `/me/team`,
* `/me/audit-logs`). The Core counterpart to {@link invoke}:
* it attaches the session bearer + the host/env/org scoping headers and maps
* non-2xx to {@link FartherShoreApiError}, exactly like the typed resources —
* the caller only supplies the path and the response type. Prefer a typed
* resource (`fs.usage`, `fs.keys`, …) when one exists.
*/
core<T>(req: CoreRequest): Promise<T>;
}
The builder-facing client config — the ONLY shape `createFartherShoreClient`
accepts. Every field here is something a builder legitimately owns at the app
layer: their session provider, their org scope, their fetch impl, mock mode,
observability hooks. It contains NO platform-infrastructure knobs.
Platform routing/plumbing (`coreUrl`, `portalHost`, `businessId`,
`gatewayUrl`, `environmentId`) is deliberately absent: the edge injects it via
`window.__FS_CONFIG__` and the SDK discovers the rest at `bootstrap()`, so a
builder calls `createFartherShoreClient()` with zero config. Our own harnesses
that must steer a client at a non-prod environment use the internal channel
({@link FartherShorePlatformConfig} via
`@farthershore/farthershore-js/internal`) — never this type.
Declaration source: packages/farthershore-js/dist/config.d.ts#L95.
export interface FartherShoreConfig {
/** Owning org id for org-owned subscriptions (the `x-fs-organization-id`
* header / `organizationId` query). Usually set at runtime via
* `fs.setOrganizationId()` / the managed org switcher rather than here. */
organizationId?: string | null;
/** The consumer API key (`fsk_…`) used to authenticate Gateway feature calls.
* Settable later via `fs.setApiKey()`. */
apiKey?: string;
/** Session token provider for Core calls. Clerk browser sessions use this;
* test personas use the platform's same-origin HttpOnly cookie instead. */
getToken?: TokenProvider;
/** Injectable fetch (tests / non-browser runtimes). Defaults to global fetch. */
fetch?: FetchLike;
/** Automatic-retry policy for transient failures (429 + transient 502/503/504
* + network faults). Retry is ON by default; this only tunes/opts out. See
* {@link RetryConfig}. */
retry?: RetryConfig__bec25563219c;
/** Optional global hook fired (before the error is thrown) on EVERY non-2xx /
* network failure that leaves the transport. Observability only — it does not
* swallow the error. Default behaviour is unchanged when unset. */
onError?: (err: FartherShoreApiError | unknown) => void;
/** Optional global hook fired (before throw) when the error is a
* {@link LimitExceededError} — a single place to surface an upgrade prompt. */
onLimitExceeded?: (err: LimitExceededError) => void;
/** Optional global hook fired (before throw) on a `401` — a single place to
* trigger re-auth. */
onUnauthorized?: (err: FartherShoreApiError) => void;
/** Render a local portal with deterministic placeholder data and no live
* backend/auth. Also enabled by `window.__FS_CONFIG__.mock === true`. */
mock?: boolean;
}
Thrown at client construction for invalid/missing config (e.g. no `coreUrl`,
no global `fetch`).
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L723.
export declare class FartherShoreConfigError extends FartherShoreError {
constructor(message: string);
}
Public export FartherShoreError.
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L2.
export declare class FartherShoreError extends Error {
constructor(message: string);
}
A {@link FartherShoreApiError} the caller should BACK OFF and retry — a rate
limit (`429`) or one of the transient throttle deny codes. `.retryAfterSeconds`
(when the gateway sent `Retry-After`) is the hint for how long. Catch it to
implement a retry/backoff loop without re-parsing status codes.
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L288.
export declare class FartherShoreRateLimitedError extends FartherShoreApiError {
/** The semantic {@link FsLimitClass} when this throttle classifies to one
* (`rate` / `concurrency` / `adaptive`), else null. */
readonly limitClass: FsLimitClass | null;
/** The parsed `_fs` deny envelope when present. */
readonly envelope: FsDenyEnvelope__adf7ef9f2448 | null;
/** The recommended client reaction (default `backoff_retry` for a throttle). */
readonly reaction: FsLimitReaction__06a9e09be641;
/** Whether the platform or an upstream provider decided the throttle. */
readonly limitOrigin: FsLimitOrigin__1d4de1805fa7;
/** The gateway decision id, when the `_fs` envelope carried one. */
readonly decisionId: string | null;
constructor(status: number, code: string, message: string, body: unknown, retryAfterSeconds?: number | null, rateLimit?: RateLimitSnapshot__934527ed940b | null);
}
Public export FetchLike.
Declaration source: packages/farthershore-js/dist/config.d.ts#L2.
export type FetchLike = typeof fetch;
Public export format.
Declaration source: packages/farthershore-js/dist/format/index.d.ts#L1.
export { describePlanKind__bc89a2a76f27, selectAutoEnrollPlan__91fe58a3dbee, formatPlanPrice__fc05951fffba, planPriceHeadline__3b389a69aee5, formatPlanPriceDetail__ce62e738fa5f, describePlanSummary__1087c6d6f26e, sortPlansForDisplay__accee323738d, filterSelectablePlans__491d00098a7d, presentPlanPrice__dbe194aa1865, formatCents__0834b254bd71, formatNanos__88e9bbf170bb, formatDate__eb204cfcfad9, formatMinimumSpend__703e50763b9b, entitlementBullets__777c9056ecca, labelResourceLimitKey__6d50ec5c1da1, synthesizePlanFeatures__42c0175e6f51, synthesizePlanFeaturesLean__5ee4c35cee39, quotaLines__aba5f4afb4f1, quotaForDimension__765de95b18ad, computeProgressBar__e4819393223f, buildRateLimits__5220b52a303e, formatRateLimitText__902f4a94c331, isTokenBusiness__5fb93c023117, buildPrimaryUsage__a1cfc1e9cdb3, buildDimensionBreakdown__f82446dddd7c, buildMeterUsageRows__dd03e7a0a916, buildPinnedMeterUsageRows__fd3dc232bb17, subscriptionStatusChip__c2e919e840ee, trialDaysRemaining__a42e758e8e6c, paymentHealth__82ab0e675721, pluralizeUnit__54c9aa5d8d69, unitSuffix__0244077a537f, usagePeriodLabel__e8ab92f06f5c, buildResourceLimitRows__f08613820468, formatPlanLimitWindow__d3866d671c3e, describePlanLimit__44aef0cd7254, catalogPricingLines__c7aab05ab71a, formatCatalogRate__1c4069e5c4b5, formatCatalogRule__8f5b591f982d, formatCatalogFunding__e3d315174586, formatCatalogExhaustion__22106a32de44, prepaidFundingBucket__c3b93630376c, prepaidBalanceNanos__82cd3a195fcf, catalogRuleQualifier__43f6b05ea45d, singularizeMeasure__4920b2d3814d, } from "./catalog-display.js";
export { planRequiresCheckoutActivation__895e488c9dd3, resolvePlanTransitionRoute__704c66191ea4, isCheckoutOnlyTransitionError__ed7cb1b92a62, describePlanChangeError__6199fc9db841, logPlanChangeError__b74061738e9e, } from "./plan-transition.js";
export { humanizeMeasureKey__87b59e8494f9, formatMeasureBreakdown__d29c7c37d4b8, } from "./usage-labels.js";
export { getScheduledTransitionCopy__d0d68b298653, getSubscriberPromoCopy__a02fd2e64736, getSubscriberStatusPresentation__3d2be580d857, humanizeSubscriberStatus__a8dba22c416c, } from "./subscriber-lifecycle.js";
//# sourceMappingURL=index.d.ts.map
Every canonical gateway deny wire `code` (mirrors
`GATEWAY_DENY_CODES` keys in `@farthershore/contracts`). Branch on
`FartherShoreApiError.code` against these.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L4.
declare const FS_DENY_CODES: {
readonly limit_allocator_unavailable: "limit_allocator_unavailable";
readonly limit_exceeded: "limit_exceeded";
readonly rate_limited: "rate_limited";
readonly credit_exhausted: "credit_exhausted";
readonly credit_state_unavailable: "credit_state_unavailable";
readonly enforcement_denied: "enforcement_denied";
readonly route_not_enabled: "route_not_enabled";
readonly invalid_entitlement_shape: "invalid_entitlement_shape";
readonly unsupported_constraint_schema: "unsupported_constraint_schema";
readonly enforcement_error: "enforcement_error";
readonly enforcement_dependency_unavailable: "enforcement_dependency_unavailable";
readonly admission_descriptor_unavailable: "admission_descriptor_unavailable";
readonly admission_descriptor_no_admissible_tuple: "admission_descriptor_no_admissible_tuple";
readonly invalid_admission_knob: "invalid_admission_knob";
readonly admission_bound_exceeded: "admission_bound_exceeded";
readonly commercial_release_unprovable: "commercial_release_unprovable";
readonly concurrency_limit_exceeded: "concurrency_limit_exceeded";
readonly concurrency_context_unavailable: "concurrency_context_unavailable";
readonly concurrency_coordinator_unavailable: "concurrency_coordinator_unavailable";
readonly key_expired: "key_expired";
readonly credential_revoked: "credential_revoked";
readonly credential_rotated: "credential_rotated";
readonly credential_env_reset: "credential_env_reset";
readonly permission_denied: "permission_denied";
readonly permission_unresolved: "permission_unresolved";
readonly geo_context_unavailable: "geo_context_unavailable";
readonly geo_blocked: "geo_blocked";
readonly geo_not_allowed: "geo_not_allowed";
readonly resource_count_limit_exceeded: "resource_count_limit_exceeded";
readonly post_stream_overspend: "post_stream_overspend";
readonly request_too_large: "request_too_large";
readonly resolver_rate_limited: "resolver_rate_limited";
readonly resolver_unavailable: "resolver_unavailable";
readonly credential_resolver_miss_rate_limited: "credential_resolver_miss_rate_limited";
readonly provider_throttled: "provider_throttled";
};
HTTP statuses that, with a limit descriptor present, mint a limit/upgrade
affordance (LimitExceededError) SDK-side. Mirrors `DENY_LIMIT_STATUSES`.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L57.
declare const FS_DENY_LIMIT_STATUSES: readonly [402, 403, 413, 429];
The closed set of usage-limit classes. Mirrors the contracts `LimitClass`.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L63.
declare const FS_LIMIT_CLASSES: readonly ["quota", "rate", "concurrency", "capacity", "spend", "adaptive"];
A normalized identity for the signed-in user — the same shape whether it
comes from Clerk or Core's safe test-persona session view. The persona
credential remains in an HttpOnly cookie and is never present in `raw`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L789.
export interface FsAuthUser {
/** Stable user/subscription id, or null when unknown. */
id: string | null;
firstName: string | null;
lastName: string | null;
/** Display name — Clerk's `fullName`, else `first last`, else null. */
fullName: string | null;
/** Primary email — Clerk's `primaryEmailAddress.emailAddress` (nested) or a
* flat `email`, else null. */
email: string | null;
imageUrl: string | null;
/** The original Clerk user or safe persona identity view, untouched. */
raw: unknown;
}
A canonical gateway deny wire code.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L42.
export type FsDenyCode = (typeof FS_DENY_CODES)[keyof typeof FS_DENY_CODES];
Public export FsDenyLimitStatus.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L58.
export type FsDenyLimitStatus = (typeof FS_DENY_LIMIT_STATUSES)[number];
Options for {@link fsFetch}.
Declaration source: packages/farthershore-js/dist/fetch.d.ts#L3.
export interface FsFetchOptions {
/** HTTP method for the upstream call. Defaults to `GET`. */
method?: string;
/** Browser-controlled headers. The named integration allowlists them. */
headers?: Record<string, string>;
/** Browser-controlled query parameters. The named integration allowlists
* each name; secret injection parameters remain server-owned. */
query?: Record<string, string>;
/** Optional, explicitly typed request body. The named integration's bounded
* body declaration is enforced by the gateway. */
body?: {
kind: "json";
value: unknown;
} | {
kind: "text";
value: string;
};
/** Abort signal — cancels the in-flight secure fetch (and the token mint). */
signal?: AbortSignal;
}
The semantic class a usage-limit deny falls into. Mirrors `LimitClass`.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L65.
export type FsLimitClass = (typeof FS_LIMIT_CLASSES)[number];
Platform-injected runtime config. Portals served through the Farther Shore
edge get a `window.__FS_CONFIG__` script injected into their HTML (the
site-shell worker's inject-meta pass), carrying the per-environment platform
values — so a portal bundle ships env-agnostic and `createFartherShoreClient()`
works with zero config. For standalone clients and platform harnesses,
explicit config wins over injected values. In a managed portal the shell's
same-origin route is authoritative and explicit Core overrides are ignored.
Declaration source: packages/farthershore-js/dist/config.d.ts#L47.
export interface FsRuntimeConfig {
/**
* Set only by the Farther Shore site shell. A managed portal must never use
* the SDK's standalone production fallback: it has to receive a valid
* same-environment Core route from that shell.
*/
managedPortal?: boolean;
/** Platform Core base URL for this environment. */
coreUrl?: string;
/** Clerk connection for clerk-strategy environments (public values). */
clerk?: {
publishableKey?: string;
signInUrl?: string;
/** Hosted sign-UP page. Optional: the SDK derives it from `signInUrl` when
* the edge does not inject one. */
signUpUrl?: string;
satelliteDomain?: string;
};
/** The business this portal serves; injected by the edge, else discovered
* by bootstrap(). */
businessId?: string;
/** The serving edge proxies `/_fs/api/*` to core, so requests should go
* SAME-ORIGIN. See {@link resolveCoreUrl}. */
coreProxy?: boolean;
/** Local placeholder-data mode for generated portals. */
mock?: boolean;
}
The validated envelope the SDK sends. A hand-mirror of the
`@farthershore/contracts` `SecureFetchEnvelope` — the published SDK bundle
stays contracts-free (see deny-codes.ts), and the parity is pinned by the
test-only drift guard `test/secure-fetch-envelope-drift.test.ts`.
Declaration source: packages/farthershore-js/dist/fetch.d.ts#L27.
export interface FsSecureFetchEnvelope {
integrationId: string;
path: string;
method: string;
headers?: Record<string, string>;
query?: Record<string, string>;
body?: {
kind: "json";
value: unknown;
} | {
kind: "text";
value: string;
};
}
Public export GatewayContextToken.
Declaration source: packages/farthershore-js/dist/types.d.ts#L803.
export interface GatewayContextToken {
/** Short-lived `fsc_` bearer accepted by the Gateway for this subscriber. */
token: string;
/** ISO timestamp when the token expires. */
expiresAt: string;
}
Whether a subscriber's lifecycle grants access to the authenticated portal
surfaces. WHERE to send someone without access is the builder's routing
decision; WHETHER they have it is platform semantics, so the rule lives here
— beside the lifecycle copy it moves in lockstep with. A new lifecycle state
changes both in one file instead of drifting across every builder repo.
Not a formatter, so it is exported flat from the package root rather than
through the `format` namespace.
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L18.
export declare function hasPortalAccess(subscriber: SubscriberDetail | null | undefined): boolean;
Same-origin named integration base URL.
Declaration source: packages/farthershore-js/dist/integrations.d.ts#L19.
export declare function integrationUrl(id: string): string;
True iff `mode` is a member of {@link COMPONENT_GATE_MODES}.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L7.
export declare function isComponentGateMode(mode: string): mode is ComponentGateMode;
True iff `id` is a well-formed builder-custom component key.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L46.
export declare function isCustomComponentKey(id: string): boolean;
True when a status is in the limit/upgrade-affording taxonomy. Mirrors the
contracts `isDenyLimitStatus`.
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L61.
export declare function isDenyLimitStatus(status: number): status is FsDenyLimitStatus;
Guard: is `value` a member of the closed {@link FsLimitClass} set?
Declaration source: packages/farthershore-js/dist/deny-codes.d.ts#L67.
export declare function isFsLimitClass(value: string): value is FsLimitClass;
True iff `id` names a confidentiality-sensitive managed component.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L40.
export declare function isSensitiveComponentKey(id: string): boolean;
Whether `permission` is a canonical permission requirement.
The grammar accepts the bare global wildcard `*`, or any non-empty subject
and non-empty verb separated by the first `:`. Route-derived subjects may
contain dots, spaces, slashes, and additional colons.
This is a contracts-free mirror of `@farthershore/authz`'s
`parsePermission`. Keep it local so the published SDK does not acquire an
`@farthershore/authz` runtime dependency; the test-only parity guard imports
the parser through a devDependency.
Declaration source: packages/farthershore-js/dist/permissions.d.ts#L12.
export declare function isValidPermissionRequirement(permission: string | null | undefined): permission is string;
Public export KeysResource.
Declaration source: packages/farthershore-js/dist/resources/keys.d.ts#L3.
export interface KeysResource {
/** The consumer's API keys for this product (secrets are never returned). */
list(opts?: {
signal?: AbortSignal;
}): Promise<ApiKey[]>;
/**
* Create a key. The returned `secret` is shown ONCE.
*
* Consumer-principal (D2): this generic route creates PERSONAL member keys.
* Managed service credentials use the canonical `serviceAccounts` lifecycle,
* which can return PENDING without creating a secret.
*
* `roleKeys` binds the key to org RBAC roles (live-bound: a role edit reaches
* the key without reprovisioning); `restrictedPermissions` optionally narrows
* the bound roles to a Stripe-style subset. Both are grantable only within
* the creator's own permissions — the backend 403s an over-reaching binding.
* (PERSONAL keys ignore `roleKeys` — their perms track the bound member.)
*/
create(input?: {
label?: string;
scopes?: string[];
roleKeys?: string[];
restrictedPermissions?: string[];
kind?: "PERSONAL";
/** PERSONAL — mint FOR this member (their `Membership.id`); admin-gated. */
memberId?: string;
}): Promise<CreatedApiKey>;
/** Permanently revoke a key by id. */
revoke(keyId: string): Promise<void>;
/** Rotate a key — revokes the old and returns a new `secret` (shown once). */
rotate(keyId: string): Promise<CreatedApiKey>;
/** Canonical managed service-account provisioning and approval lifecycle. */
readonly serviceAccounts: ServiceAccountsResource;
}
A {@link FartherShoreApiError} that is specifically a plan-limit block — a
resource quota (`402 resource_count_limit_exceeded`), a usage quota, a rate
limit, or a credit cap. Carries the {@link LimitDescriptor} so the app can
resolve an upgrade target from the bootstrap catalog and prompt the user
(see `useUpgrade` / `<UpgradePrompt>`).
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L206.
export declare class LimitExceededError extends FartherShoreApiError {
readonly limitCode: string;
readonly dimension: string | null;
readonly currentCapacity: number | null;
/** The semantic {@link FsLimitClass} of this limit — derived from the `_fs`
* envelope when present, else from the wire code + limitCode + status
* ({@link classifyFsLimit}). null only when nothing classifies it. */
readonly limitClass: FsLimitClass | null;
/** The parsed `_fs` deny envelope, when the body carried one. The richer
* source for the reaction/headroom fields below. */
readonly envelope: FsDenyEnvelope__adf7ef9f2448 | null;
/** True when retrying the SAME request can succeed (a velocity/transient cap);
* false when it never will (a spend cap / oversized request). */
readonly retrySafe: boolean;
/** True when the caller must MODIFY the request before it can succeed (a
* `capacity` ceiling or `spend` cap). */
readonly mustModify: boolean;
/** The recommended client reaction. */
readonly reaction: FsLimitReaction__06a9e09be641;
/** Whether the platform or an upstream provider decided the limit. */
readonly limitOrigin: FsLimitOrigin__1d4de1805fa7;
/** The gateway decision id (correlates with the usage event / audit), when
* the `_fs` envelope carried one. */
readonly decisionId: string | null;
/** When the limit window resets, when known (from the `_fs` envelope `reset`,
* unix-epoch ms, else the `X-RateLimit-Reset` snapshot). */
readonly reset: Date | null;
/** Units remaining in the window at decision time, when known. */
readonly remaining: number | null;
/** Units already consumed in the window at decision time, when known. */
readonly used: number | null;
/** The cap value hit, when known. */
readonly limit: number | null;
constructor(status: number, code: string, message: string, body: unknown, descriptor: LimitDescriptor__01693492a147, retryAfterSeconds?: number | null, rateLimit?: RateLimitSnapshot__934527ed940b | null);
}
FAITHFUL COPY of `@farthershore/contracts` `componentPermissionDefaults`
(parity-tested in test/component-policy-parity.test.ts — the shipped SDK
bundle must stay contracts-free).
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L18.
declare const MANAGED_COMPONENT_DEFAULTS: Readonly<Record<string, ComponentPermissionDefault>>;
A frontend-safe handle to one product-declared integration. It never exposes
its upstream origin, secret reference, or injection configuration.
Declaration source: packages/farthershore-js/dist/integrations.d.ts#L6.
export type ManagedIntegration = {
fetch(path: string, init?: ManagedIntegrationRequestInit): Promise<Response>;
/**
* Fetch-compatible adapter for native SDKs that accept a custom transport.
* Pair it with {@link url}; it converts the SDK's ordinary Request into the
* bounded named-integration envelope without exposing the injected secret.
*/
transport(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
/** Same-origin reserved base URL for native SDKs. It must be paired with this
* handle's `transport`; a raw browser fetch to the URL is not authorized. */
url(path?: string): string;
};
Public export ManagedIntegrationRequestInit.
Declaration source: packages/farthershore-js/dist/integrations.d.ts#L3.
export type ManagedIntegrationRequestInit = FsFetchOptions;
A business-level meter definition (the dimension catalog used to label/format
usage). Mirrors the wire `MeterDefinition`; only the display-relevant fields
are surfaced.
Declaration source: packages/farthershore-js/dist/types.d.ts#L15.
export interface Meter {
/** Stable dimension key (e.g. "requests", "tokens"). */
key: string;
/** Human-friendly label for the dimension. */
display: string;
/** Optional unit suffix (e.g. "ms", "tokens"). */
unit?: string;
}
Public export MeterUsageRow.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L226.
export type MeterUsageRow = {
key: string;
label: string;
used: number;
quota: number | null;
unit?: string;
/** True when the row is a MEASURE the product meters but does NOT publish in
* its served meter catalog (`ocr_pages`, `pages`) rather than a first-class
* meter. Such a row is a breakdown of the metered total, not a peer of it —
* the usage surfaces render it as a secondary line under the meter rows
* instead of as another top-level row. */
secondary?: boolean;
};
Optional money-formatting locale options. Defaults: USD, en-US.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L126.
export interface MoneyFormatOptions {
/** ISO 4217 currency code (e.g. "EUR", "GBP"). Default "USD". */
currency?: string;
/** BCP-47 locale (e.g. "de-DE"). Default "en-US". */
locale?: string;
}
A nanodollar amount off the wire: Core's decimal-integer STRING, or `null`
when the wire value was malformed (non-integer, non-string, missing). The
reader never coerces a malformed amount to `"0"` — a `null` renders as
"unavailable", never as `$0`. Format non-null values with
`format.formatNanos` (bigint) — never `Number()`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1179.
export type NanosAmount = string | null;
Normalize a Clerk user object or safe persona identity view into the
SDK's {@link FsAuthUser}. Returns null when `raw` isn't an object (signed
out / unknown). Every named field degrades to null; `fullName` falls back to
`first last` when Clerk/persona doesn't supply one.
Declaration source: packages/farthershore-js/dist/auth-user.d.ts#L6.
export declare function normalizeAuthUser(raw: unknown): FsAuthUser | null;
The closed set of notification categories.
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L4.
declare const NOTIFICATION_CATEGORIES: readonly ["billing", "usage", "access", "product", "deployments", "team", "security"];
Public export NOTIFICATION_CATEGORY_META.
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L13.
declare const NOTIFICATION_CATEGORY_META: Readonly<Record<NotificationCategory, NotificationCategoryMeta>>;
The categories a given plane's preferences page should display.
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L15.
export declare function notificationCategoriesForPlane(plane: NotificationPlane): NotificationCategory[];
Public export NotificationCategory.
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L5.
export type NotificationCategory = (typeof NOTIFICATION_CATEGORIES)[number];
Human-facing metadata for a category (drives the preferences UI).
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L7.
export interface NotificationCategoryMeta {
readonly category: NotificationCategory;
readonly label: string;
readonly description: string;
readonly planes: readonly NotificationPlane[];
}
The two principal planes a category can surface on.
Declaration source: packages/farthershore-js/dist/notification-categories.d.ts#L2.
export type NotificationPlane = "builder" | "portal";
The subscriber's full notification-preference state
(`GET /portal/businesses/:id/me/notification-preferences`). Email is the only
notifiable channel, so a preference is a single email OPT-OUT:
- `master === true` suppresses EVERY category's email;
- `categories[category] === true` additionally mutes a single category.
Email is suppressed for an event iff the master opts out OR the event's
category opts out. Category keys are the contracts notification categories
(`billing`, `usage`, …) — kept as a plain string map so the SDK stays
contracts-free; the UI joins them to `NOTIFICATION_CATEGORY_META`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1164.
export interface NotificationPreferences {
master: boolean;
categories: Record<string, boolean>;
}
The PATCH body — a PARTIAL patch of the master and/or any categories. Only
the master/categories present change; omit the rest. Send only the delta.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1170.
export interface NotificationPreferencesPatch {
master?: boolean;
categories?: Record<string, boolean>;
}
The subscriber's per-category notification preferences (the portal
`/me/notification-preferences` surface). OPT-OUT model — see
{@link NotificationPreferences}. Deliberately NON-degrading (like
{@link RbacResource}): a failed read THROWS the typed `FartherShoreApiError`
so the preferences page can render an explicit error state rather than a
silent all-opted-in default.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L169.
export interface NotificationsResource {
/** The current preference state. Missing `master`/`categories` in a partial
* wire response are normalized to the opted-in defaults. */
preferences(opts?: {
signal?: AbortSignal;
}): Promise<NotificationPreferences>;
/** Partial patch — send ONLY the changed channels/categories. Returns the
* full, normalized updated state. */
updatePreferences(patch: NotificationPreferencesPatch): Promise<NotificationPreferences>;
}
Public export OffsetPage.
Declaration source: packages/farthershore-js/dist/types.d.ts#L535.
export interface OffsetPage<T> {
data: T[];
pagination: {
limit: number;
offset: number;
hasMore: boolean;
};
}
`POST /onboarding` result: paid plans hand back `checkoutUrl` (note: NOT
`url` like checkout-session); free plans activate inline and may include a
one-time auto-created API key (drives the auto-key banner).
Declaration source: packages/farthershore-js/dist/types.d.ts#L1104.
export interface OnboardingResult {
checkoutUrl?: string | null;
subscriber?: unknown;
/** One-time full key secret when Core auto-creates the first key. */
autoApiKey?: string | {
secret?: string;
} | null;
/** Set when the first-key mint failed AFTER the subscriber became active —
* surfaced (not swallowed) so the client can tell the user. */
autoApiKeyError?: AutoApiKeyError | null;
raw: unknown;
}
Opaque allowance display — NEVER carries a nanodollar amount. Either the
plan-authored display units (`multiplier`: the allowance is
`allowanceUnits` units, remaining/consumed are fractional units of it) or,
when the plan authored no display, the consumption fraction in basis
points.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1215.
export type OpaqueAllowanceDisplay = {
kind: "multiplier";
/** Authored allowance in display units (e.g. 5 for a "5x" plan). */
allowanceUnits: number;
/** Remaining allowance in display units, 2 decimals, as a string. */
remainingUnits: string;
/** Consumed allowance in display units, 2 decimals, as a string. */
consumedUnits: string;
} | {
kind: "fraction";
/** Consumed share of the allowance in basis points (0..10000). */
consumedBasisPoints: number;
/** Remaining share of the allowance in basis points (0..10000). */
remainingBasisPoints: number;
};
Opaque plans return allowance shape ONLY — nothing a subscriber could
divide by a known request count to recover the per-unit rate. Amounts owed
surface through the invoice, not the preview.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1277.
export interface OpaqueBillPreview {
currency: string;
disclosure: "opaque";
/** The plan's recurring fee, in cents. */
recurringFeeCents: number;
allowances: OpaqueBillPreviewAllowance[];
}
A funding allowance under opaque disclosure — kind / state / expiry plus
the authored display; no amounts.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1232.
export interface OpaqueBillPreviewAllowance {
kind: string;
/** Bucket lifecycle state — Core's `BucketState`, verbatim. */
state: BucketState;
expiresAt: string | null;
display: OpaqueAllowanceDisplay;
}
Public export OrganizationsResource.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L3.
export interface OrganizationsResource {
/** The orgs through which the current user holds subscriptions to this
* product (B2B multi-org). Degrades to the empty shape on any error —
* exactly how the SSR portal treated it. Set `strict` only when a caller
* needs to render the read failure distinctly from a valid empty result. */
contexts(opts?: {
signal?: AbortSignal;
strict?: boolean;
}): Promise<SubscriptionContextsResult>;
}
Public export PaymentHealth.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L330.
export interface PaymentHealth {
state: PaymentHealthState;
/** A suggested call-to-action when the subscription needs attention, or null
* when healthy. Plain copy — the component decides how to render it. */
cta: string | null;
}
`blocked` is the one that gates access: the subscriber's plan declared no
dunning grace (or the grace ran out), so the edge is refusing every call.
`past_due` means a payment failed but a declared grace window is still
serving them — degraded, not cut off. The distinction decides whether the
host app is usable at all, so it is a separate state rather than a tone.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L329.
export type PaymentHealthState = "ok" | "past_due" | "incomplete" | "blocked" | "cancelled";
Public export PendingServiceAccountApproval.
Declaration source: packages/farthershore-js/dist/types.d.ts#L521.
export interface PendingServiceAccountApproval {
id: string;
operation: ServiceAccountApprovalOperation;
serviceAccountId: string;
requestedBy: string;
requestedPermissions: string[];
excessPermissions: string[];
createdAt: string;
serviceAccount: {
name: string;
/** Frozen grants that stay active for a pending UPDATE. */
grantedPermissions: string[];
};
}
Public export PendingServiceAccountCreateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L455.
export interface PendingServiceAccountCreateResponse {
status: "PENDING";
serviceAccountId: string;
approvalId: string;
requestedPermissions: string[];
/** A pending create has no live credential or frozen authority. */
grantedPermissions: [];
excessPermissions: string[];
eligibleApproverIds: string[];
}
Public export PendingServiceAccountUpdateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L476.
export interface PendingServiceAccountUpdateResponse {
status: "PENDING";
serviceAccountId: string;
approvalId: string;
/** Frozen grants that remain active while approval is pending. */
activePermissions: string[];
requestedPermissions: string[];
excessPermissions: string[];
eligibleApproverIds: string[];
}
Whether the granted `permissions` satisfy the required `key` under the
unified grammar: `"*"` (global), `"<subject>:*"` (subject wildcard), or the
EXACT key. There is NO verb-class widening — a `billing:write` grant never
satisfies `billing:refund` (class forms are expanded to concrete verbs at
save time, server-side). Superset of {@link permissionGrants }: it adds the
`<subject>:*` rung.
FAITHFUL COPY of the canonical `permissionSatisfies` in
`@farthershore/contracts` (`authz/verbs.ts`) — the published SDK bundle must
stay contracts-free, so a TEST-ONLY parity guard
(`test/permissions-parity.test.ts`) asserts this copy agrees with the
canonical primitive over a shared golden table. DEFINED array only (empty =
deny-all), matching the frontend's deny-on-absence stance.
Declaration source: packages/farthershore-js/dist/permissions.d.ts#L28.
export declare function permissionSatisfies(required: string, granted: readonly string[]): boolean;
Safe, non-secret view of a server-owned test-persona browser session.
Declaration source: packages/farthershore-js/dist/types.d.ts#L334.
export interface PersonaAuthSession {
kind: "test-persona";
personaId: string;
userId: string;
organizationId: string | null;
displayName: string | null;
expiresAt: string;
}
The pinned-plan display surface from `GET /me` — the dimensions the
subscriber's ACTUAL plan declares and its month-window quota rules.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L269.
export interface PinnedUsageDisplay {
/** Ordered dimension names the pinned plan displays. `rules[].d` indexes in. */
displayDims?: string[] | null;
/** Pinned rate-limit / quota allowances (month-window rows are the quotas). */
rules?: SubscriberPinnedRule__7b0d2ee36c4a[] | null;
}
A purchasable/available plan in the product catalog. Mirrors core's
`PortalPlan` (declared kind + recurring billing shape) so the template can
render the plan card, included quotas, and a subscribe button. Money for
usage lives ONLY in the bill preview ({@link BillPreview}).
Declaration source: packages/farthershore-js/dist/types.d.ts#L127.
export interface Plan {
/** Immutable `CompiledPlan.id` — the pointer passed to `subscribe()`. */
id: string;
key: string;
name: string;
description: string | null;
/**
* The builder's DECLARED plan kind. `"free"` is the free tier — a FLOOR,
* not an option: subscribers are auto-enrolled on it at sign-up and fall
* back to it when a paid plan is cancelled, so `<PlansTable>` and every
* other plan-card surface hides it rather than offering it as a choice.
* Read this field — do NOT infer it from a zero recurring fee, which is
* also true of `usage` plans that bill usage.
*/
kind: PlanKind;
/** Recurring fee, in cents (0 for free / usage plans). */
recurringFeeCents: number;
/** Billing cadence for the recurring fee + metered usage — `"month"`
* (default) or `"year"` (annual). Lets a pricing card render "$X/yr" vs
* "$X/mo" and badge annual tiers. Defaults to `"month"` when the wire DTO
* omits it (the platform omits the key for monthly plans). */
billingInterval: "month" | "year";
/** ISO 4217 currency of every money field on the plan. REQUIRED in the
* normalized model — defaults to `"USD"` when the wire DTO omits it (the
* USD-only platform omits the key today). */
currency: string;
/** Free-trial length in days (0 = no trial). */
trialDays: number;
/** Optional monthly spend cap, in cents. */
maxMonthlySpendCents: number | null;
/** Optional minimum monthly spend floor, in cents. */
minMonthlySpendCents: number | null;
/** Structural metered dimensions (no money). Empty for non-metered plans. */
meters: PlanMeter[];
/** Quota + rate-limit rules. Month-window rules are the included allowances. */
limits: PlanLimit[];
/** Optional builder-authored feature bullets shown on the plan card. */
planDetails: string[];
/** Control-plane resource limits — `key → maxCount` caps (webhooks: 5)
* such as api_keys or webhooks. Empty when the
* plan declares none. */
resourceLimits: Record<string, number>;
/**
* The plan's PUBLIC catalog terms for metered usage — the price list a buyer
* needs to compare plans, projected by Core from the served commercial
* release. `null` when the plan binds no catalog, when the served release
* carries no matching pricing policy, or when the builder declared
* `fs.disclosure.opaque`; card surfaces fall back to "priced per the
* catalog" and a docs pointer in that case.
*
* This is the only place on the SDK's plan model where per-unit money lives,
* and it is NOT an exception to the rule the rest of this module states: a
* pricing catalog is a PUBLISHED commerce term the builder authored for
* everyone, whereas a subscriber's rated usage, funding draw-down and
* projected bill remain exclusive to Core's bill preview. The SDK still
* derives NO money: it renders these rates, it never multiplies them by a
* usage count.
*/
pricingDisplay: PlanPricingDisplay | null;
}
Funding that pays for rated usage before anything is owed.
Declaration source: packages/farthershore-js/dist/types.d.ts#L232.
export interface PlanFunding {
kind: "included" | "promo" | "referral" | "prepaid";
/** Face value in minor units of {@link PlanPricingDisplay.currency}. */
amountMinor: number;
/** Whether the bucket refreshes each billing period. */
recurs: boolean;
/** The builder's authored marketing framing: the bucket is `factor`x of a
* `baseMinor` base. The base is `amountMinor / factor` by construction, so
* the label cannot misstate the allowance. */
display: {
kind: "multiplier";
factor: number;
baseMinor: number;
} | null;
}
The builder's DECLARED plan kind (`plan.kind.*` in the Business SDK):
`free` | `flat` | `usage` | `prepaid` | `hybrid` | `trial` | `custom`.
Every card decision (badge, picker, hiding the free floor) reads it —
nothing is inferred from shape.
Declaration source: packages/farthershore-js/dist/types.d.ts#L108.
export type PlanKind = PlanKindWire__a95f9171680c;
Presentation facts for a DECLARED plan kind — the ONE label map every
surface (SDK `<PlansTable>`, portal `/pricing`, dashboard plan list) reads,
so a plan never shows two different kind labels across screens.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L16.
export interface PlanKindDescription {
/** The declared kind, verbatim. */
kind: PlanKind;
/** Short human label for a badge / chip ("Subscription + usage"). */
label: string;
/** True when this kind bills consumption through a commerce usage-pricing
* binding (`usage` / `prepaid` / `hybrid` / `custom`) — money for that
* usage surfaces ONLY through the bill preview / invoice, never the plan.
* `free` / `flat` / `trial` ration (limits) instead. Mirrors contracts'
* `isUsageBilledPlanKind`; the SDK cannot import contracts. */
billsUsage: boolean;
}
A named rate-limit / quota rule on a plan. `window.name === "month"` rules
are the included-quota allowances the usage card renders against.
Declaration source: packages/farthershore-js/dist/types.d.ts#L111.
export interface PlanLimit {
dimension: string;
window: {
type: "named";
name: string;
} | {
type: "custom";
seconds: number;
};
capacity: number;
enforcement?: "enforce" | "track";
}
A structural metered dimension on a plan — `{ dimension, kind? }`, NO
money. Rates, allowances, and the projected bill come from the bill-preview
API ({@link BillPreview}), never from the plan. Wire-faithful — the public
`PlanMeter` name re-exports the codegenned `PlanMeterWire`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L103.
export type PlanMeter = PlanMeterWire__47c3d2492e8a;
Structured price presentation for a plan — the single source of truth for
how every surface headlines a plan's price. See {@link presentPlanPrice}.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L36.
export interface PlanPricePresentation {
/** Headline string: the exact recurring fee ("$19.99") when the plan
* carries one, else a kind label — "Free" (free tier), "Usage-based"
* (`usage` / `hybrid` with no fee), "Prepaid", "Free trial", "Custom".
* NEVER rounds dollars — a $19.99 plan presents "$19.99", not "$19". */
headline: string;
/** Billing-cadence suffix for a fee-bearing plan: "/mo" | "/yr", from the
* plan's real `billingInterval` (absent-on-wire defaults to month).
* Omitted when there is no recurring fee. */
cadenceSuffix?: "/mo" | "/yr";
/** The plan's DECLARED kind, verbatim (`plan.kind`). */
kind: PlanKind;
/** "N-day free trial", when the plan carries a trial. */
trialNote?: string;
/** Spend guardrails: "$N/month minimum" and/or "$N/month cap". */
spendNotes?: string[];
}
PUBLIC commerce terms for a plan's metered usage.
Declaration source: packages/farthershore-js/dist/types.d.ts#L248.
export interface PlanPricingDisplay {
/** The pricing policy key the plan's `usagePricing` binds. */
pricingPolicyKey: string;
/** Meter the policy rates. */
meterKey: string;
/** ISO 4217 currency of every amount below. */
currency: string;
/** How the plan binds the catalog. `fixed_version` plans pin `version`. */
binding: {
kind: "current" | "current_with_contract_terms" | "fixed_version";
version: number | null;
};
/** Rates in deterministic precedence order, most specific first. */
rules: PricingRule[];
/** Funding buckets declared on the plan, in authored order. */
funding: PlanFunding[];
/** What happens when funding runs out: `block` stops requests, `overage`
* keeps serving at the catalog, `prepaid` is the wallet shape. */
exhaustion: "block" | "overage" | "prepaid" | null;
}
Public export PlansResource.
Declaration source: packages/farthershore-js/dist/resources/plans.d.ts#L61.
export interface PlansResource {
/** The product's available plans (resolved via bootstrap). Empty when the
* product has no published, self-serve plans. */
list(): Promise<Plan[]>;
/** The currently-purchasable plan versions for the signed-in subscriber
* (including their pinned plan version), each with the `offerFingerprint`
* to echo back at `subscribe()` for price-change consent. Unlike `list()`,
* this is a live core read (not bootstrap-cached). */
getPlanOffers(): Promise<PlanOffer__5ab47cb32b7d[]>;
/** Start checkout for a plan. Paid → `{ url }` (navigate to Stripe). Free →
* `{ subscriber }` (activated directly). Pass `offerFingerprint` (from
* `getPlanOffers()`) to fail 409 PLAN_OFFER_CHANGED on a stale price. */
subscribe(input: SubscribeInput): Promise<SubscribeResult>;
/** The dashboard onboarding path (`POST /onboarding`) the SSR portal's
* onboarding view uses. Differs from `subscribe()`: paid plans return
* `checkoutUrl` (not `url`), and free activations may include a one-time
* `autoApiKey` (drives the auto-created-key banner). */
startOnboarding(input?: StartOnboardingInput): Promise<OnboardingResult>;
}
A catalog rate in currency-per-unit. Carries the EXACT reduced rational
alongside its decimal projection because rates like 1/3 have no finite
decimal form — render `decimal`, compare `num`/`den`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L190.
export interface PricingAmount {
num: string;
den: string;
/** `num / den` long-divided; exact where the expansion terminates. */
decimal: string;
/** True when `decimal` was truncated because the rational does not terminate. */
rounded: boolean;
}
One PUBLIC catalog rule, projected for display. `backendQuoted` rules are
never projected — a bound the backend quotes against is not a price.
Declaration source: packages/farthershore-js/dist/types.d.ts#L206.
export type PricingRule = {
/** Stable catalog-entry key — the builder's semantic rule id. */
key: string;
/** Measure this rule prices (`pages`, `tokens`). There is no per-measure
* display name anywhere in the commerce manifest, so the unit label a card
* shows is derived from this key. */
measurementKey: string;
/** Catalog-item namespace, when the rule is provider/model scoped. */
item: {
provider: string;
model: string;
modality?: string;
} | null;
/** Dimension conditions that select this rule (`mode = ocr`). */
where: Array<{
dimensionKey: string;
value: string;
}>;
} & ({
kind: "perUnit";
amount: PricingAmount;
} | {
kind: "graduated" | "volume";
tiers: PricingTier[];
});
One bracket of a tiered catalog rule. `upTo` is the inclusive cumulative
upper bound as a decimal string, `null` on the open-ended final tier.
Declaration source: packages/farthershore-js/dist/types.d.ts#L200.
export interface PricingTier {
upTo: string | null;
amount: PricingAmount;
}
Promo-code flavour on an applied subscriber promo. Mirrors the wire
`PromoCodeKind` (`percent_off` | `amount_off` | `free_months`); kept as an
open union so a producer-side addition doesn't break the typed read.
Declaration source: packages/farthershore-js/dist/types.d.ts#L812.
export type PromoCodeKind = "percent_off" | "amount_off" | "free_months" | (string & {});
Public export RateLimitLine.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L249.
export type RateLimitLine = {
text: string;
};
One derived-catalog entry (`GET /me/rbac/catalog`): the permissions a
product's routes make grantable, grouped by route subject. Never authored —
derived from the product's accepted spec.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1053.
export interface RbacCatalogEntry {
subject: string;
/** Optional display title for the subject. */
title?: string;
permissions: string[];
}
Org-facing Managed-RBAC management (FAR-698/FAR-700) — the portal-customer
`/me/rbac/*` surface. Org OWNER/ADMIN only; every method THROWS the
typed `FartherShoreApiError` rather than degrading, because the UI derives
section visibility from the error codes (`RBAC_NOT_ENABLED_BY_PRODUCT`,
`UNKNOWN_PERMISSION`). Everything here configures UX + minted-token claims;
the EDGE `permission` constraint is the security boundary — never treat
client-side gating as enforcement.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L65.
export interface RbacResource {
settings: {
/** Current org settings: `{ enabled, defaultRoleKey? }`. */
get(opts?: {
signal?: AbortSignal;
}): Promise<RbacSettings>;
/** Full-document replace. `enabled: true` seeds the editable
* Admin/Editor/Viewer templates (idempotent); omitted/null
* `defaultRoleKey` clears the default. */
update(input: {
enabled: boolean;
defaultRoleKey?: string | null;
}): Promise<RbacSettings>;
};
/** The DERIVED grantable-permission catalog (never authored) — grouped by
* route operation, in the `<route-id>:read|write` grammar. */
catalog(opts?: {
signal?: AbortSignal;
}): Promise<RbacCatalogEntry[]>;
roles: {
/** The org's role list (seeded templates + custom), sorted by key. */
list(opts?: {
signal?: AbortSignal;
}): Promise<RbacRole[]>;
/** Create a custom role. Permissions are validated against the catalog
* (400 `UNKNOWN_PERMISSION` naming offenders; `"*"` always grantable). */
create(input: {
roleKey: string;
name: string;
permissions: string[];
}): Promise<RbacRole>;
/** Rename and/or re-permission a role. */
update(roleKey: string, input: {
name?: string;
permissions?: string[];
}): Promise<RbacRole>;
/** Delete a role. Member assignments referencing it are left in place
* (resolution ignores stale keys); a matching `defaultRoleKey` is
* cleared server-side. */
remove(roleKey: string): Promise<void>;
};
/**
* Permissions Kernel Wave 6 — per-subscriber component gate policies. An
* org admin (team:manage_rbac) upserts one override row per component key;
* `requiredPermission: null` clears the permission override back to the
* component's default. Throws the typed `FartherShoreApiError` — a 409
* `GOVERNED_BY_CHANGE_SET` means change control governs these rows.
*/
componentPolicies: {
/** Upsert the override row for one component key
* (PUT /me/component-policies). */
update(input: {
componentKey: string;
requiredPermission: string | null;
gateMode: string;
}): Promise<ComponentAccessPolicyRow>;
};
/**
* Track T3 — Notion-minimal access requests. Any member files a request for a
* permission; owners/admins review the queue and approve (AUTO-GRANTS the
* permission onto the requester's direct grants) or deny.
*/
accessRequests: {
/** File a request for a permission. Idempotent on an open PENDING row for
* the same (requester, permission). Any authenticated member. */
create(input: {
permission: string;
note?: string;
}): Promise<AccessRequest__e4d3f89daefa>;
/** The request queue (OWNER/ADMIN): pending first, then resolved. */
list(opts?: {
signal?: AbortSignal;
}): Promise<AccessRequest__e4d3f89daefa[]>;
/** Approve (grants the permission) or deny a pending request. */
resolve(requestId: string, action: "approve" | "deny"): Promise<AccessRequest__e4d3f89daefa>;
};
}
One configurable role (`/me/rbac/roles`), template-seeded or custom.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1035.
export interface RbacRole {
roleKey: string;
name: string;
/** Permission strings in the `<subject>:read|write` grammar, or `"*"`. */
permissions: string[];
/** "ACCOUNT" rows are the membership-tier enforcement source: their
* permissions are editable but their identity is fixed — no rename,
* delete, default assignment, or credential binding. Absent ⇒ "CUSTOM". */
kind?: "CUSTOM" | "ACCOUNT";
/** ACCOUNT rows only: the full subscriber vocabulary — the editable
* option set (restoring a removed verb needs the catalog, not just the
* row's current grants). */
vocabulary?: string[];
createdAt?: string;
}
One assignable role, as listed on `GET /me/team` (`availableRoles`).
Declaration source: packages/farthershore-js/dist/types.d.ts#L1023.
export interface RbacRoleSummary {
roleKey: string;
name: string;
}
Org-level Managed-RBAC settings (`GET|PUT /me/rbac/settings`).
Declaration source: packages/farthershore-js/dist/types.d.ts#L1028.
export interface RbacSettings {
/** Whether role permissions are enforced for this org's user tokens. */
enabled: boolean;
/** Role auto-assigned to members with no explicit assignment. */
defaultRoleKey?: string;
}
Read `window.__FS_CONFIG__` (null outside the browser / when not injected).
Typed loosely on purpose — the payload crosses a version boundary (edge
worker vs bundled SDK), so every field stays optional.
Declaration source: packages/farthershore-js/dist/config.d.ts#L77.
export declare function readRuntimeConfig(): FsRuntimeConfig | null;
Poll `client.me()` (invalidating the read cache before each attempt) until the
subscriber lifecycle settles or the attempt budget is exhausted. Resolves with
`{ settled, subscriber, context, attempts }` — never rejects on a settle-miss
(the caller branches on `settled`). A `me()` throw IS surfaced.
Declaration source: packages/farthershore-js/dist/reconcile.d.ts#L33.
export declare function reconcileAfterCheckout(client: Pick<FartherShoreClient, "me" | "invalidate">, options?: ReconcileOptions): Promise<ReconcileResult>;
Public export ReconcileOptions.
Declaration source: packages/farthershore-js/dist/reconcile.d.ts#L3.
export interface ReconcileOptions {
/** Max number of `me()` reads before giving up. Default 6. */
maxAttempts?: number;
/** Base backoff delay in ms (doubles each attempt, capped at `maxDelayMs`).
* Default 600. */
baseDelayMs?: number;
/** Backoff ceiling in ms. Default 5000. */
maxDelayMs?: number;
/** Predicate deciding whether the lifecycle has settled. Default: ACTIVE or
* TRIALING. */
isSettled?: (subscriber: SubscriberDetail | null) => boolean;
/** Abort the poll loop early (e.g. component unmount). */
signal?: AbortSignal;
}
Public export ReconcileResult.
Declaration source: packages/farthershore-js/dist/reconcile.d.ts#L17.
export interface ReconcileResult {
/** True when the lifecycle settled within the attempt budget. */
settled: boolean;
/** The last subscriber detail read (the freshest snapshot, settled or not). */
subscriber: SubscriberDetail | null;
/** The full last `me()` context (null when signed out / no subscriber). */
context: SubscriberContext | null;
/** How many `me()` reads were issued. */
attempts: number;
}
Register a builder component's gate policy. Ids are namespaced
`custom:<slug>` (managed ids are also accepted, letting a host re-declare a
managed component's default gate). Throws on a malformed id — a typo'd
registration would otherwise silently resolve DENIED.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L67.
export declare function registerComponent(registration: ComponentRegistration): void;
Resolve the gate policy for `componentId`.
Per-field precedence: builder registration → subscriber overlay (`/me`) →
managed default → derived fail-closed default. Unknown ids and invalid
resolved permission sets resolve `{ unknown: true, gateMode: "denied" }` —
the gate renders AccessDenied, never the component.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L105.
export declare function resolveComponentPolicy(componentId: string, overlays?: readonly ComponentAccessPolicyRow[] | null): ResolvedComponentPolicy;
The resolved gate policy for one component id.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L73.
export interface ResolvedComponentPolicy {
componentId: string;
/** Render-gate permission; null ONLY when `presentational`. */
permission: string | null;
/** Every render permission that must pass. Sensitive components include
* their managed default as an AND-floor plus any stricter override. */
requiredPermissions: readonly string[];
/** Permission for the component's mutating affordances. */
writePermission: string;
/** How the component renders when the viewer lacks `permission`. */
gateMode: ComponentGateMode;
/** Where `gateMode` came from: an explicit host registration, a
* subscriber-org overlay, or the platform default. Hosts that wrap a
* component-gated surface (e.g. a route) must not force their own mode
* when the source is not `"default"` — the configured choice wins. */
gateModeSource: "registration" | "overlay" | "default";
/** Renders ungated (explicit flag only). */
presentational: boolean;
/** Whether the id is one of the contracts-owned sensitive components. */
sensitive: boolean;
/** True when the id or its resolved permission policy is invalid: render
* DENIED before evaluating any permission claim. */
unknown: boolean;
}
Public export ResourceLimitRow.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L347.
export type ResourceLimitRow = {
key: string;
label: string;
limit: number;
used: number | null;
warning: "approaching" | "exhausted" | null;
};
One resource's enforced cap and the caller's current usage.
Declaration source: packages/farthershore-js/dist/resources/entitlements.d.ts#L10.
export interface ResourceLimitUsage {
limit: number;
current: number;
}
Per-resource `{ limit, current }`. Undeclared resources are unlimited.
Declaration source: packages/farthershore-js/dist/resources/entitlements.d.ts#L15.
export type ResourceLimitUsageMap = Record<string, ResourceLimitUsage>;
One record of a declared resource, as owned and returned by core.
Declaration source: packages/farthershore-js/dist/resources/resources.d.ts#L10.
export interface ResourceRecord<TPayload = unknown> {
id: string;
resource: string;
payload: TPayload;
createdAt: string;
updatedAt: string;
}
A resource verb's options — the standard request init plus an optional
`subjectId` for SUBJECT-scoped resources (W5.4). When set, it's forwarded as
the `x-fs-subject-id` header so core keys the count on that subject.
Declaration source: packages/farthershore-js/dist/resources/resources.d.ts#L6.
export type ResourceRequestInit = RouteRequestInit & {
subjectId?: string;
};
Public export ResourcesResource.
Declaration source: packages/farthershore-js/dist/resources/resources.d.ts#L25.
export interface ResourcesResource<TPayload = unknown> {
/** List this subscriber's records of the resource. */
list(init?: ResourceRequestInit): Promise<ResourceRecord<TPayload>[]>;
/** Fetch one record by id. */
get(id: string, init?: ResourceRequestInit): Promise<ResourceRecord<TPayload>>;
/** Create a record. Throws `LimitExceededError` (402) at the plan cap. */
create(payload: TPayload, init?: ResourceRequestInit): Promise<ResourceRecord<TPayload>>;
/** Replace a record's payload. */
update(id: string, payload: TPayload, init?: ResourceRequestInit): Promise<ResourceRecord<TPayload>>;
/** Delete a record (frees one unit of the quota). */
delete(id: string, init?: ResourceRequestInit): Promise<void>;
/** Authoritative `{ count, cap }` for this resource on the caller's
* subscription (W5.2). Reads core (the system of record), so it works for
* backend-managed resources the SDK can't `list()`. Signed-out / no
* subscription → `{ count: 0, cap: null }`. */
count(init?: {
signal?: AbortSignal;
subjectId?: string;
}): Promise<ResourceUsage>;
}
The authoritative current count + cap for a resource on the caller's
subscription (W5.2). `count` is the system-of-record count read from core;
`cap` is the per-plan ceiling (a number, or `null` when uncapped/unlimited).
Works even for Model-1 backend-managed resources the SDK can't `list()`.
Declaration source: packages/farthershore-js/dist/resources/resources.d.ts#L21.
export interface ResourceUsage {
count: number;
cap: number | null;
}
`POST /me/restore` — the platform performs the un-cancel: a paid sub's
scheduled `cancel_at_period_end` is lifted on the provider, a free
CANCELLED sub is flipped back to ACTIVE inline. Like cancel, there is no
hosted-page hand-off — the caller gets the subscription back, and
`cancelAtPeriodEnd` on it is what the platform read AFTER the un-cancel.
A `false` here is the proof the notice should be gone.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1134.
export interface RestoreSubscriptionResult {
subscription?: unknown;
/** The platform's post-restore reading. `false` is the success signal; the
* field is `null` only when Core's response carried no subscription state
* to read it from — never guessed. */
cancelAtPeriodEnd: boolean | null;
raw: unknown;
}
Run `op` with a bounded wait-then-retry on a throttle/limit deny (T7).
Retries ONLY while {@link isRetryable } holds for the thrown error — which, for
a deny carrying an `_fs` envelope, is driven by `_fs.reaction`/`retrySafe`
(T10), NEVER by raw status inference. So a `concurrency_limit_exceeded` 429
(reaction `queue`, retried via `retrySafe:true` — NOT the reaction) is retried
until a slot frees, while a `spend`/`upgrade` deny is rethrown immediately.
Honors `Retry-After`; caps
attempts and per-wait delay; rethrows the LAST error once the cap is hit.
Declaration source: packages/farthershore-js/dist/retry-throttle.d.ts#L42.
export declare function retryWhileThrottled<T>(op: () => Promise<T>, options?: RetryWhileThrottledOptions): Promise<T>;
Options for {@link retryWhileThrottled}. All optional — the defaults give a
sensible bounded wait-for-slot policy out of the box.
Declaration source: packages/farthershore-js/dist/retry-throttle.d.ts#L4.
export interface RetryWhileThrottledOptions {
/** Total attempts INCLUDING the first (so `3` = up to 2 retries). Default 4.
* Floored at 1. */
maxAttempts?: number;
/** Base for the exponential backoff (ms) used when no `Retry-After` is
* present on the thrown error. Default 300. */
baseDelayMs?: number;
/** Ceiling (ms) on any single wait — caps both a `Retry-After` hint and the
* exponential backoff so a long/hostile hint can't hang the caller. Default
* 20000. */
maxDelayMs?: number;
/** Injectable delay primitive (tests pass a no-op; default is a timer-based
* sleep). SSR-safe — `setTimeout` exists in Node + the browser. */
sleep?: (ms: number) => Promise<void>;
}
Public export RouteRequestInit.
Declaration source: packages/farthershore-js/dist/resources/route.d.ts#L2.
export type RouteRequestInit = RequestInit & {
apiKey?: string;
};
Public export RouteResource.
Declaration source: packages/farthershore-js/dist/resources/route.d.ts#L15.
export interface RouteResource {
/** Raw gateway call — returns the `Response` for any content type. */
fetch(path: string, init?: RouteRequestInit): Promise<Response>;
/** `GET path` → parsed JSON. */
get<T = unknown>(path: string, init?: RouteRequestInit): Promise<T>;
/** `GET path` → parsed JSON PLUS the `X-RateLimit-*` snapshot read off the
* live response before it's discarded (W8.5). Also publishes the snapshot to
* `useRouteRateLimit()`. */
getWithMeta<T = unknown>(path: string, init?: RouteRequestInit): Promise<RouteResponseMeta<T>>;
/** `POST path` with a JSON body → parsed JSON. */
post<T = unknown>(path: string, body?: unknown, init?: RouteRequestInit): Promise<T>;
/** `PUT path` with a JSON body → parsed JSON. */
put<T = unknown>(path: string, body?: unknown, init?: RouteRequestInit): Promise<T>;
/** `PATCH path` with a JSON body → parsed JSON. */
patch<T = unknown>(path: string, body?: unknown, init?: RouteRequestInit): Promise<T>;
/** `DELETE path` → parsed JSON (or undefined on 204). */
delete<T = void>(path: string, init?: RouteRequestInit): Promise<T>;
}
A `GET` response plus the throttle snapshot read off its `X-RateLimit-*`
headers (W8.5). `remaining`/`resetAt` are null when the gateway didn't send
them. The same snapshot also updates `useRouteRateLimit()`.
Declaration source: packages/farthershore-js/dist/resources/route.d.ts#L8.
export interface RouteResponseMeta<T> {
data: T;
rateLimit: {
remaining: number | null;
resetAt: Date | null;
};
}
Build a CSV string from a header + already-escaped-or-raw row matrix, escaping
every cell through {@link escapeCsvCell} (so the formula-injection guard
applies uniformly). The generic counterpart to {@link usageToCsv} — used by
the audit-log export, which has its own columns.
Declaration source: packages/farthershore-js/dist/csv.d.ts#L37.
export declare function rowsToCsv(header: string[], rows: unknown[][]): string;
FAITHFUL COPY of contracts/evolution `SENSITIVE_COMPONENT_KEYS`.
The SDK cannot import contracts at runtime, so parity is pinned in test/.
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L30.
declare const SENSITIVE_COMPONENT_KEYS: readonly ["audit_log", "api_keys_panel", "team_panel"];
Repeatable metadata for a managed, organization-owned service account.
Declaration source: packages/farthershore-js/dist/types.d.ts#L425.
export interface ServiceAccount {
id: string;
name: string;
state: ServiceAccountProvisioningState;
requestedPermissions: string[];
grantedPermissions: string[];
createdBy: string | null;
approvedBy: string | null;
createdAt: string;
activatedAt: string | null;
revokedAt: string | null;
usageLimits?: ServiceAccountUsageLimitRequest__f255b800fa4e[];
credentialApprovals: ServiceAccountApprovalSummary[];
}
Whether an approval creates a new account or replaces an active grant snapshot.
Declaration source: packages/farthershore-js/dist/types.d.ts#L382.
export type ServiceAccountApprovalOperation = "CREATE" | "UPDATE";
Public export ServiceAccountApprovalResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L508.
export type ServiceAccountApprovalResponse = ApprovedServiceAccountCreateResponse | ApprovedServiceAccountUpdateResponse;
Public export ServiceAccountApprovalsResource.
Declaration source: packages/farthershore-js/dist/resources/keys.d.ts#L37.
export interface ServiceAccountApprovalsResource {
/** Approval requests this signed-in member is currently eligible to decide. */
list(opts?: {
signal?: AbortSignal;
limit?: number;
offset?: number;
}): Promise<OffsetPage<PendingServiceAccountApproval>>;
/** Approve the complete request or an explicitly trimmed subset. */
approve(approvalId: string, input?: ApproveServiceAccountInput): Promise<ServiceAccountApprovalResponse>;
/** Deny a pending request without minting or widening any credential. */
deny(approvalId: string): Promise<ServiceAccountDenyResponse>;
}
Public export ServiceAccountApprovalSummary.
Declaration source: packages/farthershore-js/dist/types.d.ts#L383.
export interface ServiceAccountApprovalSummary {
id: string;
operation: ServiceAccountApprovalOperation;
requestedBy: string;
requestedPermissions: string[];
excessPermissions: string[];
createdAt: string;
}
Public export ServiceAccountCreateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L475.
export type ServiceAccountCreateResponse = ActiveServiceAccountCreateResponse | PendingServiceAccountCreateResponse;
Public export ServiceAccountDenyResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L518.
export interface ServiceAccountDenyResponse {
status: "DENIED";
}
Durable provisioning state for an organization-owned service account.
Declaration source: packages/farthershore-js/dist/types.d.ts#L380.
export type ServiceAccountProvisioningState = "PENDING" | "ACTIVE";
Public export ServiceAccountRotationResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L509.
export interface ServiceAccountRotationResponse {
status: "ACTIVE";
serviceAccountId: string;
revokedKeyId: string;
apiKeyId: string;
/** One-time replacement secret. */
plaintext: string;
grantedPermissions: string[];
}
Public export ServiceAccountsResource.
Declaration source: packages/farthershore-js/dist/resources/keys.d.ts#L53.
export interface ServiceAccountsResource {
/** List managed accounts, including PENDING rows with no credential material. */
list(opts?: {
signal?: AbortSignal;
limit?: number;
offset?: number;
}): Promise<OffsetPage<ServiceAccount>>;
/** Create immediately when covered, otherwise return a strict PENDING response. */
create(input: CreateServiceAccountInput, options?: ServiceAccountMutationOptions__2dee3eb4c17c): Promise<ServiceAccountCreateResponse>;
/** Replace the frozen grant snapshot or create a pending UPDATE request. */
update(serviceAccountId: string, input: UpdateServiceAccountInput, options?: ServiceAccountMutationOptions__2dee3eb4c17c): Promise<ServiceAccountUpdateResponse>;
/** Rotate the account credential and return the replacement secret once. */
rotate(serviceAccountId: string): Promise<ServiceAccountRotationResponse>;
/** Revoke the account and every active credential attached to it. */
revoke(serviceAccountId: string): Promise<void>;
readonly approvals: ServiceAccountApprovalsResource;
}
Public export ServiceAccountUpdateResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L492.
export type ServiceAccountUpdateResponse = ActiveServiceAccountUpdateResponse | PendingServiceAccountUpdateResponse;
Public export Session.
Declaration source: packages/farthershore-js/dist/types.d.ts#L326.
export interface Session {
authenticated: boolean;
subscriber: Subscriber | null;
/** Verified browser-session identity. Present only for a server-owned test
* persona cookie; Clerk sessions expose their user through the Clerk bridge. */
authSession: PersonaAuthSession | null;
}
Result of {@link BillingResource.setSpendCap}: the stored cap (echo) + the
bumped subscription entitlement version (cache-bust signal).
Declaration source: packages/farthershore-js/dist/resources/billing.d.ts#L5.
export interface SpendCapResult {
/** The stored monthly spend cap in cents (null when cleared). */
maxMonthlySpendCents: number | null;
/** The subscription's entitlement version after the write, when returned. */
entitlementVersion?: number;
}
Input to `startOnboarding()`. Unlike direct checkout, the plan is optional:
omitting it asks Core to select the business's single declared zero-price
plan. This is the safest zero-price onboarding path because a client cannot
accidentally name a billable plan.
Declaration source: packages/farthershore-js/dist/resources/plans.d.ts#L27.
export interface StartOnboardingInput extends Omit<SubscribeInput, "compiledPlanId"> {
compiledPlanId?: string;
}
Public export StatusChip.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L294.
export interface StatusChip {
/** Sentence-case label (e.g. "Active", "Past due", "Cancels soon"). */
label: string;
tone: StatusChipTone;
}
Visual tone for a status chip. Maps onto the `fs-tag--*` modifier set.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L293.
export type StatusChipTone = "success" | "info" | "warning" | "danger" | "muted";
Input to `subscribe()`. `compiledPlanId` is the `Plan.id` (immutable
CompiledPlan pointer).
Declaration source: packages/farthershore-js/dist/resources/plans.d.ts#L5.
export interface SubscribeInput {
/** The plan to subscribe to — pass `plan.id`. */
compiledPlanId: string;
/** Owning org for org-owned subscriptions (forwarded as the
* `organizationId` query + header). */
organizationId?: string | null;
/** Where Stripe redirects after a successful paid checkout. */
successUrl?: string;
/** Where Stripe redirects if the subscriber abandons checkout. */
cancelUrl?: string;
/** OPTIONAL price-consent echo (E2 — Managed Stripe Price Integrity): the
* `offerFingerprint` from `getPlanOffers()`. When provided and the plan's
* economics changed since the offer was rendered, core rejects with
* 409 PLAN_OFFER_CHANGED (typed as `FartherShorePlanOfferChangedError`) and
* creates NO session — catch it, refetch offers, and re-present the price.
* Omit for today's unguarded behavior. */
offerFingerprint?: string;
}
Public export Subscriber.
Declaration source: packages/farthershore-js/dist/types.d.ts#L315.
export interface Subscriber {
/** Lifecycle status (e.g. ONBOARDING | ACTIVE | SUSPENDED). */
status: string | null;
/** Denormalized plan key for display. */
planKey: string | null;
/** Immutable CompiledPlan id currently active for this subscriber. */
compiledPlanId: string | null;
/** True only after the selected environment's gateway has the exact active
* subscription projection. */
gatewayReady?: boolean;
}
An active promotional code applied to a subscriber. Mirrors core's
`PortalSubscriberContext.subscriber.activePromo`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L815.
export interface SubscriberActivePromo {
id: string;
code: string;
kind: PromoCodeKind;
/** Discount magnitude (percent or cents, per `kind`), or null/absent. */
amount?: number | null;
/** How many billing periods the promo applies for. */
durationMonths: number;
/** ISO timestamp the promo stops applying, or null. */
activeUntil?: string | null;
/** ISO timestamp the promo was applied, or null. */
appliedAt?: string | null;
}
Full `GET /me` context: the subscriber (null = signed-in user has no
subscriber record for the selected org → onboarding) plus the
eligibility-scoped plan list (NOT identical to the public catalog).
Declaration source: packages/farthershore-js/dist/types.d.ts#L897.
export interface SubscriberContext {
subscriber: SubscriberDetail | null;
availablePlans: Plan[];
/**
* E1 — the subscriber's PINNED plan, resolved server-side from the
* subscription's pinned CompiledPlan version (NOT the catalog head — a
* pinned older version may not appear in `availablePlans` at all).
*
* Tri-state for old-Core back-compat:
* - `Plan` — resolved pinned plan.
* - `null` — Core resolved it: there IS no pinned plan (no
* subscription). Do NOT fall back to guessing.
* - `undefined` — the wire field was ABSENT (pre-E1 Core). Only here may
* a consumer fall back to matching `availablePlans` by
* `subscriber.compiledPlanId` (deprecated path).
*/
currentPlan?: Plan | null;
/** Managed-RBAC product-role keys assigned to the CALLER within the org
* (FAR-698/FAR-700). Server-resolved on `GET /me` — the same row-backed
* source the gateway-token mint uses; the SDK never decodes tokens.
* Empty for pre-RBAC responses. */
roles: string[];
/** The caller's resolved permission strings (`<subject>:read|write`
* grammar). `["*"]` means Managed RBAC is off or the caller is an OWNER;
* personal-org members receive the same resolved permission sets as team-org
* members. Client-side gating over these is UX ONLY — the gateway's
* `permission` constraint is the security boundary. */
permissions: string[];
/** Reviewed product permissions explicitly denied by the subscriber's
* effective roles. Present on current Core responses. */
deniedPermissions?: string[];
/** Current product permissions that were not reviewed by the effective
* roles and therefore inherit the safe product-evolution default of allow.
* Platform/account permissions are never included. */
unassignedProductPermissions?: string[];
/** Per-subscriber ComponentAccessPolicy override rows (Permissions Kernel,
* Wave 5) — `{componentKey, requiredPermission, gateMode}` as core emits
* them. Consumed by the SDK's component-policy resolver; `[]` when the
* subscriber has no overrides (or on older responses). */
componentAccessPolicies: ComponentAccessPolicyRow[];
/** Current legal acceptance state for this subscriber/org, when served by
* Core. Absent on older responses. */
legalConsent?: LegalConsentStatus__2c5f3ab016cd;
raw: unknown;
}
Rich subscriber detail from `GET /me` — superset of {@link Subscriber} with
the lifecycle/billing fields the account pages render. Extra Core fields ride
along untyped.
Declaration source: packages/farthershore-js/dist/types.d.ts#L859.
export interface SubscriberDetail {
id?: string;
status: string | null;
planKey: string | null;
compiledPlanId: string | null;
/** True only after the selected environment's gateway has the exact active
* subscription projection. */
gatewayReady?: boolean;
/** Resource limits on the subscriber's pinned plan, not the latest catalog. */
resourceLimits?: Record<string, number>;
/** Per-dimension meter map (`dimension → unit`) on the subscriber's PINNED
* compiled plan — the billing shape the subscriber is actually on. */
dimensions?: Record<string, number>;
/** The ordered list of meter dimensions the usage tab should display,
* authored by the pinned plan. `rules[].d` indexes into this array. */
displayDims?: string[];
/** Pinned-plan rate-limit / quota allowances (the source of truth for
* included quotas — see {@link SubscriberPinnedRule}). */
rules?: SubscriberPinnedRule__7b0d2ee36c4a[];
/** Stripe-driven lifecycle (e.g. ACTIVE | TRIALING | PAST_DUE | CANCELLED). */
subscriptionLifecycle?: string | null;
/** Stripe-synced trial end (ISO) — drives the trial banner countdown. */
trialEndsAt?: string | null;
/** True when a paid cancel is scheduled for period end ("Renew" un-schedules). */
cancelAtPeriodEnd?: boolean | null;
/** A scheduled plan transition (downgrades apply at period end). */
scheduledTransition?: SubscriberScheduledTransition | null;
/** An active promotional code applied to the subscription, when present. */
activePromo?: SubscriberActivePromo | null;
/** P-SPENDCAP-READ (W6.4) — the subscriber-set monthly spend cap, in cents,
* or null when none is set. STORED-not-ENFORCED today (held in
* `Subscription.customMetadata`, pending the rate-limit migration). */
maxMonthlySpendCents?: number | null;
[k: string]: unknown;
}
Result of `subscribe()`. For a PAID plan, `url` is the Stripe Checkout URL to
navigate to. For a FREE plan, there is no `url` — the subscriber was
activated directly and `subscriber` describes the new row.
Declaration source: packages/farthershore-js/dist/resources/plans.d.ts#L44.
export interface SubscribeResult {
/** Stripe Checkout URL (paid plans only). Undefined for free activations. */
url?: string;
/** The activated subscriber (free plans only). Undefined for paid checkout. */
subscriber?: {
id: string;
businessId?: string | null;
status: string;
};
/** Server-side checkout-attempt id, when returned. */
checkoutAttemptId?: string;
/** Best-effort initial API key minted on free-plan activation, when present. */
autoApiKey?: string;
/** Set when the subscriber activated but the first-key mint FAILED — surfaced
* (not swallowed) so the caller can prompt a manual key creation. */
autoApiKeyError?: AutoApiKeyError;
}
A scheduled plan transition on a subscriber. Mirrors core's
`PortalSubscriberContext.subscriber.scheduledTransition` — richer than
{@link SubscriptionScheduledTransition} (carries the resolved plan name +
type).
Declaration source: packages/farthershore-js/dist/types.d.ts#L832.
export interface SubscriberScheduledTransition {
compiledPlanId: string | null;
planName: string | null;
planType: string | null;
/** ISO timestamp the transition takes effect. */
effectiveAt: string;
/** Movement direction (`CANCEL` | `UPGRADE` | `DOWNGRADE` | `SIDEGRADE`),
* open to producer-side additions. */
kind: string;
}
The consumer's current subscription for this product. Mirrors core's
`PortalSubscriptionDto` (lifecycle + billing state + scheduled transition)
mapped to the SDK's camelCase domain convention. The widened fields degrade
to safe defaults when the wire DTO is lean (`null` / `false`).
Declaration source: packages/farthershore-js/dist/types.d.ts#L739.
export interface Subscription {
id: string;
/** Display lifecycle status (e.g. ACTIVE | TRIALING | PAST_DUE). Falls back
* across `status` / `lifecycle` on the wire. */
status: string;
planKey: string | null;
planName: string | null;
/** Owning product id, or null when absent on a lean DTO. */
businessId: string | null;
/** Immutable `CompiledPlan.id` currently active, or null. */
compiledPlanId: string | null;
/** Richer lifecycle string straight off the row (may equal `status`). */
lifecycle: string | null;
/** Payment health (`ok` | `past_due` | `incomplete` | …), or null when the
* DTO doesn't carry it (free subs). */
paymentHealth: string | null;
/** ISO start of the current billing period, or null. */
currentPeriodStart: string | null;
/** ISO end of the current billing period, or null. */
currentPeriodEnd: string | null;
/** True when a paid cancel is scheduled for period end. */
cancelAtPeriodEnd: boolean;
/** ISO trial end — drives the trial countdown. */
trialEndsAt: string | null;
/** ISO timestamp the subscription was canceled, or null. */
canceledAt: string | null;
/** A scheduled plan transition, or null when none is pending. */
scheduledTransition: SubscriptionScheduledTransition | null;
/** Whether the subscriber has a Stripe customer (can open the billing
* portal). Free subs that never touched Stripe are `false`. */
canManageInStripe: boolean;
/**
* Whether there is actually something here to cancel — SERVER-DECIDED.
*
* A subscription on a `free`-kind plan has no paid, Stripe-managed
* subscription behind it, so "cancel" has no meaning. The client cannot work
* this out on its own (the portal DTO always carries a real subscription id,
* so "nothing to cancel" looks identical to a lean wire body), which is why
* core answers it.
*
* `null` means the server did not say — treated as CANCELLABLE so an older
* core never strands a paying subscriber with no way to cancel.
*/
cancellable: boolean | null;
/** The full platform subscription DTO (large + evolving) for advanced reads. */
raw: unknown;
}
One org through which the user holds a subscription to this product.
Declaration source: packages/farthershore-js/dist/types.d.ts#L955.
export interface SubscriptionContext {
organizationId: string;
/** Org display name — matches core's wire field (`name`, NOT
* `organizationName`; see apps/core/src/routes/portal-customer/shared.ts). */
name?: string | null;
isDefault?: boolean;
/** Existing subscriber row for this business/org pair. A non-null value
* means this workspace already owns customer state for the product. */
subscriberId?: string | null;
/** Authoritative active-plan entitlement for the selected environment. */
hasEntitlement?: boolean;
[k: string]: unknown;
}
Public export SubscriptionContextsResult.
Declaration source: packages/farthershore-js/dist/types.d.ts#L968.
export interface SubscriptionContextsResult {
contexts: SubscriptionContext[];
defaultOrganizationId: string;
selectedOrganizationId: string | null;
}
A scheduled plan transition on a subscription (downgrades apply at period
end). Mirrors core's `PortalSubscriptionDto.scheduledTransition`.
Declaration source: packages/farthershore-js/dist/types.d.ts#L726.
export interface SubscriptionScheduledTransition {
/** Immutable `CompiledPlan.id` the subscription moves to, or null. */
compiledPlanId: string | null;
/** ISO timestamp the transition takes effect, or null. */
effectiveAt: string | null;
/** Movement direction (`CANCEL` | `UPGRADE` | `DOWNGRADE` | `SIDEGRADE`),
* open to producer-side additions. */
kind: string | null;
}
Team read result — `ok:false` (with `error`) drives the read-only banner.
Declaration source: packages/farthershore-js/dist/types.d.ts#L990.
export interface TeamListResult {
ok: boolean;
members: TeamMember[];
/** The org's assignable Managed-RBAC role list (FAR-698) — what the
* per-member role multi-select offers. Empty when RBAC is unused. */
availableRoles?: RbacRoleSummary[];
error?: string;
}
Public export TeamMember.
Declaration source: packages/farthershore-js/dist/types.d.ts#L974.
export interface TeamMember {
id: string;
userExternalId: string;
role: TeamRole;
/** Managed-RBAC product-role keys assigned to this member (FAR-698).
* Absent on pre-RBAC responses. */
businessRoleKeys?: string[];
/** Assigned keys whose role row no longer exists (deleted roles leave
* assignments in place — resolution ignores them). Drives the portal's
* stale-role warning. */
staleRoleKeys?: string[];
createdAt?: string;
updatedAt?: string;
[k: string]: unknown;
}
Public export TeamResource.
Declaration source: packages/farthershore-js/dist/resources/account.d.ts#L13.
export interface TeamResource {
/** Team members on the current subscription. A failed read surfaces
* `{ ok:false, error }` (drives the SSR portal's read-only banner) — NOT a
* silent empty list. */
list(opts?: {
signal?: AbortSignal;
}): Promise<TeamListResult>;
/**
* Track T2 — subscriber-team invitations. Managers (OWNER/ADMIN) invite by
* email; the invitee accepts with the emailed token. Each method THROWS the
* typed `FartherShoreApiError` on validation/authz failure.
*/
invites: {
/** Pending invitations (OWNER/ADMIN). */
list(opts?: {
signal?: AbortSignal;
}): Promise<TeamInvitation__f9f120bf906d[]>;
/** Create an invitation. `role` defaults to VIEWER; `businessRoleKeys` must
* be a subset of the caller's own permissions (403 otherwise). Returns the
* invitation plus the one-time raw token. */
create(input: {
email: string;
role?: TeamRole;
businessRoleKeys?: string[];
}): Promise<TeamInvitationCreated__c157ef151993>;
/** Revoke a pending invitation. */
revoke(invitationId: string): Promise<void>;
/** Accept an invitation with its token. The signed-in user's email must
* match the invite (403 mismatch; 409 expired/already-used). */
accept(token: string): Promise<TeamInvitationAccepted__11c705c559ac>;
};
updateRole(membershipId: string, role: TeamRole): Promise<TeamMember>;
remove(membershipId: string): Promise<void>;
/**
* Set-replace a member's Managed-RBAC product-role assignment (FAR-698):
* the given list becomes the member's full assignment; `[]` clears it.
* Every key must reference an existing role. Throws the typed
* `FartherShoreApiError` on validation/authz failures.
* Client-side role gating is UX only; the gateway's `permission`
* constraint is the security boundary.
*/
assignRoles(membershipId: string, roles: string[]): Promise<TeamMember>;
}
Public export TeamRole.
Declaration source: packages/farthershore-js/dist/types.d.ts#L973.
export type TeamRole = "OWNER" | "ADMIN" | "VIEWER";
Returns the current session bearer token (Clerk session JWT or persona JWT),
or null/undefined when signed out. May be async (e.g. Clerk's getToken).
Declaration source: packages/farthershore-js/dist/config.d.ts#L80.
export type TokenProvider = () => string | null | undefined | Promise<string | null | undefined>;
Public export TransparentBillPreview.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1257.
export interface TransparentBillPreview {
currency: string;
disclosure: "transparent";
/** The plan's recurring fee, in cents. */
recurringFeeCents: number;
/** Per-rating-window engine totals. */
windows: BillPreviewWindow[];
totals: {
/** Nanodollars, decimal strings (null = unavailable). */
ratedNanos: NanosAmount;
fundedNanos: NanosAmount;
receivableNanos: NanosAmount;
};
allowances: BillPreviewAllowance[];
/** All-zero counts mean `totals` IS the whole bill. */
usageRating: BillPreviewUsageRating__fb184ad4d633;
}
Remove a registration (host teardown / tests).
Declaration source: packages/farthershore-js/dist/component-policy.d.ts#L69.
export declare function unregisterComponent(id: string): void;
Public export UpdateServiceAccountInput.
Declaration source: packages/farthershore-js/dist/types.d.ts#L447.
export interface UpdateServiceAccountInput {
requestedPermissions?: NonEmptyPermissionList__ca911cbb6fa0;
usageLimit?: ServiceAccountUsageLimitRequest__f255b800fa4e | null;
}
Strict PUT body. Scope, subject, and quantity are immutable; at least one
value or mode/threshold field is required.
Declaration source: packages/farthershore-js/dist/types.d.ts#L637.
export type UpdateUsageLimitInput = (UsageLimitUpdateValue__e8f19d3e563b & UsageLimitUpdateMode__0a6925ca669e) | (UsageLimitNoUpdateValue__cd3ce2b61e4f & UsageLimitExplicitUpdateMode__577df72501b7) | (UsageLimitNoUpdateValue__cd3ce2b61e4f & {
mode?: never;
notifyAtPct: number | null;
});
The CSV columns the usage export emits — mirrors the {@link UsageEvent}
shape the SSR portal / dev-portal-template exported. `requests` is the native
meter.
Declaration source: packages/farthershore-js/dist/csv.d.ts#L5.
declare const USAGE_CSV_HEADER = "timestamp,operation,status,status_code,requests,tokens,latency_ms";
Public, contracts-free projection of the Stage 1 portal usage-limit DTOs.
Exact parity is pinned in `test/usage-limits.test.ts`; the private contracts
workspace package must never leak into this published SDK's declarations.
Declaration source: packages/farthershore-js/dist/types.d.ts#L546.
declare const USAGE_LIMIT_SCOPES: readonly ["ORG", "MEMBER", "SERVICE_ACCOUNT"];
Public export USAGE_LIMIT_STRATEGIES.
Declaration source: packages/farthershore-js/dist/types.d.ts#L553.
declare const USAGE_LIMIT_STRATEGIES: readonly ["fixed_window", "sliding_window"];
Public export USAGE_TRAFFIC_CLASSES.
Declaration source: packages/farthershore-js/dist/types.d.ts#L650.
declare const USAGE_TRAFFIC_CLASSES: readonly ["customer_operation", "control_plane", "admin_internal", "background_job", "webhook", "healthcheck", "unclassified"];
Whether usage is billed as a pure request COUNT or weighted USAGE. Drives the
meter label ("Requests" vs "Usage"); computed server-side.
Declaration source: packages/farthershore-js/dist/types.d.ts#L649.
export type UsageBillingBasis = "requests" | "usage";
Public export UsageChargeableOutcomes.
Declaration source: packages/farthershore-js/dist/types.d.ts#L654.
export type UsageChargeableOutcomes = "success_only" | "success_and_partial" | "attempted" | "trusted_actual_usage_only";
Public export UsageDisplay.
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L239.
export interface UsageDisplay {
label: string;
value: string;
progress: {
used: number;
total: number;
} | null;
breakdown: string | null;
detail: string;
}
Public export UsageEvent.
Declaration source: packages/farthershore-js/dist/types.d.ts#L679.
export interface UsageEvent {
id: string;
timestamp: string;
operation: string;
apiKeyPrefix: string | null;
statusCode: number | null;
status: "success" | "error";
/** Event kind (e.g. "api"); shown as the row Type. */
type: string | null;
latencyMs: number | null;
/** Canonical per-event meter values, keyed by product-declared meter. */
dimensions: UsageEventDimensions__f3dde72e4b29;
/** Compatibility aliases for common legacy portal displays. */
requests: number | null;
tokens: number | null;
/** Advisory UsagePolicy state confirmed or relayed by the gateway/core. The
* frontend decides nothing from this; it is only for rendering stale-tolerant
* labels, cooldowns, and prompts. */
usagePolicy?: UsagePolicyAdvisory;
}
Public export UsageLimit.
Declaration source: packages/farthershore-js/dist/types.d.ts#L580.
export type UsageLimit = UsageLimitSubject & UsageLimitValue & {
id: string;
quantity: string;
mode: UsageLimitMode;
period: "BILLING_PERIOD";
/** Present only for NOTIFY rows. */
notifyAtPct?: number;
ceiling: UsageLimitCeiling;
/** Present when the edge accounts this limit on a non-default window. */
effectiveWindow?: UsageLimitEffectiveWindow;
createdBy: string | null;
createdAt: string;
updatedAt: string;
};
Public export UsageLimitCeiling.
Declaration source: packages/farthershore-js/dist/types.d.ts#L549.
export interface UsageLimitCeiling {
limitUnits?: number;
limitCents?: number;
}
Public export UsageLimitDeleteResult.
Declaration source: packages/farthershore-js/dist/types.d.ts#L641.
export interface UsageLimitDeleteResult {
id: string;
deleted: true;
}
READ-ONLY: how the limit is actually accounted at the edge. Builder-owned
(inherited from the plan's own rule for the dimension); a `sliding_window`
makes the ceiling a rolling horizon of the period's length instead of one
that resets at the period boundary. Never writable by the subscriber.
Declaration source: packages/farthershore-js/dist/types.d.ts#L559.
export interface UsageLimitEffectiveWindow {
strategy: UsageLimitStrategy;
periodSeconds: number;
}
Public export UsageLimitListResponse.
Declaration source: packages/farthershore-js/dist/types.d.ts#L594.
export type UsageLimitListResponse = OffsetPage<UsageLimit>;
Public export UsageLimitMode.
Declaration source: packages/farthershore-js/dist/types.d.ts#L548.
export type UsageLimitMode = "BLOCK" | "NOTIFY";
Public export UsageLimitProfile.
Declaration source: packages/farthershore-js/dist/types.d.ts#L653.
export type UsageLimitProfile = "customer_usage" | "business_capacity" | "control_plane" | "admin_internal" | "platform_abuse_only" | "healthcheck" | "none";
Public export UsageLimitScope.
Declaration source: packages/farthershore-js/dist/types.d.ts#L547.
export type UsageLimitScope = (typeof USAGE_LIMIT_SCOPES)[number];
Public export UsageLimitsResource.
Declaration source: packages/farthershore-js/dist/resources/usage-limits.d.ts#L3.
export interface UsageLimitsResource {
/** List the current subscriber organization's visible per-actor limits.
* `options.signal` is accepted for source compatibility but does not cancel
* the shared cached fetch; the cache owns the request lifecycle. */
list(options?: {
signal?: AbortSignal;
limit?: number;
offset?: number;
}): Promise<UsageLimitListResponse>;
/** Create a subscriber-authored usage limit. */
create(input: CreateUsageLimitInput): Promise<UsageLimit>;
/** Update mutable value, mode, or threshold fields. */
update(limitId: string, input: UpdateUsageLimitInput): Promise<UsageLimit>;
/** Permanently remove a subscriber-authored usage limit. */
delete(limitId: string): Promise<UsageLimitDeleteResult>;
}
Public export UsageLimitStrategy.
Declaration source: packages/farthershore-js/dist/types.d.ts#L554.
export type UsageLimitStrategy = (typeof USAGE_LIMIT_STRATEGIES)[number];
Public export UsageLimitSubject.
Declaration source: packages/farthershore-js/dist/types.d.ts#L570.
export type UsageLimitSubject = {
scope: "ORG";
subjectId?: never;
} | {
scope: "MEMBER";
subjectId: string;
} | {
scope: "SERVICE_ACCOUNT";
subjectId: string;
};
Public export UsageLimitValue.
Declaration source: packages/farthershore-js/dist/types.d.ts#L563.
export type UsageLimitValue = {
limitUnits: number;
limitCents?: never;
} | {
limitCents: number;
limitUnits?: never;
};
Public export UsagePolicyAdvisory.
Declaration source: packages/farthershore-js/dist/types.d.ts#L655.
export interface UsagePolicyAdvisory {
/** Gateway-resolved policy id, when the usage payload includes one. */
usagePolicyId: string | null;
/** Known traffic class; null when a newer gateway sends a class this SDK
* does not know yet. See `unknownTrafficClass` for the preserved raw value. */
trafficClass: UsageTrafficClass | null;
unknownTrafficClass?: string;
policySource: UsagePolicySource | null;
limitProfile: UsageLimitProfile | null;
customerBillable: boolean | null;
providerCostTracked: boolean | null;
chargeableOutcomes: UsageChargeableOutcomes | null;
meterKey: string | null;
cooldownResetAt: number | null;
retryAfterSeconds: number | null;
freeButLimited: boolean;
providerCost: boolean;
upgradePrompt: boolean;
creditPrompt: boolean;
genericMessage: string;
/** Raw gateway/core policy fields. Preserved for forward-compatible UIs and
* debugging; advisory only and never an enforcement input. */
raw: Record<string, unknown>;
}
Public export UsagePolicySource.
Declaration source: packages/farthershore-js/dist/types.d.ts#L652.
export type UsagePolicySource = "declared" | "inherited" | "defaulted" | "inferred";
Public export UsageRange.
Declaration source: packages/farthershore-js/dist/resources/usage.d.ts#L3.
export interface UsageRange {
from?: string;
to?: string;
}
Public export UsageResource.
Declaration source: packages/farthershore-js/dist/resources/usage.d.ts#L7.
export interface UsageResource {
/** Dimension → total for the period (requests/tokens/computeMs/dollars…).
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle); the read is unmount-safe
* via the hook's active-flag and bounded by the cache TTL. */
summary(range?: UsageRange, opts?: {
signal?: AbortSignal;
}): Promise<UsageSummary>;
/** The most-recent usage events (platform caps this list).
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle); the read is unmount-safe
* via the hook's active-flag and bounded by the cache TTL. */
events(range?: UsageRange, opts?: {
signal?: AbortSignal;
}): Promise<UsageEvent[]>;
/** Everything in one round-trip: per-dimension totals + recent events + the
* billing basis (the "Requests" vs "Usage" meter-label hint).
*
* `opts.signal` is accepted for source-compat but does NOT cancel the shared
* cached fetch (the cache owns the fetch lifecycle); the read is unmount-safe
* via the hook's active-flag and bounded by the cache TTL. */
snapshot(range?: UsageRange, opts?: {
signal?: AbortSignal;
includeEvents?: boolean;
}): Promise<UsageSnapshot>;
}
A single round-trip's worth of usage: per-dimension totals, the recent
events, and the billing basis.
Declaration source: packages/farthershore-js/dist/types.d.ts#L701.
export interface UsageSnapshot {
summary: UsageSummary;
events: UsageEvent[];
billingBasis: UsageBillingBasis;
/** Whether `summary` is an EXACT total over the whole period (`true`, the
* DB-side aggregate) or an approximation from a bounded event sample
* (`false`). A `false` here means the UI should flag the figure as
* approximate. Defaults to `true` (additive — older Cores omit it). */
exact: boolean;
/** Number of usage events the `summary` total was computed from over the
* period. With `exact: true` this is the true event count; with
* `exact: false` it's the sampled (capped) count. */
sampledEvents: number;
/** ISO start of the period the `summary` covers (the resolved `from`), or
* null when the Core doesn't report it. */
periodStart: string | null;
/** ISO end of the period the `summary` covers (the resolved `to`), or null
* when the Core doesn't report it. */
periodEnd: string | null;
/** Aggregated advisory policy state from the freshest event in this snapshot.
* Null when no event carries policy metadata. */
usagePolicy: UsagePolicyAdvisory | null;
}
Public export UsageSummary.
Declaration source: packages/farthershore-js/dist/types.d.ts#L645.
export type UsageSummary = Record<string, number>;
Render a usage event list as a CSV string (header + one row per event), every
cell run through {@link escapeCsvCell}. Returns just the header line for an
empty list. Pure — a host turns the string into a download with a Blob (see
the `downloadUsageCsv` helper the components use).
Declaration source: packages/farthershore-js/dist/csv.d.ts#L30.
export declare function usageToCsv(events: UsageEvent[]): string;
Public export UsageTrafficClass.
Declaration source: packages/farthershore-js/dist/types.d.ts#L651.
export type UsageTrafficClass = (typeof USAGE_TRAFFIC_CLASSES)[number];
Reactions whose intent is explicitly "wait, then resend the same request".
Used only for documentation/intent — the actual gate is {@link isRetryable },
which reads the same `_fs.reaction`/`retrySafe` signal.
Declaration source: packages/farthershore-js/dist/retry-throttle.d.ts#L22.
declare const WAIT_THEN_RETRY_REACTIONS: ReadonlySet<FsLimitReaction__06a9e09be641>;
These declarations explain types reachable from the public exports above. They are source evidence, not supported package imports. Suffixed names are documentation identifiers that preserve distinct lexical bindings. Standard-library and third-party types (for example Promise, React and Zod) remain external boundaries; their implementation declarations are not expanded here.
Declaration source: packages/farthershore-js/dist/types.d.ts#L1061.
export interface AccessRequest__e4d3f89daefa {
id: string;
/** External identity id of the requesting member. */
requestedBy: string;
/** The requested permission (unified `<subject>:<verb>` grammar). */
permission: string;
note?: string | null;
/** PENDING | APPROVED | DENIED. */
status: string;
resolvedBy?: string | null;
resolvedAt?: string | null;
createdAt: string;
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L1251.
export interface BillPreviewUsageRating__fb184ad4d633 {
pendingEventCount: number;
unratableEventCount: number;
/** ISO instant of the oldest unaccounted event, or null when there is none. */
oldestUnratedServedAt: string | null;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L253.
export declare function buildDimensionBreakdown__f82446dddd7c(summary: Record<string, number>, meters: Meter[]): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L266.
export declare function buildMeterUsageRows__dd03e7a0a916(plan: Plan | null, summary: Record<string, number>, meters: Meter[], billingBasis?: UsageBillingBasis): MeterUsageRow[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L291.
export declare function buildPinnedMeterUsageRows__fd3dc232bb17(pinned: PinnedUsageDisplay | null | undefined, summary: Record<string, number>, meters: Meter[], billingBasis?: UsageBillingBasis): MeterUsageRow[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L254.
export declare function buildPrimaryUsage__a1cfc1e9cdb3(plan: Plan | null, summary: Record<string, number>, meters: Meter[], billingBasis?: UsageBillingBasis): UsageDisplay;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L255.
export declare function buildRateLimits__5220b52a303e(plan: Plan | null, meters: Meter[]): RateLimitLine[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L354.
export declare function buildResourceLimitRows__f08613820468(plan: Pick<Plan, "resourceLimits">, usage: ResourceLimitUsage__a25d6e733a8f): ResourceLimitRow[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L412.
export declare function catalogPricingLines__c7aab05ab71a(plan: Plan): string[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L380.
export declare function catalogRuleQualifier__43f6b05ea45d(rule: PricingRule): string;
Declaration source: packages/farthershore-js/dist/config.d.ts#L183.
export interface ClientContext__d9dbf3313290 {
/** Platform Core base URL. LAZY: resolved on read as explicit config >
* injected `window.__FS_CONFIG__` > the production platform default —
* never throws. Reading this property is what performs the lazy window
* read; never read it at module scope or client-construction time. */
readonly coreUrl: string;
/** Portal host identifying the product/env to Core. LAZY — see {@link
* coreUrl}; defaults to `location.host` in the browser, read on access. */
readonly portalHost: string | null;
businessId: string | null;
environmentId: string | null;
organizationId: string | null;
/**
* The organization selection before it is reconciled against subscription
* contexts. Unlike `organizationId`, undefined means no explicit selection;
* null is a durable request for the user's default subscription. Internal
* runtime state used by the React organization provider.
*/
organizationSelection?: string | null;
/** Subscribers notified when the imperative organization scope changes. */
organizationListeners: Set<() => void>;
/** Read-through cache backing `fs.prefetch.*` (see cache.ts). */
readCache: Map<string, ReadCacheEntry__ee67854da2b9>;
gatewayUrl: string | null;
apiKey: string | null;
/** Cached short-lived gateway context token for browser-session feature
* calls. Cleared whenever session/org scope changes. */
gatewayContextToken: {
token: string;
expiresAt: string;
cacheKey: string;
} | null;
/** In-flight context-token mint, keyed by cacheKey — SINGLE-FLIGHT coalescing
* so concurrent feature calls share ONE mint instead of stampeding Core
* (W6.3). Cleared as soon as the mint settles. Internal. */
gatewayContextTokenInflight: {
cacheKey: string;
promise: Promise<GatewayContextToken>;
} | null;
/** Explicit session bearer (for Clerk/advanced integrations), falling back
* to the configured `getToken` provider. Persona sessions are HttpOnly
* cookies and never enter JavaScript. */
sessionToken: string | null;
/** True after a cookie-authenticated Core request succeeds. This lets a
* later 401 trigger managed recovery without treating an anonymous first
* `/me` read as a lapsed session. Contains no credential. */
browserSessionAuthenticated: boolean;
getToken?: TokenProvider;
/** Runtime-installed token provider (e.g. the managed Clerk bridge inside
* `<FartherShoreRoot>`). Wins over `config.getToken`; an explicitly set
* `sessionToken` still wins over both. */
tokenProvider: TokenProvider | null;
fetch: FetchLike;
/** Resolved automatic-retry policy (defaults applied). */
retry: ResolvedRetryConfig__fe2336bea142;
/** Resolved global interceptors (all optional; default no-ops elsewhere). */
onError?: (err: unknown) => void;
onLimitExceeded?: (err: LimitExceededError) => void;
onUnauthorized?: (err: FartherShoreApiError) => void;
/** Runtime-installed 401 reaction (the managed auth layer's mid-session
* recovery), wired by `<FsAuthProvider>` via `setOnUnauthorized`. Fires AFTER
* the config-level `onUnauthorized`. Internal. */
onUnauthorizedManaged?: (err: FartherShoreApiError) => void;
/**
* LATCH: managed auth recovery has already fired for the CURRENT credential.
*
* The interceptor de-dupe is per-ERROR-OBJECT, which only collapses one
* logical failure surfacing through nested transports. A dashboard runs many
* independent reads concurrently, so a single lapsed session produces MANY
* distinct 401 errors — each firing its own recovery, each remounting the
* surface, each triggering a fresh round of reads. That feedback loop was
* measured at ~274 requests in 25s from ONE dashboard (~650/min against
* core's 100/min portal limit): the portal rate-limited itself.
*
* Recovery is a per-SESSION event, not a per-request one. Cleared whenever a
* new credential is installed, so a genuinely re-authed session can recover
* again.
*/
managedRecoveryLatched?: boolean;
/** Last `X-RateLimit-*` snapshot observed on a gateway response (W8.5) — fed
* by `fs.route.getWithMeta`, read by `useRouteRateLimit()`. Null until the first
* gateway call that carried the headers. Internal. */
lastRateLimit: RateLimitSnapshot__934527ed940b | null;
/** Subscribers notified when `lastRateLimit` changes (the `useRouteRateLimit`
* external store). Internal. */
rateLimitListeners: Set<() => void>;
/** A5-amend (T11) — the last LIMIT/throttle deny observed leaving the
* transport, recorded by `fireInterceptors`. ADVISORY: the freshest known
* RECENT deny, not a live poll (the gateway stays authoritative). Read by
* `useLimitStatus()`. Null until the first limit deny is observed. Internal. */
lastLimitDeny: ObservedLimitDeny__ff379deca309 | null;
/** Subscribers notified when `lastLimitDeny` changes (the `useLimitStatus`
* external store). Internal. */
limitDenyListeners: Set<() => void>;
/** Subscribers notified when the read cache is BUSTED (auth change, org
* switch, entitlement mutation) — every mounted `useAsync` refetches.
*
* Clearing the cache alone only stops the NEXT read from being served stale;
* it does not re-run the reads already on screen. Without this notification a
* `setSessionToken` after a 401 leaves every mounted surface showing the
* signed-out result until something happens to remount it. Internal. */
readCacheListeners: Set<() => void>;
/** True when all SDK-owned network/auth paths are served by the local mock
* transport. Internal, read by the managed auth layer. */
mockMode: boolean;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L222.
export declare function computeProgressBar__e4819393223f(used: number, total: number): {
pct: number;
status: "ok" | "warning" | "error";
};
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L43.
export declare function describePlanChangeError__6199fc9db841(err: unknown, planName?: string): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L33.
export declare function describePlanKind__bc89a2a76f27(kind: PlanKind): PlanKindDescription;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L320.
export declare function describePlanLimit__44aef0cd7254(limit: PlanLimit): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L91.
export declare function describePlanSummary__1087c6d6f26e(plan: Plan): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L173.
export declare function entitlementBullets__777c9056ecca(resourceLimits: Record<string, number> | null | undefined): string[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L124.
export declare function filterSelectablePlans__491d00098a7d(plans: Plan[], currentPlan: Plan | null | undefined): Plan[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L402.
export declare function formatCatalogExhaustion__22106a32de44(exhaustion: PlanPricingDisplay["exhaustion"]): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L388.
export declare function formatCatalogFunding__e3d315174586(funding: PlanFunding[], opts?: MoneyFormatOptions): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L368.
export declare function formatCatalogRate__1c4069e5c4b5(amount: PricingAmount, measurementKey: string, opts?: MoneyFormatOptions): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L383.
export declare function formatCatalogRule__8f5b591f982d(rule: PricingRule, opts?: MoneyFormatOptions): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L134.
export declare function formatCents__0834b254bd71(cents: number, opts?: MoneyFormatOptions): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L160.
export declare function formatDate__eb204cfcfad9(value: string | number | Date | null | undefined, opts?: DateFormatOptions): string;
Declaration source: packages/farthershore-js/dist/format/usage-labels.d.ts#L17.
export declare function formatMeasureBreakdown__d29c7c37d4b8(measures: readonly {
label: string;
used: number;
}[]): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L162.
export declare function formatMinimumSpend__703e50763b9b(plan: Plan): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L144.
export declare function formatNanos__88e9bbf170bb(nanos: string | bigint, opts?: MoneyFormatOptions): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L317.
export declare function formatPlanLimitWindow__d3866d671c3e(window: PlanLimit["window"]): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L69.
export declare function formatPlanPrice__fc05951fffba(plan: Plan): {
price: string;
period: string;
};
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L89.
export declare function formatPlanPriceDetail__ce62e738fa5f(plan: Plan): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L256.
export declare function formatRateLimitText__902f4a94c331(plan: Plan | null, meters: Meter[]): string | null;
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L109.
export interface FsDenyEnvelope__adf7ef9f2448 {
/**
* The semantic class of limit hit — the primary axis clients branch on.
* `null` ONLY when the wire carried a `limitClass` string the SDK's closed
* mirror does NOT know (a FUTURE class added to contracts but not yet shipped
* in this bundle, T13). In that case the raw value is preserved on
* {@link unknownLimitClass} and the whole `_fs` block on {@link raw} so a
* client can still render + introspect the deny, while the SDK refuses to
* invent a known-class facet for it. A KNOWN class is always non-null.
*/
limitClass: FsLimitClass | null;
/**
* T13 — the raw `limitClass` string when it is NOT a member of the closed
* {@link FsLimitClass} mirror (a future/unknown class). Undefined for every
* known class. Lets a forward-compat client surface "a `<unknownLimitClass>`
* limit was hit" + a debug breadcrumb without the SDK guessing semantics.
*/
unknownLimitClass?: string;
/**
* T13 — the raw `_fs` block exactly as it arrived on the wire, preserved for
* debugging/forwarding. Always present (even for a known class) so a developer
* can inspect fields this bundle's typed projection doesn't model yet.
*/
raw?: Record<string, unknown>;
/** The limit's scope when known (e.g. `subscription`, `org`, `route`). */
scope?: string;
/** Actor facet for actor-scoped subscriber limits. Carries kind only; raw
* actor ids must never be present in deny envelopes. */
actorScope?: "member" | "service_account";
/** The metered/resource dimension when known (e.g. `tokens`, `requests`). */
metric?: string;
/** Unix epoch ms when the limit window resets, when known. */
reset?: number;
/** Units remaining in the window at decision time, when known. */
remaining?: number;
/** Units already consumed in the window at decision time, when known. */
used?: number;
/** The cap value (the ceiling that was hit), when known. */
limit?: number;
/** True when retrying the SAME request can succeed (velocity/transient cap). */
retrySafe: boolean;
/** True when the caller must MODIFY the request (reduce size / change plan)
* before it can succeed — the `capacity`/`spend` affordances. */
mustModify: boolean;
/** Provider-supplied reason verbatim, when relayed upstream (an `adaptive`
* throttle). */
providerReason?: string;
/** Whether the platform or an upstream provider decided the limit. */
limitOrigin: FsLimitOrigin__1d4de1805fa7;
/** Human-facing next step for the END USER, when one applies. */
userAction?: string;
/** Human-facing next step for the DEVELOPER/operator, when one applies. */
devAction?: string;
/** The per-attempt request id (correlates with logs/traces). */
requestId?: string;
/** The gateway decision id (correlates with the usage event / audit). */
decisionId?: string;
/** Which exact constraint denied (projects from
* `LimitDecision.blockingConstraintId`); present on a limit deny when known. */
blockingConstraintId?: string;
/** The recommended client reaction. */
reaction: FsLimitReaction__06a9e09be641;
/** Envelope schema version. Bumped on a NON-additive envelope change. */
envelopeVersion?: number;
}
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L96.
export type FsLimitOrigin__1d4de1805fa7 = "platform" | "provider" | "subscriber";
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L99.
export type FsLimitReaction__06a9e09be641 = "none" | "backoff_retry" | "wait_then_retry" | "queue" | "reduce_then_retry" | "fallback" | "upgrade";
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L32.
export declare function getScheduledTransitionCopy__d0d68b298653(transition: SubscriberScheduledTransition | null | undefined): ScheduledTransitionCopy__a08f28383495 | null;
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L33.
export declare function getSubscriberPromoCopy__a02fd2e64736(promo: SubscriberActivePromo | null | undefined): SubscriberPromoCopy__237f8d642833 | null;
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L34.
export declare function getSubscriberStatusPresentation__3d2be580d857(subscriber: SubscriberDetail, resolvedPlanName?: string | null): SubscriberStatusPresentation__8a54b463ce40;
Declaration source: packages/farthershore-js/dist/format/usage-labels.d.ts#L10.
export declare function humanizeMeasureKey__87b59e8494f9(key: string): string;
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L31.
export declare function humanizeSubscriberStatus__a8dba22c416c(status: string | null | undefined): string;
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L36.
export declare function isCheckoutOnlyTransitionError__ed7cb1b92a62(err: unknown): boolean;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L252.
export declare function isTokenBusiness__5fb93c023117(meters: Meter[]): boolean;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L166.
export declare function labelResourceLimitKey__6d50ec5c1da1(key: string): string;
Declaration source: packages/farthershore-js/dist/types.d.ts#L80.
export interface LegalAcceptance__cc2291cc0442 {
kind: string;
version: string;
contentHash: string;
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L76.
export interface LegalConsentStatus__2c5f3ab016cd {
required: boolean;
documents: LegalDocumentStatus__f2d5a2d96393[];
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L60.
export type LegalDocumentAcceptanceMode__6e040b71b235 = "agree" | "acknowledge" | "none";
Declaration source: packages/farthershore-js/dist/types.d.ts#L61.
export interface LegalDocumentReference__0e8dba55b6a6 {
title: string;
url: string;
acceptanceMode: LegalDocumentAcceptanceMode__6e040b71b235;
effectiveDate?: string;
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L67.
export interface LegalDocumentStatus__f2d5a2d96393 extends LegalDocumentReference__0e8dba55b6a6 {
kind: string;
version: string;
contentHash: string;
consentLabel?: string;
changeNote?: string;
accepted: boolean;
acceptedAt?: string;
}
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L85.
export interface LimitDescriptor__01693492a147 {
/** Stable identifier for the limit that was hit, e.g. `resource:widgets`. */
limitCode: string;
/** The metered/resource dimension, when known (e.g. `widgets`, `requests`). */
dimension: string | null;
/** The cap the subscriber is at, when known. */
currentCapacity: number | null;
}
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L45.
export declare function logPlanChangeError__b74061738e9e(err: unknown): void;
Declaration source: packages/farthershore-js/dist/types.d.ts#L440.
export type NonEmptyPermissionList__ca911cbb6fa0 = [string, ...string[]];
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L580.
export interface ObservedLimitDeny__ff379deca309 {
/** The semantic class, or null for an UNKNOWN/future class (T13). */
limitClass: FsLimitClass | null;
/** The raw `limitClass` string when it is outside the closed mirror (T13). */
unknownLimitClass?: string;
/** The recommended client reaction. */
reaction: FsLimitReaction__06a9e09be641;
/** Whether the platform or an upstream provider decided the deny. */
limitOrigin: FsLimitOrigin__1d4de1805fa7;
/** The provider-supplied reason verbatim, when this relayed an upstream
* throttle (an adaptive deny). */
providerReason: string | null;
/** When the limit window resets, when known. */
reset: Date | null;
/** Units remaining in the window at decision time, when known. */
remaining: number | null;
/** The cap value hit, when known. */
limit: number | null;
/** The HTTP status of the deny. */
status: number;
/** The wire `code` of the deny. */
code: string;
/** The gateway decision id, when known. */
decisionId: string | null;
/** Wall-clock instant (epoch ms) the deny was observed — drives staleness. */
observedAt: number;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L342.
export declare function paymentHealth__82ab0e675721(sub: {
status?: string | null;
paymentHealth?: string | null;
}): PaymentHealth;
Declaration source: packages/farthershore-js/dist/generated/catalog-types.d.ts#L25.
export type PlanKindWire__a95f9171680c = "free" | "flat" | "usage" | "prepaid" | "hybrid" | "trial" | "custom";
Declaration source: packages/farthershore-js/dist/generated/catalog-types.d.ts#L17.
export interface PlanMeterWire__47c3d2492e8a {
dimension: string;
/** Aggregation formula (`linear` sum | `active_count` gauge |
* `event_count` per-event). OPTIONAL — absent means `linear`. */
kind?: "linear" | "active_count" | "event_count";
}
Declaration source: packages/farthershore-js/dist/resources/plans.d.ts#L31.
export interface PlanOffer__5ab47cb32b7d {
/** The immutable CompiledPlan version id (equals `plan.id`). */
compiledPlanId: string;
/** The plan, in the same wire shape as `list()` / the portal catalog. */
plan: Plan;
/** The billing fingerprint of THIS plan version's economic content. Pass it
* to `subscribe()` / `startOnboarding()` as `offerFingerprint` to get a
* 409 PLAN_OFFER_CHANGED instead of a silent price change. */
offerFingerprint: string;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L84.
export declare function planPriceHeadline__3b389a69aee5(plan: Plan): {
price: string;
period: string;
};
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L16.
export declare function planRequiresCheckoutActivation__895e488c9dd3(plan: Plan): boolean;
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L3.
export type PlanTransitionRoute__6434afad523c = "checkout" | "change-plan";
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L6.
export interface PlanTransitionSubscription__b3df65cdd542 {
/** True once the subscriber has a Stripe customer/subscription core can
* repin. Free subs that never touched Stripe are `false`. */
canManageInStripe: boolean;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L195.
export declare function pluralizeUnit__54c9aa5d8d69(unit: string, count: number): string;
Declaration source: packages/farthershore-js/dist/client.d.ts#L24.
export interface PrefetchSurface__2b22bd2b6c45 {
/** Warm the host→business resolve (joins the memoized bootstrap). */
boot(): void;
/** Warm `GET /me` (subscriber context) for dashboard/account surfaces. */
me(): void;
/** Warm the default usage snapshot (what `<UsageCard>`/the usage page read). */
usage(): void;
/** Warm the API-key list. */
apiKeys(): void;
/** Warm the subscription read (billing surfaces). */
subscription(): void;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L400.
export declare function prepaidBalanceNanos__82cd3a195fcf(preview: BillPreview | null | undefined): string | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L80.
export declare function prepaidFundingBucket__c3b93630376c(plan: Plan): PlanFunding | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L63.
export declare function presentPlanPrice__dbe194aa1865(plan: Plan, opts?: MoneyFormatOptions): PlanPricePresentation;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L220.
export declare function quotaForDimension__765de95b18ad(plan: Plan | null, dimension: string): number | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L212.
export declare function quotaLines__aba5f4afb4f1(plan: Plan): {
key: string;
text: string;
}[];
Declaration source: packages/farthershore-js/dist/errors/index.d.ts#L8.
export interface RateLimitSnapshot__934527ed940b {
/** Requests left in the current window, or null when the header is absent. */
remaining: number | null;
/** When the window resets, or null when the header is absent. The
* `X-RateLimit-Reset` value is unix-epoch SECONDS. */
resetAt: Date | null;
}
Declaration source: packages/farthershore-js/dist/cache.d.ts#L2.
export interface ReadCacheEntry__ee67854da2b9 {
at: number;
promise: Promise<unknown>;
}
Declaration source: packages/farthershore-js/dist/config.d.ts#L29.
export interface ResolvedRetryConfig__fe2336bea142 {
maxAttempts: number;
retryOn: (err: unknown) => boolean;
respectRetryAfter: boolean;
sleep: (ms: number) => Promise<void>;
}
Declaration source: packages/farthershore-js/dist/format/plan-transition.d.ts#L22.
export declare function resolvePlanTransitionRoute__704c66191ea4(plan: Plan, subscription: PlanTransitionSubscription__b3df65cdd542 | null | undefined): PlanTransitionRoute__6434afad523c;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L346.
export type ResourceLimitUsage__a25d6e733a8f = Record<string, number>;
Declaration source: packages/farthershore-js/dist/config.d.ts#L13.
export interface RetryConfig__bec25563219c {
/** Total attempts including the first (so `2` = one retry). Default 3.
* Set to `1` to disable retry. */
maxAttempts?: number;
/** Predicate deciding whether a thrown error is retryable. Defaults to the
* canonical {@link isRetryable} (429 + transient 502/503/504 + network faults
* + the named retryable deny codes). */
retryOn?: (err: unknown) => boolean;
/** Honor a `Retry-After` header for the backoff delay when present. Default
* true. */
respectRetryAfter?: boolean;
/** Override the delay primitive (tests inject a no-op; default is a
* timer-based sleep). Not part of the public surface — internal/testing. */
sleep?: (ms: number) => Promise<void>;
}
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L2.
export type ScheduledTransitionCopy__a08f28383495 = {
kind: string;
statusLabel: string;
statusSubtext: string;
isPendingCancellation: boolean;
};
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L12.
export declare function selectAutoEnrollPlan__91fe58a3dbee(plans: readonly Plan[]): Plan | null;
Declaration source: packages/farthershore-js/dist/resources/keys.d.ts#L49.
export interface ServiceAccountMutationOptions__2dee3eb4c17c {
/** Reuse this value to replay the same pending create/update request safely. */
idempotencyKey?: string;
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L399.
export type ServiceAccountUsageLimitRequest__f255b800fa4e = {
quantity: string;
limitUnits: number;
limitCents?: never;
mode: "BLOCK";
notifyAtPct?: never;
} | {
quantity: string;
limitUnits: number;
limitCents?: never;
mode: "NOTIFY";
notifyAtPct: number;
} | {
quantity: string;
limitUnits?: never;
limitCents: number;
mode: "BLOCK";
notifyAtPct?: never;
} | {
quantity: string;
limitUnits?: never;
limitCents: number;
mode: "NOTIFY";
notifyAtPct: number;
};
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L376.
export declare function singularizeMeasure__4920b2d3814d(measurementKey: string): string;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L94.
export declare function sortPlansForDisplay__accee323738d(plans: Plan[]): Plan[];
Declaration source: packages/farthershore-js/dist/types.d.ts#L848.
export interface SubscriberPinnedRule__7b0d2ee36c4a {
/** Dimension index into `displayDims`. */
d: number;
/** Window length in seconds (a 30-day month is 2592000). */
w: number;
/** Capacity (the included allowance for the window). */
c: number;
}
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L19.
export type SubscriberPromoCopy__237f8d642833 = {
title: string;
detail: string;
};
Declaration source: packages/farthershore-js/dist/format/subscriber-lifecycle.d.ts#L23.
export type SubscriberStatusPresentation__8a54b463ce40 = {
planName: string;
statusLabel: string;
statusSubtext: string | null;
pendingCancellation: boolean;
scheduledTransition: ScheduledTransitionCopy__a08f28383495 | null;
promo: SubscriberPromoCopy__237f8d642833 | null;
};
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L305.
export declare function subscriptionStatusChip__c2e919e840ee(sub: {
status: string;
cancelAtPeriodEnd?: boolean | null;
}): StatusChip;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L180.
export declare function synthesizePlanFeatures__42c0175e6f51(plan: Plan): string[];
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L187.
export declare function synthesizePlanFeaturesLean__5ee4c35cee39(plan: Plan): string[];
Declaration source: packages/farthershore-js/dist/types.d.ts#L999.
export interface TeamInvitation__f9f120bf906d {
id: string;
email: string;
role: TeamRole;
/** Managed-RBAC product roles granted on accept. */
businessRoleKeys: string[];
status: string;
invitedByExternalId?: string | null;
expiresAt: string;
createdAt: string;
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L1017.
export interface TeamInvitationAccepted__11c705c559ac {
membershipId: string;
role: TeamRole;
businessRoleKeys: string[];
}
Declaration source: packages/farthershore-js/dist/types.d.ts#L1012.
export interface TeamInvitationCreated__c157ef151993 extends TeamInvitation__f9f120bf906d {
token: string;
emailSent: boolean;
}
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L311.
export declare function trialDaysRemaining__a42e758e8e6c(sub: {
trialEndsAt?: string | null;
}, now?: number): number | null;
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L201.
export declare function unitSuffix__0244077a537f(unit: string | null | undefined, count: number): string;
Declaration source: packages/farthershore-js/dist/types.d.ts#L646.
export type UsageEventDimensions__f3dde72e4b29 = Record<string, number | null>;
Declaration source: packages/farthershore-js/dist/types.d.ts#L595.
type UsageLimitCreateMode__f16ef2d50497 = {
mode: "BLOCK";
notifyAtPct?: never;
} | {
mode: "NOTIFY";
notifyAtPct: number;
};
Declaration source: packages/farthershore-js/dist/types.d.ts#L628.
type UsageLimitExplicitUpdateMode__577df72501b7 = {
mode: "BLOCK";
notifyAtPct?: null;
} | {
mode: "NOTIFY";
notifyAtPct: number;
};
Declaration source: packages/farthershore-js/dist/types.d.ts#L614.
type UsageLimitNoUpdateValue__cd3ce2b61e4f = {
limitUnits?: never;
limitCents?: never;
};
Declaration source: packages/farthershore-js/dist/types.d.ts#L618.
type UsageLimitUpdateMode__0a6925ca669e = {
mode?: never;
notifyAtPct?: number | null;
} | {
mode: "BLOCK";
notifyAtPct?: null;
} | {
mode: "NOTIFY";
notifyAtPct: number;
};
Declaration source: packages/farthershore-js/dist/types.d.ts#L607.
type UsageLimitUpdateValue__e8f19d3e563b = {
limitUnits: number;
limitCents?: never;
} | {
limitCents: number;
limitUnits?: never;
};
Declaration source: packages/farthershore-js/dist/format/catalog-display.d.ts#L210.
export declare function usagePeriodLabel__e8ab92f06f5c(periodStart: string | null | undefined, periodEnd: string | null | undefined): string | null;