@fonderie/client 1.12.0 → 1.13.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 +52 -0
- package/dist/index.cjs +123 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -1
- package/dist/index.d.ts +84 -1
- package/dist/index.js +120 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cache.ts","../src/http.ts","../src/modules/audit.ts","../src/modules/auth.ts","../src/modules/billing.ts","../src/modules/customers.ts","../src/modules/media.ts","../src/modules/config.ts","../src/modules/webhooks.ts","../src/modules/workspaces.ts","../src/token-store.ts","../src/client.ts","../src/path.ts","../src/modules/config-admin.ts","../src/modules/admin.ts","../src/modules/auth-admin.ts","../src/modules/billing-admin.ts","../src/modules/audit-admin.ts","../src/modules/courier-admin.ts","../src/template-locales.ts","../src/types.ts","../src/config-value.ts","../src/admin-i18n/en/common.ts","../src/admin-i18n/en/nav.ts","../src/admin-i18n/en/shell.ts","../src/admin-i18n/en/session.ts","../src/admin-i18n/en/attention.ts","../src/admin-i18n/en/modules.ts","../src/admin-i18n/en/environment.ts","../src/admin-i18n/en/doctor.ts","../src/admin-i18n/en/routes.ts","../src/admin-i18n/en/log.ts","../src/admin-i18n/en/migrations.ts","../src/admin-i18n/en/tokens.ts","../src/admin-i18n/en/operators.ts","../src/admin-i18n/en/users.ts","../src/admin-i18n/en/billing.ts","../src/admin-i18n/en/catalog.ts","../src/admin-i18n/en/audit.ts","../src/admin-i18n/en/config.ts","../src/admin-i18n/en/templates.ts","../src/admin-i18n/en/index.ts","../src/admin-i18n/es/common.ts","../src/admin-i18n/es/nav.ts","../src/admin-i18n/es/shell.ts","../src/admin-i18n/es/session.ts","../src/admin-i18n/es/attention.ts","../src/admin-i18n/es/modules.ts","../src/admin-i18n/es/environment.ts","../src/admin-i18n/es/doctor.ts","../src/admin-i18n/es/routes.ts","../src/admin-i18n/es/log.ts","../src/admin-i18n/es/migrations.ts","../src/admin-i18n/es/tokens.ts","../src/admin-i18n/es/operators.ts","../src/admin-i18n/es/users.ts","../src/admin-i18n/es/billing.ts","../src/admin-i18n/es/catalog.ts","../src/admin-i18n/es/audit.ts","../src/admin-i18n/es/config.ts","../src/admin-i18n/es/templates.ts","../src/admin-i18n/es/index.ts","../src/admin-i18n/fr/common.ts","../src/admin-i18n/fr/nav.ts","../src/admin-i18n/fr/shell.ts","../src/admin-i18n/fr/session.ts","../src/admin-i18n/fr/attention.ts","../src/admin-i18n/fr/modules.ts","../src/admin-i18n/fr/environment.ts","../src/admin-i18n/fr/doctor.ts","../src/admin-i18n/fr/routes.ts","../src/admin-i18n/fr/log.ts","../src/admin-i18n/fr/migrations.ts","../src/admin-i18n/fr/tokens.ts","../src/admin-i18n/fr/operators.ts","../src/admin-i18n/fr/users.ts","../src/admin-i18n/fr/billing.ts","../src/admin-i18n/fr/catalog.ts","../src/admin-i18n/fr/audit.ts","../src/admin-i18n/fr/config.ts","../src/admin-i18n/fr/templates.ts","../src/admin-i18n/fr/index.ts","../src/admin-i18n/index.ts"],"sourcesContent":["// 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(\n\topts: IMemoryCacheOptions = {},\n): 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\t// The X-Request-ID for the failed call — quote it in a bug report; it\n\t\t// correlates to the server's logs and audit trail for the same request.\n\t\tpublic readonly requestId?: string,\n\t) {\n\t\tsuper(explanation);\n\t\tthis.name = 'FonderieApiError';\n\t}\n}\n\n// Portable random hex for W3C trace ids — crypto.getRandomValues where available\n// (browser / Node), Math.random fallback for Hermes / older React Native. Not\n// security-sensitive: these are correlation/trace ids, not secrets.\nfunction randHex(bytes: number): string {\n\tconst c = (globalThis as { crypto?: { getRandomValues?: (a: Uint8Array) => Uint8Array } }).crypto;\n\tconst arr = new Uint8Array(bytes);\n\tif (c?.getRandomValues) c.getRandomValues(arr);\n\telse for (let i = 0; i < bytes; i++) arr[i] = Math.floor(Math.random() * 256);\n\tlet out = '';\n\tfor (const b of arr) out += b.toString(16).padStart(2, '0');\n\treturn out;\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// Absolute URL for a path on this client's origin — for endpoints a browser\n\t// navigates to or embeds (e.g. a public `<img src>`) rather than fetches\n\t// through request(). Mirrors the `${baseUrl}${path}` join request() uses.\n\tabsolute(path: string): string {\n\t\treturn `${this.baseUrl}${path}`;\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\t// Start a W3C trace: the trace id doubles as the quotable correlation id\n\t\t// (sent as X-Request-ID and surfaced on FonderieApiError.requestId).\n\t\tconst traceId = randHex(16);\n\t\tconst requestId = traceId;\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\ttraceparent: `00-${traceId}-${randHex(8)}-01`,\n\t\t\t'X-Request-ID': requestId,\n\t\t};\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\t\t// The server echoes the id back; prefer it (an intermediary could rewrite\n\t\t// the one we sent), else fall back to what we generated.\n\t\tconst rid = res.headers.get('x-request-id') ?? requestId;\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)\n\t\t\t\tthrow new FonderieApiError('unknown', res.statusText, res.status, undefined, rid);\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, rid);\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 { IReadOptions, 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\tILoginHistoryPageResult,\n\tISessionsResult,\n\tIAuthProvidersResult,\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\t/**\n\t * The language the person is signing up in (e.g. 'fr-CA'). Stored on the\n\t * account, so the verification email already arrives in it. Omitted: the\n\t * app's system locale.\n\t */\n\tlocale?: string;\n}\n\nexport interface IGetLoginHistoryInput {\n\toutcome?: 'success' | 'failed';\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface ILoginInput {\n\temail: string;\n\tpassword: string;\n}\n\n// Native Sign in with Apple: the app obtains an `identityToken` from the native\n// Apple sheet (e.g. expo-apple-authentication) and hands it here — the client\n// only relays it to POST /auth/apple/native. `nonce` is the raw nonce the app\n// passed to the native request, checked server-side against the token claim.\nexport interface IAppleNativeInput {\n\tidentityToken: string;\n\tnonce?: 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\t/**\n\t * Which sign-in methods this deployment can actually honour.\n\t *\n\t * Public — the login screen needs it before anyone has signed in. Ask the\n\t * server rather than shipping a build-time flag: the flag stores the same\n\t * fact twice and lets the two disagree, and the symptom is a user clicking\n\t * a provider the server cannot complete and landing on the provider's own\n\t * error page, which the app cannot explain.\n\t */\n\tproviders() {\n\t\treturn this.http.request<IApiResponse<IAuthProvidersResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/providers',\n\t\t});\n\t}\n\n\t/**\n\t * Disconnect the OAuth provider linked to the signed-in account.\n\t *\n\t * Refused with 409 PASSWORD_REQUIRED when the account has no password:\n\t * removing the only credential is account deletion, not a settings toggle.\n\t * Check `user.hasPassword` before offering the control so the user is asked\n\t * to set a password first rather than shown an error they can't act on.\n\t */\n\tunlinkOauth(provider: string) {\n\t\treturn this.http.request<IApiResponse<null>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/auth/oauth/${encodeURIComponent(provider)}`,\n\t\t});\n\t}\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\t// Complete a native Sign in with Apple. Returns the same token/user envelope\n\t// as login (no MFA branch — OAuth completions don't gate on MFA). Requires\n\t// the API to enable the provider (`providers: ['apple']` + apple config).\n\tappleNative(input: IAppleNativeInput) {\n\t\treturn this.http.request<IApiResponse<ILoginResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/apple/native',\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\t// ── Security surfaces (login history + active sessions) ─────────────────────\n\n\t// GET /auth/login-history — the caller's own attempts, newest first,\n\t// keyset-paginated (pass the previous page's nextCursor to continue).\n\tgetLoginHistory(input: IGetLoginHistoryInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.outcome) params.set('outcome', input.outcome);\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\t\t// Single-level template (no nested backtick) so the client/route drift\n\t\t// checker can normalise the ${qs…} suffix away and match the server route.\n\t\treturn this.http.request<IApiResponse<ILoginHistoryPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/auth/login-history${qs ? '?' + qs : ''}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// GET /auth/sessions — the caller's live sessions; one is flagged current.\n\tlistSessions(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ISessionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/sessions',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// DELETE /auth/sessions/:id — revoke one of the caller's sessions.\n\tterminateSession(id: string) {\n\t\treturn this.http.request<IApiResponse<{ id: string }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/auth/sessions/${encodeURIComponent(id)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// DELETE /auth/sessions/others — revoke every session except the current one.\n\tterminateOtherSessions() {\n\t\treturn this.http.request<IApiResponse<{ count: number }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/auth/sessions/others',\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\tICancelSubscriptionInput,\n\tICheckoutUrlResult,\n\tIInvoicesResult,\n\tIPaymentMethodResult,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tISavePaymentMethodInput,\n\tISetupIntentResult,\n\tISubscriptionChangeResult,\n\tISubscriptionResult,\n\tIUsageResult,\n\tIWalletCheckoutInput,\n\tIWalletPurchaseInput,\n\tIWalletPurchaseResult,\n\tIWalletResult,\n\tIWalletTransactionsResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICheckoutInput {\n\tplan: string;\n\tinterval?: 'month' | 'year';\n\t// Optional idempotency key — a retried checkout with the same key dedupes to\n\t// one session (and one subscription) server-side. Generate once per attempt.\n\tidempotencyKey?: string;\n}\n\nexport interface IRecordUsageInput {\n\tmetric: string;\n\tquantity?: number;\n}\n\nexport interface IWalletPreferencesInput {\n\t// When false, a debit stops at the free allowance (402) rather than drawing\n\t// down purchased credits.\n\tspendPurchased: boolean;\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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// First-party cancel — no portal round-trip. Default keeps access until the\n\t// paid-through date; pass { atPeriodEnd: false } to end it immediately. 501\n\t// when the provider has no first-party cancel (the portal remains a fallback).\n\tcancelSubscription(input?: ICancelSubscriptionInput) {\n\t\treturn this.http.request<IApiResponse<ISubscriptionChangeResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/subscription/cancel',\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// Un-cancel a subscription scheduled to cancel at period end. Idempotent; 409\n\t// when the subscription is already fully canceled (start a new checkout).\n\treactivateSubscription() {\n\t\treturn this.http.request<IApiResponse<ISubscriptionChangeResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/subscription/reactivate',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\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/${encodeURIComponent(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\t// ── Wallet ─────────────────────────────────────────────────────────────────────\n\n\tgetWallet(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWalletResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/wallet',\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\tsetWalletPreferences(input: IWalletPreferencesInput) {\n\t\treturn this.http.request<IApiResponse<IWalletResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/preferences',\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// Start a one-time credit-pack purchase. Returns a hosted checkout URL to\n\t// redirect the buyer to; the wallet is credited by the payment webhook.\n\tcreateWalletCheckout(input: IWalletCheckoutInput) {\n\t\treturn this.http.request<IApiResponse<ICheckoutUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/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\t// Buy a credit pack in-app by charging the saved card — no redirect. Inspect\n\t// `result.status`: 'credited' (done — refresh the wallet), 'checkout_required'\n\t// (no saved card or the card needs 3-D Secure → fall back to\n\t// createWalletCheckout), 'declined', or 'processing' (indeterminate — retry\n\t// with the SAME idempotencyKey). Generate one idempotencyKey per attempt and\n\t// reuse it on retry so a double-submit can't double-charge.\n\tpurchaseWalletPack(input: IWalletPurchaseInput) {\n\t\treturn this.http.request<IApiResponse<IWalletPurchaseResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/purchase',\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// The wallet ledger, newest first — every credit/debit with a running\n\t// balanceAfter. Cursor-paginated: pass the previous result's `nextCursor`.\n\tgetWalletTransactions(opts?: IReadOptions & { cursor?: string; limit?: number }) {\n\t\tconst params = new URLSearchParams();\n\t\tif (opts?.cursor) params.set('cursor', opts.cursor);\n\t\tif (opts?.limit !== undefined) params.set('limit', String(opts.limit));\n\t\tconst qs = params.toString();\n\t\treturn this.http.request<IApiResponse<IWalletTransactionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/billing/wallet/transactions${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\t// ── Account ──────────────────────────────────────────────────────────────────\n\n\t// The customer's card on file (brand/last4/expiry), or { paymentMethod: null }\n\t// when none is stored. 501 when the provider can't retrieve it.\n\tgetPaymentMethod(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/payment-method',\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// Begin in-app card entry — returns a SetupIntent client secret for the\n\t// provider's embedded card element (Stripe Payment Element); the user never\n\t// leaves the site. 501 when the provider has no in-app card support.\n\tsetupPaymentMethod() {\n\t\treturn this.http.request<IApiResponse<ISetupIntentResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/payment-method/setup',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Save the card after the client confirms the SetupIntent: makes it the\n\t// default and records it. 422 when the card isn't attached to this customer.\n\tsavePaymentMethod(input: ISavePaymentMethodInput) {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/billing/payment-method',\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// Remove the saved card (detach at the provider + clear the record).\n\tremovePaymentMethod() {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/billing/payment-method',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// The customer's invoices, newest first — each links out to the hosted\n\t// invoice / PDF. 501 when the provider can't list them.\n\tlistInvoices(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IInvoicesResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/invoices',\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/notes/${encodeURIComponent(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/${encodeURIComponent(customerId)}/notes/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/relationships/${encodeURIComponent(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/${encodeURIComponent(customerId)}/relationships/${encodeURIComponent(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=${encodeURIComponent(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/${encodeURIComponent(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 { IApiResponse, IMediaAssetResult } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\n// Upload an image. `dataBase64` is the RAW base64 payload (no `data:` prefix) —\n// the server sniffs the real type from magic bytes, enforces the byte cap, and\n// rejects SVG (stored-XSS). `purpose` groups assets (e.g. 'avatar'); ownerType\n// /ownerId default server-side to the calling user, so a plain avatar upload\n// needs only `dataBase64`.\nexport interface IUploadMediaInput {\n\tdataBase64: string;\n\tpurpose?: string;\n\townerType?: string;\n\townerId?: string;\n}\n\n// ── Media client ─────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, like auth). NOT\n// workspace-scoped: @fonderie/media keys ownership off ownerType/ownerId in the\n// body, not an X-Workspace-ID header.\n\nexport class MediaClient {\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// POST /media — store an image; returns the asset with its monomorphic\n\t// /media/:id url. requireAuth server-side.\n\tupload(input: IUploadMediaInput) {\n\t\treturn this.http.request<IApiResponse<IMediaAssetResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/media',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// DELETE /media/:id — uploader-only (403 for anyone else).\n\tdelete(id: string) {\n\t\treturn this.http.request<IApiResponse<{ id: string }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/media/${encodeURIComponent(id)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// Absolute URL for a stored asset — an `<img src>` target. The GET /media/:id\n\t// route is public and cached (it can't carry a Bearer token), so turn an\n\t// upload's `asset.id` into a browser-loadable URL with this, and use it as\n\t// the avatarUrl handed to auth's updateProfile.\n\tassetUrl(id: string): string {\n\t\treturn this.http.absolute(`/media/${encodeURIComponent(id)}`);\n\t}\n\n\t// Inverse of assetUrl: pull the asset id out of one of THIS brick's\n\t// /media/:id URLs (absolute or relative); null for empty/external URLs. Lets\n\t// avatar cleanup delete only assets we minted (matched as a UUID), never a\n\t// placeholder or third-party avatar URL.\n\tassetIdFromUrl(url: string | null | undefined): string | null {\n\t\tif (!url) return null;\n\t\tconst m = url.match(\n\t\t\t/\\/media\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)/i,\n\t\t);\n\t\treturn m ? m[1]! : null;\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type { IApiResponse } from '../types';\n\n// ── Public remote config ─────────────────────────────────────────────────────\n// The frontend's read path for feature flags and runtime settings: only the\n// keys the server lists in ConfigModule's `publicKeys`. One snapshot per\n// FonderieClient, shared by every screen and hook that reads it — load it once\n// (typically right after sign-in, or at app start for signed-out flags), then\n// read synchronously anywhere.\n\nexport interface IRemoteConfigState {\n\t/** key → value, as last loaded. Empty until the first load succeeds. */\n\tvalues: Readonly<Record<string, unknown>>;\n\t/** When values were last loaded successfully; null before that. */\n\tloadedAt: Date | null;\n\tisLoading: boolean;\n\t/** The last load's failure, cleared by the next success. Values are kept. */\n\terror: unknown;\n}\n\ntype Listener = (state: IRemoteConfigState) => void;\n\nexport class ConfigClient {\n\tprivate state: IRemoteConfigState = { values: {}, loadedAt: null, isLoading: false, error: null };\n\tprivate listeners = new Set<Listener>();\n\tprivate inFlight: Promise<IRemoteConfigState> | null = null;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\t// GET /config/public — fetch the public values into the shared snapshot.\n\t// Concurrent calls share one request. A failure keeps the previous values\n\t// (a flag that was on does not flicker off because one refresh failed) and\n\t// is reported in `error`; before any success, reads fall back to defaults.\n\tload(): Promise<IRemoteConfigState> {\n\t\tif (this.inFlight) return this.inFlight;\n\t\tthis.set({ isLoading: true });\n\t\tthis.inFlight = this.http\n\t\t\t.request<IApiResponse<{ values: Record<string, unknown> }>>({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: '/config/public',\n\t\t\t\t// Sent when signed in, so per-user values can be served later\n\t\t\t\t// without a client change; the route itself is public.\n\t\t\t\ttoken: this.tokens.get(),\n\t\t\t})\n\t\t\t.then(\n\t\t\t\t(res) => this.set({ values: res.result?.values ?? {}, loadedAt: new Date(), isLoading: false, error: null }),\n\t\t\t\t(error: unknown) => this.set({ isLoading: false, error }),\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.inFlight = null;\n\t\t\t});\n\t\treturn this.inFlight;\n\t}\n\n\t// One value, with the fallback used when the key is absent — before the\n\t// first load, when it failed, or when the server does not expose the key.\n\t// Pick the SAFE fallback (feature off), not the optimistic one.\n\tget<T>(key: string, fallback: T): T {\n\t\treturn Object.hasOwn(this.state.values, key) ? (this.state.values[key] as T) : fallback;\n\t}\n\n\t// The whole current state (values, loadedAt, isLoading, error).\n\tsnapshot(): IRemoteConfigState {\n\t\treturn this.state;\n\t}\n\n\t// Called with the new state after every change; returns an unsubscribe.\n\tsubscribe(listener: Listener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate set(patch: Partial<IRemoteConfigState>): IRemoteConfigState {\n\t\t// A new object each time, so React's useSyncExternalStore and Vue refs\n\t\t// see a change by identity.\n\t\tthis.state = { ...this.state, ...patch };\n\t\tfor (const listener of this.listeners) listener(this.state);\n\t\treturn this.state;\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(userId)}/roles/${encodeURIComponent(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/${encodeURIComponent(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 { MediaClient } from './modules/media';\nimport { ConfigClient } from './modules/config';\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\treadonly media: MediaClient;\n\t/** Public remote config: flags and settings the server exposes to frontends. */\n\treadonly config: ConfigClient;\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// Media is per-user (ownership via ownerType/ownerId in the body), so no\n\t\t// setWorkspaceId wiring below — just the shared http + token store.\n\t\tthis.media = new MediaClient(this.http, this.tokens);\n\t\tthis.config = new ConfigClient(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>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'POST',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tput<T = unknown>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tpatch<T = unknown>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tdelete<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n}\n","// Where an admin surface is mounted, as CONFIG: trailing slashes are typing,\n// not meaning, so '/_admin', '/_admin/' and '/_admin//' are one prefix.\n//\n// This duplicates `normalizeMountPath` in @fonderie/core on purpose: this\n// package ships with **zero runtime dependencies** so it can be dropped into\n// any frontend, and importing a server package to strip a slash would end\n// that. One copy here, used by every admin client — not one per client.\nexport const normalizeMountPath = (path: string): string => path.replace(/\\/+$/, '');\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\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\t/** Required to change an existing key's value kind (on/off → text, list → object);\n\t * without it the server answers 409 CONFIG_TYPE_CHANGE. */\n\tallowTypeChange?: boolean;\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// Where the composed surface lives when @fonderie/admin mounts this brick's\n\t// routes — '/_admin' replaces the leading '/admin' of every path. Unset ⇒\n\t// the brick's own standalone routes under '/admin'.\n\tprefix?: 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 prefix: string | undefined;\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.prefix = opts.prefix ? normalizeMountPath(opts.prefix) : undefined;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// The path literals stay on the legacy '/admin/...' so the route table and\n\t// the coverage gate read them; the prefix is applied here at request time.\n\tprivate rebase<T extends { path: string }>(opts: T): T {\n\t\tif (!this.prefix) return opts;\n\t\treturn { ...opts, path: opts.path.replace(/^\\/admin(?=\\/|\\?|$)/, this.prefix) };\n\t}\n\n\t// ── Config ───────────────────────────────────────────────────────────────\n\n\tlistConfig(environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\tgetConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tdeleteConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tlistConfigRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigRevision[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}/revisions${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}/rollback${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\tgetSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tdeleteSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tlistSecretRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretRevision[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/revisions${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/rollback${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/reveal${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tAdminScope,\n\tIAdminAttention,\n\tIAdminCreatedLink,\n\tIAdminEnrollment,\n\tIAdminOperator,\n\tIAdminOperatorsReport,\n\tIAdminSecondFactor,\n\tIAdminSession,\n\tIAdminEnvironmentReport,\n\tIAdminDoctorReport,\n\tIAdminIssuedToken,\n\tIAdminIssueTokenInput,\n\tIAdminLogPage,\n\tIAdminManifest,\n\tIAdminMigrationModule,\n\tIAdminMigrationsReport,\n\tIAdminRoutesReport,\n\tIAdminTokensReport,\n\tIApiResponse,\n} from '../types';\n\nexport interface IAdminClientOptions {\n\tbaseUrl: string;\n\t// A token (machines, the CLI). Omit it in a browser signed in as an\n\t// operator: the session cookie authenticates instead.\n\tadminToken?: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminLogQuery {\n\tlimit?: number;\n\tbefore?: string;\n}\n\n// Deliberately not on FonderieClient: no user session can reach this surface.\nexport class AdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string | undefined;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate get<T>(suffix: string) {\n\t\treturn this.call<T>('GET', suffix);\n\t}\n\n\tprivate call<T>(method: string, suffix: string, body?: unknown) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t\t...(body !== undefined ? { body } : {}),\n\t\t});\n\t}\n\n\tattention() {\n\t\treturn this.get<IAdminAttention>('');\n\t}\n\n\tmanifest() {\n\t\treturn this.get<IAdminManifest>('/manifest');\n\t}\n\n\tdoctor() {\n\t\treturn this.get<IAdminDoctorReport>('/doctor');\n\t}\n\n\tenvironment() {\n\t\treturn this.get<IAdminEnvironmentReport>('/environment');\n\t}\n\n\troutes() {\n\t\treturn this.get<IAdminRoutesReport>('/routes');\n\t}\n\n\ttokens() {\n\t\treturn this.get<IAdminTokensReport>('/access/tokens');\n\t}\n\n\tadminLog(query: IAdminLogQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.before) q.set('before', query.before);\n\t\tconst qs = q.toString();\n\t\treturn this.get<IAdminLogPage>(`/activity/admin-log${qs ? `?${qs}` : ''}`);\n\t}\n\n\t// Root token only. The plaintext comes back once.\n\tissueToken(input: IAdminIssueTokenInput) {\n\t\treturn this.call<IAdminIssuedToken>('POST', '/access/tokens', input);\n\t}\n\n\t// Root token only.\n\trevokeToken(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/access/tokens/${encodeURIComponent(id)}`);\n\t}\n\n\t// What each module is waiting on, with every pending file's impact. Empty\n\t// when the deployment did not hand its migration sequence to the surface.\n\tmigrations() {\n\t\treturn this.get<IAdminMigrationsReport>('/migrations');\n\t}\n\n\t/**\n\t * Apply one module's pending migrations — all of them, or none.\n\t *\n\t * `expect` is the pending list you were shown, in order. If it no longer\n\t * matches, the server refuses with 409 MIGRATIONS_CHANGED rather than\n\t * applying something nobody reviewed. Also refuses 409 when an earlier\n\t * module is behind, and 422 when any pending file deletes data.\n\t */\n\tapplyMigrations(module: string, expect: readonly string[]) {\n\t\treturn this.call<IAdminMigrationModule>(\n\t\t\t'POST',\n\t\t\t`/migrations/${encodeURIComponent(module)}/apply`,\n\t\t\t{ expect },\n\t\t);\n\t}\n\t// ── operator sign-in (the served console's gate) ──────────────────────\n\t// Cookie-based: the server sets an HttpOnly session cookie; nothing here\n\t// ever holds it. Omit adminToken on this client — except for claim().\n\n\t/** Who is signed in, and whether the console can still be claimed. */\n\tsession() {\n\t\treturn this.get<IAdminSession>('/session');\n\t}\n\n\t/** The one-time claim. Needs the ROOT token as this client's adminToken. */\n\tclaim(input: { email: string; password: string; name?: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/claim', input);\n\t}\n\n\tlogin(input: { email: string; password: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/login', input);\n\t}\n\n\t/** The authenticator secret and otpauth URI to scan while enrolling. */\n\tenrollment() {\n\t\treturn this.get<IAdminEnrollment>('/session/enrollment');\n\t}\n\n\t/** Confirms the first code. The response carries the backup codes, once. */\n\tconfirmEnrollment(code: string) {\n\t\treturn this.call<IAdminSession>('POST', '/session/enrollment', { code });\n\t}\n\n\t/** The second factor after the password: an authenticator code or a backup code. */\n\tverify(factor: IAdminSecondFactor) {\n\t\treturn this.call<IAdminSession>('POST', '/session/verify', factor);\n\t}\n\n\t/** A fresh code for the next five minutes of dangerous actions. */\n\tstepUp(factor: IAdminSecondFactor) {\n\t\treturn this.call<{ stepUpFresh: boolean; backupCodesLeft?: number }>(\n\t\t\t'POST',\n\t\t\t'/session/step-up',\n\t\t\tfactor,\n\t\t);\n\t}\n\n\tlogout() {\n\t\treturn this.call<undefined>('DELETE', '/session');\n\t}\n\n\t/** What an invite or recovery link is for, before setting a password. */\n\tinspectLink(token: string) {\n\t\treturn this.call<{ kind: 'invite' | 'recovery'; email: string }>(\n\t\t\t'POST',\n\t\t\t'/session/link/inspect',\n\t\t\t{ token },\n\t\t);\n\t}\n\n\tredeemLink(input: { token: string; password: string; name?: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/link', input);\n\t}\n\n\t// ── managing operators ─────────────────────────────────────────────────\n\n\toperators() {\n\t\treturn this.get<IAdminOperatorsReport>('/access/operators');\n\t}\n\n\t/** An invite link, shown once. Needs the highest scope and a fresh code. */\n\tinviteOperator(input: { email: string; scopes: AdminScope[]; expiresInHours?: number }) {\n\t\treturn this.call<IAdminCreatedLink>('POST', '/access/operators/invites', input);\n\t}\n\n\t/** Lost password or authenticator: a single-use link; signs them out everywhere. */\n\trecoverOperator(id: string) {\n\t\treturn this.call<IAdminCreatedLink>(\n\t\t\t'POST',\n\t\t\t`/access/operators/${encodeURIComponent(id)}/recovery`,\n\t\t);\n\t}\n\n\tupdateOperator(id: string, input: { scopes?: AdminScope[]; name?: string; disabled?: boolean }) {\n\t\treturn this.call<IAdminOperator>('PUT', `/access/operators/${encodeURIComponent(id)}`, input);\n\t}\n\n\trevokeOperatorLink(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/access/operators/links/${encodeURIComponent(id)}`);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tIAdminUserDTO,\n\tIAdminUserPageResult,\n\tIApiResponse,\n\tILoginHistoryPageResult,\n\tISessionDTO,\n} from '../types';\n\nexport interface IAuthAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminLoginHistoryQuery {\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface IAdminUsersQuery {\n\tlimit?: number;\n\tcursor?: string;\n\t// true ⇒ only soft-deleted accounts (not yet purged).\n\tdeleted?: boolean;\n}\n\n// @fonderie/auth's operator routes, which exist only through @fonderie/admin.\n// Deliberately not on FonderieClient: no user session can reach them.\nexport class AuthAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAuthAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate call<T>(method: string, suffix: string) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}/users${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\t// A page of users, newest first. The same route as findUser — with an email\n\t// it looks one up, without one it lists.\n\tlistUsers(query: IAdminUsersQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tif (query.deleted) q.set('deleted', '1');\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminUserPageResult>('GET', qs ? `?${qs}` : '');\n\t}\n\n\tfindUser(email: string) {\n\t\treturn this.call<IAdminUserDTO>('GET', `?email=${encodeURIComponent(email)}`);\n\t}\n\n\tgetUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('GET', `/${encodeURIComponent(id)}`);\n\t}\n\n\tlistUserSessions(id: string) {\n\t\treturn this.call<ISessionDTO[]>('GET', `/${encodeURIComponent(id)}/sessions`);\n\t}\n\n\t// Signs the user out everywhere.\n\trevokeUserSessions(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/${encodeURIComponent(id)}/sessions`);\n\t}\n\n\tuserLoginHistory(id: string, query: IAdminLoginHistoryQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<ILoginHistoryPageResult>(\n\t\t\t'GET',\n\t\t\t`/${encodeURIComponent(id)}/login-history${qs ? `?${qs}` : ''}`,\n\t\t);\n\t}\n\n\tsuspendUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('POST', `/${encodeURIComponent(id)}/suspend`);\n\t}\n\n\tunsuspendUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('POST', `/${encodeURIComponent(id)}/unsuspend`);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tIAdminCatalog,\n\tIAdminGrantInput,\n\tIAdminPlanInput,\n\tIAdminSubscriptionDTO,\n\tIAdminSubscriptionPage,\n\tIAdminWalletDTO,\n\tIAdminWalletLedgerPage,\n\tIApiResponse,\n\tIPlanDTO,\n\tSubscriberType,\n} from '../types';\n\nexport interface IBillingAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminSubscriptionsQuery {\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface IAdminLedgerQuery {\n\tcurrency?: string;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// @fonderie/billing's operator routes, which exist only through @fonderie/admin.\n// Deliberately not on FonderieClient: no user session can reach them.\nexport class BillingAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IBillingAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate call<T>(method: string, suffix: string, body?: unknown) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t\t...(body !== undefined ? { body } : {}),\n\t\t});\n\t}\n\n\tprivate sub(type: SubscriberType, id: string) {\n\t\treturn `/${type}/${encodeURIComponent(id)}`;\n\t}\n\n\tcatalog() {\n\t\treturn this.call<IAdminCatalog>('GET', '/catalog');\n\t}\n\n\tcreatePlan(input: IAdminPlanInput & { name: string }) {\n\t\treturn this.call<IPlanDTO>('POST', '/plans', input);\n\t}\n\n\tupdatePlan(planId: string, input: IAdminPlanInput) {\n\t\treturn this.call<IPlanDTO>('PUT', `/plans/${encodeURIComponent(planId)}`, input);\n\t}\n\n\tdeletePlan(planId: string) {\n\t\treturn this.call<undefined>('DELETE', `/plans/${encodeURIComponent(planId)}`);\n\t}\n\n\t// A page of subscribers, newest first. The lookup below still answers for a\n\t// known subscriber; this is for finding one you cannot name.\n\tlistSubscriptions(query: IAdminSubscriptionsQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminSubscriptionPage>('GET', `/subscriptions${qs ? `?${qs}` : ''}`);\n\t}\n\n\tsubscription(type: SubscriberType, id: string) {\n\t\treturn this.call<IAdminSubscriptionDTO>('GET', `/subscriptions${this.sub(type, id)}`);\n\t}\n\n\twallet(type: SubscriberType, id: string, currency?: string) {\n\t\tconst qs = currency ? `?currency=${encodeURIComponent(currency)}` : '';\n\t\treturn this.call<IAdminWalletDTO>('GET', `/wallet${this.sub(type, id)}${qs}`);\n\t}\n\n\twalletLedger(type: SubscriberType, id: string, query: IAdminLedgerQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.currency) q.set('currency', query.currency);\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminWalletLedgerPage>(\n\t\t\t'GET',\n\t\t\t`/wallet${this.sub(type, id)}/ledger${qs ? `?${qs}` : ''}`,\n\t\t);\n\t}\n\n\t// Manual credit — an idempotency key is required by the server.\n\tgrant(input: IAdminGrantInput) {\n\t\treturn this.call<unknown>('POST', '/wallet/grant', input);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type { IApiResponse, IAuditPageResult } from '../types';\n\nexport interface IAuditAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\n// The workspace-scoped filters, plus the workspace itself as a filter.\nexport interface IAdminAuditQuery {\n\tworkspaceId?: string;\n\ttype?: string;\n\tactorId?: string;\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// @fonderie/audit's operator read, which exists only through @fonderie/admin.\nexport class AuditAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAuditAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// Every workspace unless one is named. Newest first, keyset-paged.\n\tlistAudit(query: IAdminAuditQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.workspaceId) q.set('workspaceId', query.workspaceId);\n\t\tif (query.type) q.set('type', query.type);\n\t\tif (query.actorId) q.set('actorId', query.actorId);\n\t\tif (query.from) q.set('from', query.from.toISOString());\n\t\tif (query.to) q.set('to', query.to.toISOString());\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.http.request<IApiResponse<IAuditPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `${this.prefix}/audit${qs ? `?${qs}` : ''}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\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 IPreviewTemplateInput {\n\ttext: string;\n\tsubject?: string;\n\thtml?: string;\n\t// Values for the template's {{variables}}. Omitted, every variable renders\n\t// empty and every {{#section}} collapses — accurate for layout, misleading\n\t// about content.\n\tdata?: Record<string, unknown>;\n}\n\n// What the renderer produced: no `html` key at all for a text-only template.\nexport interface IRenderedTemplateResult {\n\tsubject?: string;\n\thtml?: string;\n\ttext: string;\n\t// Every {{variable}} this content refers to, reported by the server so the\n\t// editor can offer the right fields without re-implementing the contract.\n\tvariables: string[];\n}\n\nexport interface ICourierAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where the composed surface lives when @fonderie/admin mounts this brick's\n\t// routes — '/_admin' replaces the leading '/admin' of every path. Unset ⇒\n\t// the brick's own standalone routes under '/admin'.\n\tprefix?: 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 prefix: string | undefined;\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.prefix = opts.prefix ? normalizeMountPath(opts.prefix) : undefined;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// The path literals stay on the legacy '/admin/...' so the route table and\n\t// the coverage gate read them; the prefix is applied here at request time.\n\tprivate rebase<T extends { path: string }>(opts: T): T {\n\t\tif (!this.prefix) return opts;\n\t\treturn { ...opts, path: opts.path.replace(/^\\/admin(?=\\/|\\?|$)/, this.prefix) };\n\t}\n\n\tlistTemplates() {\n\t\treturn this.http.request<IApiResponse<ITemplateEntry[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: '/admin/templates',\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/revisions${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/rollback${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Renders content you are HOLDING, not what is stored — so an editor can\n\t// show the change before it is saved. Server-side on purpose: the shell and\n\t// the variable substitution are the resolver's, and a preview rendered any\n\t// other way would not be the mail that sends.\n\tpreviewTemplate(type: string, input: IPreviewTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<IRenderedTemplateResult>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/preview${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n}\n","import type { ITemplateEntry } from './types';\n\n// The template store keys rows by (type, locale), and the list endpoint returns\n// them flat. An operator thinks in emails, not rows: \"welcome, in English,\n// French and Spanish\". These helpers give every console the same grouping, so\n// the React and Vue screens cannot disagree about order or suggestions.\n\n/** One email and every locale it exists in. */\nexport interface ITemplateGroup {\n\ttype: string;\n\t/** Default locale (null) first, then the rest alphabetically. */\n\tentries: ITemplateEntry[];\n\t/** The entry a click on the email itself should open: the default, else the first. */\n\tprimary: ITemplateEntry;\n\t/** Built-in email (its default-locale row can never be deleted). */\n\tsystem: boolean;\n}\n\nconst byLocale = (a: ITemplateEntry, b: ITemplateEntry): number =>\n\ta.locale === b.locale ? 0 : a.locale === null ? -1 : b.locale === null ? 1 : a.locale.localeCompare(b.locale);\n\n/** Rows grouped by type, types in the order the server listed them. */\nexport function groupTemplatesByType(rows: readonly ITemplateEntry[]): ITemplateGroup[] {\n\tconst groups = new Map<string, ITemplateEntry[]>();\n\tfor (const row of rows) {\n\t\tconst entries = groups.get(row.type);\n\t\tif (entries) entries.push(row);\n\t\telse groups.set(row.type, [row]);\n\t}\n\treturn [...groups].map(([type, entries]) => {\n\t\tentries.sort(byLocale);\n\t\tconst primary = entries[0] as ITemplateEntry;\n\t\treturn { type, entries, primary, system: entries.some((e) => e.system === true) };\n\t});\n}\n\n/**\n * Locales the app already uses elsewhere that `type` has no version in yet —\n * what \"Add locale\" should suggest first. A French welcome email with no French\n * receipt is exactly the gap an operator is looking for.\n */\nexport function missingTemplateLocales(rows: readonly ITemplateEntry[], type: string): string[] {\n\tconst has = new Set(rows.filter((r) => r.type === type).map((r) => r.locale));\n\tconst used = new Set(rows.map((r) => r.locale).filter((l): l is string => l !== null && !has.has(l)));\n\treturn [...used].sort();\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\t// OAuth provider linked to this account ('google', 'apple'), or '' if none.\n\tprovider: string;\n\t// Whether a password is set. With `provider`, this is what a settings screen\n\t// needs to render sign-in methods and to know whether unlinkOauth() can\n\t// succeed — an account with no password has no other credential, so the\n\t// server refuses (409 PASSWORD_REQUIRED) rather than locking the user out.\n\thasPassword: 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\n/** What GET /auth/providers answers: the sign-in methods this API can honour. */\nexport interface IAuthProvidersResult {\n\tproviders: string[];\n}\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(\n\tresult: ILoginResult | IMfaRequiredResult,\n): 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// Wallet balance snapshot. Money fields are digit strings (server bigint →\n// string); spendPurchased is a real boolean. granted/purchased/spendPurchased/\n// grantedExpiresAt are omitted on a legacy read that predates the bucket split.\nexport interface IWalletDTO {\n\tbalance: string;\n\tcurrency: string;\n\tprecision: number;\n\tgranted?: string;\n\tpurchased?: string;\n\tspendPurchased?: boolean;\n\tgrantedExpiresAt?: string | null;\n}\n\nexport interface IWalletResult {\n\twallet: IWalletDTO;\n}\n\n// One wallet ledger entry. Money fields are digit strings (server bigint →\n// string); `balanceAfter` is the running balance, so a history UI can show a\n// trustworthy per-row balance without re-deriving it.\nexport interface IWalletTransactionDTO {\n\tid: string;\n\ttype: string; // 'purchase' | 'grant' | 'usage' | 'refund' | 'adjustment' | 'expiry'\n\tamount: string; // signed: positive = credit, negative = debit\n\tbalanceAfter: string;\n\tcurrency: string;\n\tdescription: string | null;\n\tproviderTxId: string | null;\n\tmetadata: Record<string, unknown>;\n\tcreatedAt: string;\n}\n\nexport interface IWalletTransactionsResult {\n\ttransactions: IWalletTransactionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IWalletCheckoutInput {\n\tpackId: string;\n}\n\nexport interface IWalletPurchaseInput {\n\tpackId: string;\n\t// One per purchase attempt, REUSED on retry: a double-submit or a retry after\n\t// a `processing` result dedupes to the same charge instead of charging twice.\n\tidempotencyKey: string;\n}\n\n// Outcome of an in-app pack purchase charged to the saved card. `status` is the\n// discriminator: 'credited' carries the new balance; 'checkout_required' means\n// fall back to createWalletCheckout (no saved card, or the card needs 3-D\n// Secure); 'declined' is a hard decline; 'processing' is indeterminate — retry\n// with the SAME idempotencyKey (never a fresh hosted checkout, or you'd risk a\n// double-charge).\nexport interface IWalletPurchaseResult {\n\tstatus: 'credited' | 'checkout_required' | 'declined' | 'processing';\n\tbalance?: string;\n\tcurrency?: string;\n\tcredits?: string;\n\tduplicate?: boolean;\n\treason?: 'no_saved_card' | 'authentication_required';\n}\n\nexport interface ICancelSubscriptionInput {\n\t// Default true — keep access until the paid-through date. false ends it now.\n\tatPeriodEnd?: boolean;\n}\n\n// Result of a first-party cancel/reactivate — the subscription's new lifecycle\n// state, read straight back without waiting for the provider webhook.\nexport interface ISubscriptionChangeResult {\n\tatPeriodEnd: boolean;\n\tstatus: string;\n\tcurrentPeriodEnd: string | null;\n}\n\n// The customer's card on file, for display. Never carries the full number —\n// nor the server-side card `fingerprint`, which billing deliberately keeps\n// off the wire (it correlates identity across accounts).\nexport interface IPaymentMethodDTO {\n\tbrand: string;\n\tlast4: string;\n\texpMonth: number;\n\texpYear: number;\n}\n\nexport interface IPaymentMethodResult {\n\tpaymentMethod: IPaymentMethodDTO | null;\n}\n\n// Begin in-app card entry: the provider SetupIntent client secret the embedded\n// card element (Stripe Payment Element) confirms — no hosted-checkout redirect.\nexport interface ISetupIntentResult {\n\tclientSecret: string;\n}\n\n// Save a card after the client confirms the SetupIntent — the provider payment\n// method id the Payment Element produced.\nexport interface ISavePaymentMethodInput {\n\tpaymentMethodId: string;\n}\n\n// One invoice for an in-app history list; `hostedInvoiceUrl`/`invoicePdf` link\n// out to the provider. Amounts are digit strings (smallest currency unit).\nexport interface IInvoiceDTO {\n\tid: string;\n\tnumber: string | null;\n\tamountDue: string;\n\tamountPaid: string;\n\tcurrency: string;\n\tstatus: string;\n\tcreated: string;\n\tdueDate: string | null; // ISO-8601 when the invoice has payment terms; null when paid on charge\n\thostedInvoiceUrl: string | null;\n\tinvoicePdf: string | null;\n}\n\nexport interface IInvoicesResult {\n\tinvoices: IInvoiceDTO[];\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\t// A built-in email's default-locale row: edit and roll back, never delete.\n\t// Present on list results from @fonderie/courier ≥ the system-template release.\n\tsystem?: boolean;\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// ── Admin (the operator's surface) ───────────────────────────────────────────\n// Admin-token authenticated — see AdminClient. Shapes mirror @fonderie/admin's\n// pages; the client owns its copies, like every other section here.\n\nexport interface IAdminReadinessProblem {\n\tmodule: string;\n\tseverity: 'error' | 'warning';\n\tmessage: string;\n}\n\nexport interface IAdminReadiness {\n\tok: boolean;\n\tproblems: IAdminReadinessProblem[];\n}\n\nexport interface IAdminModuleEntry {\n\tname: string;\n\tversion: string | null;\n\treadiness: IAdminReadiness;\n\tdescribesAdmin: boolean;\n}\n\nexport interface IAdminRouteEntry {\n\tmethod: string;\n\tpath: string;\n\tmodule?: string;\n}\n\nexport interface IAdminManifest {\n\tgeneratedAt: string;\n\tenv: string;\n\t// `host` is null when the surface answers on any hostname.\n\tadmin: { version: string; log: boolean; host: string[] | null };\n\tmodules: IAdminModuleEntry[];\n\treadiness: IAdminReadiness;\n\troutes: IAdminRouteEntry[];\n}\n\nexport interface IAdminCheckResult {\n\tname: string;\n\tmodule: string;\n\tok: boolean;\n\tfindings: string[];\n\tskipped?: string;\n\tdurationMs: number;\n}\n\nexport interface IAdminDoctorReport {\n\tgeneratedAt: string;\n\tok: boolean;\n\tchecks: IAdminCheckResult[];\n}\n\nexport interface IAdminAttentionItem {\n\tsource: string;\n\tseverity: 'error' | 'advice';\n\tmessage: string;\n}\n\nexport interface IAdminAttention {\n\tgeneratedAt: string;\n\tok: boolean;\n\titems: IAdminAttentionItem[];\n}\n\nexport interface IAdminEnvironmentReport {\n\tgeneratedAt: string;\n\treadiness: IAdminReadiness;\n\tmodules: Array<{ name: string; problems: IAdminReadinessProblem[] }>;\n\tenv: Array<{ name: string; set: boolean }>;\n}\n\nexport type AdminRouteGuard = 'admin' | 'probe' | 'app';\n\nexport interface IAdminRoutesReport {\n\tgeneratedAt: string;\n\troutes: Array<IAdminRouteEntry & { guard: AdminRouteGuard }>;\n}\n\nexport type AdminScope = 'read' | 'write' | 'secrets';\n\n// An issued scoped token — never its hash or plaintext.\nexport interface IAdminTokenRecord {\n\tid: string;\n\tname: string;\n\tscopes: AdminScope[];\n\tcreatedBy: string;\n\tcreatedAt: string;\n\texpiresAt: string | null;\n\trevokedAt: string | null;\n\tlastUsedAt: string | null;\n}\n\nexport interface IAdminTokensReport {\n\tgeneratedAt: string;\n\tadmin: { ok: boolean; problems: IAdminReadinessProblem[] };\n\tlegacy: Array<{ module: string; set: boolean }>;\n\t// null when the deployment gave AdminModule no store (issuing is off).\n\tissued: IAdminTokenRecord[] | null;\n}\n\nexport interface IAdminIssueTokenInput {\n\tname: string;\n\tscopes: AdminScope[];\n\texpiresInDays?: number;\n}\n\n// The plaintext is returned once, at issue, and never again.\nexport interface IAdminIssuedToken extends IAdminTokenRecord {\n\ttoken: string;\n}\n\n// ── operators: people who sign in to the admin console ──────────────────\n\n// What the API ever says about an operator — never a hash, secret or code.\nexport interface IAdminOperator {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\tscopes: AdminScope[];\n\t// false until they have scanned the QR code and confirmed a code.\n\tenrolled: boolean;\n\tbackupCodesLeft: number;\n\tlocked: boolean;\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tlastLoginAt: string | null;\n\tdisabledAt: string | null;\n}\n\n// A pending single-use link: an invite, or a recovery for a locked-out operator.\nexport interface IAdminOperatorLink {\n\tid: string;\n\tkind: 'invite' | 'recovery';\n\temail: string;\n\tscopes: AdminScope[];\n\tcreatedBy: string;\n\tcreatedAt: string;\n\texpiresAt: string;\n}\n\nexport interface IAdminOperatorsReport {\n\toperators: IAdminOperator[];\n\tlinks: IAdminOperatorLink[];\n}\n\n// Returned once: the link to hand to the person. `url` points at the console\n// with the token in the hash, so it never reaches a server log.\nexport interface IAdminCreatedLink {\n\tid: string;\n\temail: string;\n\tscopes?: AdminScope[];\n\texpiresAt: string;\n\ttoken: string;\n\turl: string;\n}\n\nexport type AdminSessionState = 'signed-out' | 'needs-2fa' | 'needs-enrollment' | 'signed-in';\n\nexport interface IAdminSession {\n\tstate: AdminSessionState;\n\toperator: IAdminOperator | null;\n\t// true only while no operator exists yet: the root token can claim the console.\n\tclaimable?: boolean;\n\tstepUpFresh?: boolean;\n\t// Present once, right after enrollment. Show them; they are never shown again.\n\tbackupCodes?: string[];\n\t// After signing in with a backup code: how many remain.\n\tbackupCodesLeft?: number;\n}\n\nexport interface IAdminEnrollment {\n\tsecret: string;\n\t// otpauth:// — render as a QR code.\n\turi: string;\n\taccount: string;\n\tissuer: string;\n}\n\nexport type IAdminSecondFactor = { code: string } | { backupCode: string };\n\nexport interface IAdminLogEntry {\n\tid: string;\n\tat: string;\n\tactor: string;\n\tmethod: string;\n\tpath: string;\n\troute: string;\n\tmodule: string;\n\tstatus: number;\n\tdurationMs: number;\n\trequestId: string | null;\n\tclientIp: string | null;\n}\n\nexport interface IAdminLogPage {\n\tentries: IAdminLogEntry[];\n\tnext: string | null;\n}\n\n// The operator's view of a user (@fonderie/auth's described admin routes):\n// the app's own DTO plus what support asks about. Never a hash or MFA secret.\nexport interface IAdminUserDTO extends IUserDTO {\n\tdeletedAt: string | null;\n}\n\n// The operator's money reads (@fonderie/billing's described admin routes).\nexport interface IAdminCatalog {\n\t// config.plans as declared; bigint wallet amounts arrive as strings.\n\tconfigured: unknown[];\n\tstored: IPlanDTO[];\n}\n\nexport interface IAdminSubscriptionDTO {\n\tid: string;\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\tplan: string;\n\tinterval: string;\n\tstatus: string;\n\tproviderCustomerId: string | null;\n\tproviderSubscriptionId: string | null;\n\tcurrentPeriodStart: string | null;\n\tcurrentPeriodEnd: string | null;\n\tcancelAtPeriodEnd: boolean;\n\ttrialEndsAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IAdminWalletDTO extends IWalletDTO {\n\tversion: number;\n\tupdatedAt: string | null;\n}\n\nexport interface IAdminSubscriptionPage {\n\tsubscriptions: IAdminSubscriptionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IAdminWalletLedgerPage {\n\tcurrency: string;\n\tentries: IWalletTransactionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IAdminPlanInput {\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 interface IAdminGrantInput {\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\t// Minor units as a digit string (or a number below 2^53).\n\tamount: string | number;\n\tcurrency?: string;\n\tdescription?: string;\n\tidempotencyKey: 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// ── Login activity (auth security surfaces) ──────────────────────────────────\n// Session-authenticated; the caller's own history + sessions (shares the\n// AuthClient token). Login history is append-only; sessions are the live list.\n\n/** Where an auth event (login attempt, registration, session) came from. Present only when the server configures a\n * location resolver; every field is optional. Country is reliable; region and\n * city are approximate; network fields appear only with an IP-intelligence\n * provider. */\nexport interface IRequestLocationDTO {\n\tcountry?: string; // ISO-3166-1 alpha-2\n\tcountryName?: string;\n\tsubdivision?: string; // ISO-3166-2 region part\n\tsubdivisionName?: string;\n\tcity?: string;\n\tpostalCode?: string; // ZIP / postal code, approximate — not shown by describeLocation\n\tcontinent?: string;\n\ttimeZone?: string;\n\tlatitude?: number;\n\tlongitude?: number;\n\taccuracyRadius?: number; // km — how approximate the point is\n\tgeonameId?: number; // stable, language-neutral place key (GeoNames)\n\tisp?: string;\n\torg?: string;\n\tasn?: string;\n\tmobile?: boolean;\n\tproxy?: boolean;\n\thosting?: boolean;\n}\n\n/**\n * One short line for a login location: \"Mountain View, CA, US\" — most specific first,\n * skipping what is unknown. Pass a country-name formatter to localise the\n * country (e.g. Intl.DisplayNames). null when nothing is known.\n */\nexport function describeLocation(\n\tloc: IRequestLocationDTO | null | undefined,\n\tcountryName?: (code: string) => string | undefined,\n): string | null {\n\tif (!loc) return null;\n\tconst country = loc.country\n\t\t? (countryName?.(loc.country) ?? loc.country)\n\t\t: (loc.countryName ?? undefined);\n\tconst parts = [loc.city, loc.subdivision ?? loc.subdivisionName, country].filter(\n\t\t(p): p is string => typeof p === 'string' && p.length > 0,\n\t);\n\treturn parts.length > 0 ? parts.join(', ') : null;\n}\n\nexport interface ILoginEventDTO {\n\tid: string;\n\tmethod: string;\n\toutcome: string;\n\tfailureReason: string | null;\n\tipAddress: string | null;\n\tuserAgent: string | null;\n\t/** null when the server has no location resolver, or it knew nothing. */\n\tlocation: IRequestLocationDTO | null;\n\tcreatedAt: string;\n}\n\nexport interface IAdminUserPageResult {\n\tusers: IAdminUserDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface ILoginHistoryPageResult {\n\tevents: ILoginEventDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface ISessionDTO {\n\tid: string;\n\tcurrent: boolean;\n\tipAddress: string | null;\n\tuserAgent: string | null;\n\t/** Where the session was opened from; null without a server-side resolver. */\n\tlocation: IRequestLocationDTO | null;\n\tcreatedAt: string;\n\texpiresAt: string;\n}\n\nexport interface ISessionsResult {\n\tsessions: ISessionDTO[];\n}\n\n// ── Media ────────────────────────────────────────────────────────────────────\n// Session-authenticated image storage (avatars, logos). `url` is the\n// monomorphic, backend-relative /media/:id path; call client.media.assetUrl(id)\n// for an absolute `<img src>`.\n\nexport interface IMediaAssetDTO {\n\tid: string;\n\turl: string;\n\tcontentType: string;\n\tbyteSize: number;\n\townerType: string;\n\townerId: string;\n\tpurpose: string;\n\tcreatedAt: string;\n}\n\nexport interface IMediaAssetResult {\n\tasset: IMediaAssetDTO;\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\n// ---- admin: migrations ----------------------------------------------------\n\nexport type MigrationImpact = 'additive' | 'destructive';\n\nexport interface IAdminPendingMigration {\n\tfile: string;\n\timpact: MigrationImpact;\n\t// The statements that earned a 'destructive' label, as written.\n\tdestructive: string[];\n}\n\nexport interface IAdminMigrationModule {\n\tname: string;\n\tpending: IAdminPendingMigration[];\n\t// The first EARLIER module that is behind, or null. Migration order is the\n\t// app's and sets depend on each other across it.\n\tblockedBy: string | null;\n\t// Whether the panel will apply this one: something to do, nothing in front\n\t// of it, and nothing in it that deletes data.\n\tappliable: boolean;\n}\n\nexport interface IAdminMigrationsReport {\n\t// False when the database has no fonderie_migrations rows — a first\n\t// install, where \"destructive\" has nothing to destroy.\n\teverApplied: boolean;\n\tmodules: IAdminMigrationModule[];\n}\n","// Typed config values for admin UIs (and, later, feature-flag hooks).\n//\n// Config values are stored as JSON, so a stored `true` stays a boolean and `3`\n// stays a number. What an editor needs on top is: which input to show for a\n// value, and how to turn what the operator typed back into a typed value —\n// with an explanation, not a silent failure, when it doesn't parse.\n\nexport type ConfigValueType = 'string' | 'number' | 'boolean' | 'json';\n\nexport const CONFIG_VALUE_TYPES: readonly ConfigValueType[] = ['string', 'number', 'boolean', 'json'];\n\n/** The editor type for a stored value. Objects, arrays and null are JSON. */\nexport function configValueType(value: unknown): ConfigValueType {\n\tif (typeof value === 'string') return 'string';\n\tif (typeof value === 'number') return 'number';\n\tif (typeof value === 'boolean') return 'boolean';\n\treturn 'json';\n}\n\n/** What an input should show for a stored value of that type. */\nexport function formatConfigValue(value: unknown, type: ConfigValueType = configValueType(value)): string {\n\tif (type === 'string') return typeof value === 'string' ? value : String(value ?? '');\n\tif (type === 'number') return typeof value === 'number' ? String(value) : '';\n\tif (type === 'boolean') return value === true ? 'true' : 'false';\n\treturn JSON.stringify(value ?? null, null, 2);\n}\n\nexport type CastResult = { ok: true; value: unknown } | { ok: false; error: string };\n\n/**\n * Turn what an operator typed into the typed value to store.\n * - string: kept verbatim (an empty string is a valid value)\n * - number: finite numbers only — \"1e3\" and \"-2.5\" are fine, \"12px\" is not\n * - boolean: true/false, also 1/0, yes/no, on/off (case-insensitive)\n * - json: any valid JSON\n */\nexport function castConfigValue(type: ConfigValueType, raw: string): CastResult {\n\tif (type === 'string') return { ok: true, value: raw };\n\tconst t = raw.trim();\n\tif (type === 'number') {\n\t\tif (t === '') return { ok: false, error: 'Enter a number.' };\n\t\tconst n = Number(t);\n\t\treturn Number.isFinite(n) ? { ok: true, value: n } : { ok: false, error: `\"${raw}\" is not a number.` };\n\t}\n\tif (type === 'boolean') {\n\t\tconst v = t.toLowerCase();\n\t\tif (['true', '1', 'yes', 'on'].includes(v)) return { ok: true, value: true };\n\t\tif (['false', '0', 'no', 'off'].includes(v)) return { ok: true, value: false };\n\t\treturn { ok: false, error: 'Use true or false.' };\n\t}\n\ttry {\n\t\treturn { ok: true, value: JSON.parse(t) };\n\t} catch (err) {\n\t\treturn { ok: false, error: `Not valid JSON: ${(err as Error).message}` };\n\t}\n}\n\n/**\n * Config keys: letters, digits, `.`, `_`, `-`; must start with a letter; up to\n * 128 characters. Both styles work — `ENABLE_JOB_LISTING` and `feature.dark-mode`.\n */\nexport const CONFIG_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9._-]{0,127}$/;\n\nexport function configKeyProblem(key: string): string | null {\n\tif (!key) return 'Enter a key.';\n\treturn CONFIG_KEY_PATTERN.test(key)\n\t\t? null\n\t\t: 'Start with a letter; use letters, digits, \".\", \"_\" or \"-\" (max 128).';\n}\n\nexport interface IInferredConfigValue {\n\ttype: ConfigValueType;\n\tvalue: unknown;\n\t/** Human label for the detected shape: Text, Number, On/off, Object, List. */\n\tlabel: string;\n\t/**\n\t * True when the input could equally be meant as text — \"true\", \"42\". The\n\t * editor offers \"save as text instead\" for exactly these, and never needs\n\t * to ask about anything else.\n\t */\n\tambiguous: boolean;\n}\n\n// A number only when writing it back gives the same characters: \"42\" and\n// \"-2.5\" qualify; \"1.10\" (a version), \"0123\" (a postal code), \"1e3\" and\n// 12345678901234567890 (an ID past float precision) do not — they stay text\n// rather than being silently rewritten.\nconst PLAIN_NUMBER = /^-?(0|[1-9]\\d*)(\\.\\d+)?$/;\n\n/** Human label for a stored value's shape. */\nexport function configValueLabel(value: unknown): string {\n\tif (typeof value === 'string') return 'Text';\n\tif (typeof value === 'number') return 'Number';\n\tif (typeof value === 'boolean') return 'On/off';\n\tif (Array.isArray(value)) return 'List';\n\tif (value === null) return 'Empty';\n\treturn 'Object';\n}\n\n/**\n * Work out what an operator typed, without asking. Objects and lists (JSON\n * starting with { or [), on/off (true/false), plain numbers, and text for\n * everything else — including anything that merely resembles a number.\n */\nexport function inferConfigValue(raw: string): IInferredConfigValue {\n\tconst t = raw.trim();\n\tif (t === 'true' || t === 'false') {\n\t\treturn { type: 'boolean', value: t === 'true', label: 'On/off', ambiguous: true };\n\t}\n\tif (PLAIN_NUMBER.test(t)) {\n\t\tconst n = Number(t);\n\t\tif (Number.isFinite(n) && String(n) === t) return { type: 'number', value: n, label: 'Number', ambiguous: true };\n\t}\n\tif (t.startsWith('{') || t.startsWith('[')) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(t);\n\t\t\tif (parsed !== null && typeof parsed === 'object') {\n\t\t\t\treturn { type: 'json', value: parsed, label: Array.isArray(parsed) ? 'List' : 'Object', ambiguous: false };\n\t\t\t}\n\t\t} catch {\n\t\t\t// not valid JSON — it is text that happens to start with a bracket\n\t\t}\n\t}\n\treturn { type: 'string', value: raw, label: 'Text', ambiguous: false };\n}\n","// English — canonical: this shape defines the keys fr and es must match.\nconst common = {\n\trefresh: 'Refresh',\n\tworking: 'Working…',\n\tloading: 'Loading…',\n\tloadMore: 'Load more',\n\tsave: 'Save',\n\tsaving: 'Saving…',\n\tcancel: 'Cancel',\n\tdelete: 'Delete',\n\tdeleting: 'Deleting…',\n\tback: 'Back',\n\topen: 'Open',\n\tcopy: 'Copy',\n\tcopied: 'Copied',\n\tdismiss: 'Dismiss',\n\tconfirm: 'Confirm',\n\tcontinue: 'Continue',\n\treload: 'Reload',\n\tsearch: 'Search',\n\tlookUp: 'Look up',\n\tfilter: 'Filter',\n\tyes: 'yes',\n\tno: 'no',\n\tnone: 'None.',\n\tnever: 'never',\n\tyou: 'you',\n\tall: 'All',\n\tallEnvironments: 'All environments',\n\tlanguage: 'Language',\n\ttheme: 'Theme',\n\tthemeSystem: 'System',\n\tthemeLight: 'Light',\n\tthemeDark: 'Dark',\n\tstatus: {\n\t\tactive: 'active',\n\t\tinactive: 'inactive',\n\t\tready: 'ready',\n\t\terror: 'error',\n\t\tadvice: 'advice',\n\t\tok: 'ok',\n\t\tfailed: 'failed',\n\t\tskipped: 'skipped',\n\t\tsuspended: 'suspended',\n\t\tdeleted: 'deleted',\n\t\tdisabled: 'disabled',\n\t\tlocked: 'locked',\n\t\tpending: 'pending',\n\t\tset: 'set',\n\t\tmissing: 'missing',\n\t\tfree: 'free',\n\t},\n};\nexport default common;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst nav = {\n\tgroups: {\n\t\ttoday: 'Today',\n\t\tsystem: 'System',\n\t\tpeople: 'People',\n\t\tmoney: 'Money',\n\t\tsettings: 'Settings',\n\t\tmessaging: 'Messaging',\n\t\tactivity: 'Activity',\n\t},\n\titems: {\n\t\tattention: 'Attention',\n\t\tmodules: 'Modules',\n\t\tenvironment: 'Environment',\n\t\tdoctor: 'Doctor',\n\t\troutes: 'Routes',\n\t\tusers: 'Users',\n\t\tcatalog: 'Catalog',\n\t\tsubscriptions: 'Subscriptions',\n\t\tsettings: 'Config & secrets',\n\t\ttemplates: 'Templates',\n\t\taudit: 'Audit',\n\t\tlog: 'Admin log',\n\t\toperators: 'Operators',\n\t\ttokens: 'Tokens',\n\t\tmigrations: 'Migrations',\n\t},\n};\nexport default nav;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst shell = {\n\topenMenu: 'Open menu',\n\tcloseMenu: 'Close menu',\n\tnavLabel: 'Admin',\n\tmissingClient: 'Pass a {client} to use this page.',\n};\nexport default shell;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst session = {\n\tsignInTitle: 'Sign in to Admin',\n\tadminToken: 'Admin token',\n\tpasteToken: 'Paste your token',\n\ttokenFoot:\n\t\t'Kept for this tab only and sent as a Bearer header — never stored on the server. A read-scoped token is enough to look around and cannot reveal secrets.',\n\ttokenRefused: 'That token was refused.',\n\tunreachable: 'Could not reach the admin surface: {error}',\n\tforgetToken: 'Forget token',\n\tsignOut: 'Sign out',\n\tgenericError: 'Something went wrong. Try again.',\n\tstepOf: 'Step {n} of {total}',\n\tsteps: {\n\t\tadminToken: 'Admin token',\n\t\taccount: 'Your account',\n\t\tauthenticator: 'Authenticator',\n\t\tbackupCodes: 'Backup codes',\n\t\tnewPassword: 'New password',\n\t},\n\tchecking: 'Checking…',\n\twelcomeTitle: \"Welcome — let's set up your console\",\n\twelcomeSubtitle:\n\t\t\"This is the first sign-in on {host}. Paste the admin token from your deployment's configuration to begin. It is needed only this once.\",\n\tcreateAccountTitle: 'Create your account',\n\tcreateAccountSubtitle:\n\t\t'From now on you sign in with this email and password, plus an authenticator app. The admin token stays for scripts and emergencies.',\n\temail: 'Email',\n\tnameOptional: 'Name (optional)',\n\tyourNameOptional: 'Your name (optional)',\n\tpassword: 'Password',\n\tnewPassword: 'New password',\n\tconfirmPassword: 'Confirm password',\n\tpasswordHint: 'At least 12 characters.',\n\tpasswordHintNext: 'At least 12 characters. You will set up an authenticator app next.',\n\tpasswordsMismatch: 'The two passwords do not match.',\n\tcreating: 'Creating…',\n\tcreateAccount: 'Create account',\n\tloginFoot:\n\t\t'There is no sign-up. Operators are invited by another operator. Locked out? Ask another operator for a recovery link.',\n\tbackupCode: 'Backup code',\n\tauthenticatorCode: 'Authenticator code',\n\tuseApp: 'Use the authenticator app instead',\n\tuseBackup: 'Use a backup code instead',\n\tenrollTitle: 'Set up your authenticator',\n\tenrollSubtitle:\n\t\t'Every sign-in to this console needs a code from an authenticator app — 1Password, Google Authenticator, Authy, or any TOTP app.',\n\tenrollScan: 'Open your authenticator app and scan this code.',\n\tenrollEnter: 'Enter the six digits it shows.',\n\tqrAlt: 'QR code for your authenticator app',\n\tcantScan: \"Can't scan? Enter a setup key instead\",\n\tpreparing: 'Preparing…',\n\tcancelSignOut: 'Cancel and sign out',\n\tcodeFromApp: 'Code from the app',\n\tverifyContinue: 'Verify and continue',\n\tbackupTitle: 'Save your backup codes',\n\tbackupSubtitle:\n\t\t'If you lose your phone, each of these signs you in once. They are shown only now.',\n\tbackupFileHeader: 'Backup codes for {host} admin',\n\tdownload: 'Download',\n\tsavedCheckbox: 'I have saved these codes somewhere safe',\n\topenConsole: 'Open the console',\n\tlinkInvalidTitle: 'This link cannot be used',\n\tcheckingLink: 'Checking your link…',\n\tjoinTitle: 'Join the admin console',\n\trecoverTitle: 'Recover your account',\n\tjoinSubtitle: 'You were invited as {email}. Choose a password, then set up an authenticator app.',\n\trecoverSubtitle: 'Set a new password for {email}. You will set up your authenticator again.',\n\tstepUpTitle: \"Confirm it's you\",\n\tstepUpSubtitle: 'This action needs a fresh code. It covers the next five minutes.',\n\ttwoStepTitle: 'Two-step verification',\n\ttwoStepSubtitle: 'Enter the code from your authenticator app.',\n\tverify: 'Verify',\n\tchangeLanguage: 'Change language (current: {name})',\n\tthemeChoice: 'Theme: {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'That email and password do not match an operator.',\n\t\tINVALID_CODE: 'That code did not work. Codes change every 30 seconds.',\n\t\tLOCKED: 'Too many attempts. Try again in {minutes} minute(s).',\n\t\tLOCKED_GENERIC: 'Too many attempts. Try again in a few minutes.',\n\t\tRATE_LIMITED: 'Too many attempts from this address. Wait a few minutes.',\n\t\tWEAK_PASSWORD: 'Choose a stronger password — at least 12 characters, not easy to guess.',\n\t\tINVALID_LINK: 'This link has expired or was already used. Ask for a new one.',\n\t\tALREADY_OPERATOR: 'That email is already an operator. Sign in instead.',\n\t\tALREADY_CLAIMED: 'This console already has operators. Ask one for an invite.',\n\t\tCROSS_ORIGIN: 'This request did not come from the admin page.',\n\t},\n};\nexport default session;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst attention = {\n\ttitle: 'Attention',\n\tlead: 'What needs you on this deployment',\n\tleadChecked: 'What needs you on this deployment · checked {time}',\n\tneedsAction: 'Needs action',\n\tneedsActionHint: 'errors to fix',\n\tadvice: 'Advice',\n\tadviceHint: 'worth a look',\n\tmodulesReady: 'Modules ready',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Routes',\n\trunning: 'Running the checks…',\n\temptyTitle: 'Nothing needs you',\n\temptyBody: 'Every check passes. Checked {time}.',\n};\nexport default attention;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst modules = {\n\ttitle: 'Modules',\n\tlead: 'Every installed module, its version and whether it is ready.',\n\tleadSummary: '{env} · admin {version} · admin log {log} · {routes} routes',\n\tlogOn: 'on',\n\tlogOff: 'off',\n\tcolModule: 'Module',\n\tcolVersion: 'Version',\n\tcolReadiness: 'Readiness',\n\tcolAdmin: 'Admin',\n\tnotReported: 'not reported',\n\tdescribesAdmin: 'describes admin',\n};\nexport default modules;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst environment = {\n\ttitle: 'Environment',\n\tlead: 'Whether each module is configured and each variable the app reads is set. Values are never shown.',\n\tmissingCount: '{n} missing',\n\tallSet: 'all set',\n\tvariables: 'Variables',\n\tnoVariables: 'No variables declared — pass `env` to AdminModule.',\n\tmoduleReadiness: 'Module readiness',\n\tproblemOne: '1 problem',\n\tproblemMany: '{n} problems',\n};\nexport default environment;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst doctor = {\n\ttitle: 'Doctor',\n\tlead: 'Every reconciliation check across the installed modules, run on demand.',\n\tallPass: 'all checks pass',\n\toneFailed: 'a check failed',\n\trunAgain: 'Run again',\n\trunning: 'Running the checks…',\n\tcolResult: 'Result',\n\tcolCheck: 'Check',\n\tcolTime: 'Time',\n};\nexport default doctor;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst routes = {\n\ttitle: 'Routes',\n\tlead: 'Every exposed route, with its guard.',\n\tleadCount: '{n} routes exposed by this deployment, with the guard in front of each.',\n\tfilterPlaceholder: 'Filter by path, method, module…',\n\tfilterLabel: 'Filter routes',\n\tcolMethod: 'Method',\n\tcolPath: 'Path',\n\tcolGuard: 'Guard',\n\tcolModule: 'Module',\n\tapplication: 'application',\n\tnoMatch: 'No route matches “{q}”.',\n};\nexport default routes;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst log = {\n\ttitle: 'Admin log',\n\tlead: 'Every request made through this surface, newest first — refused ones included.',\n\toff: 'The admin log is off — give AdminModule a store.',\n\tempty: 'No requests yet',\n\tcolWhen: 'When',\n\tcolActor: 'Actor',\n\tcolRequest: 'Request',\n\tcolStatus: 'Status',\n\tcolModule: 'Module',\n};\nexport default log;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst migrations = {\n\ttitle: 'Migrations',\n\tlead: 'Schema changes each module ships, and whether this database has them.',\n\tneedsWrite: 'Applying migrations needs a token with the write scope.',\n\tfirstInstall:\n\t\t'This database has never been migrated — treating it as a first install, so nothing is held back.',\n\tupToDate: 'Every module is up to date',\n\tnoPending: 'No pending migrations.',\n\tpendingCount: '{n} pending',\n\tdestructive: 'destructive',\n\tadditive: 'additive',\n\tblockedBy: 'Apply \"{module}\" first — it runs before this one and is behind.',\n\tdestructiveBlocked:\n\t\t'Contains a migration that deletes data. No down-migration brings it back — apply this one through CI or `npm run migrate`.',\n\tconfirmApply: 'Apply {n} migration(s) to \"{module}\"? This changes the database schema.',\n\tapplyOne: 'Apply 1 migration',\n\tapplyMany: 'Apply {n} migrations',\n};\nexport default migrations;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst tokens = {\n\ttitle: 'Tokens',\n\tlead: \"Credentials for machines: the root token's strength, scoped tokens for the CLI and CI, and any legacy per-module tokens. People sign in as operators.\",\n\tneedsRoot: 'Issuing and revoking need the root token (the one in your deployment config).',\n\trootToken: 'Root token',\n\tstrong: 'strong',\n\tweak: 'weak',\n\tissuedTokens: 'Issued tokens',\n\tissuingOff: 'Issuing is off — give AdminModule a store and run its migrations.',\n\tcopyNow: 'Copy this now — it is never shown again.',\n\tnamePlaceholder: 'name',\n\tnameLabel: 'Name',\n\tscope: {\n\t\tread: 'read',\n\t\twrite: 'write',\n\t\tsecrets: 'secrets',\n\t},\n\tdaysPlaceholder: 'days (optional)',\n\tdaysLabel: 'Days',\n\tissue: 'Issue token',\n\tcol: {\n\t\tname: 'Name',\n\t\tscopes: 'Scopes',\n\t\tcreated: 'Created',\n\t\texpires: 'Expires',\n\t\tlastUsed: 'Last used',\n\t},\n\trevoked: 'revoked',\n\trevoke: 'Revoke',\n\trevokeConfirm: 'Revoke \"{name}\"? Anything using it stops working immediately.',\n\temptyTitle: 'No scoped tokens yet',\n\temptyBody: 'Issue a read-only token for a dashboard or a teammate instead of sharing the root.',\n\tlegacyTitle: 'Legacy per-brick tokens',\n\tlegacyNone: \"None — every brick's admin surface goes through this token.\",\n\tlegacyRow: 'still registers its standalone routes with its own token (deprecated)',\n};\nexport default tokens;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst operators = {\n\ttitle: 'Operators',\n\tlead: 'The people who can sign in to this console. Each one uses a password and an authenticator app; there is no sign-up.',\n\tlevel: {\n\t\tread: 'Read only',\n\t\teditor: 'Editor',\n\t\towner: 'Owner',\n\t},\n\tlevelHint: {\n\t\tread: 'look around, change nothing',\n\t\teditor: 'change config, templates, users',\n\t\towner: 'secrets, tokens and operators too',\n\t},\n\tneedsOwner: 'Managing operators needs the Owner level.',\n\tmintedTitle: 'Send this link to {email}. It is shown once.',\n\tmintedBody: 'It works once and expires {date}.',\n\tinvite: 'Invite',\n\tinvitePlaceholder: 'teammate@company.com',\n\tinviteLabel: 'Email to invite',\n\taccessLevelLabel: 'Access level',\n\taccessLevelFor: 'Access level for {email}',\n\tcreateInvite: 'Create invite link',\n\temptyTitle: 'No operators yet',\n\tcol: {\n\t\toperator: 'Operator',\n\t\taccess: 'Access',\n\t\tstatus: 'Status',\n\t\tlastSignIn: 'Last sign-in',\n\t},\n\tsettingUp: 'setting up',\n\tbackupCodesLeftOne: '{n} backup code left',\n\tbackupCodesLeftMany: '{n} backup codes left',\n\trecoveryLink: 'Recovery link',\n\trecoveryConfirm:\n\t\t'Create a recovery link for {email}? It signs them out everywhere; the link sets a new password and a new authenticator.',\n\tdisable: 'Disable',\n\tenable: 'Enable',\n\tdisableConfirm: 'Disable {email}? They are signed out immediately.',\n\tpendingLinks: 'Pending links',\n\tlinkKind: {\n\t\tinvite: 'invite',\n\t\trecovery: 'recovery',\n\t},\n\texpiresOn: 'expires {date}',\n\trevoke: 'Revoke',\n};\nexport default operators;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst users = {\n\ttitle: 'Users',\n\tlead: 'Everyone signed up. Open an account for its sessions, sign-ins and the suspend and sign-out controls.',\n\temailPlaceholder: 'email address',\n\temailLabel: 'Email',\n\tallUsers: 'All users',\n\twhichAccounts: 'Which accounts',\n\tactiveAccounts: 'Active',\n\tdeletedAccounts: 'Deleted',\n\tnoUserWithEmail: 'No user with that email.',\n\tmissingIdPrefix: 'No account with id',\n\tmissingIdBody: 'It was deleted, or never existed here. Its billing records remain.',\n\tplanCredits: 'Plan & credits',\n\temptyTitle: 'No users yet',\n\temptyBody: 'Sign-ups appear here as they happen.',\n\tcol: {\n\t\temail: 'Email',\n\t\tname: 'Name',\n\t\tplan: 'Plan',\n\t\tcreated: 'Created',\n\t\tstatus: 'Status',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'email',\n\t\tverified: 'verified',\n\t\tmfa: 'MFA',\n\t\tprovider: 'provider',\n\t\tlastLogin: 'last login',\n\t\tcreated: 'created',\n\t},\n\tpasswordProvider: 'password',\n\tnoPasswordSet: 'no password set',\n\tdeletedOn: 'Deleted on {date}.',\n\tdeletedBody:\n\t\t'The account cannot sign in, and it is erased when the retention purge runs. Its billing records stay.',\n\tsuspend: 'Suspend',\n\tunsuspend: 'Unsuspend',\n\tsignOutEverywhere: 'Sign out everywhere',\n\tliveSessions: 'Live sessions',\n\tsince: 'since {date}',\n\trecentSignIns: 'Recent sign-ins',\n\tnoneRecorded: 'None recorded.',\n\toutcome: {\n\t\tsuccess: 'success',\n\t\tfailure: 'failure',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hosting',\n};\nexport default users;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst billing = {\n\tstatusLabel: {\n\t\tactive: 'active',\n\t\ttrialing: 'trialing',\n\t\tpast_due: 'past due',\n\t\tunpaid: 'unpaid',\n\t\tcanceled: 'canceled',\n\t\tincomplete: 'incomplete',\n\t\tincomplete_expired: 'incomplete (expired)',\n\t\tpaused: 'paused',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'month',\n\t\tyear: 'year',\n\t},\n\trenews: 'Renews',\n\tends: 'Ends',\n\tended: 'Ended',\n\tloading: 'Loading billing…',\n\tplan: 'Plan',\n\tfree: 'Free',\n\tnoSubscription: 'no subscription',\n\tcredits: 'Credits',\n\tcurrencyPlaceholder: 'currency',\n\tcurrencyLabel: 'Wallet currency',\n\tcurrencyTitle: 'Show the wallet in another currency',\n\tbreakdown: '{permanent} permanent · {allowance} plan allowance',\n\texpires: ' (expires {date})',\n\tnoWallet: 'No wallet — billing has no wallet configuration.',\n\tgrantCredits: 'Grant credits',\n\tamountPlaceholder: 'amount ({currency})',\n\tamountLabel: 'Amount',\n\treasonPlaceholder: 'reason (optional)',\n\treasonLabel: 'Reason',\n\tgrant: 'Grant',\n\tgranted: 'Granted {amount} {currency}.',\n\tnoMovements: 'No credit movements yet',\n\tcol: {\n\t\twhen: 'When',\n\t\tkind: 'Kind',\n\t\tamount: 'Amount',\n\t\tnote: 'Note',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'purchase',\n\t\tgrant: 'grant',\n\t\tusage: 'usage',\n\t\trefund: 'refund',\n\t\tadjustment: 'adjustment',\n\t\texpiry: 'expiry',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Subscriptions',\n\t\tlead: \"Who pays, and who is behind. A user's plan and credits are also on their page under Users — free users appear only there.\",\n\t\tdetailLead: 'Plan, credits and what moved.',\n\t\tback: 'All subscriptions',\n\t\tfilterLabel: 'Filter by status',\n\t\tfilter: {\n\t\t\tall: 'All',\n\t\t\tactive: 'Active',\n\t\t\ttrialing: 'Trialing',\n\t\t\tpastDue: 'Past due',\n\t\t\tcanceled: 'Canceled',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'No subscriptions yet',\n\t\t\tactive: 'No active subscriptions',\n\t\t\ttrialing: 'No trialing subscriptions',\n\t\t\tpastDue: 'No past-due subscriptions',\n\t\t\tcanceled: 'No canceled subscriptions',\n\t\t},\n\t\temptyHint: 'Subscriptions appear here once someone checks out.',\n\t\ttypeLabel: 'Type',\n\t\ttypeWorkspace: 'workspace',\n\t\ttypeUser: 'user',\n\t\tidPlaceholder: 'subscriber id',\n\t\tidLabel: 'Subscriber id',\n\t\tcol: {\n\t\t\tsubscriber: 'Subscriber',\n\t\t\tplan: 'Plan',\n\t\t\tstatus: 'Status',\n\t\t\trenewsEnds: 'Renews / ends',\n\t\t},\n\t\tcancels: 'cancels',\n\t},\n};\nexport default billing;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst catalog = {\n\ttitle: 'Catalog',\n\tlead: 'What you sell: plans as configured in code, and as stored in the database, side by side.',\n\tconfigured: 'Configured (code)',\n\tstored: 'Stored (database)',\n\temptyTitle: 'No stored plans',\n\temptyBody: 'Plans are configured in code; nothing has been written to the database.',\n\tcol: {\n\t\tplan: 'Plan',\n\t\ttier: 'Tier',\n\t\tseats: 'Seats',\n\t\tmonthly: 'Monthly',\n\t\tyearly: 'Yearly',\n\t\ttrial: 'Trial',\n\t},\n\ttrialDays: '{n} d',\n\tdeleteConfirm: 'Delete stored plan \"{name}\"?',\n};\nexport default catalog;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst audit = {\n\ttitle: 'Audit',\n\tlead: \"What happened, across every workspace unless you name one. The chain's integrity verdict is on the Doctor page.\",\n\tworkspacePlaceholder: 'workspace id (all if empty)',\n\ttypePlaceholder: 'event type',\n\tactorPlaceholder: 'actor id',\n\tfromLabel: 'From date',\n\tfromTitle: 'From (inclusive)',\n\ttoLabel: 'To date',\n\ttoTitle: 'To (inclusive)',\n\tempty: 'Nothing recorded for this filter',\n\tcol: {\n\t\twhen: 'When',\n\t\ttype: 'Type',\n\t\tworkspace: 'Workspace',\n\t\tactor: 'Actor',\n\t\trequest: 'Request',\n\t},\n};\nexport default audit;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst config = {\n\tenvironment: 'Environment',\n\treveal: 'Reveal',\n\ttype: {\n\t\ttext: 'text',\n\t\tnumber: 'number',\n\t\tonOff: 'on/off',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Text',\n\t\tnumber: 'Number',\n\t\tonOff: 'On/off',\n\t\tlist: 'List',\n\t\tobject: 'Object',\n\t\tempty: 'Empty',\n\t},\n\tlist: {\n\t\ttitle: 'Config',\n\t\tnewEntry: 'New entry',\n\t\thint: 'Feature flags and runtime settings — text, numbers, on/off or JSON. Read by the app without a deploy.',\n\t\tempty: 'No config entries yet.',\n\t\temptyCta: 'Create one to toggle a feature or tune a setting without redeploying.',\n\t\temptyInEnv: 'No config in {env}. Entries in \"all\" still apply there.',\n\t\tpublicBadge: 'public',\n\t\tpublicTitle: 'Served to frontends by GET /config/public',\n\t\tpublicSummary: 'What frontends receive ({n} public keys)',\n\t\tpublicSummaryOne: 'What frontends receive (1 public key)',\n\t\tpublicHint:\n\t\t\t'Exactly the body of {route} — unauthenticated, so anyone can read it. Only keys the app lists as public appear.',\n\t\tsecretsTitle: 'Secrets',\n\t\tnewSecret: 'New secret',\n\t\tsecretsHint: 'Encrypted at rest; values are hidden until revealed.',\n\t\tsecretsEmpty: 'No secrets yet.',\n\t\tsecretsEmptyInEnv: 'No secrets in {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'New config entry',\n\t\tnewSecret: 'New secret',\n\t\tenvironmentLabel: 'Environment:',\n\t\tkey: 'Key',\n\t\tenvironmentHint:\n\t\t\t'\"all\" is shared by every environment; a named one (production, staging…) overrides it there.',\n\t\tvalue: 'Value',\n\t\tnewValue: 'New value',\n\t\tvaluePlaceholder: 'true · 42 · Scheduled maintenance tonight · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Detected:',\n\t\tsaveAsText: 'Save as text instead',\n\t\ton: 'On (true)',\n\t\toff: 'Off (false)',\n\t\ttype: 'Type:',\n\t\tchangeType: 'Change type…',\n\t\tchangeTypeWarning:\n\t\t\t'Changing the type changes what every screen reading this key receives. Check the code that reads it first.',\n\t\tdescription: 'Description',\n\t\tconflict:\n\t\t\t'Someone changed this entry since you opened it. Reload to see their change, then edit again.',\n\t\tconfirmDelete: 'Delete \"{key}\"? Anything that reads it falls back to its default.',\n\t\tconfirmDeleteIn: 'Delete \"{key}\" from {env}? Anything that reads it falls back to its default.',\n\t\thistory: 'History',\n\t\tunknownActor: 'unknown',\n\t\trollBack: 'Roll back',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Enter a key.',\n\t\tkeyPattern: 'Start with a letter; use letters, digits, \".\", \"_\" or \"-\" (max 128).',\n\t\texists: '\"{key}\" already exists in {env} — open it from the list to edit.',\n\t\tnumber: 'Enter a number.',\n\t\tboolean: 'Use true or false.',\n\t\tjson: 'Not valid JSON: {detail}',\n\t},\n};\nexport default config;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst templates = {\n\tdefaultLocale: 'default locale',\n\tdefaultChip: 'default',\n\tbuiltInBadge: 'built-in',\n\tsubject: 'Subject',\n\thtmlBody: 'HTML body',\n\ttextBody: 'Plain-text body',\n\tlist: {\n\t\ttitle: 'Templates',\n\t\tnewTemplate: 'New template',\n\t\thint: 'Every email the app sends. Open one to edit its copy and preview it live.',\n\t\tloading: 'Loading templates…',\n\t\topenLocale: 'Open the {locale} version of {type}',\n\t},\n\teditor: {\n\t\tloading: 'Loading template…',\n\t\tlocales: 'Locales',\n\t\tdiscardChanges: 'You have unsaved changes to this locale. Discard them and switch?',\n\t\taddLocale: '+ Add locale',\n\t\tbuiltInNote: 'built-in email: edit or roll back, it cannot be deleted',\n\t\tactive: 'Active',\n\t\tconflict:\n\t\t\t'Someone changed this template since you opened it. Reload to see their change, then edit again.',\n\t\tnoChanges: 'No changes to save',\n\t\tsampleData: 'Sample data',\n\t\tsampleNotObject: 'Sample data must be a JSON object.',\n\t\tsampleInvalid: 'Sample data is not valid JSON.',\n\t\tpreview: 'Preview',\n\t\tpreviewTitle: 'Template preview',\n\t\trendering: 'Rendering…',\n\t\tlive: 'Live',\n\t\tnothingRendered: 'Nothing rendered yet.',\n\t\thistory: 'History',\n\t\tunknownActor: 'unknown',\n\t\trollBack: 'Roll back',\n\t\tconfirmDelete: 'Delete \"{type}\"?',\n\t\tconfirmDeleteLocale:\n\t\t\t'Delete the {locale} version of \"{type}\"? People in that locale will receive the default version.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'New template',\n\t\ttitleLocale: 'Add a locale to {type}',\n\t\thintNew:\n\t\t\t'For an email your app sends that has no stored copy yet. The type must match what the app sends.',\n\t\thintLocale:\n\t\t\t'Starts from the default copy. People whose locale matches receive this version; everyone else keeps the default.',\n\t\ttype: 'Type',\n\t\tlocale: 'Locale',\n\t\tlocaleOptional: 'Locale (optional — empty is the default)',\n\t\tcreating: 'Creating…',\n\t\tsubmitNew: 'Create template',\n\t\tsubmitLocale: 'Add locale',\n\t\terrorType: 'Type: lowercase letters, digits, - and _ (e.g. weekly-digest).',\n\t\terrorLocaleRequired: 'Choose the locale to add, e.g. fr or fr-CA.',\n\t\terrorLocale: 'Locale: a language tag such as fr, es or fr-CA.',\n\t\terrorText: 'The plain-text body is required — it is what every email client can show.',\n\t\texists: '\"{type}\" already exists — open it from the list to edit.',\n\t\texistsLocale: '\"{type}\" ({locale}) already exists — open it from the list to edit.',\n\t\tuntranslated: 'Still the default copy: {fields}. Translate them before adding this locale.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst en = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default en;\n","import type en from '../en/common';\n\nconst common: typeof en = {\n\trefresh: 'Actualizar',\n\tworking: 'Procesando…',\n\tloading: 'Cargando…',\n\tloadMore: 'Cargar más',\n\tsave: 'Guardar',\n\tsaving: 'Guardando…',\n\tcancel: 'Cancelar',\n\tdelete: 'Eliminar',\n\tdeleting: 'Eliminando…',\n\tback: 'Volver',\n\topen: 'Abrir',\n\tcopy: 'Copiar',\n\tcopied: 'Copiado',\n\tdismiss: 'Cerrar',\n\tconfirm: 'Confirmar',\n\tcontinue: 'Continuar',\n\treload: 'Recargar',\n\tsearch: 'Buscar',\n\tlookUp: 'Buscar',\n\tfilter: 'Filtrar',\n\tyes: 'sí',\n\tno: 'no',\n\tnone: 'Ninguno.',\n\tnever: 'nunca',\n\tyou: 'tú',\n\tall: 'Todos',\n\tallEnvironments: 'Todos los entornos',\n\tlanguage: 'Idioma',\n\ttheme: 'Tema',\n\tthemeSystem: 'Sistema',\n\tthemeLight: 'Claro',\n\tthemeDark: 'Oscuro',\n\tstatus: {\n\t\tactive: 'activo',\n\t\tinactive: 'inactivo',\n\t\tready: 'listo',\n\t\terror: 'error',\n\t\tadvice: 'consejo',\n\t\tok: 'ok',\n\t\tfailed: 'fallido',\n\t\tskipped: 'omitido',\n\t\tsuspended: 'suspendido',\n\t\tdeleted: 'eliminado',\n\t\tdisabled: 'desactivado',\n\t\tlocked: 'bloqueado',\n\t\tpending: 'pendiente',\n\t\tset: 'definida',\n\t\tmissing: 'falta',\n\t\tfree: 'gratis',\n\t},\n};\nexport default common;\n","import type en from '../en/nav';\n\nconst nav: typeof en = {\n\tgroups: {\n\t\ttoday: 'Hoy',\n\t\tsystem: 'Sistema',\n\t\tpeople: 'Personas',\n\t\tmoney: 'Finanzas',\n\t\tsettings: 'Ajustes',\n\t\tmessaging: 'Mensajería',\n\t\tactivity: 'Actividad',\n\t},\n\titems: {\n\t\tattention: 'Atención',\n\t\tmodules: 'Módulos',\n\t\tenvironment: 'Entorno',\n\t\tdoctor: 'Diagnóstico',\n\t\troutes: 'Rutas',\n\t\tusers: 'Usuarios',\n\t\tcatalog: 'Catálogo',\n\t\tsubscriptions: 'Suscripciones',\n\t\tsettings: 'Configuración y secretos',\n\t\ttemplates: 'Plantillas',\n\t\taudit: 'Auditoría',\n\t\tlog: 'Registro de administración',\n\t\toperators: 'Operadores',\n\t\ttokens: 'Tokens',\n\t\tmigrations: 'Migraciones',\n\t},\n};\nexport default nav;\n","import type en from '../en/shell';\n\nconst shell: typeof en = {\n\topenMenu: 'Abrir el menú',\n\tcloseMenu: 'Cerrar el menú',\n\tnavLabel: 'Administración',\n\tmissingClient: 'Proporciona un {client} para usar esta página.',\n};\nexport default shell;\n","import type en from '../en/session';\n\nconst session: typeof en = {\n\tsignInTitle: 'Iniciar sesión en la administración',\n\tadminToken: 'Token de administración',\n\tpasteToken: 'Pega tu token',\n\ttokenFoot:\n\t\t'Se guarda solo para esta pestaña y se envía en un encabezado Bearer — nunca se almacena en el servidor. Un token de solo lectura basta para consultar y no puede revelar secretos.',\n\ttokenRefused: 'Ese token fue rechazado.',\n\tunreachable: 'No se pudo acceder a la interfaz de administración: {error}',\n\tforgetToken: 'Olvidar el token',\n\tsignOut: 'Cerrar sesión',\n\tgenericError: 'Algo salió mal. Inténtalo de nuevo.',\n\tstepOf: 'Paso {n} de {total}',\n\tsteps: {\n\t\tadminToken: 'Token de administración',\n\t\taccount: 'Tu cuenta',\n\t\tauthenticator: 'Autenticador',\n\t\tbackupCodes: 'Códigos de respaldo',\n\t\tnewPassword: 'Nueva contraseña',\n\t},\n\tchecking: 'Comprobando…',\n\twelcomeTitle: 'Bienvenido — configuremos tu consola',\n\twelcomeSubtitle:\n\t\t'Este es el primer inicio de sesión en {host}. Pega el token de administración de la configuración de tu despliegue para empezar. Solo se necesita esta vez.',\n\tcreateAccountTitle: 'Crea tu cuenta',\n\tcreateAccountSubtitle:\n\t\t'A partir de ahora inicias sesión con este correo y esta contraseña, además de una aplicación de autenticación. El token de administración queda para scripts y emergencias.',\n\temail: 'Correo electrónico',\n\tnameOptional: 'Nombre (opcional)',\n\tyourNameOptional: 'Tu nombre (opcional)',\n\tpassword: 'Contraseña',\n\tnewPassword: 'Nueva contraseña',\n\tconfirmPassword: 'Confirma la contraseña',\n\tpasswordHint: 'Al menos 12 caracteres.',\n\tpasswordHintNext:\n\t\t'Al menos 12 caracteres. A continuación configurarás una aplicación de autenticación.',\n\tpasswordsMismatch: 'Las dos contraseñas no coinciden.',\n\tcreating: 'Creando…',\n\tcreateAccount: 'Crear cuenta',\n\tloginFoot:\n\t\t'No hay registro: los operadores son invitados por otro operador. ¿Sin acceso? Pide a otro operador un enlace de recuperación.',\n\tbackupCode: 'Código de respaldo',\n\tauthenticatorCode: 'Código de autenticación',\n\tuseApp: 'Usar la aplicación de autenticación',\n\tuseBackup: 'Usar un código de respaldo',\n\tenrollTitle: 'Configura tu autenticador',\n\tenrollSubtitle:\n\t\t'Cada inicio de sesión en esta consola requiere un código de una aplicación de autenticación — 1Password, Google Authenticator, Authy o cualquier aplicación TOTP.',\n\tenrollScan: 'Abre tu aplicación de autenticación y escanea este código.',\n\tenrollEnter: 'Introduce los seis dígitos que muestra.',\n\tqrAlt: 'Código QR para tu aplicación de autenticación',\n\tcantScan: '¿No puedes escanear? Introduce una clave de configuración',\n\tpreparing: 'Preparando…',\n\tcancelSignOut: 'Cancelar y cerrar sesión',\n\tcodeFromApp: 'Código de la aplicación',\n\tverifyContinue: 'Verificar y continuar',\n\tbackupTitle: 'Guarda tus códigos de respaldo',\n\tbackupSubtitle:\n\t\t'Si pierdes tu teléfono, cada uno de estos códigos te permite iniciar sesión una vez. Solo se muestran ahora.',\n\tbackupFileHeader: 'Códigos de respaldo para la administración de {host}',\n\tdownload: 'Descargar',\n\tsavedCheckbox: 'He guardado estos códigos en un lugar seguro',\n\topenConsole: 'Abrir la consola',\n\tlinkInvalidTitle: 'Este enlace no se puede usar',\n\tcheckingLink: 'Comprobando tu enlace…',\n\tjoinTitle: 'Únete a la consola de administración',\n\trecoverTitle: 'Recupera tu cuenta',\n\tjoinSubtitle:\n\t\t'Te invitaron como {email}. Elige una contraseña y luego configura una aplicación de autenticación.',\n\trecoverSubtitle:\n\t\t'Define una nueva contraseña para {email}. Volverás a configurar tu autenticador.',\n\tstepUpTitle: 'Confirma que eres tú',\n\tstepUpSubtitle:\n\t\t'Esta acción requiere un código nuevo. Es válido durante los próximos cinco minutos.',\n\ttwoStepTitle: 'Verificación en dos pasos',\n\ttwoStepSubtitle: 'Introduce el código de tu aplicación de autenticación.',\n\tverify: 'Verificar',\n\tchangeLanguage: 'Cambiar idioma (actual: {name})',\n\tthemeChoice: 'Tema: {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'Ese correo y esa contraseña no corresponden a ningún operador.',\n\t\tINVALID_CODE: 'Ese código no funcionó. Los códigos cambian cada 30 segundos.',\n\t\tLOCKED: 'Demasiados intentos. Inténtalo de nuevo en {minutes} minuto(s).',\n\t\tLOCKED_GENERIC: 'Demasiados intentos. Inténtalo de nuevo en unos minutos.',\n\t\tRATE_LIMITED: 'Demasiados intentos desde esta dirección. Espera unos minutos.',\n\t\tWEAK_PASSWORD:\n\t\t\t'Elige una contraseña más segura — al menos 12 caracteres y difícil de adivinar.',\n\t\tINVALID_LINK: 'Este enlace caducó o ya se usó. Pide uno nuevo.',\n\t\tALREADY_OPERATOR: 'Ese correo ya pertenece a un operador. Inicia sesión.',\n\t\tALREADY_CLAIMED: 'Esta consola ya tiene operadores. Pide una invitación a uno de ellos.',\n\t\tCROSS_ORIGIN: 'Esta solicitud no proviene de la página de administración.',\n\t},\n};\nexport default session;\n","import type en from '../en/attention';\n\nconst attention: typeof en = {\n\ttitle: 'Atención',\n\tlead: 'Lo que necesita tu atención en este despliegue',\n\tleadChecked: 'Lo que necesita tu atención en este despliegue · comprobado a las {time}',\n\tneedsAction: 'Requiere acción',\n\tneedsActionHint: 'errores por corregir',\n\tadvice: 'Consejos',\n\tadviceHint: 'vale la pena revisarlos',\n\tmodulesReady: 'Módulos listos',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Rutas',\n\trunning: 'Ejecutando las comprobaciones…',\n\temptyTitle: 'Nada requiere tu atención',\n\temptyBody: 'Todas las comprobaciones pasan. Comprobado el {time}.',\n};\nexport default attention;\n","import type en from '../en/modules';\n\nconst modules: typeof en = {\n\ttitle: 'Módulos',\n\tlead: 'Cada módulo instalado, su versión y si está listo.',\n\tleadSummary: '{env} · admin {version} · registro de administración {log} · {routes} rutas',\n\tlogOn: 'activado',\n\tlogOff: 'desactivado',\n\tcolModule: 'Módulo',\n\tcolVersion: 'Versión',\n\tcolReadiness: 'Estado',\n\tcolAdmin: 'Admin',\n\tnotReported: 'no informada',\n\tdescribesAdmin: 'describe la administración',\n};\nexport default modules;\n","import type en from '../en/environment';\n\nconst environment: typeof en = {\n\ttitle: 'Entorno',\n\tlead: 'Si cada módulo está configurado y si cada variable que lee la aplicación está definida. Los valores nunca se muestran.',\n\tmissingCount: 'faltan {n}',\n\tallSet: 'todas definidas',\n\tvariables: 'Variables',\n\tnoVariables: 'No hay variables declaradas: pasa `env` a AdminModule.',\n\tmoduleReadiness: 'Estado de los módulos',\n\tproblemOne: '1 problema',\n\tproblemMany: '{n} problemas',\n};\nexport default environment;\n","import type en from '../en/doctor';\n\nconst doctor: typeof en = {\n\ttitle: 'Diagnóstico',\n\tlead: 'Todas las comprobaciones de coherencia de los módulos instalados, ejecutadas a demanda.',\n\tallPass: 'todas las comprobaciones pasan',\n\toneFailed: 'una comprobación falló',\n\trunAgain: 'Volver a ejecutar',\n\trunning: 'Ejecutando las comprobaciones…',\n\tcolResult: 'Resultado',\n\tcolCheck: 'Comprobación',\n\tcolTime: 'Duración',\n};\nexport default doctor;\n","import type en from '../en/routes';\n\nconst routes: typeof en = {\n\ttitle: 'Rutas',\n\tlead: 'Cada ruta expuesta, con su protección.',\n\tleadCount: '{n} rutas expuestas por este despliegue, con la protección que tiene cada una.',\n\tfilterPlaceholder: 'Filtrar por ruta, método, módulo…',\n\tfilterLabel: 'Filtrar rutas',\n\tcolMethod: 'Método',\n\tcolPath: 'Ruta',\n\tcolGuard: 'Protección',\n\tcolModule: 'Módulo',\n\tapplication: 'aplicación',\n\tnoMatch: 'Ninguna ruta coincide con «{q}».',\n};\nexport default routes;\n","import type en from '../en/log';\n\nconst log: typeof en = {\n\ttitle: 'Registro de administración',\n\tlead: 'Cada solicitud realizada a través de esta consola, de la más reciente a la más antigua, incluidas las rechazadas.',\n\toff: 'El registro de administración está desactivado: proporciona un store a AdminModule.',\n\tempty: 'Todavía no hay solicitudes',\n\tcolWhen: 'Fecha',\n\tcolActor: 'Autor',\n\tcolRequest: 'Solicitud',\n\tcolStatus: 'Estado',\n\tcolModule: 'Módulo',\n};\nexport default log;\n","import type en from '../en/migrations';\n\nconst migrations: typeof en = {\n\ttitle: 'Migraciones',\n\tlead: 'Los cambios de esquema que incluye cada módulo, y si esta base de datos ya los tiene.',\n\tneedsWrite: 'Aplicar migraciones requiere un token con permiso de escritura.',\n\tfirstInstall:\n\t\t'Esta base de datos nunca se ha migrado: se trata como una primera instalación, así que no se retiene nada.',\n\tupToDate: 'Todos los módulos están al día',\n\tnoPending: 'No hay migraciones pendientes.',\n\tpendingCount: '{n} pendientes',\n\tdestructive: 'destructiva',\n\tadditive: 'aditiva',\n\tblockedBy: 'Aplica primero «{module}»: se ejecuta antes que este y está atrasado.',\n\tdestructiveBlocked:\n\t\t'Contiene una migración que elimina datos. Ninguna migración inversa los recupera: aplícala mediante la CI o `npm run migrate`.',\n\tconfirmApply:\n\t\t'¿Aplicar {n} migración(es) a «{module}»? Esto modifica el esquema de la base de datos.',\n\tapplyOne: 'Aplicar 1 migración',\n\tapplyMany: 'Aplicar {n} migraciones',\n};\nexport default migrations;\n","import type en from '../en/tokens';\n\nconst tokens: typeof en = {\n\ttitle: 'Tokens',\n\tlead: 'Credenciales para máquinas: la solidez del token raíz, tokens con alcance limitado para la CLI y la CI, y cualquier token heredado por módulo. Las personas inician sesión como operadores.',\n\tneedsRoot: 'Emitir y revocar requieren el token raíz (el de la configuración de tu despliegue).',\n\trootToken: 'Token raíz',\n\tstrong: 'sólido',\n\tweak: 'débil',\n\tissuedTokens: 'Tokens emitidos',\n\tissuingOff:\n\t\t'La emisión está desactivada — proporciona un store a AdminModule y ejecuta sus migraciones.',\n\tcopyNow: 'Cópialo ahora — no se volverá a mostrar.',\n\tnamePlaceholder: 'nombre',\n\tnameLabel: 'Nombre',\n\tscope: {\n\t\tread: 'lectura',\n\t\twrite: 'escritura',\n\t\tsecrets: 'secretos',\n\t},\n\tdaysPlaceholder: 'días (opcional)',\n\tdaysLabel: 'Días',\n\tissue: 'Emitir token',\n\tcol: {\n\t\tname: 'Nombre',\n\t\tscopes: 'Alcances',\n\t\tcreated: 'Creado',\n\t\texpires: 'Vence',\n\t\tlastUsed: 'Último uso',\n\t},\n\trevoked: 'revocado',\n\trevoke: 'Revocar',\n\trevokeConfirm: '¿Revocar «{name}»? Todo lo que lo use dejará de funcionar de inmediato.',\n\temptyTitle: 'Aún no hay tokens con alcance limitado',\n\temptyBody:\n\t\t'Emite un token de solo lectura para un panel o un compañero en lugar de compartir el token raíz.',\n\tlegacyTitle: 'Tokens heredados por módulo',\n\tlegacyNone: 'Ninguno — la superficie de administración de cada módulo pasa por este token.',\n\tlegacyRow: 'todavía registra sus rutas independientes con su propio token (obsoleto)',\n};\nexport default tokens;\n","import type en from '../en/operators';\n\nconst operators: typeof en = {\n\ttitle: 'Operadores',\n\tlead: 'Las personas que pueden iniciar sesión en esta consola. Cada una usa una contraseña y una aplicación de autenticación; no hay registro.',\n\tlevel: {\n\t\tread: 'Solo lectura',\n\t\teditor: 'Editor',\n\t\towner: 'Propietario',\n\t},\n\tlevelHint: {\n\t\tread: 'consultar, sin cambiar nada',\n\t\teditor: 'cambiar configuración, plantillas y usuarios',\n\t\towner: 'también secretos, tokens y operadores',\n\t},\n\tneedsOwner: 'Gestionar operadores requiere el nivel Propietario.',\n\tmintedTitle: 'Envía este enlace a {email}. Solo se muestra una vez.',\n\tmintedBody: 'Funciona una sola vez y vence el {date}.',\n\tinvite: 'Invitar',\n\tinvitePlaceholder: 'companero@empresa.com',\n\tinviteLabel: 'Correo electrónico a invitar',\n\taccessLevelLabel: 'Nivel de acceso',\n\taccessLevelFor: 'Nivel de acceso de {email}',\n\tcreateInvite: 'Crear enlace de invitación',\n\temptyTitle: 'Aún no hay operadores',\n\tcol: {\n\t\toperator: 'Operador',\n\t\taccess: 'Acceso',\n\t\tstatus: 'Estado',\n\t\tlastSignIn: 'Último inicio de sesión',\n\t},\n\tsettingUp: 'en configuración',\n\tbackupCodesLeftOne: 'queda {n} código de respaldo',\n\tbackupCodesLeftMany: 'quedan {n} códigos de respaldo',\n\trecoveryLink: 'Enlace de recuperación',\n\trecoveryConfirm:\n\t\t'¿Crear un enlace de recuperación para {email}? Cierra su sesión en todas partes; el enlace permite definir una nueva contraseña y una nueva aplicación de autenticación.',\n\tdisable: 'Desactivar',\n\tenable: 'Activar',\n\tdisableConfirm: '¿Desactivar a {email}? Su sesión se cierra de inmediato.',\n\tpendingLinks: 'Enlaces pendientes',\n\tlinkKind: {\n\t\tinvite: 'invitación',\n\t\trecovery: 'recuperación',\n\t},\n\texpiresOn: 'vence el {date}',\n\trevoke: 'Revocar',\n};\nexport default operators;\n","import type en from '../en/users';\n\nconst users: typeof en = {\n\ttitle: 'Usuarios',\n\tlead: 'Todos los registrados. Abre una cuenta para ver sus sesiones, sus inicios de sesión y los controles para suspender y cerrar sesión.',\n\temailPlaceholder: 'correo electrónico',\n\temailLabel: 'Correo electrónico',\n\tallUsers: 'Todos los usuarios',\n\twhichAccounts: 'Qué cuentas',\n\tactiveAccounts: 'Activas',\n\tdeletedAccounts: 'Eliminadas',\n\tnoUserWithEmail: 'No hay ningún usuario con ese correo electrónico.',\n\tmissingIdPrefix: 'No hay ninguna cuenta con el id',\n\tmissingIdBody: 'Se eliminó o nunca existió aquí. Sus registros de facturación se conservan.',\n\tplanCredits: 'Plan y créditos',\n\temptyTitle: 'Aún no hay usuarios',\n\temptyBody: 'Los registros aparecen aquí a medida que ocurren.',\n\tcol: {\n\t\temail: 'Correo electrónico',\n\t\tname: 'Nombre',\n\t\tplan: 'Plan',\n\t\tcreated: 'Creado',\n\t\tstatus: 'Estado',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'correo electrónico',\n\t\tverified: 'verificado',\n\t\tmfa: 'MFA',\n\t\tprovider: 'proveedor',\n\t\tlastLogin: 'último inicio de sesión',\n\t\tcreated: 'creado',\n\t},\n\tpasswordProvider: 'contraseña',\n\tnoPasswordSet: 'sin contraseña',\n\tdeletedOn: 'Eliminada el {date}.',\n\tdeletedBody:\n\t\t'La cuenta no puede iniciar sesión y se borrará cuando se ejecute la purga de retención. Sus registros de facturación se conservan.',\n\tsuspend: 'Suspender',\n\tunsuspend: 'Reactivar',\n\tsignOutEverywhere: 'Cerrar sesión en todas partes',\n\tliveSessions: 'Sesiones activas',\n\tsince: 'desde el {date}',\n\trecentSignIns: 'Inicios de sesión recientes',\n\tnoneRecorded: 'Ninguno registrado.',\n\toutcome: {\n\t\tsuccess: 'correcto',\n\t\tfailure: 'fallido',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hosting',\n};\nexport default users;\n","import type en from '../en/billing';\n\nconst billing: typeof en = {\n\tstatusLabel: {\n\t\tactive: 'activa',\n\t\ttrialing: 'en prueba',\n\t\tpast_due: 'pago atrasado',\n\t\tunpaid: 'impagada',\n\t\tcanceled: 'cancelada',\n\t\tincomplete: 'incompleta',\n\t\tincomplete_expired: 'incompleta (vencida)',\n\t\tpaused: 'en pausa',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'mes',\n\t\tyear: 'año',\n\t},\n\trenews: 'Se renueva el',\n\tends: 'Termina el',\n\tended: 'Terminó el',\n\tloading: 'Cargando facturación…',\n\tplan: 'Plan',\n\tfree: 'Gratis',\n\tnoSubscription: 'sin suscripción',\n\tcredits: 'Créditos',\n\tcurrencyPlaceholder: 'moneda',\n\tcurrencyLabel: 'Moneda del monedero',\n\tcurrencyTitle: 'Mostrar el monedero en otra moneda',\n\tbreakdown: '{permanent} permanentes · {allowance} de asignación del plan',\n\texpires: ' (vence el {date})',\n\tnoWallet: 'Sin monedero — la facturación no tiene configuración de monedero.',\n\tgrantCredits: 'Otorgar créditos',\n\tamountPlaceholder: 'cantidad ({currency})',\n\tamountLabel: 'Cantidad',\n\treasonPlaceholder: 'motivo (opcional)',\n\treasonLabel: 'Motivo',\n\tgrant: 'Otorgar',\n\tgranted: 'Se otorgaron {amount} {currency}.',\n\tnoMovements: 'Aún no hay movimientos de créditos',\n\tcol: {\n\t\twhen: 'Fecha',\n\t\tkind: 'Tipo',\n\t\tamount: 'Cantidad',\n\t\tnote: 'Nota',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'compra',\n\t\tgrant: 'otorgamiento',\n\t\tusage: 'uso',\n\t\trefund: 'reembolso',\n\t\tadjustment: 'ajuste',\n\t\texpiry: 'vencimiento',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Suscripciones',\n\t\tlead: 'Quién paga y quién está atrasado. El plan y los créditos de un usuario también están en su página en Usuarios — los usuarios gratuitos solo aparecen allí.',\n\t\tdetailLead: 'Plan, créditos y movimientos.',\n\t\tback: 'Todas las suscripciones',\n\t\tfilterLabel: 'Filtrar por estado',\n\t\tfilter: {\n\t\t\tall: 'Todas',\n\t\t\tactive: 'Activas',\n\t\t\ttrialing: 'En prueba',\n\t\t\tpastDue: 'Atrasadas',\n\t\t\tcanceled: 'Canceladas',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'Aún no hay suscripciones',\n\t\t\tactive: 'No hay suscripciones activas',\n\t\t\ttrialing: 'No hay suscripciones en prueba',\n\t\t\tpastDue: 'No hay suscripciones con pago atrasado',\n\t\t\tcanceled: 'No hay suscripciones canceladas',\n\t\t},\n\t\temptyHint: 'Las suscripciones aparecen aquí cuando alguien completa una compra.',\n\t\ttypeLabel: 'Tipo',\n\t\ttypeWorkspace: 'espacio de trabajo',\n\t\ttypeUser: 'usuario',\n\t\tidPlaceholder: 'id del suscriptor',\n\t\tidLabel: 'Id del suscriptor',\n\t\tcol: {\n\t\t\tsubscriber: 'Suscriptor',\n\t\t\tplan: 'Plan',\n\t\t\tstatus: 'Estado',\n\t\t\trenewsEnds: 'Renovación / fin',\n\t\t},\n\t\tcancels: 'se cancelará',\n\t},\n};\nexport default billing;\n","import type en from '../en/catalog';\n\nconst catalog: typeof en = {\n\ttitle: 'Catálogo',\n\tlead: 'Lo que vendes: los planes tal como están configurados en el código y tal como están guardados en la base de datos, lado a lado.',\n\tconfigured: 'Configurados (código)',\n\tstored: 'Guardados (base de datos)',\n\temptyTitle: 'No hay planes guardados',\n\temptyBody:\n\t\t'Los planes están configurados en el código; no se ha escrito nada en la base de datos.',\n\tcol: {\n\t\tplan: 'Plan',\n\t\ttier: 'Nivel',\n\t\tseats: 'Plazas',\n\t\tmonthly: 'Mensual',\n\t\tyearly: 'Anual',\n\t\ttrial: 'Prueba',\n\t},\n\ttrialDays: '{n} d',\n\tdeleteConfirm: '¿Eliminar el plan guardado «{name}»?',\n};\nexport default catalog;\n","import type en from '../en/audit';\n\nconst audit: typeof en = {\n\ttitle: 'Auditoría',\n\tlead: 'Lo que ha pasado, en todos los espacios de trabajo salvo que indiques uno. El veredicto de integridad de la cadena está en la página Diagnóstico.',\n\tworkspacePlaceholder: 'id del espacio de trabajo (todos si está vacío)',\n\ttypePlaceholder: 'tipo de evento',\n\tactorPlaceholder: 'id del actor',\n\tfromLabel: 'Fecha de inicio',\n\tfromTitle: 'Desde (incluido)',\n\ttoLabel: 'Fecha de fin',\n\ttoTitle: 'Hasta (incluido)',\n\tempty: 'Nada registrado para este filtro',\n\tcol: {\n\t\twhen: 'Fecha',\n\t\ttype: 'Tipo',\n\t\tworkspace: 'Espacio de trabajo',\n\t\tactor: 'Actor',\n\t\trequest: 'Solicitud',\n\t},\n};\nexport default audit;\n","import type en from '../en/config';\n\nconst config: typeof en = {\n\tenvironment: 'Entorno',\n\treveal: 'Mostrar',\n\ttype: {\n\t\ttext: 'texto',\n\t\tnumber: 'número',\n\t\tonOff: 'sí/no',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Texto',\n\t\tnumber: 'Número',\n\t\tonOff: 'Sí/no',\n\t\tlist: 'Lista',\n\t\tobject: 'Objeto',\n\t\tempty: 'Vacío',\n\t},\n\tlist: {\n\t\ttitle: 'Configuración',\n\t\tnewEntry: 'Nueva entrada',\n\t\thint: 'Indicadores de funciones y ajustes de ejecución — texto, números, sí/no o JSON. La aplicación los lee sin desplegar.',\n\t\tempty: 'Todavía no hay entradas de configuración.',\n\t\temptyCta: 'Crea una para activar una función o ajustar un parámetro sin volver a desplegar.',\n\t\temptyInEnv: 'No hay configuración en {env}. Las entradas de \"all\" siguen aplicándose allí.',\n\t\tpublicBadge: 'público',\n\t\tpublicTitle: 'Servido a los frontends por GET /config/public',\n\t\tpublicSummary: 'Lo que reciben los frontends ({n} claves públicas)',\n\t\tpublicSummaryOne: 'Lo que reciben los frontends (1 clave pública)',\n\t\tpublicHint:\n\t\t\t'Exactamente el cuerpo de {route} — sin autenticación, así que cualquiera puede leerlo. Solo aparecen las claves que la aplicación declara públicas.',\n\t\tsecretsTitle: 'Secretos',\n\t\tnewSecret: 'Nuevo secreto',\n\t\tsecretsHint: 'Cifrados en reposo; los valores permanecen ocultos hasta que se muestran.',\n\t\tsecretsEmpty: 'Todavía no hay secretos.',\n\t\tsecretsEmptyInEnv: 'No hay secretos en {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'Nueva entrada de configuración',\n\t\tnewSecret: 'Nuevo secreto',\n\t\tenvironmentLabel: 'Entorno:',\n\t\tkey: 'Clave',\n\t\tenvironmentHint:\n\t\t\t'\"all\" lo comparten todos los entornos; uno con nombre (production, staging…) lo reemplaza allí.',\n\t\tvalue: 'Valor',\n\t\tnewValue: 'Nuevo valor',\n\t\tvaluePlaceholder: 'true · 42 · Mantenimiento programado esta noche · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Detectado:',\n\t\tsaveAsText: 'Guardar como texto',\n\t\ton: 'Sí (true)',\n\t\toff: 'No (false)',\n\t\ttype: 'Tipo:',\n\t\tchangeType: 'Cambiar tipo…',\n\t\tchangeTypeWarning:\n\t\t\t'Cambiar el tipo cambia lo que recibe cada pantalla que lee esta clave. Revisa primero el código que la lee.',\n\t\tdescription: 'Descripción',\n\t\tconflict:\n\t\t\t'Alguien cambió esta entrada desde que la abriste. Recarga para ver su cambio y vuelve a editarla.',\n\t\tconfirmDelete: '¿Eliminar \"{key}\"? Todo lo que la lee vuelve a su valor predeterminado.',\n\t\tconfirmDeleteIn:\n\t\t\t'¿Eliminar \"{key}\" de {env}? Todo lo que la lee vuelve a su valor predeterminado.',\n\t\thistory: 'Historial',\n\t\tunknownActor: 'desconocido',\n\t\trollBack: 'Restaurar',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Introduce una clave.',\n\t\tkeyPattern: 'Empieza por una letra; usa letras, dígitos, \".\", \"_\" o \"-\" (máx. 128).',\n\t\texists: '\"{key}\" ya existe en {env} — ábrela desde la lista para editarla.',\n\t\tnumber: 'Introduce un número.',\n\t\tboolean: 'Usa true o false.',\n\t\tjson: 'JSON no válido: {detail}',\n\t},\n};\nexport default config;\n","import type en from '../en/templates';\n\nconst templates: typeof en = {\n\tdefaultLocale: 'idioma predeterminado',\n\tdefaultChip: 'predeterminado',\n\tbuiltInBadge: 'integrado',\n\tsubject: 'Asunto',\n\thtmlBody: 'Cuerpo HTML',\n\ttextBody: 'Cuerpo en texto plano',\n\tlist: {\n\t\ttitle: 'Plantillas',\n\t\tnewTemplate: 'Nueva plantilla',\n\t\thint: 'Cada correo que envía la aplicación. Abre uno para editar su contenido y ver la vista previa en directo.',\n\t\tloading: 'Cargando plantillas…',\n\t\topenLocale: 'Abrir la versión {locale} de {type}',\n\t},\n\teditor: {\n\t\tloading: 'Cargando plantilla…',\n\t\tlocales: 'Idiomas',\n\t\tdiscardChanges: 'Este idioma tiene cambios sin guardar. ¿Descartarlos y cambiar de idioma?',\n\t\taddLocale: '+ Añadir idioma',\n\t\tbuiltInNote: 'correo integrado: se puede editar o restaurar, no eliminar',\n\t\tactive: 'Activa',\n\t\tconflict:\n\t\t\t'Alguien cambió esta plantilla desde que la abriste. Recarga para ver su cambio y vuelve a editarla.',\n\t\tnoChanges: 'No hay cambios que guardar',\n\t\tsampleData: 'Datos de ejemplo',\n\t\tsampleNotObject: 'Los datos de ejemplo deben ser un objeto JSON.',\n\t\tsampleInvalid: 'Los datos de ejemplo no son un JSON válido.',\n\t\tpreview: 'Vista previa',\n\t\tpreviewTitle: 'Vista previa de la plantilla',\n\t\trendering: 'Generando…',\n\t\tlive: 'En directo',\n\t\tnothingRendered: 'Todavía no se ha generado nada.',\n\t\thistory: 'Historial',\n\t\tunknownActor: 'desconocido',\n\t\trollBack: 'Restaurar',\n\t\tconfirmDelete: '¿Eliminar \"{type}\"?',\n\t\tconfirmDeleteLocale:\n\t\t\t'¿Eliminar la versión {locale} de \"{type}\"? Las personas de ese idioma recibirán la versión predeterminada.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'Nueva plantilla',\n\t\ttitleLocale: 'Añadir un idioma a {type}',\n\t\thintNew:\n\t\t\t'Para un correo que envía tu aplicación y que aún no tiene contenido guardado. El tipo debe coincidir con lo que envía la aplicación.',\n\t\thintLocale:\n\t\t\t'Parte del contenido predeterminado. Las personas cuyo idioma coincide reciben esta versión; los demás conservan la predeterminada.',\n\t\ttype: 'Tipo',\n\t\tlocale: 'Idioma',\n\t\tlocaleOptional: 'Idioma (opcional — vacío es el predeterminado)',\n\t\tcreating: 'Creando…',\n\t\tsubmitNew: 'Crear plantilla',\n\t\tsubmitLocale: 'Añadir idioma',\n\t\terrorType: 'Tipo: letras minúsculas, dígitos, - y _ (p. ej. weekly-digest).',\n\t\terrorLocaleRequired: 'Elige el idioma que quieres añadir, p. ej. fr o fr-CA.',\n\t\terrorLocale: 'Idioma: una etiqueta de idioma como fr, es o fr-CA.',\n\t\terrorText: 'El cuerpo en texto plano es obligatorio — es lo que puede mostrar cualquier cliente de correo.',\n\t\texists: '\"{type}\" ya existe — ábrela desde la lista para editarla.',\n\t\texistsLocale: '\"{type}\" ({locale}) ya existe — ábrela desde la lista para editarla.',\n\t\tuntranslated: 'Todavía en la versión predeterminada: {fields}. Tradúcelos antes de añadir este idioma.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst es = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default es;\n","import type en from '../en/common';\n\nconst common: typeof en = {\n\trefresh: 'Actualiser',\n\tworking: 'En cours…',\n\tloading: 'Chargement…',\n\tloadMore: 'Charger plus',\n\tsave: 'Enregistrer',\n\tsaving: 'Enregistrement…',\n\tcancel: 'Annuler',\n\tdelete: 'Supprimer',\n\tdeleting: 'Suppression…',\n\tback: 'Retour',\n\topen: 'Ouvrir',\n\tcopy: 'Copier',\n\tcopied: 'Copié',\n\tdismiss: 'Fermer',\n\tconfirm: 'Confirmer',\n\tcontinue: 'Continuer',\n\treload: 'Recharger',\n\tsearch: 'Rechercher',\n\tlookUp: 'Rechercher',\n\tfilter: 'Filtrer',\n\tyes: 'oui',\n\tno: 'non',\n\tnone: 'Aucun.',\n\tnever: 'jamais',\n\tyou: 'vous',\n\tall: 'Tous',\n\tallEnvironments: 'Tous les environnements',\n\tlanguage: 'Langue',\n\ttheme: 'Thème',\n\tthemeSystem: 'Système',\n\tthemeLight: 'Clair',\n\tthemeDark: 'Sombre',\n\tstatus: {\n\t\tactive: 'actif',\n\t\tinactive: 'inactif',\n\t\tready: 'prêt',\n\t\terror: 'erreur',\n\t\tadvice: 'conseil',\n\t\tok: 'ok',\n\t\tfailed: 'échec',\n\t\tskipped: 'ignoré',\n\t\tsuspended: 'suspendu',\n\t\tdeleted: 'supprimé',\n\t\tdisabled: 'désactivé',\n\t\tlocked: 'verrouillé',\n\t\tpending: 'en attente',\n\t\tset: 'défini',\n\t\tmissing: 'manquant',\n\t\tfree: 'gratuit',\n\t},\n};\nexport default common;\n","import type en from '../en/nav';\n\nconst nav: typeof en = {\n\tgroups: {\n\t\ttoday: \"Aujourd'hui\",\n\t\tsystem: 'Système',\n\t\tpeople: 'Personnes',\n\t\tmoney: 'Finances',\n\t\tsettings: 'Réglages',\n\t\tmessaging: 'Messagerie',\n\t\tactivity: 'Activité',\n\t},\n\titems: {\n\t\tattention: 'À traiter',\n\t\tmodules: 'Modules',\n\t\tenvironment: 'Environnement',\n\t\tdoctor: 'Diagnostic',\n\t\troutes: 'Routes',\n\t\tusers: 'Utilisateurs',\n\t\tcatalog: 'Catalogue',\n\t\tsubscriptions: 'Abonnements',\n\t\tsettings: 'Configuration et secrets',\n\t\ttemplates: 'Modèles',\n\t\taudit: 'Audit',\n\t\tlog: \"Journal d'administration\",\n\t\toperators: 'Opérateurs',\n\t\ttokens: 'Jetons',\n\t\tmigrations: 'Migrations',\n\t},\n};\nexport default nav;\n","import type en from '../en/shell';\n\nconst shell: typeof en = {\n\topenMenu: 'Ouvrir le menu',\n\tcloseMenu: 'Fermer le menu',\n\tnavLabel: 'Administration',\n\tmissingClient: 'Fournissez un {client} pour utiliser cette page.',\n};\nexport default shell;\n","import type en from '../en/session';\n\nconst session: typeof en = {\n\tsignInTitle: \"Se connecter à l'administration\",\n\tadminToken: \"Jeton d'administration\",\n\tpasteToken: 'Collez votre jeton',\n\ttokenFoot:\n\t\t'Conservé pour cet onglet uniquement et envoyé dans un en-tête Bearer — jamais stocké sur le serveur. Un jeton limité à la lecture suffit pour consulter et ne peut pas révéler les secrets.',\n\ttokenRefused: 'Ce jeton a été refusé.',\n\tunreachable: \"Impossible de joindre l'interface d'administration : {error}\",\n\tforgetToken: 'Oublier le jeton',\n\tsignOut: 'Se déconnecter',\n\tgenericError: \"Une erreur s'est produite. Réessayez.\",\n\tstepOf: 'Étape {n} sur {total}',\n\tsteps: {\n\t\tadminToken: \"Jeton d'administration\",\n\t\taccount: 'Votre compte',\n\t\tauthenticator: 'Authentification',\n\t\tbackupCodes: 'Codes de secours',\n\t\tnewPassword: 'Nouveau mot de passe',\n\t},\n\tchecking: 'Vérification…',\n\twelcomeTitle: 'Bienvenue — configurons votre console',\n\twelcomeSubtitle:\n\t\t\"C'est la première connexion sur {host}. Collez le jeton d'administration de la configuration de votre déploiement pour commencer. Il ne sera demandé qu'une seule fois.\",\n\tcreateAccountTitle: 'Créez votre compte',\n\tcreateAccountSubtitle:\n\t\t\"Désormais, vous vous connectez avec cet e-mail et ce mot de passe, ainsi qu'une application d'authentification. Le jeton d'administration reste réservé aux scripts et aux urgences.\",\n\temail: 'E-mail',\n\tnameOptional: 'Nom (facultatif)',\n\tyourNameOptional: 'Votre nom (facultatif)',\n\tpassword: 'Mot de passe',\n\tnewPassword: 'Nouveau mot de passe',\n\tconfirmPassword: 'Confirmez le mot de passe',\n\tpasswordHint: 'Au moins 12 caractères.',\n\tpasswordHintNext:\n\t\t\"Au moins 12 caractères. Vous configurerez ensuite une application d'authentification.\",\n\tpasswordsMismatch: 'Les deux mots de passe ne correspondent pas.',\n\tcreating: 'Création…',\n\tcreateAccount: 'Créer le compte',\n\tloginFoot:\n\t\t\"Il n'y a pas d'inscription : les opérateurs sont invités par un autre opérateur. Accès bloqué ? Demandez un lien de récupération à un autre opérateur.\",\n\tbackupCode: 'Code de secours',\n\tauthenticatorCode: \"Code d'authentification\",\n\tuseApp: \"Utiliser plutôt l'application d'authentification\",\n\tuseBackup: 'Utiliser plutôt un code de secours',\n\tenrollTitle: \"Configurez votre application d'authentification\",\n\tenrollSubtitle:\n\t\t\"Chaque connexion à cette console demande un code d'une application d'authentification — 1Password, Google Authenticator, Authy ou toute application TOTP.\",\n\tenrollScan: \"Ouvrez votre application d'authentification et scannez ce code.\",\n\tenrollEnter: 'Saisissez les six chiffres affichés.',\n\tqrAlt: \"Code QR pour votre application d'authentification\",\n\tcantScan: 'Impossible de scanner ? Saisissez plutôt une clé de configuration',\n\tpreparing: 'Préparation…',\n\tcancelSignOut: 'Annuler et se déconnecter',\n\tcodeFromApp: \"Code de l'application\",\n\tverifyContinue: 'Vérifier et continuer',\n\tbackupTitle: 'Enregistrez vos codes de secours',\n\tbackupSubtitle:\n\t\t'Si vous perdez votre téléphone, chacun de ces codes vous connecte une seule fois. Ils ne sont affichés que maintenant.',\n\tbackupFileHeader: \"Codes de secours pour l'administration de {host}\",\n\tdownload: 'Télécharger',\n\tsavedCheckbox: \"J'ai enregistré ces codes en lieu sûr\",\n\topenConsole: 'Ouvrir la console',\n\tlinkInvalidTitle: 'Ce lien ne peut pas être utilisé',\n\tcheckingLink: 'Vérification de votre lien…',\n\tjoinTitle: \"Rejoindre la console d'administration\",\n\trecoverTitle: 'Récupérer votre compte',\n\tjoinSubtitle:\n\t\t\"Vous avez été invité en tant que {email}. Choisissez un mot de passe, puis configurez une application d'authentification.\",\n\trecoverSubtitle:\n\t\t\"Définissez un nouveau mot de passe pour {email}. Vous configurerez à nouveau votre application d'authentification.\",\n\tstepUpTitle: \"Confirmez qu'il s'agit bien de vous\",\n\tstepUpSubtitle: 'Cette action demande un nouveau code. Il reste valable cinq minutes.',\n\ttwoStepTitle: 'Vérification en deux étapes',\n\ttwoStepSubtitle: \"Saisissez le code de votre application d'authentification.\",\n\tverify: 'Vérifier',\n\tchangeLanguage: 'Changer de langue (actuelle : {name})',\n\tthemeChoice: 'Thème : {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'Cet e-mail et ce mot de passe ne correspondent à aucun opérateur.',\n\t\tINVALID_CODE: \"Ce code n'a pas fonctionné. Les codes changent toutes les 30 secondes.\",\n\t\tLOCKED: 'Trop de tentatives. Réessayez dans {minutes} minute(s).',\n\t\tLOCKED_GENERIC: 'Trop de tentatives. Réessayez dans quelques minutes.',\n\t\tRATE_LIMITED: 'Trop de tentatives depuis cette adresse. Patientez quelques minutes.',\n\t\tWEAK_PASSWORD:\n\t\t\t'Choisissez un mot de passe plus robuste — au moins 12 caractères, difficile à deviner.',\n\t\tINVALID_LINK: 'Ce lien a expiré ou a déjà été utilisé. Demandez-en un nouveau.',\n\t\tALREADY_OPERATOR: 'Cet e-mail est déjà celui d’un opérateur. Connectez-vous plutôt.',\n\t\tALREADY_CLAIMED: 'Cette console a déjà des opérateurs. Demandez une invitation à l’un d’eux.',\n\t\tCROSS_ORIGIN: \"Cette requête ne provient pas de la page d'administration.\",\n\t},\n};\nexport default session;\n","import type en from '../en/attention';\n\nconst attention: typeof en = {\n\ttitle: 'À traiter',\n\tlead: 'Ce qui demande votre attention sur ce déploiement',\n\tleadChecked: 'Ce qui demande votre attention sur ce déploiement · vérifié à {time}',\n\tneedsAction: 'Action requise',\n\tneedsActionHint: 'erreurs à corriger',\n\tadvice: 'Conseils',\n\tadviceHint: 'à examiner',\n\tmodulesReady: 'Modules prêts',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Routes',\n\trunning: 'Vérifications en cours…',\n\temptyTitle: 'Rien à traiter',\n\temptyBody: 'Toutes les vérifications réussissent. Vérifié le {time}.',\n};\nexport default attention;\n","import type en from '../en/modules';\n\nconst modules: typeof en = {\n\ttitle: 'Modules',\n\tlead: 'Chaque module installé, sa version et son état de préparation.',\n\tleadSummary: \"{env} · admin {version} · journal d'administration {log} · {routes} routes\",\n\tlogOn: 'activé',\n\tlogOff: 'désactivé',\n\tcolModule: 'Module',\n\tcolVersion: 'Version',\n\tcolReadiness: 'État',\n\tcolAdmin: 'Admin',\n\tnotReported: 'non communiquée',\n\tdescribesAdmin: \"décrit l'admin\",\n};\nexport default modules;\n","import type en from '../en/environment';\n\nconst environment: typeof en = {\n\ttitle: 'Environnement',\n\tlead: \"Si chaque module est configuré et si chaque variable lue par l'application est définie. Les valeurs ne sont jamais affichées.\",\n\tmissingCount: '{n} manquantes',\n\tallSet: 'toutes définies',\n\tvariables: 'Variables',\n\tnoVariables: 'Aucune variable déclarée — passez `env` à AdminModule.',\n\tmoduleReadiness: 'État des modules',\n\tproblemOne: '1 problème',\n\tproblemMany: '{n} problèmes',\n};\nexport default environment;\n","import type en from '../en/doctor';\n\nconst doctor: typeof en = {\n\ttitle: 'Diagnostic',\n\tlead: 'Toutes les vérifications de cohérence des modules installés, lancées à la demande.',\n\tallPass: 'toutes les vérifications réussissent',\n\toneFailed: 'une vérification a échoué',\n\trunAgain: 'Relancer',\n\trunning: 'Vérifications en cours…',\n\tcolResult: 'Résultat',\n\tcolCheck: 'Vérification',\n\tcolTime: 'Durée',\n};\nexport default doctor;\n","import type en from '../en/routes';\n\nconst routes: typeof en = {\n\ttitle: 'Routes',\n\tlead: 'Chaque route exposée, avec sa protection.',\n\tleadCount: '{n} routes exposées par ce déploiement, avec la protection placée devant chacune.',\n\tfilterPlaceholder: 'Filtrer par chemin, méthode, module…',\n\tfilterLabel: 'Filtrer les routes',\n\tcolMethod: 'Méthode',\n\tcolPath: 'Chemin',\n\tcolGuard: 'Protection',\n\tcolModule: 'Module',\n\tapplication: 'application',\n\tnoMatch: 'Aucune route ne correspond à « {q} ».',\n};\nexport default routes;\n","import type en from '../en/log';\n\nconst log: typeof en = {\n\ttitle: \"Journal d'administration\",\n\tlead: 'Chaque requête passée par cette console, de la plus récente à la plus ancienne — y compris les requêtes refusées.',\n\toff: \"Le journal d'administration est désactivé — fournissez un store à AdminModule.\",\n\tempty: 'Aucune requête pour le moment',\n\tcolWhen: 'Date',\n\tcolActor: 'Auteur',\n\tcolRequest: 'Requête',\n\tcolStatus: 'Statut',\n\tcolModule: 'Module',\n};\nexport default log;\n","import type en from '../en/migrations';\n\nconst migrations: typeof en = {\n\ttitle: 'Migrations',\n\tlead: 'Les changements de schéma livrés par chaque module, et si cette base de données les contient.',\n\tneedsWrite: \"L'application des migrations nécessite un jeton avec le droit d'écriture.\",\n\tfirstInstall:\n\t\t\"Cette base de données n'a jamais été migrée — elle est traitée comme une première installation, rien n'est donc retenu.\",\n\tupToDate: 'Tous les modules sont à jour',\n\tnoPending: 'Aucune migration en attente.',\n\tpendingCount: '{n} en attente',\n\tdestructive: 'destructive',\n\tadditive: 'additive',\n\tblockedBy: \"Appliquez d'abord « {module} » — il s'exécute avant celui-ci et est en retard.\",\n\tdestructiveBlocked:\n\t\t'Contient une migration qui supprime des données. Aucune migration inverse ne les restaure — appliquez-la via la CI ou `npm run migrate`.',\n\tconfirmApply:\n\t\t'Appliquer {n} migration(s) à « {module} » ? Cela modifie le schéma de la base de données.',\n\tapplyOne: 'Appliquer 1 migration',\n\tapplyMany: 'Appliquer {n} migrations',\n};\nexport default migrations;\n","import type en from '../en/tokens';\n\nconst tokens: typeof en = {\n\ttitle: 'Jetons',\n\tlead: 'Les identifiants des machines : la robustesse du jeton racine, les jetons à portée limitée pour la CLI et la CI, et les éventuels jetons hérités par module. Les personnes se connectent en tant qu’opérateurs.',\n\tneedsRoot:\n\t\t'Émettre et révoquer nécessitent le jeton racine (celui de la configuration de votre déploiement).',\n\trootToken: 'Jeton racine',\n\tstrong: 'robuste',\n\tweak: 'faible',\n\tissuedTokens: 'Jetons émis',\n\tissuingOff:\n\t\t\"L'émission est désactivée — fournissez un store à AdminModule et exécutez ses migrations.\",\n\tcopyNow: 'Copiez-le maintenant — il ne sera plus jamais affiché.',\n\tnamePlaceholder: 'nom',\n\tnameLabel: 'Nom',\n\tscope: {\n\t\tread: 'lecture',\n\t\twrite: 'écriture',\n\t\tsecrets: 'secrets',\n\t},\n\tdaysPlaceholder: 'jours (facultatif)',\n\tdaysLabel: 'Jours',\n\tissue: 'Émettre un jeton',\n\tcol: {\n\t\tname: 'Nom',\n\t\tscopes: 'Portées',\n\t\tcreated: 'Créé le',\n\t\texpires: 'Expire le',\n\t\tlastUsed: 'Dernière utilisation',\n\t},\n\trevoked: 'révoqué',\n\trevoke: 'Révoquer',\n\trevokeConfirm: 'Révoquer « {name} » ? Tout ce qui l’utilise cesse de fonctionner immédiatement.',\n\temptyTitle: 'Aucun jeton à portée limitée pour le moment',\n\temptyBody:\n\t\t'Émettez un jeton en lecture seule pour un tableau de bord ou un collègue au lieu de partager le jeton racine.',\n\tlegacyTitle: 'Jetons hérités par brique',\n\tlegacyNone: \"Aucun — la surface d'administration de chaque brique passe par ce jeton.\",\n\tlegacyRow: 'enregistre encore ses routes autonomes avec son propre jeton (obsolète)',\n};\nexport default tokens;\n","import type en from '../en/operators';\n\nconst operators: typeof en = {\n\ttitle: 'Opérateurs',\n\tlead: \"Les personnes qui peuvent se connecter à cette console. Chacune utilise un mot de passe et une application d'authentification ; il n'y a pas d'inscription.\",\n\tlevel: {\n\t\tread: 'Lecture seule',\n\t\teditor: 'Éditeur',\n\t\towner: 'Propriétaire',\n\t},\n\tlevelHint: {\n\t\tread: 'consulter, sans rien modifier',\n\t\teditor: 'modifier la configuration, les modèles et les utilisateurs',\n\t\towner: 'aussi les secrets, les jetons et les opérateurs',\n\t},\n\tneedsOwner: 'La gestion des opérateurs nécessite le niveau Propriétaire.',\n\tmintedTitle: \"Envoyez ce lien à {email}. Il n'est affiché qu'une fois.\",\n\tmintedBody: \"Il ne fonctionne qu'une fois et expire le {date}.\",\n\tinvite: 'Inviter',\n\tinvitePlaceholder: 'collegue@entreprise.com',\n\tinviteLabel: 'E-mail à inviter',\n\taccessLevelLabel: \"Niveau d'accès\",\n\taccessLevelFor: \"Niveau d'accès de {email}\",\n\tcreateInvite: \"Créer un lien d'invitation\",\n\temptyTitle: 'Aucun opérateur pour le moment',\n\tcol: {\n\t\toperator: 'Opérateur',\n\t\taccess: 'Accès',\n\t\tstatus: 'Statut',\n\t\tlastSignIn: 'Dernière connexion',\n\t},\n\tsettingUp: 'configuration en cours',\n\tbackupCodesLeftOne: '{n} code de secours restant',\n\tbackupCodesLeftMany: '{n} codes de secours restants',\n\trecoveryLink: 'Lien de récupération',\n\trecoveryConfirm:\n\t\t\"Créer un lien de récupération pour {email} ? Cela le déconnecte partout ; le lien permet de définir un nouveau mot de passe et une nouvelle application d'authentification.\",\n\tdisable: 'Désactiver',\n\tenable: 'Activer',\n\tdisableConfirm: 'Désactiver {email} ? Il est déconnecté immédiatement.',\n\tpendingLinks: 'Liens en attente',\n\tlinkKind: {\n\t\tinvite: 'invitation',\n\t\trecovery: 'récupération',\n\t},\n\texpiresOn: 'expire le {date}',\n\trevoke: 'Révoquer',\n};\nexport default operators;\n","import type en from '../en/users';\n\nconst users: typeof en = {\n\ttitle: 'Utilisateurs',\n\tlead: 'Tous les inscrits. Ouvrez un compte pour voir ses sessions, ses connexions et les commandes de suspension et de déconnexion.',\n\temailPlaceholder: 'adresse e-mail',\n\temailLabel: 'E-mail',\n\tallUsers: 'Tous les utilisateurs',\n\twhichAccounts: 'Quels comptes',\n\tactiveAccounts: 'Actifs',\n\tdeletedAccounts: 'Supprimés',\n\tnoUserWithEmail: 'Aucun utilisateur avec cette adresse e-mail.',\n\tmissingIdPrefix: \"Aucun compte avec l'id\",\n\tmissingIdBody:\n\t\t\"Il a été supprimé, ou n'a jamais existé ici. Ses données de facturation sont conservées.\",\n\tplanCredits: 'Forfait et crédits',\n\temptyTitle: 'Aucun utilisateur pour le moment',\n\temptyBody: 'Les inscriptions apparaissent ici au fil de l’eau.',\n\tcol: {\n\t\temail: 'E-mail',\n\t\tname: 'Nom',\n\t\tplan: 'Forfait',\n\t\tcreated: 'Créé le',\n\t\tstatus: 'Statut',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'e-mail',\n\t\tverified: 'vérifié',\n\t\tmfa: 'MFA',\n\t\tprovider: 'fournisseur',\n\t\tlastLogin: 'dernière connexion',\n\t\tcreated: 'créé le',\n\t},\n\tpasswordProvider: 'mot de passe',\n\tnoPasswordSet: 'aucun mot de passe défini',\n\tdeletedOn: 'Supprimé le {date}.',\n\tdeletedBody:\n\t\t'Le compte ne peut plus se connecter et sera effacé lors de la purge de conservation. Ses données de facturation sont conservées.',\n\tsuspend: 'Suspendre',\n\tunsuspend: 'Réactiver',\n\tsignOutEverywhere: 'Déconnecter partout',\n\tliveSessions: 'Sessions actives',\n\tsince: 'depuis le {date}',\n\trecentSignIns: 'Connexions récentes',\n\tnoneRecorded: 'Aucune enregistrée.',\n\toutcome: {\n\t\tsuccess: 'réussie',\n\t\tfailure: 'échec',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hébergeur',\n};\nexport default users;\n","import type en from '../en/billing';\n\nconst billing: typeof en = {\n\tstatusLabel: {\n\t\tactive: 'actif',\n\t\ttrialing: \"en période d'essai\",\n\t\tpast_due: 'en retard de paiement',\n\t\tunpaid: 'impayé',\n\t\tcanceled: 'résilié',\n\t\tincomplete: 'incomplet',\n\t\tincomplete_expired: 'incomplet (expiré)',\n\t\tpaused: 'en pause',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'mois',\n\t\tyear: 'an',\n\t},\n\trenews: 'Renouvelé le',\n\tends: 'Se termine le',\n\tended: 'Terminé le',\n\tloading: 'Chargement de la facturation…',\n\tplan: 'Forfait',\n\tfree: 'Gratuit',\n\tnoSubscription: 'aucun abonnement',\n\tcredits: 'Crédits',\n\tcurrencyPlaceholder: 'devise',\n\tcurrencyLabel: 'Devise du portefeuille',\n\tcurrencyTitle: 'Afficher le portefeuille dans une autre devise',\n\tbreakdown: '{permanent} permanents · {allowance} d’allocation du forfait',\n\texpires: ' (expire le {date})',\n\tnoWallet: \"Aucun portefeuille — la facturation n'a pas de configuration de portefeuille.\",\n\tgrantCredits: 'Octroyer des crédits',\n\tamountPlaceholder: 'montant ({currency})',\n\tamountLabel: 'Montant',\n\treasonPlaceholder: 'motif (facultatif)',\n\treasonLabel: 'Motif',\n\tgrant: 'Octroyer',\n\tgranted: '{amount} {currency} octroyés.',\n\tnoMovements: 'Aucun mouvement de crédits pour le moment',\n\tcol: {\n\t\twhen: 'Date',\n\t\tkind: 'Type',\n\t\tamount: 'Montant',\n\t\tnote: 'Note',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'achat',\n\t\tgrant: 'octroi',\n\t\tusage: 'utilisation',\n\t\trefund: 'remboursement',\n\t\tadjustment: 'ajustement',\n\t\texpiry: 'expiration',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Abonnements',\n\t\tlead: \"Qui paie, et qui est en retard. Le forfait et les crédits d'un utilisateur figurent aussi sur sa page dans Utilisateurs — les utilisateurs gratuits n'apparaissent que là.\",\n\t\tdetailLead: 'Forfait, crédits et mouvements.',\n\t\tback: 'Tous les abonnements',\n\t\tfilterLabel: 'Filtrer par statut',\n\t\tfilter: {\n\t\t\tall: 'Tous',\n\t\t\tactive: 'Actifs',\n\t\t\ttrialing: \"En période d'essai\",\n\t\t\tpastDue: 'En retard',\n\t\t\tcanceled: 'Résiliés',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'Aucun abonnement pour le moment',\n\t\t\tactive: 'Aucun abonnement actif',\n\t\t\ttrialing: \"Aucun abonnement en période d'essai\",\n\t\t\tpastDue: 'Aucun abonnement en retard de paiement',\n\t\t\tcanceled: 'Aucun abonnement résilié',\n\t\t},\n\t\temptyHint: \"Les abonnements apparaissent ici dès qu'un client passe commande.\",\n\t\ttypeLabel: 'Type',\n\t\ttypeWorkspace: 'espace de travail',\n\t\ttypeUser: 'utilisateur',\n\t\tidPlaceholder: \"id de l'abonné\",\n\t\tidLabel: \"Id de l'abonné\",\n\t\tcol: {\n\t\t\tsubscriber: 'Abonné',\n\t\t\tplan: 'Forfait',\n\t\t\tstatus: 'Statut',\n\t\t\trenewsEnds: 'Renouvellement / fin',\n\t\t},\n\t\tcancels: 'résiliation prévue',\n\t},\n};\nexport default billing;\n","import type en from '../en/catalog';\n\nconst catalog: typeof en = {\n\ttitle: 'Catalogue',\n\tlead: 'Ce que vous vendez : les forfaits tels que configurés dans le code, et tels qu’enregistrés dans la base de données, côte à côte.',\n\tconfigured: 'Configurés (code)',\n\tstored: 'Enregistrés (base de données)',\n\temptyTitle: 'Aucun forfait enregistré',\n\temptyBody:\n\t\t\"Les forfaits sont configurés dans le code ; rien n'a été écrit dans la base de données.\",\n\tcol: {\n\t\tplan: 'Forfait',\n\t\ttier: 'Niveau',\n\t\tseats: 'Places',\n\t\tmonthly: 'Mensuel',\n\t\tyearly: 'Annuel',\n\t\ttrial: 'Essai',\n\t},\n\ttrialDays: '{n} j',\n\tdeleteConfirm: 'Supprimer le forfait enregistré « {name} » ?',\n};\nexport default catalog;\n","import type en from '../en/audit';\n\nconst audit: typeof en = {\n\ttitle: 'Audit',\n\tlead: \"Ce qui s'est passé, dans tous les espaces de travail sauf si vous en nommez un. Le verdict d'intégrité de la chaîne se trouve sur la page Diagnostic.\",\n\tworkspacePlaceholder: \"id d'espace de travail (tous si vide)\",\n\ttypePlaceholder: \"type d'événement\",\n\tactorPlaceholder: \"id de l'acteur\",\n\tfromLabel: 'Date de début',\n\tfromTitle: 'Du (inclus)',\n\ttoLabel: 'Date de fin',\n\ttoTitle: 'Au (inclus)',\n\tempty: 'Rien d’enregistré pour ce filtre',\n\tcol: {\n\t\twhen: 'Date',\n\t\ttype: 'Type',\n\t\tworkspace: 'Espace de travail',\n\t\tactor: 'Acteur',\n\t\trequest: 'Requête',\n\t},\n};\nexport default audit;\n","import type en from '../en/config';\n\nconst config: typeof en = {\n\tenvironment: 'Environnement',\n\treveal: 'Afficher',\n\ttype: {\n\t\ttext: 'texte',\n\t\tnumber: 'nombre',\n\t\tonOff: 'oui/non',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Texte',\n\t\tnumber: 'Nombre',\n\t\tonOff: 'Oui/non',\n\t\tlist: 'Liste',\n\t\tobject: 'Objet',\n\t\tempty: 'Vide',\n\t},\n\tlist: {\n\t\ttitle: 'Configuration',\n\t\tnewEntry: 'Nouvelle entrée',\n\t\thint: \"Drapeaux de fonctionnalité et réglages d'exécution — texte, nombres, oui/non ou JSON. Lus par l'application sans redéploiement.\",\n\t\tempty: 'Aucune entrée de configuration pour le moment.',\n\t\temptyCta: 'Créez-en une pour activer une fonctionnalité ou ajuster un réglage sans redéployer.',\n\t\temptyInEnv: 'Aucune configuration dans {env}. Les entrées de « all » s’y appliquent toujours.',\n\t\tpublicBadge: 'public',\n\t\tpublicTitle: 'Servi aux frontends par GET /config/public',\n\t\tpublicSummary: 'Ce que reçoivent les frontends ({n} clés publiques)',\n\t\tpublicSummaryOne: 'Ce que reçoivent les frontends (1 clé publique)',\n\t\tpublicHint:\n\t\t\t\"Exactement le corps de {route} — sans authentification, donc lisible par tous. Seules les clés que l'application déclare publiques y figurent.\",\n\t\tsecretsTitle: 'Secrets',\n\t\tnewSecret: 'Nouveau secret',\n\t\tsecretsHint: 'Chiffrés au repos ; les valeurs restent masquées jusqu’à leur affichage.',\n\t\tsecretsEmpty: 'Aucun secret pour le moment.',\n\t\tsecretsEmptyInEnv: 'Aucun secret dans {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'Nouvelle entrée de configuration',\n\t\tnewSecret: 'Nouveau secret',\n\t\tenvironmentLabel: 'Environnement :',\n\t\tkey: 'Clé',\n\t\tenvironmentHint:\n\t\t\t'« all » est partagé par tous les environnements ; un environnement nommé (production, staging…) le remplace.',\n\t\tvalue: 'Valeur',\n\t\tnewValue: 'Nouvelle valeur',\n\t\tvaluePlaceholder: 'true · 42 · Maintenance prévue ce soir · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Détecté :',\n\t\tsaveAsText: 'Enregistrer plutôt comme texte',\n\t\ton: 'Oui (true)',\n\t\toff: 'Non (false)',\n\t\ttype: 'Type :',\n\t\tchangeType: 'Changer de type…',\n\t\tchangeTypeWarning:\n\t\t\t'Changer le type modifie ce que reçoit chaque écran qui lit cette clé. Vérifiez d’abord le code qui la lit.',\n\t\tdescription: 'Description',\n\t\tconflict:\n\t\t\t'Quelqu’un a modifié cette entrée depuis son ouverture. Rechargez pour voir sa modification, puis modifiez à nouveau.',\n\t\tconfirmDelete: 'Supprimer « {key} » ? Tout ce qui la lit revient à sa valeur par défaut.',\n\t\tconfirmDeleteIn:\n\t\t\t'Supprimer « {key} » de {env} ? Tout ce qui la lit revient à sa valeur par défaut.',\n\t\thistory: 'Historique',\n\t\tunknownActor: 'inconnu',\n\t\trollBack: 'Restaurer',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Saisissez une clé.',\n\t\tkeyPattern:\n\t\t\t'Commencez par une lettre ; utilisez des lettres, des chiffres, « . », « _ » ou « - » (128 max).',\n\t\texists: '« {key} » existe déjà dans {env} — ouvrez-la depuis la liste pour la modifier.',\n\t\tnumber: 'Saisissez un nombre.',\n\t\tboolean: 'Utilisez true ou false.',\n\t\tjson: 'JSON non valide : {detail}',\n\t},\n};\nexport default config;\n","import type en from '../en/templates';\n\nconst templates: typeof en = {\n\tdefaultLocale: 'langue par défaut',\n\tdefaultChip: 'par défaut',\n\tbuiltInBadge: 'intégré',\n\tsubject: 'Objet',\n\thtmlBody: 'Corps HTML',\n\ttextBody: 'Corps en texte brut',\n\tlist: {\n\t\ttitle: 'Modèles',\n\t\tnewTemplate: 'Nouveau modèle',\n\t\thint: \"Chaque e-mail envoyé par l'application. Ouvrez-en un pour modifier son contenu et le prévisualiser en direct.\",\n\t\tloading: 'Chargement des modèles…',\n\t\topenLocale: 'Ouvrir la version {locale} de {type}',\n\t},\n\teditor: {\n\t\tloading: 'Chargement du modèle…',\n\t\tlocales: 'Langues',\n\t\tdiscardChanges: 'Cette langue a des modifications non enregistrées. Les abandonner et changer de langue ?',\n\t\taddLocale: '+ Ajouter une langue',\n\t\tbuiltInNote: 'e-mail intégré : modifiable ou restaurable, mais pas supprimable',\n\t\tactive: 'Actif',\n\t\tconflict:\n\t\t\t'Quelqu’un a modifié ce modèle depuis son ouverture. Rechargez pour voir sa modification, puis modifiez à nouveau.',\n\t\tnoChanges: 'Aucune modification à enregistrer',\n\t\tsampleData: \"Données d'exemple\",\n\t\tsampleNotObject: \"Les données d'exemple doivent être un objet JSON.\",\n\t\tsampleInvalid: \"Les données d'exemple ne sont pas un JSON valide.\",\n\t\tpreview: 'Aperçu',\n\t\tpreviewTitle: 'Aperçu du modèle',\n\t\trendering: 'Rendu en cours…',\n\t\tlive: 'En direct',\n\t\tnothingRendered: 'Rien n’a encore été rendu.',\n\t\thistory: 'Historique',\n\t\tunknownActor: 'inconnu',\n\t\trollBack: 'Restaurer',\n\t\tconfirmDelete: 'Supprimer « {type} » ?',\n\t\tconfirmDeleteLocale:\n\t\t\t'Supprimer la version {locale} de « {type} » ? Les personnes de cette langue recevront la version par défaut.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'Nouveau modèle',\n\t\ttitleLocale: 'Ajouter une langue à {type}',\n\t\thintNew:\n\t\t\t\"Pour un e-mail envoyé par votre application qui n'a pas encore de contenu enregistré. Le type doit correspondre à ce que l'application envoie.\",\n\t\thintLocale:\n\t\t\t'Part du contenu par défaut. Les personnes dont la langue correspond reçoivent cette version ; les autres gardent la version par défaut.',\n\t\ttype: 'Type',\n\t\tlocale: 'Langue',\n\t\tlocaleOptional: 'Langue (facultative — vide correspond à la langue par défaut)',\n\t\tcreating: 'Création…',\n\t\tsubmitNew: 'Créer le modèle',\n\t\tsubmitLocale: 'Ajouter la langue',\n\t\terrorType: 'Type : lettres minuscules, chiffres, - et _ (ex. weekly-digest).',\n\t\terrorLocaleRequired: 'Choisissez la langue à ajouter, par ex. fr ou fr-CA.',\n\t\terrorLocale: 'Langue : une étiquette de langue comme fr, es ou fr-CA.',\n\t\terrorText: 'Le corps en texte brut est obligatoire — c’est ce que tout client e-mail peut afficher.',\n\t\texists: '« {type} » existe déjà — ouvrez-le depuis la liste pour le modifier.',\n\t\texistsLocale: '« {type} » ({locale}) existe déjà — ouvrez-le depuis la liste pour le modifier.',\n\t\tuntranslated: 'Encore dans la version par défaut : {fields}. Traduisez-les avant d’ajouter cette langue.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst fr = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default fr;\n","import en from './en';\nimport es from './es';\nimport fr from './fr';\n\n// The admin console's own language — the OPERATOR's preference, independent\n// of the locales the app serves its customers. A founder in France can run\n// the console in French while every customer email stays English.\n//\n// English is canonical: its shape defines the key space, and fr/es are typed\n// against it, so a missing or extra key is a compile error (the pattern the\n// reference app uses for its own UI).\n\nexport const ADMIN_LOCALES = ['en', 'fr', 'es'] as const;\nexport type AdminLocale = (typeof ADMIN_LOCALES)[number];\nexport const DEFAULT_ADMIN_LOCALE: AdminLocale = 'en';\n\n/**\n * One value per console language, read-only. Frozen at runtime too: these\n * maps are shared by every console on the page, so an embedding app must not\n * be able to rename \"Français\" for everyone by assignment.\n */\nexport type LocaleMap<T> = Readonly<Record<AdminLocale, T>>;\n\n/** Native-language names, for the language menu. */\nexport const adminLocaleNames: LocaleMap<string> = Object.freeze({\n\ten: 'English',\n\tfr: 'Français',\n\tes: 'Español',\n});\n\n/** BCP 47 tags for Intl (dates, numbers). */\nexport const adminLocaleTags: LocaleMap<string> = Object.freeze({\n\ten: 'en-US',\n\tfr: 'fr-FR',\n\tes: 'es-ES',\n});\n\nexport const isAdminLocale = (value: unknown): value is AdminLocale =>\n\t(ADMIN_LOCALES as readonly unknown[]).includes(value);\n\n/** The first supported language in a browser's preference list, else English. */\nexport function detectAdminLocale(languages: readonly string[] = []): AdminLocale {\n\tfor (const tag of languages) {\n\t\tconst base = tag.toLowerCase().split('-')[0];\n\t\tif (isAdminLocale(base)) return base;\n\t}\n\treturn DEFAULT_ADMIN_LOCALE;\n}\n\nexport type AdminMessages = typeof en;\ntype MessagePath<T> = {\n\t[K in keyof T & string]: T[K] extends string\n\t\t? K\n\t\t: T[K] extends object\n\t\t\t? `${K}.${MessagePath<T[K]>}`\n\t\t\t: never;\n}[keyof T & string];\n/** Every dot-path to a string in the dictionary, e.g. 'users.title'. */\nexport type AdminMessageKey = MessagePath<AdminMessages>;\nexport type AdminMessageParams = Record<string, string | number>;\n\nconst dictionaries: LocaleMap<AdminMessages> = { en, fr, es };\n\n/**\n * A translator for one locale: t('users.title'), t('users.count', { n: 3 }).\n * A missing key renders the key itself — visible, never a crash. `{name}`\n * placeholders are interpolated from params.\n */\nexport function createAdminT(locale: AdminLocale | undefined = DEFAULT_ADMIN_LOCALE) {\n\tconst dict = dictionaries[locale] ?? dictionaries[DEFAULT_ADMIN_LOCALE];\n\tconst t = (key: AdminMessageKey, params?: AdminMessageParams): string => {\n\t\tlet node: unknown = dict;\n\t\tfor (const part of key.split('.')) {\n\t\t\tif (node == null || typeof node !== 'object') break;\n\t\t\tnode = (node as Record<string, unknown>)[part];\n\t\t}\n\t\tconst text = typeof node === 'string' ? node : key;\n\t\treturn params\n\t\t\t? text.replace(/\\{(\\w+)\\}/g, (m, n: string) => (n in params ? String(params[n]) : m))\n\t\t\t: text;\n\t};\n\treturn t;\n}\nexport type AdminT = ReturnType<typeof createAdminT>;\n\n/** Dates in the console's language: 'date', 'datetime' or 'time'. */\nexport function formatAdminDate(\n\tvalue: string | number | Date,\n\tlocale: AdminLocale | undefined = DEFAULT_ADMIN_LOCALE,\n\tstyle: 'date' | 'datetime' | 'time' = 'datetime',\n): string {\n\tconst d = value instanceof Date ? value : new Date(value);\n\tconst tag = adminLocaleTags[locale] ?? adminLocaleTags.en;\n\tif (style === 'date') return d.toLocaleDateString(tag);\n\tif (style === 'time') return d.toLocaleTimeString(tag);\n\treturn d.toLocaleString(tag);\n}\n"],"mappings":"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","names":["data","tokens","tokens","tokens","tokens","tokens","tokens","tokens","tokens","tokens","config","environment","common","common_default","nav","nav_default","shell","shell_default","session","session_default","attention","attention_default","modules","modules_default","environment","environment_default","doctor","doctor_default","routes","routes_default","log","log_default","migrations","migrations_default","tokens","tokens_default","operators","operators_default","users","users_default","billing","billing_default","catalog","catalog_default","audit","audit_default","config","config_default","templates","templates_default","common_default","nav_default","shell_default","session_default","attention_default","modules_default","environment_default","doctor_default","routes_default","log_default","migrations_default","tokens_default","operators_default","users_default","billing_default","catalog_default","audit_default","config_default","templates_default","common","common_default","nav","nav_default","shell","shell_default","session","session_default","attention","attention_default","modules","modules_default","environment","environment_default","doctor","doctor_default","routes","routes_default","log","log_default","migrations","migrations_default","tokens","tokens_default","operators","operators_default","users","users_default","billing","billing_default","catalog","catalog_default","audit","audit_default","config","config_default","templates","templates_default","common_default","nav_default","shell_default","session_default","attention_default","modules_default","environment_default","doctor_default","routes_default","log_default","migrations_default","tokens_default","operators_default","users_default","billing_default","catalog_default","audit_default","config_default","templates_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts","../src/http.ts","../src/modules/audit.ts","../src/modules/auth.ts","../src/modules/billing.ts","../src/modules/customers.ts","../src/modules/media.ts","../src/modules/config.ts","../src/modules/webhooks.ts","../src/modules/workspaces.ts","../src/token-store.ts","../src/client.ts","../src/path.ts","../src/modules/config-admin.ts","../src/modules/admin.ts","../src/modules/auth-admin.ts","../src/modules/billing-admin.ts","../src/modules/audit-admin.ts","../src/modules/courier-admin.ts","../src/template-locales.ts","../src/types.ts","../src/config-value.ts","../src/admin-i18n/en/common.ts","../src/admin-i18n/en/nav.ts","../src/admin-i18n/en/shell.ts","../src/admin-i18n/en/session.ts","../src/admin-i18n/en/attention.ts","../src/admin-i18n/en/modules.ts","../src/admin-i18n/en/environment.ts","../src/admin-i18n/en/doctor.ts","../src/admin-i18n/en/routes.ts","../src/admin-i18n/en/log.ts","../src/admin-i18n/en/migrations.ts","../src/admin-i18n/en/tokens.ts","../src/admin-i18n/en/operators.ts","../src/admin-i18n/en/users.ts","../src/admin-i18n/en/billing.ts","../src/admin-i18n/en/catalog.ts","../src/admin-i18n/en/audit.ts","../src/admin-i18n/en/config.ts","../src/admin-i18n/en/templates.ts","../src/admin-i18n/en/index.ts","../src/admin-i18n/es/common.ts","../src/admin-i18n/es/nav.ts","../src/admin-i18n/es/shell.ts","../src/admin-i18n/es/session.ts","../src/admin-i18n/es/attention.ts","../src/admin-i18n/es/modules.ts","../src/admin-i18n/es/environment.ts","../src/admin-i18n/es/doctor.ts","../src/admin-i18n/es/routes.ts","../src/admin-i18n/es/log.ts","../src/admin-i18n/es/migrations.ts","../src/admin-i18n/es/tokens.ts","../src/admin-i18n/es/operators.ts","../src/admin-i18n/es/users.ts","../src/admin-i18n/es/billing.ts","../src/admin-i18n/es/catalog.ts","../src/admin-i18n/es/audit.ts","../src/admin-i18n/es/config.ts","../src/admin-i18n/es/templates.ts","../src/admin-i18n/es/index.ts","../src/admin-i18n/fr/common.ts","../src/admin-i18n/fr/nav.ts","../src/admin-i18n/fr/shell.ts","../src/admin-i18n/fr/session.ts","../src/admin-i18n/fr/attention.ts","../src/admin-i18n/fr/modules.ts","../src/admin-i18n/fr/environment.ts","../src/admin-i18n/fr/doctor.ts","../src/admin-i18n/fr/routes.ts","../src/admin-i18n/fr/log.ts","../src/admin-i18n/fr/migrations.ts","../src/admin-i18n/fr/tokens.ts","../src/admin-i18n/fr/operators.ts","../src/admin-i18n/fr/users.ts","../src/admin-i18n/fr/billing.ts","../src/admin-i18n/fr/catalog.ts","../src/admin-i18n/fr/audit.ts","../src/admin-i18n/fr/config.ts","../src/admin-i18n/fr/templates.ts","../src/admin-i18n/fr/index.ts","../src/admin-i18n/index.ts"],"sourcesContent":["// 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(\n\topts: IMemoryCacheOptions = {},\n): 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\t// The X-Request-ID for the failed call — quote it in a bug report; it\n\t\t// correlates to the server's logs and audit trail for the same request.\n\t\tpublic readonly requestId?: string,\n\t) {\n\t\tsuper(explanation);\n\t\tthis.name = 'FonderieApiError';\n\t}\n}\n\n// Portable random hex for W3C trace ids — crypto.getRandomValues where available\n// (browser / Node), Math.random fallback for Hermes / older React Native. Not\n// security-sensitive: these are correlation/trace ids, not secrets.\nfunction randHex(bytes: number): string {\n\tconst c = (globalThis as { crypto?: { getRandomValues?: (a: Uint8Array) => Uint8Array } }).crypto;\n\tconst arr = new Uint8Array(bytes);\n\tif (c?.getRandomValues) c.getRandomValues(arr);\n\telse for (let i = 0; i < bytes; i++) arr[i] = Math.floor(Math.random() * 256);\n\tlet out = '';\n\tfor (const b of arr) out += b.toString(16).padStart(2, '0');\n\treturn out;\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// Absolute URL for a path on this client's origin — for endpoints a browser\n\t// navigates to or embeds (e.g. a public `<img src>`) rather than fetches\n\t// through request(). Mirrors the `${baseUrl}${path}` join request() uses.\n\tabsolute(path: string): string {\n\t\treturn `${this.baseUrl}${path}`;\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\t// Start a W3C trace: the trace id doubles as the quotable correlation id\n\t\t// (sent as X-Request-ID and surfaced on FonderieApiError.requestId).\n\t\tconst traceId = randHex(16);\n\t\tconst requestId = traceId;\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\ttraceparent: `00-${traceId}-${randHex(8)}-01`,\n\t\t\t'X-Request-ID': requestId,\n\t\t};\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\t\t// The server echoes the id back; prefer it (an intermediary could rewrite\n\t\t// the one we sent), else fall back to what we generated.\n\t\tconst rid = res.headers.get('x-request-id') ?? requestId;\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)\n\t\t\t\tthrow new FonderieApiError('unknown', res.statusText, res.status, undefined, rid);\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, rid);\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 { IReadOptions, 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\tILoginHistoryPageResult,\n\tISessionsResult,\n\tIAuthProvidersResult,\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\t/**\n\t * The language the person is signing up in (e.g. 'fr-CA'). Stored on the\n\t * account, so the verification email already arrives in it. Omitted: the\n\t * app's system locale.\n\t */\n\tlocale?: string;\n}\n\nexport interface IGetLoginHistoryInput {\n\toutcome?: 'success' | 'failed';\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface ILoginInput {\n\temail: string;\n\tpassword: string;\n}\n\n// Native Sign in with Apple: the app obtains an `identityToken` from the native\n// Apple sheet (e.g. expo-apple-authentication) and hands it here — the client\n// only relays it to POST /auth/apple/native. `nonce` is the raw nonce the app\n// passed to the native request, checked server-side against the token claim.\nexport interface IAppleNativeInput {\n\tidentityToken: string;\n\tnonce?: 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\t/**\n\t * Which sign-in methods this deployment can actually honour.\n\t *\n\t * Public — the login screen needs it before anyone has signed in. Ask the\n\t * server rather than shipping a build-time flag: the flag stores the same\n\t * fact twice and lets the two disagree, and the symptom is a user clicking\n\t * a provider the server cannot complete and landing on the provider's own\n\t * error page, which the app cannot explain.\n\t */\n\tproviders() {\n\t\treturn this.http.request<IApiResponse<IAuthProvidersResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/providers',\n\t\t});\n\t}\n\n\t/**\n\t * Disconnect the OAuth provider linked to the signed-in account.\n\t *\n\t * Refused with 409 PASSWORD_REQUIRED when the account has no password:\n\t * removing the only credential is account deletion, not a settings toggle.\n\t * Check `user.hasPassword` before offering the control so the user is asked\n\t * to set a password first rather than shown an error they can't act on.\n\t */\n\tunlinkOauth(provider: string) {\n\t\treturn this.http.request<IApiResponse<null>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/auth/oauth/${encodeURIComponent(provider)}`,\n\t\t});\n\t}\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\t// Complete a native Sign in with Apple. Returns the same token/user envelope\n\t// as login (no MFA branch — OAuth completions don't gate on MFA). Requires\n\t// the API to enable the provider (`providers: ['apple']` + apple config).\n\tappleNative(input: IAppleNativeInput) {\n\t\treturn this.http.request<IApiResponse<ILoginResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/auth/apple/native',\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\t// ── Security surfaces (login history + active sessions) ─────────────────────\n\n\t// GET /auth/login-history — the caller's own attempts, newest first,\n\t// keyset-paginated (pass the previous page's nextCursor to continue).\n\tgetLoginHistory(input: IGetLoginHistoryInput = {}, opts?: IReadOptions) {\n\t\tconst params = new URLSearchParams();\n\t\tif (input.limit !== undefined) params.set('limit', String(input.limit));\n\t\tif (input.outcome) params.set('outcome', input.outcome);\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\t\t// Single-level template (no nested backtick) so the client/route drift\n\t\t// checker can normalise the ${qs…} suffix away and match the server route.\n\t\treturn this.http.request<IApiResponse<ILoginHistoryPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/auth/login-history${qs ? '?' + qs : ''}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// GET /auth/sessions — the caller's live sessions; one is flagged current.\n\tlistSessions(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<ISessionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/auth/sessions',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tbust: opts?.bust,\n\t\t});\n\t}\n\n\t// DELETE /auth/sessions/:id — revoke one of the caller's sessions.\n\tterminateSession(id: string) {\n\t\treturn this.http.request<IApiResponse<{ id: string }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/auth/sessions/${encodeURIComponent(id)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// DELETE /auth/sessions/others — revoke every session except the current one.\n\tterminateOtherSessions() {\n\t\treturn this.http.request<IApiResponse<{ count: number }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/auth/sessions/others',\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\tICancelSubscriptionInput,\n\tICheckoutUrlResult,\n\tIInvoicesResult,\n\tIPaymentMethodResult,\n\tIPlanListResult,\n\tIPlanResult,\n\tIPortalUrlResult,\n\tISavePaymentMethodInput,\n\tISetupIntentResult,\n\tISubscriptionChangeResult,\n\tISubscriptionResult,\n\tIUsageResult,\n\tIWalletCheckoutInput,\n\tIWalletPurchaseInput,\n\tIWalletPurchaseResult,\n\tIWalletResult,\n\tIWalletTransactionsResult,\n} from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\nexport interface ICheckoutInput {\n\tplan: string;\n\tinterval?: 'month' | 'year';\n\t// Optional idempotency key — a retried checkout with the same key dedupes to\n\t// one session (and one subscription) server-side. Generate once per attempt.\n\tidempotencyKey?: string;\n}\n\nexport interface IRecordUsageInput {\n\tmetric: string;\n\tquantity?: number;\n}\n\nexport interface IWalletPreferencesInput {\n\t// When false, a debit stops at the free allowance (402) rather than drawing\n\t// down purchased credits.\n\tspendPurchased: boolean;\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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// First-party cancel — no portal round-trip. Default keeps access until the\n\t// paid-through date; pass { atPeriodEnd: false } to end it immediately. 501\n\t// when the provider has no first-party cancel (the portal remains a fallback).\n\tcancelSubscription(input?: ICancelSubscriptionInput) {\n\t\treturn this.http.request<IApiResponse<ISubscriptionChangeResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/subscription/cancel',\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// Un-cancel a subscription scheduled to cancel at period end. Idempotent; 409\n\t// when the subscription is already fully canceled (start a new checkout).\n\treactivateSubscription() {\n\t\treturn this.http.request<IApiResponse<ISubscriptionChangeResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/subscription/reactivate',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\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/${encodeURIComponent(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\t// ── Wallet ─────────────────────────────────────────────────────────────────────\n\n\tgetWallet(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IWalletResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/wallet',\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\tsetWalletPreferences(input: IWalletPreferencesInput) {\n\t\treturn this.http.request<IApiResponse<IWalletResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/preferences',\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// Start a one-time credit-pack purchase. Returns a hosted checkout URL to\n\t// redirect the buyer to; the wallet is credited by the payment webhook.\n\tcreateWalletCheckout(input: IWalletCheckoutInput) {\n\t\treturn this.http.request<IApiResponse<ICheckoutUrlResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/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\t// Buy a credit pack in-app by charging the saved card — no redirect. Inspect\n\t// `result.status`: 'credited' (done — refresh the wallet), 'checkout_required'\n\t// (no saved card or the card needs 3-D Secure → fall back to\n\t// createWalletCheckout), 'declined', or 'processing' (indeterminate — retry\n\t// with the SAME idempotencyKey). Generate one idempotencyKey per attempt and\n\t// reuse it on retry so a double-submit can't double-charge.\n\tpurchaseWalletPack(input: IWalletPurchaseInput) {\n\t\treturn this.http.request<IApiResponse<IWalletPurchaseResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/wallet/purchase',\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// The wallet ledger, newest first — every credit/debit with a running\n\t// balanceAfter. Cursor-paginated: pass the previous result's `nextCursor`.\n\tgetWalletTransactions(opts?: IReadOptions & { cursor?: string; limit?: number }) {\n\t\tconst params = new URLSearchParams();\n\t\tif (opts?.cursor) params.set('cursor', opts.cursor);\n\t\tif (opts?.limit !== undefined) params.set('limit', String(opts.limit));\n\t\tconst qs = params.toString();\n\t\treturn this.http.request<IApiResponse<IWalletTransactionsResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `/billing/wallet/transactions${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\t// ── Account ──────────────────────────────────────────────────────────────────\n\n\t// The customer's card on file (brand/last4/expiry), or { paymentMethod: null }\n\t// when none is stored. 501 when the provider can't retrieve it.\n\tgetPaymentMethod(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/payment-method',\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// Begin in-app card entry — returns a SetupIntent client secret for the\n\t// provider's embedded card element (Stripe Payment Element); the user never\n\t// leaves the site. 501 when the provider has no in-app card support.\n\tsetupPaymentMethod() {\n\t\treturn this.http.request<IApiResponse<ISetupIntentResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/billing/payment-method/setup',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// Save the card after the client confirms the SetupIntent: makes it the\n\t// default and records it. 422 when the card isn't attached to this customer.\n\tsavePaymentMethod(input: ISavePaymentMethodInput) {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath: '/billing/payment-method',\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// Remove the saved card (detach at the provider + clear the record).\n\tremovePaymentMethod() {\n\t\treturn this.http.request<IApiResponse<IPaymentMethodResult>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: '/billing/payment-method',\n\t\t\ttoken: this.tokens.get(),\n\t\t\tworkspaceId: this.workspaceId,\n\t\t});\n\t}\n\n\t// The customer's invoices, newest first — each links out to the hosted\n\t// invoice / PDF. 501 when the provider can't list them.\n\tlistInvoices(opts?: IReadOptions) {\n\t\treturn this.http.request<IApiResponse<IInvoicesResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: '/billing/invoices',\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(customerId)}/emails/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(customerId)}/phones/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(customerId)}/addresses/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/notes/${encodeURIComponent(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/${encodeURIComponent(customerId)}/notes/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(customerId)}/relationships/${encodeURIComponent(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/${encodeURIComponent(customerId)}/relationships/${encodeURIComponent(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=${encodeURIComponent(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/${encodeURIComponent(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 { IApiResponse, IMediaAssetResult } from '../types';\n\n// ── Input shapes ─────────────────────────────────────────────────────────────\n\n// Upload an image. `dataBase64` is the RAW base64 payload (no `data:` prefix) —\n// the server sniffs the real type from magic bytes, enforces the byte cap, and\n// rejects SVG (stored-XSS). `purpose` groups assets (e.g. 'avatar'); ownerType\n// /ownerId default server-side to the calling user, so a plain avatar upload\n// needs only `dataBase64`.\nexport interface IUploadMediaInput {\n\tdataBase64: string;\n\tpurpose?: string;\n\townerType?: string;\n\townerId?: string;\n}\n\n// ── Media client ─────────────────────────────────────────────────────────────\n// Session-authenticated (shares FonderieClient's TokenStore, like auth). NOT\n// workspace-scoped: @fonderie/media keys ownership off ownerType/ownerId in the\n// body, not an X-Workspace-ID header.\n\nexport class MediaClient {\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// POST /media — store an image; returns the asset with its monomorphic\n\t// /media/:id url. requireAuth server-side.\n\tupload(input: IUploadMediaInput) {\n\t\treturn this.http.request<IApiResponse<IMediaAssetResult>>({\n\t\t\tmethod: 'POST',\n\t\t\tpath: '/media',\n\t\t\tbody: input,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// DELETE /media/:id — uploader-only (403 for anyone else).\n\tdelete(id: string) {\n\t\treturn this.http.request<IApiResponse<{ id: string }>>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath: `/media/${encodeURIComponent(id)}`,\n\t\t\ttoken: this.tokens.get(),\n\t\t});\n\t}\n\n\t// Absolute URL for a stored asset — an `<img src>` target. The GET /media/:id\n\t// route is public and cached (it can't carry a Bearer token), so turn an\n\t// upload's `asset.id` into a browser-loadable URL with this, and use it as\n\t// the avatarUrl handed to auth's updateProfile.\n\tassetUrl(id: string): string {\n\t\treturn this.http.absolute(`/media/${encodeURIComponent(id)}`);\n\t}\n\n\t// Inverse of assetUrl: pull the asset id out of one of THIS brick's\n\t// /media/:id URLs (absolute or relative); null for empty/external URLs. Lets\n\t// avatar cleanup delete only assets we minted (matched as a UUID), never a\n\t// placeholder or third-party avatar URL.\n\tassetIdFromUrl(url: string | null | undefined): string | null {\n\t\tif (!url) return null;\n\t\tconst m = url.match(\n\t\t\t/\\/media\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)/i,\n\t\t);\n\t\treturn m ? m[1]! : null;\n\t}\n}\n","import type { HttpClient } from '../http';\nimport type { TokenStore } from '../token-store';\nimport type { IApiResponse } from '../types';\n\n// ── Public remote config ─────────────────────────────────────────────────────\n// The frontend's read path for feature flags and runtime settings: only the\n// keys the server lists in ConfigModule's `publicKeys`. One snapshot per\n// FonderieClient, shared by every screen and hook that reads it — load it once\n// (typically right after sign-in, or at app start for signed-out flags), then\n// read synchronously anywhere.\n\nexport interface IRemoteConfigState {\n\t/** key → value, as last loaded. Empty until the first load succeeds. */\n\tvalues: Readonly<Record<string, unknown>>;\n\t/** When values were last loaded successfully; null before that. */\n\tloadedAt: Date | null;\n\tisLoading: boolean;\n\t/** The last load's failure, cleared by the next success. Values are kept. */\n\terror: unknown;\n}\n\ntype Listener = (state: IRemoteConfigState) => void;\n\nexport class ConfigClient {\n\tprivate state: IRemoteConfigState = { values: {}, loadedAt: null, isLoading: false, error: null };\n\tprivate listeners = new Set<Listener>();\n\tprivate inFlight: Promise<IRemoteConfigState> | null = null;\n\n\tconstructor(\n\t\tprivate http: HttpClient,\n\t\tprivate tokens: TokenStore,\n\t) {}\n\n\t// GET /config/public — fetch the public values into the shared snapshot.\n\t// Concurrent calls share one request. A failure keeps the previous values\n\t// (a flag that was on does not flicker off because one refresh failed) and\n\t// is reported in `error`; before any success, reads fall back to defaults.\n\tload(): Promise<IRemoteConfigState> {\n\t\tif (this.inFlight) return this.inFlight;\n\t\tthis.set({ isLoading: true });\n\t\tthis.inFlight = this.http\n\t\t\t.request<IApiResponse<{ values: Record<string, unknown> }>>({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: '/config/public',\n\t\t\t\t// Sent when signed in, so per-user values can be served later\n\t\t\t\t// without a client change; the route itself is public.\n\t\t\t\ttoken: this.tokens.get(),\n\t\t\t})\n\t\t\t.then(\n\t\t\t\t(res) => this.set({ values: res.result?.values ?? {}, loadedAt: new Date(), isLoading: false, error: null }),\n\t\t\t\t(error: unknown) => this.set({ isLoading: false, error }),\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.inFlight = null;\n\t\t\t});\n\t\treturn this.inFlight;\n\t}\n\n\t// One value, with the fallback used when the key is absent — before the\n\t// first load, when it failed, or when the server does not expose the key.\n\t// Pick the SAFE fallback (feature off), not the optimistic one.\n\tget<T>(key: string, fallback: T): T {\n\t\treturn Object.hasOwn(this.state.values, key) ? (this.state.values[key] as T) : fallback;\n\t}\n\n\t// The whole current state (values, loadedAt, isLoading, error).\n\tsnapshot(): IRemoteConfigState {\n\t\treturn this.state;\n\t}\n\n\t// Called with the new state after every change; returns an unsubscribe.\n\tsubscribe(listener: Listener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate set(patch: Partial<IRemoteConfigState>): IRemoteConfigState {\n\t\t// A new object each time, so React's useSyncExternalStore and Vue refs\n\t\t// see a change by identity.\n\t\tthis.state = { ...this.state, ...patch };\n\t\tfor (const listener of this.listeners) listener(this.state);\n\t\treturn this.state;\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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(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/${encodeURIComponent(userId)}/roles/${encodeURIComponent(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/${encodeURIComponent(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 { MediaClient } from './modules/media';\nimport { ConfigClient } from './modules/config';\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\treadonly media: MediaClient;\n\t/** Public remote config: flags and settings the server exposes to frontends. */\n\treadonly config: ConfigClient;\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// Media is per-user (ownership via ownerType/ownerId in the body), so no\n\t\t// setWorkspaceId wiring below — just the shared http + token store.\n\t\tthis.media = new MediaClient(this.http, this.tokens);\n\t\tthis.config = new ConfigClient(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>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'POST',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tput<T = unknown>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'PUT',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tpatch<T = unknown>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\tconfig?: IRequestConfig,\n\t): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'PATCH',\n\t\t\tpath,\n\t\t\tbody,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n\n\tdelete<T = unknown>(path: string, config?: IRequestConfig): Promise<IApiResponse<T>> {\n\t\treturn this.request<T>({\n\t\t\tmethod: 'DELETE',\n\t\t\tpath,\n\t\t\ttoken: config?.token,\n\t\t\tworkspaceId: config?.workspaceId,\n\t\t\tinvalidate: config?.invalidate,\n\t\t});\n\t}\n}\n","// Where an admin surface is mounted, as CONFIG: trailing slashes are typing,\n// not meaning, so '/_admin', '/_admin/' and '/_admin//' are one prefix.\n//\n// This duplicates `normalizeMountPath` in @fonderie/core on purpose: this\n// package ships with **zero runtime dependencies** so it can be dropped into\n// any frontend, and importing a server package to strip a slash would end\n// that. One copy here, used by every admin client — not one per client.\nexport const normalizeMountPath = (path: string): string => path.replace(/\\/+$/, '');\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\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\t/** Required to change an existing key's value kind (on/off → text, list → object);\n\t * without it the server answers 409 CONFIG_TYPE_CHANGE. */\n\tallowTypeChange?: boolean;\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// Where the composed surface lives when @fonderie/admin mounts this brick's\n\t// routes — '/_admin' replaces the leading '/admin' of every path. Unset ⇒\n\t// the brick's own standalone routes under '/admin'.\n\tprefix?: 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 prefix: string | undefined;\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.prefix = opts.prefix ? normalizeMountPath(opts.prefix) : undefined;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// The path literals stay on the legacy '/admin/...' so the route table and\n\t// the coverage gate read them; the prefix is applied here at request time.\n\tprivate rebase<T extends { path: string }>(opts: T): T {\n\t\tif (!this.prefix) return opts;\n\t\treturn { ...opts, path: opts.path.replace(/^\\/admin(?=\\/|\\?|$)/, this.prefix) };\n\t}\n\n\t// ── Config ───────────────────────────────────────────────────────────────\n\n\tlistConfig(environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\tgetConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigEntry>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tdeleteConfig(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tlistConfigRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<IConfigRevision[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}/revisions${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/config/${encodeURIComponent(key)}/rollback${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\tgetSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretEntry>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tdeleteSecret(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<undefined>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\tlistSecretRevisions(key: string, environment?: string) {\n\t\treturn this.http.request<IApiResponse<ISecretRevision[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/revisions${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/rollback${envQuery(environment)}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/secrets/${encodeURIComponent(key)}/reveal${envQuery(environment)}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tAdminScope,\n\tIAdminAttention,\n\tIAdminCreatedLink,\n\tIAdminEnrollment,\n\tIAdminOperator,\n\tIAdminOperatorsReport,\n\tIAdminSecondFactor,\n\tIAdminSession,\n\tIAdminEnvironmentReport,\n\tIAdminDoctorReport,\n\tIAdminIssuedToken,\n\tIAdminIssueTokenInput,\n\tIAdminLogPage,\n\tIAdminManifest,\n\tIAdminMigrationModule,\n\tIAdminMigrationsReport,\n\tIAdminRoutesReport,\n\tIAdminTokensReport,\n\tIApiResponse,\n} from '../types';\n\nexport interface IAdminClientOptions {\n\tbaseUrl: string;\n\t// A token (machines, the CLI). Omit it in a browser signed in as an\n\t// operator: the session cookie authenticates instead.\n\tadminToken?: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminLogQuery {\n\tlimit?: number;\n\tbefore?: string;\n}\n\n// Deliberately not on FonderieClient: no user session can reach this surface.\nexport class AdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string | undefined;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate get<T>(suffix: string) {\n\t\treturn this.call<T>('GET', suffix);\n\t}\n\n\tprivate call<T>(method: string, suffix: string, body?: unknown) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t\t...(body !== undefined ? { body } : {}),\n\t\t});\n\t}\n\n\tattention() {\n\t\treturn this.get<IAdminAttention>('');\n\t}\n\n\tmanifest() {\n\t\treturn this.get<IAdminManifest>('/manifest');\n\t}\n\n\tdoctor() {\n\t\treturn this.get<IAdminDoctorReport>('/doctor');\n\t}\n\n\tenvironment() {\n\t\treturn this.get<IAdminEnvironmentReport>('/environment');\n\t}\n\n\troutes() {\n\t\treturn this.get<IAdminRoutesReport>('/routes');\n\t}\n\n\ttokens() {\n\t\treturn this.get<IAdminTokensReport>('/access/tokens');\n\t}\n\n\tadminLog(query: IAdminLogQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.before) q.set('before', query.before);\n\t\tconst qs = q.toString();\n\t\treturn this.get<IAdminLogPage>(`/activity/admin-log${qs ? `?${qs}` : ''}`);\n\t}\n\n\t// Root token only. The plaintext comes back once.\n\tissueToken(input: IAdminIssueTokenInput) {\n\t\treturn this.call<IAdminIssuedToken>('POST', '/access/tokens', input);\n\t}\n\n\t// Root token only.\n\trevokeToken(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/access/tokens/${encodeURIComponent(id)}`);\n\t}\n\n\t// What each module is waiting on, with every pending file's impact. Empty\n\t// when the deployment did not hand its migration sequence to the surface.\n\tmigrations() {\n\t\treturn this.get<IAdminMigrationsReport>('/migrations');\n\t}\n\n\t/**\n\t * Apply one module's pending migrations — all of them, or none.\n\t *\n\t * `expect` is the pending list you were shown, in order. If it no longer\n\t * matches, the server refuses with 409 MIGRATIONS_CHANGED rather than\n\t * applying something nobody reviewed. Also refuses 409 when an earlier\n\t * module is behind, and 422 when any pending file deletes data.\n\t */\n\tapplyMigrations(module: string, expect: readonly string[]) {\n\t\treturn this.call<IAdminMigrationModule>(\n\t\t\t'POST',\n\t\t\t`/migrations/${encodeURIComponent(module)}/apply`,\n\t\t\t{ expect },\n\t\t);\n\t}\n\t// ── operator sign-in (the served console's gate) ──────────────────────\n\t// Cookie-based: the server sets an HttpOnly session cookie; nothing here\n\t// ever holds it. Omit adminToken on this client — except for claim().\n\n\t/** Who is signed in, and whether the console can still be claimed. */\n\tsession() {\n\t\treturn this.get<IAdminSession>('/session');\n\t}\n\n\t/** The one-time claim. Needs the ROOT token as this client's adminToken. */\n\tclaim(input: { email: string; password: string; name?: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/claim', input);\n\t}\n\n\tlogin(input: { email: string; password: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/login', input);\n\t}\n\n\t/** The authenticator secret and otpauth URI to scan while enrolling. */\n\tenrollment() {\n\t\treturn this.get<IAdminEnrollment>('/session/enrollment');\n\t}\n\n\t/** Confirms the first code. The response carries the backup codes, once. */\n\tconfirmEnrollment(code: string) {\n\t\treturn this.call<IAdminSession>('POST', '/session/enrollment', { code });\n\t}\n\n\t/** The second factor after the password: an authenticator code or a backup code. */\n\tverify(factor: IAdminSecondFactor) {\n\t\treturn this.call<IAdminSession>('POST', '/session/verify', factor);\n\t}\n\n\t/** A fresh code for the next five minutes of dangerous actions. */\n\tstepUp(factor: IAdminSecondFactor) {\n\t\treturn this.call<{ stepUpFresh: boolean; backupCodesLeft?: number }>(\n\t\t\t'POST',\n\t\t\t'/session/step-up',\n\t\t\tfactor,\n\t\t);\n\t}\n\n\tlogout() {\n\t\treturn this.call<undefined>('DELETE', '/session');\n\t}\n\n\t/** What an invite or recovery link is for, before setting a password. */\n\tinspectLink(token: string) {\n\t\treturn this.call<{ kind: 'invite' | 'recovery'; email: string }>(\n\t\t\t'POST',\n\t\t\t'/session/link/inspect',\n\t\t\t{ token },\n\t\t);\n\t}\n\n\tredeemLink(input: { token: string; password: string; name?: string }) {\n\t\treturn this.call<IAdminSession>('POST', '/session/link', input);\n\t}\n\n\t// ── managing operators ─────────────────────────────────────────────────\n\n\toperators() {\n\t\treturn this.get<IAdminOperatorsReport>('/access/operators');\n\t}\n\n\t/** An invite link, shown once. Needs the highest scope and a fresh code. */\n\tinviteOperator(input: { email: string; scopes: AdminScope[]; expiresInHours?: number }) {\n\t\treturn this.call<IAdminCreatedLink>('POST', '/access/operators/invites', input);\n\t}\n\n\t/** Lost password or authenticator: a single-use link; signs them out everywhere. */\n\trecoverOperator(id: string) {\n\t\treturn this.call<IAdminCreatedLink>(\n\t\t\t'POST',\n\t\t\t`/access/operators/${encodeURIComponent(id)}/recovery`,\n\t\t);\n\t}\n\n\tupdateOperator(id: string, input: { scopes?: AdminScope[]; name?: string; disabled?: boolean }) {\n\t\treturn this.call<IAdminOperator>('PUT', `/access/operators/${encodeURIComponent(id)}`, input);\n\t}\n\n\trevokeOperatorLink(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/access/operators/links/${encodeURIComponent(id)}`);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tIAdminUserDTO,\n\tIAdminUserPageResult,\n\tIApiResponse,\n\tILoginHistoryPageResult,\n\tISessionDTO,\n} from '../types';\n\nexport interface IAuthAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminLoginHistoryQuery {\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface IAdminUsersQuery {\n\tlimit?: number;\n\tcursor?: string;\n\t// true ⇒ only soft-deleted accounts (not yet purged).\n\tdeleted?: boolean;\n}\n\n// @fonderie/auth's operator routes, which exist only through @fonderie/admin.\n// Deliberately not on FonderieClient: no user session can reach them.\nexport class AuthAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAuthAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate call<T>(method: string, suffix: string) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}/users${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n\n\t// A page of users, newest first. The same route as findUser — with an email\n\t// it looks one up, without one it lists.\n\tlistUsers(query: IAdminUsersQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tif (query.deleted) q.set('deleted', '1');\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminUserPageResult>('GET', qs ? `?${qs}` : '');\n\t}\n\n\tfindUser(email: string) {\n\t\treturn this.call<IAdminUserDTO>('GET', `?email=${encodeURIComponent(email)}`);\n\t}\n\n\tgetUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('GET', `/${encodeURIComponent(id)}`);\n\t}\n\n\tlistUserSessions(id: string) {\n\t\treturn this.call<ISessionDTO[]>('GET', `/${encodeURIComponent(id)}/sessions`);\n\t}\n\n\t// Signs the user out everywhere.\n\trevokeUserSessions(id: string) {\n\t\treturn this.call<undefined>('DELETE', `/${encodeURIComponent(id)}/sessions`);\n\t}\n\n\tuserLoginHistory(id: string, query: IAdminLoginHistoryQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<ILoginHistoryPageResult>(\n\t\t\t'GET',\n\t\t\t`/${encodeURIComponent(id)}/login-history${qs ? `?${qs}` : ''}`,\n\t\t);\n\t}\n\n\tsuspendUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('POST', `/${encodeURIComponent(id)}/suspend`);\n\t}\n\n\tunsuspendUser(id: string) {\n\t\treturn this.call<IAdminUserDTO>('POST', `/${encodeURIComponent(id)}/unsuspend`);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tIAdminCatalog,\n\tIAdminGrantInput,\n\tIAdminPlanInput,\n\tIAdminSubscriptionDTO,\n\tIAdminSubscriptionPage,\n\tIAdminWalletDTO,\n\tIAdminWalletLedgerPage,\n\tIApiResponse,\n\tIPlanDTO,\n\tSubscriberType,\n} from '../types';\n\nexport interface IBillingAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\nexport interface IAdminSubscriptionsQuery {\n\tlimit?: number;\n\tcursor?: string;\n}\n\nexport interface IAdminLedgerQuery {\n\tcurrency?: string;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// @fonderie/billing's operator routes, which exist only through @fonderie/admin.\n// Deliberately not on FonderieClient: no user session can reach them.\nexport class BillingAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IBillingAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\tprivate call<T>(method: string, suffix: string, body?: unknown) {\n\t\treturn this.http.request<IApiResponse<T>>({\n\t\t\tmethod,\n\t\t\tpath: `${this.prefix}${suffix}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t\t...(body !== undefined ? { body } : {}),\n\t\t});\n\t}\n\n\tprivate sub(type: SubscriberType, id: string) {\n\t\treturn `/${type}/${encodeURIComponent(id)}`;\n\t}\n\n\tcatalog() {\n\t\treturn this.call<IAdminCatalog>('GET', '/catalog');\n\t}\n\n\tcreatePlan(input: IAdminPlanInput & { name: string }) {\n\t\treturn this.call<IPlanDTO>('POST', '/plans', input);\n\t}\n\n\tupdatePlan(planId: string, input: IAdminPlanInput) {\n\t\treturn this.call<IPlanDTO>('PUT', `/plans/${encodeURIComponent(planId)}`, input);\n\t}\n\n\tdeletePlan(planId: string) {\n\t\treturn this.call<undefined>('DELETE', `/plans/${encodeURIComponent(planId)}`);\n\t}\n\n\t// A page of subscribers, newest first. The lookup below still answers for a\n\t// known subscriber; this is for finding one you cannot name.\n\tlistSubscriptions(query: IAdminSubscriptionsQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminSubscriptionPage>('GET', `/subscriptions${qs ? `?${qs}` : ''}`);\n\t}\n\n\tsubscription(type: SubscriberType, id: string) {\n\t\treturn this.call<IAdminSubscriptionDTO>('GET', `/subscriptions${this.sub(type, id)}`);\n\t}\n\n\twallet(type: SubscriberType, id: string, currency?: string) {\n\t\tconst qs = currency ? `?currency=${encodeURIComponent(currency)}` : '';\n\t\treturn this.call<IAdminWalletDTO>('GET', `/wallet${this.sub(type, id)}${qs}`);\n\t}\n\n\twalletLedger(type: SubscriberType, id: string, query: IAdminLedgerQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.currency) q.set('currency', query.currency);\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.call<IAdminWalletLedgerPage>(\n\t\t\t'GET',\n\t\t\t`/wallet${this.sub(type, id)}/ledger${qs ? `?${qs}` : ''}`,\n\t\t);\n\t}\n\n\t// Manual credit — an idempotency key is required by the server.\n\tgrant(input: IAdminGrantInput) {\n\t\treturn this.call<unknown>('POST', '/wallet/grant', input);\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type { IApiResponse, IAuditPageResult } from '../types';\n\nexport interface IAuditAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where AdminModule was mounted, relative to baseUrl. Default '/_admin'.\n\tprefix?: string;\n\t// Recorded as X-Actor in the admin log.\n\tactor?: string;\n}\n\n// The workspace-scoped filters, plus the workspace itself as a filter.\nexport interface IAdminAuditQuery {\n\tworkspaceId?: string;\n\ttype?: string;\n\tactorId?: string;\n\tfrom?: Date;\n\tto?: Date;\n\tlimit?: number;\n\tcursor?: string;\n}\n\n// @fonderie/audit's operator read, which exists only through @fonderie/admin.\nexport class AuditAdminClient {\n\tprivate http: HttpClient;\n\tprivate adminToken: string;\n\tprivate prefix: string;\n\tprivate actorHeaders: Record<string, string> | undefined;\n\n\tconstructor(opts: IAuditAdminClientOptions) {\n\t\tthis.http = new HttpClient(opts.baseUrl);\n\t\tthis.adminToken = opts.adminToken;\n\t\tthis.prefix = normalizeMountPath(opts.prefix ?? '/_admin');\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// Every workspace unless one is named. Newest first, keyset-paged.\n\tlistAudit(query: IAdminAuditQuery = {}) {\n\t\tconst q = new URLSearchParams();\n\t\tif (query.workspaceId) q.set('workspaceId', query.workspaceId);\n\t\tif (query.type) q.set('type', query.type);\n\t\tif (query.actorId) q.set('actorId', query.actorId);\n\t\tif (query.from) q.set('from', query.from.toISOString());\n\t\tif (query.to) q.set('to', query.to.toISOString());\n\t\tif (query.limit) q.set('limit', String(query.limit));\n\t\tif (query.cursor) q.set('cursor', query.cursor);\n\t\tconst qs = q.toString();\n\t\treturn this.http.request<IApiResponse<IAuditPageResult>>({\n\t\t\tmethod: 'GET',\n\t\t\tpath: `${this.prefix}/audit${qs ? `?${qs}` : ''}`,\n\t\t\ttoken: this.adminToken,\n\t\t\theaders: this.actorHeaders,\n\t\t});\n\t}\n}\n","import { HttpClient } from '../http';\nimport { normalizeMountPath } from '../path';\nimport type {\n\tIApiResponse,\n\tIBuiltInTemplate,\n\tITemplateCatalog,\n\tITemplateEntry,\n\tITemplateResolution,\n\tITemplateRevision,\n} 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 IPreviewTemplateInput {\n\ttext: string;\n\tsubject?: string;\n\thtml?: string;\n\t// Values for the template's {{variables}}. Omitted, every variable renders\n\t// empty and every {{#section}} collapses — accurate for layout, misleading\n\t// about content.\n\tdata?: Record<string, unknown>;\n}\n\n// What the renderer produced: no `html` key at all for a text-only template.\nexport interface IRenderedTemplateResult {\n\tsubject?: string;\n\thtml?: string;\n\ttext: string;\n\t// Every {{variable}} this content refers to, reported by the server so the\n\t// editor can offer the right fields without re-implementing the contract.\n\tvariables: string[];\n}\n\nexport interface ICourierAdminClientOptions {\n\tbaseUrl: string;\n\tadminToken: string;\n\t// Where the composed surface lives when @fonderie/admin mounts this brick's\n\t// routes — '/_admin' replaces the leading '/admin' of every path. Unset ⇒\n\t// the brick's own standalone routes under '/admin'.\n\tprefix?: 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 prefix: string | undefined;\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.prefix = opts.prefix ? normalizeMountPath(opts.prefix) : undefined;\n\t\tthis.actorHeaders = opts.actor ? { 'X-Actor': opts.actor } : undefined;\n\t}\n\n\t// The path literals stay on the legacy '/admin/...' so the route table and\n\t// the coverage gate read them; the prefix is applied here at request time.\n\tprivate rebase<T extends { path: string }>(opts: T): T {\n\t\tif (!this.prefix) return opts;\n\t\treturn { ...opts, path: opts.path.replace(/^\\/admin(?=\\/|\\?|$)/, this.prefix) };\n\t}\n\n\tlistTemplates() {\n\t\treturn this.http.request<IApiResponse<ITemplateEntry[]>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: '/admin/templates',\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Every email — saved or built-in only — with its languages and the app's\n\t// locales. The flat listTemplates() only sees saved rows.\n\tgetTemplateCatalog() {\n\t\treturn this.http.request<IApiResponse<ITemplateCatalog>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: '/admin/template-catalog',\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Fonderie's own copy in a language (omitted: the English default). 404 when\n\t// none ships in that language.\n\tgetBuiltInTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<IBuiltInTemplate>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/built-in${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Who receives what: decided server-side by the same function a real send\n\t// runs, so the answer cannot drift from delivery.\n\tresolveTemplate(type: string, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<ITemplateResolution>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/resolve${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'PUT',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'GET',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/revisions${q}`,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t}),\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\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/rollback${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Renders content you are HOLDING, not what is stored — so an editor can\n\t// show the change before it is saved. Server-side on purpose: the shell and\n\t// the variable substitution are the resolver's, and a preview rendered any\n\t// other way would not be the mail that sends.\n\tpreviewTemplate(type: string, input: IPreviewTemplateInput, locale?: string | null) {\n\t\tconst q = locale ? `?locale=${encodeURIComponent(locale)}` : '';\n\t\treturn this.http.request<IApiResponse<IRenderedTemplateResult>>(\n\t\t\tthis.rebase({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tpath: `/admin/templates/${encodeURIComponent(type)}/preview${q}`,\n\t\t\t\tbody: input,\n\t\t\t\ttoken: this.adminToken,\n\t\t\t\theaders: this.actorHeaders,\n\t\t\t}),\n\t\t);\n\t}\n}\n","import type { ITemplateCatalog, ITemplateCatalogEntry, ITemplateEntry } from './types';\n\n// The template store keys rows by (type, locale), and the list endpoint returns\n// them flat. An operator thinks in emails, not rows: \"welcome, in English,\n// French and Spanish\". These helpers give every console the same grouping, so\n// the React and Vue screens cannot disagree about order or suggestions.\n\n/** One email and every locale it exists in. */\nexport interface ITemplateGroup {\n\ttype: string;\n\t/** Default locale (null) first, then the rest alphabetically. */\n\tentries: ITemplateEntry[];\n\t/** The entry a click on the email itself should open: the default, else the first. */\n\tprimary: ITemplateEntry;\n\t/** Built-in email (its default-locale row can never be deleted). */\n\tsystem: boolean;\n}\n\nconst byLocale = (a: ITemplateEntry, b: ITemplateEntry): number =>\n\ta.locale === b.locale ? 0 : a.locale === null ? -1 : b.locale === null ? 1 : a.locale.localeCompare(b.locale);\n\n/** Rows grouped by type, types in the order the server listed them. */\nexport function groupTemplatesByType(rows: readonly ITemplateEntry[]): ITemplateGroup[] {\n\tconst groups = new Map<string, ITemplateEntry[]>();\n\tfor (const row of rows) {\n\t\tconst entries = groups.get(row.type);\n\t\tif (entries) entries.push(row);\n\t\telse groups.set(row.type, [row]);\n\t}\n\treturn [...groups].map(([type, entries]) => {\n\t\tentries.sort(byLocale);\n\t\tconst primary = entries[0] as ITemplateEntry;\n\t\treturn { type, entries, primary, system: entries.some((e) => e.system === true) };\n\t});\n}\n\n/**\n * Locales the app already uses elsewhere that `type` has no version in yet —\n * what \"Add locale\" should suggest first. A French welcome email with no French\n * receipt is exactly the gap an operator is looking for.\n */\nexport function missingTemplateLocales(rows: readonly ITemplateEntry[], type: string): string[] {\n\tconst has = new Set(rows.filter((r) => r.type === type).map((r) => r.locale));\n\tconst used = new Set(rows.map((r) => r.locale).filter((l): l is string => l !== null && !has.has(l)));\n\treturn [...used].sort();\n}\n\n// ── From the catalog (saved AND built-in) ─────────────────────────────────\n\n/** One language an email exists in, as the console shows it. */\nexport interface ITemplateLanguage {\n\t/** What to open: null is the default version. */\n\tlocale: string | null;\n\t/** What to show: the default version is labelled with the system locale. */\n\tlabel: string;\n\t/** The app saved this version (else it is Fonderie's built-in copy, untouched). */\n\tsaved: boolean;\n\t/** Fonderie ships this language. */\n\tbuiltIn: boolean;\n\t/** A saved version switched off is skipped when sending. Built-in copy is always on. */\n\tactive: boolean;\n}\n\n/**\n * Every language one email exists in, sorted by label — the default version\n * shown as the system locale ('en-US'), then e.g. 'es', 'fr', 'fr-CA'. A saved\n * version and the built-in copy of the same language are one entry: the saved\n * one is what sends.\n */\nexport function templateLanguages(email: ITemplateCatalogEntry, defaultLocale: string): ITemplateLanguage[] {\n\tconst out = new Map<string, ITemplateLanguage>();\n\tconst saved = new Map(email.versions.map((v) => [v.locale, v]));\n\tconst base = saved.get(null);\n\tif (base || email.builtIn.default) {\n\t\tout.set('', {\n\t\t\tlocale: null,\n\t\t\tlabel: defaultLocale,\n\t\t\tsaved: Boolean(base),\n\t\t\tbuiltIn: email.builtIn.default,\n\t\t\tactive: base ? base.active : true,\n\t\t});\n\t}\n\tfor (const lang of email.builtIn.languages) {\n\t\tconst own = saved.get(lang);\n\t\tout.set(lang, { locale: lang, label: lang, saved: Boolean(own), builtIn: true, active: own ? own.active : true });\n\t}\n\tfor (const v of email.versions) {\n\t\tif (v.locale === null || out.has(v.locale)) continue;\n\t\tout.set(v.locale, { locale: v.locale, label: v.locale, saved: true, builtIn: false, active: v.active });\n\t}\n\treturn [...out.values()].sort((a, b) => a.label.localeCompare(b.label));\n}\n\n/**\n * What \"Add locale\" should suggest for `type`: locales the app already uses on\n * other emails (saved or built-in) that this one lacks. Never the system locale\n * — the default version already is that locale.\n */\nexport function suggestTemplateLocales(catalog: ITemplateCatalog, type: string): string[] {\n\tconst email = catalog.emails.find((e) => e.type === type);\n\tconst has = new Set(email ? templateLanguages(email, catalog.defaultLocale).map((l) => l.label) : []);\n\tconst used = new Set<string>();\n\tfor (const e of catalog.emails) {\n\t\tfor (const l of templateLanguages(e, catalog.defaultLocale)) {\n\t\t\tif (l.locale !== null && !has.has(l.label)) used.add(l.label);\n\t\t}\n\t}\n\treturn [...used].sort();\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\t// OAuth provider linked to this account ('google', 'apple'), or '' if none.\n\tprovider: string;\n\t// Whether a password is set. With `provider`, this is what a settings screen\n\t// needs to render sign-in methods and to know whether unlinkOauth() can\n\t// succeed — an account with no password has no other credential, so the\n\t// server refuses (409 PASSWORD_REQUIRED) rather than locking the user out.\n\thasPassword: 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\n/** What GET /auth/providers answers: the sign-in methods this API can honour. */\nexport interface IAuthProvidersResult {\n\tproviders: string[];\n}\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(\n\tresult: ILoginResult | IMfaRequiredResult,\n): 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// Wallet balance snapshot. Money fields are digit strings (server bigint →\n// string); spendPurchased is a real boolean. granted/purchased/spendPurchased/\n// grantedExpiresAt are omitted on a legacy read that predates the bucket split.\nexport interface IWalletDTO {\n\tbalance: string;\n\tcurrency: string;\n\tprecision: number;\n\tgranted?: string;\n\tpurchased?: string;\n\tspendPurchased?: boolean;\n\tgrantedExpiresAt?: string | null;\n}\n\nexport interface IWalletResult {\n\twallet: IWalletDTO;\n}\n\n// One wallet ledger entry. Money fields are digit strings (server bigint →\n// string); `balanceAfter` is the running balance, so a history UI can show a\n// trustworthy per-row balance without re-deriving it.\nexport interface IWalletTransactionDTO {\n\tid: string;\n\ttype: string; // 'purchase' | 'grant' | 'usage' | 'refund' | 'adjustment' | 'expiry'\n\tamount: string; // signed: positive = credit, negative = debit\n\tbalanceAfter: string;\n\tcurrency: string;\n\tdescription: string | null;\n\tproviderTxId: string | null;\n\tmetadata: Record<string, unknown>;\n\tcreatedAt: string;\n}\n\nexport interface IWalletTransactionsResult {\n\ttransactions: IWalletTransactionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IWalletCheckoutInput {\n\tpackId: string;\n}\n\nexport interface IWalletPurchaseInput {\n\tpackId: string;\n\t// One per purchase attempt, REUSED on retry: a double-submit or a retry after\n\t// a `processing` result dedupes to the same charge instead of charging twice.\n\tidempotencyKey: string;\n}\n\n// Outcome of an in-app pack purchase charged to the saved card. `status` is the\n// discriminator: 'credited' carries the new balance; 'checkout_required' means\n// fall back to createWalletCheckout (no saved card, or the card needs 3-D\n// Secure); 'declined' is a hard decline; 'processing' is indeterminate — retry\n// with the SAME idempotencyKey (never a fresh hosted checkout, or you'd risk a\n// double-charge).\nexport interface IWalletPurchaseResult {\n\tstatus: 'credited' | 'checkout_required' | 'declined' | 'processing';\n\tbalance?: string;\n\tcurrency?: string;\n\tcredits?: string;\n\tduplicate?: boolean;\n\treason?: 'no_saved_card' | 'authentication_required';\n}\n\nexport interface ICancelSubscriptionInput {\n\t// Default true — keep access until the paid-through date. false ends it now.\n\tatPeriodEnd?: boolean;\n}\n\n// Result of a first-party cancel/reactivate — the subscription's new lifecycle\n// state, read straight back without waiting for the provider webhook.\nexport interface ISubscriptionChangeResult {\n\tatPeriodEnd: boolean;\n\tstatus: string;\n\tcurrentPeriodEnd: string | null;\n}\n\n// The customer's card on file, for display. Never carries the full number —\n// nor the server-side card `fingerprint`, which billing deliberately keeps\n// off the wire (it correlates identity across accounts).\nexport interface IPaymentMethodDTO {\n\tbrand: string;\n\tlast4: string;\n\texpMonth: number;\n\texpYear: number;\n}\n\nexport interface IPaymentMethodResult {\n\tpaymentMethod: IPaymentMethodDTO | null;\n}\n\n// Begin in-app card entry: the provider SetupIntent client secret the embedded\n// card element (Stripe Payment Element) confirms — no hosted-checkout redirect.\nexport interface ISetupIntentResult {\n\tclientSecret: string;\n}\n\n// Save a card after the client confirms the SetupIntent — the provider payment\n// method id the Payment Element produced.\nexport interface ISavePaymentMethodInput {\n\tpaymentMethodId: string;\n}\n\n// One invoice for an in-app history list; `hostedInvoiceUrl`/`invoicePdf` link\n// out to the provider. Amounts are digit strings (smallest currency unit).\nexport interface IInvoiceDTO {\n\tid: string;\n\tnumber: string | null;\n\tamountDue: string;\n\tamountPaid: string;\n\tcurrency: string;\n\tstatus: string;\n\tcreated: string;\n\tdueDate: string | null; // ISO-8601 when the invoice has payment terms; null when paid on charge\n\thostedInvoiceUrl: string | null;\n\tinvoicePdf: string | null;\n}\n\nexport interface IInvoicesResult {\n\tinvoices: IInvoiceDTO[];\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\n// Every email the app can send — saved or built-in only — with the languages it\n// exists in. GET /admin/template-catalog.\nexport interface ITemplateCatalog {\n\t/** The system locale: the default (untagged) version is written in it. */\n\tdefaultLocale: string;\n\t/** Per market or language, where its content comes from, before the system locale. */\n\tfallbacks: Record<string, string[]>;\n\temails: ITemplateCatalogEntry[];\n}\n\nexport interface ITemplateCatalogEntry {\n\ttype: string;\n\t/** Built-in email: its default version can be edited and rolled back, never deleted. */\n\tsystem: boolean;\n\t/** What Fonderie ships: the English default, and the other languages. */\n\tbuiltIn: { default: boolean; languages: string[] };\n\t/** The app's saved versions (locale null = the default version). */\n\tversions: Array<{ locale: string | null; active: boolean; version: number; updatedAt: string }>;\n}\n\n// Fonderie's own copy of an email in one language.\nexport interface IBuiltInTemplate {\n\ttype: string;\n\t/** The language key it matched ('fr' for fr-CA), or the system locale for the English. */\n\tlocale: string;\n\tsubject: string | null;\n\thtml: string | null;\n\ttext: string;\n}\n\n// Who receives what: the version a send in `requested` would use.\nexport interface ITemplateResolution {\n\trequested: string;\n\t/** Locales tried before the system locale, in order. */\n\tchain: string[];\n\tdefaultLocale: string;\n\t/** The version used: a saved tag, a built-in language, or the system locale. */\n\tsent: string;\n\tsource: 'saved' | 'built-in';\n}\n\nexport interface ITemplateEntry {\n\t// A built-in email's default-locale row: edit and roll back, never delete.\n\t// Present on list results from @fonderie/courier ≥ the system-template release.\n\tsystem?: boolean;\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// ── Admin (the operator's surface) ───────────────────────────────────────────\n// Admin-token authenticated — see AdminClient. Shapes mirror @fonderie/admin's\n// pages; the client owns its copies, like every other section here.\n\nexport interface IAdminReadinessProblem {\n\tmodule: string;\n\tseverity: 'error' | 'warning';\n\tmessage: string;\n}\n\nexport interface IAdminReadiness {\n\tok: boolean;\n\tproblems: IAdminReadinessProblem[];\n}\n\nexport interface IAdminModuleEntry {\n\tname: string;\n\tversion: string | null;\n\treadiness: IAdminReadiness;\n\tdescribesAdmin: boolean;\n}\n\nexport interface IAdminRouteEntry {\n\tmethod: string;\n\tpath: string;\n\tmodule?: string;\n}\n\nexport interface IAdminManifest {\n\tgeneratedAt: string;\n\tenv: string;\n\t// `host` is null when the surface answers on any hostname.\n\tadmin: { version: string; log: boolean; host: string[] | null };\n\tmodules: IAdminModuleEntry[];\n\treadiness: IAdminReadiness;\n\troutes: IAdminRouteEntry[];\n}\n\nexport interface IAdminCheckResult {\n\tname: string;\n\tmodule: string;\n\tok: boolean;\n\tfindings: string[];\n\tskipped?: string;\n\tdurationMs: number;\n}\n\nexport interface IAdminDoctorReport {\n\tgeneratedAt: string;\n\tok: boolean;\n\tchecks: IAdminCheckResult[];\n}\n\nexport interface IAdminAttentionItem {\n\tsource: string;\n\tseverity: 'error' | 'advice';\n\tmessage: string;\n}\n\nexport interface IAdminAttention {\n\tgeneratedAt: string;\n\tok: boolean;\n\titems: IAdminAttentionItem[];\n}\n\nexport interface IAdminEnvironmentReport {\n\tgeneratedAt: string;\n\treadiness: IAdminReadiness;\n\tmodules: Array<{ name: string; problems: IAdminReadinessProblem[] }>;\n\tenv: Array<{ name: string; set: boolean }>;\n}\n\nexport type AdminRouteGuard = 'admin' | 'probe' | 'app';\n\nexport interface IAdminRoutesReport {\n\tgeneratedAt: string;\n\troutes: Array<IAdminRouteEntry & { guard: AdminRouteGuard }>;\n}\n\nexport type AdminScope = 'read' | 'write' | 'secrets';\n\n// An issued scoped token — never its hash or plaintext.\nexport interface IAdminTokenRecord {\n\tid: string;\n\tname: string;\n\tscopes: AdminScope[];\n\tcreatedBy: string;\n\tcreatedAt: string;\n\texpiresAt: string | null;\n\trevokedAt: string | null;\n\tlastUsedAt: string | null;\n}\n\nexport interface IAdminTokensReport {\n\tgeneratedAt: string;\n\tadmin: { ok: boolean; problems: IAdminReadinessProblem[] };\n\tlegacy: Array<{ module: string; set: boolean }>;\n\t// null when the deployment gave AdminModule no store (issuing is off).\n\tissued: IAdminTokenRecord[] | null;\n}\n\nexport interface IAdminIssueTokenInput {\n\tname: string;\n\tscopes: AdminScope[];\n\texpiresInDays?: number;\n}\n\n// The plaintext is returned once, at issue, and never again.\nexport interface IAdminIssuedToken extends IAdminTokenRecord {\n\ttoken: string;\n}\n\n// ── operators: people who sign in to the admin console ──────────────────\n\n// What the API ever says about an operator — never a hash, secret or code.\nexport interface IAdminOperator {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\tscopes: AdminScope[];\n\t// false until they have scanned the QR code and confirmed a code.\n\tenrolled: boolean;\n\tbackupCodesLeft: number;\n\tlocked: boolean;\n\tcreatedBy: string;\n\tcreatedAt: string;\n\tlastLoginAt: string | null;\n\tdisabledAt: string | null;\n}\n\n// A pending single-use link: an invite, or a recovery for a locked-out operator.\nexport interface IAdminOperatorLink {\n\tid: string;\n\tkind: 'invite' | 'recovery';\n\temail: string;\n\tscopes: AdminScope[];\n\tcreatedBy: string;\n\tcreatedAt: string;\n\texpiresAt: string;\n}\n\nexport interface IAdminOperatorsReport {\n\toperators: IAdminOperator[];\n\tlinks: IAdminOperatorLink[];\n}\n\n// Returned once: the link to hand to the person. `url` points at the console\n// with the token in the hash, so it never reaches a server log.\nexport interface IAdminCreatedLink {\n\tid: string;\n\temail: string;\n\tscopes?: AdminScope[];\n\texpiresAt: string;\n\ttoken: string;\n\turl: string;\n}\n\nexport type AdminSessionState = 'signed-out' | 'needs-2fa' | 'needs-enrollment' | 'signed-in';\n\nexport interface IAdminSession {\n\tstate: AdminSessionState;\n\toperator: IAdminOperator | null;\n\t// true only while no operator exists yet: the root token can claim the console.\n\tclaimable?: boolean;\n\tstepUpFresh?: boolean;\n\t// Present once, right after enrollment. Show them; they are never shown again.\n\tbackupCodes?: string[];\n\t// After signing in with a backup code: how many remain.\n\tbackupCodesLeft?: number;\n}\n\nexport interface IAdminEnrollment {\n\tsecret: string;\n\t// otpauth:// — render as a QR code.\n\turi: string;\n\taccount: string;\n\tissuer: string;\n}\n\nexport type IAdminSecondFactor = { code: string } | { backupCode: string };\n\nexport interface IAdminLogEntry {\n\tid: string;\n\tat: string;\n\tactor: string;\n\tmethod: string;\n\tpath: string;\n\troute: string;\n\tmodule: string;\n\tstatus: number;\n\tdurationMs: number;\n\trequestId: string | null;\n\tclientIp: string | null;\n}\n\nexport interface IAdminLogPage {\n\tentries: IAdminLogEntry[];\n\tnext: string | null;\n}\n\n// The operator's view of a user (@fonderie/auth's described admin routes):\n// the app's own DTO plus what support asks about. Never a hash or MFA secret.\nexport interface IAdminUserDTO extends IUserDTO {\n\tdeletedAt: string | null;\n}\n\n// The operator's money reads (@fonderie/billing's described admin routes).\nexport interface IAdminCatalog {\n\t// config.plans as declared; bigint wallet amounts arrive as strings.\n\tconfigured: unknown[];\n\tstored: IPlanDTO[];\n}\n\nexport interface IAdminSubscriptionDTO {\n\tid: string;\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\tplan: string;\n\tinterval: string;\n\tstatus: string;\n\tproviderCustomerId: string | null;\n\tproviderSubscriptionId: string | null;\n\tcurrentPeriodStart: string | null;\n\tcurrentPeriodEnd: string | null;\n\tcancelAtPeriodEnd: boolean;\n\ttrialEndsAt: string | null;\n\tcreatedAt: string;\n}\n\nexport interface IAdminWalletDTO extends IWalletDTO {\n\tversion: number;\n\tupdatedAt: string | null;\n}\n\nexport interface IAdminSubscriptionPage {\n\tsubscriptions: IAdminSubscriptionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IAdminWalletLedgerPage {\n\tcurrency: string;\n\tentries: IWalletTransactionDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface IAdminPlanInput {\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 interface IAdminGrantInput {\n\tsubscriberType: SubscriberType;\n\tsubscriberId: string;\n\t// Minor units as a digit string (or a number below 2^53).\n\tamount: string | number;\n\tcurrency?: string;\n\tdescription?: string;\n\tidempotencyKey: 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// ── Login activity (auth security surfaces) ──────────────────────────────────\n// Session-authenticated; the caller's own history + sessions (shares the\n// AuthClient token). Login history is append-only; sessions are the live list.\n\n/** Where an auth event (login attempt, registration, session) came from. Present only when the server configures a\n * location resolver; every field is optional. Country is reliable; region and\n * city are approximate; network fields appear only with an IP-intelligence\n * provider. */\nexport interface IRequestLocationDTO {\n\tcountry?: string; // ISO-3166-1 alpha-2\n\tcountryName?: string;\n\tsubdivision?: string; // ISO-3166-2 region part\n\tsubdivisionName?: string;\n\tcity?: string;\n\tpostalCode?: string; // ZIP / postal code, approximate — not shown by describeLocation\n\tcontinent?: string;\n\ttimeZone?: string;\n\tlatitude?: number;\n\tlongitude?: number;\n\taccuracyRadius?: number; // km — how approximate the point is\n\tgeonameId?: number; // stable, language-neutral place key (GeoNames)\n\tisp?: string;\n\torg?: string;\n\tasn?: string;\n\tmobile?: boolean;\n\tproxy?: boolean;\n\thosting?: boolean;\n}\n\n/**\n * One short line for a login location: \"Mountain View, CA, US\" — most specific first,\n * skipping what is unknown. Pass a country-name formatter to localise the\n * country (e.g. Intl.DisplayNames). null when nothing is known.\n */\nexport function describeLocation(\n\tloc: IRequestLocationDTO | null | undefined,\n\tcountryName?: (code: string) => string | undefined,\n): string | null {\n\tif (!loc) return null;\n\tconst country = loc.country\n\t\t? (countryName?.(loc.country) ?? loc.country)\n\t\t: (loc.countryName ?? undefined);\n\tconst parts = [loc.city, loc.subdivision ?? loc.subdivisionName, country].filter(\n\t\t(p): p is string => typeof p === 'string' && p.length > 0,\n\t);\n\treturn parts.length > 0 ? parts.join(', ') : null;\n}\n\nexport interface ILoginEventDTO {\n\tid: string;\n\tmethod: string;\n\toutcome: string;\n\tfailureReason: string | null;\n\tipAddress: string | null;\n\tuserAgent: string | null;\n\t/** null when the server has no location resolver, or it knew nothing. */\n\tlocation: IRequestLocationDTO | null;\n\tcreatedAt: string;\n}\n\nexport interface IAdminUserPageResult {\n\tusers: IAdminUserDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface ILoginHistoryPageResult {\n\tevents: ILoginEventDTO[];\n\tnextCursor: string | null;\n}\n\nexport interface ISessionDTO {\n\tid: string;\n\tcurrent: boolean;\n\tipAddress: string | null;\n\tuserAgent: string | null;\n\t/** Where the session was opened from; null without a server-side resolver. */\n\tlocation: IRequestLocationDTO | null;\n\tcreatedAt: string;\n\texpiresAt: string;\n}\n\nexport interface ISessionsResult {\n\tsessions: ISessionDTO[];\n}\n\n// ── Media ────────────────────────────────────────────────────────────────────\n// Session-authenticated image storage (avatars, logos). `url` is the\n// monomorphic, backend-relative /media/:id path; call client.media.assetUrl(id)\n// for an absolute `<img src>`.\n\nexport interface IMediaAssetDTO {\n\tid: string;\n\turl: string;\n\tcontentType: string;\n\tbyteSize: number;\n\townerType: string;\n\townerId: string;\n\tpurpose: string;\n\tcreatedAt: string;\n}\n\nexport interface IMediaAssetResult {\n\tasset: IMediaAssetDTO;\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\n// ---- admin: migrations ----------------------------------------------------\n\nexport type MigrationImpact = 'additive' | 'destructive';\n\nexport interface IAdminPendingMigration {\n\tfile: string;\n\timpact: MigrationImpact;\n\t// The statements that earned a 'destructive' label, as written.\n\tdestructive: string[];\n}\n\nexport interface IAdminMigrationModule {\n\tname: string;\n\tpending: IAdminPendingMigration[];\n\t// The first EARLIER module that is behind, or null. Migration order is the\n\t// app's and sets depend on each other across it.\n\tblockedBy: string | null;\n\t// Whether the panel will apply this one: something to do, nothing in front\n\t// of it, and nothing in it that deletes data.\n\tappliable: boolean;\n}\n\nexport interface IAdminMigrationsReport {\n\t// False when the database has no fonderie_migrations rows — a first\n\t// install, where \"destructive\" has nothing to destroy.\n\teverApplied: boolean;\n\tmodules: IAdminMigrationModule[];\n}\n","// Typed config values for admin UIs (and, later, feature-flag hooks).\n//\n// Config values are stored as JSON, so a stored `true` stays a boolean and `3`\n// stays a number. What an editor needs on top is: which input to show for a\n// value, and how to turn what the operator typed back into a typed value —\n// with an explanation, not a silent failure, when it doesn't parse.\n\nexport type ConfigValueType = 'string' | 'number' | 'boolean' | 'json';\n\nexport const CONFIG_VALUE_TYPES: readonly ConfigValueType[] = ['string', 'number', 'boolean', 'json'];\n\n/** The editor type for a stored value. Objects, arrays and null are JSON. */\nexport function configValueType(value: unknown): ConfigValueType {\n\tif (typeof value === 'string') return 'string';\n\tif (typeof value === 'number') return 'number';\n\tif (typeof value === 'boolean') return 'boolean';\n\treturn 'json';\n}\n\n/** What an input should show for a stored value of that type. */\nexport function formatConfigValue(value: unknown, type: ConfigValueType = configValueType(value)): string {\n\tif (type === 'string') return typeof value === 'string' ? value : String(value ?? '');\n\tif (type === 'number') return typeof value === 'number' ? String(value) : '';\n\tif (type === 'boolean') return value === true ? 'true' : 'false';\n\treturn JSON.stringify(value ?? null, null, 2);\n}\n\nexport type CastResult = { ok: true; value: unknown } | { ok: false; error: string };\n\n/**\n * Turn what an operator typed into the typed value to store.\n * - string: kept verbatim (an empty string is a valid value)\n * - number: finite numbers only — \"1e3\" and \"-2.5\" are fine, \"12px\" is not\n * - boolean: true/false, also 1/0, yes/no, on/off (case-insensitive)\n * - json: any valid JSON\n */\nexport function castConfigValue(type: ConfigValueType, raw: string): CastResult {\n\tif (type === 'string') return { ok: true, value: raw };\n\tconst t = raw.trim();\n\tif (type === 'number') {\n\t\tif (t === '') return { ok: false, error: 'Enter a number.' };\n\t\tconst n = Number(t);\n\t\treturn Number.isFinite(n) ? { ok: true, value: n } : { ok: false, error: `\"${raw}\" is not a number.` };\n\t}\n\tif (type === 'boolean') {\n\t\tconst v = t.toLowerCase();\n\t\tif (['true', '1', 'yes', 'on'].includes(v)) return { ok: true, value: true };\n\t\tif (['false', '0', 'no', 'off'].includes(v)) return { ok: true, value: false };\n\t\treturn { ok: false, error: 'Use true or false.' };\n\t}\n\ttry {\n\t\treturn { ok: true, value: JSON.parse(t) };\n\t} catch (err) {\n\t\treturn { ok: false, error: `Not valid JSON: ${(err as Error).message}` };\n\t}\n}\n\n/**\n * Config keys: letters, digits, `.`, `_`, `-`; must start with a letter; up to\n * 128 characters. Both styles work — `ENABLE_JOB_LISTING` and `feature.dark-mode`.\n */\nexport const CONFIG_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9._-]{0,127}$/;\n\nexport function configKeyProblem(key: string): string | null {\n\tif (!key) return 'Enter a key.';\n\treturn CONFIG_KEY_PATTERN.test(key)\n\t\t? null\n\t\t: 'Start with a letter; use letters, digits, \".\", \"_\" or \"-\" (max 128).';\n}\n\nexport interface IInferredConfigValue {\n\ttype: ConfigValueType;\n\tvalue: unknown;\n\t/** Human label for the detected shape: Text, Number, On/off, Object, List. */\n\tlabel: string;\n\t/**\n\t * True when the input could equally be meant as text — \"true\", \"42\". The\n\t * editor offers \"save as text instead\" for exactly these, and never needs\n\t * to ask about anything else.\n\t */\n\tambiguous: boolean;\n}\n\n// A number only when writing it back gives the same characters: \"42\" and\n// \"-2.5\" qualify; \"1.10\" (a version), \"0123\" (a postal code), \"1e3\" and\n// 12345678901234567890 (an ID past float precision) do not — they stay text\n// rather than being silently rewritten.\nconst PLAIN_NUMBER = /^-?(0|[1-9]\\d*)(\\.\\d+)?$/;\n\n/** Human label for a stored value's shape. */\nexport function configValueLabel(value: unknown): string {\n\tif (typeof value === 'string') return 'Text';\n\tif (typeof value === 'number') return 'Number';\n\tif (typeof value === 'boolean') return 'On/off';\n\tif (Array.isArray(value)) return 'List';\n\tif (value === null) return 'Empty';\n\treturn 'Object';\n}\n\n/**\n * Work out what an operator typed, without asking. Objects and lists (JSON\n * starting with { or [), on/off (true/false), plain numbers, and text for\n * everything else — including anything that merely resembles a number.\n */\nexport function inferConfigValue(raw: string): IInferredConfigValue {\n\tconst t = raw.trim();\n\tif (t === 'true' || t === 'false') {\n\t\treturn { type: 'boolean', value: t === 'true', label: 'On/off', ambiguous: true };\n\t}\n\tif (PLAIN_NUMBER.test(t)) {\n\t\tconst n = Number(t);\n\t\tif (Number.isFinite(n) && String(n) === t) return { type: 'number', value: n, label: 'Number', ambiguous: true };\n\t}\n\tif (t.startsWith('{') || t.startsWith('[')) {\n\t\ttry {\n\t\t\tconst parsed: unknown = JSON.parse(t);\n\t\t\tif (parsed !== null && typeof parsed === 'object') {\n\t\t\t\treturn { type: 'json', value: parsed, label: Array.isArray(parsed) ? 'List' : 'Object', ambiguous: false };\n\t\t\t}\n\t\t} catch {\n\t\t\t// not valid JSON — it is text that happens to start with a bracket\n\t\t}\n\t}\n\treturn { type: 'string', value: raw, label: 'Text', ambiguous: false };\n}\n","// English — canonical: this shape defines the keys fr and es must match.\nconst common = {\n\trefresh: 'Refresh',\n\tworking: 'Working…',\n\tloading: 'Loading…',\n\tloadMore: 'Load more',\n\tsave: 'Save',\n\tsaving: 'Saving…',\n\tcancel: 'Cancel',\n\tdelete: 'Delete',\n\tdeleting: 'Deleting…',\n\tback: 'Back',\n\topen: 'Open',\n\tcopy: 'Copy',\n\tcopied: 'Copied',\n\tdismiss: 'Dismiss',\n\tconfirm: 'Confirm',\n\tcontinue: 'Continue',\n\treload: 'Reload',\n\tsearch: 'Search',\n\tlookUp: 'Look up',\n\tfilter: 'Filter',\n\tyes: 'yes',\n\tno: 'no',\n\tnone: 'None.',\n\tnever: 'never',\n\tyou: 'you',\n\tall: 'All',\n\tallEnvironments: 'All environments',\n\tlanguage: 'Language',\n\ttheme: 'Theme',\n\tthemeSystem: 'System',\n\tthemeLight: 'Light',\n\tthemeDark: 'Dark',\n\tstatus: {\n\t\tactive: 'active',\n\t\tinactive: 'inactive',\n\t\tready: 'ready',\n\t\terror: 'error',\n\t\tadvice: 'advice',\n\t\tok: 'ok',\n\t\tfailed: 'failed',\n\t\tskipped: 'skipped',\n\t\tsuspended: 'suspended',\n\t\tdeleted: 'deleted',\n\t\tdisabled: 'disabled',\n\t\tlocked: 'locked',\n\t\tpending: 'pending',\n\t\tset: 'set',\n\t\tmissing: 'missing',\n\t\tfree: 'free',\n\t},\n};\nexport default common;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst nav = {\n\tgroups: {\n\t\ttoday: 'Today',\n\t\tsystem: 'System',\n\t\tpeople: 'People',\n\t\tmoney: 'Money',\n\t\tsettings: 'Settings',\n\t\tmessaging: 'Messaging',\n\t\tactivity: 'Activity',\n\t},\n\titems: {\n\t\tattention: 'Attention',\n\t\tmodules: 'Modules',\n\t\tenvironment: 'Environment',\n\t\tdoctor: 'Doctor',\n\t\troutes: 'Routes',\n\t\tusers: 'Users',\n\t\tcatalog: 'Catalog',\n\t\tsubscriptions: 'Subscriptions',\n\t\tsettings: 'Config & secrets',\n\t\ttemplates: 'Templates',\n\t\taudit: 'Audit',\n\t\tlog: 'Admin log',\n\t\toperators: 'Operators',\n\t\ttokens: 'Tokens',\n\t\tmigrations: 'Migrations',\n\t},\n};\nexport default nav;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst shell = {\n\topenMenu: 'Open menu',\n\tcloseMenu: 'Close menu',\n\tnavLabel: 'Admin',\n\tmissingClient: 'Pass a {client} to use this page.',\n};\nexport default shell;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst session = {\n\tsignInTitle: 'Sign in to Admin',\n\tadminToken: 'Admin token',\n\tpasteToken: 'Paste your token',\n\ttokenFoot:\n\t\t'Kept for this tab only and sent as a Bearer header — never stored on the server. A read-scoped token is enough to look around and cannot reveal secrets.',\n\ttokenRefused: 'That token was refused.',\n\tunreachable: 'Could not reach the admin surface: {error}',\n\tforgetToken: 'Forget token',\n\tsignOut: 'Sign out',\n\tgenericError: 'Something went wrong. Try again.',\n\tstepOf: 'Step {n} of {total}',\n\tsteps: {\n\t\tadminToken: 'Admin token',\n\t\taccount: 'Your account',\n\t\tauthenticator: 'Authenticator',\n\t\tbackupCodes: 'Backup codes',\n\t\tnewPassword: 'New password',\n\t},\n\tchecking: 'Checking…',\n\twelcomeTitle: \"Welcome — let's set up your console\",\n\twelcomeSubtitle:\n\t\t\"This is the first sign-in on {host}. Paste the admin token from your deployment's configuration to begin. It is needed only this once.\",\n\tcreateAccountTitle: 'Create your account',\n\tcreateAccountSubtitle:\n\t\t'From now on you sign in with this email and password, plus an authenticator app. The admin token stays for scripts and emergencies.',\n\temail: 'Email',\n\tnameOptional: 'Name (optional)',\n\tyourNameOptional: 'Your name (optional)',\n\tpassword: 'Password',\n\tnewPassword: 'New password',\n\tconfirmPassword: 'Confirm password',\n\tpasswordHint: 'At least 12 characters.',\n\tpasswordHintNext: 'At least 12 characters. You will set up an authenticator app next.',\n\tpasswordsMismatch: 'The two passwords do not match.',\n\tcreating: 'Creating…',\n\tcreateAccount: 'Create account',\n\tloginFoot:\n\t\t'There is no sign-up. Operators are invited by another operator. Locked out? Ask another operator for a recovery link.',\n\tbackupCode: 'Backup code',\n\tauthenticatorCode: 'Authenticator code',\n\tuseApp: 'Use the authenticator app instead',\n\tuseBackup: 'Use a backup code instead',\n\tenrollTitle: 'Set up your authenticator',\n\tenrollSubtitle:\n\t\t'Every sign-in to this console needs a code from an authenticator app — 1Password, Google Authenticator, Authy, or any TOTP app.',\n\tenrollScan: 'Open your authenticator app and scan this code.',\n\tenrollEnter: 'Enter the six digits it shows.',\n\tqrAlt: 'QR code for your authenticator app',\n\tcantScan: \"Can't scan? Enter a setup key instead\",\n\tpreparing: 'Preparing…',\n\tcancelSignOut: 'Cancel and sign out',\n\tcodeFromApp: 'Code from the app',\n\tverifyContinue: 'Verify and continue',\n\tbackupTitle: 'Save your backup codes',\n\tbackupSubtitle:\n\t\t'If you lose your phone, each of these signs you in once. They are shown only now.',\n\tbackupFileHeader: 'Backup codes for {host} admin',\n\tdownload: 'Download',\n\tsavedCheckbox: 'I have saved these codes somewhere safe',\n\topenConsole: 'Open the console',\n\tlinkInvalidTitle: 'This link cannot be used',\n\tcheckingLink: 'Checking your link…',\n\tjoinTitle: 'Join the admin console',\n\trecoverTitle: 'Recover your account',\n\tjoinSubtitle: 'You were invited as {email}. Choose a password, then set up an authenticator app.',\n\trecoverSubtitle: 'Set a new password for {email}. You will set up your authenticator again.',\n\tstepUpTitle: \"Confirm it's you\",\n\tstepUpSubtitle: 'This action needs a fresh code. It covers the next five minutes.',\n\ttwoStepTitle: 'Two-step verification',\n\ttwoStepSubtitle: 'Enter the code from your authenticator app.',\n\tverify: 'Verify',\n\tchangeLanguage: 'Change language (current: {name})',\n\tthemeChoice: 'Theme: {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'That email and password do not match an operator.',\n\t\tINVALID_CODE: 'That code did not work. Codes change every 30 seconds.',\n\t\tLOCKED: 'Too many attempts. Try again in {minutes} minute(s).',\n\t\tLOCKED_GENERIC: 'Too many attempts. Try again in a few minutes.',\n\t\tRATE_LIMITED: 'Too many attempts from this address. Wait a few minutes.',\n\t\tWEAK_PASSWORD: 'Choose a stronger password — at least 12 characters, not easy to guess.',\n\t\tINVALID_LINK: 'This link has expired or was already used. Ask for a new one.',\n\t\tALREADY_OPERATOR: 'That email is already an operator. Sign in instead.',\n\t\tALREADY_CLAIMED: 'This console already has operators. Ask one for an invite.',\n\t\tCROSS_ORIGIN: 'This request did not come from the admin page.',\n\t},\n};\nexport default session;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst attention = {\n\ttitle: 'Attention',\n\tlead: 'What needs you on this deployment',\n\tleadChecked: 'What needs you on this deployment · checked {time}',\n\tneedsAction: 'Needs action',\n\tneedsActionHint: 'errors to fix',\n\tadvice: 'Advice',\n\tadviceHint: 'worth a look',\n\tmodulesReady: 'Modules ready',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Routes',\n\trunning: 'Running the checks…',\n\temptyTitle: 'Nothing needs you',\n\temptyBody: 'Every check passes. Checked {time}.',\n};\nexport default attention;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst modules = {\n\ttitle: 'Modules',\n\tlead: 'Every installed module, its version and whether it is ready.',\n\tleadSummary: '{env} · admin {version} · admin log {log} · {routes} routes',\n\tlogOn: 'on',\n\tlogOff: 'off',\n\tcolModule: 'Module',\n\tcolVersion: 'Version',\n\tcolReadiness: 'Readiness',\n\tcolAdmin: 'Admin',\n\tnotReported: 'not reported',\n\tdescribesAdmin: 'describes admin',\n};\nexport default modules;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst environment = {\n\ttitle: 'Environment',\n\tlead: 'Whether each module is configured and each variable the app reads is set. Values are never shown.',\n\tmissingCount: '{n} missing',\n\tallSet: 'all set',\n\tvariables: 'Variables',\n\tnoVariables: 'No variables declared — pass `env` to AdminModule.',\n\tmoduleReadiness: 'Module readiness',\n\tproblemOne: '1 problem',\n\tproblemMany: '{n} problems',\n};\nexport default environment;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst doctor = {\n\ttitle: 'Doctor',\n\tlead: 'Every reconciliation check across the installed modules, run on demand.',\n\tallPass: 'all checks pass',\n\toneFailed: 'a check failed',\n\trunAgain: 'Run again',\n\trunning: 'Running the checks…',\n\tcolResult: 'Result',\n\tcolCheck: 'Check',\n\tcolTime: 'Time',\n};\nexport default doctor;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst routes = {\n\ttitle: 'Routes',\n\tlead: 'Every exposed route, with its guard.',\n\tleadCount: '{n} routes exposed by this deployment, with the guard in front of each.',\n\tfilterPlaceholder: 'Filter by path, method, module…',\n\tfilterLabel: 'Filter routes',\n\tcolMethod: 'Method',\n\tcolPath: 'Path',\n\tcolGuard: 'Guard',\n\tcolModule: 'Module',\n\tapplication: 'application',\n\tnoMatch: 'No route matches “{q}”.',\n};\nexport default routes;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst log = {\n\ttitle: 'Admin log',\n\tlead: 'Every request made through this surface, newest first — refused ones included.',\n\toff: 'The admin log is off — give AdminModule a store.',\n\tempty: 'No requests yet',\n\tcolWhen: 'When',\n\tcolActor: 'Actor',\n\tcolRequest: 'Request',\n\tcolStatus: 'Status',\n\tcolModule: 'Module',\n};\nexport default log;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst migrations = {\n\ttitle: 'Migrations',\n\tlead: 'Schema changes each module ships, and whether this database has them.',\n\tneedsWrite: 'Applying migrations needs a token with the write scope.',\n\tfirstInstall:\n\t\t'This database has never been migrated — treating it as a first install, so nothing is held back.',\n\tupToDate: 'Every module is up to date',\n\tnoPending: 'No pending migrations.',\n\tpendingCount: '{n} pending',\n\tdestructive: 'destructive',\n\tadditive: 'additive',\n\tblockedBy: 'Apply \"{module}\" first — it runs before this one and is behind.',\n\tdestructiveBlocked:\n\t\t'Contains a migration that deletes data. No down-migration brings it back — apply this one through CI or `npm run migrate`.',\n\tconfirmApply: 'Apply {n} migration(s) to \"{module}\"? This changes the database schema.',\n\tapplyOne: 'Apply 1 migration',\n\tapplyMany: 'Apply {n} migrations',\n};\nexport default migrations;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst tokens = {\n\ttitle: 'Tokens',\n\tlead: \"Credentials for machines: the root token's strength, scoped tokens for the CLI and CI, and any legacy per-module tokens. People sign in as operators.\",\n\tneedsRoot: 'Issuing and revoking need the root token (the one in your deployment config).',\n\trootToken: 'Root token',\n\tstrong: 'strong',\n\tweak: 'weak',\n\tissuedTokens: 'Issued tokens',\n\tissuingOff: 'Issuing is off — give AdminModule a store and run its migrations.',\n\tcopyNow: 'Copy this now — it is never shown again.',\n\tnamePlaceholder: 'name',\n\tnameLabel: 'Name',\n\tscope: {\n\t\tread: 'read',\n\t\twrite: 'write',\n\t\tsecrets: 'secrets',\n\t},\n\tdaysPlaceholder: 'days (optional)',\n\tdaysLabel: 'Days',\n\tissue: 'Issue token',\n\tcol: {\n\t\tname: 'Name',\n\t\tscopes: 'Scopes',\n\t\tcreated: 'Created',\n\t\texpires: 'Expires',\n\t\tlastUsed: 'Last used',\n\t},\n\trevoked: 'revoked',\n\trevoke: 'Revoke',\n\trevokeConfirm: 'Revoke \"{name}\"? Anything using it stops working immediately.',\n\temptyTitle: 'No scoped tokens yet',\n\temptyBody: 'Issue a read-only token for a dashboard or a teammate instead of sharing the root.',\n\tlegacyTitle: 'Legacy per-brick tokens',\n\tlegacyNone: \"None — every brick's admin surface goes through this token.\",\n\tlegacyRow: 'still registers its standalone routes with its own token (deprecated)',\n};\nexport default tokens;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst operators = {\n\ttitle: 'Operators',\n\tlead: 'The people who can sign in to this console. Each one uses a password and an authenticator app; there is no sign-up.',\n\tlevel: {\n\t\tread: 'Read only',\n\t\teditor: 'Editor',\n\t\towner: 'Owner',\n\t},\n\tlevelHint: {\n\t\tread: 'look around, change nothing',\n\t\teditor: 'change config, templates, users',\n\t\towner: 'secrets, tokens and operators too',\n\t},\n\tneedsOwner: 'Managing operators needs the Owner level.',\n\tmintedTitle: 'Send this link to {email}. It is shown once.',\n\tmintedBody: 'It works once and expires {date}.',\n\tinvite: 'Invite',\n\tinvitePlaceholder: 'teammate@company.com',\n\tinviteLabel: 'Email to invite',\n\taccessLevelLabel: 'Access level',\n\taccessLevelFor: 'Access level for {email}',\n\tcreateInvite: 'Create invite link',\n\temptyTitle: 'No operators yet',\n\tcol: {\n\t\toperator: 'Operator',\n\t\taccess: 'Access',\n\t\tstatus: 'Status',\n\t\tlastSignIn: 'Last sign-in',\n\t},\n\tsettingUp: 'setting up',\n\tbackupCodesLeftOne: '{n} backup code left',\n\tbackupCodesLeftMany: '{n} backup codes left',\n\trecoveryLink: 'Recovery link',\n\trecoveryConfirm:\n\t\t'Create a recovery link for {email}? It signs them out everywhere; the link sets a new password and a new authenticator.',\n\tdisable: 'Disable',\n\tenable: 'Enable',\n\tdisableConfirm: 'Disable {email}? They are signed out immediately.',\n\tpendingLinks: 'Pending links',\n\tlinkKind: {\n\t\tinvite: 'invite',\n\t\trecovery: 'recovery',\n\t},\n\texpiresOn: 'expires {date}',\n\trevoke: 'Revoke',\n};\nexport default operators;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst users = {\n\ttitle: 'Users',\n\tlead: 'Everyone signed up. Open an account for its sessions, sign-ins and the suspend and sign-out controls.',\n\temailPlaceholder: 'email address',\n\temailLabel: 'Email',\n\tallUsers: 'All users',\n\twhichAccounts: 'Which accounts',\n\tactiveAccounts: 'Active',\n\tdeletedAccounts: 'Deleted',\n\tnoUserWithEmail: 'No user with that email.',\n\tmissingIdPrefix: 'No account with id',\n\tmissingIdBody: 'It was deleted, or never existed here. Its billing records remain.',\n\tplanCredits: 'Plan & credits',\n\temptyTitle: 'No users yet',\n\temptyBody: 'Sign-ups appear here as they happen.',\n\tcol: {\n\t\temail: 'Email',\n\t\tname: 'Name',\n\t\tplan: 'Plan',\n\t\tcreated: 'Created',\n\t\tstatus: 'Status',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'email',\n\t\tverified: 'verified',\n\t\tmfa: 'MFA',\n\t\tprovider: 'provider',\n\t\tlastLogin: 'last login',\n\t\tcreated: 'created',\n\t},\n\tpasswordProvider: 'password',\n\tnoPasswordSet: 'no password set',\n\tdeletedOn: 'Deleted on {date}.',\n\tdeletedBody:\n\t\t'The account cannot sign in, and it is erased when the retention purge runs. Its billing records stay.',\n\tsuspend: 'Suspend',\n\tunsuspend: 'Unsuspend',\n\tsignOutEverywhere: 'Sign out everywhere',\n\tliveSessions: 'Live sessions',\n\tsince: 'since {date}',\n\trecentSignIns: 'Recent sign-ins',\n\tnoneRecorded: 'None recorded.',\n\toutcome: {\n\t\tsuccess: 'success',\n\t\tfailure: 'failure',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hosting',\n};\nexport default users;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst billing = {\n\tstatusLabel: {\n\t\tactive: 'active',\n\t\ttrialing: 'trialing',\n\t\tpast_due: 'past due',\n\t\tunpaid: 'unpaid',\n\t\tcanceled: 'canceled',\n\t\tincomplete: 'incomplete',\n\t\tincomplete_expired: 'incomplete (expired)',\n\t\tpaused: 'paused',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'month',\n\t\tyear: 'year',\n\t},\n\trenews: 'Renews',\n\tends: 'Ends',\n\tended: 'Ended',\n\tloading: 'Loading billing…',\n\tplan: 'Plan',\n\tfree: 'Free',\n\tnoSubscription: 'no subscription',\n\tcredits: 'Credits',\n\tcurrencyPlaceholder: 'currency',\n\tcurrencyLabel: 'Wallet currency',\n\tcurrencyTitle: 'Show the wallet in another currency',\n\tbreakdown: '{permanent} permanent · {allowance} plan allowance',\n\texpires: ' (expires {date})',\n\tnoWallet: 'No wallet — billing has no wallet configuration.',\n\tgrantCredits: 'Grant credits',\n\tamountPlaceholder: 'amount ({currency})',\n\tamountLabel: 'Amount',\n\treasonPlaceholder: 'reason (optional)',\n\treasonLabel: 'Reason',\n\tgrant: 'Grant',\n\tgranted: 'Granted {amount} {currency}.',\n\tnoMovements: 'No credit movements yet',\n\tcol: {\n\t\twhen: 'When',\n\t\tkind: 'Kind',\n\t\tamount: 'Amount',\n\t\tnote: 'Note',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'purchase',\n\t\tgrant: 'grant',\n\t\tusage: 'usage',\n\t\trefund: 'refund',\n\t\tadjustment: 'adjustment',\n\t\texpiry: 'expiry',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Subscriptions',\n\t\tlead: \"Who pays, and who is behind. A user's plan and credits are also on their page under Users — free users appear only there.\",\n\t\tdetailLead: 'Plan, credits and what moved.',\n\t\tback: 'All subscriptions',\n\t\tfilterLabel: 'Filter by status',\n\t\tfilter: {\n\t\t\tall: 'All',\n\t\t\tactive: 'Active',\n\t\t\ttrialing: 'Trialing',\n\t\t\tpastDue: 'Past due',\n\t\t\tcanceled: 'Canceled',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'No subscriptions yet',\n\t\t\tactive: 'No active subscriptions',\n\t\t\ttrialing: 'No trialing subscriptions',\n\t\t\tpastDue: 'No past-due subscriptions',\n\t\t\tcanceled: 'No canceled subscriptions',\n\t\t},\n\t\temptyHint: 'Subscriptions appear here once someone checks out.',\n\t\ttypeLabel: 'Type',\n\t\ttypeWorkspace: 'workspace',\n\t\ttypeUser: 'user',\n\t\tidPlaceholder: 'subscriber id',\n\t\tidLabel: 'Subscriber id',\n\t\tcol: {\n\t\t\tsubscriber: 'Subscriber',\n\t\t\tplan: 'Plan',\n\t\t\tstatus: 'Status',\n\t\t\trenewsEnds: 'Renews / ends',\n\t\t},\n\t\tcancels: 'cancels',\n\t},\n};\nexport default billing;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst catalog = {\n\ttitle: 'Catalog',\n\tlead: 'What you sell: plans as configured in code, and as stored in the database, side by side.',\n\tconfigured: 'Configured (code)',\n\tstored: 'Stored (database)',\n\temptyTitle: 'No stored plans',\n\temptyBody: 'Plans are configured in code; nothing has been written to the database.',\n\tcol: {\n\t\tplan: 'Plan',\n\t\ttier: 'Tier',\n\t\tseats: 'Seats',\n\t\tmonthly: 'Monthly',\n\t\tyearly: 'Yearly',\n\t\ttrial: 'Trial',\n\t},\n\ttrialDays: '{n} d',\n\tdeleteConfirm: 'Delete stored plan \"{name}\"?',\n};\nexport default catalog;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst audit = {\n\ttitle: 'Audit',\n\tlead: \"What happened, across every workspace unless you name one. The chain's integrity verdict is on the Doctor page.\",\n\tworkspacePlaceholder: 'workspace id (all if empty)',\n\ttypePlaceholder: 'event type',\n\tactorPlaceholder: 'actor id',\n\tfromLabel: 'From date',\n\tfromTitle: 'From (inclusive)',\n\ttoLabel: 'To date',\n\ttoTitle: 'To (inclusive)',\n\tempty: 'Nothing recorded for this filter',\n\tcol: {\n\t\twhen: 'When',\n\t\ttype: 'Type',\n\t\tworkspace: 'Workspace',\n\t\tactor: 'Actor',\n\t\trequest: 'Request',\n\t},\n};\nexport default audit;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst config = {\n\tenvironment: 'Environment',\n\treveal: 'Reveal',\n\ttype: {\n\t\ttext: 'text',\n\t\tnumber: 'number',\n\t\tonOff: 'on/off',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Text',\n\t\tnumber: 'Number',\n\t\tonOff: 'On/off',\n\t\tlist: 'List',\n\t\tobject: 'Object',\n\t\tempty: 'Empty',\n\t},\n\tlist: {\n\t\ttitle: 'Config',\n\t\tnewEntry: 'New entry',\n\t\thint: 'Feature flags and runtime settings — text, numbers, on/off or JSON. Read by the app without a deploy.',\n\t\tempty: 'No config entries yet.',\n\t\temptyCta: 'Create one to toggle a feature or tune a setting without redeploying.',\n\t\temptyInEnv: 'No config in {env}. Entries in \"all\" still apply there.',\n\t\tpublicBadge: 'public',\n\t\tpublicTitle: 'Served to frontends by GET /config/public',\n\t\tpublicSummary: 'What frontends receive ({n} public keys)',\n\t\tpublicSummaryOne: 'What frontends receive (1 public key)',\n\t\tpublicHint:\n\t\t\t'Exactly the body of {route} — unauthenticated, so anyone can read it. Only keys the app lists as public appear.',\n\t\tsecretsTitle: 'Secrets',\n\t\tnewSecret: 'New secret',\n\t\tsecretsHint: 'Encrypted at rest; values are hidden until revealed.',\n\t\tsecretsEmpty: 'No secrets yet.',\n\t\tsecretsEmptyInEnv: 'No secrets in {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'New config entry',\n\t\tnewSecret: 'New secret',\n\t\tenvironmentLabel: 'Environment:',\n\t\tkey: 'Key',\n\t\tenvironmentHint:\n\t\t\t'\"all\" is shared by every environment; a named one (production, staging…) overrides it there.',\n\t\tvalue: 'Value',\n\t\tnewValue: 'New value',\n\t\tvaluePlaceholder: 'true · 42 · Scheduled maintenance tonight · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Detected:',\n\t\tsaveAsText: 'Save as text instead',\n\t\ton: 'On (true)',\n\t\toff: 'Off (false)',\n\t\ttype: 'Type:',\n\t\tchangeType: 'Change type…',\n\t\tchangeTypeWarning:\n\t\t\t'Changing the type changes what every screen reading this key receives. Check the code that reads it first.',\n\t\tdescription: 'Description',\n\t\tconflict:\n\t\t\t'Someone changed this entry since you opened it. Reload to see their change, then edit again.',\n\t\tconfirmDelete: 'Delete \"{key}\"? Anything that reads it falls back to its default.',\n\t\tconfirmDeleteIn: 'Delete \"{key}\" from {env}? Anything that reads it falls back to its default.',\n\t\thistory: 'History',\n\t\tunknownActor: 'unknown',\n\t\trollBack: 'Roll back',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Enter a key.',\n\t\tkeyPattern: 'Start with a letter; use letters, digits, \".\", \"_\" or \"-\" (max 128).',\n\t\texists: '\"{key}\" already exists in {env} — open it from the list to edit.',\n\t\tnumber: 'Enter a number.',\n\t\tboolean: 'Use true or false.',\n\t\tjson: 'Not valid JSON: {detail}',\n\t},\n};\nexport default config;\n","// English — canonical: this shape defines the keys fr and es must match.\nconst templates = {\n\tdefaultLocale: 'default locale',\n\tdefaultChip: 'default',\n\tbuiltInBadge: 'built-in',\n\tsubject: 'Subject',\n\thtmlBody: 'HTML body',\n\ttextBody: 'Plain-text body',\n\tlist: {\n\t\ttitle: 'Templates',\n\t\tnewTemplate: 'New template',\n\t\thint: 'Every email the app sends. Open one to edit its copy and preview it live.',\n\t\tloading: 'Loading templates…',\n\t\topenLocale: 'Open the {locale} version of {type}',\n\t\tlegend: 'Solid: a version you saved. Dashed: Fonderie’s built-in copy, not edited. Struck through: switched off.',\n\t\tlanguages: 'Languages',\n\t},\n\teditor: {\n\t\tloading: 'Loading template…',\n\t\tlocales: 'Locales',\n\t\tdiscardChanges: 'You have unsaved changes to this locale. Discard them and switch?',\n\t\taddLocale: '+ Add locale',\n\t\tbuiltInNote: 'built-in email: edit or roll back, it cannot be deleted',\n\t\tactive: 'Active',\n\t\tconflict:\n\t\t\t'Someone changed this template since you opened it. Reload to see their change, then edit again.',\n\t\tnoChanges: 'No changes to save',\n\t\tsampleData: 'Sample data',\n\t\tsampleNotObject: 'Sample data must be a JSON object.',\n\t\tsampleInvalid: 'Sample data is not valid JSON.',\n\t\tpreview: 'Preview',\n\t\tpreviewTitle: 'Template preview',\n\t\trendering: 'Rendering…',\n\t\tlive: 'Live',\n\t\tnothingRendered: 'Nothing rendered yet.',\n\t\thistory: 'History',\n\t\tunknownActor: 'unknown',\n\t\trollBack: 'Roll back',\n\t\tconfirmDelete: 'Delete \"{type}\"?',\n\t\tconfirmDeleteLocale:\n\t\t\t'Delete the {locale} version of \"{type}\"? People in that locale will receive the default version.',\n\t\tbuiltInCopy: 'Fonderie’s built-in copy. Saving creates your own version of it.',\n\t\tresetToBuiltIn: 'Reset to built-in',\n\t\tconfirmReset: 'Replace your {locale} version with Fonderie’s built-in copy?',\n\t\tchain: 'Fallback: {chain}',\n\t\twhoReceives: 'Who receives what',\n\t\twhoPlaceholder: 'A locale, e.g. fr-BE',\n\t\tcheck: 'Check',\n\t\treceives: 'A {requested} user receives the {sent} version.',\n\t\tsourceSaved: 'It is your saved version.',\n\t\tsourceBuiltIn: 'It is Fonderie’s built-in copy.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'New template',\n\t\ttitleLocale: 'Add a locale to {type}',\n\t\thintNew:\n\t\t\t'For an email your app sends that has no stored copy yet. The type must match what the app sends.',\n\t\thintLocale:\n\t\t\t'Starts from the default copy. People whose locale matches receive this version; everyone else keeps the default.',\n\t\ttype: 'Type',\n\t\tlocale: 'Locale',\n\t\tlocaleOptional: 'Locale (optional — empty is the default)',\n\t\tcreating: 'Creating…',\n\t\tsubmitNew: 'Create template',\n\t\tsubmitLocale: 'Add locale',\n\t\terrorType: 'Type: lowercase letters, digits, - and _ (e.g. weekly-digest).',\n\t\terrorLocaleRequired: 'Choose the locale to add, e.g. fr or fr-CA.',\n\t\terrorLocale: 'Locale: a language tag such as fr, es or fr-CA.',\n\t\terrorText: 'The plain-text body is required — it is what every email client can show.',\n\t\texists: '\"{type}\" already exists — open it from the list to edit.',\n\t\texistsLocale: '\"{type}\" ({locale}) already exists — open it from the list to edit.',\n\t\tuntranslated: 'Still the default copy: {fields}. Translate them before adding this locale.',\n\t\terrorDefaultLocale: '{locale} is the default version of this email. Edit the default instead.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst en = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default en;\n","import type en from '../en/common';\n\nconst common: typeof en = {\n\trefresh: 'Actualizar',\n\tworking: 'Procesando…',\n\tloading: 'Cargando…',\n\tloadMore: 'Cargar más',\n\tsave: 'Guardar',\n\tsaving: 'Guardando…',\n\tcancel: 'Cancelar',\n\tdelete: 'Eliminar',\n\tdeleting: 'Eliminando…',\n\tback: 'Volver',\n\topen: 'Abrir',\n\tcopy: 'Copiar',\n\tcopied: 'Copiado',\n\tdismiss: 'Cerrar',\n\tconfirm: 'Confirmar',\n\tcontinue: 'Continuar',\n\treload: 'Recargar',\n\tsearch: 'Buscar',\n\tlookUp: 'Buscar',\n\tfilter: 'Filtrar',\n\tyes: 'sí',\n\tno: 'no',\n\tnone: 'Ninguno.',\n\tnever: 'nunca',\n\tyou: 'tú',\n\tall: 'Todos',\n\tallEnvironments: 'Todos los entornos',\n\tlanguage: 'Idioma',\n\ttheme: 'Tema',\n\tthemeSystem: 'Sistema',\n\tthemeLight: 'Claro',\n\tthemeDark: 'Oscuro',\n\tstatus: {\n\t\tactive: 'activo',\n\t\tinactive: 'inactivo',\n\t\tready: 'listo',\n\t\terror: 'error',\n\t\tadvice: 'consejo',\n\t\tok: 'ok',\n\t\tfailed: 'fallido',\n\t\tskipped: 'omitido',\n\t\tsuspended: 'suspendido',\n\t\tdeleted: 'eliminado',\n\t\tdisabled: 'desactivado',\n\t\tlocked: 'bloqueado',\n\t\tpending: 'pendiente',\n\t\tset: 'definida',\n\t\tmissing: 'falta',\n\t\tfree: 'gratis',\n\t},\n};\nexport default common;\n","import type en from '../en/nav';\n\nconst nav: typeof en = {\n\tgroups: {\n\t\ttoday: 'Hoy',\n\t\tsystem: 'Sistema',\n\t\tpeople: 'Personas',\n\t\tmoney: 'Finanzas',\n\t\tsettings: 'Ajustes',\n\t\tmessaging: 'Mensajería',\n\t\tactivity: 'Actividad',\n\t},\n\titems: {\n\t\tattention: 'Atención',\n\t\tmodules: 'Módulos',\n\t\tenvironment: 'Entorno',\n\t\tdoctor: 'Diagnóstico',\n\t\troutes: 'Rutas',\n\t\tusers: 'Usuarios',\n\t\tcatalog: 'Catálogo',\n\t\tsubscriptions: 'Suscripciones',\n\t\tsettings: 'Configuración y secretos',\n\t\ttemplates: 'Plantillas',\n\t\taudit: 'Auditoría',\n\t\tlog: 'Registro de administración',\n\t\toperators: 'Operadores',\n\t\ttokens: 'Tokens',\n\t\tmigrations: 'Migraciones',\n\t},\n};\nexport default nav;\n","import type en from '../en/shell';\n\nconst shell: typeof en = {\n\topenMenu: 'Abrir el menú',\n\tcloseMenu: 'Cerrar el menú',\n\tnavLabel: 'Administración',\n\tmissingClient: 'Proporciona un {client} para usar esta página.',\n};\nexport default shell;\n","import type en from '../en/session';\n\nconst session: typeof en = {\n\tsignInTitle: 'Iniciar sesión en la administración',\n\tadminToken: 'Token de administración',\n\tpasteToken: 'Pega tu token',\n\ttokenFoot:\n\t\t'Se guarda solo para esta pestaña y se envía en un encabezado Bearer — nunca se almacena en el servidor. Un token de solo lectura basta para consultar y no puede revelar secretos.',\n\ttokenRefused: 'Ese token fue rechazado.',\n\tunreachable: 'No se pudo acceder a la interfaz de administración: {error}',\n\tforgetToken: 'Olvidar el token',\n\tsignOut: 'Cerrar sesión',\n\tgenericError: 'Algo salió mal. Inténtalo de nuevo.',\n\tstepOf: 'Paso {n} de {total}',\n\tsteps: {\n\t\tadminToken: 'Token de administración',\n\t\taccount: 'Tu cuenta',\n\t\tauthenticator: 'Autenticador',\n\t\tbackupCodes: 'Códigos de respaldo',\n\t\tnewPassword: 'Nueva contraseña',\n\t},\n\tchecking: 'Comprobando…',\n\twelcomeTitle: 'Bienvenido — configuremos tu consola',\n\twelcomeSubtitle:\n\t\t'Este es el primer inicio de sesión en {host}. Pega el token de administración de la configuración de tu despliegue para empezar. Solo se necesita esta vez.',\n\tcreateAccountTitle: 'Crea tu cuenta',\n\tcreateAccountSubtitle:\n\t\t'A partir de ahora inicias sesión con este correo y esta contraseña, además de una aplicación de autenticación. El token de administración queda para scripts y emergencias.',\n\temail: 'Correo electrónico',\n\tnameOptional: 'Nombre (opcional)',\n\tyourNameOptional: 'Tu nombre (opcional)',\n\tpassword: 'Contraseña',\n\tnewPassword: 'Nueva contraseña',\n\tconfirmPassword: 'Confirma la contraseña',\n\tpasswordHint: 'Al menos 12 caracteres.',\n\tpasswordHintNext:\n\t\t'Al menos 12 caracteres. A continuación configurarás una aplicación de autenticación.',\n\tpasswordsMismatch: 'Las dos contraseñas no coinciden.',\n\tcreating: 'Creando…',\n\tcreateAccount: 'Crear cuenta',\n\tloginFoot:\n\t\t'No hay registro: los operadores son invitados por otro operador. ¿Sin acceso? Pide a otro operador un enlace de recuperación.',\n\tbackupCode: 'Código de respaldo',\n\tauthenticatorCode: 'Código de autenticación',\n\tuseApp: 'Usar la aplicación de autenticación',\n\tuseBackup: 'Usar un código de respaldo',\n\tenrollTitle: 'Configura tu autenticador',\n\tenrollSubtitle:\n\t\t'Cada inicio de sesión en esta consola requiere un código de una aplicación de autenticación — 1Password, Google Authenticator, Authy o cualquier aplicación TOTP.',\n\tenrollScan: 'Abre tu aplicación de autenticación y escanea este código.',\n\tenrollEnter: 'Introduce los seis dígitos que muestra.',\n\tqrAlt: 'Código QR para tu aplicación de autenticación',\n\tcantScan: '¿No puedes escanear? Introduce una clave de configuración',\n\tpreparing: 'Preparando…',\n\tcancelSignOut: 'Cancelar y cerrar sesión',\n\tcodeFromApp: 'Código de la aplicación',\n\tverifyContinue: 'Verificar y continuar',\n\tbackupTitle: 'Guarda tus códigos de respaldo',\n\tbackupSubtitle:\n\t\t'Si pierdes tu teléfono, cada uno de estos códigos te permite iniciar sesión una vez. Solo se muestran ahora.',\n\tbackupFileHeader: 'Códigos de respaldo para la administración de {host}',\n\tdownload: 'Descargar',\n\tsavedCheckbox: 'He guardado estos códigos en un lugar seguro',\n\topenConsole: 'Abrir la consola',\n\tlinkInvalidTitle: 'Este enlace no se puede usar',\n\tcheckingLink: 'Comprobando tu enlace…',\n\tjoinTitle: 'Únete a la consola de administración',\n\trecoverTitle: 'Recupera tu cuenta',\n\tjoinSubtitle:\n\t\t'Te invitaron como {email}. Elige una contraseña y luego configura una aplicación de autenticación.',\n\trecoverSubtitle:\n\t\t'Define una nueva contraseña para {email}. Volverás a configurar tu autenticador.',\n\tstepUpTitle: 'Confirma que eres tú',\n\tstepUpSubtitle:\n\t\t'Esta acción requiere un código nuevo. Es válido durante los próximos cinco minutos.',\n\ttwoStepTitle: 'Verificación en dos pasos',\n\ttwoStepSubtitle: 'Introduce el código de tu aplicación de autenticación.',\n\tverify: 'Verificar',\n\tchangeLanguage: 'Cambiar idioma (actual: {name})',\n\tthemeChoice: 'Tema: {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'Ese correo y esa contraseña no corresponden a ningún operador.',\n\t\tINVALID_CODE: 'Ese código no funcionó. Los códigos cambian cada 30 segundos.',\n\t\tLOCKED: 'Demasiados intentos. Inténtalo de nuevo en {minutes} minuto(s).',\n\t\tLOCKED_GENERIC: 'Demasiados intentos. Inténtalo de nuevo en unos minutos.',\n\t\tRATE_LIMITED: 'Demasiados intentos desde esta dirección. Espera unos minutos.',\n\t\tWEAK_PASSWORD:\n\t\t\t'Elige una contraseña más segura — al menos 12 caracteres y difícil de adivinar.',\n\t\tINVALID_LINK: 'Este enlace caducó o ya se usó. Pide uno nuevo.',\n\t\tALREADY_OPERATOR: 'Ese correo ya pertenece a un operador. Inicia sesión.',\n\t\tALREADY_CLAIMED: 'Esta consola ya tiene operadores. Pide una invitación a uno de ellos.',\n\t\tCROSS_ORIGIN: 'Esta solicitud no proviene de la página de administración.',\n\t},\n};\nexport default session;\n","import type en from '../en/attention';\n\nconst attention: typeof en = {\n\ttitle: 'Atención',\n\tlead: 'Lo que necesita tu atención en este despliegue',\n\tleadChecked: 'Lo que necesita tu atención en este despliegue · comprobado a las {time}',\n\tneedsAction: 'Requiere acción',\n\tneedsActionHint: 'errores por corregir',\n\tadvice: 'Consejos',\n\tadviceHint: 'vale la pena revisarlos',\n\tmodulesReady: 'Módulos listos',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Rutas',\n\trunning: 'Ejecutando las comprobaciones…',\n\temptyTitle: 'Nada requiere tu atención',\n\temptyBody: 'Todas las comprobaciones pasan. Comprobado el {time}.',\n};\nexport default attention;\n","import type en from '../en/modules';\n\nconst modules: typeof en = {\n\ttitle: 'Módulos',\n\tlead: 'Cada módulo instalado, su versión y si está listo.',\n\tleadSummary: '{env} · admin {version} · registro de administración {log} · {routes} rutas',\n\tlogOn: 'activado',\n\tlogOff: 'desactivado',\n\tcolModule: 'Módulo',\n\tcolVersion: 'Versión',\n\tcolReadiness: 'Estado',\n\tcolAdmin: 'Admin',\n\tnotReported: 'no informada',\n\tdescribesAdmin: 'describe la administración',\n};\nexport default modules;\n","import type en from '../en/environment';\n\nconst environment: typeof en = {\n\ttitle: 'Entorno',\n\tlead: 'Si cada módulo está configurado y si cada variable que lee la aplicación está definida. Los valores nunca se muestran.',\n\tmissingCount: 'faltan {n}',\n\tallSet: 'todas definidas',\n\tvariables: 'Variables',\n\tnoVariables: 'No hay variables declaradas: pasa `env` a AdminModule.',\n\tmoduleReadiness: 'Estado de los módulos',\n\tproblemOne: '1 problema',\n\tproblemMany: '{n} problemas',\n};\nexport default environment;\n","import type en from '../en/doctor';\n\nconst doctor: typeof en = {\n\ttitle: 'Diagnóstico',\n\tlead: 'Todas las comprobaciones de coherencia de los módulos instalados, ejecutadas a demanda.',\n\tallPass: 'todas las comprobaciones pasan',\n\toneFailed: 'una comprobación falló',\n\trunAgain: 'Volver a ejecutar',\n\trunning: 'Ejecutando las comprobaciones…',\n\tcolResult: 'Resultado',\n\tcolCheck: 'Comprobación',\n\tcolTime: 'Duración',\n};\nexport default doctor;\n","import type en from '../en/routes';\n\nconst routes: typeof en = {\n\ttitle: 'Rutas',\n\tlead: 'Cada ruta expuesta, con su protección.',\n\tleadCount: '{n} rutas expuestas por este despliegue, con la protección que tiene cada una.',\n\tfilterPlaceholder: 'Filtrar por ruta, método, módulo…',\n\tfilterLabel: 'Filtrar rutas',\n\tcolMethod: 'Método',\n\tcolPath: 'Ruta',\n\tcolGuard: 'Protección',\n\tcolModule: 'Módulo',\n\tapplication: 'aplicación',\n\tnoMatch: 'Ninguna ruta coincide con «{q}».',\n};\nexport default routes;\n","import type en from '../en/log';\n\nconst log: typeof en = {\n\ttitle: 'Registro de administración',\n\tlead: 'Cada solicitud realizada a través de esta consola, de la más reciente a la más antigua, incluidas las rechazadas.',\n\toff: 'El registro de administración está desactivado: proporciona un store a AdminModule.',\n\tempty: 'Todavía no hay solicitudes',\n\tcolWhen: 'Fecha',\n\tcolActor: 'Autor',\n\tcolRequest: 'Solicitud',\n\tcolStatus: 'Estado',\n\tcolModule: 'Módulo',\n};\nexport default log;\n","import type en from '../en/migrations';\n\nconst migrations: typeof en = {\n\ttitle: 'Migraciones',\n\tlead: 'Los cambios de esquema que incluye cada módulo, y si esta base de datos ya los tiene.',\n\tneedsWrite: 'Aplicar migraciones requiere un token con permiso de escritura.',\n\tfirstInstall:\n\t\t'Esta base de datos nunca se ha migrado: se trata como una primera instalación, así que no se retiene nada.',\n\tupToDate: 'Todos los módulos están al día',\n\tnoPending: 'No hay migraciones pendientes.',\n\tpendingCount: '{n} pendientes',\n\tdestructive: 'destructiva',\n\tadditive: 'aditiva',\n\tblockedBy: 'Aplica primero «{module}»: se ejecuta antes que este y está atrasado.',\n\tdestructiveBlocked:\n\t\t'Contiene una migración que elimina datos. Ninguna migración inversa los recupera: aplícala mediante la CI o `npm run migrate`.',\n\tconfirmApply:\n\t\t'¿Aplicar {n} migración(es) a «{module}»? Esto modifica el esquema de la base de datos.',\n\tapplyOne: 'Aplicar 1 migración',\n\tapplyMany: 'Aplicar {n} migraciones',\n};\nexport default migrations;\n","import type en from '../en/tokens';\n\nconst tokens: typeof en = {\n\ttitle: 'Tokens',\n\tlead: 'Credenciales para máquinas: la solidez del token raíz, tokens con alcance limitado para la CLI y la CI, y cualquier token heredado por módulo. Las personas inician sesión como operadores.',\n\tneedsRoot: 'Emitir y revocar requieren el token raíz (el de la configuración de tu despliegue).',\n\trootToken: 'Token raíz',\n\tstrong: 'sólido',\n\tweak: 'débil',\n\tissuedTokens: 'Tokens emitidos',\n\tissuingOff:\n\t\t'La emisión está desactivada — proporciona un store a AdminModule y ejecuta sus migraciones.',\n\tcopyNow: 'Cópialo ahora — no se volverá a mostrar.',\n\tnamePlaceholder: 'nombre',\n\tnameLabel: 'Nombre',\n\tscope: {\n\t\tread: 'lectura',\n\t\twrite: 'escritura',\n\t\tsecrets: 'secretos',\n\t},\n\tdaysPlaceholder: 'días (opcional)',\n\tdaysLabel: 'Días',\n\tissue: 'Emitir token',\n\tcol: {\n\t\tname: 'Nombre',\n\t\tscopes: 'Alcances',\n\t\tcreated: 'Creado',\n\t\texpires: 'Vence',\n\t\tlastUsed: 'Último uso',\n\t},\n\trevoked: 'revocado',\n\trevoke: 'Revocar',\n\trevokeConfirm: '¿Revocar «{name}»? Todo lo que lo use dejará de funcionar de inmediato.',\n\temptyTitle: 'Aún no hay tokens con alcance limitado',\n\temptyBody:\n\t\t'Emite un token de solo lectura para un panel o un compañero en lugar de compartir el token raíz.',\n\tlegacyTitle: 'Tokens heredados por módulo',\n\tlegacyNone: 'Ninguno — la superficie de administración de cada módulo pasa por este token.',\n\tlegacyRow: 'todavía registra sus rutas independientes con su propio token (obsoleto)',\n};\nexport default tokens;\n","import type en from '../en/operators';\n\nconst operators: typeof en = {\n\ttitle: 'Operadores',\n\tlead: 'Las personas que pueden iniciar sesión en esta consola. Cada una usa una contraseña y una aplicación de autenticación; no hay registro.',\n\tlevel: {\n\t\tread: 'Solo lectura',\n\t\teditor: 'Editor',\n\t\towner: 'Propietario',\n\t},\n\tlevelHint: {\n\t\tread: 'consultar, sin cambiar nada',\n\t\teditor: 'cambiar configuración, plantillas y usuarios',\n\t\towner: 'también secretos, tokens y operadores',\n\t},\n\tneedsOwner: 'Gestionar operadores requiere el nivel Propietario.',\n\tmintedTitle: 'Envía este enlace a {email}. Solo se muestra una vez.',\n\tmintedBody: 'Funciona una sola vez y vence el {date}.',\n\tinvite: 'Invitar',\n\tinvitePlaceholder: 'companero@empresa.com',\n\tinviteLabel: 'Correo electrónico a invitar',\n\taccessLevelLabel: 'Nivel de acceso',\n\taccessLevelFor: 'Nivel de acceso de {email}',\n\tcreateInvite: 'Crear enlace de invitación',\n\temptyTitle: 'Aún no hay operadores',\n\tcol: {\n\t\toperator: 'Operador',\n\t\taccess: 'Acceso',\n\t\tstatus: 'Estado',\n\t\tlastSignIn: 'Último inicio de sesión',\n\t},\n\tsettingUp: 'en configuración',\n\tbackupCodesLeftOne: 'queda {n} código de respaldo',\n\tbackupCodesLeftMany: 'quedan {n} códigos de respaldo',\n\trecoveryLink: 'Enlace de recuperación',\n\trecoveryConfirm:\n\t\t'¿Crear un enlace de recuperación para {email}? Cierra su sesión en todas partes; el enlace permite definir una nueva contraseña y una nueva aplicación de autenticación.',\n\tdisable: 'Desactivar',\n\tenable: 'Activar',\n\tdisableConfirm: '¿Desactivar a {email}? Su sesión se cierra de inmediato.',\n\tpendingLinks: 'Enlaces pendientes',\n\tlinkKind: {\n\t\tinvite: 'invitación',\n\t\trecovery: 'recuperación',\n\t},\n\texpiresOn: 'vence el {date}',\n\trevoke: 'Revocar',\n};\nexport default operators;\n","import type en from '../en/users';\n\nconst users: typeof en = {\n\ttitle: 'Usuarios',\n\tlead: 'Todos los registrados. Abre una cuenta para ver sus sesiones, sus inicios de sesión y los controles para suspender y cerrar sesión.',\n\temailPlaceholder: 'correo electrónico',\n\temailLabel: 'Correo electrónico',\n\tallUsers: 'Todos los usuarios',\n\twhichAccounts: 'Qué cuentas',\n\tactiveAccounts: 'Activas',\n\tdeletedAccounts: 'Eliminadas',\n\tnoUserWithEmail: 'No hay ningún usuario con ese correo electrónico.',\n\tmissingIdPrefix: 'No hay ninguna cuenta con el id',\n\tmissingIdBody: 'Se eliminó o nunca existió aquí. Sus registros de facturación se conservan.',\n\tplanCredits: 'Plan y créditos',\n\temptyTitle: 'Aún no hay usuarios',\n\temptyBody: 'Los registros aparecen aquí a medida que ocurren.',\n\tcol: {\n\t\temail: 'Correo electrónico',\n\t\tname: 'Nombre',\n\t\tplan: 'Plan',\n\t\tcreated: 'Creado',\n\t\tstatus: 'Estado',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'correo electrónico',\n\t\tverified: 'verificado',\n\t\tmfa: 'MFA',\n\t\tprovider: 'proveedor',\n\t\tlastLogin: 'último inicio de sesión',\n\t\tcreated: 'creado',\n\t},\n\tpasswordProvider: 'contraseña',\n\tnoPasswordSet: 'sin contraseña',\n\tdeletedOn: 'Eliminada el {date}.',\n\tdeletedBody:\n\t\t'La cuenta no puede iniciar sesión y se borrará cuando se ejecute la purga de retención. Sus registros de facturación se conservan.',\n\tsuspend: 'Suspender',\n\tunsuspend: 'Reactivar',\n\tsignOutEverywhere: 'Cerrar sesión en todas partes',\n\tliveSessions: 'Sesiones activas',\n\tsince: 'desde el {date}',\n\trecentSignIns: 'Inicios de sesión recientes',\n\tnoneRecorded: 'Ninguno registrado.',\n\toutcome: {\n\t\tsuccess: 'correcto',\n\t\tfailure: 'fallido',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hosting',\n};\nexport default users;\n","import type en from '../en/billing';\n\nconst billing: typeof en = {\n\tstatusLabel: {\n\t\tactive: 'activa',\n\t\ttrialing: 'en prueba',\n\t\tpast_due: 'pago atrasado',\n\t\tunpaid: 'impagada',\n\t\tcanceled: 'cancelada',\n\t\tincomplete: 'incompleta',\n\t\tincomplete_expired: 'incompleta (vencida)',\n\t\tpaused: 'en pausa',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'mes',\n\t\tyear: 'año',\n\t},\n\trenews: 'Se renueva el',\n\tends: 'Termina el',\n\tended: 'Terminó el',\n\tloading: 'Cargando facturación…',\n\tplan: 'Plan',\n\tfree: 'Gratis',\n\tnoSubscription: 'sin suscripción',\n\tcredits: 'Créditos',\n\tcurrencyPlaceholder: 'moneda',\n\tcurrencyLabel: 'Moneda del monedero',\n\tcurrencyTitle: 'Mostrar el monedero en otra moneda',\n\tbreakdown: '{permanent} permanentes · {allowance} de asignación del plan',\n\texpires: ' (vence el {date})',\n\tnoWallet: 'Sin monedero — la facturación no tiene configuración de monedero.',\n\tgrantCredits: 'Otorgar créditos',\n\tamountPlaceholder: 'cantidad ({currency})',\n\tamountLabel: 'Cantidad',\n\treasonPlaceholder: 'motivo (opcional)',\n\treasonLabel: 'Motivo',\n\tgrant: 'Otorgar',\n\tgranted: 'Se otorgaron {amount} {currency}.',\n\tnoMovements: 'Aún no hay movimientos de créditos',\n\tcol: {\n\t\twhen: 'Fecha',\n\t\tkind: 'Tipo',\n\t\tamount: 'Cantidad',\n\t\tnote: 'Nota',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'compra',\n\t\tgrant: 'otorgamiento',\n\t\tusage: 'uso',\n\t\trefund: 'reembolso',\n\t\tadjustment: 'ajuste',\n\t\texpiry: 'vencimiento',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Suscripciones',\n\t\tlead: 'Quién paga y quién está atrasado. El plan y los créditos de un usuario también están en su página en Usuarios — los usuarios gratuitos solo aparecen allí.',\n\t\tdetailLead: 'Plan, créditos y movimientos.',\n\t\tback: 'Todas las suscripciones',\n\t\tfilterLabel: 'Filtrar por estado',\n\t\tfilter: {\n\t\t\tall: 'Todas',\n\t\t\tactive: 'Activas',\n\t\t\ttrialing: 'En prueba',\n\t\t\tpastDue: 'Atrasadas',\n\t\t\tcanceled: 'Canceladas',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'Aún no hay suscripciones',\n\t\t\tactive: 'No hay suscripciones activas',\n\t\t\ttrialing: 'No hay suscripciones en prueba',\n\t\t\tpastDue: 'No hay suscripciones con pago atrasado',\n\t\t\tcanceled: 'No hay suscripciones canceladas',\n\t\t},\n\t\temptyHint: 'Las suscripciones aparecen aquí cuando alguien completa una compra.',\n\t\ttypeLabel: 'Tipo',\n\t\ttypeWorkspace: 'espacio de trabajo',\n\t\ttypeUser: 'usuario',\n\t\tidPlaceholder: 'id del suscriptor',\n\t\tidLabel: 'Id del suscriptor',\n\t\tcol: {\n\t\t\tsubscriber: 'Suscriptor',\n\t\t\tplan: 'Plan',\n\t\t\tstatus: 'Estado',\n\t\t\trenewsEnds: 'Renovación / fin',\n\t\t},\n\t\tcancels: 'se cancelará',\n\t},\n};\nexport default billing;\n","import type en from '../en/catalog';\n\nconst catalog: typeof en = {\n\ttitle: 'Catálogo',\n\tlead: 'Lo que vendes: los planes tal como están configurados en el código y tal como están guardados en la base de datos, lado a lado.',\n\tconfigured: 'Configurados (código)',\n\tstored: 'Guardados (base de datos)',\n\temptyTitle: 'No hay planes guardados',\n\temptyBody:\n\t\t'Los planes están configurados en el código; no se ha escrito nada en la base de datos.',\n\tcol: {\n\t\tplan: 'Plan',\n\t\ttier: 'Nivel',\n\t\tseats: 'Plazas',\n\t\tmonthly: 'Mensual',\n\t\tyearly: 'Anual',\n\t\ttrial: 'Prueba',\n\t},\n\ttrialDays: '{n} d',\n\tdeleteConfirm: '¿Eliminar el plan guardado «{name}»?',\n};\nexport default catalog;\n","import type en from '../en/audit';\n\nconst audit: typeof en = {\n\ttitle: 'Auditoría',\n\tlead: 'Lo que ha pasado, en todos los espacios de trabajo salvo que indiques uno. El veredicto de integridad de la cadena está en la página Diagnóstico.',\n\tworkspacePlaceholder: 'id del espacio de trabajo (todos si está vacío)',\n\ttypePlaceholder: 'tipo de evento',\n\tactorPlaceholder: 'id del actor',\n\tfromLabel: 'Fecha de inicio',\n\tfromTitle: 'Desde (incluido)',\n\ttoLabel: 'Fecha de fin',\n\ttoTitle: 'Hasta (incluido)',\n\tempty: 'Nada registrado para este filtro',\n\tcol: {\n\t\twhen: 'Fecha',\n\t\ttype: 'Tipo',\n\t\tworkspace: 'Espacio de trabajo',\n\t\tactor: 'Actor',\n\t\trequest: 'Solicitud',\n\t},\n};\nexport default audit;\n","import type en from '../en/config';\n\nconst config: typeof en = {\n\tenvironment: 'Entorno',\n\treveal: 'Mostrar',\n\ttype: {\n\t\ttext: 'texto',\n\t\tnumber: 'número',\n\t\tonOff: 'sí/no',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Texto',\n\t\tnumber: 'Número',\n\t\tonOff: 'Sí/no',\n\t\tlist: 'Lista',\n\t\tobject: 'Objeto',\n\t\tempty: 'Vacío',\n\t},\n\tlist: {\n\t\ttitle: 'Configuración',\n\t\tnewEntry: 'Nueva entrada',\n\t\thint: 'Indicadores de funciones y ajustes de ejecución — texto, números, sí/no o JSON. La aplicación los lee sin desplegar.',\n\t\tempty: 'Todavía no hay entradas de configuración.',\n\t\temptyCta: 'Crea una para activar una función o ajustar un parámetro sin volver a desplegar.',\n\t\temptyInEnv: 'No hay configuración en {env}. Las entradas de \"all\" siguen aplicándose allí.',\n\t\tpublicBadge: 'público',\n\t\tpublicTitle: 'Servido a los frontends por GET /config/public',\n\t\tpublicSummary: 'Lo que reciben los frontends ({n} claves públicas)',\n\t\tpublicSummaryOne: 'Lo que reciben los frontends (1 clave pública)',\n\t\tpublicHint:\n\t\t\t'Exactamente el cuerpo de {route} — sin autenticación, así que cualquiera puede leerlo. Solo aparecen las claves que la aplicación declara públicas.',\n\t\tsecretsTitle: 'Secretos',\n\t\tnewSecret: 'Nuevo secreto',\n\t\tsecretsHint: 'Cifrados en reposo; los valores permanecen ocultos hasta que se muestran.',\n\t\tsecretsEmpty: 'Todavía no hay secretos.',\n\t\tsecretsEmptyInEnv: 'No hay secretos en {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'Nueva entrada de configuración',\n\t\tnewSecret: 'Nuevo secreto',\n\t\tenvironmentLabel: 'Entorno:',\n\t\tkey: 'Clave',\n\t\tenvironmentHint:\n\t\t\t'\"all\" lo comparten todos los entornos; uno con nombre (production, staging…) lo reemplaza allí.',\n\t\tvalue: 'Valor',\n\t\tnewValue: 'Nuevo valor',\n\t\tvaluePlaceholder: 'true · 42 · Mantenimiento programado esta noche · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Detectado:',\n\t\tsaveAsText: 'Guardar como texto',\n\t\ton: 'Sí (true)',\n\t\toff: 'No (false)',\n\t\ttype: 'Tipo:',\n\t\tchangeType: 'Cambiar tipo…',\n\t\tchangeTypeWarning:\n\t\t\t'Cambiar el tipo cambia lo que recibe cada pantalla que lee esta clave. Revisa primero el código que la lee.',\n\t\tdescription: 'Descripción',\n\t\tconflict:\n\t\t\t'Alguien cambió esta entrada desde que la abriste. Recarga para ver su cambio y vuelve a editarla.',\n\t\tconfirmDelete: '¿Eliminar \"{key}\"? Todo lo que la lee vuelve a su valor predeterminado.',\n\t\tconfirmDeleteIn:\n\t\t\t'¿Eliminar \"{key}\" de {env}? Todo lo que la lee vuelve a su valor predeterminado.',\n\t\thistory: 'Historial',\n\t\tunknownActor: 'desconocido',\n\t\trollBack: 'Restaurar',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Introduce una clave.',\n\t\tkeyPattern: 'Empieza por una letra; usa letras, dígitos, \".\", \"_\" o \"-\" (máx. 128).',\n\t\texists: '\"{key}\" ya existe en {env} — ábrela desde la lista para editarla.',\n\t\tnumber: 'Introduce un número.',\n\t\tboolean: 'Usa true o false.',\n\t\tjson: 'JSON no válido: {detail}',\n\t},\n};\nexport default config;\n","import type en from '../en/templates';\n\nconst templates: typeof en = {\n\tdefaultLocale: 'idioma predeterminado',\n\tdefaultChip: 'predeterminado',\n\tbuiltInBadge: 'integrado',\n\tsubject: 'Asunto',\n\thtmlBody: 'Cuerpo HTML',\n\ttextBody: 'Cuerpo en texto plano',\n\tlist: {\n\t\ttitle: 'Plantillas',\n\t\tnewTemplate: 'Nueva plantilla',\n\t\thint: 'Cada correo que envía la aplicación. Abre uno para editar su contenido y ver la vista previa en directo.',\n\t\tloading: 'Cargando plantillas…',\n\t\topenLocale: 'Abrir la versión {locale} de {type}',\n\t\tlegend: 'Sólido: una versión que guardaste. Discontinuo: la versión integrada de Fonderie, sin editar. Tachado: desactivada.',\n\t\tlanguages: 'Idiomas',\n\t},\n\teditor: {\n\t\tloading: 'Cargando plantilla…',\n\t\tlocales: 'Idiomas',\n\t\tdiscardChanges: 'Este idioma tiene cambios sin guardar. ¿Descartarlos y cambiar de idioma?',\n\t\taddLocale: '+ Añadir idioma',\n\t\tbuiltInNote: 'correo integrado: se puede editar o restaurar, no eliminar',\n\t\tactive: 'Activa',\n\t\tconflict:\n\t\t\t'Alguien cambió esta plantilla desde que la abriste. Recarga para ver su cambio y vuelve a editarla.',\n\t\tnoChanges: 'No hay cambios que guardar',\n\t\tsampleData: 'Datos de ejemplo',\n\t\tsampleNotObject: 'Los datos de ejemplo deben ser un objeto JSON.',\n\t\tsampleInvalid: 'Los datos de ejemplo no son un JSON válido.',\n\t\tpreview: 'Vista previa',\n\t\tpreviewTitle: 'Vista previa de la plantilla',\n\t\trendering: 'Generando…',\n\t\tlive: 'En directo',\n\t\tnothingRendered: 'Todavía no se ha generado nada.',\n\t\thistory: 'Historial',\n\t\tunknownActor: 'desconocido',\n\t\trollBack: 'Restaurar',\n\t\tconfirmDelete: '¿Eliminar \"{type}\"?',\n\t\tconfirmDeleteLocale:\n\t\t\t'¿Eliminar la versión {locale} de \"{type}\"? Las personas de ese idioma recibirán la versión predeterminada.',\n\t\tbuiltInCopy: 'Versión integrada de Fonderie. Al guardarla se crea tu propia versión.',\n\t\tresetToBuiltIn: 'Restablecer la versión integrada',\n\t\tconfirmReset: '¿Reemplazar tu versión {locale} por la versión integrada de Fonderie?',\n\t\tchain: 'Respaldo: {chain}',\n\t\twhoReceives: 'Quién recibe qué',\n\t\twhoPlaceholder: 'Un idioma, p. ej. fr-BE',\n\t\tcheck: 'Comprobar',\n\t\treceives: 'Un usuario {requested} recibe la versión {sent}.',\n\t\tsourceSaved: 'Es tu versión guardada.',\n\t\tsourceBuiltIn: 'Es la versión integrada de Fonderie.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'Nueva plantilla',\n\t\ttitleLocale: 'Añadir un idioma a {type}',\n\t\thintNew:\n\t\t\t'Para un correo que envía tu aplicación y que aún no tiene contenido guardado. El tipo debe coincidir con lo que envía la aplicación.',\n\t\thintLocale:\n\t\t\t'Parte del contenido predeterminado. Las personas cuyo idioma coincide reciben esta versión; los demás conservan la predeterminada.',\n\t\ttype: 'Tipo',\n\t\tlocale: 'Idioma',\n\t\tlocaleOptional: 'Idioma (opcional — vacío es el predeterminado)',\n\t\tcreating: 'Creando…',\n\t\tsubmitNew: 'Crear plantilla',\n\t\tsubmitLocale: 'Añadir idioma',\n\t\terrorType: 'Tipo: letras minúsculas, dígitos, - y _ (p. ej. weekly-digest).',\n\t\terrorLocaleRequired: 'Elige el idioma que quieres añadir, p. ej. fr o fr-CA.',\n\t\terrorLocale: 'Idioma: una etiqueta de idioma como fr, es o fr-CA.',\n\t\terrorText: 'El cuerpo en texto plano es obligatorio — es lo que puede mostrar cualquier cliente de correo.',\n\t\texists: '\"{type}\" ya existe — ábrela desde la lista para editarla.',\n\t\texistsLocale: '\"{type}\" ({locale}) ya existe — ábrela desde la lista para editarla.',\n\t\tuntranslated: 'Todavía en la versión predeterminada: {fields}. Tradúcelos antes de añadir este idioma.',\n\t\terrorDefaultLocale: '{locale} es la versión predeterminada de este correo. Edita la predeterminada en su lugar.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst es = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default es;\n","import type en from '../en/common';\n\nconst common: typeof en = {\n\trefresh: 'Actualiser',\n\tworking: 'En cours…',\n\tloading: 'Chargement…',\n\tloadMore: 'Charger plus',\n\tsave: 'Enregistrer',\n\tsaving: 'Enregistrement…',\n\tcancel: 'Annuler',\n\tdelete: 'Supprimer',\n\tdeleting: 'Suppression…',\n\tback: 'Retour',\n\topen: 'Ouvrir',\n\tcopy: 'Copier',\n\tcopied: 'Copié',\n\tdismiss: 'Fermer',\n\tconfirm: 'Confirmer',\n\tcontinue: 'Continuer',\n\treload: 'Recharger',\n\tsearch: 'Rechercher',\n\tlookUp: 'Rechercher',\n\tfilter: 'Filtrer',\n\tyes: 'oui',\n\tno: 'non',\n\tnone: 'Aucun.',\n\tnever: 'jamais',\n\tyou: 'vous',\n\tall: 'Tous',\n\tallEnvironments: 'Tous les environnements',\n\tlanguage: 'Langue',\n\ttheme: 'Thème',\n\tthemeSystem: 'Système',\n\tthemeLight: 'Clair',\n\tthemeDark: 'Sombre',\n\tstatus: {\n\t\tactive: 'actif',\n\t\tinactive: 'inactif',\n\t\tready: 'prêt',\n\t\terror: 'erreur',\n\t\tadvice: 'conseil',\n\t\tok: 'ok',\n\t\tfailed: 'échec',\n\t\tskipped: 'ignoré',\n\t\tsuspended: 'suspendu',\n\t\tdeleted: 'supprimé',\n\t\tdisabled: 'désactivé',\n\t\tlocked: 'verrouillé',\n\t\tpending: 'en attente',\n\t\tset: 'défini',\n\t\tmissing: 'manquant',\n\t\tfree: 'gratuit',\n\t},\n};\nexport default common;\n","import type en from '../en/nav';\n\nconst nav: typeof en = {\n\tgroups: {\n\t\ttoday: \"Aujourd'hui\",\n\t\tsystem: 'Système',\n\t\tpeople: 'Personnes',\n\t\tmoney: 'Finances',\n\t\tsettings: 'Réglages',\n\t\tmessaging: 'Messagerie',\n\t\tactivity: 'Activité',\n\t},\n\titems: {\n\t\tattention: 'À traiter',\n\t\tmodules: 'Modules',\n\t\tenvironment: 'Environnement',\n\t\tdoctor: 'Diagnostic',\n\t\troutes: 'Routes',\n\t\tusers: 'Utilisateurs',\n\t\tcatalog: 'Catalogue',\n\t\tsubscriptions: 'Abonnements',\n\t\tsettings: 'Configuration et secrets',\n\t\ttemplates: 'Modèles',\n\t\taudit: 'Audit',\n\t\tlog: \"Journal d'administration\",\n\t\toperators: 'Opérateurs',\n\t\ttokens: 'Jetons',\n\t\tmigrations: 'Migrations',\n\t},\n};\nexport default nav;\n","import type en from '../en/shell';\n\nconst shell: typeof en = {\n\topenMenu: 'Ouvrir le menu',\n\tcloseMenu: 'Fermer le menu',\n\tnavLabel: 'Administration',\n\tmissingClient: 'Fournissez un {client} pour utiliser cette page.',\n};\nexport default shell;\n","import type en from '../en/session';\n\nconst session: typeof en = {\n\tsignInTitle: \"Se connecter à l'administration\",\n\tadminToken: \"Jeton d'administration\",\n\tpasteToken: 'Collez votre jeton',\n\ttokenFoot:\n\t\t'Conservé pour cet onglet uniquement et envoyé dans un en-tête Bearer — jamais stocké sur le serveur. Un jeton limité à la lecture suffit pour consulter et ne peut pas révéler les secrets.',\n\ttokenRefused: 'Ce jeton a été refusé.',\n\tunreachable: \"Impossible de joindre l'interface d'administration : {error}\",\n\tforgetToken: 'Oublier le jeton',\n\tsignOut: 'Se déconnecter',\n\tgenericError: \"Une erreur s'est produite. Réessayez.\",\n\tstepOf: 'Étape {n} sur {total}',\n\tsteps: {\n\t\tadminToken: \"Jeton d'administration\",\n\t\taccount: 'Votre compte',\n\t\tauthenticator: 'Authentification',\n\t\tbackupCodes: 'Codes de secours',\n\t\tnewPassword: 'Nouveau mot de passe',\n\t},\n\tchecking: 'Vérification…',\n\twelcomeTitle: 'Bienvenue — configurons votre console',\n\twelcomeSubtitle:\n\t\t\"C'est la première connexion sur {host}. Collez le jeton d'administration de la configuration de votre déploiement pour commencer. Il ne sera demandé qu'une seule fois.\",\n\tcreateAccountTitle: 'Créez votre compte',\n\tcreateAccountSubtitle:\n\t\t\"Désormais, vous vous connectez avec cet e-mail et ce mot de passe, ainsi qu'une application d'authentification. Le jeton d'administration reste réservé aux scripts et aux urgences.\",\n\temail: 'E-mail',\n\tnameOptional: 'Nom (facultatif)',\n\tyourNameOptional: 'Votre nom (facultatif)',\n\tpassword: 'Mot de passe',\n\tnewPassword: 'Nouveau mot de passe',\n\tconfirmPassword: 'Confirmez le mot de passe',\n\tpasswordHint: 'Au moins 12 caractères.',\n\tpasswordHintNext:\n\t\t\"Au moins 12 caractères. Vous configurerez ensuite une application d'authentification.\",\n\tpasswordsMismatch: 'Les deux mots de passe ne correspondent pas.',\n\tcreating: 'Création…',\n\tcreateAccount: 'Créer le compte',\n\tloginFoot:\n\t\t\"Il n'y a pas d'inscription : les opérateurs sont invités par un autre opérateur. Accès bloqué ? Demandez un lien de récupération à un autre opérateur.\",\n\tbackupCode: 'Code de secours',\n\tauthenticatorCode: \"Code d'authentification\",\n\tuseApp: \"Utiliser plutôt l'application d'authentification\",\n\tuseBackup: 'Utiliser plutôt un code de secours',\n\tenrollTitle: \"Configurez votre application d'authentification\",\n\tenrollSubtitle:\n\t\t\"Chaque connexion à cette console demande un code d'une application d'authentification — 1Password, Google Authenticator, Authy ou toute application TOTP.\",\n\tenrollScan: \"Ouvrez votre application d'authentification et scannez ce code.\",\n\tenrollEnter: 'Saisissez les six chiffres affichés.',\n\tqrAlt: \"Code QR pour votre application d'authentification\",\n\tcantScan: 'Impossible de scanner ? Saisissez plutôt une clé de configuration',\n\tpreparing: 'Préparation…',\n\tcancelSignOut: 'Annuler et se déconnecter',\n\tcodeFromApp: \"Code de l'application\",\n\tverifyContinue: 'Vérifier et continuer',\n\tbackupTitle: 'Enregistrez vos codes de secours',\n\tbackupSubtitle:\n\t\t'Si vous perdez votre téléphone, chacun de ces codes vous connecte une seule fois. Ils ne sont affichés que maintenant.',\n\tbackupFileHeader: \"Codes de secours pour l'administration de {host}\",\n\tdownload: 'Télécharger',\n\tsavedCheckbox: \"J'ai enregistré ces codes en lieu sûr\",\n\topenConsole: 'Ouvrir la console',\n\tlinkInvalidTitle: 'Ce lien ne peut pas être utilisé',\n\tcheckingLink: 'Vérification de votre lien…',\n\tjoinTitle: \"Rejoindre la console d'administration\",\n\trecoverTitle: 'Récupérer votre compte',\n\tjoinSubtitle:\n\t\t\"Vous avez été invité en tant que {email}. Choisissez un mot de passe, puis configurez une application d'authentification.\",\n\trecoverSubtitle:\n\t\t\"Définissez un nouveau mot de passe pour {email}. Vous configurerez à nouveau votre application d'authentification.\",\n\tstepUpTitle: \"Confirmez qu'il s'agit bien de vous\",\n\tstepUpSubtitle: 'Cette action demande un nouveau code. Il reste valable cinq minutes.',\n\ttwoStepTitle: 'Vérification en deux étapes',\n\ttwoStepSubtitle: \"Saisissez le code de votre application d'authentification.\",\n\tverify: 'Vérifier',\n\tchangeLanguage: 'Changer de langue (actuelle : {name})',\n\tthemeChoice: 'Thème : {name}',\n\terrors: {\n\t\tINVALID_CREDENTIALS: 'Cet e-mail et ce mot de passe ne correspondent à aucun opérateur.',\n\t\tINVALID_CODE: \"Ce code n'a pas fonctionné. Les codes changent toutes les 30 secondes.\",\n\t\tLOCKED: 'Trop de tentatives. Réessayez dans {minutes} minute(s).',\n\t\tLOCKED_GENERIC: 'Trop de tentatives. Réessayez dans quelques minutes.',\n\t\tRATE_LIMITED: 'Trop de tentatives depuis cette adresse. Patientez quelques minutes.',\n\t\tWEAK_PASSWORD:\n\t\t\t'Choisissez un mot de passe plus robuste — au moins 12 caractères, difficile à deviner.',\n\t\tINVALID_LINK: 'Ce lien a expiré ou a déjà été utilisé. Demandez-en un nouveau.',\n\t\tALREADY_OPERATOR: 'Cet e-mail est déjà celui d’un opérateur. Connectez-vous plutôt.',\n\t\tALREADY_CLAIMED: 'Cette console a déjà des opérateurs. Demandez une invitation à l’un d’eux.',\n\t\tCROSS_ORIGIN: \"Cette requête ne provient pas de la page d'administration.\",\n\t},\n};\nexport default session;\n","import type en from '../en/attention';\n\nconst attention: typeof en = {\n\ttitle: 'À traiter',\n\tlead: 'Ce qui demande votre attention sur ce déploiement',\n\tleadChecked: 'Ce qui demande votre attention sur ce déploiement · vérifié à {time}',\n\tneedsAction: 'Action requise',\n\tneedsActionHint: 'erreurs à corriger',\n\tadvice: 'Conseils',\n\tadviceHint: 'à examiner',\n\tmodulesReady: 'Modules prêts',\n\tmodulesReadyHint: 'admin {version}',\n\troutes: 'Routes',\n\trunning: 'Vérifications en cours…',\n\temptyTitle: 'Rien à traiter',\n\temptyBody: 'Toutes les vérifications réussissent. Vérifié le {time}.',\n};\nexport default attention;\n","import type en from '../en/modules';\n\nconst modules: typeof en = {\n\ttitle: 'Modules',\n\tlead: 'Chaque module installé, sa version et son état de préparation.',\n\tleadSummary: \"{env} · admin {version} · journal d'administration {log} · {routes} routes\",\n\tlogOn: 'activé',\n\tlogOff: 'désactivé',\n\tcolModule: 'Module',\n\tcolVersion: 'Version',\n\tcolReadiness: 'État',\n\tcolAdmin: 'Admin',\n\tnotReported: 'non communiquée',\n\tdescribesAdmin: \"décrit l'admin\",\n};\nexport default modules;\n","import type en from '../en/environment';\n\nconst environment: typeof en = {\n\ttitle: 'Environnement',\n\tlead: \"Si chaque module est configuré et si chaque variable lue par l'application est définie. Les valeurs ne sont jamais affichées.\",\n\tmissingCount: '{n} manquantes',\n\tallSet: 'toutes définies',\n\tvariables: 'Variables',\n\tnoVariables: 'Aucune variable déclarée — passez `env` à AdminModule.',\n\tmoduleReadiness: 'État des modules',\n\tproblemOne: '1 problème',\n\tproblemMany: '{n} problèmes',\n};\nexport default environment;\n","import type en from '../en/doctor';\n\nconst doctor: typeof en = {\n\ttitle: 'Diagnostic',\n\tlead: 'Toutes les vérifications de cohérence des modules installés, lancées à la demande.',\n\tallPass: 'toutes les vérifications réussissent',\n\toneFailed: 'une vérification a échoué',\n\trunAgain: 'Relancer',\n\trunning: 'Vérifications en cours…',\n\tcolResult: 'Résultat',\n\tcolCheck: 'Vérification',\n\tcolTime: 'Durée',\n};\nexport default doctor;\n","import type en from '../en/routes';\n\nconst routes: typeof en = {\n\ttitle: 'Routes',\n\tlead: 'Chaque route exposée, avec sa protection.',\n\tleadCount: '{n} routes exposées par ce déploiement, avec la protection placée devant chacune.',\n\tfilterPlaceholder: 'Filtrer par chemin, méthode, module…',\n\tfilterLabel: 'Filtrer les routes',\n\tcolMethod: 'Méthode',\n\tcolPath: 'Chemin',\n\tcolGuard: 'Protection',\n\tcolModule: 'Module',\n\tapplication: 'application',\n\tnoMatch: 'Aucune route ne correspond à « {q} ».',\n};\nexport default routes;\n","import type en from '../en/log';\n\nconst log: typeof en = {\n\ttitle: \"Journal d'administration\",\n\tlead: 'Chaque requête passée par cette console, de la plus récente à la plus ancienne — y compris les requêtes refusées.',\n\toff: \"Le journal d'administration est désactivé — fournissez un store à AdminModule.\",\n\tempty: 'Aucune requête pour le moment',\n\tcolWhen: 'Date',\n\tcolActor: 'Auteur',\n\tcolRequest: 'Requête',\n\tcolStatus: 'Statut',\n\tcolModule: 'Module',\n};\nexport default log;\n","import type en from '../en/migrations';\n\nconst migrations: typeof en = {\n\ttitle: 'Migrations',\n\tlead: 'Les changements de schéma livrés par chaque module, et si cette base de données les contient.',\n\tneedsWrite: \"L'application des migrations nécessite un jeton avec le droit d'écriture.\",\n\tfirstInstall:\n\t\t\"Cette base de données n'a jamais été migrée — elle est traitée comme une première installation, rien n'est donc retenu.\",\n\tupToDate: 'Tous les modules sont à jour',\n\tnoPending: 'Aucune migration en attente.',\n\tpendingCount: '{n} en attente',\n\tdestructive: 'destructive',\n\tadditive: 'additive',\n\tblockedBy: \"Appliquez d'abord « {module} » — il s'exécute avant celui-ci et est en retard.\",\n\tdestructiveBlocked:\n\t\t'Contient une migration qui supprime des données. Aucune migration inverse ne les restaure — appliquez-la via la CI ou `npm run migrate`.',\n\tconfirmApply:\n\t\t'Appliquer {n} migration(s) à « {module} » ? Cela modifie le schéma de la base de données.',\n\tapplyOne: 'Appliquer 1 migration',\n\tapplyMany: 'Appliquer {n} migrations',\n};\nexport default migrations;\n","import type en from '../en/tokens';\n\nconst tokens: typeof en = {\n\ttitle: 'Jetons',\n\tlead: 'Les identifiants des machines : la robustesse du jeton racine, les jetons à portée limitée pour la CLI et la CI, et les éventuels jetons hérités par module. Les personnes se connectent en tant qu’opérateurs.',\n\tneedsRoot:\n\t\t'Émettre et révoquer nécessitent le jeton racine (celui de la configuration de votre déploiement).',\n\trootToken: 'Jeton racine',\n\tstrong: 'robuste',\n\tweak: 'faible',\n\tissuedTokens: 'Jetons émis',\n\tissuingOff:\n\t\t\"L'émission est désactivée — fournissez un store à AdminModule et exécutez ses migrations.\",\n\tcopyNow: 'Copiez-le maintenant — il ne sera plus jamais affiché.',\n\tnamePlaceholder: 'nom',\n\tnameLabel: 'Nom',\n\tscope: {\n\t\tread: 'lecture',\n\t\twrite: 'écriture',\n\t\tsecrets: 'secrets',\n\t},\n\tdaysPlaceholder: 'jours (facultatif)',\n\tdaysLabel: 'Jours',\n\tissue: 'Émettre un jeton',\n\tcol: {\n\t\tname: 'Nom',\n\t\tscopes: 'Portées',\n\t\tcreated: 'Créé le',\n\t\texpires: 'Expire le',\n\t\tlastUsed: 'Dernière utilisation',\n\t},\n\trevoked: 'révoqué',\n\trevoke: 'Révoquer',\n\trevokeConfirm: 'Révoquer « {name} » ? Tout ce qui l’utilise cesse de fonctionner immédiatement.',\n\temptyTitle: 'Aucun jeton à portée limitée pour le moment',\n\temptyBody:\n\t\t'Émettez un jeton en lecture seule pour un tableau de bord ou un collègue au lieu de partager le jeton racine.',\n\tlegacyTitle: 'Jetons hérités par brique',\n\tlegacyNone: \"Aucun — la surface d'administration de chaque brique passe par ce jeton.\",\n\tlegacyRow: 'enregistre encore ses routes autonomes avec son propre jeton (obsolète)',\n};\nexport default tokens;\n","import type en from '../en/operators';\n\nconst operators: typeof en = {\n\ttitle: 'Opérateurs',\n\tlead: \"Les personnes qui peuvent se connecter à cette console. Chacune utilise un mot de passe et une application d'authentification ; il n'y a pas d'inscription.\",\n\tlevel: {\n\t\tread: 'Lecture seule',\n\t\teditor: 'Éditeur',\n\t\towner: 'Propriétaire',\n\t},\n\tlevelHint: {\n\t\tread: 'consulter, sans rien modifier',\n\t\teditor: 'modifier la configuration, les modèles et les utilisateurs',\n\t\towner: 'aussi les secrets, les jetons et les opérateurs',\n\t},\n\tneedsOwner: 'La gestion des opérateurs nécessite le niveau Propriétaire.',\n\tmintedTitle: \"Envoyez ce lien à {email}. Il n'est affiché qu'une fois.\",\n\tmintedBody: \"Il ne fonctionne qu'une fois et expire le {date}.\",\n\tinvite: 'Inviter',\n\tinvitePlaceholder: 'collegue@entreprise.com',\n\tinviteLabel: 'E-mail à inviter',\n\taccessLevelLabel: \"Niveau d'accès\",\n\taccessLevelFor: \"Niveau d'accès de {email}\",\n\tcreateInvite: \"Créer un lien d'invitation\",\n\temptyTitle: 'Aucun opérateur pour le moment',\n\tcol: {\n\t\toperator: 'Opérateur',\n\t\taccess: 'Accès',\n\t\tstatus: 'Statut',\n\t\tlastSignIn: 'Dernière connexion',\n\t},\n\tsettingUp: 'configuration en cours',\n\tbackupCodesLeftOne: '{n} code de secours restant',\n\tbackupCodesLeftMany: '{n} codes de secours restants',\n\trecoveryLink: 'Lien de récupération',\n\trecoveryConfirm:\n\t\t\"Créer un lien de récupération pour {email} ? Cela le déconnecte partout ; le lien permet de définir un nouveau mot de passe et une nouvelle application d'authentification.\",\n\tdisable: 'Désactiver',\n\tenable: 'Activer',\n\tdisableConfirm: 'Désactiver {email} ? Il est déconnecté immédiatement.',\n\tpendingLinks: 'Liens en attente',\n\tlinkKind: {\n\t\tinvite: 'invitation',\n\t\trecovery: 'récupération',\n\t},\n\texpiresOn: 'expire le {date}',\n\trevoke: 'Révoquer',\n};\nexport default operators;\n","import type en from '../en/users';\n\nconst users: typeof en = {\n\ttitle: 'Utilisateurs',\n\tlead: 'Tous les inscrits. Ouvrez un compte pour voir ses sessions, ses connexions et les commandes de suspension et de déconnexion.',\n\temailPlaceholder: 'adresse e-mail',\n\temailLabel: 'E-mail',\n\tallUsers: 'Tous les utilisateurs',\n\twhichAccounts: 'Quels comptes',\n\tactiveAccounts: 'Actifs',\n\tdeletedAccounts: 'Supprimés',\n\tnoUserWithEmail: 'Aucun utilisateur avec cette adresse e-mail.',\n\tmissingIdPrefix: \"Aucun compte avec l'id\",\n\tmissingIdBody:\n\t\t\"Il a été supprimé, ou n'a jamais existé ici. Ses données de facturation sont conservées.\",\n\tplanCredits: 'Forfait et crédits',\n\temptyTitle: 'Aucun utilisateur pour le moment',\n\temptyBody: 'Les inscriptions apparaissent ici au fil de l’eau.',\n\tcol: {\n\t\temail: 'E-mail',\n\t\tname: 'Nom',\n\t\tplan: 'Forfait',\n\t\tcreated: 'Créé le',\n\t\tstatus: 'Statut',\n\t},\n\tfield: {\n\t\tid: 'id',\n\t\temail: 'e-mail',\n\t\tverified: 'vérifié',\n\t\tmfa: 'MFA',\n\t\tprovider: 'fournisseur',\n\t\tlastLogin: 'dernière connexion',\n\t\tcreated: 'créé le',\n\t},\n\tpasswordProvider: 'mot de passe',\n\tnoPasswordSet: 'aucun mot de passe défini',\n\tdeletedOn: 'Supprimé le {date}.',\n\tdeletedBody:\n\t\t'Le compte ne peut plus se connecter et sera effacé lors de la purge de conservation. Ses données de facturation sont conservées.',\n\tsuspend: 'Suspendre',\n\tunsuspend: 'Réactiver',\n\tsignOutEverywhere: 'Déconnecter partout',\n\tliveSessions: 'Sessions actives',\n\tsince: 'depuis le {date}',\n\trecentSignIns: 'Connexions récentes',\n\tnoneRecorded: 'Aucune enregistrée.',\n\toutcome: {\n\t\tsuccess: 'réussie',\n\t\tfailure: 'échec',\n\t},\n\tproxyVpn: 'proxy/VPN',\n\thosting: 'hébergeur',\n};\nexport default users;\n","import type en from '../en/billing';\n\nconst billing: typeof en = {\n\tstatusLabel: {\n\t\tactive: 'actif',\n\t\ttrialing: \"en période d'essai\",\n\t\tpast_due: 'en retard de paiement',\n\t\tunpaid: 'impayé',\n\t\tcanceled: 'résilié',\n\t\tincomplete: 'incomplet',\n\t\tincomplete_expired: 'incomplet (expiré)',\n\t\tpaused: 'en pause',\n\t},\n\tintervalLabel: {\n\t\tmonth: 'mois',\n\t\tyear: 'an',\n\t},\n\trenews: 'Renouvelé le',\n\tends: 'Se termine le',\n\tended: 'Terminé le',\n\tloading: 'Chargement de la facturation…',\n\tplan: 'Forfait',\n\tfree: 'Gratuit',\n\tnoSubscription: 'aucun abonnement',\n\tcredits: 'Crédits',\n\tcurrencyPlaceholder: 'devise',\n\tcurrencyLabel: 'Devise du portefeuille',\n\tcurrencyTitle: 'Afficher le portefeuille dans une autre devise',\n\tbreakdown: '{permanent} permanents · {allowance} d’allocation du forfait',\n\texpires: ' (expire le {date})',\n\tnoWallet: \"Aucun portefeuille — la facturation n'a pas de configuration de portefeuille.\",\n\tgrantCredits: 'Octroyer des crédits',\n\tamountPlaceholder: 'montant ({currency})',\n\tamountLabel: 'Montant',\n\treasonPlaceholder: 'motif (facultatif)',\n\treasonLabel: 'Motif',\n\tgrant: 'Octroyer',\n\tgranted: '{amount} {currency} octroyés.',\n\tnoMovements: 'Aucun mouvement de crédits pour le moment',\n\tcol: {\n\t\twhen: 'Date',\n\t\tkind: 'Type',\n\t\tamount: 'Montant',\n\t\tnote: 'Note',\n\t},\n\tledgerKind: {\n\t\tpurchase: 'achat',\n\t\tgrant: 'octroi',\n\t\tusage: 'utilisation',\n\t\trefund: 'remboursement',\n\t\tadjustment: 'ajustement',\n\t\texpiry: 'expiration',\n\t},\n\tsubscriptions: {\n\t\ttitle: 'Abonnements',\n\t\tlead: \"Qui paie, et qui est en retard. Le forfait et les crédits d'un utilisateur figurent aussi sur sa page dans Utilisateurs — les utilisateurs gratuits n'apparaissent que là.\",\n\t\tdetailLead: 'Forfait, crédits et mouvements.',\n\t\tback: 'Tous les abonnements',\n\t\tfilterLabel: 'Filtrer par statut',\n\t\tfilter: {\n\t\t\tall: 'Tous',\n\t\t\tactive: 'Actifs',\n\t\t\ttrialing: \"En période d'essai\",\n\t\t\tpastDue: 'En retard',\n\t\t\tcanceled: 'Résiliés',\n\t\t},\n\t\tempty: {\n\t\t\tall: 'Aucun abonnement pour le moment',\n\t\t\tactive: 'Aucun abonnement actif',\n\t\t\ttrialing: \"Aucun abonnement en période d'essai\",\n\t\t\tpastDue: 'Aucun abonnement en retard de paiement',\n\t\t\tcanceled: 'Aucun abonnement résilié',\n\t\t},\n\t\temptyHint: \"Les abonnements apparaissent ici dès qu'un client passe commande.\",\n\t\ttypeLabel: 'Type',\n\t\ttypeWorkspace: 'espace de travail',\n\t\ttypeUser: 'utilisateur',\n\t\tidPlaceholder: \"id de l'abonné\",\n\t\tidLabel: \"Id de l'abonné\",\n\t\tcol: {\n\t\t\tsubscriber: 'Abonné',\n\t\t\tplan: 'Forfait',\n\t\t\tstatus: 'Statut',\n\t\t\trenewsEnds: 'Renouvellement / fin',\n\t\t},\n\t\tcancels: 'résiliation prévue',\n\t},\n};\nexport default billing;\n","import type en from '../en/catalog';\n\nconst catalog: typeof en = {\n\ttitle: 'Catalogue',\n\tlead: 'Ce que vous vendez : les forfaits tels que configurés dans le code, et tels qu’enregistrés dans la base de données, côte à côte.',\n\tconfigured: 'Configurés (code)',\n\tstored: 'Enregistrés (base de données)',\n\temptyTitle: 'Aucun forfait enregistré',\n\temptyBody:\n\t\t\"Les forfaits sont configurés dans le code ; rien n'a été écrit dans la base de données.\",\n\tcol: {\n\t\tplan: 'Forfait',\n\t\ttier: 'Niveau',\n\t\tseats: 'Places',\n\t\tmonthly: 'Mensuel',\n\t\tyearly: 'Annuel',\n\t\ttrial: 'Essai',\n\t},\n\ttrialDays: '{n} j',\n\tdeleteConfirm: 'Supprimer le forfait enregistré « {name} » ?',\n};\nexport default catalog;\n","import type en from '../en/audit';\n\nconst audit: typeof en = {\n\ttitle: 'Audit',\n\tlead: \"Ce qui s'est passé, dans tous les espaces de travail sauf si vous en nommez un. Le verdict d'intégrité de la chaîne se trouve sur la page Diagnostic.\",\n\tworkspacePlaceholder: \"id d'espace de travail (tous si vide)\",\n\ttypePlaceholder: \"type d'événement\",\n\tactorPlaceholder: \"id de l'acteur\",\n\tfromLabel: 'Date de début',\n\tfromTitle: 'Du (inclus)',\n\ttoLabel: 'Date de fin',\n\ttoTitle: 'Au (inclus)',\n\tempty: 'Rien d’enregistré pour ce filtre',\n\tcol: {\n\t\twhen: 'Date',\n\t\ttype: 'Type',\n\t\tworkspace: 'Espace de travail',\n\t\tactor: 'Acteur',\n\t\trequest: 'Requête',\n\t},\n};\nexport default audit;\n","import type en from '../en/config';\n\nconst config: typeof en = {\n\tenvironment: 'Environnement',\n\treveal: 'Afficher',\n\ttype: {\n\t\ttext: 'texte',\n\t\tnumber: 'nombre',\n\t\tonOff: 'oui/non',\n\t\tjson: 'json',\n\t},\n\tshape: {\n\t\ttext: 'Texte',\n\t\tnumber: 'Nombre',\n\t\tonOff: 'Oui/non',\n\t\tlist: 'Liste',\n\t\tobject: 'Objet',\n\t\tempty: 'Vide',\n\t},\n\tlist: {\n\t\ttitle: 'Configuration',\n\t\tnewEntry: 'Nouvelle entrée',\n\t\thint: \"Drapeaux de fonctionnalité et réglages d'exécution — texte, nombres, oui/non ou JSON. Lus par l'application sans redéploiement.\",\n\t\tempty: 'Aucune entrée de configuration pour le moment.',\n\t\temptyCta: 'Créez-en une pour activer une fonctionnalité ou ajuster un réglage sans redéployer.',\n\t\temptyInEnv: 'Aucune configuration dans {env}. Les entrées de « all » s’y appliquent toujours.',\n\t\tpublicBadge: 'public',\n\t\tpublicTitle: 'Servi aux frontends par GET /config/public',\n\t\tpublicSummary: 'Ce que reçoivent les frontends ({n} clés publiques)',\n\t\tpublicSummaryOne: 'Ce que reçoivent les frontends (1 clé publique)',\n\t\tpublicHint:\n\t\t\t\"Exactement le corps de {route} — sans authentification, donc lisible par tous. Seules les clés que l'application déclare publiques y figurent.\",\n\t\tsecretsTitle: 'Secrets',\n\t\tnewSecret: 'Nouveau secret',\n\t\tsecretsHint: 'Chiffrés au repos ; les valeurs restent masquées jusqu’à leur affichage.',\n\t\tsecretsEmpty: 'Aucun secret pour le moment.',\n\t\tsecretsEmptyInEnv: 'Aucun secret dans {env}.',\n\t},\n\teditor: {\n\t\tnewEntry: 'Nouvelle entrée de configuration',\n\t\tnewSecret: 'Nouveau secret',\n\t\tenvironmentLabel: 'Environnement :',\n\t\tkey: 'Clé',\n\t\tenvironmentHint:\n\t\t\t'« all » est partagé par tous les environnements ; un environnement nommé (production, staging…) le remplace.',\n\t\tvalue: 'Valeur',\n\t\tnewValue: 'Nouvelle valeur',\n\t\tvaluePlaceholder: 'true · 42 · Maintenance prévue ce soir · {\"ids\": [\"m1\", \"m2\"]}',\n\t\tdetected: 'Détecté :',\n\t\tsaveAsText: 'Enregistrer plutôt comme texte',\n\t\ton: 'Oui (true)',\n\t\toff: 'Non (false)',\n\t\ttype: 'Type :',\n\t\tchangeType: 'Changer de type…',\n\t\tchangeTypeWarning:\n\t\t\t'Changer le type modifie ce que reçoit chaque écran qui lit cette clé. Vérifiez d’abord le code qui la lit.',\n\t\tdescription: 'Description',\n\t\tconflict:\n\t\t\t'Quelqu’un a modifié cette entrée depuis son ouverture. Rechargez pour voir sa modification, puis modifiez à nouveau.',\n\t\tconfirmDelete: 'Supprimer « {key} » ? Tout ce qui la lit revient à sa valeur par défaut.',\n\t\tconfirmDeleteIn:\n\t\t\t'Supprimer « {key} » de {env} ? Tout ce qui la lit revient à sa valeur par défaut.',\n\t\thistory: 'Historique',\n\t\tunknownActor: 'inconnu',\n\t\trollBack: 'Restaurer',\n\t},\n\terrors: {\n\t\tkeyRequired: 'Saisissez une clé.',\n\t\tkeyPattern:\n\t\t\t'Commencez par une lettre ; utilisez des lettres, des chiffres, « . », « _ » ou « - » (128 max).',\n\t\texists: '« {key} » existe déjà dans {env} — ouvrez-la depuis la liste pour la modifier.',\n\t\tnumber: 'Saisissez un nombre.',\n\t\tboolean: 'Utilisez true ou false.',\n\t\tjson: 'JSON non valide : {detail}',\n\t},\n};\nexport default config;\n","import type en from '../en/templates';\n\nconst templates: typeof en = {\n\tdefaultLocale: 'langue par défaut',\n\tdefaultChip: 'par défaut',\n\tbuiltInBadge: 'intégré',\n\tsubject: 'Objet',\n\thtmlBody: 'Corps HTML',\n\ttextBody: 'Corps en texte brut',\n\tlist: {\n\t\ttitle: 'Modèles',\n\t\tnewTemplate: 'Nouveau modèle',\n\t\thint: \"Chaque e-mail envoyé par l'application. Ouvrez-en un pour modifier son contenu et le prévisualiser en direct.\",\n\t\tloading: 'Chargement des modèles…',\n\t\topenLocale: 'Ouvrir la version {locale} de {type}',\n\t\tlegend: 'Plein : une version que vous avez enregistrée. Pointillés : la version intégrée de Fonderie, non modifiée. Barré : désactivée.',\n\t\tlanguages: 'Langues',\n\t},\n\teditor: {\n\t\tloading: 'Chargement du modèle…',\n\t\tlocales: 'Langues',\n\t\tdiscardChanges: 'Cette langue a des modifications non enregistrées. Les abandonner et changer de langue ?',\n\t\taddLocale: '+ Ajouter une langue',\n\t\tbuiltInNote: 'e-mail intégré : modifiable ou restaurable, mais pas supprimable',\n\t\tactive: 'Actif',\n\t\tconflict:\n\t\t\t'Quelqu’un a modifié ce modèle depuis son ouverture. Rechargez pour voir sa modification, puis modifiez à nouveau.',\n\t\tnoChanges: 'Aucune modification à enregistrer',\n\t\tsampleData: \"Données d'exemple\",\n\t\tsampleNotObject: \"Les données d'exemple doivent être un objet JSON.\",\n\t\tsampleInvalid: \"Les données d'exemple ne sont pas un JSON valide.\",\n\t\tpreview: 'Aperçu',\n\t\tpreviewTitle: 'Aperçu du modèle',\n\t\trendering: 'Rendu en cours…',\n\t\tlive: 'En direct',\n\t\tnothingRendered: 'Rien n’a encore été rendu.',\n\t\thistory: 'Historique',\n\t\tunknownActor: 'inconnu',\n\t\trollBack: 'Restaurer',\n\t\tconfirmDelete: 'Supprimer « {type} » ?',\n\t\tconfirmDeleteLocale:\n\t\t\t'Supprimer la version {locale} de « {type} » ? Les personnes de cette langue recevront la version par défaut.',\n\t\tbuiltInCopy: 'Version intégrée de Fonderie. L’enregistrer crée votre propre version.',\n\t\tresetToBuiltIn: 'Rétablir la version intégrée',\n\t\tconfirmReset: 'Remplacer votre version {locale} par la version intégrée de Fonderie ?',\n\t\tchain: 'Repli : {chain}',\n\t\twhoReceives: 'Qui reçoit quoi',\n\t\twhoPlaceholder: 'Une langue, p. ex. fr-BE',\n\t\tcheck: 'Vérifier',\n\t\treceives: 'Un utilisateur {requested} reçoit la version {sent}.',\n\t\tsourceSaved: 'C’est votre version enregistrée.',\n\t\tsourceBuiltIn: 'C’est la version intégrée de Fonderie.',\n\t},\n\tcreate: {\n\t\ttitleNew: 'Nouveau modèle',\n\t\ttitleLocale: 'Ajouter une langue à {type}',\n\t\thintNew:\n\t\t\t\"Pour un e-mail envoyé par votre application qui n'a pas encore de contenu enregistré. Le type doit correspondre à ce que l'application envoie.\",\n\t\thintLocale:\n\t\t\t'Part du contenu par défaut. Les personnes dont la langue correspond reçoivent cette version ; les autres gardent la version par défaut.',\n\t\ttype: 'Type',\n\t\tlocale: 'Langue',\n\t\tlocaleOptional: 'Langue (facultative — vide correspond à la langue par défaut)',\n\t\tcreating: 'Création…',\n\t\tsubmitNew: 'Créer le modèle',\n\t\tsubmitLocale: 'Ajouter la langue',\n\t\terrorType: 'Type : lettres minuscules, chiffres, - et _ (ex. weekly-digest).',\n\t\terrorLocaleRequired: 'Choisissez la langue à ajouter, par ex. fr ou fr-CA.',\n\t\terrorLocale: 'Langue : une étiquette de langue comme fr, es ou fr-CA.',\n\t\terrorText: 'Le corps en texte brut est obligatoire — c’est ce que tout client e-mail peut afficher.',\n\t\texists: '« {type} » existe déjà — ouvrez-le depuis la liste pour le modifier.',\n\t\texistsLocale: '« {type} » ({locale}) existe déjà — ouvrez-le depuis la liste pour le modifier.',\n\t\tuntranslated: 'Encore dans la version par défaut : {fields}. Traduisez-les avant d’ajouter cette langue.',\n\t\terrorDefaultLocale: '{locale} est la version par défaut de cet e-mail. Modifiez plutôt la version par défaut.',\n\t},\n};\nexport default templates;\n","import common from \"./common\";\nimport nav from \"./nav\";\nimport shell from \"./shell\";\nimport session from \"./session\";\nimport attention from \"./attention\";\nimport modules from \"./modules\";\nimport environment from \"./environment\";\nimport doctor from \"./doctor\";\nimport routes from \"./routes\";\nimport log from \"./log\";\nimport migrations from \"./migrations\";\nimport tokens from \"./tokens\";\nimport operators from \"./operators\";\nimport users from \"./users\";\nimport billing from \"./billing\";\nimport catalog from \"./catalog\";\nimport audit from \"./audit\";\nimport config from \"./config\";\nimport templates from \"./templates\";\n\n// One object per domain; each non-English file is typed against its English\n// counterpart, so a missing or extra key is a compile error.\nconst fr = { common, nav, shell, session, attention, modules, environment, doctor, routes, log, migrations, tokens, operators, users, billing, catalog, audit, config, templates };\nexport default fr;\n","import en from './en';\nimport es from './es';\nimport fr from './fr';\n\n// The admin console's own language — the OPERATOR's preference, independent\n// of the locales the app serves its customers. A founder in France can run\n// the console in French while every customer email stays English.\n//\n// English is canonical: its shape defines the key space, and fr/es are typed\n// against it, so a missing or extra key is a compile error (the pattern the\n// reference app uses for its own UI).\n\nexport const ADMIN_LOCALES = ['en', 'fr', 'es'] as const;\nexport type AdminLocale = (typeof ADMIN_LOCALES)[number];\nexport const DEFAULT_ADMIN_LOCALE: AdminLocale = 'en';\n\n/**\n * One value per console language, read-only. Frozen at runtime too: these\n * maps are shared by every console on the page, so an embedding app must not\n * be able to rename \"Français\" for everyone by assignment.\n */\nexport type LocaleMap<T> = Readonly<Record<AdminLocale, T>>;\n\n/** Native-language names, for the language menu. */\nexport const adminLocaleNames: LocaleMap<string> = Object.freeze({\n\ten: 'English',\n\tfr: 'Français',\n\tes: 'Español',\n});\n\n/** BCP 47 tags for Intl (dates, numbers). */\nexport const adminLocaleTags: LocaleMap<string> = Object.freeze({\n\ten: 'en-US',\n\tfr: 'fr-FR',\n\tes: 'es-ES',\n});\n\nexport const isAdminLocale = (value: unknown): value is AdminLocale =>\n\t(ADMIN_LOCALES as readonly unknown[]).includes(value);\n\n/** The first supported language in a browser's preference list, else English. */\nexport function detectAdminLocale(languages: readonly string[] = []): AdminLocale {\n\tfor (const tag of languages) {\n\t\tconst base = tag.toLowerCase().split('-')[0];\n\t\tif (isAdminLocale(base)) return base;\n\t}\n\treturn DEFAULT_ADMIN_LOCALE;\n}\n\nexport type AdminMessages = typeof en;\ntype MessagePath<T> = {\n\t[K in keyof T & string]: T[K] extends string\n\t\t? K\n\t\t: T[K] extends object\n\t\t\t? `${K}.${MessagePath<T[K]>}`\n\t\t\t: never;\n}[keyof T & string];\n/** Every dot-path to a string in the dictionary, e.g. 'users.title'. */\nexport type AdminMessageKey = MessagePath<AdminMessages>;\nexport type AdminMessageParams = Record<string, string | number>;\n\nconst dictionaries: LocaleMap<AdminMessages> = { en, fr, es };\n\n/**\n * A translator for one locale: t('users.title'), t('users.count', { n: 3 }).\n * A missing key renders the key itself — visible, never a crash. `{name}`\n * placeholders are interpolated from params.\n */\nexport function createAdminT(locale: AdminLocale | undefined = DEFAULT_ADMIN_LOCALE) {\n\tconst dict = dictionaries[locale] ?? dictionaries[DEFAULT_ADMIN_LOCALE];\n\tconst t = (key: AdminMessageKey, params?: AdminMessageParams): string => {\n\t\tlet node: unknown = dict;\n\t\tfor (const part of key.split('.')) {\n\t\t\tif (node == null || typeof node !== 'object') break;\n\t\t\tnode = (node as Record<string, unknown>)[part];\n\t\t}\n\t\tconst text = typeof node === 'string' ? node : key;\n\t\treturn params\n\t\t\t? text.replace(/\\{(\\w+)\\}/g, (m, n: string) => (n in params ? String(params[n]) : m))\n\t\t\t: text;\n\t};\n\treturn t;\n}\nexport type AdminT = ReturnType<typeof createAdminT>;\n\n/** Dates in the console's language: 'date', 'datetime' or 'time'. */\nexport function formatAdminDate(\n\tvalue: string | number | Date,\n\tlocale: AdminLocale | undefined = DEFAULT_ADMIN_LOCALE,\n\tstyle: 'date' | 'datetime' | 'time' = 'datetime',\n): string {\n\tconst d = value instanceof Date ? value : new Date(value);\n\tconst tag = adminLocaleTags[locale] ?? adminLocaleTags.en;\n\tif (style === 'date') return d.toLocaleDateString(tag);\n\tif (style === 'time') return d.toLocaleTimeString(tag);\n\treturn d.toLocaleString(tag);\n}\n"],"mappings":"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","names":["data","tokens","tokens","tokens","tokens","tokens","tokens","tokens","tokens","tokens","config","environment","catalog","common","common_default","nav","nav_default","shell","shell_default","session","session_default","attention","attention_default","modules","modules_default","environment","environment_default","doctor","doctor_default","routes","routes_default","log","log_default","migrations","migrations_default","tokens","tokens_default","operators","operators_default","users","users_default","billing","billing_default","catalog","catalog_default","audit","audit_default","config","config_default","templates","templates_default","common_default","nav_default","shell_default","session_default","attention_default","modules_default","environment_default","doctor_default","routes_default","log_default","migrations_default","tokens_default","operators_default","users_default","billing_default","catalog_default","audit_default","config_default","templates_default","common","common_default","nav","nav_default","shell","shell_default","session","session_default","attention","attention_default","modules","modules_default","environment","environment_default","doctor","doctor_default","routes","routes_default","log","log_default","migrations","migrations_default","tokens","tokens_default","operators","operators_default","users","users_default","billing","billing_default","catalog","catalog_default","audit","audit_default","config","config_default","templates","templates_default","common_default","nav_default","shell_default","session_default","attention_default","modules_default","environment_default","doctor_default","routes_default","log_default","migrations_default","tokens_default","operators_default","users_default","billing_default","catalog_default","audit_default","config_default","templates_default"]}
|