@fonderie/client 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/brain/signatures.md +38 -25
- package/dist/index.cjs +25 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -24
- package/dist/index.d.ts +44 -24
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/cache.ts","../src/http.ts","../src/modules/audit.ts","../src/modules/auth.ts","../src/modules/billing.ts","../src/modules/customers.ts","../src/modules/webhooks.ts","../src/modules/workspaces.ts","../src/token-store.ts","../src/client.ts","../src/modules/config-admin.ts","../src/modules/courier-admin.ts","../src/types.ts"],"sourcesContent":["export type { IClientAuthConfig, IFonderieClientOptions, IRequestConfig } from './client';\nexport type { ICache, IMemoryCacheOptions } from './cache';\nexport { createMemoryCache } from './cache';\nexport { FonderieClient } from './client';\nexport { FonderieApiError } from './http';\nexport type { IListAuditEventsInput } from './modules/audit';\nexport { AuditClient } from './modules/audit';\nexport type {\n\tIChangePasswordInput,\n\tILoginInput,\n\tIRegisterInput,\n\tIResetPasswordInput,\n\tIUpdatePreferencesInput,\n\tIUpdateProfileInput,\n} from './modules/auth';\nexport { AuthClient } from './modules/auth';\nexport type {\n\tICheckoutInput,\n\tICreatePlanInput,\n\tIRecordUsageInput,\n\tIUpdatePlanInput,\n} from './modules/billing';\nexport { BillingClient } from './modules/billing';\nexport type {\n\tIConfigAdminClientOptions,\n\tIRollbackInput,\n\tISetConfigInput,\n\tISetSecretInput,\n} from './modules/config-admin';\nexport { ConfigAdminClient } from './modules/config-admin';\nexport type {\n\tICourierAdminClientOptions,\n\tIRollbackTemplateInput,\n\tISetTemplateInput,\n} from './modules/courier-admin';\nexport { CourierAdminClient } from './modules/courier-admin';\nexport type {\n\tIAddAddressInput,\n\tIAddEmailInput,\n\tIAddPhoneInput,\n\tIAddRelationshipInput,\n\tIBlacklistCustomerInput,\n\tICreateCustomerInput,\n\tIGetCustomerInput,\n\tIListCustomersInput,\n\tIUpdateCustomerInput,\n} from './modules/customers';\nexport { CustomersClient } from './modules/customers';\nexport type {\n\tICreateWebhookEndpointInput,\n\tIUpdateWebhookEndpointInput,\n} from './modules/webhooks';\nexport { WebhooksClient } from './modules/webhooks';\nexport type {\n\tICreateRoleInput,\n\tICreateWorkspaceInput,\n\tIInviteEntry,\n\tIRolePermission,\n\tIRolePermissionInput,\n\tIRolePermissionsResult,\n\tIUpdateRoleInput,\n\tIUpdateSettingsInput,\n\tIUpdateWorkspaceInput,\n} from './modules/workspaces';\nexport { WorkspacesClient } from './modules/workspaces';\nexport type {\n\tCustomerLabelType,\n\tCustomerSex,\n\tCustomerType,\n\tIAcceptInvitationResult,\n\tIAddressDTO,\n\tIApiError,\n\tIApiResponse,\n\tIAuditEventDTO,\n\tIAuditPageResult,\n\tICheckoutUrlResult,\n\tIConfigEntry,\n\tIConfigRevision,\n\tICustomerAddressDTO,\n\tICustomerAddressListResult,\n\tICustomerAddressResult,\n\tICustomerDetailD2DTO,\n\tICustomerDetailDTO,\n\tICustomerDTO,\n\tICustomerEmailDTO,\n\tICustomerEmailListResult,\n\tICustomerEmailResult,\n\tICustomerLabelDTO,\n\tICustomerLabelListResult,\n\tICustomerListResult,\n\tICustomerNoteDTO,\n\tICustomerNoteListResult,\n\tICustomerNoteResult,\n\tICustomerPhoneDTO,\n\tICustomerPhoneListResult,\n\tICustomerPhoneResult,\n\tICustomerRelationshipDTO,\n\tICustomerRelationshipExpandedD2DTO,\n\tICustomerRelationshipExpandedDTO,\n\tICustomerRelationshipListResult,\n\tICustomerRelationshipResult,\n\tICustomerResult,\n\tICustomerShallowDTO,\n\tICustomerTagListResult,\n\tIInvitationDTO,\n\tIInvitationListResult,\n\tIInviteResult,\n\tILoginResult,\n\tIMemberDTO,\n\tIMemberListResult,\n\tIMeResult,\n\tIMfaEnabledResult,\n\tIMfaRequiredResult,\n\tIMfaSetupResult,\n\tIPlanDTO,\n\tIPlanFeature,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tIRefreshResult,\n\tIReadOptions,\n\tIRegisterResult,\n\tIResendVerificationResult,\n\tIRevealSecretResult,\n\tIRoleDTO,\n\tIRoleListResult,\n\tIRoleResult,\n\tISecretEntry,\n\tISecretRevision,\n\tISubscriptionDTO,\n\tISubscriptionResult,\n\tITemplateEntry,\n\tITemplateRevision,\n\tITestWebhookResult,\n\tITokens,\n\tIUsageResult,\n\tIUserDTO,\n\tIUserPreferences,\n\tIUserSkill,\n\tIVerifyEmailResult,\n\tIWebhookDeliveryDTO,\n\tIWebhookDeliveryListResult,\n\tIWebhookEndpointCreatedDTO,\n\tIWebhookEndpointDTO,\n\tIWebhookEndpointListResult,\n\tIWorkspaceAddressDTO,\n\tIWorkspaceDTO,\n\tIWorkspaceListResult,\n\tIWorkspaceResult,\n\tIWorkspaceSettingsDTO,\n\tIWorkspaceSettingsResult,\n\tSubscriberType,\n} from './types';\nexport { isMfaRequired } from './types';\n","// Optional response cache for FonderieClient. A cache instance is created per\n// client (never module-global) so it is safe on a server — one client per\n// request means no cross-user/tenant leakage. It sweeps lazily on read, so\n// there is no background timer keeping a process alive.\n\nexport interface ICache {\n\t// Returns the cached value if present and still within its TTL, else undefined.\n\tget<T>(key: string): T | undefined;\n\t// Stores a value with a per-entry TTL (ms).\n\tset<T>(key: string, value: T, ttlMs: number): void;\n\t// Deduplicates concurrent in-flight requests for the same key.\n\tdedupe<T>(key: string, fn: () => Promise<T>): Promise<T>;\n\t// Evicts every entry whose key contains `fragment` (and cancels in-flight\n\t// dedupe for those), so a write can bust the reads it affects.\n\tinvalidate(fragment: string): void;\n\tclear(): void;\n}\n\nexport interface IMemoryCacheOptions {\n\t// Default TTL (ms) applied to cached GETs when a call doesn't specify one.\n\tdefaultTtlMs?: number;\n}\n\ninterface Entry {\n\tvalue: unknown;\n\texpiresAt: number;\n}\n\nexport function createMemoryCache(opts: IMemoryCacheOptions = {}): ICache & { defaultTtlMs: number } {\n\tconst store = new Map<string, Entry>();\n\tconst inflight = new Map<string, Promise<unknown>>();\n\tconst defaultTtlMs = opts.defaultTtlMs ?? 60_000;\n\n\treturn {\n\t\tdefaultTtlMs,\n\n\t\tget<T>(key: string): T | undefined {\n\t\t\tconst entry = store.get(key);\n\t\t\tif (!entry) return undefined;\n\t\t\tif (Date.now() > entry.expiresAt) {\n\t\t\t\tstore.delete(key); // lazy sweep\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn entry.value as T;\n\t\t},\n\n\t\tset<T>(key: string, value: T, ttlMs: number): void {\n\t\t\tstore.set(key, { value, expiresAt: Date.now() + ttlMs });\n\t\t},\n\n\t\tdedupe<T>(key: string, fn: () => Promise<T>): Promise<T> {\n\t\t\tconst existing = inflight.get(key);\n\t\t\tif (existing) return existing as Promise<T>;\n\t\t\tconst req = fn().finally(() => inflight.delete(key));\n\t\t\tinflight.set(key, req);\n\t\t\treturn req;\n\t\t},\n\n\t\tinvalidate(fragment: string): void {\n\t\t\tfor (const key of store.keys()) if (key.includes(fragment)) store.delete(key);\n\t\t\tfor (const key of inflight.keys()) if (key.includes(fragment)) inflight.delete(key);\n\t\t},\n\n\t\tclear(): void {\n\t\t\tstore.clear();\n\t\t\tinflight.clear();\n\t\t},\n\t};\n}\n","import type { ICache } from './cache';\nimport type { IApiError } from './types';\n\nexport class FonderieApiError extends Error {\n\tconstructor(\n\t\tpublic readonly reason: string,\n\t\tpublic readonly explanation: string,\n\t\tpublic readonly status: number,\n\t\tpublic readonly details?: unknown,\n\t) {\n\t\tsuper(explanation);\n\t\tthis.name = 'FonderieApiError';\n\t}\n}\n\nexport interface IRequestOptions {\n\tmethod: string;\n\tpath: string;\n\tbody?: unknown;\n\ttoken?: string | undefined;\n\tcookie?: string | undefined;\n\t// Resolves the billing subscriber to a workspace (@fonderie/billing's\n\t// resolveSubscriber falls back to the session user when omitted).\n\tworkspaceId?: string | undefined;\n\t// Cache control (only applies when the client was given a cache):\n\t// cache: number → cache this GET for that many ms\n\t// cache: false → skip the cache for this GET\n\t// bust: true → ignore any cached value and refresh it\n\t// invalidate → extra key fragments to evict after a successful write\n\tcache?: number | false | undefined;\n\tbust?: boolean | undefined;\n\tinvalidate?: string[] | undefined;\n}\n\nexport interface IHttpDeps {\n\tcache?: ICache | undefined;\n\tdefaultTtlMs?: number | undefined;\n\t// Called once on a 401 (except for /auth/* requests). Returns a fresh access\n\t// token to retry with, or undefined to let the 401 surface. Callers should\n\t// make this single-flight.\n\trefresh?: (() => Promise<string | undefined>) | undefined;\n}\n\nexport class HttpClient {\n\tprivate cache: ICache | undefined;\n\tprivate defaultTtlMs: number;\n\tprivate refresh: (() => Promise<string | undefined>) | undefined;\n\n\tconstructor(\n\t\tprivate baseUrl: string,\n\t\tdeps: IHttpDeps = {},\n\t) {\n\t\tthis.cache = deps.cache;\n\t\tthis.defaultTtlMs = deps.defaultTtlMs ?? 60_000;\n\t\tthis.refresh = deps.refresh;\n\t}\n\n\t// Drop all cached responses — sign-out must not leave one session's data\n\t// servable to the next.\n\tclearCache(): void {\n\t\tthis.cache?.clear();\n\t}\n\n\tasync request<T>(opts: IRequestOptions): Promise<T> {\n\t\tconst method = opts.method.toUpperCase();\n\n\t\tconst cache = this.cache;\n\n\t\t// ── Read path: serve/populate cache (GET only, opt-in) ──────────────────\n\t\tif (cache && method === 'GET' && opts.cache !== false) {\n\t\t\tconst key = `GET ${opts.path}::ws=${opts.workspaceId ?? ''}`;\n\t\t\tif (!opts.bust) {\n\t\t\t\tconst hit = cache.get<T>(key);\n\t\t\t\tif (hit !== undefined) return hit;\n\t\t\t}\n\t\t\tconst ttl = typeof opts.cache === 'number' ? opts.cache : this.defaultTtlMs;\n\t\t\treturn cache.dedupe(key, async () => {\n\t\t\t\tconst data = await this.exec<T>(opts);\n\t\t\t\tcache.set(key, data, ttl);\n\t\t\t\treturn data;\n\t\t\t});\n\t\t}\n\n\t\tconst data = await this.exec<T>(opts);\n\n\t\t// ── Write path: bust the reads this mutation affects ────────────────────\n\t\tif (cache && method !== 'GET') {\n\t\t\tconst resource = opts.path.split('?')[0]?.split('/').filter(Boolean)[0];\n\t\t\tif (resource) cache.invalidate(`/${resource}`);\n\t\t\tfor (const fragment of opts.invalidate ?? []) cache.invalidate(fragment);\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tprivate async exec<T>(opts: IRequestOptions, retried = false): Promise<T> {\n\t\tconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\t\tif (opts.token) headers['Authorization'] = `Bearer ${opts.token}`;\n\t\tif (opts.cookie) headers['Cookie'] = opts.cookie;\n\t\tif (opts.workspaceId) headers['X-Workspace-ID'] = opts.workspaceId;\n\n\t\tconst fetchInit: RequestInit = { method: opts.method, headers, credentials: 'include' };\n\t\tif (opts.body !== undefined) fetchInit.body = JSON.stringify(opts.body);\n\n\t\tconst res = await fetch(`${this.baseUrl}${opts.path}`, fetchInit);\n\n\t\t// Reactive renew: on a 401, refresh once and retry (never for /auth/* to\n\t\t// avoid recursing through the refresh/login endpoints themselves).\n\t\tif (res.status === 401 && this.refresh && !retried && !opts.path.startsWith('/auth/')) {\n\t\t\tconst newToken = await this.refresh();\n\t\t\tif (newToken) return this.exec<T>({ ...opts, token: newToken }, true);\n\t\t}\n\n\t\t// 204 No Content (e.g. some DELETE routes) has no body to parse.\n\t\tif (res.status === 204) {\n\t\t\tif (!res.ok) throw new FonderieApiError('unknown', res.statusText, res.status);\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\tconst data = (await res.json()) as T | IApiError;\n\n\t\tif (!res.ok || res.status === 202) {\n\t\t\tconst err = data as IApiError;\n\t\t\tthrow new FonderieApiError(err.reason, err.explanation, res.status, err.details);\n\t\t}\n\n\t\treturn data as T;\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions, IApiResponse, IAuditPageResult } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface IListAuditEventsInput {\n\ttype?: string;\n\tactorId?: string;\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// ── Audit client ─────────────────────────────────────────────────────────────\n\nexport class AuditClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes the audit query to a workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\tlistEvents(input: IListAuditEventsInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.type) params.set('type', input.type);\n\t\tif (input.actorId) params.set('actorId', input.actorId);\n\t\tif (input.from) params.set('from', input.from.toISOString());\n\t\tif (input.to) params.set('to', input.to.toISOString());\n\t\tif (input.cursor) params.set('cursor', input.cursor);\n\t\tconst qs = params.toString();\n\n\t\treturn this.http.request<IApiResponse<IAuditPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/audit${qs ? `?${qs}` : ''}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tILoginResult,\n\tIMfaRequiredResult,\n\tIMeResult,\n\tIMfaEnabledResult,\n\tIMfaSetupResult,\n\tIRefreshResult,\n\tIRegisterResult,\n\tIResendVerificationResult,\n\tIVerifyEmailResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface IRegisterInput {\n\temail: string;\n\tpassword: string;\n\tfirstName?: string;\n\tlastName?: string;\n}\n\nexport interface ILoginInput {\n\temail: string;\n\tpassword: string;\n}\n\nexport interface IResetPasswordInput {\n\t// The 6-digit code emailed by forgotPassword. Matches @fonderie/auth's\n\t// resetPasswordSchema ({ pin, password }); the route is POST /auth/email/reset.\n\tpin: string;\n\tpassword: string;\n}\n\n// User updates are split by @fonderie/auth into dedicated, individually\n// validated routes — there is no combined /users/update endpoint.\nexport interface IUpdateProfileInput {\n\tfirstName?: string;\n\tlastName?: string;\n\tavatarUrl?: string;\n}\n\nexport interface IUpdatePreferencesInput {\n\tlocale?: string;\n\ttimezone?: string;\n\tnotifications?: unknown;\n\temailDigest?: unknown;\n\tdateFormat?: unknown;\n\ttimeFormat?: unknown;\n}\n\nexport interface IChangePasswordInput {\n\tcurrentPassword: string;\n\tnewPassword: string;\n}\n\n// ── MFA sub-client ───────────────────────────────────────────────────────────\n\nclass MfaClient {\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate token: () => string | undefined,\n\t) {}\n\n\tsetup() {\n\t\treturn this.http.request<IApiResponse<IMfaSetupResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/setup',\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\tverify(token: string) {\n\t\treturn this.http.request<IApiResponse<IMfaEnabledResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/verify',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\t// MFA-login: complete a login that returned MFA_REQUIRED. Authenticates with\n\t// the temporary `mfaToken` (not the session) and verifies the TOTP `code` —\n\t// same route as `verify`, different auth context. Returns the completed login.\n\tverifyLogin(mfaToken: string, code: string) {\n\t\treturn this.http.request<IApiResponse<ILoginResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/verify',\n\t\t\tbody: { token: code },\n\t\t\ttoken: mfaToken,\n\t\t});\n\t}\n\n\tdisable(token: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/disable',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\t// POST /auth/mfa/backup-codes (mfaTokenSchema { token }) — returns a fresh set.\n\tregenerateBackupCodes(token: string) {\n\t\treturn this.http.request<IApiResponse<{ backupCodes: string[] }>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/backup-codes',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n}\n\n// ── Auth client ──────────────────────────────────────────────────────────────\n\nexport class AuthClient {\n\treadonly mfa: MfaClient;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {\n\t\tthis.mfa = new MfaClient(http, () => this.tokens.get());\n\t}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t\t// Signing out (token → undefined) also drops the shared response cache,\n\t\t// so the hooks' logout paths can't leak one session's data to the next.\n\t\tif (!token) this.http.clearCache();\n\t}\n\n\t// ── Public ─────────────────────────────────────────────────────────────────\n\n\tregister(input: IRegisterInput) {\n\t\treturn this.http.request<IApiResponse<IRegisterResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/register',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\tlogin(input: ILoginInput) {\n\t\treturn this.http.request<IApiResponse<ILoginResult | IMfaRequiredResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/login',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\trefreshTokens(refreshToken?: string) {\n\t\treturn this.http.request<IApiResponse<IRefreshResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/refresh',\n\t\t\tbody: refreshToken ? { refreshToken } : undefined,\n\t\t});\n\t}\n\n\tforgotPassword(email: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/email/forgot',\n\t\t\tbody: { email },\n\t\t});\n\t}\n\n\tresetPassword(input: IResetPasswordInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/email/reset',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\tverifyEmail(token: string) {\n\t\t// @fonderie/auth registers this as POST /auth/verify with body { token }\n\t\t// (verifySchema = { token: sixDigitPin }).\n\t\treturn this.http.request<IApiResponse<IVerifyEmailResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/verify',\n\t\t\tbody: { token },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Protected ──────────────────────────────────────────────────────────────\n\n\tlogout(refreshToken?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/logout',\n\t\t\tbody: refreshToken ? { refreshToken } : undefined,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tsendVerificationEmail() {\n\t\t// @fonderie/auth registers this as GET /auth/send-verification (requireAuth).\n\t\treturn this.http.request<IApiResponse<IResendVerificationResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/send-verification',\n\t\t\ttoken: this.tokens.get(),\n\t\t\t// A send-action on a GET route: never serve it from the cache, or a\n\t\t\t// resend inside the TTL would silently no-op.\n\t\t\tcache: false,\n\t\t});\n\t}\n\n\t// ── Protected + Verified ───────────────────────────────────────────────────\n\n\tgetUser(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/users',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateProfile(input: IUpdateProfileInput) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/profile',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePreferences(input: IUpdatePreferencesInput) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/preferences',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdateEmail(email: string) {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/email',\n\t\t\tbody: { email },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePhone(phone: string) {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/phone',\n\t\t\tbody: { phone },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tchangePassword(input: IChangePasswordInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/password',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// GET /users/export — the caller's own data as a portable bundle (SAR).\n\texportData() {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/users/export',\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tdeleteUser() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/users',\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tICheckoutUrlResult,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tISubscriptionResult,\n\tIUsageResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICheckoutInput {\n\tplan: string;\n\tinterval?: 'month' | 'year';\n}\n\nexport interface IRecordUsageInput {\n\tmetric: string;\n\tquantity?: number;\n}\n\nexport interface ICreatePlanInput {\n\tname: string;\n\tdescription?: string | null;\n\ttier?: number;\n\tseats?: number | null;\n\ttrialDays?: number;\n\tmonthlyAmount?: number | null;\n\tmonthlyPriceId?: string | null;\n\tyearlyAmount?: number | null;\n\tyearlyPriceId?: string | null;\n\tfeatures?: unknown;\n\tmetadata?: unknown;\n}\n\nexport type IUpdatePlanInput = Partial<ICreatePlanInput>;\n\n// ── Billing client ───────────────────────────────────────────────────────────\n\nexport class BillingClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Subscriber is resolved from this workspace ID (X-Workspace-ID) when set,\n\t// falling back to the session user otherwise — see @fonderie/billing's\n\t// resolveSubscriber. Call with undefined to bill the signed-in user directly.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Plans — public read-only ────────────────────────────────────────────────\n\n\tlistPlans(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPlanListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/plans',\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tgetPlan(planId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// ── Plans — admin write ──────────────────────────────────────────────────────\n\t// Unlike every other write in this client, @fonderie/billing does not gate\n\t// these with requireAuth or an admin token — \"the caller is responsible for\n\t// authorization\" (its own routes.ts comment). Sending the session token is\n\t// harmless (the server ignores it) but does nothing on its own; gate access\n\t// to these calls yourself (an app-level route guard, a reverse-proxy admin\n\t// zone, or similar) before wiring them into a UI.\n\n\tcreatePlan(input: ICreatePlanInput) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/plans',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePlan(planId: string, input: IUpdatePlanInput) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tdeletePlan(planId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Subscription ─────────────────────────────────────────────────────────────\n\n\tgetSubscription(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ISubscriptionResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/subscription',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// ── Checkout / portal ────────────────────────────────────────────────────────\n\n\tcreateCheckoutSession(input: ICheckoutInput) {\n\t\treturn this.http.request<IApiResponse<ICheckoutUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/checkout',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tcreatePortalSession() {\n\t\treturn this.http.request<IApiResponse<IPortalUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/portal',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Usage ────────────────────────────────────────────────────────────────────\n\n\trecordUsage(input: IRecordUsageInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/usage',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetUsage(metric: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IUsageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/billing/usage/${metric}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tCustomerLabelType,\n\tCustomerSex,\n\tCustomerType,\n\tIApiResponse,\n\tICustomerAddressListResult,\n\tICustomerAddressResult,\n\tICustomerDetailD2DTO,\n\tICustomerDetailDTO,\n\tICustomerEmailListResult,\n\tICustomerEmailResult,\n\tICustomerLabelListResult,\n\tICustomerListResult,\n\tICustomerNoteListResult,\n\tICustomerNoteResult,\n\tICustomerPhoneListResult,\n\tICustomerPhoneResult,\n\tICustomerRelationshipListResult,\n\tICustomerRelationshipResult,\n\tICustomerResult,\n\tICustomerTagListResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface IListCustomersInput {\n\tsearch?: string;\n\tblacklisted?: boolean;\n\tlimit?: number;\n\toffset?: number;\n}\n\nexport interface IGetCustomerInput {\n\tdepth?: 1 | 2;\n}\n\nexport interface ICreateCustomerInput {\n\ttype?: CustomerType;\n\tsex?: CustomerSex;\n\tfirstName?: string | null;\n\tlastName?: string | null;\n\tcompanyName?: string | null;\n\tavatarUrl?: string | null;\n\tlocale?: string | null;\n\treferenceCode?: string | null;\n\treferralCode?: string | null;\n\treferredByCode?: string | null;\n}\n\nexport type IUpdateCustomerInput = ICreateCustomerInput;\n\nexport interface IBlacklistCustomerInput {\n\treason?: string;\n}\n\nexport interface IAddEmailInput {\n\temail: string;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddPhoneInput {\n\tphone: string;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddAddressInput {\n\tcountryIso: string;\n\tzipPostalCode: string;\n\tsubdivision1Iso?: string | null;\n\tsubdivision2Iso?: string | null;\n\tunit?: string | null;\n\tline1?: string | null;\n\tline2?: string | null;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddRelationshipInput {\n\trelatedId: string;\n\trelationship?: string;\n\tisPrimary?: boolean;\n}\n\n// ── Customers client ─────────────────────────────────────────────────────────\n\nexport class CustomersClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every request to this workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces/audit/webhooks.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Core customer CRUD ───────────────────────────────────────────────────────\n\n\tlistCustomers(input: IListCustomersInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.search !== undefined) params.set('search', input.search);\n\t\tif (input.blacklisted !== undefined) params.set('blacklisted', String(input.blacklisted));\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.offset !== undefined) params.set('offset', String(input.offset));\n\t\tconst qs = params.toString();\n\n\t\treturn this.http.request<IApiResponse<ICustomerListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: qs ? `/customers?${qs}` : '/customers',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateCustomer(input: ICreateCustomerInput = {}) {\n\t\treturn this.http.request<IApiResponse<ICustomerResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/customers',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// depth defaults to 2 server-side; pass { depth: 1 } for one level of\n\t// relationship expansion instead of the D2 (nested-relationships) shape.\n\tgetCustomer(customerId: string, input: IGetCustomerInput = {}, opts?: IReadOptions) {\n\t\tconst qs = input.depth === 1 ? '?depth=1' : '';\n\t\treturn this.http.request<IApiResponse<ICustomerDetailDTO | ICustomerDetailD2DTO>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}${qs}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateCustomer(customerId: string, input: IUpdateCustomerInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteCustomer(customerId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tblacklistCustomer(customerId: string, input: IBlacklistCustomerInput = {}) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/blacklist`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tunblacklistCustomer(customerId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/unblacklist`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Emails ───────────────────────────────────────────────────────────────────\n\n\tlistEmails(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/emails`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddEmail(customerId: string, input: IAddEmailInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/emails`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — email addresses themselves are immutable\n\t// once added; remove and re-add to change the address.\n\tupdateEmailLabel(customerId: string, emailId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryEmail(customerId: string, emailId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveEmail(customerId: string, emailId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Phones ───────────────────────────────────────────────────────────────────\n\n\tlistPhones(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/phones`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddPhone(customerId: string, input: IAddPhoneInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/phones`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — same as updateEmailLabel.\n\tupdatePhoneLabel(customerId: string, phoneId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryPhone(customerId: string, phoneId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremovePhone(customerId: string, phoneId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Addresses ────────────────────────────────────────────────────────────────\n\n\tlistAddresses(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/addresses`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddAddress(customerId: string, input: IAddAddressInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/addresses`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — same as updateEmailLabel.\n\tupdateAddressLabel(customerId: string, addrId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryAddress(customerId: string, addrId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveAddress(customerId: string, addrId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Notes ────────────────────────────────────────────────────────────────────\n\n\tlistNotes(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/notes`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateNote(customerId: string, body: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/notes`,\n\t\t\tbody: { body },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tupdateNote(customerId: string, noteId: string, body: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/notes/${noteId}`,\n\t\t\tbody: { body },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteNote(customerId: string, noteId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/notes/${noteId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Tags ─────────────────────────────────────────────────────────────────────\n\n\tlistTags(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerTagListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/tags`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddTag(customerId: string, tag: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/tags`,\n\t\t\tbody: { tag },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveTag(customerId: string, tag: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/tags/${encodeURIComponent(tag)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Relationships ────────────────────────────────────────────────────────────\n\n\tlistRelationships(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerRelationshipListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/relationships`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddRelationship(customerId: string, input: IAddRelationshipInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerRelationshipResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/relationships`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryRelationship(customerId: string, relatedId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/relationships/${relatedId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveRelationship(customerId: string, relatedId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/relationships/${relatedId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Labels ───────────────────────────────────────────────────────────────────\n\t// Shared vocabulary across all customers in the workspace — labels are\n\t// looked up/created implicitly by addEmail/addPhone/addAddress's `label`\n\t// string; these two methods are for managing the vocabulary directly\n\t// (e.g. an admin screen listing/pruning unused labels).\n\n\tlistLabels(type: CustomerLabelType, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerLabelListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/labels?type=${type}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tremoveLabel(labelId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/labels/${labelId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tITestWebhookResult,\n\tIWebhookDeliveryListResult,\n\tIWebhookEndpointCreatedDTO,\n\tIWebhookEndpointDTO,\n\tIWebhookEndpointListResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICreateWebhookEndpointInput {\n\turl: string;\n\tevents?: string[];\n}\n\nexport interface IUpdateWebhookEndpointInput {\n\turl?: string;\n\tevents?: string[];\n\tenabled?: boolean;\n}\n\n// ── Webhooks client ──────────────────────────────────────────────────────────\n\nexport class WebhooksClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every request to this workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces/audit.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\tlistEndpoints(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/webhooks',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// The response includes `secret` — shown once, at creation. There is no\n\t// way to retrieve it again afterward; store it or let the caller copy it.\n\tcreateEndpoint(input: ICreateWebhookEndpointInput) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointCreatedDTO>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/webhooks',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetEndpoint(endpointId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointDTO>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateEndpoint(endpointId: string, input: IUpdateWebhookEndpointInput) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointDTO>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteEndpoint(endpointId: string) {\n\t\treturn this.http.request<undefined>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tlistDeliveries(endpointId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookDeliveryListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/webhooks/${endpointId}/deliveries`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\ttestEndpoint(endpointId: string) {\n\t\treturn this.http.request<IApiResponse<ITestWebhookResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/webhooks/${endpointId}/test`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIAcceptInvitationResult,\n\tIApiResponse,\n\tIInvitationListResult,\n\tIInviteResult,\n\tIMemberListResult,\n\tIRoleListResult,\n\tIRoleResult,\n\tIWorkspaceListResult,\n\tIWorkspaceResult,\n\tIWorkspaceSettingsResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICreateWorkspaceInput {\n\tname: string;\n\tdescription?: string;\n\ttype?: string;\n}\n\nexport interface IUpdateWorkspaceInput {\n\tname?: string;\n\tdescription?: string | null;\n\tmotto?: string | null;\n\tphone?: string | null;\n\tbusinessType?: string | null;\n\taddress?: {\n\t\tline1?: string;\n\t\tline2?: string;\n\t\tcity?: string;\n\t\tstate?: string;\n\t\tzip?: string;\n\t\tcountry?: string;\n\t} | null;\n}\n\nexport interface IInviteEntry {\n\temail: string;\n\troleId?: string;\n}\n\nexport interface IUpdateSettingsInput {\n\tlocale?: string;\n\ttimezone?: string;\n\tcurrency?: string;\n\tdateFormat?: string;\n\ttimeFormat?: string;\n}\n\nexport interface ICreateRoleInput {\n\tname: string;\n\tdescription?: string;\n}\n\nexport interface IUpdateRoleInput {\n\tname?: string;\n\tdescription?: string | null;\n\tactive?: boolean;\n}\n\nexport interface IRolePermissionInput {\n\tpermissionKey: string;\n\tcanCreate?: boolean;\n\tcanRead?: boolean;\n\tcanUpdate?: boolean;\n\tcanDelete?: boolean;\n}\n\nexport interface IRolePermission {\n\tpermissionKey: string;\n\tcanCreate: boolean;\n\tcanRead: boolean;\n\tcanUpdate: boolean;\n\tcanDelete: boolean;\n}\n\nexport interface IRolePermissionsResult {\n\tpermissions: IRolePermission[];\n}\n\n// ── Workspaces client ────────────────────────────────────────────────────────\n\nexport class WorkspacesClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every subsequent request to this workspace (X-Workspace-ID).\n\t// Falls back to the caller's personal workspace when unset.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Workspace creation + listing ─────────────────────────────────────────────\n\n\tlistWorkspaces(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateWorkspace(input: ICreateWorkspaceInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tgetWorkspace(id: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/${id}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateWorkspace(input: IUpdateWorkspaceInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/workspaces',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Personal workspaces can't be archived — the server returns 403 if you try.\n\tarchiveWorkspace() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/archive',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\trestoreWorkspace() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/restore',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Roles ────────────────────────────────────────────────────────────────────\n\n\tlistRoles(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/roles',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateRole(input: ICreateRoleInput) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/roles',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetRole(roleId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateRole(roleId: string, input: IUpdateRoleInput) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveRole(roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetRolePermissions(roleId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRolePermissionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/roles/${roleId}/permissions`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tsetRolePermissions(roleId: string, permissions: IRolePermissionInput[]) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/workspaces/roles/${roleId}/permissions`,\n\t\t\tbody: { permissions },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Members ──────────────────────────────────────────────────────────────────\n\n\tlistMembers(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IMemberListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/members',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tremoveMember(userId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/members/${userId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetMemberRoles(userId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/members/${userId}/roles`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddMemberRole(userId: string, roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/workspaces/members/${userId}/roles`,\n\t\t\tbody: { roleId },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveMemberRole(userId: string, roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/members/${userId}/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Invitations ──────────────────────────────────────────────────────────────\n\n\tlistInvitations(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IInvitationListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/invitations',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tinvite(entries: IInviteEntry | IInviteEntry[]) {\n\t\treturn this.http.request<IApiResponse<IInviteResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/invitations',\n\t\t\tbody: entries,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tcancelInvitation(inviteId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/invitations/${inviteId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tacceptInvitation(pin: string) {\n\t\treturn this.http.request<IApiResponse<IAcceptInvitationResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/invitations/accept',\n\t\t\tbody: { pin },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Settings ─────────────────────────────────────────────────────────────────\n\n\tgetSettings(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceSettingsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/settings',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateSettings(input: IUpdateSettingsInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceSettingsResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/workspaces/settings',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","// Shared by every module of a FonderieClient so that setting the access\n// token on one (e.g. AuthClient after login) is immediately visible to all\n// the others (e.g. BillingClient) — they're separate module instances, but\n// one session.\nexport class TokenStore {\n\tprivate token: string | undefined;\n\n\tconstructor(initial?: string) {\n\t\tthis.token = initial;\n\t}\n\n\tget(): string | undefined {\n\t\treturn this.token;\n\t}\n\n\tset(token: string | undefined) {\n\t\tthis.token = token;\n\t}\n}\n","import type { ICache } from './cache';\nimport { HttpClient } from './http';\nimport { AuditClient } from './modules/audit';\nimport { AuthClient } from './modules/auth';\nimport { BillingClient } from './modules/billing';\nimport { CustomersClient } from './modules/customers';\nimport { WebhooksClient } from './modules/webhooks';\nimport { WorkspacesClient } from './modules/workspaces';\nimport { TokenStore } from './token-store';\nimport type { IApiResponse, ITokens } from './types';\n\n// Reactive token renewal. When set, the client refreshes once on a 401 and\n// retries the request. The app owns where the refresh token lives and where new\n// tokens are persisted.\nexport interface IClientAuthConfig {\n\tgetRefreshToken?: () => string | undefined;\n\tonTokensChanged?: (tokens: ITokens) => void;\n\tonAuthError?: () => void;\n}\n\nexport interface IFonderieClientOptions {\n\tbaseUrl: string;\n\taccessToken?: string;\n\tworkspaceId?: string;\n\t// Opt-in response cache (see createMemoryCache). Omit for no caching.\n\tcache?: ICache;\n\t// Opt-in reactive renew.\n\tauth?: IClientAuthConfig;\n}\n\n// Per-call options for the generic transport.\nexport interface IRequestConfig {\n\tworkspaceId?: string;\n\t// Per-call Bearer override — e.g. the MFA-login step, where a temporary\n\t// mfaToken is used before the session access token exists. Defaults to the\n\t// client's stored token.\n\ttoken?: string;\n\t// Cache this GET for `cache` ms; false to skip; bust to force-refresh.\n\tcache?: number | false;\n\tbust?: boolean;\n\t// Extra cache key fragments to evict after a write.\n\tinvalidate?: string[];\n}\n\nexport class FonderieClient {\n\treadonly auth: AuthClient;\n\treadonly billing: BillingClient;\n\treadonly workspaces: WorkspacesClient;\n\treadonly audit: AuditClient;\n\treadonly webhooks: WebhooksClient;\n\treadonly customers: CustomersClient;\n\n\tprivate http: HttpClient;\n\tprivate tokens: TokenStore;\n\tprivate workspaceId: string | undefined;\n\tprivate cache: ICache | undefined;\n\tprivate authConfig: IClientAuthConfig | undefined;\n\tprivate refreshing: Promise<string | undefined> | null = null;\n\n\tconstructor(opts: IFonderieClientOptions) {\n\t\tthis.tokens = new TokenStore(opts.accessToken);\n\t\tthis.workspaceId = opts.workspaceId;\n\t\tthis.cache = opts.cache;\n\t\tthis.authConfig = opts.auth;\n\t\tthis.http = new HttpClient(opts.baseUrl, {\n\t\t\tcache: opts.cache,\n\t\t\tdefaultTtlMs: (opts.cache as { defaultTtlMs?: number } | undefined)?.defaultTtlMs,\n\t\t\trefresh: opts.auth ? () => this.doRefresh() : undefined,\n\t\t});\n\t\tthis.auth = new AuthClient(this.http, this.tokens);\n\t\tthis.billing = new BillingClient(this.http, this.tokens);\n\t\tthis.workspaces = new WorkspacesClient(this.http, this.tokens);\n\t\tthis.audit = new AuditClient(this.http, this.tokens);\n\t\tthis.webhooks = new WebhooksClient(this.http, this.tokens);\n\t\tthis.customers = new CustomersClient(this.http, this.tokens);\n\t\t// Route through the setter so the constructor option scopes the\n\t\t// workspace-aware modules exactly like a later setWorkspaceId() call.\n\t\tif (opts.workspaceId !== undefined) this.setWorkspaceId(opts.workspaceId);\n\t}\n\n\t// Single-flight refresh: POST /auth/refresh with the app-supplied refresh\n\t// token, store the new access token, notify the app, return it for the retry.\n\tprivate doRefresh(): Promise<string | undefined> {\n\t\tif (this.refreshing) return this.refreshing;\n\t\tthis.refreshing = (async () => {\n\t\t\tconst refreshToken = this.authConfig?.getRefreshToken?.();\n\t\t\tif (!refreshToken) {\n\t\t\t\tthis.authConfig?.onAuthError?.();\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { result } = await this.auth.refreshTokens(refreshToken);\n\t\t\t\tconst tokens = (result as unknown as { tokens: ITokens }).tokens;\n\t\t\t\tthis.tokens.set(tokens.access);\n\t\t\t\tthis.authConfig?.onTokensChanged?.(tokens);\n\t\t\t\treturn tokens.access;\n\t\t\t} catch {\n\t\t\t\tthis.tokens.set(undefined);\n\t\t\t\tthis.authConfig?.onAuthError?.();\n\t\t\t\treturn undefined;\n\t\t\t} finally {\n\t\t\t\tthis.refreshing = null;\n\t\t\t}\n\t\t})();\n\t\treturn this.refreshing;\n\t}\n\n\t// The JWT used to authenticate every request — the typed modules and the\n\t// generic transport share one token store. Passing undefined signs out and\n\t// clears the cache (so no session's data survives a logout).\n\tsetAccessToken(token: string | undefined): void {\n\t\tthis.tokens.set(token);\n\t\tif (!token) this.clearCache();\n\t}\n\n\t// Drop all cached responses (e.g. on switching accounts).\n\tclearCache(): void {\n\t\tthis.cache?.clear();\n\t}\n\n\t// Default X-Workspace-ID for the generic transport, also propagated to the\n\t// workspace-scoped modules so one call configures the whole client.\n\tsetWorkspaceId(workspaceId: string | undefined): void {\n\t\tthis.workspaceId = workspaceId;\n\t\tthis.billing.setWorkspaceId(workspaceId);\n\t\tthis.workspaces.setWorkspaceId(workspaceId);\n\t\tthis.customers.setWorkspaceId(workspaceId);\n\t\tthis.audit.setWorkspaceId(workspaceId);\n\t\tthis.webhooks.setWorkspaceId(workspaceId);\n\t}\n\n\t// ── Generic transport ──────────────────────────────────────────────────────\n\t// A Fonderie-aware HTTP client for endpoints outside the typed modules (an\n\t// app's own routes on the same backend). It attaches the shared JWT and\n\t// X-Workspace-ID automatically and returns Fonderie's { reason, explanation,\n\t// result } envelope — so you don't hand-roll auth for custom endpoints.\n\n\trequest<T = unknown>(opts: {\n\t\tmethod: string;\n\t\tpath: string;\n\t\tbody?: unknown;\n\t\ttoken?: string | undefined;\n\t\tworkspaceId?: string | undefined;\n\t\tcache?: number | false | undefined;\n\t\tbust?: boolean | undefined;\n\t\tinvalidate?: string[] | undefined;\n\t}): Promise<IApiResponse<T>> {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod: opts.method,\n\t\t\tpath: opts.path,\n\t\t\tbody: opts.body,\n\t\t\ttoken: opts.token ?? this.tokens.get(),\n\t\t\tworkspaceId: opts.workspaceId ?? this.workspaceId,\n\t\t\tcache: opts.cache,\n\t\t\tbust: opts.bust,\n\t\t\tinvalidate: opts.invalidate,\n\t\t});\n\t}\n\n\tget<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'GET',\n\t\t\tpath,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tcache: config?.cache,\n\t\t\tbust: config?.bust,\n\t\t});\n\t}\n\n\tpost<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'POST', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tput<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'PUT', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tpatch<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'PATCH', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tdelete<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'DELETE', path, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n}\n","import { HttpClient } from '../http';\nimport type {\n\tIApiResponse,\n\tIConfigEntry,\n\tIConfigRevision,\n\tIRevealSecretResult,\n\tISecretEntry,\n\tISecretRevision,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ISetConfigInput {\n\tvalue: unknown;\n\tdescription?: string;\n\tifVersion?: number;\n}\n\nexport interface ISetSecretInput {\n\tvalue: string;\n\tdescription?: string;\n\tifVersion?: number;\n}\n\nexport interface IRollbackInput {\n\ttoVersion: number;\n}\n\nexport interface IConfigAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n}\n\nfunction envQuery(environment?: string): string {\n\treturn environment ? `?environment=${encodeURIComponent(environment)}` : '';\n}\n\n// ── Config admin client ──────────────────────────────────────────────────────\n//\n// Separate from FonderieClient on purpose, for the same reason as\n// CourierAdminClient: @fonderie/config's admin routes (/admin/config/*,\n// /admin/secrets/*) are guarded by a static bearer token configured on the\n// server, not the signed-in user's session. Construct with that token\n// directly; it shares no state with AuthClient/BillingClient/WorkspacesClient.\nexport class ConfigAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\n\tconstructor(opts: IConfigAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t}\n\n\t// ── Config ───────────────────────────────────────────────────────────────\n\n\tlistConfig(environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetConfig(key: string, input: ISetConfigInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tdeleteConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tlistConfigRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config/${key}/revisions${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollbackConfig(key: string, input: IRollbackInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/config/${key}/rollback${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\t// ── Secrets (masked) ─────────────────────────────────────────────────────\n\n\tlistSecrets(environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetSecret(key: string, input: ISetSecretInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tdeleteSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tlistSecretRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets/${key}/revisions${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollbackSecret(key: string, input: IRollbackInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/secrets/${key}/rollback${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\t// POST (not GET) so the decrypted value never lands in a URL or access log.\n\trevealSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IRevealSecretResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/secrets/${key}/reveal${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n}\n","import { HttpClient } from '../http';\nimport type { IApiResponse, ITemplateEntry, ITemplateRevision } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ISetTemplateInput {\n\ttext: string;\n\tsubject?: string;\n\thtml?: string;\n\tactive?: boolean;\n\tifVersion?: number;\n}\n\nexport interface IRollbackTemplateInput {\n\ttoVersion: number;\n}\n\nexport interface ICourierAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n}\n\n// ── Courier admin client ─────────────────────────────────────────────────────\n//\n// Separate from FonderieClient on purpose: @fonderie/courier's admin routes\n// (/admin/templates/*) are guarded by a static bearer token configured on the\n// server (CourierModule's adminToken), not the signed-in user's session —\n// the same model @fonderie/config's admin surface uses, and the one the\n// `fonderie template`/`fonderie config` CLI commands already speak to via\n// FONDERIE_ADMIN_URL/FONDERIE_ADMIN_TOKEN. Bundling this into FonderieClient\n// would suggest an end-user's session token can reach it, which it can't —\n// this is an ops/admin-dashboard client, constructed with its own token.\nexport class CourierAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\n\tconstructor(opts: ICourierAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t}\n\n\tlistTemplates() {\n\t\treturn this.http.request<IApiResponse<ITemplateEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/admin/templates',\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetTemplate(type: string, input: ISetTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tdeleteTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tlistRevisions(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/templates/${type}/revisions${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollback(type: string, input: IRollbackTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/templates/${type}/rollback${q}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n}\n","// Per-call read options accepted by the typed sub-clients' GET methods.\nexport interface IReadOptions {\n\t// Ignore any cached value and refresh it (pull-to-refresh semantics).\n\tbust?: boolean | undefined;\n}\n\n// ── Envelope ─────────────────────────────────────────────────────────────────\n\nexport interface IApiResponse<T = undefined> {\n\treason: string;\n\texplanation: string;\n\tresult: T;\n}\n\nexport interface IApiError {\n\treason: string;\n\texplanation: string;\n\tdetails?: unknown;\n}\n\n// ── User ─────────────────────────────────────────────────────────────────────\n\nexport interface IUserPreferences {\n\tlocale: string;\n\ttimezone: string;\n\tnotifications: { email: boolean; inApp: boolean; sms: boolean; push: boolean };\n\temailDigest: string;\n\tdateFormat: string;\n\ttimeFormat: string;\n}\n\nexport interface IUserSkill {\n\tname: string;\n\tlevel: string;\n}\n\nexport interface IUserDTO {\n\tid: string;\n\temail: string;\n\tfirstName: string;\n\tlastName: string;\n\tphone: string;\n\tprofileImageUrl: string;\n\tisActive: boolean;\n\tlastLogin: string;\n\tskills: IUserSkill[];\n\tpreferences: IUserPreferences;\n\tisEmailVerified: boolean;\n\tmfaEnabled: boolean;\n\tsuspended: boolean;\n\twhitelist: boolean;\n\tipWhitelist: string[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ITokens {\n\taccess: string;\n\trefresh: string;\n}\n\n// ── Auth endpoint results ─────────────────────────────────────────────────────\n\nexport interface IRegisterResult {\n\ttokens: ITokens;\n\tuser: IUserDTO;\n}\n\nexport interface ILoginResult {\n\ttokens: ITokens;\n\tuser: IUserDTO;\n}\n\n// Login response when the account has MFA enabled: no tokens yet — complete\n// the login with auth.mfa.verifyLogin(mfaToken, code).\nexport interface IMfaRequiredResult {\n\tmfaToken: string;\n}\n\nexport function isMfaRequired(result: ILoginResult | IMfaRequiredResult): result is IMfaRequiredResult {\n\treturn !('tokens' in result);\n}\n\nexport interface IRefreshResult {\n\ttokens: ITokens;\n}\n\nexport interface IVerifyEmailResult {\n\tverified: boolean;\n\temail: string;\n}\n\nexport interface IResendVerificationResult {\n\tstat: string;\n\tmessage: string;\n\tdata: {\n\t\ttoken: string;\n\t\texpiresAt: string;\n\t\temail: string;\n\t};\n}\n\nexport interface IMeResult {\n\tuser: IUserDTO;\n}\n\nexport interface IMfaSetupResult {\n\t// Data-URI QR code to scan, plus the one-time backup codes generated at\n\t// setup — matches @fonderie/auth's /auth/mfa/setup response.\n\tqr: string;\n\tbackupCodes: string[];\n}\n\nexport interface IMfaEnabledResult {\n\ttokens: ITokens;\n\tuser: IUserDTO;\n}\n\n// ── Billing ──────────────────────────────────────────────────────────────────\n\nexport interface IPlanFeature {\n\tname: string;\n\tdescription: string;\n\tenabled: boolean;\n\tlimit?: number;\n}\n\nexport interface IPlanDTO {\n\tid: string;\n\tplanId: string;\n\tname: string;\n\tdescription: string;\n\ttier: number;\n\tseats: number | null;\n\ttrialDays: number;\n\tpricing: {\n\t\tmonthly: number; // in cents, e.g. 1999 = $19.99\n\t\tyearly: number; // in cents\n\t\tcurrency: string; // ISO 4217, e.g. 'USD'\n\t};\n\tfeatures: IPlanFeature[];\n\tmetadata: Record<string, unknown>;\n}\n\nexport type SubscriberType = 'user' | 'workspace';\n\nexport interface ISubscriptionDTO {\n\tid: string;\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\tplan: string;\n\tinterval: string;\n\tstatus: string;\n\tcancelAtPeriodEnd: boolean;\n\tcurrentPeriodStart: string | null;\n\tcurrentPeriodEnd: string | null;\n\ttrialEndsAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IPlanListResult {\n\tplans: IPlanDTO[];\n}\n\nexport interface IPlanResult {\n\tplan: IPlanDTO;\n}\n\nexport interface ISubscriptionResult {\n\tsubscription: ISubscriptionDTO;\n}\n\nexport interface ICheckoutUrlResult {\n\turl: string;\n}\n\nexport interface IPortalUrlResult {\n\turl: string;\n}\n\nexport interface IUsageResult {\n\tmetric: string;\n\ttotal: number;\n\tsince: string;\n}\n\n// ── Workspaces ───────────────────────────────────────────────────────────────\n\nexport interface IWorkspaceAddressDTO {\n\tline1: string;\n\tline2: string;\n\tcity: string;\n\tstate: string;\n\tzip: string;\n\tcountry: string;\n}\n\nexport interface IWorkspaceDTO {\n\tid: string;\n\tname: string;\n\tslug: string;\n\ttype: string;\n\tdescription: string;\n\tmotto: string;\n\tphone: string;\n\tbusinessType: string;\n\taddress: IWorkspaceAddressDTO;\n\tplan: string;\n\townerId: string;\n\tisPersonal: boolean;\n\tisArchived: boolean;\n\tarchivedAt: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface IRoleDTO {\n\tid: string;\n\tname: string;\n\tisSystem: boolean;\n\tactive: boolean;\n\tdescription: string;\n\tworkspaceId: string;\n}\n\nexport interface IMemberDTO {\n\tuserId: string;\n\tworkspaceId: string;\n\troleId: string;\n\troleName: string;\n\tconfirmed: boolean;\n\tcreatedAt: string;\n}\n\nexport interface IInvitationDTO {\n\tid: string;\n\tworkspaceId: string;\n\temail: string;\n\troleId: string;\n\ttoken: string;\n\tstatus: string;\n\texpiresAt: string;\n\tcreatedAt: string;\n}\n\nexport interface IWorkspaceSettingsDTO {\n\tlocale: string;\n\ttimezone: string;\n\tcurrency: string;\n\tdateFormat: string;\n\ttimeFormat: string;\n}\n\nexport interface IWorkspaceListResult {\n\tworkspaces: IWorkspaceDTO[];\n}\n\nexport interface IWorkspaceResult {\n\tworkspace: IWorkspaceDTO;\n}\n\nexport interface IMemberListResult {\n\tmembers: IMemberDTO[];\n}\n\nexport interface IRoleListResult {\n\troles: IRoleDTO[];\n}\n\nexport interface IRoleResult {\n\trole: IRoleDTO;\n}\n\nexport interface IInvitationListResult {\n\tinvitations: IInvitationDTO[];\n}\n\nexport interface IInviteResult {\n\tinvitations: Array<{ invitationId: string; email: string }>;\n}\n\nexport interface IAcceptInvitationResult {\n\tworkspaceId: string;\n}\n\nexport interface IWorkspaceSettingsResult {\n\tsettings: IWorkspaceSettingsDTO;\n}\n\n// ── Courier admin (template management) ─────────────────────────────────────\n// Admin-token authenticated, not user-session authenticated — see\n// CourierAdminClient. Result shapes here are the raw resource, not wrapped\n// in a named key, matching @fonderie/courier's admin route handlers.\n\nexport interface ITemplateEntry {\n\ttype: string;\n\tlocale: string | null;\n\tsubject: string | null;\n\thtml: string | null;\n\ttext: string;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface ITemplateRevision {\n\ttype: string;\n\tlocale: string | null;\n\tsubject: string | null;\n\thtml: string | null;\n\ttext: string;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\n// ── Config admin (feature flags / remote config + secrets) ──────────────────\n// Admin-token authenticated, not user-session authenticated — see\n// ConfigAdminClient. Result shapes here are the raw resource, matching\n// @fonderie/config's admin route handlers.\n\nexport interface IConfigEntry {\n\tkey: string;\n\tvalue: unknown;\n\tenvironment: string;\n\tdescription: string | null;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface IConfigRevision {\n\tkey: string;\n\tenvironment: string;\n\tvalue: unknown;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\n// Deliberately has no `value` — admin list/get never return a secret's\n// plaintext, only the explicit reveal path does.\nexport interface ISecretEntry {\n\tkey: string;\n\tenvironment: string;\n\tdescription: string | null;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface ISecretRevision {\n\tkey: string;\n\tenvironment: string;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IRevealSecretResult {\n\tvalue: string;\n}\n\n// ── Audit ────────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces) — unlike courier-admin/config-admin,\n// which use a standalone admin token. Read-only: @fonderie/audit has one route.\n\nexport interface IAuditEventDTO {\n\tid: string;\n\ttype: string;\n\tactorId: string | null;\n\trequestId: string | null;\n\tpayload: Record<string, unknown>;\n\tcreatedAt: string;\n}\n\nexport interface IAuditPageResult {\n\tevents: IAuditEventDTO[];\n\tnextCursor: string | null;\n}\n\n// ── Webhooks ─────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces/audit).\n\nexport interface IWebhookEndpointDTO {\n\tid: string;\n\turl: string;\n\tevents: string[];\n\tenabled: boolean;\n\tcreatedAt: string;\n}\n\n// The signing secret is only ever returned here, at creation — every other\n// read masks it, matching @fonderie/webhooks' own toEndpointDTO/toEndpointCreatedDTO split.\nexport interface IWebhookEndpointCreatedDTO extends IWebhookEndpointDTO {\n\tsecret: string;\n}\n\nexport interface IWebhookDeliveryDTO {\n\tid: string;\n\teventId: string;\n\teventType: string;\n\tstatus: string;\n\tattempts: number;\n\tresponseStatus: number | null;\n\tdeliveredAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IWebhookEndpointListResult {\n\tendpoints: IWebhookEndpointDTO[];\n}\n\nexport interface IWebhookDeliveryListResult {\n\tdeliveries: IWebhookDeliveryDTO[];\n}\n\nexport interface ITestWebhookResult {\n\tstatus: number | null;\n\tok: boolean;\n\terror?: string;\n}\n\n// ── Customers ────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces/audit/webhooks).\n\nexport type CustomerType = 'individual' | 'business';\nexport type CustomerSex = 'UNKNOWN' | 'MALE' | 'FEMALE';\nexport type CustomerLabelType = 'phone' | 'email' | 'address';\n\nexport interface ICustomerDTO {\n\tid: string;\n\ttype: string;\n\tsex: CustomerSex;\n\tfirstName: string;\n\tlastName: string;\n\tcompanyName: string;\n\tavatarUrl: string;\n\tlocale: string;\n\treferenceCode: string;\n\treferralCode: string;\n\treferredBy: string | null;\n\tblacklisted: { status: boolean; reason: string | null };\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ICustomerEmailDTO {\n\tid: string;\n\temail: string;\n\tlabel: string;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\nexport interface ICustomerPhoneDTO {\n\tid: string;\n\tphone: string;\n\tlabel: string;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\nexport interface IAddressDTO {\n\tcountryIso: string;\n\tsubdivision1Iso: string;\n\tsubdivision2Iso: string;\n\tzipPostalCode: string;\n\tunit: string;\n\tline1: string;\n\tline2: string;\n}\n\nexport interface ICustomerAddressDTO {\n\tid: string;\n\tlabel: string;\n\tisPrimary: boolean;\n\taddress: IAddressDTO;\n}\n\nexport interface ICustomerNoteDTO {\n\tid: string;\n\tauthorId: string;\n\tbody: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ICustomerRelationshipDTO {\n\tid: string;\n\trelatedId: string;\n\trelationship: string;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\n// Flat merge: relationship metadata + related customer fields spread at the\n// same level. `id` is the relationship record id; `customerId` is the\n// related customer's id — matches @fonderie/customers' own flattening.\nexport type ICustomerRelationshipExpandedDTO = Omit<ICustomerShallowDTO, 'id'> & {\n\tid: string;\n\tcustomerId: string;\n\trelationship: string;\n\tisPrimary: boolean;\n};\n\nexport type ICustomerRelationshipExpandedD2DTO = ICustomerRelationshipExpandedDTO & {\n\trelationships: ICustomerRelationshipExpandedDTO[];\n};\n\nexport interface ICustomerShallowDTO extends ICustomerDTO {\n\temails: ICustomerEmailDTO[];\n\tphones: ICustomerPhoneDTO[];\n\taddresses: ICustomerAddressDTO[];\n\tnotes: ICustomerNoteDTO[];\n\ttags: string[];\n}\n\nexport interface ICustomerDetailDTO extends ICustomerDTO {\n\temails: ICustomerEmailDTO[];\n\tphones: ICustomerPhoneDTO[];\n\taddresses: ICustomerAddressDTO[];\n\tnotes: ICustomerNoteDTO[];\n\trelationships: ICustomerRelationshipExpandedDTO[];\n\ttags: string[];\n}\n\n// depth=1 (default via getCustomer) — one level of relationship expansion.\n// depth=2 (getCustomer(id, { depth: 2 })) — relationships carry their own\n// relationships array one level deeper. Matches @fonderie/customers' D2 DTOs.\nexport interface ICustomerDetailD2DTO extends Omit<ICustomerDetailDTO, 'relationships'> {\n\trelationships: ICustomerRelationshipExpandedD2DTO[];\n}\n\nexport interface ICustomerLabelDTO {\n\tid: string;\n\ttype: CustomerLabelType;\n\tvalue: string;\n\tcreatedAt: string;\n}\n\nexport interface ICustomerListResult {\n\tcustomers: ICustomerDTO[];\n\t// Total matching rows regardless of limit/offset — for pagination.\n\ttotal: number;\n}\n\nexport interface ICustomerResult {\n\tcustomer: ICustomerDTO;\n}\n\nexport interface ICustomerEmailListResult {\n\temails: ICustomerEmailDTO[];\n}\n\nexport interface ICustomerEmailResult {\n\temail: ICustomerEmailDTO;\n}\n\nexport interface ICustomerPhoneListResult {\n\tphones: ICustomerPhoneDTO[];\n}\n\nexport interface ICustomerPhoneResult {\n\tphone: ICustomerPhoneDTO;\n}\n\nexport interface ICustomerAddressListResult {\n\taddresses: ICustomerAddressDTO[];\n}\n\nexport interface ICustomerAddressResult {\n\taddress: ICustomerAddressDTO;\n}\n\nexport interface ICustomerNoteListResult {\n\tnotes: ICustomerNoteDTO[];\n}\n\nexport interface ICustomerNoteResult {\n\tnote: ICustomerNoteDTO;\n}\n\nexport interface ICustomerTagListResult {\n\ttags: string[];\n}\n\nexport interface ICustomerRelationshipListResult {\n\trelationships: ICustomerRelationshipDTO[];\n}\n\nexport interface ICustomerRelationshipResult {\n\trelationship: ICustomerRelationshipDTO;\n}\n\nexport interface ICustomerLabelListResult {\n\tlabels: ICustomerLabelDTO[];\n}\n"],"mappings":"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","names":["data"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/cache.ts","../src/http.ts","../src/modules/audit.ts","../src/modules/auth.ts","../src/modules/billing.ts","../src/modules/customers.ts","../src/modules/webhooks.ts","../src/modules/workspaces.ts","../src/token-store.ts","../src/client.ts","../src/modules/config-admin.ts","../src/modules/courier-admin.ts","../src/types.ts"],"sourcesContent":["export type { IClientAuthConfig, IFonderieClientOptions, IRequestConfig } from './client';\nexport type { ICache, IMemoryCacheOptions } from './cache';\nexport { createMemoryCache } from './cache';\nexport { FonderieClient } from './client';\nexport { FonderieApiError } from './http';\nexport type { IListAuditEventsInput } from './modules/audit';\nexport { AuditClient } from './modules/audit';\nexport type {\n\tIChangePasswordInput,\n\tILoginInput,\n\tIRegisterInput,\n\tIResetPasswordInput,\n\tIUpdatePreferencesInput,\n\tIUpdateProfileInput,\n} from './modules/auth';\nexport { AuthClient } from './modules/auth';\nexport type {\n\tICheckoutInput,\n\tICreatePlanInput,\n\tIRecordUsageInput,\n\tIUpdatePlanInput,\n} from './modules/billing';\nexport { BillingClient } from './modules/billing';\nexport type {\n\tIConfigAdminClientOptions,\n\tIRollbackInput,\n\tISetConfigInput,\n\tISetSecretInput,\n} from './modules/config-admin';\nexport { ConfigAdminClient } from './modules/config-admin';\nexport type {\n\tICourierAdminClientOptions,\n\tIRollbackTemplateInput,\n\tISetTemplateInput,\n} from './modules/courier-admin';\nexport { CourierAdminClient } from './modules/courier-admin';\nexport type {\n\tIAddAddressInput,\n\tIAddEmailInput,\n\tIAddPhoneInput,\n\tIAddRelationshipInput,\n\tIBlacklistCustomerInput,\n\tICreateCustomerInput,\n\tIGetCustomerInput,\n\tIListCustomersInput,\n\tIUpdateCustomerInput,\n} from './modules/customers';\nexport { CustomersClient } from './modules/customers';\nexport type {\n\tICreateWebhookEndpointInput,\n\tIUpdateWebhookEndpointInput,\n} from './modules/webhooks';\nexport { WebhooksClient } from './modules/webhooks';\nexport type {\n\tICreateRoleInput,\n\tICreateWorkspaceInput,\n\tIInviteEntry,\n\tIRolePermission,\n\tIRolePermissionInput,\n\tIRolePermissionsResult,\n\tIUpdateRoleInput,\n\tIUpdateSettingsInput,\n\tIUpdateWorkspaceInput,\n} from './modules/workspaces';\nexport { WorkspacesClient } from './modules/workspaces';\nexport type {\n\tCustomerLabelType,\n\tCustomerSex,\n\tCustomerType,\n\tIAcceptInvitationResult,\n\tIAddressDTO,\n\tIApiError,\n\tIApiResponse,\n\tIAuditEventDTO,\n\tIAuditPageResult,\n\tICheckoutUrlResult,\n\tIConfigEntry,\n\tIConfigRevision,\n\tICustomerAddressDTO,\n\tICustomerAddressListResult,\n\tICustomerAddressResult,\n\tICustomerDetailD2DTO,\n\tICustomerDetailDTO,\n\tICustomerDTO,\n\tICustomerEmailDTO,\n\tICustomerEmailListResult,\n\tICustomerEmailResult,\n\tICustomerLabelDTO,\n\tICustomerLabelListResult,\n\tICustomerListResult,\n\tICustomerNoteDTO,\n\tICustomerNoteListResult,\n\tICustomerNoteResult,\n\tICustomerPhoneDTO,\n\tICustomerPhoneListResult,\n\tICustomerPhoneResult,\n\tICustomerRelationshipDTO,\n\tICustomerRelationshipExpandedD2DTO,\n\tICustomerRelationshipExpandedDTO,\n\tICustomerRelationshipListResult,\n\tICustomerRelationshipResult,\n\tICustomerResult,\n\tICustomerShallowDTO,\n\tICustomerTagListResult,\n\tIInvitationDTO,\n\tIInvitationListResult,\n\tIInviteResult,\n\tILoginResult,\n\tIMemberDTO,\n\tIMemberListResult,\n\tIMeResult,\n\tIMfaEnabledResult,\n\tIMfaRequiredResult,\n\tIMfaSetupResult,\n\tIPlanDTO,\n\tIPlanFeature,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tIRefreshResult,\n\tIReadOptions,\n\tIRegisterResult,\n\tIResendVerificationResult,\n\tIRevealSecretResult,\n\tIRoleDTO,\n\tIRoleListResult,\n\tIRoleResult,\n\tISecretEntry,\n\tISecretRevision,\n\tISubscriptionDTO,\n\tISubscriptionResult,\n\tITemplateEntry,\n\tITemplateRevision,\n\tITestWebhookResult,\n\tITokens,\n\tIUsageResult,\n\tIUserDTO,\n\tIUserPreferences,\n\tIVerifyEmailResult,\n\tIWebhookDeliveryDTO,\n\tIWebhookDeliveryListResult,\n\tIWebhookEndpointCreatedDTO,\n\tIWebhookEndpointDTO,\n\tIWebhookEndpointListResult,\n\tIWorkspaceAddressDTO,\n\tIWorkspaceDTO,\n\tIWorkspaceListResult,\n\tIWorkspaceResult,\n\tIWorkspaceSettingsDTO,\n\tIWorkspaceSettingsResult,\n\tSubscriberType,\n} from './types';\nexport { isMfaRequired } from './types';\n","// Optional response cache for FonderieClient. A cache instance is created per\n// client (never module-global) so it is safe on a server — one client per\n// request means no cross-user/tenant leakage. It sweeps lazily on read, so\n// there is no background timer keeping a process alive.\n\nexport interface ICache {\n\t// Returns the cached value if present and still within its TTL, else undefined.\n\tget<T>(key: string): T | undefined;\n\t// Stores a value with a per-entry TTL (ms).\n\tset<T>(key: string, value: T, ttlMs: number): void;\n\t// Deduplicates concurrent in-flight requests for the same key.\n\tdedupe<T>(key: string, fn: () => Promise<T>): Promise<T>;\n\t// Evicts every entry whose key contains `fragment` (and cancels in-flight\n\t// dedupe for those), so a write can bust the reads it affects.\n\tinvalidate(fragment: string): void;\n\tclear(): void;\n}\n\nexport interface IMemoryCacheOptions {\n\t// Default TTL (ms) applied to cached GETs when a call doesn't specify one.\n\tdefaultTtlMs?: number;\n}\n\ninterface Entry {\n\tvalue: unknown;\n\texpiresAt: number;\n}\n\nexport function createMemoryCache(opts: IMemoryCacheOptions = {}): ICache & { defaultTtlMs: number } {\n\tconst store = new Map<string, Entry>();\n\tconst inflight = new Map<string, Promise<unknown>>();\n\tconst defaultTtlMs = opts.defaultTtlMs ?? 60_000;\n\n\treturn {\n\t\tdefaultTtlMs,\n\n\t\tget<T>(key: string): T | undefined {\n\t\t\tconst entry = store.get(key);\n\t\t\tif (!entry) return undefined;\n\t\t\tif (Date.now() > entry.expiresAt) {\n\t\t\t\tstore.delete(key); // lazy sweep\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn entry.value as T;\n\t\t},\n\n\t\tset<T>(key: string, value: T, ttlMs: number): void {\n\t\t\tstore.set(key, { value, expiresAt: Date.now() + ttlMs });\n\t\t},\n\n\t\tdedupe<T>(key: string, fn: () => Promise<T>): Promise<T> {\n\t\t\tconst existing = inflight.get(key);\n\t\t\tif (existing) return existing as Promise<T>;\n\t\t\tconst req = fn().finally(() => inflight.delete(key));\n\t\t\tinflight.set(key, req);\n\t\t\treturn req;\n\t\t},\n\n\t\tinvalidate(fragment: string): void {\n\t\t\tfor (const key of store.keys()) if (key.includes(fragment)) store.delete(key);\n\t\t\tfor (const key of inflight.keys()) if (key.includes(fragment)) inflight.delete(key);\n\t\t},\n\n\t\tclear(): void {\n\t\t\tstore.clear();\n\t\t\tinflight.clear();\n\t\t},\n\t};\n}\n","import type { ICache } from './cache';\nimport type { IApiError } from './types';\n\nexport class FonderieApiError extends Error {\n\tconstructor(\n\t\tpublic readonly reason: string,\n\t\tpublic readonly explanation: string,\n\t\tpublic readonly status: number,\n\t\tpublic readonly details?: unknown,\n\t) {\n\t\tsuper(explanation);\n\t\tthis.name = 'FonderieApiError';\n\t}\n}\n\nexport interface IRequestOptions {\n\tmethod: string;\n\tpath: string;\n\tbody?: unknown;\n\ttoken?: string | undefined;\n\tcookie?: string | undefined;\n\t// Resolves the billing subscriber to a workspace (@fonderie/billing's\n\t// resolveSubscriber falls back to the session user when omitted).\n\tworkspaceId?: string | undefined;\n\t// Extra request headers (e.g. the admin surfaces' X-Actor attribution).\n\theaders?: Record<string, string> | undefined;\n\t// Cache control (only applies when the client was given a cache):\n\t// cache: number → cache this GET for that many ms\n\t// cache: false → skip the cache for this GET\n\t// bust: true → ignore any cached value and refresh it\n\t// invalidate → extra key fragments to evict after a successful write\n\tcache?: number | false | undefined;\n\tbust?: boolean | undefined;\n\tinvalidate?: string[] | undefined;\n}\n\nexport interface IHttpDeps {\n\tcache?: ICache | undefined;\n\tdefaultTtlMs?: number | undefined;\n\t// Called once on a 401 (except for /auth/* requests). Returns a fresh access\n\t// token to retry with, or undefined to let the 401 surface. Callers should\n\t// make this single-flight.\n\trefresh?: (() => Promise<string | undefined>) | undefined;\n}\n\nexport class HttpClient {\n\tprivate cache: ICache | undefined;\n\tprivate defaultTtlMs: number;\n\tprivate refresh: (() => Promise<string | undefined>) | undefined;\n\n\tconstructor(\n\t\tprivate baseUrl: string,\n\t\tdeps: IHttpDeps = {},\n\t) {\n\t\tthis.cache = deps.cache;\n\t\tthis.defaultTtlMs = deps.defaultTtlMs ?? 60_000;\n\t\tthis.refresh = deps.refresh;\n\t}\n\n\t// Drop all cached responses — sign-out must not leave one session's data\n\t// servable to the next.\n\tclearCache(): void {\n\t\tthis.cache?.clear();\n\t}\n\n\tasync request<T>(opts: IRequestOptions): Promise<T> {\n\t\tconst method = opts.method.toUpperCase();\n\n\t\tconst cache = this.cache;\n\n\t\t// ── Read path: serve/populate cache (GET only, opt-in) ──────────────────\n\t\tif (cache && method === 'GET' && opts.cache !== false) {\n\t\t\tconst key = `GET ${opts.path}::ws=${opts.workspaceId ?? ''}`;\n\t\t\tif (!opts.bust) {\n\t\t\t\tconst hit = cache.get<T>(key);\n\t\t\t\tif (hit !== undefined) return hit;\n\t\t\t}\n\t\t\tconst ttl = typeof opts.cache === 'number' ? opts.cache : this.defaultTtlMs;\n\t\t\treturn cache.dedupe(key, async () => {\n\t\t\t\tconst data = await this.exec<T>(opts);\n\t\t\t\tcache.set(key, data, ttl);\n\t\t\t\treturn data;\n\t\t\t});\n\t\t}\n\n\t\tconst data = await this.exec<T>(opts);\n\n\t\t// ── Write path: bust the reads this mutation affects ────────────────────\n\t\tif (cache && method !== 'GET') {\n\t\t\tconst resource = opts.path.split('?')[0]?.split('/').filter(Boolean)[0];\n\t\t\tif (resource) cache.invalidate(`/${resource}`);\n\t\t\tfor (const fragment of opts.invalidate ?? []) cache.invalidate(fragment);\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tprivate async exec<T>(opts: IRequestOptions, retried = false): Promise<T> {\n\t\tconst headers: Record<string, string> = { 'Content-Type': 'application/json' };\n\t\tif (opts.token) headers['Authorization'] = `Bearer ${opts.token}`;\n\t\tif (opts.cookie) headers['Cookie'] = opts.cookie;\n\t\tif (opts.workspaceId) headers['X-Workspace-ID'] = opts.workspaceId;\n\t\tObject.assign(headers, opts.headers ?? {});\n\n\t\tconst fetchInit: RequestInit = { method: opts.method, headers, credentials: 'include' };\n\t\tif (opts.body !== undefined) fetchInit.body = JSON.stringify(opts.body);\n\n\t\tconst res = await fetch(`${this.baseUrl}${opts.path}`, fetchInit);\n\n\t\t// Reactive renew: on a 401, refresh once and retry (never for /auth/* to\n\t\t// avoid recursing through the refresh/login endpoints themselves).\n\t\tif (res.status === 401 && this.refresh && !retried && !opts.path.startsWith('/auth/')) {\n\t\t\tconst newToken = await this.refresh();\n\t\t\tif (newToken) return this.exec<T>({ ...opts, token: newToken }, true);\n\t\t}\n\n\t\t// 204 No Content (e.g. some DELETE routes) has no body to parse.\n\t\tif (res.status === 204) {\n\t\t\tif (!res.ok) throw new FonderieApiError('unknown', res.statusText, res.status);\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\tconst data = (await res.json()) as T | IApiError;\n\n\t\tif (!res.ok || res.status === 202) {\n\t\t\tconst err = data as IApiError;\n\t\t\tthrow new FonderieApiError(err.reason, err.explanation, res.status, err.details);\n\t\t}\n\n\t\treturn data as T;\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions, IApiResponse, IAuditPageResult } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface IListAuditEventsInput {\n\ttype?: string;\n\tactorId?: string;\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// ── Audit client ─────────────────────────────────────────────────────────────\n\nexport class AuditClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes the audit query to a workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\tlistEvents(input: IListAuditEventsInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.type) params.set('type', input.type);\n\t\tif (input.actorId) params.set('actorId', input.actorId);\n\t\tif (input.from) params.set('from', input.from.toISOString());\n\t\tif (input.to) params.set('to', input.to.toISOString());\n\t\tif (input.cursor) params.set('cursor', input.cursor);\n\t\tconst qs = params.toString();\n\n\t\treturn this.http.request<IApiResponse<IAuditPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/audit${qs ? `?${qs}` : ''}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tILoginResult,\n\tIMfaRequiredResult,\n\tIMeResult,\n\tIMfaEnabledResult,\n\tIMfaSetupResult,\n\tIRefreshResult,\n\tIRegisterResult,\n\tIResendVerificationResult,\n\tIVerifyEmailResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\n// NOTE: the server's register/login schemas also accept a { phone } variant\n// (OTP-based phone auth). It is deliberately not surfaced in the typed client\n// yet — doing it properly needs a verifyPhone completion method plus hooks in\n// all three frontend frameworks, which is its own cycle. Tracked in\n// docs/DTO-GAP-AUDIT.md.\nexport interface IRegisterInput {\n\temail: string;\n\tpassword: string;\n\tfirstName?: string;\n\tlastName?: string;\n}\n\nexport interface ILoginInput {\n\temail: string;\n\tpassword: string;\n}\n\nexport interface IResetPasswordInput {\n\t// The 6-digit code emailed by forgotPassword. Matches @fonderie/auth's\n\t// resetPasswordSchema ({ pin, password }); the route is POST /auth/email/reset.\n\tpin: string;\n\tpassword: string;\n}\n\n// User updates are split by @fonderie/auth into dedicated, individually\n// validated routes — there is no combined /users/update endpoint.\nexport interface IUpdateProfileInput {\n\t// Explicit null clears the field server-side (same pattern as\n\t// IUpdateWorkspaceInput); undefined leaves it untouched.\n\tfirstName?: string | null;\n\tlastName?: string | null;\n\tavatarUrl?: string | null;\n}\n\nexport interface IUpdatePreferencesInput {\n\tlocale?: string;\n\ttimezone?: string;\n\t// Replaces the stored notifications object; flags left out fall back to\n\t// the server defaults on read.\n\tnotifications?: { email?: boolean; inApp?: boolean; sms?: boolean; push?: boolean };\n\temailDigest?: string;\n\tdateFormat?: string;\n\ttimeFormat?: string;\n}\n\nexport interface IChangePasswordInput {\n\tcurrentPassword: string;\n\tnewPassword: string;\n}\n\n// ── MFA sub-client ───────────────────────────────────────────────────────────\n\nclass MfaClient {\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate token: () => string | undefined,\n\t) {}\n\n\tsetup() {\n\t\treturn this.http.request<IApiResponse<IMfaSetupResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/setup',\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\tverify(token: string) {\n\t\treturn this.http.request<IApiResponse<IMfaEnabledResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/verify',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\t// MFA-login: complete a login that returned MFA_REQUIRED. Authenticates with\n\t// the temporary `mfaToken` (not the session) and verifies the TOTP `code` —\n\t// same route as `verify`, different auth context. Returns the completed login.\n\tverifyLogin(mfaToken: string, code: string) {\n\t\treturn this.http.request<IApiResponse<ILoginResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/verify',\n\t\t\tbody: { token: code },\n\t\t\ttoken: mfaToken,\n\t\t});\n\t}\n\n\tdisable(token: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/disable',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n\n\t// POST /auth/mfa/backup-codes (mfaTokenSchema { token }) — returns a fresh set.\n\tregenerateBackupCodes(token: string) {\n\t\treturn this.http.request<IApiResponse<{ backupCodes: string[] }>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/mfa/backup-codes',\n\t\t\tbody: { token },\n\t\t\ttoken: this.token(),\n\t\t});\n\t}\n}\n\n// ── Auth client ──────────────────────────────────────────────────────────────\n\nexport class AuthClient {\n\treadonly mfa: MfaClient;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {\n\t\tthis.mfa = new MfaClient(http, () => this.tokens.get());\n\t}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t\t// Signing out (token → undefined) also drops the shared response cache,\n\t\t// so the hooks' logout paths can't leak one session's data to the next.\n\t\tif (!token) this.http.clearCache();\n\t}\n\n\t// ── Public ─────────────────────────────────────────────────────────────────\n\n\tregister(input: IRegisterInput) {\n\t\treturn this.http.request<IApiResponse<IRegisterResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/register',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\tlogin(input: ILoginInput) {\n\t\treturn this.http.request<IApiResponse<ILoginResult | IMfaRequiredResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/login',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\trefreshTokens(refreshToken?: string) {\n\t\treturn this.http.request<IApiResponse<IRefreshResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/refresh',\n\t\t\tbody: refreshToken ? { refreshToken } : undefined,\n\t\t});\n\t}\n\n\tforgotPassword(email: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/email/forgot',\n\t\t\tbody: { email },\n\t\t});\n\t}\n\n\tresetPassword(input: IResetPasswordInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/email/reset',\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\tverifyEmail(token: string) {\n\t\t// @fonderie/auth registers this as POST /auth/verify with body { token }\n\t\t// (verifySchema = { token: sixDigitPin }).\n\t\treturn this.http.request<IApiResponse<IVerifyEmailResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/verify',\n\t\t\tbody: { token },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Protected ──────────────────────────────────────────────────────────────\n\n\tlogout(refreshToken?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/logout',\n\t\t\tbody: refreshToken ? { refreshToken } : undefined,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tsendVerificationEmail() {\n\t\t// @fonderie/auth registers this as GET /auth/send-verification (requireAuth).\n\t\treturn this.http.request<IApiResponse<IResendVerificationResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/send-verification',\n\t\t\ttoken: this.tokens.get(),\n\t\t\t// A send-action on a GET route: never serve it from the cache, or a\n\t\t\t// resend inside the TTL would silently no-op.\n\t\t\tcache: false,\n\t\t});\n\t}\n\n\t// ── Protected + Verified ───────────────────────────────────────────────────\n\n\tgetUser(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/users',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateProfile(input: IUpdateProfileInput) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/profile',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePreferences(input: IUpdatePreferencesInput) {\n\t\treturn this.http.request<IApiResponse<IMeResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/preferences',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdateEmail(email: string) {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/email',\n\t\t\tbody: { email },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePhone(phone: string) {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/phone',\n\t\t\tbody: { phone },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tchangePassword(input: IChangePasswordInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/users/password',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// GET /users/export — the caller's own data as a portable bundle (SAR).\n\texportData() {\n\t\treturn this.http.request<IApiResponse<unknown>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/users/export',\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tdeleteUser() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/users',\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tICheckoutUrlResult,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tISubscriptionResult,\n\tIUsageResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICheckoutInput {\n\tplan: string;\n\tinterval?: 'month' | 'year';\n}\n\nexport interface IRecordUsageInput {\n\tmetric: string;\n\tquantity?: number;\n}\n\nexport interface ICreatePlanInput {\n\tname: string;\n\tdescription?: string | null;\n\ttier?: number;\n\tseats?: number | null;\n\ttrialDays?: number;\n\tmonthlyAmount?: number | null;\n\tmonthlyPriceId?: string | null;\n\tyearlyAmount?: number | null;\n\tyearlyPriceId?: string | null;\n\tfeatures?: unknown;\n\tmetadata?: unknown;\n}\n\nexport type IUpdatePlanInput = Partial<ICreatePlanInput>;\n\n// ── Billing client ───────────────────────────────────────────────────────────\n\nexport class BillingClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Subscriber is resolved from this workspace ID (X-Workspace-ID) when set,\n\t// falling back to the session user otherwise — see @fonderie/billing's\n\t// resolveSubscriber. Call with undefined to bill the signed-in user directly.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Plans — public read-only ────────────────────────────────────────────────\n\n\tlistPlans(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPlanListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/plans',\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tgetPlan(planId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// ── Plans — admin write ──────────────────────────────────────────────────────\n\t// Unlike every other write in this client, @fonderie/billing does not gate\n\t// these with requireAuth or an admin token — \"the caller is responsible for\n\t// authorization\" (its own routes.ts comment). Sending the session token is\n\t// harmless (the server ignores it) but does nothing on its own; gate access\n\t// to these calls yourself (an app-level route guard, a reverse-proxy admin\n\t// zone, or similar) before wiring them into a UI.\n\n\tcreatePlan(input: ICreatePlanInput) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/plans',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tupdatePlan(planId: string, input: IUpdatePlanInput) {\n\t\treturn this.http.request<IApiResponse<IPlanResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tdeletePlan(planId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/plans/${planId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Subscription ─────────────────────────────────────────────────────────────\n\n\tgetSubscription(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ISubscriptionResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/subscription',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// ── Checkout / portal ────────────────────────────────────────────────────────\n\n\tcreateCheckoutSession(input: ICheckoutInput) {\n\t\treturn this.http.request<IApiResponse<ICheckoutUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/checkout',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tcreatePortalSession() {\n\t\treturn this.http.request<IApiResponse<IPortalUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/portal',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Usage ────────────────────────────────────────────────────────────────────\n\n\trecordUsage(input: IRecordUsageInput) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/usage',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetUsage(metric: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IUsageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/billing/usage/${metric}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tCustomerLabelType,\n\tCustomerSex,\n\tCustomerType,\n\tIApiResponse,\n\tICustomerAddressListResult,\n\tICustomerAddressResult,\n\tICustomerDetailD2DTO,\n\tICustomerDetailDTO,\n\tICustomerEmailListResult,\n\tICustomerEmailResult,\n\tICustomerLabelListResult,\n\tICustomerListResult,\n\tICustomerNoteListResult,\n\tICustomerNoteResult,\n\tICustomerPhoneListResult,\n\tICustomerPhoneResult,\n\tICustomerRelationshipListResult,\n\tICustomerRelationshipResult,\n\tICustomerResult,\n\tICustomerTagListResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface IListCustomersInput {\n\tsearch?: string;\n\tblacklisted?: boolean;\n\tlimit?: number;\n\toffset?: number;\n}\n\nexport interface IGetCustomerInput {\n\tdepth?: 1 | 2;\n}\n\nexport interface ICreateCustomerInput {\n\ttype?: CustomerType;\n\tsex?: CustomerSex;\n\tfirstName?: string | null;\n\tlastName?: string | null;\n\tcompanyName?: string | null;\n\tavatarUrl?: string | null;\n\tlocale?: string | null;\n\treferenceCode?: string | null;\n\treferralCode?: string | null;\n\treferredByCode?: string | null;\n}\n\n// Referral codes are create-time only — the server's update path never\n// writes them, so including them here made updateCustomer({ referralCode })\n// a type-correct 200-OK silent no-op.\nexport type IUpdateCustomerInput = Omit<ICreateCustomerInput, 'referralCode' | 'referredByCode'>;\n\nexport interface IBlacklistCustomerInput {\n\treason?: string;\n}\n\nexport interface IAddEmailInput {\n\temail: string;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddPhoneInput {\n\tphone: string;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddAddressInput {\n\tcountryIso: string;\n\tzipPostalCode: string;\n\tsubdivision1Iso?: string | null;\n\tsubdivision2Iso?: string | null;\n\tunit?: string | null;\n\tline1?: string | null;\n\tline2?: string | null;\n\tlabel?: string;\n\tisPrimary?: boolean;\n}\n\nexport interface IAddRelationshipInput {\n\trelatedId: string;\n\t// Required — the server rejects relationship-less links with a 422.\n\trelationship: string;\n\tisPrimary?: boolean;\n}\n\n// ── Customers client ─────────────────────────────────────────────────────────\n\nexport class CustomersClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every request to this workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces/audit/webhooks.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Core customer CRUD ───────────────────────────────────────────────────────\n\n\tlistCustomers(input: IListCustomersInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.search !== undefined) params.set('search', input.search);\n\t\tif (input.blacklisted !== undefined) params.set('blacklisted', String(input.blacklisted));\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.offset !== undefined) params.set('offset', String(input.offset));\n\t\tconst qs = params.toString();\n\n\t\treturn this.http.request<IApiResponse<ICustomerListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: qs ? `/customers?${qs}` : '/customers',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateCustomer(input: ICreateCustomerInput = {}) {\n\t\treturn this.http.request<IApiResponse<ICustomerResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/customers',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// depth defaults to 2 server-side; pass { depth: 1 } for one level of\n\t// relationship expansion instead of the D2 (nested-relationships) shape.\n\tgetCustomer(customerId: string, input: IGetCustomerInput = {}, opts?: IReadOptions) {\n\t\tconst qs = input.depth === 1 ? '?depth=1' : '';\n\t\treturn this.http.request<IApiResponse<ICustomerDetailDTO | ICustomerDetailD2DTO>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}${qs}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateCustomer(customerId: string, input: IUpdateCustomerInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteCustomer(customerId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tblacklistCustomer(customerId: string, input: IBlacklistCustomerInput = {}) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/blacklist`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tunblacklistCustomer(customerId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/unblacklist`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Emails ───────────────────────────────────────────────────────────────────\n\n\tlistEmails(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/emails`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddEmail(customerId: string, input: IAddEmailInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/emails`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — email addresses themselves are immutable\n\t// once added; remove and re-add to change the address.\n\tupdateEmailLabel(customerId: string, emailId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerEmailResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryEmail(customerId: string, emailId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveEmail(customerId: string, emailId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/emails/${emailId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Phones ───────────────────────────────────────────────────────────────────\n\n\tlistPhones(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/phones`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddPhone(customerId: string, input: IAddPhoneInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/phones`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — same as updateEmailLabel.\n\tupdatePhoneLabel(customerId: string, phoneId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerPhoneResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryPhone(customerId: string, phoneId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremovePhone(customerId: string, phoneId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/phones/${phoneId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Addresses ────────────────────────────────────────────────────────────────\n\n\tlistAddresses(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/addresses`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddAddress(customerId: string, input: IAddAddressInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/addresses`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Only the label is editable — same as updateEmailLabel.\n\tupdateAddressLabel(customerId: string, addrId: string, label: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerAddressResult>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}`,\n\t\t\tbody: { label },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryAddress(customerId: string, addrId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveAddress(customerId: string, addrId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/addresses/${addrId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Notes ────────────────────────────────────────────────────────────────────\n\n\tlistNotes(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/notes`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateNote(customerId: string, body: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/notes`,\n\t\t\tbody: { body },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tupdateNote(customerId: string, noteId: string, body: string) {\n\t\treturn this.http.request<IApiResponse<ICustomerNoteResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/notes/${noteId}`,\n\t\t\tbody: { body },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteNote(customerId: string, noteId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/notes/${noteId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Tags ─────────────────────────────────────────────────────────────────────\n\n\tlistTags(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerTagListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/tags`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddTag(customerId: string, tag: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/tags`,\n\t\t\tbody: { tag },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveTag(customerId: string, tag: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/tags/${encodeURIComponent(tag)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Relationships ────────────────────────────────────────────────────────────\n\n\tlistRelationships(customerId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerRelationshipListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/${customerId}/relationships`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddRelationship(customerId: string, input: IAddRelationshipInput) {\n\t\treturn this.http.request<IApiResponse<ICustomerRelationshipResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/customers/${customerId}/relationships`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tsetPrimaryRelationship(customerId: string, relatedId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/customers/${customerId}/relationships/${relatedId}/primary`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveRelationship(customerId: string, relatedId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/${customerId}/relationships/${relatedId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Labels ───────────────────────────────────────────────────────────────────\n\t// Shared vocabulary across all customers in the workspace — labels are\n\t// looked up/created implicitly by addEmail/addPhone/addAddress's `label`\n\t// string; these two methods are for managing the vocabulary directly\n\t// (e.g. an admin screen listing/pruning unused labels).\n\n\tlistLabels(type: CustomerLabelType, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ICustomerLabelListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/customers/labels?type=${type}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tremoveLabel(labelId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/customers/labels/${labelId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIApiResponse,\n\tITestWebhookResult,\n\tIWebhookDeliveryListResult,\n\tIWebhookEndpointCreatedDTO,\n\tIWebhookEndpointDTO,\n\tIWebhookEndpointListResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICreateWebhookEndpointInput {\n\turl: string;\n\tevents?: string[];\n}\n\nexport interface IUpdateWebhookEndpointInput {\n\turl?: string;\n\tevents?: string[];\n\tenabled?: boolean;\n}\n\n// ── Webhooks client ──────────────────────────────────────────────────────────\n\nexport class WebhooksClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every request to this workspace (X-Workspace-ID). Falls back to\n\t// the caller's personal workspace when unset, same as billing/workspaces/audit.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\tlistEndpoints(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/webhooks',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// The response includes `secret` — shown once, at creation. There is no\n\t// way to retrieve it again afterward; store it or let the caller copy it.\n\tcreateEndpoint(input: ICreateWebhookEndpointInput) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointCreatedDTO>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/webhooks',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetEndpoint(endpointId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointDTO>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateEndpoint(endpointId: string, input: IUpdateWebhookEndpointInput) {\n\t\treturn this.http.request<IApiResponse<IWebhookEndpointDTO>>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tdeleteEndpoint(endpointId: string) {\n\t\treturn this.http.request<undefined>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/webhooks/${endpointId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tlistDeliveries(endpointId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWebhookDeliveryListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/webhooks/${endpointId}/deliveries`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\ttestEndpoint(endpointId: string) {\n\t\treturn this.http.request<IApiResponse<ITestWebhookResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/webhooks/${endpointId}/test`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type {\n\tIReadOptions,\n\tIAcceptInvitationResult,\n\tIApiResponse,\n\tIInvitationListResult,\n\tIInviteResult,\n\tIMemberListResult,\n\tIRoleListResult,\n\tIRoleResult,\n\tIWorkspaceListResult,\n\tIWorkspaceResult,\n\tIWorkspaceSettingsResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICreateWorkspaceInput {\n\tname: string;\n\tdescription?: string;\n\ttype?: string;\n}\n\nexport interface IUpdateWorkspaceInput {\n\tname?: string;\n\tdescription?: string | null;\n\tmotto?: string | null;\n\tphone?: string | null;\n\tbusinessType?: string | null;\n\taddress?: {\n\t\tline1?: string;\n\t\tline2?: string;\n\t\tcity?: string;\n\t\tstate?: string;\n\t\tzip?: string;\n\t\tcountry?: string;\n\t} | null;\n}\n\nexport interface IInviteEntry {\n\temail: string;\n\troleId?: string;\n}\n\nexport interface IUpdateSettingsInput {\n\tlocale?: string;\n\ttimezone?: string;\n\tcurrency?: string;\n\tdateFormat?: string;\n\ttimeFormat?: string;\n}\n\nexport interface ICreateRoleInput {\n\tname: string;\n\tdescription?: string;\n}\n\nexport interface IUpdateRoleInput {\n\tname?: string;\n\tdescription?: string | null;\n\tactive?: boolean;\n}\n\nexport interface IRolePermissionInput {\n\tpermissionKey: string;\n\tcanCreate?: boolean;\n\tcanRead?: boolean;\n\tcanUpdate?: boolean;\n\tcanDelete?: boolean;\n}\n\nexport interface IRolePermission {\n\tpermissionKey: string;\n\tcanCreate: boolean;\n\tcanRead: boolean;\n\tcanUpdate: boolean;\n\tcanDelete: boolean;\n}\n\nexport interface IRolePermissionsResult {\n\tpermissions: IRolePermission[];\n}\n\n// ── Workspaces client ────────────────────────────────────────────────────────\n\nexport class WorkspacesClient {\n\tprivate workspaceId: string | undefined;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\tsetAccessToken(token: string | undefined) {\n\t\tthis.tokens.set(token);\n\t}\n\n\t// Scopes every subsequent request to this workspace (X-Workspace-ID).\n\t// Falls back to the caller's personal workspace when unset.\n\tsetWorkspaceId(workspaceId: string | undefined) {\n\t\tthis.workspaceId = workspaceId;\n\t}\n\n\t// ── Workspace creation + listing ─────────────────────────────────────────────\n\n\tlistWorkspaces(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateWorkspace(input: ICreateWorkspaceInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\tgetWorkspace(id: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/${id}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateWorkspace(input: IUpdateWorkspaceInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/workspaces',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Personal workspaces can't be archived — the server returns 403 if you try.\n\tarchiveWorkspace() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/archive',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\trestoreWorkspace() {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/restore',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Roles ────────────────────────────────────────────────────────────────────\n\n\tlistRoles(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/roles',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tcreateRole(input: ICreateRoleInput) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/roles',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetRole(roleId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateRole(roleId: string, input: IUpdateRoleInput) {\n\t\treturn this.http.request<IApiResponse<IRoleResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveRole(roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetRolePermissions(roleId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRolePermissionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/roles/${roleId}/permissions`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tsetRolePermissions(roleId: string, permissions: IRolePermissionInput[]) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/workspaces/roles/${roleId}/permissions`,\n\t\t\tbody: { permissions },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Members ──────────────────────────────────────────────────────────────────\n\n\tlistMembers(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IMemberListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/members',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tremoveMember(userId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/members/${userId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tgetMemberRoles(userId: string, opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IRoleListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/workspaces/members/${userId}/roles`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\taddMemberRole(userId: string, roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/workspaces/members/${userId}/roles`,\n\t\t\tbody: { roleId },\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tremoveMemberRole(userId: string, roleId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/members/${userId}/roles/${roleId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// ── Invitations ──────────────────────────────────────────────────────────────\n\n\tlistInvitations(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IInvitationListResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/invitations',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tinvite(entries: IInviteEntry | IInviteEntry[]) {\n\t\treturn this.http.request<IApiResponse<IInviteResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/invitations',\n\t\t\tbody: entries,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tcancelInvitation(inviteId: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/workspaces/invitations/${inviteId}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\tacceptInvitation(pin: string) {\n\t\treturn this.http.request<IApiResponse<IAcceptInvitationResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/workspaces/invitations/accept',\n\t\t\tbody: { pin },\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// ── Settings ─────────────────────────────────────────────────────────────────\n\n\tgetSettings(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceSettingsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/workspaces/settings',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\tupdateSettings(input: IUpdateSettingsInput) {\n\t\treturn this.http.request<IApiResponse<IWorkspaceSettingsResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/workspaces/settings',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n}\n","// Shared by every module of a FonderieClient so that setting the access\n// token on one (e.g. AuthClient after login) is immediately visible to all\n// the others (e.g. BillingClient) — they're separate module instances, but\n// one session.\nexport class TokenStore {\n\tprivate token: string | undefined;\n\n\tconstructor(initial?: string) {\n\t\tthis.token = initial;\n\t}\n\n\tget(): string | undefined {\n\t\treturn this.token;\n\t}\n\n\tset(token: string | undefined) {\n\t\tthis.token = token;\n\t}\n}\n","import type { ICache } from './cache';\nimport { HttpClient } from './http';\nimport { AuditClient } from './modules/audit';\nimport { AuthClient } from './modules/auth';\nimport { BillingClient } from './modules/billing';\nimport { CustomersClient } from './modules/customers';\nimport { WebhooksClient } from './modules/webhooks';\nimport { WorkspacesClient } from './modules/workspaces';\nimport { TokenStore } from './token-store';\nimport type { IApiResponse, ITokens } from './types';\n\n// Reactive token renewal. When set, the client refreshes once on a 401 and\n// retries the request. The app owns where the refresh token lives and where new\n// tokens are persisted.\nexport interface IClientAuthConfig {\n\tgetRefreshToken?: () => string | undefined;\n\tonTokensChanged?: (tokens: ITokens) => void;\n\tonAuthError?: () => void;\n}\n\nexport interface IFonderieClientOptions {\n\tbaseUrl: string;\n\taccessToken?: string;\n\tworkspaceId?: string;\n\t// Opt-in response cache (see createMemoryCache). Omit for no caching.\n\tcache?: ICache;\n\t// Opt-in reactive renew.\n\tauth?: IClientAuthConfig;\n}\n\n// Per-call options for the generic transport.\nexport interface IRequestConfig {\n\tworkspaceId?: string;\n\t// Per-call Bearer override — e.g. the MFA-login step, where a temporary\n\t// mfaToken is used before the session access token exists. Defaults to the\n\t// client's stored token.\n\ttoken?: string;\n\t// Cache this GET for `cache` ms; false to skip; bust to force-refresh.\n\tcache?: number | false;\n\tbust?: boolean;\n\t// Extra cache key fragments to evict after a write.\n\tinvalidate?: string[];\n}\n\nexport class FonderieClient {\n\treadonly auth: AuthClient;\n\treadonly billing: BillingClient;\n\treadonly workspaces: WorkspacesClient;\n\treadonly audit: AuditClient;\n\treadonly webhooks: WebhooksClient;\n\treadonly customers: CustomersClient;\n\n\tprivate http: HttpClient;\n\tprivate tokens: TokenStore;\n\tprivate workspaceId: string | undefined;\n\tprivate cache: ICache | undefined;\n\tprivate authConfig: IClientAuthConfig | undefined;\n\tprivate refreshing: Promise<string | undefined> | null = null;\n\n\tconstructor(opts: IFonderieClientOptions) {\n\t\tthis.tokens = new TokenStore(opts.accessToken);\n\t\tthis.workspaceId = opts.workspaceId;\n\t\tthis.cache = opts.cache;\n\t\tthis.authConfig = opts.auth;\n\t\tthis.http = new HttpClient(opts.baseUrl, {\n\t\t\tcache: opts.cache,\n\t\t\tdefaultTtlMs: (opts.cache as { defaultTtlMs?: number } | undefined)?.defaultTtlMs,\n\t\t\trefresh: opts.auth ? () => this.doRefresh() : undefined,\n\t\t});\n\t\tthis.auth = new AuthClient(this.http, this.tokens);\n\t\tthis.billing = new BillingClient(this.http, this.tokens);\n\t\tthis.workspaces = new WorkspacesClient(this.http, this.tokens);\n\t\tthis.audit = new AuditClient(this.http, this.tokens);\n\t\tthis.webhooks = new WebhooksClient(this.http, this.tokens);\n\t\tthis.customers = new CustomersClient(this.http, this.tokens);\n\t\t// Route through the setter so the constructor option scopes the\n\t\t// workspace-aware modules exactly like a later setWorkspaceId() call.\n\t\tif (opts.workspaceId !== undefined) this.setWorkspaceId(opts.workspaceId);\n\t}\n\n\t// Single-flight refresh: POST /auth/refresh with the app-supplied refresh\n\t// token, store the new access token, notify the app, return it for the retry.\n\tprivate doRefresh(): Promise<string | undefined> {\n\t\tif (this.refreshing) return this.refreshing;\n\t\tthis.refreshing = (async () => {\n\t\t\tconst refreshToken = this.authConfig?.getRefreshToken?.();\n\t\t\tif (!refreshToken) {\n\t\t\t\tthis.authConfig?.onAuthError?.();\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { result } = await this.auth.refreshTokens(refreshToken);\n\t\t\t\tconst tokens = (result as unknown as { tokens: ITokens }).tokens;\n\t\t\t\tthis.tokens.set(tokens.access);\n\t\t\t\tthis.authConfig?.onTokensChanged?.(tokens);\n\t\t\t\treturn tokens.access;\n\t\t\t} catch {\n\t\t\t\tthis.tokens.set(undefined);\n\t\t\t\tthis.authConfig?.onAuthError?.();\n\t\t\t\treturn undefined;\n\t\t\t} finally {\n\t\t\t\tthis.refreshing = null;\n\t\t\t}\n\t\t})();\n\t\treturn this.refreshing;\n\t}\n\n\t// The JWT used to authenticate every request — the typed modules and the\n\t// generic transport share one token store. Passing undefined signs out and\n\t// clears the cache (so no session's data survives a logout).\n\tsetAccessToken(token: string | undefined): void {\n\t\tthis.tokens.set(token);\n\t\tif (!token) this.clearCache();\n\t}\n\n\t// Drop all cached responses (e.g. on switching accounts).\n\tclearCache(): void {\n\t\tthis.cache?.clear();\n\t}\n\n\t// Default X-Workspace-ID for the generic transport, also propagated to the\n\t// workspace-scoped modules so one call configures the whole client.\n\tsetWorkspaceId(workspaceId: string | undefined): void {\n\t\tthis.workspaceId = workspaceId;\n\t\tthis.billing.setWorkspaceId(workspaceId);\n\t\tthis.workspaces.setWorkspaceId(workspaceId);\n\t\tthis.customers.setWorkspaceId(workspaceId);\n\t\tthis.audit.setWorkspaceId(workspaceId);\n\t\tthis.webhooks.setWorkspaceId(workspaceId);\n\t}\n\n\t// ── Generic transport ──────────────────────────────────────────────────────\n\t// A Fonderie-aware HTTP client for endpoints outside the typed modules (an\n\t// app's own routes on the same backend). It attaches the shared JWT and\n\t// X-Workspace-ID automatically and returns Fonderie's { reason, explanation,\n\t// result } envelope — so you don't hand-roll auth for custom endpoints.\n\n\trequest<T = unknown>(opts: {\n\t\tmethod: string;\n\t\tpath: string;\n\t\tbody?: unknown;\n\t\ttoken?: string | undefined;\n\t\tworkspaceId?: string | undefined;\n\t\tcache?: number | false | undefined;\n\t\tbust?: boolean | undefined;\n\t\tinvalidate?: string[] | undefined;\n\t}): Promise<IApiResponse<T>> {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod: opts.method,\n\t\t\tpath: opts.path,\n\t\t\tbody: opts.body,\n\t\t\ttoken: opts.token ?? this.tokens.get(),\n\t\t\tworkspaceId: opts.workspaceId ?? this.workspaceId,\n\t\t\tcache: opts.cache,\n\t\t\tbust: opts.bust,\n\t\t\tinvalidate: opts.invalidate,\n\t\t});\n\t}\n\n\tget<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'GET',\n\t\t\tpath,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tcache: config?.cache,\n\t\t\tbust: config?.bust,\n\t\t});\n\t}\n\n\tpost<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'POST', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tput<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'PUT', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tpatch<T = unknown>(path: string, body?: unknown, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'PATCH', path, body, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n\n\tdelete<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({ method: 'DELETE', path, token: config?.token, workspaceId: config?.workspaceId, invalidate: config?.invalidate });\n\t}\n}\n","import { HttpClient } from '../http';\nimport type {\n\tIApiResponse,\n\tIConfigEntry,\n\tIConfigRevision,\n\tIRevealSecretResult,\n\tISecretEntry,\n\tISecretRevision,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ISetConfigInput {\n\tvalue: unknown;\n\tdescription?: string;\n\t// Deactivated entries stay stored but are excluded from runtime reads.\n\tactive?: boolean;\n\tifVersion?: number;\n}\n\nexport interface ISetSecretInput {\n\tvalue: string;\n\tdescription?: string;\n\t// Deactivated secrets stay stored but are excluded from runtime reads.\n\tactive?: boolean;\n\tifVersion?: number;\n}\n\nexport interface IRollbackInput {\n\ttoVersion: number;\n}\n\nexport interface IConfigAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Sent as X-Actor on writes — recorded as updatedBy and in revision\n\t// history (defaults server-side to 'admin-token').\n\tactor?: string;\n}\n\nfunction envQuery(environment?: string): string {\n\treturn environment ? `?environment=${encodeURIComponent(environment)}` : '';\n}\n\n// ── Config admin client ──────────────────────────────────────────────────────\n//\n// Separate from FonderieClient on purpose, for the same reason as\n// CourierAdminClient: @fonderie/config's admin routes (/admin/config/*,\n// /admin/secrets/*) are guarded by a static bearer token configured on the\n// server, not the signed-in user's session. Construct with that token\n// directly; it shares no state with AuthClient/BillingClient/WorkspacesClient.\nexport class ConfigAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IConfigAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// ── Config ───────────────────────────────────────────────────────────────\n\n\tlistConfig(environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetConfig(key: string, input: ISetConfigInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tdeleteConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/config/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tlistConfigRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/config/${key}/revisions${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollbackConfig(key: string, input: IRollbackInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/config/${key}/rollback${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\t// ── Secrets (masked) ─────────────────────────────────────────────────────\n\n\tlistSecrets(environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetSecret(key: string, input: ISetSecretInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tdeleteSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/secrets/${key}${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tlistSecretRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/secrets/${key}/revisions${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollbackSecret(key: string, input: IRollbackInput, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/secrets/${key}/rollback${envQuery(environment)}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\t// POST (not GET) so the decrypted value never lands in a URL or access log.\n\trevealSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IRevealSecretResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/secrets/${key}/reveal${envQuery(environment)}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n}\n","import { HttpClient } from '../http';\nimport type { IApiResponse, ITemplateEntry, ITemplateRevision } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ISetTemplateInput {\n\ttext: string;\n\tsubject?: string;\n\thtml?: string;\n\tactive?: boolean;\n\tifVersion?: number;\n}\n\nexport interface IRollbackTemplateInput {\n\ttoVersion: number;\n}\n\nexport interface ICourierAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Sent as X-Actor on writes — recorded as updatedBy and in revision\n\t// history (defaults server-side to 'admin-token').\n\tactor?: string;\n}\n\n// ── Courier admin client ─────────────────────────────────────────────────────\n//\n// Separate from FonderieClient on purpose: @fonderie/courier's admin routes\n// (/admin/templates/*) are guarded by a static bearer token configured on the\n// server (CourierModule's adminToken), not the signed-in user's session —\n// the same model @fonderie/config's admin surface uses, and the one the\n// `fonderie template`/`fonderie config` CLI commands already speak to via\n// FONDERIE_ADMIN_URL/FONDERIE_ADMIN_TOKEN. Bundling this into FonderieClient\n// would suggest an end-user's session token can reach it, which it can't —\n// this is an ops/admin-dashboard client, constructed with its own token.\nexport class CourierAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: ICourierAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tlistTemplates() {\n\t\treturn this.http.request<IApiResponse<ITemplateEntry[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/admin/templates',\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tgetTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\tsetTemplate(type: string, input: ISetTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tdeleteTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<undefined>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/admin/templates/${type}${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\tlistRevisions(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateRevision[]>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/admin/templates/${type}/revisions${q}`,\n\t\t\ttoken: this.adminToken,\n\t\t});\n\t}\n\n\trollback(type: string, input: IRollbackTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateEntry>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: `/admin/templates/${type}/rollback${q}`,\n\t\t\tbody: input,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n}\n","// Per-call read options accepted by the typed sub-clients' GET methods.\nexport interface IReadOptions {\n\t// Ignore any cached value and refresh it (pull-to-refresh semantics).\n\tbust?: boolean | undefined;\n}\n\n// ── Envelope ─────────────────────────────────────────────────────────────────\n\nexport interface IApiResponse<T = undefined> {\n\treason: string;\n\texplanation: string;\n\tresult: T;\n}\n\nexport interface IApiError {\n\treason: string;\n\texplanation: string;\n\tdetails?: unknown;\n}\n\n// ── User ─────────────────────────────────────────────────────────────────────\n\nexport interface IUserPreferences {\n\tlocale: string;\n\ttimezone: string;\n\tnotifications: { email: boolean; inApp: boolean; sms: boolean; push: boolean };\n\temailDigest: string;\n\tdateFormat: string;\n\ttimeFormat: string;\n}\n\nexport interface IUserDTO {\n\tid: string;\n\temail: string;\n\tfirstName: string;\n\tlastName: string;\n\tphone: string;\n\tprofileImageUrl: string;\n\tisActive: boolean;\n\tlastLogin: string;\n\tpreferences: IUserPreferences;\n\tisEmailVerified: boolean;\n\tisPhoneVerified: boolean;\n\tmfaEnabled: boolean;\n\tsuspended: boolean;\n\twhitelist: boolean;\n\tipWhitelist: string[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ITokens {\n\taccess: string;\n\trefresh: string;\n}\n\n// ── Auth endpoint results ─────────────────────────────────────────────────────\n\nexport interface IRegisterResult {\n\ttokens: ITokens;\n\tuser: IUserDTO;\n\t// True when the account still needs email verification (config-dependent;\n\t// route the user to the verify screen). Absent on phone and MFA/OAuth\n\t// completions, which don't compute it.\n\trequiresVerification?: boolean;\n}\n\nexport interface ILoginResult {\n\ttokens: ITokens;\n\tuser: IUserDTO;\n\t// True when the account still needs email verification (config-dependent;\n\t// route the user to the verify screen). Absent on phone and MFA/OAuth\n\t// completions, which don't compute it.\n\trequiresVerification?: boolean;\n}\n\n// Login response when the account has MFA enabled: no tokens yet — complete\n// the login with auth.mfa.verifyLogin(mfaToken, code).\nexport interface IMfaRequiredResult {\n\tmfaToken: string;\n}\n\nexport function isMfaRequired(result: ILoginResult | IMfaRequiredResult): result is IMfaRequiredResult {\n\treturn !('tokens' in result);\n}\n\nexport interface IRefreshResult {\n\ttokens: ITokens;\n}\n\nexport interface IVerifyEmailResult {\n\tverified: boolean;\n\temail: string;\n}\n\n// GET /auth/send-verification: `{ email }` after a resend, `{ verified: true,\n// email }` when the address was already verified, and no result at all on the\n// phone branch — hence both fields optional. The verification pin itself is\n// only ever emailed; it never appears in the response.\nexport interface IResendVerificationResult {\n\temail?: string;\n\tverified?: boolean;\n}\n\nexport interface IMeResult {\n\tuser: IUserDTO;\n}\n\nexport interface IMfaSetupResult {\n\t// Data-URI QR code to scan, plus the one-time backup codes generated at\n\t// setup — matches @fonderie/auth's /auth/mfa/setup response.\n\tqr: string;\n\tbackupCodes: string[];\n}\n\n// POST /auth/mfa/verify with a full session token (setup confirmation). The\n// session token is NOT rotated — MFA is enforced at login, so the existing\n// session stays valid unchanged. The `{ tokens, user }` response only exists\n// on the mfa-pending login path, typed separately as ILoginResult (verifyLogin).\nexport interface IMfaEnabledResult {\n\tmfaEnabled: boolean;\n}\n\n// ── Billing ──────────────────────────────────────────────────────────────────\n\nexport interface IPlanFeature {\n\tname: string;\n\tdescription: string;\n\tenabled: boolean;\n\tlimit?: number;\n}\n\nexport interface IPlanDTO {\n\tid: string;\n\tplanId: string;\n\tname: string;\n\tdescription: string;\n\ttier: number;\n\tseats: number | null;\n\ttrialDays: number;\n\tpricing: {\n\t\tmonthly: number; // in cents, e.g. 1999 = $19.99\n\t\tyearly: number; // in cents\n\t\tcurrency: string; // ISO 4217, e.g. 'USD'\n\t};\n\t/** True when pricing came from a stale cache — a provider outage or a\n\t * transfer window. Show prices as indicative when set. */\n\tpricingStale?: boolean;\n\tfeatures: IPlanFeature[];\n\tmetadata: Record<string, unknown>;\n}\n\nexport type SubscriberType = 'user' | 'workspace';\n\nexport interface ISubscriptionDTO {\n\tid: string;\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\tplan: string;\n\tinterval: string;\n\tstatus: string;\n\tcancelAtPeriodEnd: boolean;\n\tcurrentPeriodStart: string | null;\n\tcurrentPeriodEnd: string | null;\n\ttrialEndsAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IPlanListResult {\n\tplans: IPlanDTO[];\n}\n\nexport interface IPlanResult {\n\tplan: IPlanDTO;\n}\n\nexport interface ISubscriptionResult {\n\tsubscription: ISubscriptionDTO;\n}\n\nexport interface ICheckoutUrlResult {\n\turl: string;\n}\n\nexport interface IPortalUrlResult {\n\turl: string;\n}\n\nexport interface IUsageResult {\n\tmetric: string;\n\ttotal: number;\n\tsince: string;\n}\n\n// ── Workspaces ───────────────────────────────────────────────────────────────\n\nexport interface IWorkspaceAddressDTO {\n\tline1: string;\n\tline2: string;\n\tcity: string;\n\tstate: string;\n\tzip: string;\n\tcountry: string;\n}\n\nexport interface IWorkspaceDTO {\n\tid: string;\n\tname: string;\n\tslug: string;\n\ttype: string;\n\tdescription: string;\n\tmotto: string;\n\tphone: string;\n\tbusinessType: string;\n\taddress: IWorkspaceAddressDTO;\n\tplan: string;\n\townerId: string;\n\tisPersonal: boolean;\n\tisArchived: boolean;\n\tarchivedAt: string;\n\t// User id that archived the workspace; '' while unarchived.\n\tarchivedBy: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface IRoleDTO {\n\tid: string;\n\tname: string;\n\tisSystem: boolean;\n\tactive: boolean;\n\tdescription: string;\n\tworkspaceId: string;\n}\n\nexport interface IMemberDTO {\n\tuserId: string;\n\tworkspaceId: string;\n\troleId: string;\n\troleName: string;\n\tconfirmed: boolean;\n\tcreatedAt: string;\n\t/** Identity, so a member list can be rendered without a second request. */\n\temail: string;\n\tfirstName: string;\n\tlastName: string;\n\tprofileImageUrl: string;\n}\n\nexport interface IInvitationDTO {\n\tid: string;\n\tworkspaceId: string;\n\temail: string;\n\troleId: string;\n\ttoken: string;\n\tstatus: string;\n\texpiresAt: string;\n\tcreatedAt: string;\n}\n\nexport interface IWorkspaceSettingsDTO {\n\tlocale: string;\n\ttimezone: string;\n\tcurrency: string;\n\tdateFormat: string;\n\ttimeFormat: string;\n}\n\nexport interface IWorkspaceListResult {\n\tworkspaces: IWorkspaceDTO[];\n}\n\nexport interface IWorkspaceResult {\n\tworkspace: IWorkspaceDTO;\n}\n\nexport interface IMemberListResult {\n\tmembers: IMemberDTO[];\n}\n\nexport interface IRoleListResult {\n\troles: IRoleDTO[];\n}\n\nexport interface IRoleResult {\n\trole: IRoleDTO;\n}\n\nexport interface IInvitationListResult {\n\tinvitations: IInvitationDTO[];\n}\n\nexport interface IInviteResult {\n\tinvitations: Array<{ invitationId: string; email: string }>;\n}\n\nexport interface IAcceptInvitationResult {\n\tworkspaceId: string;\n}\n\nexport interface IWorkspaceSettingsResult {\n\tsettings: IWorkspaceSettingsDTO;\n}\n\n// ── Courier admin (template management) ─────────────────────────────────────\n// Admin-token authenticated, not user-session authenticated — see\n// CourierAdminClient. Result shapes here are the raw resource, not wrapped\n// in a named key, matching @fonderie/courier's admin route handlers.\n\nexport interface ITemplateEntry {\n\ttype: string;\n\tlocale: string | null;\n\tsubject: string | null;\n\thtml: string | null;\n\ttext: string;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface ITemplateRevision {\n\ttype: string;\n\tlocale: string | null;\n\tsubject: string | null;\n\thtml: string | null;\n\ttext: string;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\n// ── Config admin (feature flags / remote config + secrets) ──────────────────\n// Admin-token authenticated, not user-session authenticated — see\n// ConfigAdminClient. Result shapes here are the raw resource, matching\n// @fonderie/config's admin route handlers.\n\nexport interface IConfigEntry {\n\tkey: string;\n\tvalue: unknown;\n\tenvironment: string;\n\tdescription: string | null;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface IConfigRevision {\n\tkey: string;\n\tenvironment: string;\n\tvalue: unknown;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\n// Deliberately has no `value` — admin list/get never return a secret's\n// plaintext, only the explicit reveal path does.\nexport interface ISecretEntry {\n\tkey: string;\n\tenvironment: string;\n\tdescription: string | null;\n\tactive: boolean;\n\tversion: number;\n\tupdatedBy: string | null;\n\tupdatedAt: string;\n}\n\nexport interface ISecretRevision {\n\tkey: string;\n\tenvironment: string;\n\tversion: number;\n\tactor: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IRevealSecretResult {\n\tvalue: string;\n}\n\n// ── Audit ────────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces) — unlike courier-admin/config-admin,\n// which use a standalone admin token. Read-only: @fonderie/audit has one route.\n\nexport interface IAuditEventDTO {\n\tid: string;\n\ttype: string;\n\tactorId: string | null;\n\trequestId: string | null;\n\tpayload: Record<string, unknown>;\n\tcreatedAt: string;\n}\n\nexport interface IAuditPageResult {\n\tevents: IAuditEventDTO[];\n\tnextCursor: string | null;\n}\n\n// ── Webhooks ─────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces/audit).\n\nexport interface IWebhookEndpointDTO {\n\tid: string;\n\turl: string;\n\tevents: string[];\n\tenabled: boolean;\n\tcreatedAt: string;\n}\n\n// The signing secret is only ever returned here, at creation — every other\n// read masks it, matching @fonderie/webhooks' own toEndpointDTO/toEndpointCreatedDTO split.\nexport interface IWebhookEndpointCreatedDTO extends IWebhookEndpointDTO {\n\tsecret: string;\n}\n\nexport interface IWebhookDeliveryDTO {\n\tid: string;\n\teventId: string;\n\teventType: string;\n\tstatus: string;\n\tattempts: number;\n\t// The event body that was delivered — what the endpoint received.\n\tpayload: Record<string, unknown>;\n\tresponseStatus: number | null;\n\t// The receiving endpoint's response body (useful when debugging failures).\n\tresponseBody: string | null;\n\t// When the next retry is due; null once delivered or exhausted.\n\tnextAttemptAt: string | null;\n\tdeliveredAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IWebhookEndpointListResult {\n\tendpoints: IWebhookEndpointDTO[];\n}\n\nexport interface IWebhookDeliveryListResult {\n\tdeliveries: IWebhookDeliveryDTO[];\n}\n\nexport interface ITestWebhookResult {\n\tstatus: number | null;\n\tok: boolean;\n\terror?: string;\n}\n\n// ── Customers ────────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, scoped via\n// setWorkspaceId like billing/workspaces/audit/webhooks).\n\nexport type CustomerType = 'individual' | 'business';\nexport type CustomerSex = 'UNKNOWN' | 'MALE' | 'FEMALE';\nexport type CustomerLabelType = 'phone' | 'email' | 'address';\n\nexport interface ICustomerDTO {\n\tid: string;\n\ttype: string;\n\tsex: CustomerSex;\n\tfirstName: string;\n\tlastName: string;\n\tcompanyName: string;\n\tavatarUrl: string;\n\tlocale: string;\n\treferenceCode: string;\n\treferralCode: string;\n\treferredBy: string | null;\n\tblacklisted: { status: boolean; reason: string | null };\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ICustomerEmailDTO {\n\tid: string;\n\temail: string;\n\tlabel: string;\n\t// Id of the shared label row (see listLabels) — null when unlabeled.\n\tlabelId: string | null;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\nexport interface ICustomerPhoneDTO {\n\tid: string;\n\tphone: string;\n\tlabel: string;\n\t// Id of the shared label row (see listLabels) — null when unlabeled.\n\tlabelId: string | null;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\nexport interface IAddressDTO {\n\tcountryIso: string;\n\tsubdivision1Iso: string;\n\tsubdivision2Iso: string;\n\tzipPostalCode: string;\n\tunit: string;\n\tline1: string;\n\tline2: string;\n}\n\nexport interface ICustomerAddressDTO {\n\tid: string;\n\tlabel: string;\n\t// Id of the shared label row (see listLabels) — null when unlabeled.\n\tlabelId: string | null;\n\tisPrimary: boolean;\n\taddress: IAddressDTO;\n}\n\nexport interface ICustomerNoteDTO {\n\tid: string;\n\tauthorId: string;\n\tbody: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface ICustomerRelationshipDTO {\n\tid: string;\n\trelatedId: string;\n\trelationship: string;\n\tisPrimary: boolean;\n\tcreatedAt: string;\n}\n\n// Flat merge: relationship metadata + related customer fields spread at the\n// same level. `id` is the relationship record id; `customerId` is the\n// related customer's id — matches @fonderie/customers' own flattening.\nexport type ICustomerRelationshipExpandedDTO = Omit<ICustomerShallowDTO, 'id'> & {\n\tid: string;\n\tcustomerId: string;\n\trelationship: string;\n\tisPrimary: boolean;\n\t// When the relationship itself was created. The spread customer fields\n\t// include the related CUSTOMER's createdAt/updatedAt — don't sort\n\t// relationships by those.\n\trelationshipCreatedAt: string;\n};\n\nexport type ICustomerRelationshipExpandedD2DTO = ICustomerRelationshipExpandedDTO & {\n\trelationships: ICustomerRelationshipExpandedDTO[];\n};\n\nexport interface ICustomerShallowDTO extends ICustomerDTO {\n\temails: ICustomerEmailDTO[];\n\tphones: ICustomerPhoneDTO[];\n\taddresses: ICustomerAddressDTO[];\n\tnotes: ICustomerNoteDTO[];\n\ttags: string[];\n}\n\nexport interface ICustomerDetailDTO extends ICustomerDTO {\n\temails: ICustomerEmailDTO[];\n\tphones: ICustomerPhoneDTO[];\n\taddresses: ICustomerAddressDTO[];\n\tnotes: ICustomerNoteDTO[];\n\trelationships: ICustomerRelationshipExpandedDTO[];\n\ttags: string[];\n}\n\n// depth=1 (default via getCustomer) — one level of relationship expansion.\n// depth=2 (getCustomer(id, { depth: 2 })) — relationships carry their own\n// relationships array one level deeper. Matches @fonderie/customers' D2 DTOs.\nexport interface ICustomerDetailD2DTO extends Omit<ICustomerDetailDTO, 'relationships'> {\n\trelationships: ICustomerRelationshipExpandedD2DTO[];\n}\n\nexport interface ICustomerLabelDTO {\n\tid: string;\n\ttype: CustomerLabelType;\n\tvalue: string;\n\tcreatedAt: string;\n}\n\nexport interface ICustomerListResult {\n\tcustomers: ICustomerDTO[];\n\t// Total matching rows regardless of limit/offset — for pagination.\n\ttotal: number;\n}\n\nexport interface ICustomerResult {\n\tcustomer: ICustomerDTO;\n}\n\nexport interface ICustomerEmailListResult {\n\temails: ICustomerEmailDTO[];\n}\n\nexport interface ICustomerEmailResult {\n\temail: ICustomerEmailDTO;\n}\n\nexport interface ICustomerPhoneListResult {\n\tphones: ICustomerPhoneDTO[];\n}\n\nexport interface ICustomerPhoneResult {\n\tphone: ICustomerPhoneDTO;\n}\n\nexport interface ICustomerAddressListResult {\n\taddresses: ICustomerAddressDTO[];\n}\n\nexport interface ICustomerAddressResult {\n\taddress: ICustomerAddressDTO;\n}\n\nexport interface ICustomerNoteListResult {\n\tnotes: ICustomerNoteDTO[];\n}\n\nexport interface ICustomerNoteResult {\n\tnote: ICustomerNoteDTO;\n}\n\nexport interface ICustomerTagListResult {\n\ttags: string[];\n}\n\nexport interface ICustomerRelationshipListResult {\n\trelationships: ICustomerRelationshipDTO[];\n}\n\nexport interface ICustomerRelationshipResult {\n\trelationship: ICustomerRelationshipDTO;\n}\n\nexport interface ICustomerLabelListResult {\n\tlabels: ICustomerLabelDTO[];\n}\n"],"mappings":"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","names":["data"]}
|