@smplkit/sdk 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/config/client.ts","../src/auth.ts","../src/transport.ts","../src/client.ts"],"sourcesContent":["/**\n * smplkit — Official TypeScript SDK for the smplkit platform.\n *\n * @packageDocumentation\n */\n\n// Main client\nexport { SmplkitClient } from \"./client.js\";\nexport type { SmplkitClientOptions } from \"./client.js\";\n\n// Config types\nexport { ConfigClient } from \"./config/client.js\";\nexport type { Config, CreateConfigOptions, GetConfigOptions } from \"./config/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 * 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 * ConfigClient — management-plane operations for configs.\n *\n * Provides CRUD operations on config resources. Obtained via\n * `SmplkitClient.config`.\n */\n\nimport { SmplNotFoundError, SmplValidationError } from \"../errors.js\";\nimport type { Transport } from \"../transport.js\";\nimport type { Config, CreateConfigOptions, GetConfigOptions } from \"./types.js\";\n\nconst CONFIGS_PATH = \"/api/v1/configs\";\n\n/**\n * JSON:API resource shape as returned by the Config API.\n * @internal\n */\ninterface JsonApiResource {\n id: string;\n type: string;\n attributes: {\n name: string;\n key: string;\n description: string | null;\n parent: string | null;\n values: Record<string, unknown> | null;\n environments: Record<string, Record<string, unknown>> | null;\n created_at: string | null;\n updated_at: string | null;\n };\n}\n\n/**\n * Client for the smplkit Config API.\n *\n * All methods are async and return `Promise<T>`. Network and server\n * errors are mapped to typed SDK exceptions.\n */\nexport class ConfigClient {\n /** @internal */\n private readonly transport: Transport;\n\n /** @internal */\n constructor(transport: Transport) {\n this.transport = transport;\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 * @param options - Lookup options.\n * @returns The matching config.\n * @throws {SmplNotFoundError} If no matching config exists.\n * @throws {Error} If neither or both of `key` and `id` are provided.\n */\n async get(options: GetConfigOptions): Promise<Config> {\n const { key, id } = options;\n\n if ((key === undefined) === (id === undefined)) {\n throw new Error(\"Exactly one of 'key' or 'id' must be provided.\");\n }\n\n if (id !== undefined) {\n return this.getById(id);\n }\n\n return this.getByKey(key!);\n }\n\n /**\n * List all configs for the account.\n *\n * @returns An array of config objects.\n */\n async list(): Promise<Config[]> {\n const response = await this.transport.get(CONFIGS_PATH);\n const resources = response.data as JsonApiResource[];\n return resources.map((r) => this.resourceToModel(r));\n }\n\n /**\n * Create a new config.\n *\n * @param options - Config creation options.\n * @returns The created config.\n * @throws {SmplValidationError} If the server rejects the request.\n */\n async create(options: CreateConfigOptions): Promise<Config> {\n const body = this.buildRequestBody(options);\n const response = await this.transport.post(CONFIGS_PATH, body);\n\n if (!response.data) {\n throw new SmplValidationError(\"Failed to create config\");\n }\n\n return this.resourceToModel(response.data as JsonApiResource);\n }\n\n /**\n * Delete a config by UUID.\n *\n * @param configId - The UUID of the config to delete.\n * @throws {SmplNotFoundError} If the config does not exist.\n * @throws {SmplConflictError} If the config has children.\n */\n async delete(configId: string): Promise<void> {\n await this.transport.delete(`${CONFIGS_PATH}/${configId}`);\n }\n\n /** Fetch a config by UUID. */\n private async getById(configId: string): Promise<Config> {\n const response = await this.transport.get(`${CONFIGS_PATH}/${configId}`);\n\n if (!response.data) {\n throw new SmplNotFoundError(`Config ${configId} not found`);\n }\n\n return this.resourceToModel(response.data as JsonApiResource);\n }\n\n /** Fetch a config by key using the list endpoint with a filter. */\n private async getByKey(key: string): Promise<Config> {\n const response = await this.transport.get(CONFIGS_PATH, { \"filter[key]\": key });\n const resources = response.data as JsonApiResource[];\n\n if (!resources || resources.length === 0) {\n throw new SmplNotFoundError(`Config with key '${key}' not found`);\n }\n\n return this.resourceToModel(resources[0]);\n }\n\n /**\n * Convert a JSON:API resource to a Config domain model.\n * @internal\n */\n private resourceToModel(resource: JsonApiResource): Config {\n const attrs = resource.attributes;\n return {\n id: resource.id,\n key: attrs.key ?? \"\",\n name: attrs.name,\n description: attrs.description ?? null,\n parent: attrs.parent ?? null,\n values: attrs.values ?? {},\n environments: attrs.environments ?? {},\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 /** Build a JSON:API request body for create operations. */\n private buildRequestBody(options: CreateConfigOptions): Record<string, unknown> {\n const attributes: Record<string, unknown> = {\n name: options.name,\n };\n\n if (options.key !== undefined) attributes.key = options.key;\n if (options.description !== undefined) attributes.description = options.description;\n if (options.parent !== undefined) attributes.parent = options.parent;\n if (options.values !== undefined) attributes.values = options.values;\n\n return {\n data: {\n type: \"config\",\n attributes,\n },\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 /** Base URL for all API requests. Must not have a trailing slash. */\n baseUrl: 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 baseUrl: string;\n private readonly timeout: number;\n\n constructor(options: TransportOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Send a GET request.\n *\n * @param path - URL path relative to `baseUrl` (e.g. `/api/v1/configs`).\n * @param params - Optional query parameters.\n * @returns Parsed JSON response body.\n */\n async get(path: string, params?: Record<string, string>): Promise<JsonBody> {\n return this.request(\"GET\", path, undefined, params);\n }\n\n /**\n * Send a POST request with a JSON body.\n *\n * @param path - URL path relative to `baseUrl`.\n * @param body - JSON-serializable request body.\n * @returns Parsed JSON response body.\n */\n async post(path: string, body: JsonBody): Promise<JsonBody> {\n return this.request(\"POST\", path, body);\n }\n\n /**\n * Send a PUT request with a JSON body.\n *\n * @param path - URL path relative to `baseUrl`.\n * @param body - JSON-serializable request body.\n * @returns Parsed JSON response body.\n */\n async put(path: string, body: JsonBody): Promise<JsonBody> {\n return this.request(\"PUT\", path, body);\n }\n\n /**\n * Send a DELETE request.\n *\n * @param path - URL path relative to `baseUrl`.\n * @returns Parsed JSON response body (empty object for 204 responses).\n */\n async delete(path: string): Promise<JsonBody> {\n return this.request(\"DELETE\", path);\n }\n\n /**\n * Core request method. Handles headers, timeouts, and error mapping.\n */\n private async request(\n method: string,\n path: string,\n body?: JsonBody,\n params?: Record<string, string>,\n ): Promise<JsonBody> {\n let url = `${this.baseUrl}${path}`;\n\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 * Top-level SDK client — SmplkitClient.\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 { Transport } from \"./transport.js\";\n\nconst DEFAULT_BASE_URL = \"https://config.smplkit.com\";\n\n/** Configuration options for the {@link SmplkitClient}. */\nexport interface SmplkitClientOptions {\n /** API key for authenticating with the smplkit platform. */\n apiKey: string;\n\n /**\n * Base URL for all API requests.\n * @default \"https://config.smplkit.com\"\n */\n baseUrl?: 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 { SmplkitClient } from \"smplkit\";\n *\n * const client = new SmplkitClient({ apiKey: \"sk_api_...\" });\n * const cfg = await client.config.get({ key: \"common\" });\n * ```\n */\nexport class SmplkitClient {\n /** Client for config management-plane operations. */\n readonly config: ConfigClient;\n\n /** @internal */\n private readonly transport: Transport;\n\n constructor(options: SmplkitClientOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n\n this.transport = new Transport({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n timeout: options.timeout,\n });\n\n this.config = new ConfigClient(this.transport);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config/client.ts","../src/errors.ts","../src/config/types.ts","../src/client.ts"],"sourcesContent":["/**\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 ConfigResource = components[\"schemas\"][\"ConfigResource\"];\n\n/** @internal */\nfunction resourceToConfig(resource: ConfigResource, client: ConfigClient): Config {\n const attrs: ApiConfig = 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 values: (attrs.values ?? {}) as Record<string, unknown>,\n environments: (attrs.environments ?? {}) as Record<string, unknown>,\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 * 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 values?: 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.values !== undefined)\n attrs.values = options.values as { [key: string]: unknown } | null;\n if (options.environments !== undefined)\n attrs.environments = options.environments as { [key: string]: unknown } | null;\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 `SmplkitClient.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 values: options.values,\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 values: payload.values,\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 values: 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. */\n values: Record<string, unknown>;\n\n /**\n * Per-environment overrides.\n * Stored as `{ env_name: { values: { key: value } } }` to match the\n * server's format.\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 values: 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.values = fields.values;\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.values - 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 values?: 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 values: options.values ?? this.values,\n environments: options.environments ?? this.environments,\n });\n this.name = updated.name;\n this.description = updated.description;\n this.values = updated.values;\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 `values`.\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 newValues: Record<string, unknown>;\n let newEnvs: Record<string, unknown>;\n\n if (environment === undefined) {\n newValues = values;\n newEnvs = this.environments;\n } else {\n newValues = this.values;\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 values: newValues,\n environments: newEnvs,\n });\n this.values = updated.values;\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.values, [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; values: Record<string, unknown>; environments: Record<string, unknown> }>\n > {\n const chain: Array<{\n id: string;\n values: Record<string, unknown>;\n environments: Record<string, unknown>;\n }> = [{ id: this.id, values: this.values, 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 values: parentConfig.values,\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 values?: 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 * Top-level SDK client — SmplkitClient.\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\";\n\n/** Configuration options for the {@link SmplkitClient}. */\nexport interface SmplkitClientOptions {\n /** API key for authenticating with the smplkit platform. */\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 { SmplkitClient } from \"@smplkit/sdk\";\n *\n * const client = new SmplkitClient({ apiKey: \"sk_api_...\" });\n * const cfg = await client.config.get({ key: \"common\" });\n * ```\n */\nexport class SmplkitClient {\n /** Client for config management-plane operations. */\n readonly config: ConfigClient;\n\n constructor(options: SmplkitClientOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n\n this.config = new ConfigClient(options.apiKey, options.timeout);\n }\n}\n"],"mappings":"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","names":["ConfigRuntime"]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ ConfigRuntime
3
+ } from "./chunk-PZD5PSQY.js";
4
+ export {
5
+ ConfigRuntime
6
+ };
7
+ //# sourceMappingURL=runtime-CCRTBKED.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@smplkit/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
+ "type": "module",
4
5
  "description": "Official TypeScript SDK for the smplkit platform",
