@smplkit/sdk 1.1.10 → 1.2.1
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/dist/index.cjs +1678 -409
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +658 -201
- package/dist/index.d.ts +658 -201
- package/dist/index.js +1664 -79
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-RF6LYU4V.js +0 -317
- package/dist/chunk-RF6LYU4V.js.map +0 -1
- package/dist/runtime-FT745HBO.js +0 -7
- package/dist/runtime-FT745HBO.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/resolve.ts","../src/config/runtime.ts","../src/index.ts","../src/config/client.ts","../src/errors.ts","../src/config/types.ts","../src/resolve.ts","../src/client.ts"],"sourcesContent":["/**\n * Deep-merge resolution algorithm for config inheritance chains.\n *\n * Mirrors the Python SDK's `_resolver.py` (ADR-024 §2.5–2.6).\n */\n\n/** A single entry in a config inheritance chain (child-to-root ordering). */\nexport interface ChainConfig {\n /** Config UUID. */\n id: string;\n /** Base key-value pairs (unwrapped from typed item definitions). */\n items: Record<string, unknown>;\n /**\n * Per-environment overrides.\n * Each entry is `{ values: { key: value, ... } }` — values are already\n * unwrapped from the server's `{ value: raw }` wrapper by the client layer.\n */\n environments: Record<string, unknown>;\n}\n\n/**\n * Recursively merge two dicts, with `override` taking precedence.\n *\n * Nested dicts are merged recursively. Non-dict values (strings, numbers,\n * booleans, arrays, null) are replaced wholesale.\n */\nexport function deepMerge(\n base: Record<string, unknown>,\n override: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (\n key in result &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key]) &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n result[key] = deepMerge(\n result[key] as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Resolve the full configuration for an environment given a config chain.\n *\n * Walks from root (last element) to child (first element), accumulating\n * values via deep merge so that child configs override parent configs.\n *\n * For each config in the chain, base `values` are merged with\n * environment-specific values (env wins), then that result is merged\n * on top of the accumulated parent result (child wins over parent).\n *\n * @param chain - Ordered list of config data from child (index 0) to root ancestor (last).\n * @param environment - The environment key to resolve for.\n */\nexport function resolveChain(chain: ChainConfig[], environment: string): Record<string, unknown> {\n let accumulated: Record<string, unknown> = {};\n\n // Walk from root to child (reverse order — chain is child-to-root)\n for (let i = chain.length - 1; i >= 0; i--) {\n const config = chain[i];\n const baseValues: Record<string, unknown> = config.items ?? {};\n\n // Environments are stored as { env_name: { values: { key: val } } }\n const envEntry = (config.environments ?? {})[environment];\n const envValues: Record<string, unknown> =\n envEntry !== null &&\n envEntry !== undefined &&\n typeof envEntry === \"object\" &&\n !Array.isArray(envEntry)\n ? (((envEntry as Record<string, unknown>).values ?? {}) as Record<string, unknown>)\n : {};\n\n // Merge environment overrides on top of base values (env wins)\n const configResolved = deepMerge(baseValues, envValues);\n\n // Merge this config's resolved values on top of accumulated parent values (child wins)\n accumulated = deepMerge(accumulated, configResolved);\n }\n\n return accumulated;\n}\n","/**\n * ConfigRuntime — runtime-plane value resolution with WebSocket updates.\n *\n * Holds a fully resolved local cache of config values for a specific\n * environment. All value-access methods are synchronous (local reads);\n * only {@link refresh} and {@link close} are async.\n *\n * A background WebSocket connection is maintained for real-time updates.\n * If the WebSocket fails, the runtime operates in cache-only mode and\n * reconnects automatically with exponential backoff.\n */\n\nimport WebSocket from \"ws\";\nimport { resolveChain } from \"./resolve.js\";\nimport type { ChainConfig } from \"./resolve.js\";\nimport type { ConfigChangeEvent, ConfigStats, ConnectionStatus } from \"./runtime-types.js\";\n\n/** @internal */\ninterface ChangeListener {\n callback: (event: ConfigChangeEvent) => void;\n key: string | null;\n}\n\n/** @internal */\ninterface WsConfigChangedMessage {\n type: \"config_changed\";\n config_id: string;\n changes: Array<{\n key: string;\n old_value: unknown;\n new_value: unknown;\n }>;\n}\n\n/** @internal */\ninterface WsConfigDeletedMessage {\n type: \"config_deleted\";\n config_id: string;\n}\n\ntype WsMessage =\n | { type: \"subscribed\"; config_id: string; environment: string }\n | { type: \"error\"; message: string }\n | WsConfigChangedMessage\n | WsConfigDeletedMessage;\n\n/** @internal */\nconst BACKOFF_MS = [1000, 2000, 4000, 8000, 16000, 32000, 60000];\n\n/** @internal Options for constructing a ConfigRuntime. */\nexport interface ConfigRuntimeOptions {\n configKey: string;\n configId: string;\n environment: string;\n chain: ChainConfig[];\n apiKey: string;\n baseUrl: string;\n fetchChain: (() => Promise<ChainConfig[]>) | null;\n}\n\n/**\n * Runtime configuration handle for a specific environment.\n *\n * Obtained by calling {@link Config.connect}. All value-access methods\n * are synchronous and served entirely from a local in-process cache.\n * The cache is populated eagerly on construction and kept current via\n * a background WebSocket connection.\n */\nexport class ConfigRuntime {\n private _cache: Record<string, unknown>;\n private _chain: ChainConfig[];\n private _fetchCount: number;\n private _lastFetchAt: string | null;\n private _closed = false;\n private _wsStatus: ConnectionStatus = \"disconnected\";\n private _ws: InstanceType<typeof WebSocket> | null = null;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _backoffIndex = 0;\n private _listeners: ChangeListener[] = [];\n\n private readonly _configId: string;\n private readonly _environment: string;\n private readonly _apiKey: string;\n private readonly _baseUrl: string;\n private readonly _fetchChain: (() => Promise<ChainConfig[]>) | null;\n\n /** @internal */\n constructor(options: ConfigRuntimeOptions) {\n this._configId = options.configId;\n this._environment = options.environment;\n this._apiKey = options.apiKey;\n this._baseUrl = options.baseUrl;\n this._fetchChain = options.fetchChain;\n this._chain = options.chain;\n this._cache = resolveChain(options.chain, options.environment);\n this._fetchCount = options.chain.length;\n this._lastFetchAt = new Date().toISOString();\n\n // Start WebSocket in background — non-blocking\n this._connectWebSocket();\n }\n\n // ---- Value access (synchronous, local cache) ----\n\n /**\n * Return the resolved value for `key`, or `defaultValue` if absent.\n *\n * @param key - The config key to look up.\n * @param defaultValue - Returned when the key is not present (default: null).\n */\n get(key: string, defaultValue: unknown = null): unknown {\n return key in this._cache ? this._cache[key] : defaultValue;\n }\n\n /**\n * Return the value as a string, or `defaultValue` if absent or not a string.\n */\n getString(key: string, defaultValue: string | null = null): string | null {\n const value = this._cache[key];\n return typeof value === \"string\" ? value : defaultValue;\n }\n\n /**\n * Return the value as a number, or `defaultValue` if absent or not a number.\n */\n getInt(key: string, defaultValue: number | null = null): number | null {\n const value = this._cache[key];\n return typeof value === \"number\" ? value : defaultValue;\n }\n\n /**\n * Return the value as a boolean, or `defaultValue` if absent or not a boolean.\n */\n getBool(key: string, defaultValue: boolean | null = null): boolean | null {\n const value = this._cache[key];\n return typeof value === \"boolean\" ? value : defaultValue;\n }\n\n /**\n * Return whether `key` is present in the resolved configuration.\n */\n exists(key: string): boolean {\n return key in this._cache;\n }\n\n /**\n * Return a shallow copy of the full resolved configuration.\n */\n getAll(): Record<string, unknown> {\n return { ...this._cache };\n }\n\n // ---- Change listeners ----\n\n /**\n * Register a listener that fires when a config value changes.\n *\n * @param callback - Called with a {@link ConfigChangeEvent} on each change.\n * @param options.key - If provided, the listener fires only for this key.\n * If omitted, the listener fires for all changes.\n */\n onChange(callback: (event: ConfigChangeEvent) => void, options?: { key?: string }): void {\n this._listeners.push({\n callback,\n key: options?.key ?? null,\n });\n }\n\n // ---- Diagnostics ----\n\n /**\n * Return diagnostic statistics for this runtime.\n */\n stats(): ConfigStats {\n return {\n fetchCount: this._fetchCount,\n lastFetchAt: this._lastFetchAt,\n };\n }\n\n /**\n * Return the current WebSocket connection status.\n */\n connectionStatus(): ConnectionStatus {\n return this._wsStatus;\n }\n\n // ---- Lifecycle ----\n\n /**\n * Force a manual refresh of the cached configuration.\n *\n * Re-fetches the full config chain via HTTP, re-resolves values, updates\n * the local cache, and fires listeners for any detected changes.\n *\n * @throws {Error} If no `fetchChain` function was provided on construction.\n */\n async refresh(): Promise<void> {\n if (!this._fetchChain) {\n throw new Error(\"No fetchChain function provided; cannot refresh.\");\n }\n\n const newChain = await this._fetchChain();\n const oldCache = this._cache;\n\n this._chain = newChain;\n this._cache = resolveChain(newChain, this._environment);\n this._fetchCount += newChain.length;\n this._lastFetchAt = new Date().toISOString();\n\n this._diffAndFire(oldCache, this._cache, \"manual\");\n }\n\n /**\n * Close the runtime connection.\n *\n * Shuts down the WebSocket and cancels any pending reconnect timer.\n * Safe to call multiple times.\n */\n async close(): Promise<void> {\n this._closed = true;\n this._wsStatus = \"disconnected\";\n\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n\n if (this._ws !== null) {\n this._ws.close();\n this._ws = null;\n }\n }\n\n /**\n * Async dispose support for `await using` (TypeScript 5.2+).\n */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n\n // ---- WebSocket internals ----\n\n private _buildWsUrl(): string {\n let url = this._baseUrl;\n if (url.startsWith(\"https://\")) {\n url = \"wss://\" + url.slice(\"https://\".length);\n } else if (url.startsWith(\"http://\")) {\n url = \"ws://\" + url.slice(\"http://\".length);\n } else {\n url = \"wss://\" + url;\n }\n url = url.replace(/\\/$/, \"\");\n return `${url}/api/ws/v1/configs?api_key=${this._apiKey}`;\n }\n\n private _connectWebSocket(): void {\n if (this._closed) return;\n\n this._wsStatus = \"connecting\";\n const wsUrl = this._buildWsUrl();\n\n try {\n const ws = new WebSocket(wsUrl);\n this._ws = ws;\n\n ws.on(\"open\", () => {\n if (this._closed) {\n ws.close();\n return;\n }\n this._backoffIndex = 0;\n this._wsStatus = \"connected\";\n ws.send(\n JSON.stringify({\n type: \"subscribe\",\n config_id: this._configId,\n environment: this._environment,\n }),\n );\n });\n\n ws.on(\"message\", (data: WebSocket.RawData) => {\n try {\n const msg = JSON.parse(String(data)) as WsMessage;\n this._handleMessage(msg);\n } catch {\n // ignore unparseable messages\n }\n });\n\n ws.on(\"close\", () => {\n if (!this._closed) {\n this._wsStatus = \"disconnected\";\n this._scheduleReconnect();\n }\n });\n\n ws.on(\"error\", () => {\n // 'close' will fire after 'error'; reconnect is handled there\n });\n } catch {\n if (!this._closed) {\n this._scheduleReconnect();\n }\n }\n }\n\n private _scheduleReconnect(): void {\n if (this._closed) return;\n\n const delay = BACKOFF_MS[Math.min(this._backoffIndex, BACKOFF_MS.length - 1)];\n this._backoffIndex++;\n this._wsStatus = \"connecting\";\n\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n // On reconnect, resync the cache to pick up changes missed while offline\n if (this._fetchChain) {\n this._fetchChain()\n .then((newChain) => {\n const oldCache = this._cache;\n this._chain = newChain;\n this._cache = resolveChain(newChain, this._environment);\n this._fetchCount += newChain.length;\n this._lastFetchAt = new Date().toISOString();\n this._diffAndFire(oldCache, this._cache, \"manual\");\n })\n .catch(() => {\n // ignore fetch errors during reconnect\n })\n .finally(() => {\n this._connectWebSocket();\n });\n } else {\n this._connectWebSocket();\n }\n }, delay);\n }\n\n private _handleMessage(msg: WsMessage): void {\n if (msg.type === \"config_changed\") {\n this._applyChanges(msg.config_id, msg.changes);\n } else if (msg.type === \"config_deleted\") {\n this._closed = true;\n void this.close();\n }\n }\n\n private _applyChanges(\n configId: string,\n changes: Array<{ key: string; old_value: unknown; new_value: unknown }>,\n ): void {\n const chainEntry = this._chain.find((c) => c.id === configId);\n if (!chainEntry) return;\n\n for (const change of changes) {\n const { key, new_value } = change;\n\n // Get or create the environment entry\n const envEntry =\n chainEntry.environments[this._environment] !== undefined &&\n chainEntry.environments[this._environment] !== null\n ? (chainEntry.environments[this._environment] as Record<string, unknown>)\n : null;\n const envValues =\n envEntry !== null && typeof envEntry === \"object\"\n ? ((envEntry.values ?? {}) as Record<string, unknown>)\n : null;\n\n if (new_value === null || new_value === undefined) {\n // Deletion: remove from base items and env values\n delete chainEntry.items[key];\n if (envValues) delete envValues[key];\n } else if (envValues && key in envValues) {\n // Update existing env-specific override\n envValues[key] = new_value;\n } else if (key in chainEntry.items) {\n // Update existing base value\n chainEntry.items[key] = new_value;\n } else {\n // New key — put in base items\n chainEntry.items[key] = new_value;\n }\n }\n\n const oldCache = this._cache;\n this._cache = resolveChain(this._chain, this._environment);\n this._diffAndFire(oldCache, this._cache, \"websocket\");\n }\n\n private _diffAndFire(\n oldCache: Record<string, unknown>,\n newCache: Record<string, unknown>,\n source: \"websocket\" | \"poll\" | \"manual\",\n ): void {\n const allKeys = new Set([...Object.keys(oldCache), ...Object.keys(newCache)]);\n\n for (const key of allKeys) {\n const oldVal = key in oldCache ? oldCache[key] : null;\n const newVal = key in newCache ? newCache[key] : null;\n\n if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n const event: ConfigChangeEvent = { key, oldValue: oldVal, newValue: newVal, source };\n this._fireListeners(event);\n }\n }\n }\n\n private _fireListeners(event: ConfigChangeEvent): void {\n for (const listener of this._listeners) {\n if (listener.key === null || listener.key === event.key) {\n try {\n listener.callback(event);\n } catch {\n // ignore listener errors to prevent one bad listener from stopping others\n }\n }\n }\n }\n}\n","/**\n * smplkit — Official TypeScript SDK for the smplkit platform.\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { SmplClient } from \"./client.js\";\nexport type { SmplClientOptions } from \"./client.js\";\n\n// Config — management plane\nexport { ConfigClient } from \"./config/client.js\";\nexport type { CreateConfigOptions, GetConfigOptions } from \"./config/types.js\";\nexport { Config } from \"./config/types.js\";\n\n// Config — runtime plane\nexport { ConfigRuntime } from \"./config/runtime.js\";\nexport type {\n ConfigChangeEvent,\n ConfigStats,\n ConnectionStatus,\n ConnectOptions,\n} from \"./config/runtime-types.js\";\n\n// Error hierarchy\nexport {\n SmplError,\n SmplConnectionError,\n SmplTimeoutError,\n SmplNotFoundError,\n SmplConflictError,\n SmplValidationError,\n} from \"./errors.js\";\n","/**\n * ConfigClient — management-plane operations for configs.\n *\n * Uses the generated OpenAPI types (`src/generated/config.d.ts`) via\n * `openapi-fetch` for all HTTP calls, keeping the client layer fully\n * type-safe without hand-coded request/response shapes.\n */\n\nimport createClient from \"openapi-fetch\";\nimport type { components, operations } from \"../generated/config.d.ts\";\nimport {\n SmplConflictError,\n SmplNotFoundError,\n SmplValidationError,\n SmplError,\n SmplConnectionError,\n SmplTimeoutError,\n} from \"../errors.js\";\nimport { Config } from \"./types.js\";\nimport type { ConfigUpdatePayload, CreateConfigOptions, GetConfigOptions } from \"./types.js\";\n\nconst BASE_URL = \"https://config.smplkit.com\";\n\ntype ApiConfig = components[\"schemas\"][\"Config\"];\ntype ApiConfigOutput = components[\"schemas\"][\"Config\"];\ntype ConfigResource = components[\"schemas\"][\"ConfigResource\"];\n\n/**\n * Extract raw values from typed items: `{key: {value, type?, description?}}` -> `{key: rawValue}`.\n * @internal\n */\nfunction extractItemValues(\n items: Record<string, { value: unknown }> | null | undefined,\n): Record<string, unknown> {\n if (!items) return {};\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(items)) {\n result[key] = item && typeof item === \"object\" && \"value\" in item ? item.value : item;\n }\n return result;\n}\n\n/**\n * Extract raw values from environment overrides.\n * Wire format: `{ env: { values: { key: { value: raw } } } }`\n * SDK format: `{ env: { values: { key: raw } } }`\n * @internal\n */\nfunction extractEnvironments(\n environments:\n | Record<string, { values?: Record<string, { value: unknown }> | null }>\n | null\n | undefined,\n): Record<string, unknown> {\n if (!environments) return {};\n const result: Record<string, unknown> = {};\n for (const [envName, envEntry] of Object.entries(environments)) {\n if (envEntry && typeof envEntry === \"object\" && envEntry.values) {\n const unwrapped: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(envEntry.values)) {\n unwrapped[key] = item && typeof item === \"object\" && \"value\" in item ? item.value : item;\n }\n result[envName] = { values: unwrapped };\n } else {\n result[envName] = envEntry;\n }\n }\n return result;\n}\n\n/** @internal */\nfunction resourceToConfig(resource: ConfigResource, client: ConfigClient): Config {\n const attrs: ApiConfigOutput = resource.attributes;\n return new Config(client, {\n id: resource.id ?? \"\",\n key: attrs.key ?? \"\",\n name: attrs.name,\n description: attrs.description ?? null,\n parent: attrs.parent ?? null,\n items: extractItemValues(attrs.items as Record<string, { value: unknown }> | null | undefined),\n environments: extractEnvironments(\n attrs.environments as\n | Record<string, { values?: Record<string, { value: unknown }> | null }>\n | null\n | undefined,\n ),\n createdAt: attrs.created_at ? new Date(attrs.created_at) : null,\n updatedAt: attrs.updated_at ? new Date(attrs.updated_at) : null,\n });\n}\n\n/**\n * Map fetch or HTTP errors to typed SDK exceptions.\n * @internal\n */\nasync function checkError(response: Response, context: string): Promise<never> {\n const body = await response.text().catch(() => \"\");\n switch (response.status) {\n case 404:\n throw new SmplNotFoundError(body || context, 404, body);\n case 409:\n throw new SmplConflictError(body || context, 409, body);\n case 422:\n throw new SmplValidationError(body || context, 422, body);\n default:\n throw new SmplError(`HTTP ${response.status}: ${body}`, response.status, body);\n }\n}\n\n/**\n * Re-raise fetch-level errors (network, timeout) as typed SDK exceptions.\n * @internal\n */\nfunction wrapFetchError(err: unknown): never {\n if (\n err instanceof SmplNotFoundError ||\n err instanceof SmplConflictError ||\n err instanceof SmplValidationError ||\n err instanceof SmplError\n ) {\n throw err;\n }\n if (err instanceof TypeError) {\n throw new SmplConnectionError(`Network error: ${err.message}`);\n }\n throw new SmplConnectionError(\n `Request failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n}\n\n/**\n * Wrap plain values into typed item format for the API.\n * `{key: rawValue}` -> `{key: {value: rawValue}}`\n * @internal\n */\nfunction wrapItemValues(\n values: Record<string, unknown> | null | undefined,\n): Record<string, { value: unknown }> | null {\n if (!values) return null;\n const result: Record<string, { value: unknown }> = {};\n for (const [key, val] of Object.entries(values)) {\n result[key] = { value: val };\n }\n return result;\n}\n\n/**\n * Wrap plain environment values into the API wire format.\n * SDK format: `{ env: { values: { key: raw } } }`\n * Wire format: `{ env: { values: { key: { value: raw } } } }`\n * @internal\n */\nfunction wrapEnvironments(\n environments: Record<string, unknown> | null | undefined,\n): Record<string, unknown> | null {\n if (!environments) return null;\n const result: Record<string, unknown> = {};\n for (const [envName, envEntry] of Object.entries(environments)) {\n if (envEntry && typeof envEntry === \"object\" && !Array.isArray(envEntry)) {\n const entry = envEntry as Record<string, unknown>;\n if (entry.values && typeof entry.values === \"object\" && !Array.isArray(entry.values)) {\n const wrapped: Record<string, { value: unknown }> = {};\n for (const [key, val] of Object.entries(entry.values as Record<string, unknown>)) {\n wrapped[key] = { value: val };\n }\n result[envName] = { ...entry, values: wrapped };\n } else {\n result[envName] = envEntry;\n }\n } else {\n result[envName] = envEntry;\n }\n }\n return result;\n}\n\n/**\n * Build a JSON:API request body for create/update operations.\n * @internal\n */\nfunction buildRequestBody(options: {\n id?: string | null;\n name: string;\n key?: string | null;\n description?: string | null;\n parent?: string | null;\n items?: Record<string, unknown> | null;\n environments?: Record<string, unknown> | null;\n}): operations[\"create_config\"][\"requestBody\"][\"content\"][\"application/json\"] {\n const attrs: ApiConfig = {\n name: options.name,\n };\n if (options.key !== undefined) attrs.key = options.key;\n if (options.description !== undefined) attrs.description = options.description;\n if (options.parent !== undefined) attrs.parent = options.parent;\n if (options.items !== undefined)\n attrs.items = wrapItemValues(options.items) as ApiConfig[\"items\"];\n if (options.environments !== undefined)\n attrs.environments = wrapEnvironments(options.environments) as ApiConfig[\"environments\"];\n\n return {\n data: {\n id: options.id ?? null,\n type: \"config\",\n attributes: attrs,\n },\n };\n}\n\n/**\n * Client for the smplkit Config API (management plane).\n *\n * All methods are async and return `Promise<T>`. Network and server\n * errors are mapped to typed SDK exceptions.\n *\n * Obtained via `SmplClient.config`.\n */\nexport class ConfigClient {\n /** @internal — used by Config instances for reconnecting and WebSocket auth. */\n readonly _apiKey: string;\n\n /** @internal */\n readonly _baseUrl: string = BASE_URL;\n\n /** @internal */\n private readonly _http: ReturnType<typeof createClient<import(\"../generated/config.d.ts\").paths>>;\n\n /** @internal */\n constructor(apiKey: string, timeout?: number) {\n this._apiKey = apiKey;\n const ms = timeout ?? 30_000;\n this._http = createClient<import(\"../generated/config.d.ts\").paths>({\n baseUrl: BASE_URL,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n Accept: \"application/json\",\n },\n // openapi-fetch custom fetch receives a pre-built Request object\n fetch: async (request: Request): Promise<Response> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), ms);\n try {\n return await fetch(new Request(request, { signal: controller.signal }));\n } catch (err) {\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new SmplTimeoutError(`Request timed out after ${ms}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n },\n });\n }\n\n /**\n * Fetch a single config by key or UUID.\n *\n * Exactly one of `key` or `id` must be provided.\n *\n * @throws {SmplNotFoundError} If no matching config exists.\n */\n async get(options: GetConfigOptions): Promise<Config> {\n const { key, id } = options;\n if ((key === undefined) === (id === undefined)) {\n throw new Error(\"Exactly one of 'key' or 'id' must be provided.\");\n }\n return id !== undefined ? this._getById(id) : this._getByKey(key!);\n }\n\n /**\n * List all configs for the account.\n */\n async list(): Promise<Config[]> {\n let data: components[\"schemas\"][\"ConfigListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs\", {});\n if (result.error !== undefined) await checkError(result.response, \"Failed to list configs\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data) return [];\n return data.data.map((r) => resourceToConfig(r, this));\n }\n\n /**\n * Create a new config.\n *\n * @throws {SmplValidationError} If the server rejects the request.\n */\n async create(options: CreateConfigOptions): Promise<Config> {\n const body = buildRequestBody({\n name: options.name,\n key: options.key,\n description: options.description,\n parent: options.parent,\n items: options.items,\n });\n\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.POST(\"/api/v1/configs\", { body });\n if (result.error !== undefined) await checkError(result.response, \"Failed to create config\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplValidationError(\"Failed to create config\");\n return resourceToConfig(data.data, this);\n }\n\n /**\n * Delete a config by UUID.\n *\n * @throws {SmplNotFoundError} If the config does not exist.\n * @throws {SmplConflictError} If the config has child configs.\n */\n async delete(configId: string): Promise<void> {\n try {\n const result = await this._http.DELETE(\"/api/v1/configs/{id}\", {\n params: { path: { id: configId } },\n });\n if (result.error !== undefined && result.response.status !== 204)\n await checkError(result.response, `Failed to delete config ${configId}`);\n } catch (err) {\n wrapFetchError(err);\n }\n }\n\n /**\n * Internal: PUT a full config update and return the updated model.\n *\n * Called by {@link Config} instance methods.\n * @internal\n */\n async _updateConfig(payload: ConfigUpdatePayload): Promise<Config> {\n const body = buildRequestBody({\n id: payload.configId,\n name: payload.name,\n key: payload.key,\n description: payload.description,\n parent: payload.parent,\n items: payload.items,\n environments: payload.environments,\n });\n\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.PUT(\"/api/v1/configs/{id}\", {\n params: { path: { id: payload.configId } },\n body,\n });\n if (result.error !== undefined)\n await checkError(result.response, `Failed to update config ${payload.configId}`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data)\n throw new SmplValidationError(`Failed to update config ${payload.configId}`);\n return resourceToConfig(data.data, this);\n }\n\n // ---- Private helpers ----\n\n private async _getById(configId: string): Promise<Config> {\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs/{id}\", {\n params: { path: { id: configId } },\n });\n if (result.error !== undefined)\n await checkError(result.response, `Config ${configId} not found`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplNotFoundError(`Config ${configId} not found`);\n return resourceToConfig(data.data, this);\n }\n\n private async _getByKey(key: string): Promise<Config> {\n let data: components[\"schemas\"][\"ConfigListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs\", {\n params: { query: { \"filter[key]\": key } },\n });\n if (result.error !== undefined)\n await checkError(result.response, `Config with key '${key}' not found`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data || data.data.length === 0) {\n throw new SmplNotFoundError(`Config with key '${key}' not found`);\n }\n return resourceToConfig(data.data[0], this);\n }\n}\n","/**\n * Structured SDK error types.\n *\n * All smplkit errors extend {@link SmplError}, allowing callers to catch\n * the base class for generic handling or specific subclasses for\n * fine-grained control.\n */\n\n/** Base exception for all smplkit SDK errors. */\nexport class SmplError extends Error {\n /** The HTTP status code, if the error originated from an HTTP response. */\n public readonly statusCode?: number;\n\n /** The raw response body, if available. */\n public readonly responseBody?: string;\n\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message);\n this.name = \"SmplError\";\n this.statusCode = statusCode;\n this.responseBody = responseBody;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when a network request fails (e.g., DNS resolution, connection refused). */\nexport class SmplConnectionError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode, responseBody);\n this.name = \"SmplConnectionError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when an operation exceeds its timeout. */\nexport class SmplTimeoutError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode, responseBody);\n this.name = \"SmplTimeoutError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when a requested resource does not exist (HTTP 404). */\nexport class SmplNotFoundError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 404, responseBody);\n this.name = \"SmplNotFoundError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when an operation conflicts with current state (HTTP 409). */\nexport class SmplConflictError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 409, responseBody);\n this.name = \"SmplConflictError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when the server rejects a request due to validation errors (HTTP 422). */\nexport class SmplValidationError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 422, responseBody);\n this.name = \"SmplValidationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Config resource — management-plane model with runtime connect support.\n *\n * Instances are returned by {@link ConfigClient} methods and provide\n * management-plane operations (`update`, `setValues`, `setValue`) as well\n * as the {@link connect} entry point for runtime value resolution.\n */\n\nimport type { ConfigRuntime } from \"./runtime.js\";\nimport type { ConnectOptions } from \"./runtime-types.js\";\n\n/**\n * Internal type used by {@link ConfigClient}. Not part of the public API.\n * @internal\n */\nexport interface ConfigUpdatePayload {\n configId: string;\n name: string;\n key: string | null;\n description: string | null;\n parent: string | null;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n}\n\n/**\n * A configuration resource fetched from the smplkit Config service.\n *\n * Instances are returned by {@link ConfigClient} methods and provide\n * management-plane operations as well as the {@link connect} entry point\n * for runtime value resolution.\n */\nexport class Config {\n /** UUID of the config. */\n id: string;\n\n /** Human-readable key (e.g. `\"user_service\"`). */\n key: string;\n\n /** Display name. */\n name: string;\n\n /** Optional description. */\n description: string | null;\n\n /** Parent config UUID, or null if this is a root config. */\n parent: string | null;\n\n /** Base key-value pairs (unwrapped from typed item definitions). */\n items: Record<string, unknown>;\n\n /**\n * Per-environment overrides.\n * Stored as `{ env_name: { values: { key: value } } }` — values are\n * unwrapped from the server's `{ value: raw }` wrapper.\n */\n environments: Record<string, unknown>;\n\n /** When the config was created, or null if unavailable. */\n createdAt: Date | null;\n\n /** When the config was last updated, or null if unavailable. */\n updatedAt: Date | null;\n\n /**\n * Internal reference to the parent client.\n * @internal\n */\n private readonly _client: {\n _updateConfig(payload: ConfigUpdatePayload): Promise<Config>;\n get(options: { id: string }): Promise<Config>;\n readonly _apiKey: string;\n readonly _baseUrl: string;\n };\n\n /** @internal */\n constructor(\n client: {\n _updateConfig(payload: ConfigUpdatePayload): Promise<Config>;\n get(options: { id: string }): Promise<Config>;\n readonly _apiKey: string;\n readonly _baseUrl: string;\n },\n fields: {\n id: string;\n key: string;\n name: string;\n description: string | null;\n parent: string | null;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n createdAt: Date | null;\n updatedAt: Date | null;\n },\n ) {\n this._client = client;\n this.id = fields.id;\n this.key = fields.key;\n this.name = fields.name;\n this.description = fields.description;\n this.parent = fields.parent;\n this.items = fields.items;\n this.environments = fields.environments;\n this.createdAt = fields.createdAt;\n this.updatedAt = fields.updatedAt;\n }\n\n /**\n * Update this config's attributes on the server.\n *\n * Builds the request from current attribute values, overriding with any\n * provided options. Updates local attributes in place on success.\n *\n * @param options.name - New display name.\n * @param options.description - New description (pass empty string to clear).\n * @param options.items - New base values (replaces entirely).\n * @param options.environments - New environments dict (replaces entirely).\n */\n async update(options: {\n name?: string;\n description?: string;\n items?: Record<string, unknown>;\n environments?: Record<string, unknown>;\n }): Promise<void> {\n const updated = await this._client._updateConfig({\n configId: this.id,\n name: options.name ?? this.name,\n key: this.key,\n description: options.description !== undefined ? options.description : this.description,\n parent: this.parent,\n items: options.items ?? this.items,\n environments: options.environments ?? this.environments,\n });\n this.name = updated.name;\n this.description = updated.description;\n this.items = updated.items;\n this.environments = updated.environments;\n this.updatedAt = updated.updatedAt;\n }\n\n /**\n * Replace base or environment-specific values.\n *\n * When `environment` is provided, replaces that environment's `values`\n * sub-dict (other environments are preserved). When omitted, replaces\n * the base `items`.\n *\n * @param values - The complete set of values to set.\n * @param environment - Target environment, or omit for base values.\n */\n async setValues(values: Record<string, unknown>, environment?: string): Promise<void> {\n let newItems: Record<string, unknown>;\n let newEnvs: Record<string, unknown>;\n\n if (environment === undefined) {\n newItems = values;\n newEnvs = this.environments;\n } else {\n newItems = this.items;\n // Preserve any extra metadata on the environment entry (like other sub-keys),\n // but replace the `values` sub-dict entirely.\n const existingEntry =\n typeof this.environments[environment] === \"object\" &&\n this.environments[environment] !== null\n ? { ...(this.environments[environment] as Record<string, unknown>) }\n : {};\n existingEntry.values = values;\n newEnvs = { ...this.environments, [environment]: existingEntry };\n }\n\n const updated = await this._client._updateConfig({\n configId: this.id,\n name: this.name,\n key: this.key,\n description: this.description,\n parent: this.parent,\n items: newItems,\n environments: newEnvs,\n });\n this.items = updated.items;\n this.environments = updated.environments;\n this.updatedAt = updated.updatedAt;\n }\n\n /**\n * Set a single key within base or environment-specific values.\n *\n * Merges the key into existing values rather than replacing all values.\n *\n * @param key - The config key to set.\n * @param value - The value to assign.\n * @param environment - Target environment, or omit for base values.\n */\n async setValue(key: string, value: unknown, environment?: string): Promise<void> {\n if (environment === undefined) {\n const merged = { ...this.items, [key]: value };\n await this.setValues(merged);\n } else {\n const envEntry =\n typeof this.environments[environment] === \"object\" &&\n this.environments[environment] !== null\n ? (this.environments[environment] as Record<string, unknown>)\n : {};\n const existing = {\n ...(typeof envEntry.values === \"object\" && envEntry.values !== null\n ? (envEntry.values as Record<string, unknown>)\n : {}),\n };\n existing[key] = value;\n await this.setValues(existing, environment);\n }\n }\n\n /**\n * Connect to this config for runtime value resolution.\n *\n * Eagerly fetches this config and its full parent chain, resolves values\n * for the given environment via deep merge, and returns a\n * {@link ConfigRuntime} with a fully populated local cache.\n *\n * A background WebSocket connection is started for real-time updates.\n * If the WebSocket fails to connect, the runtime operates in cache-only\n * mode and reconnects automatically.\n *\n * Supports both `await` and `await using` (TypeScript 5.2+)::\n *\n * ```typescript\n * // Simple await\n * const runtime = await config.connect(\"production\");\n * try { ... } finally { await runtime.close(); }\n *\n * // await using (auto-close)\n * await using runtime = await config.connect(\"production\");\n * ```\n *\n * @param environment - The environment to resolve for (e.g. `\"production\"`).\n * @param options.timeout - Milliseconds to wait for the initial fetch.\n */\n async connect(environment: string, options?: ConnectOptions): Promise<ConfigRuntime> {\n // Lazy import to avoid loading ws at module-init time\n const { ConfigRuntime } = await import(\"./runtime.js\");\n\n const timeout = options?.timeout ?? 30_000;\n const chain = await this._buildChain(timeout);\n\n return new ConfigRuntime({\n configKey: this.key,\n configId: this.id,\n environment,\n chain,\n apiKey: this._client._apiKey,\n baseUrl: this._client._baseUrl,\n fetchChain: () => this._buildChain(timeout),\n });\n }\n\n /**\n * Walk the parent chain and return config data objects, child-to-root.\n * @internal\n */\n private async _buildChain(\n _timeout: number,\n ): Promise<\n Array<{ id: string; items: Record<string, unknown>; environments: Record<string, unknown> }>\n > {\n const chain: Array<{\n id: string;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n }> = [{ id: this.id, items: this.items, environments: this.environments }];\n\n let parentId = this.parent;\n while (parentId !== null) {\n const parentConfig = await this._client.get({ id: parentId });\n chain.push({\n id: parentConfig.id,\n items: parentConfig.items,\n environments: parentConfig.environments,\n });\n parentId = parentConfig.parent;\n }\n\n return chain;\n }\n\n toString(): string {\n return `Config(id=${this.id}, key=${this.key}, name=${this.name})`;\n }\n}\n\n/** Options for creating a new config. */\nexport interface CreateConfigOptions {\n /** Display name for the config. */\n name: string;\n /** Human-readable key. Auto-generated by the server if omitted. */\n key?: string;\n /** Optional description. */\n description?: string;\n /** Parent config UUID. Defaults to the account's `common` config if omitted. */\n parent?: string;\n /** Initial base values. */\n items?: Record<string, unknown>;\n}\n\n/** Options for fetching a single config. Exactly one of `key` or `id` must be provided. */\nexport interface GetConfigOptions {\n /** Fetch by human-readable key. */\n key?: string;\n /** Fetch by UUID. */\n id?: string;\n}\n","/**\n * API key resolution chain: explicit → env var → config file.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { SmplError } from \"./errors.js\";\n\nconst NO_API_KEY_MESSAGE =\n \"No API key provided. Set one of:\\n\" +\n \" 1. Pass apiKey to the constructor\\n\" +\n \" 2. Set the SMPLKIT_API_KEY environment variable\\n\" +\n \" 3. Create a ~/.smplkit file with:\\n\" +\n \" [default]\\n\" +\n \" api_key = your_key_here\";\n\nexport function resolveApiKey(explicit?: string): string {\n if (explicit) return explicit;\n\n const envVal = process.env.SMPLKIT_API_KEY;\n if (envVal) return envVal;\n\n const configPath = join(homedir(), \".smplkit\");\n try {\n const content = readFileSync(configPath, \"utf-8\");\n let inDefaultSection = false;\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"[\")) {\n inDefaultSection = trimmed.toLowerCase() === \"[default]\";\n continue;\n }\n if (inDefaultSection && trimmed.startsWith(\"api_key\")) {\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex !== -1) {\n const value = trimmed.slice(eqIndex + 1).trim();\n if (value) return value;\n }\n }\n }\n } catch {\n // File doesn't exist or isn't readable — skip\n }\n\n throw new SmplError(NO_API_KEY_MESSAGE);\n}\n","/**\n * Top-level SDK client — SmplClient.\n *\n * The main entry point for the smplkit TypeScript SDK. Provides access\n * to sub-clients for each API domain (config, flags, logging, etc.).\n */\n\nimport { ConfigClient } from \"./config/client.js\";\nimport { resolveApiKey } from \"./resolve.js\";\n\n/** Configuration options for the {@link SmplClient}. */\nexport interface SmplClientOptions {\n /**\n * API key for authenticating with the smplkit platform.\n * When omitted, the SDK resolves it from the `SMPLKIT_API_KEY`\n * environment variable or the `~/.smplkit` configuration file.\n */\n apiKey?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Entry point for the smplkit TypeScript SDK.\n *\n * @example\n * ```typescript\n * import { SmplClient } from \"@smplkit/sdk\";\n *\n * const client = new SmplClient({ apiKey: \"sk_api_...\" });\n * const cfg = await client.config.get({ key: \"common\" });\n * ```\n */\nexport class SmplClient {\n /** Client for config management-plane operations. */\n readonly config: ConfigClient;\n\n constructor(options: SmplClientOptions = {}) {\n const apiKey = resolveApiKey(options.apiKey);\n this.config = new ConfigClient(apiKey, options.timeout);\n }\n}\n"],"mappings":"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","names":["WebSocket","ConfigRuntime","createClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/client.ts","../src/errors.ts","../src/config/resolve.ts","../src/config/types.ts","../src/flags/client.ts","../src/auth.ts","../src/transport.ts","../src/flags/models.ts","../src/ws.ts","../src/resolve.ts","../src/client.ts","../src/config/runtime.ts","../src/flags/types.ts"],"sourcesContent":["/**\n * smplkit — Official TypeScript SDK for the smplkit platform.\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { SmplClient } from \"./client.js\";\nexport type { SmplClientOptions } from \"./client.js\";\n\n// Config — management plane\nexport { ConfigClient } from \"./config/client.js\";\nexport type { CreateConfigOptions, GetConfigOptions } from \"./config/types.js\";\nexport { Config } from \"./config/types.js\";\n\n// Config — runtime plane\nexport { ConfigRuntime } from \"./config/runtime.js\";\nexport type {\n ConfigChangeEvent,\n ConfigStats,\n ConnectionStatus,\n ConnectOptions,\n} from \"./config/runtime-types.js\";\n\n// Flags — public types\nexport { Context, Rule } from \"./flags/types.js\";\nexport type { FlagType } from \"./flags/types.js\";\n\n// Flags — management plane\nexport { FlagsClient } from \"./flags/client.js\";\nexport { Flag, ContextType } from \"./flags/models.js\";\n\n// Flags — runtime plane\nexport {\n BoolFlagHandle,\n StringFlagHandle,\n NumberFlagHandle,\n JsonFlagHandle,\n FlagChangeEvent,\n FlagStats,\n} from \"./flags/client.js\";\n\n// Shared WebSocket\nexport { SharedWebSocket } from \"./ws.js\";\n\n// Error hierarchy\nexport {\n SmplError,\n SmplConnectionError,\n SmplTimeoutError,\n SmplNotFoundError,\n SmplNotConnectedError,\n SmplConflictError,\n SmplValidationError,\n} from \"./errors.js\";\n","/**\n * ConfigClient — management-plane operations for configs.\n *\n * Uses the generated OpenAPI types (`src/generated/config.d.ts`) via\n * `openapi-fetch` for all HTTP calls, keeping the client layer fully\n * type-safe without hand-coded request/response shapes.\n */\n\nimport createClient from \"openapi-fetch\";\nimport type { components, operations } from \"../generated/config.d.ts\";\nimport {\n SmplConflictError,\n SmplNotFoundError,\n SmplNotConnectedError,\n SmplValidationError,\n SmplError,\n SmplConnectionError,\n SmplTimeoutError,\n} from \"../errors.js\";\nimport { resolveChain } from \"./resolve.js\";\nimport { Config } from \"./types.js\";\nimport type { ConfigUpdatePayload, CreateConfigOptions, GetConfigOptions } from \"./types.js\";\n\nconst BASE_URL = \"https://config.smplkit.com\";\n\ntype ApiConfig = components[\"schemas\"][\"Config\"];\ntype ApiConfigOutput = components[\"schemas\"][\"Config\"];\ntype ConfigResource = components[\"schemas\"][\"ConfigResource\"];\n\n/**\n * Extract raw values from typed items: `{key: {value, type?, description?}}` -> `{key: rawValue}`.\n * @internal\n */\nfunction extractItemValues(\n items: Record<string, { value: unknown }> | null | undefined,\n): Record<string, unknown> {\n if (!items) return {};\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(items)) {\n result[key] = item && typeof item === \"object\" && \"value\" in item ? item.value : item;\n }\n return result;\n}\n\n/**\n * Extract raw values from environment overrides.\n * Wire format: `{ env: { values: { key: { value: raw } } } }`\n * SDK format: `{ env: { values: { key: raw } } }`\n * @internal\n */\nfunction extractEnvironments(\n environments:\n | Record<string, { values?: Record<string, { value: unknown }> | null }>\n | null\n | undefined,\n): Record<string, unknown> {\n if (!environments) return {};\n const result: Record<string, unknown> = {};\n for (const [envName, envEntry] of Object.entries(environments)) {\n if (envEntry && typeof envEntry === \"object\" && envEntry.values) {\n const unwrapped: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(envEntry.values)) {\n unwrapped[key] = item && typeof item === \"object\" && \"value\" in item ? item.value : item;\n }\n result[envName] = { values: unwrapped };\n } else {\n result[envName] = envEntry;\n }\n }\n return result;\n}\n\n/** @internal */\nfunction resourceToConfig(resource: ConfigResource, client: ConfigClient): Config {\n const attrs: ApiConfigOutput = resource.attributes;\n return new Config(client, {\n id: resource.id ?? \"\",\n key: attrs.key ?? \"\",\n name: attrs.name,\n description: attrs.description ?? null,\n parent: attrs.parent ?? null,\n items: extractItemValues(attrs.items as Record<string, { value: unknown }> | null | undefined),\n environments: extractEnvironments(\n attrs.environments as\n | Record<string, { values?: Record<string, { value: unknown }> | null }>\n | null\n | undefined,\n ),\n createdAt: attrs.created_at ? new Date(attrs.created_at) : null,\n updatedAt: attrs.updated_at ? new Date(attrs.updated_at) : null,\n });\n}\n\n/**\n * Map fetch or HTTP errors to typed SDK exceptions.\n * @internal\n */\nasync function checkError(response: Response, context: string): Promise<never> {\n const body = await response.text().catch(() => \"\");\n switch (response.status) {\n case 404:\n throw new SmplNotFoundError(body || context, 404, body);\n case 409:\n throw new SmplConflictError(body || context, 409, body);\n case 422:\n throw new SmplValidationError(body || context, 422, body);\n default:\n throw new SmplError(`HTTP ${response.status}: ${body}`, response.status, body);\n }\n}\n\n/**\n * Re-raise fetch-level errors (network, timeout) as typed SDK exceptions.\n * @internal\n */\nfunction wrapFetchError(err: unknown): never {\n if (\n err instanceof SmplNotFoundError ||\n err instanceof SmplConflictError ||\n err instanceof SmplValidationError ||\n err instanceof SmplError\n ) {\n throw err;\n }\n if (err instanceof TypeError) {\n throw new SmplConnectionError(`Network error: ${err.message}`);\n }\n throw new SmplConnectionError(\n `Request failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n}\n\n/**\n * Wrap plain values into typed item format for the API.\n * `{key: rawValue}` -> `{key: {value: rawValue}}`\n * @internal\n */\nfunction wrapItemValues(\n values: Record<string, unknown> | null | undefined,\n): Record<string, { value: unknown }> | null {\n if (!values) return null;\n const result: Record<string, { value: unknown }> = {};\n for (const [key, val] of Object.entries(values)) {\n result[key] = { value: val };\n }\n return result;\n}\n\n/**\n * Wrap plain environment values into the API wire format.\n * SDK format: `{ env: { values: { key: raw } } }`\n * Wire format: `{ env: { values: { key: { value: raw } } } }`\n * @internal\n */\nfunction wrapEnvironments(\n environments: Record<string, unknown> | null | undefined,\n): Record<string, unknown> | null {\n if (!environments) return null;\n const result: Record<string, unknown> = {};\n for (const [envName, envEntry] of Object.entries(environments)) {\n if (envEntry && typeof envEntry === \"object\" && !Array.isArray(envEntry)) {\n const entry = envEntry as Record<string, unknown>;\n if (entry.values && typeof entry.values === \"object\" && !Array.isArray(entry.values)) {\n const wrapped: Record<string, { value: unknown }> = {};\n for (const [key, val] of Object.entries(entry.values as Record<string, unknown>)) {\n wrapped[key] = { value: val };\n }\n result[envName] = { ...entry, values: wrapped };\n } else {\n result[envName] = envEntry;\n }\n } else {\n result[envName] = envEntry;\n }\n }\n return result;\n}\n\n/**\n * Build a JSON:API request body for create/update operations.\n * @internal\n */\nfunction buildRequestBody(options: {\n id?: string | null;\n name: string;\n key?: string | null;\n description?: string | null;\n parent?: string | null;\n items?: Record<string, unknown> | null;\n environments?: Record<string, unknown> | null;\n}): operations[\"create_config\"][\"requestBody\"][\"content\"][\"application/json\"] {\n const attrs: ApiConfig = {\n name: options.name,\n };\n if (options.key !== undefined) attrs.key = options.key;\n if (options.description !== undefined) attrs.description = options.description;\n if (options.parent !== undefined) attrs.parent = options.parent;\n if (options.items !== undefined)\n attrs.items = wrapItemValues(options.items) as ApiConfig[\"items\"];\n if (options.environments !== undefined)\n attrs.environments = wrapEnvironments(options.environments) as ApiConfig[\"environments\"];\n\n return {\n data: {\n id: options.id ?? null,\n type: \"config\",\n attributes: attrs,\n },\n };\n}\n\n/**\n * Client for the smplkit Config API (management plane).\n *\n * All methods are async and return `Promise<T>`. Network and server\n * errors are mapped to typed SDK exceptions.\n *\n * Obtained via `SmplClient.config`.\n */\nexport class ConfigClient {\n /** @internal — used by Config instances for reconnecting and WebSocket auth. */\n readonly _apiKey: string;\n\n /** @internal */\n readonly _baseUrl: string = BASE_URL;\n\n /** @internal */\n private readonly _http: ReturnType<typeof createClient<import(\"../generated/config.d.ts\").paths>>;\n\n /** @internal — returns the shared WebSocket for real-time updates. */\n _getSharedWs?: () => import(\"../ws.js\").SharedWebSocket;\n\n /** @internal — set by SmplClient after construction. */\n _parent: { readonly _environment: string; readonly _service: string | null } | null = null;\n\n private _configCache: Record<string, Record<string, unknown>> = {};\n private _connected = false;\n\n /** @internal */\n constructor(apiKey: string, timeout?: number) {\n this._apiKey = apiKey;\n const ms = timeout ?? 30_000;\n this._http = createClient<import(\"../generated/config.d.ts\").paths>({\n baseUrl: BASE_URL,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n Accept: \"application/json\",\n },\n // openapi-fetch custom fetch receives a pre-built Request object\n fetch: async (request: Request): Promise<Response> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), ms);\n try {\n return await fetch(new Request(request, { signal: controller.signal }));\n } catch (err) {\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new SmplTimeoutError(`Request timed out after ${ms}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n },\n });\n }\n\n /**\n * Fetch a single config by key or UUID.\n *\n * Exactly one of `key` or `id` must be provided.\n *\n * @throws {SmplNotFoundError} If no matching config exists.\n */\n async get(options: GetConfigOptions): Promise<Config> {\n const { key, id } = options;\n if ((key === undefined) === (id === undefined)) {\n throw new Error(\"Exactly one of 'key' or 'id' must be provided.\");\n }\n return id !== undefined ? this._getById(id) : this._getByKey(key!);\n }\n\n /**\n * List all configs for the account.\n */\n async list(): Promise<Config[]> {\n let data: components[\"schemas\"][\"ConfigListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs\", {});\n if (result.error !== undefined) await checkError(result.response, \"Failed to list configs\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data) return [];\n return data.data.map((r) => resourceToConfig(r, this));\n }\n\n /**\n * Create a new config.\n *\n * @throws {SmplValidationError} If the server rejects the request.\n */\n async create(options: CreateConfigOptions): Promise<Config> {\n const body = buildRequestBody({\n name: options.name,\n key: options.key,\n description: options.description,\n parent: options.parent,\n items: options.items,\n });\n\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.POST(\"/api/v1/configs\", { body });\n if (result.error !== undefined) await checkError(result.response, \"Failed to create config\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplValidationError(\"Failed to create config\");\n return resourceToConfig(data.data, this);\n }\n\n /**\n * Delete a config by UUID.\n *\n * @throws {SmplNotFoundError} If the config does not exist.\n * @throws {SmplConflictError} If the config has child configs.\n */\n async delete(configId: string): Promise<void> {\n try {\n const result = await this._http.DELETE(\"/api/v1/configs/{id}\", {\n params: { path: { id: configId } },\n });\n if (result.error !== undefined && result.response.status !== 204)\n await checkError(result.response, `Failed to delete config ${configId}`);\n } catch (err) {\n wrapFetchError(err);\n }\n }\n\n /**\n * Fetch all configs, resolve values for the environment, and cache.\n * @internal — called by SmplClient.connect().\n */\n async _connectInternal(environment: string): Promise<void> {\n const configs = await this.list();\n const cache: Record<string, Record<string, unknown>> = {};\n for (const cfg of configs) {\n const chain = await cfg._buildChain(this._http);\n cache[cfg.key] = resolveChain(chain, environment);\n }\n this._configCache = cache;\n this._connected = true;\n }\n\n /**\n * Read a resolved config value (prescriptive access).\n *\n * Requires {@link SmplClient.connect} to have been called.\n *\n * @param configKey - The config key to look up.\n * @param itemKey - Optional specific item key. If omitted, returns all values.\n * @param defaultValue - Default value if the key is missing.\n *\n * @throws {SmplNotConnectedError} If connect() has not been called.\n */\n getValue(configKey: string, itemKey?: string, defaultValue?: unknown): unknown {\n if (!this._connected) {\n throw new SmplNotConnectedError(\"SmplClient is not connected. Call client.connect() first.\");\n }\n const resolved = this._configCache[configKey];\n if (resolved === undefined) {\n return defaultValue ?? null;\n }\n if (itemKey === undefined) {\n return { ...resolved };\n }\n return itemKey in resolved ? resolved[itemKey] : (defaultValue ?? null);\n }\n\n /**\n * Internal: PUT a full config update and return the updated model.\n *\n * Called by {@link Config} instance methods.\n * @internal\n */\n async _updateConfig(payload: ConfigUpdatePayload): Promise<Config> {\n const body = buildRequestBody({\n id: payload.configId,\n name: payload.name,\n key: payload.key,\n description: payload.description,\n parent: payload.parent,\n items: payload.items,\n environments: payload.environments,\n });\n\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.PUT(\"/api/v1/configs/{id}\", {\n params: { path: { id: payload.configId } },\n body,\n });\n if (result.error !== undefined)\n await checkError(result.response, `Failed to update config ${payload.configId}`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data)\n throw new SmplValidationError(`Failed to update config ${payload.configId}`);\n return resourceToConfig(data.data, this);\n }\n\n // ---- Private helpers ----\n\n private async _getById(configId: string): Promise<Config> {\n let data: components[\"schemas\"][\"ConfigResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs/{id}\", {\n params: { path: { id: configId } },\n });\n if (result.error !== undefined)\n await checkError(result.response, `Config ${configId} not found`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplNotFoundError(`Config ${configId} not found`);\n return resourceToConfig(data.data, this);\n }\n\n private async _getByKey(key: string): Promise<Config> {\n let data: components[\"schemas\"][\"ConfigListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/configs\", {\n params: { query: { \"filter[key]\": key } },\n });\n if (result.error !== undefined)\n await checkError(result.response, `Config with key '${key}' not found`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data || data.data.length === 0) {\n throw new SmplNotFoundError(`Config with key '${key}' not found`);\n }\n return resourceToConfig(data.data[0], this);\n }\n}\n","/**\n * Structured SDK error types.\n *\n * All smplkit errors extend {@link SmplError}, allowing callers to catch\n * the base class for generic handling or specific subclasses for\n * fine-grained control.\n */\n\n/** Base exception for all smplkit SDK errors. */\nexport class SmplError extends Error {\n /** The HTTP status code, if the error originated from an HTTP response. */\n public readonly statusCode?: number;\n\n /** The raw response body, if available. */\n public readonly responseBody?: string;\n\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message);\n this.name = \"SmplError\";\n this.statusCode = statusCode;\n this.responseBody = responseBody;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when a network request fails (e.g., DNS resolution, connection refused). */\nexport class SmplConnectionError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode, responseBody);\n this.name = \"SmplConnectionError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when an operation exceeds its timeout. */\nexport class SmplTimeoutError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode, responseBody);\n this.name = \"SmplTimeoutError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when a requested resource does not exist (HTTP 404). */\nexport class SmplNotFoundError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 404, responseBody);\n this.name = \"SmplNotFoundError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when an operation conflicts with current state (HTTP 409). */\nexport class SmplConflictError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 409, responseBody);\n this.name = \"SmplConflictError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when a method requiring connect() is called before connecting. */\nexport class SmplNotConnectedError extends SmplError {\n constructor(message: string) {\n super(message);\n this.name = \"SmplNotConnectedError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Raised when the server rejects a request due to validation errors (HTTP 422). */\nexport class SmplValidationError extends SmplError {\n constructor(message: string, statusCode?: number, responseBody?: string) {\n super(message, statusCode ?? 422, responseBody);\n this.name = \"SmplValidationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Deep-merge resolution algorithm for config inheritance chains.\n *\n * Mirrors the Python SDK's `_resolver.py` (ADR-024 §2.5–2.6).\n */\n\n/** A single entry in a config inheritance chain (child-to-root ordering). */\nexport interface ChainConfig {\n /** Config UUID. */\n id: string;\n /** Base key-value pairs (unwrapped from typed item definitions). */\n items: Record<string, unknown>;\n /**\n * Per-environment overrides.\n * Each entry is `{ values: { key: value, ... } }` — values are already\n * unwrapped from the server's `{ value: raw }` wrapper by the client layer.\n */\n environments: Record<string, unknown>;\n}\n\n/**\n * Recursively merge two dicts, with `override` taking precedence.\n *\n * Nested dicts are merged recursively. Non-dict values (strings, numbers,\n * booleans, arrays, null) are replaced wholesale.\n */\nexport function deepMerge(\n base: Record<string, unknown>,\n override: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (\n key in result &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key]) &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n result[key] = deepMerge(\n result[key] as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Resolve the full configuration for an environment given a config chain.\n *\n * Walks from root (last element) to child (first element), accumulating\n * values via deep merge so that child configs override parent configs.\n *\n * For each config in the chain, base `values` are merged with\n * environment-specific values (env wins), then that result is merged\n * on top of the accumulated parent result (child wins over parent).\n *\n * @param chain - Ordered list of config data from child (index 0) to root ancestor (last).\n * @param environment - The environment key to resolve for.\n */\nexport function resolveChain(chain: ChainConfig[], environment: string): Record<string, unknown> {\n let accumulated: Record<string, unknown> = {};\n\n // Walk from root to child (reverse order — chain is child-to-root)\n for (let i = chain.length - 1; i >= 0; i--) {\n const config = chain[i];\n const baseValues: Record<string, unknown> = config.items ?? {};\n\n // Environments are stored as { env_name: { values: { key: val } } }\n const envEntry = (config.environments ?? {})[environment];\n const envValues: Record<string, unknown> =\n envEntry !== null &&\n envEntry !== undefined &&\n typeof envEntry === \"object\" &&\n !Array.isArray(envEntry)\n ? (((envEntry as Record<string, unknown>).values ?? {}) as Record<string, unknown>)\n : {};\n\n // Merge environment overrides on top of base values (env wins)\n const configResolved = deepMerge(baseValues, envValues);\n\n // Merge this config's resolved values on top of accumulated parent values (child wins)\n accumulated = deepMerge(accumulated, configResolved);\n }\n\n return accumulated;\n}\n","/**\n * Config resource — management-plane model with runtime connect support.\n *\n * Instances are returned by {@link ConfigClient} methods and provide\n * management-plane operations (`update`, `setValues`, `setValue`) as well\n * as the {@link connect} entry point for runtime value resolution.\n */\n\n// ConfigRuntime and ConnectOptions no longer imported here —\n// connect() has been moved to SmplClient.connect().\n\n/**\n * Internal type used by {@link ConfigClient}. Not part of the public API.\n * @internal\n */\nexport interface ConfigUpdatePayload {\n configId: string;\n name: string;\n key: string | null;\n description: string | null;\n parent: string | null;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n}\n\n/**\n * A configuration resource fetched from the smplkit Config service.\n *\n * Instances are returned by {@link ConfigClient} methods and provide\n * management-plane operations as well as the {@link connect} entry point\n * for runtime value resolution.\n */\nexport class Config {\n /** UUID of the config. */\n id: string;\n\n /** Human-readable key (e.g. `\"user_service\"`). */\n key: string;\n\n /** Display name. */\n name: string;\n\n /** Optional description. */\n description: string | null;\n\n /** Parent config UUID, or null if this is a root config. */\n parent: string | null;\n\n /** Base key-value pairs (unwrapped from typed item definitions). */\n items: Record<string, unknown>;\n\n /**\n * Per-environment overrides.\n * Stored as `{ env_name: { values: { key: value } } }` — values are\n * unwrapped from the server's `{ value: raw }` wrapper.\n */\n environments: Record<string, unknown>;\n\n /** When the config was created, or null if unavailable. */\n createdAt: Date | null;\n\n /** When the config was last updated, or null if unavailable. */\n updatedAt: Date | null;\n\n /**\n * Internal reference to the parent client.\n * @internal\n */\n private readonly _client: {\n _updateConfig(payload: ConfigUpdatePayload): Promise<Config>;\n get(options: { id: string }): Promise<Config>;\n readonly _apiKey: string;\n readonly _baseUrl: string;\n _getSharedWs?: () => import(\"../ws.js\").SharedWebSocket;\n };\n\n /** @internal */\n constructor(\n client: {\n _updateConfig(payload: ConfigUpdatePayload): Promise<Config>;\n get(options: { id: string }): Promise<Config>;\n readonly _apiKey: string;\n readonly _baseUrl: string;\n _getSharedWs?: () => import(\"../ws.js\").SharedWebSocket;\n },\n fields: {\n id: string;\n key: string;\n name: string;\n description: string | null;\n parent: string | null;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n createdAt: Date | null;\n updatedAt: Date | null;\n },\n ) {\n this._client = client;\n this.id = fields.id;\n this.key = fields.key;\n this.name = fields.name;\n this.description = fields.description;\n this.parent = fields.parent;\n this.items = fields.items;\n this.environments = fields.environments;\n this.createdAt = fields.createdAt;\n this.updatedAt = fields.updatedAt;\n }\n\n /**\n * Update this config's attributes on the server.\n *\n * Builds the request from current attribute values, overriding with any\n * provided options. Updates local attributes in place on success.\n *\n * @param options.name - New display name.\n * @param options.description - New description (pass empty string to clear).\n * @param options.items - New base values (replaces entirely).\n * @param options.environments - New environments dict (replaces entirely).\n */\n async update(options: {\n name?: string;\n description?: string;\n items?: Record<string, unknown>;\n environments?: Record<string, unknown>;\n }): Promise<void> {\n const updated = await this._client._updateConfig({\n configId: this.id,\n name: options.name ?? this.name,\n key: this.key,\n description: options.description !== undefined ? options.description : this.description,\n parent: this.parent,\n items: options.items ?? this.items,\n environments: options.environments ?? this.environments,\n });\n this.name = updated.name;\n this.description = updated.description;\n this.items = updated.items;\n this.environments = updated.environments;\n this.updatedAt = updated.updatedAt;\n }\n\n /**\n * Replace base or environment-specific values.\n *\n * When `environment` is provided, replaces that environment's `values`\n * sub-dict (other environments are preserved). When omitted, replaces\n * the base `items`.\n *\n * @param values - The complete set of values to set.\n * @param environment - Target environment, or omit for base values.\n */\n async setValues(values: Record<string, unknown>, environment?: string): Promise<void> {\n let newItems: Record<string, unknown>;\n let newEnvs: Record<string, unknown>;\n\n if (environment === undefined) {\n newItems = values;\n newEnvs = this.environments;\n } else {\n newItems = this.items;\n // Preserve any extra metadata on the environment entry (like other sub-keys),\n // but replace the `values` sub-dict entirely.\n const existingEntry =\n typeof this.environments[environment] === \"object\" &&\n this.environments[environment] !== null\n ? { ...(this.environments[environment] as Record<string, unknown>) }\n : {};\n existingEntry.values = values;\n newEnvs = { ...this.environments, [environment]: existingEntry };\n }\n\n const updated = await this._client._updateConfig({\n configId: this.id,\n name: this.name,\n key: this.key,\n description: this.description,\n parent: this.parent,\n items: newItems,\n environments: newEnvs,\n });\n this.items = updated.items;\n this.environments = updated.environments;\n this.updatedAt = updated.updatedAt;\n }\n\n /**\n * Set a single key within base or environment-specific values.\n *\n * Merges the key into existing values rather than replacing all values.\n *\n * @param key - The config key to set.\n * @param value - The value to assign.\n * @param environment - Target environment, or omit for base values.\n */\n async setValue(key: string, value: unknown, environment?: string): Promise<void> {\n if (environment === undefined) {\n const merged = { ...this.items, [key]: value };\n await this.setValues(merged);\n } else {\n const envEntry =\n typeof this.environments[environment] === \"object\" &&\n this.environments[environment] !== null\n ? (this.environments[environment] as Record<string, unknown>)\n : {};\n const existing = {\n ...(typeof envEntry.values === \"object\" && envEntry.values !== null\n ? (envEntry.values as Record<string, unknown>)\n : {}),\n };\n existing[key] = value;\n await this.setValues(existing, environment);\n }\n }\n\n /**\n * Walk the parent chain and return config data objects, child-to-root.\n * @internal\n */\n async _buildChain(\n _timeout?: unknown,\n ): Promise<\n Array<{ id: string; items: Record<string, unknown>; environments: Record<string, unknown> }>\n > {\n const chain: Array<{\n id: string;\n items: Record<string, unknown>;\n environments: Record<string, unknown>;\n }> = [{ id: this.id, items: this.items, environments: this.environments }];\n\n let parentId = this.parent;\n while (parentId !== null) {\n const parentConfig = await this._client.get({ id: parentId });\n chain.push({\n id: parentConfig.id,\n items: parentConfig.items,\n environments: parentConfig.environments,\n });\n parentId = parentConfig.parent;\n }\n\n return chain;\n }\n\n toString(): string {\n return `Config(id=${this.id}, key=${this.key}, name=${this.name})`;\n }\n}\n\n/** Options for creating a new config. */\nexport interface CreateConfigOptions {\n /** Display name for the config. */\n name: string;\n /** Human-readable key. Auto-generated by the server if omitted. */\n key?: string;\n /** Optional description. */\n description?: string;\n /** Parent config UUID. Defaults to the account's `common` config if omitted. */\n parent?: string;\n /** Initial base values. */\n items?: Record<string, unknown>;\n}\n\n/** Options for fetching a single config. Exactly one of `key` or `id` must be provided. */\nexport interface GetConfigOptions {\n /** Fetch by human-readable key. */\n key?: string;\n /** Fetch by UUID. */\n id?: string;\n}\n","/**\n * FlagsClient — management + prescriptive runtime for Smpl Flags.\n *\n * Uses the generated OpenAPI types (`src/generated/flags.d.ts`) via\n * `openapi-fetch` for all HTTP calls. Context type management and\n * context registration use direct HTTP via the Transport class since\n * these endpoints are on the flags service but not in the generated spec.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport createClient from \"openapi-fetch\";\nimport type { components } from \"../generated/flags.d.ts\";\nimport {\n SmplConflictError,\n SmplError,\n SmplNotConnectedError,\n SmplNotFoundError,\n SmplTimeoutError,\n SmplValidationError,\n} from \"../errors.js\";\nimport { Transport } from \"../transport.js\";\nimport { Flag, ContextType } from \"./models.js\";\nimport type { Context, FlagType } from \"./types.js\";\nimport type { SharedWebSocket } from \"../ws.js\";\n\n// Use require-style import for json-logic-js (no TS types)\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nimport jsonLogic from \"json-logic-js\";\n\nconst FLAGS_BASE_URL = \"https://flags.smplkit.com\";\nconst APP_BASE_URL = \"https://app.smplkit.com\";\nconst CACHE_MAX_SIZE = 10_000;\nconst CONTEXT_REGISTRATION_LRU_SIZE = 10_000;\nconst CONTEXT_BATCH_FLUSH_SIZE = 100;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ntype FlagResource = components[\"schemas\"][\"FlagResource\"];\n\n/** Map HTTP errors to typed SDK exceptions. @internal */\nasync function checkError(response: Response, context: string): Promise<never> {\n const body = await response.text().catch(() => \"\");\n switch (response.status) {\n case 404:\n throw new SmplNotFoundError(body || context, 404, body);\n case 409:\n throw new SmplConflictError(body || context, 409, body);\n case 422:\n throw new SmplValidationError(body || context, 422, body);\n default:\n throw new SmplError(`HTTP ${response.status}: ${body}`, response.status, body);\n }\n}\n\n/** Re-raise fetch-level errors as typed SDK exceptions. @internal */\nfunction wrapFetchError(err: unknown): never {\n if (\n err instanceof SmplNotFoundError ||\n err instanceof SmplConflictError ||\n err instanceof SmplValidationError ||\n err instanceof SmplError\n ) {\n throw err;\n }\n if (err instanceof TypeError) {\n throw new SmplConnectionError(`Network error: ${err.message}`);\n }\n throw new SmplConnectionError(\n `Request failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n}\n\n// Re-import for the above helper\nimport { SmplConnectionError } from \"../errors.js\";\n\n/** Convert Context list to nested evaluation dict. @internal */\nfunction contextsToEvalDict(contexts: Context[]): Record<string, any> {\n const result: Record<string, any> = {};\n for (const ctx of contexts) {\n result[ctx.type] = { key: ctx.key, ...ctx.attributes };\n }\n return result;\n}\n\n/** Recursively sort object keys for stable serialization. @internal */\nfunction sortedStringify(obj: any): string {\n if (obj === null || obj === undefined) return \"null\";\n if (typeof obj !== \"object\") return JSON.stringify(obj);\n if (Array.isArray(obj)) return \"[\" + obj.map(sortedStringify).join(\",\") + \"]\";\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + sortedStringify(obj[k])).join(\",\") + \"}\";\n}\n\n/** Compute a stable hash for a context evaluation dict. @internal */\nfunction hashContext(evalDict: Record<string, any>): string {\n const serialized = sortedStringify(evalDict);\n // Simple hash — no crypto needed, just cache keying\n let hash = 0;\n for (let i = 0; i < serialized.length; i++) {\n const chr = serialized.charCodeAt(i);\n hash = ((hash << 5) - hash + chr) | 0;\n }\n return hash.toString(36);\n}\n\n/**\n * Evaluate a flag definition against the given context.\n *\n * Follows ADR-022 §2.6 semantics:\n * 1. Look up the environment. If missing, return flag-level default.\n * 2. If disabled, return env default or flag default.\n * 3. Iterate rules; first match wins.\n * 4. No match → env default or flag default.\n * @internal\n */\nfunction evaluateFlag(\n flagDef: Record<string, any>,\n environment: string | null,\n evalDict: Record<string, any>,\n): any {\n const flagDefault = flagDef.default;\n const environments = flagDef.environments ?? {};\n\n if (environment === null || !(environment in environments)) {\n return flagDefault;\n }\n\n const envConfig = environments[environment];\n const envDefault = envConfig.default;\n const fallback = envDefault !== undefined && envDefault !== null ? envDefault : flagDefault;\n\n if (!envConfig.enabled) {\n return fallback;\n }\n\n const rules = envConfig.rules ?? [];\n for (const rule of rules) {\n const logic = rule.logic;\n if (!logic || Object.keys(logic).length === 0) {\n continue;\n }\n try {\n const result = jsonLogic.apply(logic, evalDict);\n if (result) {\n return rule.value;\n }\n } catch {\n // Skip invalid rules\n continue;\n }\n }\n\n return fallback;\n}\n\n// ---------------------------------------------------------------------------\n// Change event\n// ---------------------------------------------------------------------------\n\n/** Describes a flag definition change. */\nexport class FlagChangeEvent {\n readonly key: string;\n readonly source: string;\n\n constructor(key: string, source: string) {\n this.key = key;\n this.source = source;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resolution cache + stats\n// ---------------------------------------------------------------------------\n\n/** @internal */\nclass ResolutionCache {\n private _maxSize: number;\n private _cache = new Map<string, any>();\n cacheHits = 0;\n cacheMisses = 0;\n\n constructor(maxSize: number = CACHE_MAX_SIZE) {\n this._maxSize = maxSize;\n }\n\n get(cacheKey: string): [boolean, any] {\n if (this._cache.has(cacheKey)) {\n // Move to end (delete + re-set)\n const value = this._cache.get(cacheKey);\n this._cache.delete(cacheKey);\n this._cache.set(cacheKey, value);\n this.cacheHits++;\n return [true, value];\n }\n this.cacheMisses++;\n return [false, null];\n }\n\n put(cacheKey: string, value: any): void {\n if (this._cache.has(cacheKey)) {\n this._cache.delete(cacheKey);\n }\n this._cache.set(cacheKey, value);\n if (this._cache.size > this._maxSize) {\n // Remove oldest (first) entry\n const firstKey = this._cache.keys().next().value;\n if (firstKey !== undefined) {\n this._cache.delete(firstKey);\n }\n }\n }\n\n clear(): void {\n this._cache.clear();\n }\n}\n\n/** Cache statistics for the flags runtime. */\nexport class FlagStats {\n readonly cacheHits: number;\n readonly cacheMisses: number;\n\n constructor(cacheHits: number, cacheMisses: number) {\n this.cacheHits = cacheHits;\n this.cacheMisses = cacheMisses;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Typed flag handles\n// ---------------------------------------------------------------------------\n\n/** @internal */\nclass FlagHandleBase {\n /** @internal */ readonly _namespace: FlagsClient;\n /** @internal */ readonly _key: string;\n /** @internal */ readonly _default: any;\n /** @internal */ _listeners: Array<(event: FlagChangeEvent) => void> = [];\n\n constructor(namespace: FlagsClient, key: string, defaultValue: any) {\n this._namespace = namespace;\n this._key = key;\n this._default = defaultValue;\n }\n\n get key(): string {\n return this._key;\n }\n\n get default(): any {\n return this._default;\n }\n\n /* v8 ignore next 3 — overridden by all exported subclasses */\n get(options?: { context?: Context[] }): any {\n return this._namespace._evaluateHandle(this._key, this._default, options?.context ?? null);\n }\n\n /** Register a flag-specific change listener. Works as a decorator. */\n onChange(callback: (event: FlagChangeEvent) => void): (event: FlagChangeEvent) => void {\n this._listeners.push(callback);\n return callback;\n }\n}\n\n/** Typed handle for a boolean flag. */\nexport class BoolFlagHandle extends FlagHandleBase {\n get(options?: { context?: Context[] }): boolean {\n const value = this._namespace._evaluateHandle(\n this._key,\n this._default,\n options?.context ?? null,\n );\n if (typeof value === \"boolean\") {\n return value;\n }\n return this._default;\n }\n}\n\n/** Typed handle for a string flag. */\nexport class StringFlagHandle extends FlagHandleBase {\n get(options?: { context?: Context[] }): string {\n const value = this._namespace._evaluateHandle(\n this._key,\n this._default,\n options?.context ?? null,\n );\n if (typeof value === \"string\") {\n return value;\n }\n return this._default;\n }\n}\n\n/** Typed handle for a numeric flag. */\nexport class NumberFlagHandle extends FlagHandleBase {\n get(options?: { context?: Context[] }): number {\n const value = this._namespace._evaluateHandle(\n this._key,\n this._default,\n options?.context ?? null,\n );\n if (typeof value === \"number\") {\n return value;\n }\n return this._default;\n }\n}\n\n/** Typed handle for a JSON flag. */\nexport class JsonFlagHandle extends FlagHandleBase {\n get(options?: { context?: Context[] }): Record<string, any> {\n const value = this._namespace._evaluateHandle(\n this._key,\n this._default,\n options?.context ?? null,\n );\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return value as Record<string, any>;\n }\n return this._default;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Context registration buffer\n// ---------------------------------------------------------------------------\n\n/** @internal */\nclass ContextRegistrationBuffer {\n private _seen = new Map<string, Record<string, any>>();\n private _pending: Array<Record<string, any>> = [];\n\n observe(contexts: Context[]): void {\n for (const ctx of contexts) {\n const cacheKey = `${ctx.type}:${ctx.key}`;\n if (!this._seen.has(cacheKey)) {\n if (this._seen.size >= CONTEXT_REGISTRATION_LRU_SIZE) {\n // Remove oldest entry\n const firstKey = this._seen.keys().next().value;\n if (firstKey !== undefined) {\n this._seen.delete(firstKey);\n }\n }\n this._seen.set(cacheKey, ctx.attributes);\n this._pending.push({\n id: `${ctx.type}:${ctx.key}`,\n name: ctx.name ?? ctx.key,\n attributes: { ...ctx.attributes },\n });\n }\n }\n }\n\n drain(): Array<Record<string, any>> {\n const batch = this._pending;\n this._pending = [];\n return batch;\n }\n\n get pendingCount(): number {\n return this._pending.length;\n }\n}\n\n// ---------------------------------------------------------------------------\n// FlagsClient\n// ---------------------------------------------------------------------------\n\n/**\n * Client for the smplkit Flags API — management plane + prescriptive runtime.\n *\n * Obtained via `SmplClient.flags`.\n */\nexport class FlagsClient {\n /** @internal */\n readonly _apiKey: string;\n /** @internal */\n readonly _baseUrl: string = FLAGS_BASE_URL;\n\n /** @internal */\n private readonly _http: ReturnType<typeof createClient<import(\"../generated/flags.d.ts\").paths>>;\n /** @internal */\n private readonly _transport: Transport;\n\n // Runtime state\n private _environment: string | null = null;\n private _flagStore: Record<string, Record<string, any>> = {};\n private _connected = false;\n private _cache = new ResolutionCache();\n private _contextProvider: (() => Context[]) | null = null;\n private _contextBuffer = new ContextRegistrationBuffer();\n private _handles: Record<string, FlagHandleBase> = {};\n private _globalListeners: Array<(event: FlagChangeEvent) => void> = [];\n\n // Shared WebSocket (set during connect)\n private _wsManager: SharedWebSocket | null = null;\n private readonly _ensureWs: () => SharedWebSocket;\n\n /** @internal — set by SmplClient after construction. */\n _parent: { readonly _environment: string; readonly _service: string | null } | null = null;\n\n /** @internal */\n constructor(apiKey: string, ensureWs: () => SharedWebSocket, timeout?: number) {\n this._apiKey = apiKey;\n this._ensureWs = ensureWs;\n const ms = timeout ?? 30_000;\n\n this._http = createClient<import(\"../generated/flags.d.ts\").paths>({\n baseUrl: FLAGS_BASE_URL,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n Accept: \"application/json\",\n },\n fetch: async (request: Request): Promise<Response> => {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), ms);\n try {\n return await fetch(new Request(request, { signal: controller.signal }));\n } catch (err) {\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new SmplTimeoutError(`Request timed out after ${ms}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n },\n });\n\n this._transport = new Transport({ apiKey, timeout: ms });\n }\n\n // ------------------------------------------------------------------\n // Management methods\n // ------------------------------------------------------------------\n\n /** Create a flag. */\n async create(\n key: string,\n options: {\n name: string;\n type: FlagType;\n default: unknown;\n description?: string;\n values?: Array<{ name: string; value: unknown }>;\n },\n ): Promise<Flag> {\n let values = options.values;\n if (values === undefined && options.type === \"BOOLEAN\") {\n values = [\n { name: \"True\", value: true },\n { name: \"False\", value: false },\n ];\n }\n\n const body = {\n data: {\n type: \"flag\" as const,\n attributes: {\n key,\n name: options.name,\n description: options.description ?? \"\",\n type: options.type,\n default: options.default,\n values: values ?? [],\n },\n },\n };\n\n let data: components[\"schemas\"][\"FlagResponse\"] | undefined;\n try {\n const result = await this._http.POST(\"/api/v1/flags\", { body });\n if (result.error !== undefined) await checkError(result.response, \"Failed to create flag\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplValidationError(\"Failed to create flag\");\n return this._resourceToModel(data.data);\n }\n\n /** Fetch a flag by UUID. */\n async get(flagId: string): Promise<Flag> {\n let data: components[\"schemas\"][\"FlagResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/flags/{id}\", {\n params: { path: { id: flagId } },\n });\n if (result.error !== undefined) await checkError(result.response, `Flag ${flagId} not found`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplNotFoundError(`Flag ${flagId} not found`);\n return this._resourceToModel(data.data);\n }\n\n /** List all flags. */\n async list(): Promise<Flag[]> {\n let data: components[\"schemas\"][\"FlagListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/flags\", {});\n if (result.error !== undefined) await checkError(result.response, \"Failed to list flags\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data) return [];\n return data.data.map((r) => this._resourceToModel(r));\n }\n\n /** Delete a flag by UUID. */\n async delete(flagId: string): Promise<void> {\n try {\n const result = await this._http.DELETE(\"/api/v1/flags/{id}\", {\n params: { path: { id: flagId } },\n });\n if (result.error !== undefined && result.response.status !== 204)\n await checkError(result.response, `Failed to delete flag ${flagId}`);\n } catch (err) {\n wrapFetchError(err);\n }\n }\n\n /**\n * Internal: PUT a full flag update.\n * Called by {@link Flag} instance methods.\n * @internal\n */\n async _updateFlag(options: {\n flag: Flag;\n environments?: Record<string, any>;\n values?: Array<{ name: string; value: unknown }>;\n default?: unknown;\n description?: string;\n name?: string;\n }): Promise<Flag> {\n const { flag } = options;\n const body = {\n data: {\n type: \"flag\" as const,\n attributes: {\n key: flag.key,\n name: options.name !== undefined ? options.name : flag.name,\n type: flag.type,\n default: options.default !== undefined ? options.default : flag.default,\n values: options.values !== undefined ? options.values : flag.values,\n description:\n options.description !== undefined ? options.description : (flag.description ?? \"\"),\n ...(options.environments !== undefined\n ? { environments: options.environments }\n : flag.environments && Object.keys(flag.environments).length > 0\n ? { environments: flag.environments }\n : {}),\n },\n },\n };\n\n let data: components[\"schemas\"][\"FlagResponse\"] | undefined;\n try {\n const result = await this._http.PUT(\"/api/v1/flags/{id}\", {\n params: { path: { id: flag.id } },\n body,\n });\n if (result.error !== undefined)\n await checkError(result.response, `Failed to update flag ${flag.id}`);\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data || !data.data) throw new SmplValidationError(`Failed to update flag ${flag.id}`);\n return this._resourceToModel(data.data);\n }\n\n // ------------------------------------------------------------------\n // Context type management (direct HTTP — not in generated spec)\n // ------------------------------------------------------------------\n\n /** Create a context type. */\n async createContextType(key: string, options: { name: string }): Promise<ContextType> {\n const resp = await this._transport.post(`${APP_BASE_URL}/api/v1/context_types`, {\n data: { type: \"context_type\", attributes: { key, name: options.name } },\n });\n const data = resp.data ?? {};\n return this._parseContextType(data);\n }\n\n /** Update a context type (merge attributes). */\n async updateContextType(\n ctId: string,\n options: { attributes: Record<string, any> },\n ): Promise<ContextType> {\n const resp = await this._transport.put(`${APP_BASE_URL}/api/v1/context_types/${ctId}`, {\n data: { type: \"context_type\", attributes: { attributes: options.attributes } },\n });\n const data = resp.data ?? {};\n return this._parseContextType(data);\n }\n\n /** List all context types. */\n async listContextTypes(): Promise<ContextType[]> {\n const resp = await this._transport.get(`${APP_BASE_URL}/api/v1/context_types`);\n const items = resp.data ?? [];\n return (items as any[]).map((item: any) => this._parseContextType(item));\n }\n\n /** Delete a context type. */\n async deleteContextType(ctId: string): Promise<void> {\n await this._transport.delete(`${APP_BASE_URL}/api/v1/context_types/${ctId}`);\n }\n\n /** List context instances filtered by context type key. */\n async listContexts(options: { contextTypeKey: string }): Promise<any[]> {\n const resp = await this._transport.get(`${APP_BASE_URL}/api/v1/contexts`, {\n \"filter[context_type]\": options.contextTypeKey,\n });\n return resp.data ?? [];\n }\n\n // ------------------------------------------------------------------\n // Runtime: typed flag handles\n // ------------------------------------------------------------------\n\n /** Declare a boolean flag handle. */\n boolFlag(key: string, defaultValue: boolean): BoolFlagHandle {\n const handle = new BoolFlagHandle(this, key, defaultValue);\n this._handles[key] = handle;\n return handle;\n }\n\n /** Declare a string flag handle. */\n stringFlag(key: string, defaultValue: string): StringFlagHandle {\n const handle = new StringFlagHandle(this, key, defaultValue);\n this._handles[key] = handle;\n return handle;\n }\n\n /** Declare a numeric flag handle. */\n numberFlag(key: string, defaultValue: number): NumberFlagHandle {\n const handle = new NumberFlagHandle(this, key, defaultValue);\n this._handles[key] = handle;\n return handle;\n }\n\n /** Declare a JSON flag handle. */\n jsonFlag(key: string, defaultValue: Record<string, any>): JsonFlagHandle {\n const handle = new JsonFlagHandle(this, key, defaultValue);\n this._handles[key] = handle;\n return handle;\n }\n\n // ------------------------------------------------------------------\n // Runtime: context provider\n // ------------------------------------------------------------------\n\n /**\n * Register a context provider function.\n *\n * Called on every `handle.get()` to supply the current evaluation\n * context. Can also be used as a decorator:\n *\n * ```typescript\n * client.flags.setContextProvider(() => [\n * new Context(\"user\", userId, { plan: userPlan }),\n * ]);\n * ```\n */\n setContextProvider(fn: () => Context[]): void {\n this._contextProvider = fn;\n }\n\n /**\n * Register a context provider — decorator-style alias.\n *\n * ```typescript\n * const provider = client.flags.contextProvider(() => [...]);\n * ```\n */\n contextProvider(fn: () => Context[]): () => Context[] {\n this._contextProvider = fn;\n return fn;\n }\n\n // ------------------------------------------------------------------\n // Runtime: connect / disconnect / refresh\n // ------------------------------------------------------------------\n\n /**\n * Connect to an environment: fetch flag definitions, register on\n * shared WebSocket, enable local evaluation.\n * @internal — called by SmplClient.connect().\n */\n async _connectInternal(environment: string): Promise<void> {\n this._environment = environment;\n await this._fetchAllFlags();\n this._connected = true;\n this._cache.clear();\n\n // Register on the shared WebSocket\n this._wsManager = this._ensureWs();\n this._wsManager.on(\"flag_changed\", this._handleFlagChanged);\n this._wsManager.on(\"flag_deleted\", this._handleFlagDeleted);\n }\n\n /** Disconnect: unregister from WebSocket, flush contexts, clear state. */\n async disconnect(): Promise<void> {\n if (this._wsManager !== null) {\n this._wsManager.off(\"flag_changed\", this._handleFlagChanged);\n this._wsManager.off(\"flag_deleted\", this._handleFlagDeleted);\n this._wsManager = null;\n }\n\n await this._flushContexts();\n this._flagStore = {};\n this._cache.clear();\n this._connected = false;\n this._environment = null;\n }\n\n /** Re-fetch all flag definitions and clear cache. */\n async refresh(): Promise<void> {\n await this._fetchAllFlags();\n this._cache.clear();\n this._fireChangeListenersAll(\"manual\");\n }\n\n /** Return the current WebSocket connection status. */\n connectionStatus(): string {\n if (this._wsManager !== null) {\n return this._wsManager.connectionStatus;\n }\n return \"disconnected\";\n }\n\n /** Return cache statistics. */\n stats(): FlagStats {\n return new FlagStats(this._cache.cacheHits, this._cache.cacheMisses);\n }\n\n // ------------------------------------------------------------------\n // Runtime: change listeners\n // ------------------------------------------------------------------\n\n /** Register a global change listener that fires for any flag change. */\n onChangeAny(callback: (event: FlagChangeEvent) => void): (event: FlagChangeEvent) => void {\n this._globalListeners.push(callback);\n return callback;\n }\n\n /**\n * Register a global change listener — decorator-style alias.\n *\n * ```typescript\n * const listener = client.flags.onChange((event) => { ... });\n * ```\n */\n onChange(callback: (event: FlagChangeEvent) => void): (event: FlagChangeEvent) => void {\n return this.onChangeAny(callback);\n }\n\n // ------------------------------------------------------------------\n // Runtime: context registration\n // ------------------------------------------------------------------\n\n /**\n * Explicitly register context(s) for background batch registration.\n *\n * Accepts a single Context or an array. Fire-and-forget — never\n * blocks. Works before `connect()` is called.\n */\n register(context: Context | Context[]): void {\n if (Array.isArray(context)) {\n this._contextBuffer.observe(context);\n } else {\n this._contextBuffer.observe([context]);\n }\n }\n\n /** Flush pending context registrations to the server. */\n async flushContexts(): Promise<void> {\n await this._flushContexts();\n }\n\n // ------------------------------------------------------------------\n // Runtime: Tier 1 evaluate\n // ------------------------------------------------------------------\n\n /**\n * Tier 1 explicit evaluation — stateless, no provider or cache.\n *\n * Useful for scripts, one-off jobs, and infrastructure code.\n */\n async evaluate(key: string, options: { environment: string; context: Context[] }): Promise<any> {\n const evalDict = contextsToEvalDict(options.context);\n\n // Auto-inject service context if set and not already provided\n if (this._parent?._service && !(\"service\" in evalDict)) {\n evalDict[\"service\"] = { key: this._parent._service };\n }\n\n // Use local store if connected, otherwise fetch\n let flagDef: Record<string, any> | null = null;\n if (this._connected && key in this._flagStore) {\n flagDef = this._flagStore[key];\n } else {\n const flags = await this._fetchFlagsList();\n for (const f of flags) {\n if (f.key === key) {\n flagDef = f;\n break;\n }\n }\n }\n\n if (flagDef === null) {\n return null;\n }\n\n return evaluateFlag(flagDef, options.environment, evalDict);\n }\n\n // ------------------------------------------------------------------\n // Internal: evaluation\n // ------------------------------------------------------------------\n\n /** @internal */\n _evaluateHandle(key: string, defaultValue: any, context: Context[] | null): any {\n if (!this._connected) {\n throw new SmplNotConnectedError(\"SmplClient is not connected. Call client.connect() first.\");\n }\n\n let evalDict: Record<string, any>;\n if (context !== null) {\n evalDict = contextsToEvalDict(context);\n } else if (this._contextProvider !== null) {\n const contexts = this._contextProvider();\n evalDict = contextsToEvalDict(contexts);\n this._contextBuffer.observe(contexts);\n if (this._contextBuffer.pendingCount >= CONTEXT_BATCH_FLUSH_SIZE) {\n // Fire-and-forget background flush\n void this._flushContexts();\n }\n } else {\n evalDict = {};\n }\n\n // Auto-inject service context if set and not already provided\n if (this._parent?._service && !(\"service\" in evalDict)) {\n evalDict[\"service\"] = { key: this._parent._service };\n }\n\n const ctxHash = hashContext(evalDict);\n const cacheKey = `${key}:${ctxHash}`;\n\n const [hit, cachedValue] = this._cache.get(cacheKey);\n if (hit) {\n return cachedValue;\n }\n\n const flagDef = this._flagStore[key];\n if (flagDef === undefined) {\n this._cache.put(cacheKey, defaultValue);\n return defaultValue;\n }\n\n let value = evaluateFlag(flagDef, this._environment, evalDict);\n if (value === null || value === undefined) {\n value = defaultValue;\n }\n\n this._cache.put(cacheKey, value);\n return value;\n }\n\n // ------------------------------------------------------------------\n // Internal: event handlers (called by SharedWebSocket)\n // ------------------------------------------------------------------\n\n private _handleFlagChanged = (data: Record<string, any>): void => {\n const flagKey = data.key as string | undefined;\n // Re-fetch all flags (async, fire-and-forget)\n void this._fetchAllFlags().then(() => {\n this._cache.clear();\n this._fireChangeListeners(flagKey ?? null, \"websocket\");\n });\n };\n\n private _handleFlagDeleted = (data: Record<string, any>): void => {\n const flagKey = data.key as string | undefined;\n void this._fetchAllFlags().then(() => {\n this._cache.clear();\n this._fireChangeListeners(flagKey ?? null, \"websocket\");\n });\n };\n\n // ------------------------------------------------------------------\n // Internal: flag store\n // ------------------------------------------------------------------\n\n private async _fetchAllFlags(): Promise<void> {\n const flags = await this._fetchFlagsList();\n const store: Record<string, Record<string, any>> = {};\n for (const f of flags) {\n store[f.key] = f;\n }\n this._flagStore = store;\n }\n\n private async _fetchFlagsList(): Promise<Array<Record<string, any>>> {\n let data: components[\"schemas\"][\"FlagListResponse\"] | undefined;\n try {\n const result = await this._http.GET(\"/api/v1/flags\", {});\n if (result.error !== undefined) await checkError(result.response, \"Failed to list flags\");\n data = result.data;\n } catch (err) {\n wrapFetchError(err);\n }\n if (!data) return [];\n return data.data.map((r) => this._resourceToPlainDict(r));\n }\n\n // ------------------------------------------------------------------\n // Internal: change listeners\n // ------------------------------------------------------------------\n\n private _fireChangeListeners(flagKey: string | null, source: string): void {\n if (flagKey) {\n const event = new FlagChangeEvent(flagKey, source);\n for (const cb of this._globalListeners) {\n try {\n cb(event);\n } catch {\n // ignore listener errors\n }\n }\n const handle = this._handles[flagKey];\n if (handle) {\n for (const cb of handle._listeners) {\n try {\n cb(event);\n } catch {\n // ignore listener errors\n }\n }\n }\n }\n }\n\n private _fireChangeListenersAll(source: string): void {\n for (const flagKey of Object.keys(this._flagStore)) {\n this._fireChangeListeners(flagKey, source);\n }\n }\n\n // ------------------------------------------------------------------\n // Internal: context flush\n // ------------------------------------------------------------------\n\n private async _flushContexts(): Promise<void> {\n const batch = this._contextBuffer.drain();\n if (batch.length === 0) return;\n try {\n await this._transport.put(`${APP_BASE_URL}/api/v1/contexts/bulk`, {\n contexts: batch,\n });\n } catch {\n // Fire-and-forget: ignore registration failures\n }\n }\n\n // ------------------------------------------------------------------\n // Internal: model conversion\n // ------------------------------------------------------------------\n\n private _resourceToModel(resource: FlagResource): Flag {\n const attrs = resource.attributes;\n return new Flag(this, {\n id: resource.id ?? \"\",\n key: attrs.key,\n name: attrs.name,\n type: attrs.type,\n default: attrs.default,\n values: (attrs.values ?? []).map((v) => ({ name: v.name, value: v.value })),\n description: attrs.description ?? null,\n environments: attrs.environments ?? {},\n createdAt: attrs.created_at ?? null,\n updatedAt: attrs.updated_at ?? null,\n });\n }\n\n private _resourceToPlainDict(resource: FlagResource): Record<string, any> {\n const attrs = resource.attributes;\n return {\n key: attrs.key,\n name: attrs.name,\n type: attrs.type,\n default: attrs.default,\n values: (attrs.values ?? []).map((v) => ({ name: v.name, value: v.value })),\n description: attrs.description ?? null,\n environments: attrs.environments ?? {},\n };\n }\n\n private _parseContextType(data: any): ContextType {\n const attrs = data.attributes ?? {};\n return new ContextType({\n id: data.id ?? \"\",\n key: attrs.key ?? \"\",\n name: attrs.name ?? \"\",\n attributes: attrs.attributes ?? {},\n });\n }\n}\n","/**\n * Authentication handling for API key auth.\n *\n * @internal This module is not part of the public API.\n */\n\n/**\n * Build the Authorization header value for Bearer token auth.\n *\n * @param apiKey - The API key to use for authentication.\n * @returns The header value string in the form `Bearer {apiKey}`.\n */\nexport function buildAuthHeader(apiKey: string): string {\n return `Bearer ${apiKey}`;\n}\n","/**\n * Internal HTTP client wrapper.\n *\n * Uses native `fetch` with `AbortController` for timeouts. Maps network\n * errors and HTTP status codes to typed SDK exceptions.\n *\n * @internal This module is not part of the public API.\n */\n\nimport { buildAuthHeader } from \"./auth.js\";\nimport {\n SmplConnectionError,\n SmplConflictError,\n SmplError,\n SmplNotFoundError,\n SmplTimeoutError,\n SmplValidationError,\n} from \"./errors.js\";\n\nconst SDK_VERSION = \"0.0.0\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Options for constructing a {@link Transport} instance. */\nexport interface TransportOptions {\n /** The API key used for Bearer token authentication. */\n apiKey: string;\n\n /** Request timeout in milliseconds. Defaults to 30 000. */\n timeout?: number;\n}\n\n/** Parsed JSON response from the API. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype JsonBody = Record<string, any>;\n\n/**\n * Low-level HTTP transport that handles auth, timeouts, and error mapping.\n *\n * @internal\n */\nexport class Transport {\n private readonly apiKey: string;\n private readonly timeout: number;\n\n constructor(options: TransportOptions) {\n this.apiKey = options.apiKey;\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Send a GET request.\n *\n * @param url - Fully-qualified URL (e.g. `https://config.smplkit.com/api/v1/configs`).\n * @param params - Optional query parameters.\n * @returns Parsed JSON response body.\n */\n async get(url: string, params?: Record<string, string>): Promise<JsonBody> {\n return this.request(\"GET\", url, undefined, params);\n }\n\n /**\n * Send a POST request with a JSON body.\n *\n * @param url - Fully-qualified URL.\n * @param body - JSON-serializable request body.\n * @returns Parsed JSON response body.\n */\n async post(url: string, body: JsonBody): Promise<JsonBody> {\n return this.request(\"POST\", url, body);\n }\n\n /**\n * Send a PUT request with a JSON body.\n *\n * @param url - Fully-qualified URL.\n * @param body - JSON-serializable request body.\n * @returns Parsed JSON response body.\n */\n async put(url: string, body: JsonBody): Promise<JsonBody> {\n return this.request(\"PUT\", url, body);\n }\n\n /**\n * Send a DELETE request.\n *\n * @param url - Fully-qualified URL.\n * @returns Parsed JSON response body (empty object for 204 responses).\n */\n async delete(url: string): Promise<JsonBody> {\n return this.request(\"DELETE\", url);\n }\n\n /**\n * Core request method. Handles headers, timeouts, and error mapping.\n */\n private async request(\n method: string,\n url: string,\n body?: JsonBody,\n params?: Record<string, string>,\n ): Promise<JsonBody> {\n if (params) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n\n const headers: Record<string, string> = {\n Authorization: buildAuthHeader(this.apiKey),\n \"User-Agent\": `smplkit-typescript-sdk/${SDK_VERSION}`,\n Accept: \"application/vnd.api+json\",\n };\n\n if (body !== undefined) {\n headers[\"Content-Type\"] = \"application/vnd.api+json\";\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new SmplTimeoutError(`Request timed out after ${this.timeout}ms`);\n }\n if (error instanceof TypeError) {\n throw new SmplConnectionError(`Network error: ${error.message}`);\n }\n throw new SmplConnectionError(\n `Request failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n } finally {\n clearTimeout(timeoutId);\n }\n\n // 204 No Content — return empty object\n if (response.status === 204) {\n return {};\n }\n\n const responseText = await response.text();\n\n if (!response.ok) {\n this.throwForStatus(response.status, responseText);\n }\n\n try {\n return JSON.parse(responseText) as JsonBody;\n } catch {\n throw new SmplError(`Invalid JSON response: ${responseText}`, response.status, responseText);\n }\n }\n\n /**\n * Map HTTP error status codes to typed SDK exceptions.\n *\n * @throws {SmplNotFoundError} On 404.\n * @throws {SmplConflictError} On 409.\n * @throws {SmplValidationError} On 422.\n * @throws {SmplError} On any other non-2xx status.\n */\n private throwForStatus(status: number, body: string): never {\n switch (status) {\n case 404:\n throw new SmplNotFoundError(body, 404, body);\n case 409:\n throw new SmplConflictError(body, 409, body);\n case 422:\n throw new SmplValidationError(body, 422, body);\n default:\n throw new SmplError(`HTTP ${status}: ${body}`, status, body);\n }\n }\n}\n","/**\n * Flag and ContextType resource models returned by the management API.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { FlagsClient } from \"./client.js\";\n\n/**\n * A flag resource returned by {@link FlagsClient} management methods.\n *\n * Provides `update()` for partial updates and `addRule()` for\n * conveniently appending a rule to an environment.\n */\nexport class Flag {\n /** UUID of the flag. */\n id: string;\n /** Unique key within the account. */\n key: string;\n /** Human-readable display name. */\n name: string;\n /** Value type: BOOLEAN, STRING, NUMERIC, or JSON. */\n type: string;\n /** Flag-level default value. */\n default: unknown;\n /** Closed set of possible values. */\n values: Array<{ name: string; value: unknown }>;\n /** Optional description. */\n description: string | null;\n /** Per-environment configuration. */\n environments: Record<string, any>;\n /** When the flag was created. */\n createdAt: string | null;\n /** When the flag was last updated. */\n updatedAt: string | null;\n\n /** @internal */\n private readonly _client: FlagsClient;\n\n /** @internal */\n constructor(\n client: FlagsClient,\n fields: {\n id: string;\n key: string;\n name: string;\n type: string;\n default: unknown;\n values: Array<{ name: string; value: unknown }>;\n description: string | null;\n environments: Record<string, any>;\n createdAt: string | null;\n updatedAt: string | null;\n },\n ) {\n this._client = client;\n this.id = fields.id;\n this.key = fields.key;\n this.name = fields.name;\n this.type = fields.type;\n this.default = fields.default;\n this.values = fields.values;\n this.description = fields.description;\n this.environments = fields.environments;\n this.createdAt = fields.createdAt;\n this.updatedAt = fields.updatedAt;\n }\n\n /**\n * Update this flag's attributes on the server.\n *\n * Only provided fields are changed; others retain their current values.\n */\n async update(options: {\n environments?: Record<string, any>;\n values?: Array<{ name: string; value: unknown }>;\n default?: unknown;\n description?: string;\n name?: string;\n }): Promise<void> {\n const updated = await this._client._updateFlag({\n flag: this,\n environments: options.environments,\n values: options.values,\n default: options.default,\n description: options.description,\n name: options.name,\n });\n this._apply(updated);\n }\n\n /**\n * Add a rule to a specific environment.\n *\n * The built rule must include an `environment` key (set via\n * `Rule(...).environment(\"env_key\")`). Re-fetches current state\n * first to avoid stale data.\n */\n async addRule(builtRule: Record<string, any>): Promise<void> {\n const envKey = builtRule.environment as string | undefined;\n if (!envKey) {\n throw new Error(\n \"Built rule must include 'environment' key. \" +\n 'Use new Rule(...).environment(\"env_key\").when(...).serve(...).build()',\n );\n }\n\n // Re-fetch current state to avoid staleness\n const current = await this._client.get(this.id);\n this._apply(current);\n\n const envs = { ...this.environments };\n const envData = { ...(envs[envKey] ?? { enabled: true, rules: [] }) };\n const rules = [...(envData.rules ?? [])];\n\n // Strip the environment key from the rule — it's metadata, not part of the rule\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { environment: _env, ...ruleCopy } = builtRule;\n rules.push(ruleCopy);\n envData.rules = rules;\n envs[envKey] = envData;\n\n const updated = await this._client._updateFlag({\n flag: this,\n environments: envs,\n });\n this._apply(updated);\n }\n\n /** @internal */\n _apply(other: Flag): void {\n this.id = other.id;\n this.key = other.key;\n this.name = other.name;\n this.type = other.type;\n this.default = other.default;\n this.values = other.values;\n this.description = other.description;\n this.environments = other.environments;\n this.createdAt = other.createdAt;\n this.updatedAt = other.updatedAt;\n }\n\n toString(): string {\n return `Flag(key=${this.key}, type=${this.type}, default=${this.default})`;\n }\n}\n\n/** A context type resource returned by management API methods. */\nexport class ContextType {\n /** UUID. */\n id: string;\n /** Unique key within the account. */\n key: string;\n /** Human-readable display name. */\n name: string;\n /** Known attributes. */\n attributes: Record<string, any>;\n\n constructor(fields: { id: string; key: string; name: string; attributes: Record<string, any> }) {\n this.id = fields.id;\n this.key = fields.key;\n this.name = fields.name;\n this.attributes = fields.attributes;\n }\n\n toString(): string {\n return `ContextType(key=${this.key}, name=${this.name})`;\n }\n}\n","/**\n * Shared WebSocket connection to the app service event gateway.\n *\n * A single {@link SharedWebSocket} instance is shared across all product\n * modules (config, flags) within one {@link SmplClient}. Product modules\n * register listeners for specific event types; the shared connection\n * dispatches incoming events to the appropriate listeners.\n *\n * Protocol:\n * - Connect to `wss://app.smplkit.com/api/ws/v1/events?api_key={key}`\n * - Receive `{\"type\": \"connected\"}` on success\n * - Receive events: `{\"event\": \"config_changed\", ...}`, `{\"event\": \"flag_changed\", ...}`\n * - No subscribe message — the API key determines the account\n * - Heartbeat: server sends `ping`, client responds with `pong`\n * - Reconnect with exponential backoff\n */\n\nimport WebSocket from \"ws\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype EventCallback = (data: Record<string, any>) => void;\n\nconst BACKOFF_MS = [1000, 2000, 4000, 8000, 16000, 32000, 60000];\n\n/**\n * Manages a single WebSocket connection to the app service event gateway.\n *\n * Shared across config and flags modules for efficient multiplexing.\n */\nexport class SharedWebSocket {\n private readonly _appBaseUrl: string;\n private readonly _apiKey: string;\n\n private _listeners: Map<string, EventCallback[]> = new Map();\n private _connectionStatus: string = \"disconnected\";\n private _closed = false;\n private _ws: InstanceType<typeof WebSocket> | null = null;\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private _backoffIndex = 0;\n\n constructor(appBaseUrl: string, apiKey: string) {\n this._appBaseUrl = appBaseUrl;\n this._apiKey = apiKey;\n }\n\n // ------------------------------------------------------------------\n // Listener registration\n // ------------------------------------------------------------------\n\n /** Register a listener for a specific event type. */\n on(eventName: string, callback: EventCallback): void {\n if (!this._listeners.has(eventName)) {\n this._listeners.set(eventName, []);\n }\n this._listeners.get(eventName)!.push(callback);\n }\n\n /** Unregister a listener for a specific event type. */\n off(eventName: string, callback: EventCallback): void {\n const list = this._listeners.get(eventName);\n if (list) {\n const idx = list.indexOf(callback);\n if (idx !== -1) {\n list.splice(idx, 1);\n }\n }\n }\n\n private _dispatch(eventName: string, data: Record<string, any>): void {\n const callbacks = this._listeners.get(eventName);\n if (callbacks) {\n for (const cb of [...callbacks]) {\n try {\n cb(data);\n } catch {\n // ignore listener errors\n }\n }\n }\n }\n\n // ------------------------------------------------------------------\n // Connection status\n // ------------------------------------------------------------------\n\n get connectionStatus(): string {\n return this._connectionStatus;\n }\n\n // ------------------------------------------------------------------\n // Lifecycle\n // ------------------------------------------------------------------\n\n /** Start the WebSocket connection. */\n start(): void {\n this._closed = false;\n this._connect();\n }\n\n /** Stop the WebSocket connection. */\n stop(): void {\n this._closed = true;\n this._connectionStatus = \"disconnected\";\n\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n\n if (this._ws !== null) {\n this._ws.close();\n this._ws = null;\n }\n }\n\n // ------------------------------------------------------------------\n // Connection internals\n // ------------------------------------------------------------------\n\n private _buildWsUrl(): string {\n let url = this._appBaseUrl;\n if (url.startsWith(\"https://\")) {\n url = \"wss://\" + url.slice(\"https://\".length);\n } else if (url.startsWith(\"http://\")) {\n url = \"ws://\" + url.slice(\"http://\".length);\n } else {\n url = \"wss://\" + url;\n }\n url = url.replace(/\\/$/, \"\");\n return `${url}/api/ws/v1/events?api_key=${this._apiKey}`;\n }\n\n private _connect(): void {\n if (this._closed) return;\n\n this._connectionStatus = \"connecting\";\n const wsUrl = this._buildWsUrl();\n\n try {\n const ws = new WebSocket(wsUrl);\n this._ws = ws;\n\n ws.on(\"open\", () => {\n if (this._closed) {\n ws.close();\n return;\n }\n // Don't set connected yet — wait for {\"type\": \"connected\"} confirmation\n });\n\n ws.on(\"message\", (data: WebSocket.RawData) => {\n try {\n const raw = String(data);\n\n // Heartbeat: server sends \"ping\", we respond with \"pong\"\n if (raw === \"ping\") {\n ws.send(\"pong\");\n return;\n }\n\n const msg = JSON.parse(raw) as Record<string, any>;\n\n // Connection confirmation\n if (msg.type === \"connected\") {\n this._backoffIndex = 0;\n this._connectionStatus = \"connected\";\n return;\n }\n\n // Error from server\n if (msg.type === \"error\") {\n return;\n }\n\n // Route events by the \"event\" field\n const eventName = msg.event as string | undefined;\n if (eventName) {\n this._dispatch(eventName, msg);\n }\n } catch {\n // ignore unparseable messages\n }\n });\n\n ws.on(\"close\", () => {\n if (!this._closed) {\n this._connectionStatus = \"disconnected\";\n this._scheduleReconnect();\n }\n });\n\n ws.on(\"error\", () => {\n // 'close' will fire after 'error'; reconnect is handled there\n });\n } catch {\n if (!this._closed) {\n this._scheduleReconnect();\n }\n }\n }\n\n private _scheduleReconnect(): void {\n if (this._closed) return;\n\n const delay = BACKOFF_MS[Math.min(this._backoffIndex, BACKOFF_MS.length - 1)];\n this._backoffIndex++;\n this._connectionStatus = \"connecting\";\n\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null;\n this._connect();\n }, delay);\n }\n}\n","/**\n * API key resolution chain: explicit → env var → config file.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { SmplError } from \"./errors.js\";\n\nconst NO_API_KEY_MESSAGE =\n \"No API key provided. Set one of:\\n\" +\n \" 1. Pass apiKey to the constructor\\n\" +\n \" 2. Set the SMPLKIT_API_KEY environment variable\\n\" +\n \" 3. Create a ~/.smplkit file with:\\n\" +\n \" [default]\\n\" +\n \" api_key = your_key_here\";\n\nexport function resolveApiKey(explicit?: string): string {\n if (explicit) return explicit;\n\n const envVal = process.env.SMPLKIT_API_KEY;\n if (envVal) return envVal;\n\n const configPath = join(homedir(), \".smplkit\");\n try {\n const content = readFileSync(configPath, \"utf-8\");\n let inDefaultSection = false;\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"[\")) {\n inDefaultSection = trimmed.toLowerCase() === \"[default]\";\n continue;\n }\n if (inDefaultSection && trimmed.startsWith(\"api_key\")) {\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex !== -1) {\n const value = trimmed.slice(eqIndex + 1).trim();\n if (value) return value;\n }\n }\n }\n } catch {\n // File doesn't exist or isn't readable — skip\n }\n\n throw new SmplError(NO_API_KEY_MESSAGE);\n}\n","/**\n * Top-level SDK client — SmplClient.\n *\n * The main entry point for the smplkit TypeScript SDK. Provides access\n * to sub-clients for each API domain (config, flags, logging, etc.).\n */\n\nimport { ConfigClient } from \"./config/client.js\";\nimport { FlagsClient } from \"./flags/client.js\";\nimport { SharedWebSocket } from \"./ws.js\";\nimport { resolveApiKey } from \"./resolve.js\";\nimport { SmplError } from \"./errors.js\";\n\nconst APP_BASE_URL = \"https://app.smplkit.com\";\n\nconst NO_ENVIRONMENT_MESSAGE =\n \"No environment provided. Set one of:\\n\" +\n \" 1. Pass environment to the constructor\\n\" +\n \" 2. Set the SMPLKIT_ENVIRONMENT environment variable\";\n\n/** Configuration options for the {@link SmplClient}. */\nexport interface SmplClientOptions {\n /**\n * API key for authenticating with the smplkit platform.\n * When omitted, the SDK resolves it from the `SMPLKIT_API_KEY`\n * environment variable or the `~/.smplkit` configuration file.\n */\n apiKey?: string;\n\n /**\n * The environment to connect to (e.g. `\"production\"`, `\"staging\"`).\n * When omitted, resolved from the `SMPLKIT_ENVIRONMENT` environment variable.\n */\n environment?: string;\n\n /**\n * Optional service name. When set, the SDK automatically registers\n * the service as a context instance and includes it in flag\n * evaluation context.\n */\n service?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Entry point for the smplkit TypeScript SDK.\n *\n * @example\n * ```typescript\n * import { SmplClient } from \"@smplkit/sdk\";\n *\n * const client = new SmplClient({ apiKey: \"sk_api_...\", environment: \"production\" });\n * await client.connect();\n * ```\n */\nexport class SmplClient {\n /** Client for config management-plane operations. */\n readonly config: ConfigClient;\n\n /** Client for flags management and runtime operations. */\n readonly flags: FlagsClient;\n\n private _wsManager: SharedWebSocket | null = null;\n private readonly _apiKey: string;\n\n /** @internal */\n readonly _environment: string;\n\n /** @internal */\n readonly _service: string | null;\n\n private _connected = false;\n private readonly _timeout: number;\n\n constructor(options: SmplClientOptions = {}) {\n const apiKey = resolveApiKey(options.apiKey);\n this._apiKey = apiKey;\n\n const environment = options.environment || process.env.SMPLKIT_ENVIRONMENT;\n if (!environment) {\n throw new SmplError(NO_ENVIRONMENT_MESSAGE);\n }\n this._environment = environment;\n this._service = options.service || process.env.SMPLKIT_SERVICE || null;\n\n this._timeout = options.timeout ?? 30_000;\n this.config = new ConfigClient(apiKey, this._timeout);\n this.flags = new FlagsClient(apiKey, () => this._ensureWs(), this._timeout);\n\n // Wire the shared WebSocket into the config client\n this.config._getSharedWs = () => this._ensureWs();\n\n // Wire parent reference into sub-clients\n this.flags._parent = this;\n this.config._parent = this;\n }\n\n /**\n * Connect to the smplkit platform.\n *\n * Fetches initial flag and config data, opens the shared WebSocket,\n * and registers the service as a context instance (if provided).\n *\n * This method is idempotent — calling it multiple times is safe.\n */\n async connect(): Promise<void> {\n if (this._connected) return;\n\n // Register service context (fire-and-forget)\n if (this._service) {\n await this._registerServiceContext();\n }\n\n // Connect flags (fetch definitions, register WS listeners)\n await this.flags._connectInternal(this._environment);\n\n // Connect config (fetch all, resolve, cache)\n await this.config._connectInternal(this._environment);\n\n this._connected = true;\n }\n\n /** @internal */\n private async _registerServiceContext(): Promise<void> {\n try {\n await fetch(`${APP_BASE_URL}/api/v1/contexts/bulk`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${this._apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n contexts: [\n {\n type: \"service\",\n key: this._service,\n attributes: { name: this._service },\n },\n ],\n }),\n });\n } catch {\n // Fire-and-forget: log warning on failure\n }\n }\n\n /** Lazily create and start the shared WebSocket. @internal */\n private _ensureWs(): SharedWebSocket {\n if (this._wsManager === null) {\n this._wsManager = new SharedWebSocket(APP_BASE_URL, this._apiKey);\n this._wsManager.start();\n }\n return this._wsManager;\n }\n\n /** Close the shared WebSocket and release resources. */\n close(): void {\n if (this._wsManager !== null) {\n this._wsManager.stop();\n this._wsManager = null;\n }\n }\n}\n","/**\n * ConfigRuntime — runtime-plane value resolution with WebSocket updates.\n *\n * Holds a fully resolved local cache of config values for a specific\n * environment. All value-access methods are synchronous (local reads);\n * only {@link refresh} and {@link close} are async.\n *\n * A background WebSocket connection is maintained for real-time updates.\n * If the WebSocket fails, the runtime operates in cache-only mode and\n * reconnects automatically with exponential backoff.\n */\n\nimport { resolveChain } from \"./resolve.js\";\nimport type { ChainConfig } from \"./resolve.js\";\nimport type { ConfigChangeEvent, ConfigStats, ConnectionStatus } from \"./runtime-types.js\";\nimport type { SharedWebSocket } from \"../ws.js\";\n\n/** @internal */\ninterface ChangeListener {\n callback: (event: ConfigChangeEvent) => void;\n key: string | null;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/** @internal Options for constructing a ConfigRuntime. */\nexport interface ConfigRuntimeOptions {\n configKey: string;\n configId: string;\n environment: string;\n chain: ChainConfig[];\n apiKey: string;\n baseUrl: string;\n fetchChain: (() => Promise<ChainConfig[]>) | null;\n sharedWs?: SharedWebSocket | null;\n}\n\n/**\n * Runtime configuration handle for a specific environment.\n *\n * Obtained by calling {@link Config.connect}. All value-access methods\n * are synchronous and served entirely from a local in-process cache.\n * The cache is populated eagerly on construction and kept current via\n * a background WebSocket connection.\n */\nexport class ConfigRuntime {\n private _cache: Record<string, unknown>;\n private _chain: ChainConfig[];\n private _fetchCount: number;\n private _lastFetchAt: string | null;\n private _closed = false;\n private _listeners: ChangeListener[] = [];\n\n private readonly _environment: string;\n private readonly _fetchChain: (() => Promise<ChainConfig[]>) | null;\n private _sharedWs: SharedWebSocket | null = null;\n\n /** @internal */\n constructor(options: ConfigRuntimeOptions) {\n this._environment = options.environment;\n this._fetchChain = options.fetchChain;\n this._chain = options.chain;\n this._cache = resolveChain(options.chain, options.environment);\n this._fetchCount = options.chain.length;\n this._lastFetchAt = new Date().toISOString();\n\n // Register on shared WebSocket for config_changed events\n if (options.sharedWs) {\n this._sharedWs = options.sharedWs;\n this._sharedWs.on(\"config_changed\", this._handleConfigChanged);\n this._sharedWs.on(\"config_deleted\", this._handleConfigDeleted);\n }\n }\n\n // ---- Value access (synchronous, local cache) ----\n\n /**\n * Return the resolved value for `key`, or `defaultValue` if absent.\n *\n * @param key - The config key to look up.\n * @param defaultValue - Returned when the key is not present (default: null).\n */\n get(key: string, defaultValue: unknown = null): unknown {\n return key in this._cache ? this._cache[key] : defaultValue;\n }\n\n /**\n * Return the value as a string, or `defaultValue` if absent or not a string.\n */\n getString(key: string, defaultValue: string | null = null): string | null {\n const value = this._cache[key];\n return typeof value === \"string\" ? value : defaultValue;\n }\n\n /**\n * Return the value as a number, or `defaultValue` if absent or not a number.\n */\n getInt(key: string, defaultValue: number | null = null): number | null {\n const value = this._cache[key];\n return typeof value === \"number\" ? value : defaultValue;\n }\n\n /**\n * Return the value as a boolean, or `defaultValue` if absent or not a boolean.\n */\n getBool(key: string, defaultValue: boolean | null = null): boolean | null {\n const value = this._cache[key];\n return typeof value === \"boolean\" ? value : defaultValue;\n }\n\n /**\n * Return whether `key` is present in the resolved configuration.\n */\n exists(key: string): boolean {\n return key in this._cache;\n }\n\n /**\n * Return a shallow copy of the full resolved configuration.\n */\n getAll(): Record<string, unknown> {\n return { ...this._cache };\n }\n\n // ---- Change listeners ----\n\n /**\n * Register a listener that fires when a config value changes.\n *\n * @param callback - Called with a {@link ConfigChangeEvent} on each change.\n * @param options.key - If provided, the listener fires only for this key.\n * If omitted, the listener fires for all changes.\n */\n onChange(callback: (event: ConfigChangeEvent) => void, options?: { key?: string }): void {\n this._listeners.push({\n callback,\n key: options?.key ?? null,\n });\n }\n\n // ---- Diagnostics ----\n\n /**\n * Return diagnostic statistics for this runtime.\n */\n stats(): ConfigStats {\n return {\n fetchCount: this._fetchCount,\n lastFetchAt: this._lastFetchAt,\n };\n }\n\n /**\n * Return the current WebSocket connection status.\n */\n connectionStatus(): ConnectionStatus {\n if (this._sharedWs) {\n return this._sharedWs.connectionStatus as ConnectionStatus;\n }\n return \"disconnected\";\n }\n\n // ---- Lifecycle ----\n\n /**\n * Force a manual refresh of the cached configuration.\n *\n * Re-fetches the full config chain via HTTP, re-resolves values, updates\n * the local cache, and fires listeners for any detected changes.\n *\n * @throws {Error} If no `fetchChain` function was provided on construction.\n */\n async refresh(): Promise<void> {\n if (!this._fetchChain) {\n throw new Error(\"No fetchChain function provided; cannot refresh.\");\n }\n\n const newChain = await this._fetchChain();\n const oldCache = this._cache;\n\n this._chain = newChain;\n this._cache = resolveChain(newChain, this._environment);\n this._fetchCount += newChain.length;\n this._lastFetchAt = new Date().toISOString();\n\n this._diffAndFire(oldCache, this._cache, \"manual\");\n }\n\n /**\n * Close the runtime connection.\n *\n * Unregisters from the shared WebSocket. Safe to call multiple times.\n */\n async close(): Promise<void> {\n this._closed = true;\n\n if (this._sharedWs !== null) {\n this._sharedWs.off(\"config_changed\", this._handleConfigChanged);\n this._sharedWs.off(\"config_deleted\", this._handleConfigDeleted);\n this._sharedWs = null;\n }\n }\n\n /**\n * Async dispose support for `await using` (TypeScript 5.2+).\n */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n\n // ---- Shared WebSocket event handlers ----\n\n private _handleConfigChanged = (data: Record<string, any>): void => {\n if (this._closed) return;\n const configId = data.config_id as string | undefined;\n const changes = data.changes as\n | Array<{ key: string; old_value: unknown; new_value: unknown }>\n | undefined;\n if (configId && changes) {\n this._applyChanges(configId, changes);\n } else if (this._fetchChain) {\n // Full re-fetch if the event doesn't include granular changes\n void this._fetchChain()\n .then((newChain) => {\n const oldCache = this._cache;\n this._chain = newChain;\n this._cache = resolveChain(newChain, this._environment);\n this._fetchCount += newChain.length;\n this._lastFetchAt = new Date().toISOString();\n this._diffAndFire(oldCache, this._cache, \"websocket\");\n })\n .catch(() => {\n // ignore fetch errors\n });\n }\n };\n\n private _handleConfigDeleted = (_data: Record<string, any>): void => {\n this._closed = true;\n void this.close();\n };\n\n private _applyChanges(\n configId: string,\n changes: Array<{ key: string; old_value: unknown; new_value: unknown }>,\n ): void {\n const chainEntry = this._chain.find((c) => c.id === configId);\n if (!chainEntry) return;\n\n for (const change of changes) {\n const { key, new_value } = change;\n\n // Get or create the environment entry\n const envEntry =\n chainEntry.environments[this._environment] !== undefined &&\n chainEntry.environments[this._environment] !== null\n ? (chainEntry.environments[this._environment] as Record<string, unknown>)\n : null;\n const envValues =\n envEntry !== null && typeof envEntry === \"object\"\n ? ((envEntry.values ?? {}) as Record<string, unknown>)\n : null;\n\n if (new_value === null || new_value === undefined) {\n // Deletion: remove from base items and env values\n delete chainEntry.items[key];\n if (envValues) delete envValues[key];\n } else if (envValues && key in envValues) {\n // Update existing env-specific override\n envValues[key] = new_value;\n } else if (key in chainEntry.items) {\n // Update existing base value\n chainEntry.items[key] = new_value;\n } else {\n // New key — put in base items\n chainEntry.items[key] = new_value;\n }\n }\n\n const oldCache = this._cache;\n this._cache = resolveChain(this._chain, this._environment);\n this._diffAndFire(oldCache, this._cache, \"websocket\");\n }\n\n private _diffAndFire(\n oldCache: Record<string, unknown>,\n newCache: Record<string, unknown>,\n source: \"websocket\" | \"poll\" | \"manual\",\n ): void {\n const allKeys = new Set([...Object.keys(oldCache), ...Object.keys(newCache)]);\n\n for (const key of allKeys) {\n const oldVal = key in oldCache ? oldCache[key] : null;\n const newVal = key in newCache ? newCache[key] : null;\n\n if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {\n const event: ConfigChangeEvent = { key, oldValue: oldVal, newValue: newVal, source };\n this._fireListeners(event);\n }\n }\n }\n\n private _fireListeners(event: ConfigChangeEvent): void {\n for (const listener of this._listeners) {\n if (listener.key === null || listener.key === event.key) {\n try {\n listener.callback(event);\n } catch {\n // ignore listener errors to prevent one bad listener from stopping others\n }\n }\n }\n }\n}\n","/**\n * Public types for the Flags SDK: FlagType, Context, Rule.\n */\n\n/** The value type of a flag. */\nexport type FlagType = \"BOOLEAN\" | \"STRING\" | \"NUMERIC\" | \"JSON\";\n\n/**\n * A typed evaluation context entity.\n *\n * Represents a single entity (user, account, device, etc.) in the\n * evaluation context. The *type* and *key* identify the entity;\n * *attributes* carry the data that JSON Logic rules target.\n *\n * @example\n * ```typescript\n * new Context(\"user\", \"user-123\", { plan: \"enterprise\", firstName: \"Alice\" })\n * new Context(\"user\", \"user-123\", { plan: \"enterprise\" }, { name: \"Alice Smith\" })\n * ```\n */\nexport class Context {\n readonly type: string;\n readonly key: string;\n readonly name: string | null;\n readonly attributes: Record<string, unknown>;\n\n constructor(\n type: string,\n key: string,\n attributes?: Record<string, unknown>,\n options?: { name?: string },\n ) {\n this.type = type;\n this.key = key;\n this.name = options?.name ?? null;\n this.attributes = { ...(attributes ?? {}) };\n }\n\n toString(): string {\n return `Context(type=${this.type}, key=${this.key}, name=${this.name})`;\n }\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Fluent builder for JSON Logic rule dicts.\n *\n * @example\n * ```typescript\n * new Rule(\"Enable for enterprise users\")\n * .when(\"user.plan\", \"==\", \"enterprise\")\n * .when(\"account.region\", \"==\", \"us\")\n * .serve(true)\n * .build()\n * ```\n *\n * Multiple `.when()` calls are AND'd. `.environment()` tags the\n * built dict with an environment key for use with `Flag.addRule()`.\n */\nexport class Rule {\n private _description: string;\n private _conditions: Record<string, any>[] = [];\n private _value: any = null;\n private _environment: string | null = null;\n\n constructor(description: string) {\n this._description = description;\n }\n\n /** Tag this rule with an environment key (used by `addRule`). */\n environment(envKey: string): Rule {\n this._environment = envKey;\n return this;\n }\n\n /** Add a condition. Multiple calls are AND'd. */\n when(variable: string, op: string, value: any): Rule {\n if (op === \"contains\") {\n // JSON Logic \"in\" with reversed operands: value in var\n this._conditions.push({ in: [value, { var: variable }] });\n } else {\n this._conditions.push({ [op]: [{ var: variable }, value] });\n }\n return this;\n }\n\n /** Set the value returned when this rule matches. */\n serve(value: any): Rule {\n this._value = value;\n return this;\n }\n\n /** Finalize and return the rule as a plain object. */\n build(): Record<string, any> {\n let logic: Record<string, any>;\n if (this._conditions.length === 1) {\n logic = this._conditions[0];\n } else if (this._conditions.length > 1) {\n logic = { and: this._conditions };\n } else {\n logic = {};\n }\n\n const result: Record<string, any> = {\n description: this._description,\n logic,\n value: this._value,\n };\n\n if (this._environment !== null) {\n result.environment = this._environment;\n }\n\n return result;\n }\n}\n"],"mappings":"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","names":["createClient","import_openapi_fetch","checkError","wrapFetchError","jsonLogic","createClient","WebSocket","APP_BASE_URL"]}
|