5
6
  "main": "./dist/index.cjs",
6
7
  "module": "./dist/index.js",
@@ -53,6 +54,7 @@
53
54
  "license": "MIT",
54
55
  "devDependencies": {
55
56
  "@types/node": "^18.19.130",
57
+ "@types/ws": "^8.18.1",
56
58
  "@typescript-eslint/eslint-plugin": "^7.0.0",
57
59
  "@typescript-eslint/parser": "^7.0.0",
58
60
  "@vitest/coverage-v8": "^1.0.0",
@@ -64,5 +66,9 @@
64
66
  "tsup": "^8.0.0",
65
67
  "typescript": "^5.4.0",
66
68
  "vitest": "^1.0.0"
69
+ },
70
+ "dependencies": {
71
+ "openapi-fetch": "^0.17.0",
72
+ "ws": "^8.20.0"
67
73
  }
68
74
  }
package/dist/index.d.mts DELETED
@@ -1,265 +0,0 @@
1
- /**
2
- * Internal HTTP client wrapper.
3
- *
4
- * Uses native `fetch` with `AbortController` for timeouts. Maps network
5
- * errors and HTTP status codes to typed SDK exceptions.
6
- *
7
- * @internal This module is not part of the public API.
8
- */
9
- /** Options for constructing a {@link Transport} instance. */
10
- interface TransportOptions {
11
- /** The API key used for Bearer token authentication. */
12
- apiKey: string;
13
- /** Base URL for all API requests. Must not have a trailing slash. */
14
- baseUrl: string;
15
- /** Request timeout in milliseconds. Defaults to 30 000. */
16
- timeout?: number;
17
- }
18
- /** Parsed JSON response from the API. */
19
- type JsonBody = Record<string, any>;
20
- /**
21
- * Low-level HTTP transport that handles auth, timeouts, and error mapping.
22
- *
23
- * @internal
24
- */
25
- declare class Transport {
26
- private readonly apiKey;
27
- private readonly baseUrl;
28
- private readonly timeout;
29
- constructor(options: TransportOptions);
30
- /**
31
- * Send a GET request.
32
- *
33
- * @param path - URL path relative to `baseUrl` (e.g. `/api/v1/configs`).
34
- * @param params - Optional query parameters.
35
- * @returns Parsed JSON response body.
36
- */
37
- get(path: string, params?: Record<string, string>): Promise<JsonBody>;
38
- /**
39
- * Send a POST request with a JSON body.
40
- *
41
- * @param path - URL path relative to `baseUrl`.
42
- * @param body - JSON-serializable request body.
43
- * @returns Parsed JSON response body.
44
- */
45
- post(path: string, body: JsonBody): Promise<JsonBody>;
46
- /**
47
- * Send a PUT request with a JSON body.
48
- *
49
- * @param path - URL path relative to `baseUrl`.
50
- * @param body - JSON-serializable request body.
51
- * @returns Parsed JSON response body.
52
- */
53
- put(path: string, body: JsonBody): Promise<JsonBody>;
54
- /**
55
- * Send a DELETE request.
56
- *
57
- * @param path - URL path relative to `baseUrl`.
58
- * @returns Parsed JSON response body (empty object for 204 responses).
59
- */
60
- delete(path: string): Promise<JsonBody>;
61
- /**
62
- * Core request method. Handles headers, timeouts, and error mapping.
63
- */
64
- private request;
65
- /**
66
- * Map HTTP error status codes to typed SDK exceptions.
67
- *
68
- * @throws {SmplNotFoundError} On 404.
69
- * @throws {SmplConflictError} On 409.
70
- * @throws {SmplValidationError} On 422.
71
- * @throws {SmplError} On any other non-2xx status.
72
- */
73
- private throwForStatus;
74
- }
75
-
76
- /**
77
- * Config resource types.
78
- *
79
- * These types represent the domain model for config resources after
80
- * unwrapping the JSON:API envelope.
81
- */
82
- /** A config resource as returned by the smplkit Config API. */
83
- interface Config {
84
- /** UUID of the config. */
85
- id: string;
86
- /** Human-readable key (e.g. `"user_service"`). */
87
- key: string;
88
- /** Display name for the config. */
89
- name: string;
90
- /** Optional description. */
91
- description: string | null;
92
- /** Parent config UUID, or null if this is a root config. */
93
- parent: string | null;
94
- /** Base key-value pairs. */
95
- values: Record<string, unknown>;
96
- /** Per-environment overrides, keyed by environment name. */
97
- environments: Record<string, Record<string, unknown>>;
98
- /** When the config was created, or null if unavailable. */
99
- createdAt: Date | null;
100
- /** When the config was last updated, or null if unavailable. */
101
- updatedAt: Date | null;
102
- }
103
- /** Options for creating a new config. */
104
- interface CreateConfigOptions {
105
- /** Display name for the config. */
106
- name: string;
107
- /** Human-readable key. Auto-generated by the server if omitted. */
108
- key?: string;
109
- /** Optional description. */
110
- description?: string;
111
- /** Parent config UUID. */
112
- parent?: string;
113
- /** Initial base values. */
114
- values?: Record<string, unknown>;
115
- }
116
- /** Options for fetching a single config. Exactly one of `key` or `id` must be provided. */
117
- interface GetConfigOptions {
118
- /** Fetch by human-readable key. */
119
- key?: string;
120
- /** Fetch by UUID. */
121
- id?: string;
122
- }
123
-
124
- /**
125
- * ConfigClient — management-plane operations for configs.
126
- *
127
- * Provides CRUD operations on config resources. Obtained via
128
- * `SmplkitClient.config`.
129
- */
130
-
131
- /**
132
- * Client for the smplkit Config API.
133
- *
134
- * All methods are async and return `Promise<T>`. Network and server
135
- * errors are mapped to typed SDK exceptions.
136
- */
137
- declare class ConfigClient {
138
- /** @internal */
139
- private readonly transport;
140
- /** @internal */
141
- constructor(transport: Transport);
142
- /**
143
- * Fetch a single config by key or UUID.
144
- *
145
- * Exactly one of `key` or `id` must be provided.
146
- *
147
- * @param options - Lookup options.
148
- * @returns The matching config.
149
- * @throws {SmplNotFoundError} If no matching config exists.
150
- * @throws {Error} If neither or both of `key` and `id` are provided.
151
- */
152
- get(options: GetConfigOptions): Promise<Config>;
153
- /**
154
- * List all configs for the account.
155
- *
156
- * @returns An array of config objects.
157
- */
158
- list(): Promise<Config[]>;
159
- /**
160
- * Create a new config.
161
- *
162
- * @param options - Config creation options.
163
- * @returns The created config.
164
- * @throws {SmplValidationError} If the server rejects the request.
165
- */
166
- create(options: CreateConfigOptions): Promise<Config>;
167
- /**
168
- * Delete a config by UUID.
169
- *
170
- * @param configId - The UUID of the config to delete.
171
- * @throws {SmplNotFoundError} If the config does not exist.
172
- * @throws {SmplConflictError} If the config has children.
173
- */
174
- delete(configId: string): Promise<void>;
175
- /** Fetch a config by UUID. */
176
- private getById;
177
- /** Fetch a config by key using the list endpoint with a filter. */
178
- private getByKey;
179
- /**
180
- * Convert a JSON:API resource to a Config domain model.
181
- * @internal
182
- */
183
- private resourceToModel;
184
- /** Build a JSON:API request body for create operations. */
185
- private buildRequestBody;
186
- }
187
-
188
- /**
189
- * Top-level SDK client — SmplkitClient.
190
- *
191
- * The main entry point for the smplkit TypeScript SDK. Provides access
192
- * to sub-clients for each API domain (config, flags, logging, etc.).
193
- */
194
-
195
- /** Configuration options for the {@link SmplkitClient}. */
196
- interface SmplkitClientOptions {
197
- /** API key for authenticating with the smplkit platform. */
198
- apiKey: string;
199
- /**
200
- * Base URL for all API requests.
201
- * @default "https://config.smplkit.com"
202
- */
203
- baseUrl?: string;
204
- /**
205
- * Request timeout in milliseconds.
206
- * @default 30000
207
- */
208
- timeout?: number;
209
- }
210
- /**
211
- * Entry point for the smplkit TypeScript SDK.
212
- *
213
- * @example
214
- * ```typescript
215
- * import { SmplkitClient } from "smplkit";
216
- *
217
- * const client = new SmplkitClient({ apiKey: "sk_api_..." });
218
- * const cfg = await client.config.get({ key: "common" });
219
- * ```
220
- */
221
- declare class SmplkitClient {
222
- /** Client for config management-plane operations. */
223
- readonly config: ConfigClient;
224
- /** @internal */
225
- private readonly transport;
226
- constructor(options: SmplkitClientOptions);
227
- }
228
-
229
- /**
230
- * Structured SDK error types.
231
- *
232
- * All smplkit errors extend {@link SmplError}, allowing callers to catch
233
- * the base class for generic handling or specific subclasses for
234
- * fine-grained control.
235
- */
236
- /** Base exception for all smplkit SDK errors. */
237
- declare class SmplError extends Error {
238
- /** The HTTP status code, if the error originated from an HTTP response. */
239
- readonly statusCode?: number;
240
- /** The raw response body, if available. */
241
- readonly responseBody?: string;
242
- constructor(message: string, statusCode?: number, responseBody?: string);
243
- }
244
- /** Raised when a network request fails (e.g., DNS resolution, connection refused). */
245
- declare class SmplConnectionError extends SmplError {
246
- constructor(message: string, statusCode?: number, responseBody?: string);
247
- }
248
- /** Raised when an operation exceeds its timeout. */
249
- declare class SmplTimeoutError extends SmplError {
250
- constructor(message: string, statusCode?: number, responseBody?: string);
251
- }
252
- /** Raised when a requested resource does not exist (HTTP 404). */
253
- declare class SmplNotFoundError extends SmplError {
254
- constructor(message: string, statusCode?: number, responseBody?: string);
255
- }
256
- /** Raised when an operation conflicts with current state (HTTP 409). */
257
- declare class SmplConflictError extends SmplError {
258
- constructor(message: string, statusCode?: number, responseBody?: string);
259
- }
260
- /** Raised when the server rejects a request due to validation errors (HTTP 422). */
261
- declare class SmplValidationError extends SmplError {
262
- constructor(message: string, statusCode?: number, responseBody?: string);
263
- }
264
-
265
- export { type Config, ConfigClient, type CreateConfigOptions, type GetConfigOptions, SmplConflictError, SmplConnectionError, SmplError, SmplNotFoundError, SmplTimeoutError, SmplValidationError, SmplkitClient, type SmplkitClientOptions };