@simplr-ai/node 1.2.0 → 1.2.2
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 +20 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -358,6 +358,7 @@ var SimplrFlags = class {
|
|
|
358
358
|
defaultUserId;
|
|
359
359
|
timer = null;
|
|
360
360
|
ready = false;
|
|
361
|
+
etag = null;
|
|
361
362
|
constructor(options) {
|
|
362
363
|
if (!options?.publicKey) throw new Error("SimplrFlags: `publicKey` is required");
|
|
363
364
|
this.cfg = {
|
|
@@ -370,7 +371,8 @@ var SimplrFlags = class {
|
|
|
370
371
|
redactFields: options.redactFields
|
|
371
372
|
};
|
|
372
373
|
this.environment = options.environment;
|
|
373
|
-
|
|
374
|
+
const requested = options.refreshIntervalMs ?? 6e4;
|
|
375
|
+
this.refreshIntervalMs = requested > 0 ? Math.max(requested, 3e4) : 0;
|
|
374
376
|
}
|
|
375
377
|
/** Fetch the flag config once and start the background refresh. */
|
|
376
378
|
async initialize() {
|
|
@@ -387,16 +389,27 @@ var SimplrFlags = class {
|
|
|
387
389
|
setUser(userId) {
|
|
388
390
|
this.defaultUserId = userId;
|
|
389
391
|
}
|
|
390
|
-
/** Re-fetch the flag config (counts as one billable request). */
|
|
391
392
|
async refresh() {
|
|
392
393
|
const path = this.environment ? `/v1/flags?environment=${encodeURIComponent(this.environment)}` : "/v1/flags";
|
|
394
|
+
const controller = new AbortController();
|
|
395
|
+
const timer = setTimeout(() => controller.abort(), this.cfg.timeoutMs);
|
|
393
396
|
try {
|
|
394
|
-
const
|
|
395
|
-
|
|
397
|
+
const headers = { ...this.cfg.authHeaders };
|
|
398
|
+
if (this.etag) headers["If-None-Match"] = this.etag;
|
|
399
|
+
const res = await this.cfg.fetchImpl(`${this.cfg.baseUrl}${path}`, { headers, signal: controller.signal });
|
|
400
|
+
if (res.status === 304) return;
|
|
401
|
+
if (!res.ok) return;
|
|
402
|
+
const responseEtag = res.headers?.get?.("etag");
|
|
403
|
+
if (responseEtag) this.etag = responseEtag;
|
|
404
|
+
const text = await res.text();
|
|
405
|
+
const json = text ? JSON.parse(text) : {};
|
|
406
|
+
const list = json?.content?.flags || [];
|
|
396
407
|
const map = {};
|
|
397
408
|
for (const f of list) map[f.key] = f;
|
|
398
409
|
this.flags = map;
|
|
399
410
|
} catch {
|
|
411
|
+
} finally {
|
|
412
|
+
clearTimeout(timer);
|
|
400
413
|
}
|
|
401
414
|
}
|
|
402
415
|
/** Evaluate a flag locally. Deterministic per user; no network call. */
|
|
@@ -874,7 +887,8 @@ var Simplr = class {
|
|
|
874
887
|
if (!options?.apiKey) throw new Error("Simplr: `apiKey` is required");
|
|
875
888
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
876
889
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
877
|
-
|
|
890
|
+
const logSelf = !!options.logSelfCalls;
|
|
891
|
+
if (options.shipNetworkLogs && logSelf) {
|
|
878
892
|
this.shipper = new NetworkLogShipper({
|
|
879
893
|
baseUrl,
|
|
880
894
|
apiKey: options.apiKey,
|
|
@@ -895,7 +909,7 @@ var Simplr = class {
|
|
|
895
909
|
timeoutMs: options.timeoutMs ?? 15e3,
|
|
896
910
|
fetchImpl,
|
|
897
911
|
onNetworkLog,
|
|
898
|
-
logBodies: options.logBodies ?? options.shipNetworkLogs,
|
|
912
|
+
logBodies: options.logBodies ?? (options.shipNetworkLogs && logSelf),
|
|
899
913
|
redactFields: options.redactFields
|
|
900
914
|
};
|
|
901
915
|
if (typeof this.cfg.fetchImpl !== "function") {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/network-log.ts","../src/http.ts","../src/network-shipper.ts","../src/resources.ts","../src/flags.ts","../src/profiles.ts","../src/rum.ts","../src/ai.ts","../src/webhooks.ts","../src/admin.ts"],"sourcesContent":["import { apiRequest, type HttpConfig } from \"./http.js\";\nimport { NetworkLogShipper } from \"./network-shipper.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\nimport { EdgeResource, OrdersResource, PhoneResource } from \"./resources.js\";\nimport { SimplrFlags } from \"./flags.js\";\nimport { SimplrProfiles } from \"./profiles.js\";\nimport { SimplrRUM } from \"./rum.js\";\nimport { SimplrAI } from \"./ai.js\";\nimport * as webhooks from \"./webhooks.js\";\nimport type { BulkResult, CheckInput, CheckResult, SimplrOptions } from \"./types.js\";\n\nexport { SimplrError, WebhookVerificationError } from \"./errors.js\";\nexport * from \"./types.js\";\nexport type {\n NetworkLogEntry,\n NetworkLogger,\n NetworkSource,\n} from \"./network-log.js\";\nexport { NetworkLogShipper } from \"./network-shipper.js\";\nexport type { ShipperConfig } from \"./network-shipper.js\";\nexport { verify as verifyWebhook, constructEvent as constructWebhookEvent } from \"./webhooks.js\";\nexport { SimplrFlags } from \"./flags.js\";\nexport type { FlagDefinition, FlagRule, FlagsOptions, EvalContext } from \"./flags.js\";\nexport { SimplrAdmin } from \"./admin.js\";\nexport type { SimplrAdminOptions } from \"./admin.js\";\nexport { SimplrProfiles } from \"./profiles.js\";\nexport { SimplrRUM } from \"./rum.js\";\nexport type { SimplrRUMConfig } from \"./rum.js\";\nexport { SimplrAI } from \"./ai.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.simplr.sh\";\n\n/**\n * Simplr server-side client.\n *\n * ```ts\n * import { Simplr } from \"@simplr-ai/node\";\n * const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! });\n * const result = await simplr.check({ email: \"user@example.com\", event_type: \"signup\" });\n * ```\n */\nexport class Simplr {\n private readonly cfg: HttpConfig;\n\n readonly orders: OrdersResource;\n readonly phone: PhoneResource;\n readonly edge: EdgeResource;\n /** Anonymous user profiles + order fraud monitoring. */\n readonly profiles: SimplrProfiles;\n /** Real User Monitoring — batched events to /v1/rum/events. */\n readonly rum: SimplrRUM;\n /** AI delegation — OAuth-like AI authentication. */\n readonly ai: SimplrAI;\n /** Webhook signature helpers (no network). */\n readonly webhooks = webhooks;\n\n private readonly _flags?: SimplrFlags;\n private readonly shipper?: NetworkLogShipper;\n\n constructor(options: SimplrOptions) {\n if (!options?.apiKey) throw new Error(\"Simplr: `apiKey` is required\");\n const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (options.shipNetworkLogs) {\n this.shipper = new NetworkLogShipper({\n baseUrl,\n apiKey: options.apiKey,\n fetchImpl,\n sdk: \"node\",\n applicationId: options.applicationId,\n environment: options.environment,\n });\n this.shipper.start();\n }\n\n const onNetworkLog: NetworkLogger | undefined =\n this.shipper || options.onNetworkLog\n ? (entry) => {\n this.shipper?.add(entry);\n options.onNetworkLog?.(entry);\n }\n : undefined;\n\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.apiKey },\n baseUrl,\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl,\n onNetworkLog,\n logBodies: options.logBodies ?? options.shipNetworkLogs,\n redactFields: options.redactFields,\n };\n if (typeof this.cfg.fetchImpl !== \"function\") {\n throw new Error(\"Simplr: no global fetch available — use Node 18+ or pass `fetch` in options\");\n }\n this.orders = new OrdersResource(this.cfg);\n this.phone = new PhoneResource(this.cfg);\n this.edge = new EdgeResource(this.cfg);\n this.profiles = new SimplrProfiles(this.cfg);\n this.rum = new SimplrRUM(this.cfg);\n this.ai = new SimplrAI(this.cfg);\n if (options.publicKey) {\n this._flags = new SimplrFlags({\n publicKey: options.publicKey,\n environment: options.environment,\n baseUrl: this.cfg.baseUrl,\n timeoutMs: this.cfg.timeoutMs,\n fetch: this.cfg.fetchImpl,\n onNetworkLog: this.cfg.onNetworkLog,\n logBodies: this.cfg.logBodies,\n redactFields: options.redactFields,\n });\n }\n }\n\n /**\n * Server-side feature flags. Requires a `publicKey` in the constructor options\n * (flag config is read with the public key). Call `simplr.flags.initialize()` once.\n */\n get flags(): SimplrFlags {\n if (!this._flags) {\n throw new Error(\n \"Simplr.flags requires a `publicKey` — pass it to `new Simplr({ apiKey, publicKey })`.\",\n );\n }\n return this._flags;\n }\n\n /** Run an identity/fraud check. Provide any of email, phone, device, behavior. */\n check(input: CheckInput): Promise<CheckResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check\", input);\n }\n\n /** Run up to 100 checks at once. */\n checkBulk(items: CheckInput[]): Promise<BulkResult<CheckResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/bulk\", { items });\n }\n\n flushNetworkLogs(): Promise<void> {\n return this.shipper?.flush() ?? Promise.resolve();\n }\n\n close(): void {\n this.shipper?.stop();\n this._flags?.dispose();\n }\n}\n\nexport default Simplr;\n","/** Thrown when the Simplr API returns a non-2xx response. */\nexport class SimplrError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"SimplrError\";\n this.status = status;\n this.body = body;\n }\n}\n\n/** Thrown when a webhook signature fails verification. */\nexport class WebhookVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WebhookVerificationError\";\n }\n}\n","export type NetworkSource = \"frontend\" | \"backend\";\n\nexport interface NetworkLogEntry {\n id: string;\n source: NetworkSource;\n timestamp: string;\n sdk?: string;\n applicationId?: string;\n environment?: string;\n method: string;\n url: string;\n requestHeaders?: Record<string, string>;\n requestBody?: unknown;\n status?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: unknown;\n durationMs?: number;\n ok?: boolean;\n error?: string;\n}\n\nexport type NetworkLogger = (entry: NetworkLogEntry) => void;\n\nconst SENSITIVE_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n \"x-auth-token\",\n \"x-csrf-token\",\n \"x-xsrf-token\",\n]);\n\nconst SENSITIVE_KEY_PARTS = [\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n \"api_key\",\n \"apikey\",\n \"authorization\",\n \"auth\",\n \"credential\",\n \"private_key\",\n \"card\",\n \"cardnumber\",\n \"pan\",\n \"cvv\",\n \"cvc\",\n \"ssn\",\n \"pin\",\n \"otp\",\n];\n\nconst MAX_REDACT_DEPTH = 8;\n\nexport const MAX_BODY_CHARS = 10_000;\n\nfunction isSensitiveKey(key: string, extraKeys: string[]): boolean {\n const lower = key.toLowerCase();\n if (extraKeys.some((k) => lower === k.toLowerCase())) return true;\n return SENSITIVE_KEY_PARTS.some((part) => lower.includes(part));\n}\n\nfunction redactDeep(value: unknown, extraKeys: string[], depth = 0): unknown {\n if (depth >= MAX_REDACT_DEPTH) return \"[truncated]\";\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, extraKeys, depth + 1));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSensitiveKey(key, extraKeys)\n ? \"[REDACTED]\"\n : redactDeep(val, extraKeys, depth + 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactHeaders(\n headers: Record<string, string> | Headers | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n const out: Record<string, string> = {};\n const set = (key: string, value: string) => {\n out[key] = SENSITIVE_HEADERS.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n };\n if (typeof (headers as Headers).forEach === \"function\" && !Array.isArray(headers)) {\n (headers as Headers).forEach((value, key) => set(key, value));\n } else {\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n set(key, String(value));\n }\n }\n return out;\n}\n\nexport function previewBody(raw: unknown, redactFields: string[] = []): unknown {\n if (raw === undefined || raw === null) return undefined;\n let value: unknown = raw;\n if (typeof raw === \"string\") {\n try {\n value = JSON.parse(raw);\n } catch {\n return raw.length > MAX_BODY_CHARS ? raw.slice(0, MAX_BODY_CHARS) + \"…[truncated]\" : raw;\n }\n }\n const redacted = redactDeep(value, redactFields);\n let text: string;\n try {\n text = JSON.stringify(redacted);\n } catch {\n return \"[unserializable]\";\n }\n if (text.length > MAX_BODY_CHARS) {\n return text.slice(0, MAX_BODY_CHARS) + \"…[truncated]\";\n }\n return redacted;\n}\n\nexport function newLogId(): string {\n const uuid = (globalThis as any)?.crypto?.randomUUID;\n if (typeof uuid === \"function\") return uuid.call((globalThis as any).crypto);\n return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n","import { SimplrError } from \"./errors.js\";\nimport {\n newLogId,\n previewBody,\n redactHeaders,\n type NetworkLogger,\n} from \"./network-log.js\";\n\nexport interface HttpConfig {\n authHeaders: Record<string, string>;\n baseUrl: string;\n timeoutMs: number;\n fetchImpl: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport async function apiRequest<T>(\n cfg: HttpConfig,\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);\n\n const url = `${cfg.baseUrl}${path}`;\n const requestHeaders = {\n \"Content-Type\": \"application/json\",\n ...cfg.authHeaders,\n };\n const startedAt = Date.now();\n const log = cfg.onNetworkLog\n ? {\n id: newLogId(),\n source: \"backend\" as const,\n timestamp: new Date(startedAt).toISOString(),\n method,\n url,\n requestHeaders: redactHeaders(requestHeaders),\n requestBody: cfg.logBodies ? previewBody(body, cfg.redactFields) : undefined,\n }\n : null;\n\n const emit = (extra: Record<string, unknown>) => {\n if (!log || !cfg.onNetworkLog) return;\n try {\n cfg.onNetworkLog({ ...log, durationMs: Date.now() - startedAt, ...extra });\n } catch {\n /* empty */\n }\n };\n\n try {\n const res = await cfg.fetchImpl(url, {\n method,\n headers: requestHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const text = await res.text();\n let parsed: any;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n emit({\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n responseHeaders: redactHeaders(res.headers),\n responseBody: cfg.logBodies ? previewBody(parsed ?? text, cfg.redactFields) : undefined,\n });\n\n if (!res.ok) {\n const message =\n (parsed && (parsed.message || parsed.error)) || `Simplr API error ${res.status}`;\n throw new SimplrError(message, res.status, parsed);\n }\n\n return (parsed && typeof parsed === \"object\" && \"content\" in parsed\n ? parsed.content\n : parsed) as T;\n } catch (err) {\n if (err instanceof SimplrError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n emit({ ok: false, error: `timed out after ${cfg.timeoutMs}ms` });\n throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);\n }\n emit({ ok: false, error: err instanceof Error ? err.message : \"Network error\" });\n throw new SimplrError(err instanceof Error ? err.message : \"Network error\", 0, null);\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { NetworkLogEntry } from \"./network-log.js\";\n\nexport interface ShipperConfig {\n baseUrl: string;\n apiKey: string;\n fetchImpl: typeof fetch;\n sdk: string;\n applicationId?: string;\n environment?: string;\n batchSize?: number;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_BATCH = 25;\nconst DEFAULT_FLUSH_MS = 5000;\n\nexport class NetworkLogShipper {\n private readonly cfg: ShipperConfig;\n private queue: NetworkLogEntry[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cfg: ShipperConfig) {\n this.cfg = cfg;\n }\n\n start(): void {\n if (this.timer) return;\n const interval = this.cfg.flushIntervalMs ?? DEFAULT_FLUSH_MS;\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n\n add(entry: NetworkLogEntry): void {\n this.queue.push({\n ...entry,\n sdk: this.cfg.sdk,\n applicationId: entry.applicationId ?? this.cfg.applicationId,\n environment: entry.environment ?? this.cfg.environment,\n });\n if (this.queue.length >= (this.cfg.batchSize ?? DEFAULT_BATCH)) {\n void this.flush();\n }\n }\n\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n const logs = this.queue;\n this.queue = [];\n try {\n await this.cfg.fetchImpl(`${this.cfg.baseUrl}/v1/network-logs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.cfg.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n } catch {\n /* empty */\n }\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n void this.flush();\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n BulkResult,\n EdgeLogEntry,\n OrderInput,\n OrderResult,\n PhoneReportInput,\n} from \"./types.js\";\n\n/** Order fraud scoring. */\nexport class OrdersResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Submit a single order for fraud scoring. */\n submit(order: OrderInput): Promise<OrderResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Submit up to 100 orders at once. */\n submitBulk(orders: OrderInput[]): Promise<BulkResult<OrderResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders/bulk\", { orders });\n }\n}\n\n/** Phone intelligence + outcome reporting. */\nexport class PhoneResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Report the real-world outcome for a phone number to improve scoring. */\n report(input: PhoneReportInput): Promise<{ success: boolean }> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/phone/report\", input);\n }\n\n /** Fetch stored risk intelligence for a phone number. */\n intelligence(phone: string): Promise<Record<string, unknown>> {\n return apiRequest(this.cfg, \"GET\", `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`);\n }\n}\n\n/** Edge device registration + log ingestion. */\nexport class EdgeResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Register an edge device. */\n registerDevice(input: { device_id: string; name?: string; firmware?: string; [k: string]: unknown }) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/devices/register\", input);\n }\n\n /** Report a device heartbeat with health metrics. */\n heartbeat(deviceId: string, metrics: Record<string, unknown>) {\n return apiRequest(\n this.cfg,\n \"POST\",\n `/v1/edge/devices/${encodeURIComponent(deviceId)}/heartbeat`,\n metrics,\n );\n }\n\n /** Batch-ingest structured logs for a device. */\n ingestLogs(deviceId: string, logs: EdgeLogEntry[]) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/logs\", { device_id: deviceId, logs });\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\n\n/**\n * MurmurHash3 (x86, 32-bit) — identical to the browser SDK so a given user\n * buckets the same way on the client and the server.\n */\nfunction murmurHash3(input: string, seed = 0): number {\n let h1 = seed;\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n for (let i = 0; i < input.length; i++) {\n let k1 = input.charCodeAt(i);\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n h1 ^= input.length;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n return h1 >>> 0;\n}\n\nexport interface FlagRule {\n attribute: string;\n op: \"eq\" | \"neq\" | \"contains\";\n value: string;\n}\n\nexport interface FlagDefinition {\n key: string;\n enabled: boolean;\n rollout_percentage: number;\n target_user_ids: string[];\n rules: FlagRule[];\n}\n\nexport interface FlagsOptions {\n /** Public API key (pk_live_… / pk_test_…). Required — flags read uses the public key. */\n publicKey: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n /**\n * Which environment's flags to load. Defaults to the key's own environment\n * (the API falls back to the key's live/test mode when unset). Accepts a\n * named environment slug (e.g. \"dev\", \"uat\", \"prod\") as well as the legacy\n * \"live\"/\"test\" key modes. Sent to the API as `?environment=<value>`.\n */\n environment?: string;\n /** Auto-refresh interval in ms (default 60000; 0 disables). */\n refreshIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport interface EvalContext {\n userId?: string;\n attributes?: Record<string, unknown>;\n}\n\nfunction matchRule(rule: FlagRule, attributes: Record<string, unknown>): boolean {\n const actual = attributes[rule.attribute];\n switch (rule.op) {\n case \"eq\":\n return String(actual) === rule.value;\n case \"neq\":\n return String(actual) !== rule.value;\n case \"contains\":\n return String(actual ?? \"\").includes(rule.value);\n default:\n return false;\n }\n}\n\n/**\n * Server-side feature flags with local, deterministic evaluation.\n *\n * ```ts\n * const flags = new SimplrFlags({ publicKey: process.env.SIMPLR_PUBLIC_KEY! });\n * await flags.initialize();\n * if (flags.isEnabled(\"new-checkout\", { userId: \"user_123\" })) { ... }\n * ```\n */\nexport class SimplrFlags {\n private readonly cfg: HttpConfig;\n private readonly environment?: string;\n private readonly refreshIntervalMs: number;\n private flags: Record<string, FlagDefinition> = {};\n private defaultUserId?: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private ready = false;\n\n constructor(options: FlagsOptions) {\n if (!options?.publicKey) throw new Error(\"SimplrFlags: `publicKey` is required\");\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.publicKey },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n onNetworkLog: options.onNetworkLog,\n logBodies: options.logBodies,\n redactFields: options.redactFields,\n };\n this.environment = options.environment;\n this.refreshIntervalMs = options.refreshIntervalMs ?? 60000;\n }\n\n /** Fetch the flag config once and start the background refresh. */\n async initialize(): Promise<void> {\n await this.refresh();\n this.ready = true;\n if (this.refreshIntervalMs > 0) {\n this.timer = setInterval(() => {\n void this.refresh();\n }, this.refreshIntervalMs);\n // Don't keep the process alive just for flag refreshes.\n (this.timer as any)?.unref?.();\n }\n }\n\n /** Set the default identifier used for bucketing when none is passed to isEnabled. */\n setUser(userId: string): void {\n this.defaultUserId = userId;\n }\n\n /** Re-fetch the flag config (counts as one billable request). */\n async refresh(): Promise<void> {\n const path = this.environment\n ? `/v1/flags?environment=${encodeURIComponent(this.environment)}`\n : \"/v1/flags\";\n try {\n const content = await apiRequest<{ flags: FlagDefinition[] }>(this.cfg, \"GET\", path);\n const list = content?.flags || [];\n const map: Record<string, FlagDefinition> = {};\n for (const f of list) map[f.key] = f;\n this.flags = map;\n } catch {\n // keep last-known flags on error\n }\n }\n\n /** Evaluate a flag locally. Deterministic per user; no network call. */\n isEnabled(key: string, ctx: EvalContext = {}): boolean {\n const f = this.flags[key];\n if (!f || !f.enabled) return false;\n\n const uid = ctx.userId || this.defaultUserId || \"anonymous\";\n if (f.target_user_ids?.includes(uid)) return true;\n if (ctx.attributes && f.rules?.length && f.rules.some((r) => matchRule(r, ctx.attributes!))) {\n return true;\n }\n if (f.rollout_percentage >= 100) return true;\n if (f.rollout_percentage <= 0) return false;\n return murmurHash3(`${key}:${uid}`) % 100 < f.rollout_percentage;\n }\n\n getAll(): Record<string, FlagDefinition> {\n return { ...this.flags };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n /** Stop the background refresh timer. */\n dispose(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n IdentifyOptions,\n OrderInput,\n OrderResult,\n ProfileResult,\n ProfileRiskResult,\n} from \"./types.js\";\n\n/**\n * Anonymous user profile management and order fraud monitoring.\n *\n * Works with the configured key (secret for server-side use). Mirrors the\n * browser SimplrProfiles surface but reuses the Node http helper (which unwraps\n * the `{ success, message, content }` envelope).\n */\nexport class SimplrProfiles {\n constructor(private readonly cfg: HttpConfig) {}\n\n /**\n * Identify a user — creates or updates an anonymous profile and (optionally)\n * links a device fingerprint. POST /v1/profiles.\n */\n identify(externalId: string, options?: IdentifyOptions): Promise<ProfileResult> {\n const { profileType, fingerprintHash, ...rest } = options ?? {};\n const body: Record<string, unknown> = {\n external_id: externalId,\n profile_type: profileType || \"customer\",\n ...rest,\n };\n if (fingerprintHash) body.fingerprint_hash = fingerprintHash;\n return apiRequest<ProfileResult>(this.cfg, \"POST\", \"/v1/profiles\", body);\n }\n\n /** Submit an order for real-time fraud scoring. POST /v1/orders. */\n submitOrder(order: OrderInput): Promise<OrderResult> {\n return apiRequest<OrderResult>(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Get the risk profile for a user. GET /v1/profiles/{externalId}. */\n getProfileRisk(externalId: string): Promise<ProfileRiskResult> {\n return apiRequest<ProfileRiskResult>(\n this.cfg,\n \"GET\",\n `/v1/profiles/${encodeURIComponent(externalId)}`,\n );\n }\n\n /** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */\n async reportOutcome(externalId: string, outcome: \"fraud\" | \"legitimate\"): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/profiles/${encodeURIComponent(externalId)}/outcome`,\n { outcome },\n );\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { RUMEvent, RUMEventType, RUMLogLevel } from \"./types.js\";\n\nexport interface SimplrRUMConfig {\n /** Application identifier (required). */\n applicationId: string;\n /** Optional version/environment tags applied to every event. */\n applicationVersion?: string;\n environment?: string;\n /** Flush when this many events are queued (default 30). */\n batchSize?: number;\n /** Background flush interval in ms (default 10000; 0 disables the timer). */\n flushInterval?: number;\n /** Override the events endpoint path (default /v1/rum/events). */\n endpoint?: string;\n}\n\nconst DEFAULT_BATCH_SIZE = 30;\nconst DEFAULT_FLUSH_INTERVAL = 10000;\nconst DEFAULT_ENDPOINT = \"/v1/rum/events\";\n\nfunction genId(): string {\n return (\n Date.now().toString(36) + Math.random().toString(36).slice(2, 10)\n );\n}\n\n/**\n * Server-side Real User Monitoring. Batches events and flushes them to\n * POST /v1/rum/events using the configured key. Unlike the browser SDK there is\n * no DOM auto-capture — views/actions/errors/logs are reported via the public\n * API. A timer-based flush is installed with `unref()` so it never keeps the\n * Node process alive.\n */\nexport class SimplrRUM {\n private config: SimplrRUMConfig | null = null;\n private initialized = false;\n private queue: RUMEvent[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n\n private sessionId: string | null = null;\n private currentViewId: string | null = null;\n private userId?: string;\n private userAttributes?: Record<string, unknown>;\n private globalAttributes: Record<string, unknown> = {};\n private batchSize = DEFAULT_BATCH_SIZE;\n private endpoint = DEFAULT_ENDPOINT;\n\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Initialize the SDK, start a session, and begin the flush timer. */\n initialize(config: SimplrRUMConfig): void {\n if (this.initialized) return;\n this.config = config;\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n this.sessionId = genId();\n this.initialized = true;\n\n this.trackEvent(\"session_start\");\n\n const interval = config.flushInterval ?? DEFAULT_FLUSH_INTERVAL;\n if (interval > 0) {\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /** Associate subsequent events with a user. */\n setUser(userId: string, attributes?: Record<string, unknown>): void {\n this.userId = userId;\n this.userAttributes = attributes;\n }\n\n clearUser(): void {\n this.userId = undefined;\n this.userAttributes = undefined;\n }\n\n addAttribute(key: string, value: unknown): void {\n this.globalAttributes[key] = value;\n }\n\n removeAttribute(key: string): void {\n delete this.globalAttributes[key];\n }\n\n /** Track a screen/page view. */\n trackView(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.currentViewId = genId();\n this.trackEvent(\"view\", {\n view: { id: this.currentViewId, name },\n attributes,\n });\n }\n\n /** Track a user action. */\n trackAction(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"action\", { action: { name, type: \"custom\" }, attributes });\n }\n\n /** Track an error. */\n trackError(error: Error | { message: string; stack?: string; type?: string }, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n const data =\n error instanceof Error\n ? { message: error.message, stack: error.stack, type: error.constructor.name }\n : error;\n this.trackEvent(\"error\", { error: data, attributes });\n }\n\n /** Emit a log line. */\n log(level: RUMLogLevel, message: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"log\", { log: { level, message }, attributes });\n }\n\n private trackEvent(type: RUMEventType, data?: Partial<RUMEvent>): void {\n if (!this.initialized || !this.sessionId) return;\n const event: RUMEvent = {\n type,\n timestamp: Date.now(),\n sessionId: this.sessionId,\n viewId: this.currentViewId || undefined,\n userId: this.userId,\n applicationId: this.config!.applicationId,\n applicationVersion: this.config?.applicationVersion,\n environment: this.config?.environment,\n userAttributes: this.userAttributes,\n globalAttributes:\n Object.keys(this.globalAttributes).length > 0 ? this.globalAttributes : undefined,\n ...data,\n };\n this.queue.push(event);\n if (this.queue.length >= this.batchSize) void this.flush();\n }\n\n /** Flush queued events to POST /v1/rum/events. */\n async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const events = this.queue;\n this.queue = [];\n try {\n await apiRequest(this.cfg, \"POST\", this.endpoint, {\n events,\n sentAt: Date.now(),\n });\n } catch {\n // Re-queue on failure so events aren't lost.\n this.queue = [...events, ...this.queue];\n } finally {\n this.flushing = false;\n }\n }\n\n /** End the session, flush remaining events, and stop the timer. */\n async stopSession(): Promise<void> {\n if (!this.initialized) return;\n this.trackEvent(\"session_end\");\n await this.flush();\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.initialized = false;\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getViewId(): string | null {\n return this.currentViewId;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n CreateDelegationOptions,\n DelegationInfo,\n DelegationResult,\n DelegationStats,\n ValidationResult,\n} from \"./types.js\";\n\nfunction mapDelegation(d: any): DelegationInfo {\n return {\n delegationId: d.delegation_id,\n endUserId: d.end_user_id,\n bindingMode: d.binding_mode,\n status: d.status,\n expiresAt: d.expires_at,\n useCount: d.use_count,\n lastUsedAt: d.last_used_at,\n createdAt: d.created_at,\n };\n}\n\n/**\n * AI delegation — OAuth-like AI authentication. Lets you mint, validate and\n * revoke delegation tokens that an end user shares with their AI agent.\n *\n * Reuses the Node http helper, which unwraps the `{ success, message, content }`\n * envelope — so `apiRequest` returns the inner `content` object directly.\n */\nexport class SimplrAI {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Create a new AI delegation token for a user. POST /v1/ai/delegations. */\n async createDelegation(options: CreateDelegationOptions): Promise<DelegationResult> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/delegations\", {\n end_user_id: options.userId,\n end_user_email: options.email,\n binding: options.binding || \"any_location\",\n expires_in_days: options.expiresInDays || 7,\n session_id: options.sessionId,\n fingerprint_hash: options.fingerprintHash,\n });\n const d = content.delegation;\n return {\n token: d.token,\n delegationId: d.delegation_id,\n expiresAt: d.expires_at,\n bindingMode: d.binding_mode,\n };\n }\n\n /** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */\n async validate(\n token: string,\n options?: { fingerprintHash?: string; aiProvider?: string; action?: string },\n ): Promise<ValidationResult> {\n try {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/validate\", {\n token,\n fingerprint_hash: options?.fingerprintHash,\n ai_provider: options?.aiProvider,\n action: options?.action,\n });\n return {\n valid: true,\n sessionType: content.session_type,\n endUserId: content.end_user_id,\n delegation: content.delegation\n ? {\n delegationId: content.delegation.delegation_id,\n bindingMode: content.delegation.binding_mode,\n expiresAt: content.delegation.expires_at,\n useCount: content.delegation.use_count,\n }\n : undefined,\n };\n } catch (err) {\n return { valid: false, error: err instanceof Error ? err.message : \"Validation failed\" };\n }\n }\n\n /** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */\n async revoke(delegationId: string, reason?: string): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}/revoke`,\n { reason },\n );\n }\n\n /** List delegations, optionally filtered by user. GET /v1/ai/delegations. */\n async list(userId?: string): Promise<DelegationInfo[]> {\n const path = userId\n ? `/v1/ai/delegations?end_user_id=${encodeURIComponent(userId)}`\n : \"/v1/ai/delegations\";\n const content = await apiRequest<any>(this.cfg, \"GET\", path);\n return (content.delegations || []).map(mapDelegation);\n }\n\n /** Get a single delegation. GET /v1/ai/delegations/{id}. */\n async get(delegationId: string): Promise<DelegationInfo> {\n const content = await apiRequest<any>(\n this.cfg,\n \"GET\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}`,\n );\n return mapDelegation(content.delegation);\n }\n\n /** Get delegation statistics. GET /v1/ai/stats. */\n async stats(): Promise<DelegationStats> {\n const content = await apiRequest<any>(this.cfg, \"GET\", \"/v1/ai/stats\");\n const s = content.stats;\n return {\n totalDelegations: s.total_delegations,\n activeDelegations: s.active_delegations,\n totalUses: s.total_uses,\n delegationsByBinding: {\n verifiedDevice: s.delegations_by_binding.verified_device,\n anyLocation: s.delegations_by_binding.any_location,\n },\n };\n }\n\n /** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */\n async revokeAllForUser(userId: string, reason?: string): Promise<number> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/revoke-all\", {\n end_user_id: userId,\n reason,\n });\n return content.revoked_count;\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { WebhookVerificationError } from \"./errors.js\";\n\nexport interface VerifyOptions {\n /** Reject signatures whose timestamp is older than this many seconds (default 300). 0 disables. */\n toleranceSec?: number;\n}\n\nfunction parseHeader(header: string): { t: string; v1: string } | null {\n // Format: \"t=<unix-seconds>,v1=<hex-hmac>\"\n const parts = header.split(\",\").map((p) => p.trim());\n let t = \"\";\n let v1 = \"\";\n for (const part of parts) {\n const [k, v] = part.split(\"=\");\n if (k === \"t\") t = v;\n if (k === \"v1\") v1 = v;\n }\n return t && v1 ? { t, v1 } : null;\n}\n\nfunction expectedSignature(timestamp: string, payload: string, secret: string): string {\n return createHmac(\"sha256\", secret).update(`${timestamp}.${payload}`).digest(\"hex\");\n}\n\nfunction safeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n try {\n return timingSafeEqual(Buffer.from(a, \"hex\"), Buffer.from(b, \"hex\"));\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a Simplr webhook signature.\n *\n * @param payload The RAW request body string (do not re-serialize parsed JSON).\n * @param header The `X-Simplr-Signature` header value (`t=…,v1=…`).\n * @param secret The webhook's signing secret.\n * @returns true if the signature is valid and within the tolerance window.\n */\nexport function verify(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): boolean {\n const tolerance = options.toleranceSec ?? 300;\n const parsed = parseHeader(header || \"\");\n if (!parsed) return false;\n\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n const expected = expectedSignature(parsed.t, body, secret);\n if (!safeEqualHex(parsed.v1, expected)) return false;\n\n if (tolerance > 0) {\n const ts = Number(parsed.t);\n if (!Number.isFinite(ts)) return false;\n const ageSec = Math.abs(Date.now() / 1000 - ts);\n if (ageSec > tolerance) return false;\n }\n return true;\n}\n\n/**\n * Verify the signature and return the parsed event object.\n * Throws {@link WebhookVerificationError} if verification fails.\n */\nexport function constructEvent<T = { event: string; data: unknown }>(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): T {\n if (!verify(payload, header, secret, options)) {\n throw new WebhookVerificationError(\"Webhook signature verification failed\");\n }\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n return JSON.parse(body) as T;\n}\n\nexport const webhooks = { verify, constructEvent };\n","import { apiRequest, type HttpConfig } from \"./http.js\";\n\nexport interface SimplrAdminOptions {\n /** Portal token (JWT) for dashboard/admin operations. */\n token: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n}\n\nfunction qs(params: Record<string, unknown>): string {\n const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);\n if (!entries.length) return \"\";\n return \"?\" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join(\"&\");\n}\n\n/** Usage / measurement reads. */\nclass UsageApi {\n constructor(private readonly cfg: HttpConfig) {}\n /** Aggregate usage stats for an org. */\n stats(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/stats${qs({ org_id: orgId })}`);\n }\n /** Raw usage logs for an org. */\n logs(orgId: string, params: { page?: number; limit?: number } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/logs${qs({ org_id: orgId, ...params })}`);\n }\n /** Billing usage breakdown (per-service totals + estimated cost). */\n billing(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/billing/usage${qs({ org_id: orgId })}`);\n }\n}\n\n/** Feature-flag administration (create/update/delete/history). */\nclass FlagsAdminApi {\n constructor(private readonly cfg: HttpConfig) {}\n list(orgId: string, environment?: \"live\" | \"test\") {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags${qs({ org_id: orgId, environment })}`);\n }\n get(orgId: string, id: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n create(orgId: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"POST\", \"/v1/feature-flags\", { org_id: orgId, ...data });\n }\n update(orgId: string, id: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"PATCH\", `/v1/feature-flags/${id}`, { org_id: orgId, ...data });\n }\n remove(orgId: string, id: string) {\n return apiRequest(this.cfg, \"DELETE\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n history(orgId: string, id: string, params: { limit?: number; offset?: number } = {}) {\n return apiRequest(\n this.cfg,\n \"GET\",\n `/v1/feature-flags/${id}/history${qs({ org_id: orgId, ...params })}`,\n );\n }\n}\n\n/** RUM analytics reads. */\nclass RumApi {\n constructor(private readonly cfg: HttpConfig) {}\n overview(orgId: string, params: { application_id?: string; start_date?: string; end_date?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/overview${qs({ org_id: orgId, ...params })}`);\n }\n sessions(orgId: string, params: { page?: number; limit?: number; user_id?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/sessions${qs({ org_id: orgId, ...params })}`);\n }\n}\n\n/**\n * Management client for dashboard/admin operations that require a portal token\n * (usage/measurement, feature-flag CRUD, RUM analytics).\n *\n * ```ts\n * const admin = new SimplrAdmin({ token: process.env.SIMPLR_PORTAL_TOKEN! });\n * const usage = await admin.usage.billing(orgId);\n * await admin.flags.create(orgId, { key: \"new-checkout\", environment: \"test\", rollout_percentage: 10 });\n * ```\n */\nexport class SimplrAdmin {\n readonly usage: UsageApi;\n readonly flags: FlagsAdminApi;\n readonly rum: RumApi;\n\n constructor(options: SimplrAdminOptions) {\n if (!options?.token) throw new Error(\"SimplrAdmin: `token` is required\");\n const cfg: HttpConfig = {\n authHeaders: { Authorization: `Bearer ${options.token}` },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n };\n if (typeof cfg.fetchImpl !== \"function\") {\n throw new Error(\"SimplrAdmin: no global fetch available — use Node 18+ or pass `fetch`\");\n }\n this.usage = new UsageApi(cfg);\n this.flags = new FlagsAdminApi(cfg);\n this.rum = new RumApi(cfg);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/network-log.ts","../src/http.ts","../src/network-shipper.ts","../src/resources.ts","../src/flags.ts","../src/profiles.ts","../src/rum.ts","../src/ai.ts","../src/webhooks.ts","../src/admin.ts"],"sourcesContent":["import { apiRequest, type HttpConfig } from \"./http.js\";\nimport { NetworkLogShipper } from \"./network-shipper.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\nimport { EdgeResource, OrdersResource, PhoneResource } from \"./resources.js\";\nimport { SimplrFlags } from \"./flags.js\";\nimport { SimplrProfiles } from \"./profiles.js\";\nimport { SimplrRUM } from \"./rum.js\";\nimport { SimplrAI } from \"./ai.js\";\nimport * as webhooks from \"./webhooks.js\";\nimport type { BulkResult, CheckInput, CheckResult, SimplrOptions } from \"./types.js\";\n\nexport { SimplrError, WebhookVerificationError } from \"./errors.js\";\nexport * from \"./types.js\";\nexport type {\n NetworkLogEntry,\n NetworkLogger,\n NetworkSource,\n} from \"./network-log.js\";\nexport { NetworkLogShipper } from \"./network-shipper.js\";\nexport type { ShipperConfig } from \"./network-shipper.js\";\nexport { verify as verifyWebhook, constructEvent as constructWebhookEvent } from \"./webhooks.js\";\nexport { SimplrFlags } from \"./flags.js\";\nexport type { FlagDefinition, FlagRule, FlagsOptions, EvalContext } from \"./flags.js\";\nexport { SimplrAdmin } from \"./admin.js\";\nexport type { SimplrAdminOptions } from \"./admin.js\";\nexport { SimplrProfiles } from \"./profiles.js\";\nexport { SimplrRUM } from \"./rum.js\";\nexport type { SimplrRUMConfig } from \"./rum.js\";\nexport { SimplrAI } from \"./ai.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.simplr.sh\";\n\n/**\n * Simplr server-side client.\n *\n * ```ts\n * import { Simplr } from \"@simplr-ai/node\";\n * const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! });\n * const result = await simplr.check({ email: \"user@example.com\", event_type: \"signup\" });\n * ```\n */\nexport class Simplr {\n private readonly cfg: HttpConfig;\n\n readonly orders: OrdersResource;\n readonly phone: PhoneResource;\n readonly edge: EdgeResource;\n /** Anonymous user profiles + order fraud monitoring. */\n readonly profiles: SimplrProfiles;\n /** Real User Monitoring — batched events to /v1/rum/events. */\n readonly rum: SimplrRUM;\n /** AI delegation — OAuth-like AI authentication. */\n readonly ai: SimplrAI;\n /** Webhook signature helpers (no network). */\n readonly webhooks = webhooks;\n\n private readonly _flags?: SimplrFlags;\n private readonly shipper?: NetworkLogShipper;\n\n constructor(options: SimplrOptions) {\n if (!options?.apiKey) throw new Error(\"Simplr: `apiKey` is required\");\n const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const logSelf = !!options.logSelfCalls;\n\n if (options.shipNetworkLogs && logSelf) {\n this.shipper = new NetworkLogShipper({\n baseUrl,\n apiKey: options.apiKey,\n fetchImpl,\n sdk: \"node\",\n applicationId: options.applicationId,\n environment: options.environment,\n });\n this.shipper.start();\n }\n\n const onNetworkLog: NetworkLogger | undefined =\n this.shipper || options.onNetworkLog\n ? (entry) => {\n this.shipper?.add(entry);\n options.onNetworkLog?.(entry);\n }\n : undefined;\n\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.apiKey },\n baseUrl,\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl,\n onNetworkLog,\n logBodies: options.logBodies ?? (options.shipNetworkLogs && logSelf),\n redactFields: options.redactFields,\n };\n if (typeof this.cfg.fetchImpl !== \"function\") {\n throw new Error(\"Simplr: no global fetch available — use Node 18+ or pass `fetch` in options\");\n }\n this.orders = new OrdersResource(this.cfg);\n this.phone = new PhoneResource(this.cfg);\n this.edge = new EdgeResource(this.cfg);\n this.profiles = new SimplrProfiles(this.cfg);\n this.rum = new SimplrRUM(this.cfg);\n this.ai = new SimplrAI(this.cfg);\n if (options.publicKey) {\n this._flags = new SimplrFlags({\n publicKey: options.publicKey,\n environment: options.environment,\n baseUrl: this.cfg.baseUrl,\n timeoutMs: this.cfg.timeoutMs,\n fetch: this.cfg.fetchImpl,\n onNetworkLog: this.cfg.onNetworkLog,\n logBodies: this.cfg.logBodies,\n redactFields: options.redactFields,\n });\n }\n }\n\n /**\n * Server-side feature flags. Requires a `publicKey` in the constructor options\n * (flag config is read with the public key). Call `simplr.flags.initialize()` once.\n */\n get flags(): SimplrFlags {\n if (!this._flags) {\n throw new Error(\n \"Simplr.flags requires a `publicKey` — pass it to `new Simplr({ apiKey, publicKey })`.\",\n );\n }\n return this._flags;\n }\n\n /** Run an identity/fraud check. Provide any of email, phone, device, behavior. */\n check(input: CheckInput): Promise<CheckResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check\", input);\n }\n\n /** Run up to 100 checks at once. */\n checkBulk(items: CheckInput[]): Promise<BulkResult<CheckResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/bulk\", { items });\n }\n\n flushNetworkLogs(): Promise<void> {\n return this.shipper?.flush() ?? Promise.resolve();\n }\n\n close(): void {\n this.shipper?.stop();\n this._flags?.dispose();\n }\n}\n\nexport default Simplr;\n","/** Thrown when the Simplr API returns a non-2xx response. */\nexport class SimplrError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"SimplrError\";\n this.status = status;\n this.body = body;\n }\n}\n\n/** Thrown when a webhook signature fails verification. */\nexport class WebhookVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WebhookVerificationError\";\n }\n}\n","export type NetworkSource = \"frontend\" | \"backend\";\n\nexport interface NetworkLogEntry {\n id: string;\n source: NetworkSource;\n timestamp: string;\n sdk?: string;\n applicationId?: string;\n environment?: string;\n method: string;\n url: string;\n requestHeaders?: Record<string, string>;\n requestBody?: unknown;\n status?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: unknown;\n durationMs?: number;\n ok?: boolean;\n error?: string;\n}\n\nexport type NetworkLogger = (entry: NetworkLogEntry) => void;\n\nconst SENSITIVE_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n \"x-auth-token\",\n \"x-csrf-token\",\n \"x-xsrf-token\",\n]);\n\nconst SENSITIVE_KEY_PARTS = [\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n \"api_key\",\n \"apikey\",\n \"authorization\",\n \"auth\",\n \"credential\",\n \"private_key\",\n \"card\",\n \"cardnumber\",\n \"pan\",\n \"cvv\",\n \"cvc\",\n \"ssn\",\n \"pin\",\n \"otp\",\n];\n\nconst MAX_REDACT_DEPTH = 8;\n\nexport const MAX_BODY_CHARS = 10_000;\n\nfunction isSensitiveKey(key: string, extraKeys: string[]): boolean {\n const lower = key.toLowerCase();\n if (extraKeys.some((k) => lower === k.toLowerCase())) return true;\n return SENSITIVE_KEY_PARTS.some((part) => lower.includes(part));\n}\n\nfunction redactDeep(value: unknown, extraKeys: string[], depth = 0): unknown {\n if (depth >= MAX_REDACT_DEPTH) return \"[truncated]\";\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, extraKeys, depth + 1));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSensitiveKey(key, extraKeys)\n ? \"[REDACTED]\"\n : redactDeep(val, extraKeys, depth + 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactHeaders(\n headers: Record<string, string> | Headers | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n const out: Record<string, string> = {};\n const set = (key: string, value: string) => {\n out[key] = SENSITIVE_HEADERS.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n };\n if (typeof (headers as Headers).forEach === \"function\" && !Array.isArray(headers)) {\n (headers as Headers).forEach((value, key) => set(key, value));\n } else {\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n set(key, String(value));\n }\n }\n return out;\n}\n\nexport function previewBody(raw: unknown, redactFields: string[] = []): unknown {\n if (raw === undefined || raw === null) return undefined;\n let value: unknown = raw;\n if (typeof raw === \"string\") {\n try {\n value = JSON.parse(raw);\n } catch {\n return raw.length > MAX_BODY_CHARS ? raw.slice(0, MAX_BODY_CHARS) + \"…[truncated]\" : raw;\n }\n }\n const redacted = redactDeep(value, redactFields);\n let text: string;\n try {\n text = JSON.stringify(redacted);\n } catch {\n return \"[unserializable]\";\n }\n if (text.length > MAX_BODY_CHARS) {\n return text.slice(0, MAX_BODY_CHARS) + \"…[truncated]\";\n }\n return redacted;\n}\n\nexport function newLogId(): string {\n const uuid = (globalThis as any)?.crypto?.randomUUID;\n if (typeof uuid === \"function\") return uuid.call((globalThis as any).crypto);\n return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n","import { SimplrError } from \"./errors.js\";\nimport {\n newLogId,\n previewBody,\n redactHeaders,\n type NetworkLogger,\n} from \"./network-log.js\";\n\nexport interface HttpConfig {\n authHeaders: Record<string, string>;\n baseUrl: string;\n timeoutMs: number;\n fetchImpl: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport async function apiRequest<T>(\n cfg: HttpConfig,\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);\n\n const url = `${cfg.baseUrl}${path}`;\n const requestHeaders = {\n \"Content-Type\": \"application/json\",\n ...cfg.authHeaders,\n };\n const startedAt = Date.now();\n const log = cfg.onNetworkLog\n ? {\n id: newLogId(),\n source: \"backend\" as const,\n timestamp: new Date(startedAt).toISOString(),\n method,\n url,\n requestHeaders: redactHeaders(requestHeaders),\n requestBody: cfg.logBodies ? previewBody(body, cfg.redactFields) : undefined,\n }\n : null;\n\n const emit = (extra: Record<string, unknown>) => {\n if (!log || !cfg.onNetworkLog) return;\n try {\n cfg.onNetworkLog({ ...log, durationMs: Date.now() - startedAt, ...extra });\n } catch {\n /* empty */\n }\n };\n\n try {\n const res = await cfg.fetchImpl(url, {\n method,\n headers: requestHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const text = await res.text();\n let parsed: any;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n emit({\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n responseHeaders: redactHeaders(res.headers),\n responseBody: cfg.logBodies ? previewBody(parsed ?? text, cfg.redactFields) : undefined,\n });\n\n if (!res.ok) {\n const message =\n (parsed && (parsed.message || parsed.error)) || `Simplr API error ${res.status}`;\n throw new SimplrError(message, res.status, parsed);\n }\n\n return (parsed && typeof parsed === \"object\" && \"content\" in parsed\n ? parsed.content\n : parsed) as T;\n } catch (err) {\n if (err instanceof SimplrError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n emit({ ok: false, error: `timed out after ${cfg.timeoutMs}ms` });\n throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);\n }\n emit({ ok: false, error: err instanceof Error ? err.message : \"Network error\" });\n throw new SimplrError(err instanceof Error ? err.message : \"Network error\", 0, null);\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { NetworkLogEntry } from \"./network-log.js\";\n\nexport interface ShipperConfig {\n baseUrl: string;\n apiKey: string;\n fetchImpl: typeof fetch;\n sdk: string;\n applicationId?: string;\n environment?: string;\n batchSize?: number;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_BATCH = 25;\nconst DEFAULT_FLUSH_MS = 5000;\n\nexport class NetworkLogShipper {\n private readonly cfg: ShipperConfig;\n private queue: NetworkLogEntry[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cfg: ShipperConfig) {\n this.cfg = cfg;\n }\n\n start(): void {\n if (this.timer) return;\n const interval = this.cfg.flushIntervalMs ?? DEFAULT_FLUSH_MS;\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n\n add(entry: NetworkLogEntry): void {\n this.queue.push({\n ...entry,\n sdk: this.cfg.sdk,\n applicationId: entry.applicationId ?? this.cfg.applicationId,\n environment: entry.environment ?? this.cfg.environment,\n });\n if (this.queue.length >= (this.cfg.batchSize ?? DEFAULT_BATCH)) {\n void this.flush();\n }\n }\n\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n const logs = this.queue;\n this.queue = [];\n try {\n await this.cfg.fetchImpl(`${this.cfg.baseUrl}/v1/network-logs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.cfg.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n } catch {\n /* empty */\n }\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n void this.flush();\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n BulkResult,\n EdgeLogEntry,\n OrderInput,\n OrderResult,\n PhoneReportInput,\n} from \"./types.js\";\n\n/** Order fraud scoring. */\nexport class OrdersResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Submit a single order for fraud scoring. */\n submit(order: OrderInput): Promise<OrderResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Submit up to 100 orders at once. */\n submitBulk(orders: OrderInput[]): Promise<BulkResult<OrderResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders/bulk\", { orders });\n }\n}\n\n/** Phone intelligence + outcome reporting. */\nexport class PhoneResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Report the real-world outcome for a phone number to improve scoring. */\n report(input: PhoneReportInput): Promise<{ success: boolean }> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/phone/report\", input);\n }\n\n /** Fetch stored risk intelligence for a phone number. */\n intelligence(phone: string): Promise<Record<string, unknown>> {\n return apiRequest(this.cfg, \"GET\", `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`);\n }\n}\n\n/** Edge device registration + log ingestion. */\nexport class EdgeResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Register an edge device. */\n registerDevice(input: { device_id: string; name?: string; firmware?: string; [k: string]: unknown }) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/devices/register\", input);\n }\n\n /** Report a device heartbeat with health metrics. */\n heartbeat(deviceId: string, metrics: Record<string, unknown>) {\n return apiRequest(\n this.cfg,\n \"POST\",\n `/v1/edge/devices/${encodeURIComponent(deviceId)}/heartbeat`,\n metrics,\n );\n }\n\n /** Batch-ingest structured logs for a device. */\n ingestLogs(deviceId: string, logs: EdgeLogEntry[]) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/logs\", { device_id: deviceId, logs });\n }\n}\n","import { type HttpConfig } from \"./http.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\n\n/**\n * MurmurHash3 (x86, 32-bit) — identical to the browser SDK so a given user\n * buckets the same way on the client and the server.\n */\nfunction murmurHash3(input: string, seed = 0): number {\n let h1 = seed;\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n for (let i = 0; i < input.length; i++) {\n let k1 = input.charCodeAt(i);\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n h1 ^= input.length;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n return h1 >>> 0;\n}\n\nexport interface FlagRule {\n attribute: string;\n op: \"eq\" | \"neq\" | \"contains\";\n value: string;\n}\n\nexport interface FlagDefinition {\n key: string;\n enabled: boolean;\n rollout_percentage: number;\n target_user_ids: string[];\n rules: FlagRule[];\n}\n\nexport interface FlagsOptions {\n /** Public API key (pk_live_… / pk_test_…). Required — flags read uses the public key. */\n publicKey: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n /**\n * Which environment's flags to load. Defaults to the key's own environment\n * (the API falls back to the key's live/test mode when unset). Accepts a\n * named environment slug (e.g. \"dev\", \"uat\", \"prod\") as well as the legacy\n * \"live\"/\"test\" key modes. Sent to the API as `?environment=<value>`.\n */\n environment?: string;\n /** Auto-refresh interval in ms (default 60000; 0 disables). */\n refreshIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport interface EvalContext {\n userId?: string;\n attributes?: Record<string, unknown>;\n}\n\nfunction matchRule(rule: FlagRule, attributes: Record<string, unknown>): boolean {\n const actual = attributes[rule.attribute];\n switch (rule.op) {\n case \"eq\":\n return String(actual) === rule.value;\n case \"neq\":\n return String(actual) !== rule.value;\n case \"contains\":\n return String(actual ?? \"\").includes(rule.value);\n default:\n return false;\n }\n}\n\n/**\n * Server-side feature flags with local, deterministic evaluation.\n *\n * ```ts\n * const flags = new SimplrFlags({ publicKey: process.env.SIMPLR_PUBLIC_KEY! });\n * await flags.initialize();\n * if (flags.isEnabled(\"new-checkout\", { userId: \"user_123\" })) { ... }\n * ```\n */\nexport class SimplrFlags {\n private readonly cfg: HttpConfig;\n private readonly environment?: string;\n private readonly refreshIntervalMs: number;\n private flags: Record<string, FlagDefinition> = {};\n private defaultUserId?: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private ready = false;\n private etag: string | null = null;\n\n constructor(options: FlagsOptions) {\n if (!options?.publicKey) throw new Error(\"SimplrFlags: `publicKey` is required\");\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.publicKey },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n onNetworkLog: options.onNetworkLog,\n logBodies: options.logBodies,\n redactFields: options.redactFields,\n };\n this.environment = options.environment;\n const requested = options.refreshIntervalMs ?? 60000;\n this.refreshIntervalMs = requested > 0 ? Math.max(requested, 30000) : 0;\n }\n\n /** Fetch the flag config once and start the background refresh. */\n async initialize(): Promise<void> {\n await this.refresh();\n this.ready = true;\n if (this.refreshIntervalMs > 0) {\n this.timer = setInterval(() => {\n void this.refresh();\n }, this.refreshIntervalMs);\n // Don't keep the process alive just for flag refreshes.\n (this.timer as any)?.unref?.();\n }\n }\n\n /** Set the default identifier used for bucketing when none is passed to isEnabled. */\n setUser(userId: string): void {\n this.defaultUserId = userId;\n }\n\n async refresh(): Promise<void> {\n const path = this.environment\n ? `/v1/flags?environment=${encodeURIComponent(this.environment)}`\n : \"/v1/flags\";\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.cfg.timeoutMs);\n try {\n const headers: Record<string, string> = { ...this.cfg.authHeaders };\n if (this.etag) headers[\"If-None-Match\"] = this.etag;\n const res = await this.cfg.fetchImpl(`${this.cfg.baseUrl}${path}`, { headers, signal: controller.signal });\n if (res.status === 304) return;\n if (!res.ok) return;\n const responseEtag = res.headers?.get?.(\"etag\");\n if (responseEtag) this.etag = responseEtag;\n const text = await res.text();\n const json: any = text ? JSON.parse(text) : {};\n const list: FlagDefinition[] = json?.content?.flags || [];\n const map: Record<string, FlagDefinition> = {};\n for (const f of list) map[f.key] = f;\n this.flags = map;\n } catch {\n /* empty */\n } finally {\n clearTimeout(timer);\n }\n }\n\n /** Evaluate a flag locally. Deterministic per user; no network call. */\n isEnabled(key: string, ctx: EvalContext = {}): boolean {\n const f = this.flags[key];\n if (!f || !f.enabled) return false;\n\n const uid = ctx.userId || this.defaultUserId || \"anonymous\";\n if (f.target_user_ids?.includes(uid)) return true;\n if (ctx.attributes && f.rules?.length && f.rules.some((r) => matchRule(r, ctx.attributes!))) {\n return true;\n }\n if (f.rollout_percentage >= 100) return true;\n if (f.rollout_percentage <= 0) return false;\n return murmurHash3(`${key}:${uid}`) % 100 < f.rollout_percentage;\n }\n\n getAll(): Record<string, FlagDefinition> {\n return { ...this.flags };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n /** Stop the background refresh timer. */\n dispose(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n IdentifyOptions,\n OrderInput,\n OrderResult,\n ProfileResult,\n ProfileRiskResult,\n} from \"./types.js\";\n\n/**\n * Anonymous user profile management and order fraud monitoring.\n *\n * Works with the configured key (secret for server-side use). Mirrors the\n * browser SimplrProfiles surface but reuses the Node http helper (which unwraps\n * the `{ success, message, content }` envelope).\n */\nexport class SimplrProfiles {\n constructor(private readonly cfg: HttpConfig) {}\n\n /**\n * Identify a user — creates or updates an anonymous profile and (optionally)\n * links a device fingerprint. POST /v1/profiles.\n */\n identify(externalId: string, options?: IdentifyOptions): Promise<ProfileResult> {\n const { profileType, fingerprintHash, ...rest } = options ?? {};\n const body: Record<string, unknown> = {\n external_id: externalId,\n profile_type: profileType || \"customer\",\n ...rest,\n };\n if (fingerprintHash) body.fingerprint_hash = fingerprintHash;\n return apiRequest<ProfileResult>(this.cfg, \"POST\", \"/v1/profiles\", body);\n }\n\n /** Submit an order for real-time fraud scoring. POST /v1/orders. */\n submitOrder(order: OrderInput): Promise<OrderResult> {\n return apiRequest<OrderResult>(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Get the risk profile for a user. GET /v1/profiles/{externalId}. */\n getProfileRisk(externalId: string): Promise<ProfileRiskResult> {\n return apiRequest<ProfileRiskResult>(\n this.cfg,\n \"GET\",\n `/v1/profiles/${encodeURIComponent(externalId)}`,\n );\n }\n\n /** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */\n async reportOutcome(externalId: string, outcome: \"fraud\" | \"legitimate\"): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/profiles/${encodeURIComponent(externalId)}/outcome`,\n { outcome },\n );\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { RUMEvent, RUMEventType, RUMLogLevel } from \"./types.js\";\n\nexport interface SimplrRUMConfig {\n /** Application identifier (required). */\n applicationId: string;\n /** Optional version/environment tags applied to every event. */\n applicationVersion?: string;\n environment?: string;\n /** Flush when this many events are queued (default 30). */\n batchSize?: number;\n /** Background flush interval in ms (default 10000; 0 disables the timer). */\n flushInterval?: number;\n /** Override the events endpoint path (default /v1/rum/events). */\n endpoint?: string;\n}\n\nconst DEFAULT_BATCH_SIZE = 30;\nconst DEFAULT_FLUSH_INTERVAL = 10000;\nconst DEFAULT_ENDPOINT = \"/v1/rum/events\";\n\nfunction genId(): string {\n return (\n Date.now().toString(36) + Math.random().toString(36).slice(2, 10)\n );\n}\n\n/**\n * Server-side Real User Monitoring. Batches events and flushes them to\n * POST /v1/rum/events using the configured key. Unlike the browser SDK there is\n * no DOM auto-capture — views/actions/errors/logs are reported via the public\n * API. A timer-based flush is installed with `unref()` so it never keeps the\n * Node process alive.\n */\nexport class SimplrRUM {\n private config: SimplrRUMConfig | null = null;\n private initialized = false;\n private queue: RUMEvent[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n\n private sessionId: string | null = null;\n private currentViewId: string | null = null;\n private userId?: string;\n private userAttributes?: Record<string, unknown>;\n private globalAttributes: Record<string, unknown> = {};\n private batchSize = DEFAULT_BATCH_SIZE;\n private endpoint = DEFAULT_ENDPOINT;\n\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Initialize the SDK, start a session, and begin the flush timer. */\n initialize(config: SimplrRUMConfig): void {\n if (this.initialized) return;\n this.config = config;\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n this.sessionId = genId();\n this.initialized = true;\n\n this.trackEvent(\"session_start\");\n\n const interval = config.flushInterval ?? DEFAULT_FLUSH_INTERVAL;\n if (interval > 0) {\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /** Associate subsequent events with a user. */\n setUser(userId: string, attributes?: Record<string, unknown>): void {\n this.userId = userId;\n this.userAttributes = attributes;\n }\n\n clearUser(): void {\n this.userId = undefined;\n this.userAttributes = undefined;\n }\n\n addAttribute(key: string, value: unknown): void {\n this.globalAttributes[key] = value;\n }\n\n removeAttribute(key: string): void {\n delete this.globalAttributes[key];\n }\n\n /** Track a screen/page view. */\n trackView(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.currentViewId = genId();\n this.trackEvent(\"view\", {\n view: { id: this.currentViewId, name },\n attributes,\n });\n }\n\n /** Track a user action. */\n trackAction(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"action\", { action: { name, type: \"custom\" }, attributes });\n }\n\n /** Track an error. */\n trackError(error: Error | { message: string; stack?: string; type?: string }, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n const data =\n error instanceof Error\n ? { message: error.message, stack: error.stack, type: error.constructor.name }\n : error;\n this.trackEvent(\"error\", { error: data, attributes });\n }\n\n /** Emit a log line. */\n log(level: RUMLogLevel, message: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"log\", { log: { level, message }, attributes });\n }\n\n private trackEvent(type: RUMEventType, data?: Partial<RUMEvent>): void {\n if (!this.initialized || !this.sessionId) return;\n const event: RUMEvent = {\n type,\n timestamp: Date.now(),\n sessionId: this.sessionId,\n viewId: this.currentViewId || undefined,\n userId: this.userId,\n applicationId: this.config!.applicationId,\n applicationVersion: this.config?.applicationVersion,\n environment: this.config?.environment,\n userAttributes: this.userAttributes,\n globalAttributes:\n Object.keys(this.globalAttributes).length > 0 ? this.globalAttributes : undefined,\n ...data,\n };\n this.queue.push(event);\n if (this.queue.length >= this.batchSize) void this.flush();\n }\n\n /** Flush queued events to POST /v1/rum/events. */\n async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const events = this.queue;\n this.queue = [];\n try {\n await apiRequest(this.cfg, \"POST\", this.endpoint, {\n events,\n sentAt: Date.now(),\n });\n } catch {\n // Re-queue on failure so events aren't lost.\n this.queue = [...events, ...this.queue];\n } finally {\n this.flushing = false;\n }\n }\n\n /** End the session, flush remaining events, and stop the timer. */\n async stopSession(): Promise<void> {\n if (!this.initialized) return;\n this.trackEvent(\"session_end\");\n await this.flush();\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.initialized = false;\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getViewId(): string | null {\n return this.currentViewId;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n CreateDelegationOptions,\n DelegationInfo,\n DelegationResult,\n DelegationStats,\n ValidationResult,\n} from \"./types.js\";\n\nfunction mapDelegation(d: any): DelegationInfo {\n return {\n delegationId: d.delegation_id,\n endUserId: d.end_user_id,\n bindingMode: d.binding_mode,\n status: d.status,\n expiresAt: d.expires_at,\n useCount: d.use_count,\n lastUsedAt: d.last_used_at,\n createdAt: d.created_at,\n };\n}\n\n/**\n * AI delegation — OAuth-like AI authentication. Lets you mint, validate and\n * revoke delegation tokens that an end user shares with their AI agent.\n *\n * Reuses the Node http helper, which unwraps the `{ success, message, content }`\n * envelope — so `apiRequest` returns the inner `content` object directly.\n */\nexport class SimplrAI {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Create a new AI delegation token for a user. POST /v1/ai/delegations. */\n async createDelegation(options: CreateDelegationOptions): Promise<DelegationResult> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/delegations\", {\n end_user_id: options.userId,\n end_user_email: options.email,\n binding: options.binding || \"any_location\",\n expires_in_days: options.expiresInDays || 7,\n session_id: options.sessionId,\n fingerprint_hash: options.fingerprintHash,\n });\n const d = content.delegation;\n return {\n token: d.token,\n delegationId: d.delegation_id,\n expiresAt: d.expires_at,\n bindingMode: d.binding_mode,\n };\n }\n\n /** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */\n async validate(\n token: string,\n options?: { fingerprintHash?: string; aiProvider?: string; action?: string },\n ): Promise<ValidationResult> {\n try {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/validate\", {\n token,\n fingerprint_hash: options?.fingerprintHash,\n ai_provider: options?.aiProvider,\n action: options?.action,\n });\n return {\n valid: true,\n sessionType: content.session_type,\n endUserId: content.end_user_id,\n delegation: content.delegation\n ? {\n delegationId: content.delegation.delegation_id,\n bindingMode: content.delegation.binding_mode,\n expiresAt: content.delegation.expires_at,\n useCount: content.delegation.use_count,\n }\n : undefined,\n };\n } catch (err) {\n return { valid: false, error: err instanceof Error ? err.message : \"Validation failed\" };\n }\n }\n\n /** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */\n async revoke(delegationId: string, reason?: string): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}/revoke`,\n { reason },\n );\n }\n\n /** List delegations, optionally filtered by user. GET /v1/ai/delegations. */\n async list(userId?: string): Promise<DelegationInfo[]> {\n const path = userId\n ? `/v1/ai/delegations?end_user_id=${encodeURIComponent(userId)}`\n : \"/v1/ai/delegations\";\n const content = await apiRequest<any>(this.cfg, \"GET\", path);\n return (content.delegations || []).map(mapDelegation);\n }\n\n /** Get a single delegation. GET /v1/ai/delegations/{id}. */\n async get(delegationId: string): Promise<DelegationInfo> {\n const content = await apiRequest<any>(\n this.cfg,\n \"GET\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}`,\n );\n return mapDelegation(content.delegation);\n }\n\n /** Get delegation statistics. GET /v1/ai/stats. */\n async stats(): Promise<DelegationStats> {\n const content = await apiRequest<any>(this.cfg, \"GET\", \"/v1/ai/stats\");\n const s = content.stats;\n return {\n totalDelegations: s.total_delegations,\n activeDelegations: s.active_delegations,\n totalUses: s.total_uses,\n delegationsByBinding: {\n verifiedDevice: s.delegations_by_binding.verified_device,\n anyLocation: s.delegations_by_binding.any_location,\n },\n };\n }\n\n /** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */\n async revokeAllForUser(userId: string, reason?: string): Promise<number> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/revoke-all\", {\n end_user_id: userId,\n reason,\n });\n return content.revoked_count;\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { WebhookVerificationError } from \"./errors.js\";\n\nexport interface VerifyOptions {\n /** Reject signatures whose timestamp is older than this many seconds (default 300). 0 disables. */\n toleranceSec?: number;\n}\n\nfunction parseHeader(header: string): { t: string; v1: string } | null {\n // Format: \"t=<unix-seconds>,v1=<hex-hmac>\"\n const parts = header.split(\",\").map((p) => p.trim());\n let t = \"\";\n let v1 = \"\";\n for (const part of parts) {\n const [k, v] = part.split(\"=\");\n if (k === \"t\") t = v;\n if (k === \"v1\") v1 = v;\n }\n return t && v1 ? { t, v1 } : null;\n}\n\nfunction expectedSignature(timestamp: string, payload: string, secret: string): string {\n return createHmac(\"sha256\", secret).update(`${timestamp}.${payload}`).digest(\"hex\");\n}\n\nfunction safeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n try {\n return timingSafeEqual(Buffer.from(a, \"hex\"), Buffer.from(b, \"hex\"));\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a Simplr webhook signature.\n *\n * @param payload The RAW request body string (do not re-serialize parsed JSON).\n * @param header The `X-Simplr-Signature` header value (`t=…,v1=…`).\n * @param secret The webhook's signing secret.\n * @returns true if the signature is valid and within the tolerance window.\n */\nexport function verify(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): boolean {\n const tolerance = options.toleranceSec ?? 300;\n const parsed = parseHeader(header || \"\");\n if (!parsed) return false;\n\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n const expected = expectedSignature(parsed.t, body, secret);\n if (!safeEqualHex(parsed.v1, expected)) return false;\n\n if (tolerance > 0) {\n const ts = Number(parsed.t);\n if (!Number.isFinite(ts)) return false;\n const ageSec = Math.abs(Date.now() / 1000 - ts);\n if (ageSec > tolerance) return false;\n }\n return true;\n}\n\n/**\n * Verify the signature and return the parsed event object.\n * Throws {@link WebhookVerificationError} if verification fails.\n */\nexport function constructEvent<T = { event: string; data: unknown }>(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): T {\n if (!verify(payload, header, secret, options)) {\n throw new WebhookVerificationError(\"Webhook signature verification failed\");\n }\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n return JSON.parse(body) as T;\n}\n\nexport const webhooks = { verify, constructEvent };\n","import { apiRequest, type HttpConfig } from \"./http.js\";\n\nexport interface SimplrAdminOptions {\n /** Portal token (JWT) for dashboard/admin operations. */\n token: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n}\n\nfunction qs(params: Record<string, unknown>): string {\n const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);\n if (!entries.length) return \"\";\n return \"?\" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join(\"&\");\n}\n\n/** Usage / measurement reads. */\nclass UsageApi {\n constructor(private readonly cfg: HttpConfig) {}\n /** Aggregate usage stats for an org. */\n stats(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/stats${qs({ org_id: orgId })}`);\n }\n /** Raw usage logs for an org. */\n logs(orgId: string, params: { page?: number; limit?: number } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/logs${qs({ org_id: orgId, ...params })}`);\n }\n /** Billing usage breakdown (per-service totals + estimated cost). */\n billing(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/billing/usage${qs({ org_id: orgId })}`);\n }\n}\n\n/** Feature-flag administration (create/update/delete/history). */\nclass FlagsAdminApi {\n constructor(private readonly cfg: HttpConfig) {}\n list(orgId: string, environment?: \"live\" | \"test\") {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags${qs({ org_id: orgId, environment })}`);\n }\n get(orgId: string, id: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n create(orgId: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"POST\", \"/v1/feature-flags\", { org_id: orgId, ...data });\n }\n update(orgId: string, id: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"PATCH\", `/v1/feature-flags/${id}`, { org_id: orgId, ...data });\n }\n remove(orgId: string, id: string) {\n return apiRequest(this.cfg, \"DELETE\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n history(orgId: string, id: string, params: { limit?: number; offset?: number } = {}) {\n return apiRequest(\n this.cfg,\n \"GET\",\n `/v1/feature-flags/${id}/history${qs({ org_id: orgId, ...params })}`,\n );\n }\n}\n\n/** RUM analytics reads. */\nclass RumApi {\n constructor(private readonly cfg: HttpConfig) {}\n overview(orgId: string, params: { application_id?: string; start_date?: string; end_date?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/overview${qs({ org_id: orgId, ...params })}`);\n }\n sessions(orgId: string, params: { page?: number; limit?: number; user_id?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/sessions${qs({ org_id: orgId, ...params })}`);\n }\n}\n\n/**\n * Management client for dashboard/admin operations that require a portal token\n * (usage/measurement, feature-flag CRUD, RUM analytics).\n *\n * ```ts\n * const admin = new SimplrAdmin({ token: process.env.SIMPLR_PORTAL_TOKEN! });\n * const usage = await admin.usage.billing(orgId);\n * await admin.flags.create(orgId, { key: \"new-checkout\", environment: \"test\", rollout_percentage: 10 });\n * ```\n */\nexport class SimplrAdmin {\n readonly usage: UsageApi;\n readonly flags: FlagsAdminApi;\n readonly rum: RumApi;\n\n constructor(options: SimplrAdminOptions) {\n if (!options?.token) throw new Error(\"SimplrAdmin: `token` is required\");\n const cfg: HttpConfig = {\n authHeaders: { Authorization: `Bearer ${options.token}` },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n };\n if (typeof cfg.fetchImpl !== \"function\") {\n throw new Error(\"SimplrAdmin: no global fetch available — use Node 18+ or pass `fetch`\");\n }\n this.usage = new UsageApi(cfg);\n this.flags = new FlagsAdminApi(cfg);\n this.rum = new RumApi(cfg);\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -54,6 +54,7 @@ interface SimplrOptions {
|
|
|
54
54
|
redactFields?: string[];
|
|
55
55
|
shipNetworkLogs?: boolean;
|
|
56
56
|
applicationId?: string;
|
|
57
|
+
logSelfCalls?: boolean;
|
|
57
58
|
}
|
|
58
59
|
interface CheckInput {
|
|
59
60
|
email?: string;
|
|
@@ -328,12 +329,12 @@ declare class SimplrFlags {
|
|
|
328
329
|
private defaultUserId?;
|
|
329
330
|
private timer;
|
|
330
331
|
private ready;
|
|
332
|
+
private etag;
|
|
331
333
|
constructor(options: FlagsOptions);
|
|
332
334
|
/** Fetch the flag config once and start the background refresh. */
|
|
333
335
|
initialize(): Promise<void>;
|
|
334
336
|
/** Set the default identifier used for bucketing when none is passed to isEnabled. */
|
|
335
337
|
setUser(userId: string): void;
|
|
336
|
-
/** Re-fetch the flag config (counts as one billable request). */
|
|
337
338
|
refresh(): Promise<void>;
|
|
338
339
|
/** Evaluate a flag locally. Deterministic per user; no network call. */
|
|
339
340
|
isEnabled(key: string, ctx?: EvalContext): boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ interface SimplrOptions {
|
|
|
54
54
|
redactFields?: string[];
|
|
55
55
|
shipNetworkLogs?: boolean;
|
|
56
56
|
applicationId?: string;
|
|
57
|
+
logSelfCalls?: boolean;
|
|
57
58
|
}
|
|
58
59
|
interface CheckInput {
|
|
59
60
|
email?: string;
|
|
@@ -328,12 +329,12 @@ declare class SimplrFlags {
|
|
|
328
329
|
private defaultUserId?;
|
|
329
330
|
private timer;
|
|
330
331
|
private ready;
|
|
332
|
+
private etag;
|
|
331
333
|
constructor(options: FlagsOptions);
|
|
332
334
|
/** Fetch the flag config once and start the background refresh. */
|
|
333
335
|
initialize(): Promise<void>;
|
|
334
336
|
/** Set the default identifier used for bucketing when none is passed to isEnabled. */
|
|
335
337
|
setUser(userId: string): void;
|
|
336
|
-
/** Re-fetch the flag config (counts as one billable request). */
|
|
337
338
|
refresh(): Promise<void>;
|
|
338
339
|
/** Evaluate a flag locally. Deterministic per user; no network call. */
|
|
339
340
|
isEnabled(key: string, ctx?: EvalContext): boolean;
|
package/dist/index.js
CHANGED
|
@@ -327,6 +327,7 @@ var SimplrFlags = class {
|
|
|
327
327
|
defaultUserId;
|
|
328
328
|
timer = null;
|
|
329
329
|
ready = false;
|
|
330
|
+
etag = null;
|
|
330
331
|
constructor(options) {
|
|
331
332
|
if (!options?.publicKey) throw new Error("SimplrFlags: `publicKey` is required");
|
|
332
333
|
this.cfg = {
|
|
@@ -339,7 +340,8 @@ var SimplrFlags = class {
|
|
|
339
340
|
redactFields: options.redactFields
|
|
340
341
|
};
|
|
341
342
|
this.environment = options.environment;
|
|
342
|
-
|
|
343
|
+
const requested = options.refreshIntervalMs ?? 6e4;
|
|
344
|
+
this.refreshIntervalMs = requested > 0 ? Math.max(requested, 3e4) : 0;
|
|
343
345
|
}
|
|
344
346
|
/** Fetch the flag config once and start the background refresh. */
|
|
345
347
|
async initialize() {
|
|
@@ -356,16 +358,27 @@ var SimplrFlags = class {
|
|
|
356
358
|
setUser(userId) {
|
|
357
359
|
this.defaultUserId = userId;
|
|
358
360
|
}
|
|
359
|
-
/** Re-fetch the flag config (counts as one billable request). */
|
|
360
361
|
async refresh() {
|
|
361
362
|
const path = this.environment ? `/v1/flags?environment=${encodeURIComponent(this.environment)}` : "/v1/flags";
|
|
363
|
+
const controller = new AbortController();
|
|
364
|
+
const timer = setTimeout(() => controller.abort(), this.cfg.timeoutMs);
|
|
362
365
|
try {
|
|
363
|
-
const
|
|
364
|
-
|
|
366
|
+
const headers = { ...this.cfg.authHeaders };
|
|
367
|
+
if (this.etag) headers["If-None-Match"] = this.etag;
|
|
368
|
+
const res = await this.cfg.fetchImpl(`${this.cfg.baseUrl}${path}`, { headers, signal: controller.signal });
|
|
369
|
+
if (res.status === 304) return;
|
|
370
|
+
if (!res.ok) return;
|
|
371
|
+
const responseEtag = res.headers?.get?.("etag");
|
|
372
|
+
if (responseEtag) this.etag = responseEtag;
|
|
373
|
+
const text = await res.text();
|
|
374
|
+
const json = text ? JSON.parse(text) : {};
|
|
375
|
+
const list = json?.content?.flags || [];
|
|
365
376
|
const map = {};
|
|
366
377
|
for (const f of list) map[f.key] = f;
|
|
367
378
|
this.flags = map;
|
|
368
379
|
} catch {
|
|
380
|
+
} finally {
|
|
381
|
+
clearTimeout(timer);
|
|
369
382
|
}
|
|
370
383
|
}
|
|
371
384
|
/** Evaluate a flag locally. Deterministic per user; no network call. */
|
|
@@ -843,7 +856,8 @@ var Simplr = class {
|
|
|
843
856
|
if (!options?.apiKey) throw new Error("Simplr: `apiKey` is required");
|
|
844
857
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
845
858
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
846
|
-
|
|
859
|
+
const logSelf = !!options.logSelfCalls;
|
|
860
|
+
if (options.shipNetworkLogs && logSelf) {
|
|
847
861
|
this.shipper = new NetworkLogShipper({
|
|
848
862
|
baseUrl,
|
|
849
863
|
apiKey: options.apiKey,
|
|
@@ -864,7 +878,7 @@ var Simplr = class {
|
|
|
864
878
|
timeoutMs: options.timeoutMs ?? 15e3,
|
|
865
879
|
fetchImpl,
|
|
866
880
|
onNetworkLog,
|
|
867
|
-
logBodies: options.logBodies ?? options.shipNetworkLogs,
|
|
881
|
+
logBodies: options.logBodies ?? (options.shipNetworkLogs && logSelf),
|
|
868
882
|
redactFields: options.redactFields
|
|
869
883
|
};
|
|
870
884
|
if (typeof this.cfg.fetchImpl !== "function") {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/network-log.ts","../src/http.ts","../src/network-shipper.ts","../src/resources.ts","../src/flags.ts","../src/profiles.ts","../src/rum.ts","../src/ai.ts","../src/webhooks.ts","../src/admin.ts","../src/index.ts"],"sourcesContent":["/** Thrown when the Simplr API returns a non-2xx response. */\nexport class SimplrError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"SimplrError\";\n this.status = status;\n this.body = body;\n }\n}\n\n/** Thrown when a webhook signature fails verification. */\nexport class WebhookVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WebhookVerificationError\";\n }\n}\n","export type NetworkSource = \"frontend\" | \"backend\";\n\nexport interface NetworkLogEntry {\n id: string;\n source: NetworkSource;\n timestamp: string;\n sdk?: string;\n applicationId?: string;\n environment?: string;\n method: string;\n url: string;\n requestHeaders?: Record<string, string>;\n requestBody?: unknown;\n status?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: unknown;\n durationMs?: number;\n ok?: boolean;\n error?: string;\n}\n\nexport type NetworkLogger = (entry: NetworkLogEntry) => void;\n\nconst SENSITIVE_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n \"x-auth-token\",\n \"x-csrf-token\",\n \"x-xsrf-token\",\n]);\n\nconst SENSITIVE_KEY_PARTS = [\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n \"api_key\",\n \"apikey\",\n \"authorization\",\n \"auth\",\n \"credential\",\n \"private_key\",\n \"card\",\n \"cardnumber\",\n \"pan\",\n \"cvv\",\n \"cvc\",\n \"ssn\",\n \"pin\",\n \"otp\",\n];\n\nconst MAX_REDACT_DEPTH = 8;\n\nexport const MAX_BODY_CHARS = 10_000;\n\nfunction isSensitiveKey(key: string, extraKeys: string[]): boolean {\n const lower = key.toLowerCase();\n if (extraKeys.some((k) => lower === k.toLowerCase())) return true;\n return SENSITIVE_KEY_PARTS.some((part) => lower.includes(part));\n}\n\nfunction redactDeep(value: unknown, extraKeys: string[], depth = 0): unknown {\n if (depth >= MAX_REDACT_DEPTH) return \"[truncated]\";\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, extraKeys, depth + 1));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSensitiveKey(key, extraKeys)\n ? \"[REDACTED]\"\n : redactDeep(val, extraKeys, depth + 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactHeaders(\n headers: Record<string, string> | Headers | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n const out: Record<string, string> = {};\n const set = (key: string, value: string) => {\n out[key] = SENSITIVE_HEADERS.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n };\n if (typeof (headers as Headers).forEach === \"function\" && !Array.isArray(headers)) {\n (headers as Headers).forEach((value, key) => set(key, value));\n } else {\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n set(key, String(value));\n }\n }\n return out;\n}\n\nexport function previewBody(raw: unknown, redactFields: string[] = []): unknown {\n if (raw === undefined || raw === null) return undefined;\n let value: unknown = raw;\n if (typeof raw === \"string\") {\n try {\n value = JSON.parse(raw);\n } catch {\n return raw.length > MAX_BODY_CHARS ? raw.slice(0, MAX_BODY_CHARS) + \"…[truncated]\" : raw;\n }\n }\n const redacted = redactDeep(value, redactFields);\n let text: string;\n try {\n text = JSON.stringify(redacted);\n } catch {\n return \"[unserializable]\";\n }\n if (text.length > MAX_BODY_CHARS) {\n return text.slice(0, MAX_BODY_CHARS) + \"…[truncated]\";\n }\n return redacted;\n}\n\nexport function newLogId(): string {\n const uuid = (globalThis as any)?.crypto?.randomUUID;\n if (typeof uuid === \"function\") return uuid.call((globalThis as any).crypto);\n return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n","import { SimplrError } from \"./errors.js\";\nimport {\n newLogId,\n previewBody,\n redactHeaders,\n type NetworkLogger,\n} from \"./network-log.js\";\n\nexport interface HttpConfig {\n authHeaders: Record<string, string>;\n baseUrl: string;\n timeoutMs: number;\n fetchImpl: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport async function apiRequest<T>(\n cfg: HttpConfig,\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);\n\n const url = `${cfg.baseUrl}${path}`;\n const requestHeaders = {\n \"Content-Type\": \"application/json\",\n ...cfg.authHeaders,\n };\n const startedAt = Date.now();\n const log = cfg.onNetworkLog\n ? {\n id: newLogId(),\n source: \"backend\" as const,\n timestamp: new Date(startedAt).toISOString(),\n method,\n url,\n requestHeaders: redactHeaders(requestHeaders),\n requestBody: cfg.logBodies ? previewBody(body, cfg.redactFields) : undefined,\n }\n : null;\n\n const emit = (extra: Record<string, unknown>) => {\n if (!log || !cfg.onNetworkLog) return;\n try {\n cfg.onNetworkLog({ ...log, durationMs: Date.now() - startedAt, ...extra });\n } catch {\n /* empty */\n }\n };\n\n try {\n const res = await cfg.fetchImpl(url, {\n method,\n headers: requestHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const text = await res.text();\n let parsed: any;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n emit({\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n responseHeaders: redactHeaders(res.headers),\n responseBody: cfg.logBodies ? previewBody(parsed ?? text, cfg.redactFields) : undefined,\n });\n\n if (!res.ok) {\n const message =\n (parsed && (parsed.message || parsed.error)) || `Simplr API error ${res.status}`;\n throw new SimplrError(message, res.status, parsed);\n }\n\n return (parsed && typeof parsed === \"object\" && \"content\" in parsed\n ? parsed.content\n : parsed) as T;\n } catch (err) {\n if (err instanceof SimplrError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n emit({ ok: false, error: `timed out after ${cfg.timeoutMs}ms` });\n throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);\n }\n emit({ ok: false, error: err instanceof Error ? err.message : \"Network error\" });\n throw new SimplrError(err instanceof Error ? err.message : \"Network error\", 0, null);\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { NetworkLogEntry } from \"./network-log.js\";\n\nexport interface ShipperConfig {\n baseUrl: string;\n apiKey: string;\n fetchImpl: typeof fetch;\n sdk: string;\n applicationId?: string;\n environment?: string;\n batchSize?: number;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_BATCH = 25;\nconst DEFAULT_FLUSH_MS = 5000;\n\nexport class NetworkLogShipper {\n private readonly cfg: ShipperConfig;\n private queue: NetworkLogEntry[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cfg: ShipperConfig) {\n this.cfg = cfg;\n }\n\n start(): void {\n if (this.timer) return;\n const interval = this.cfg.flushIntervalMs ?? DEFAULT_FLUSH_MS;\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n\n add(entry: NetworkLogEntry): void {\n this.queue.push({\n ...entry,\n sdk: this.cfg.sdk,\n applicationId: entry.applicationId ?? this.cfg.applicationId,\n environment: entry.environment ?? this.cfg.environment,\n });\n if (this.queue.length >= (this.cfg.batchSize ?? DEFAULT_BATCH)) {\n void this.flush();\n }\n }\n\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n const logs = this.queue;\n this.queue = [];\n try {\n await this.cfg.fetchImpl(`${this.cfg.baseUrl}/v1/network-logs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.cfg.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n } catch {\n /* empty */\n }\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n void this.flush();\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n BulkResult,\n EdgeLogEntry,\n OrderInput,\n OrderResult,\n PhoneReportInput,\n} from \"./types.js\";\n\n/** Order fraud scoring. */\nexport class OrdersResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Submit a single order for fraud scoring. */\n submit(order: OrderInput): Promise<OrderResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Submit up to 100 orders at once. */\n submitBulk(orders: OrderInput[]): Promise<BulkResult<OrderResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders/bulk\", { orders });\n }\n}\n\n/** Phone intelligence + outcome reporting. */\nexport class PhoneResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Report the real-world outcome for a phone number to improve scoring. */\n report(input: PhoneReportInput): Promise<{ success: boolean }> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/phone/report\", input);\n }\n\n /** Fetch stored risk intelligence for a phone number. */\n intelligence(phone: string): Promise<Record<string, unknown>> {\n return apiRequest(this.cfg, \"GET\", `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`);\n }\n}\n\n/** Edge device registration + log ingestion. */\nexport class EdgeResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Register an edge device. */\n registerDevice(input: { device_id: string; name?: string; firmware?: string; [k: string]: unknown }) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/devices/register\", input);\n }\n\n /** Report a device heartbeat with health metrics. */\n heartbeat(deviceId: string, metrics: Record<string, unknown>) {\n return apiRequest(\n this.cfg,\n \"POST\",\n `/v1/edge/devices/${encodeURIComponent(deviceId)}/heartbeat`,\n metrics,\n );\n }\n\n /** Batch-ingest structured logs for a device. */\n ingestLogs(deviceId: string, logs: EdgeLogEntry[]) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/logs\", { device_id: deviceId, logs });\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\n\n/**\n * MurmurHash3 (x86, 32-bit) — identical to the browser SDK so a given user\n * buckets the same way on the client and the server.\n */\nfunction murmurHash3(input: string, seed = 0): number {\n let h1 = seed;\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n for (let i = 0; i < input.length; i++) {\n let k1 = input.charCodeAt(i);\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n h1 ^= input.length;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n return h1 >>> 0;\n}\n\nexport interface FlagRule {\n attribute: string;\n op: \"eq\" | \"neq\" | \"contains\";\n value: string;\n}\n\nexport interface FlagDefinition {\n key: string;\n enabled: boolean;\n rollout_percentage: number;\n target_user_ids: string[];\n rules: FlagRule[];\n}\n\nexport interface FlagsOptions {\n /** Public API key (pk_live_… / pk_test_…). Required — flags read uses the public key. */\n publicKey: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n /**\n * Which environment's flags to load. Defaults to the key's own environment\n * (the API falls back to the key's live/test mode when unset). Accepts a\n * named environment slug (e.g. \"dev\", \"uat\", \"prod\") as well as the legacy\n * \"live\"/\"test\" key modes. Sent to the API as `?environment=<value>`.\n */\n environment?: string;\n /** Auto-refresh interval in ms (default 60000; 0 disables). */\n refreshIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport interface EvalContext {\n userId?: string;\n attributes?: Record<string, unknown>;\n}\n\nfunction matchRule(rule: FlagRule, attributes: Record<string, unknown>): boolean {\n const actual = attributes[rule.attribute];\n switch (rule.op) {\n case \"eq\":\n return String(actual) === rule.value;\n case \"neq\":\n return String(actual) !== rule.value;\n case \"contains\":\n return String(actual ?? \"\").includes(rule.value);\n default:\n return false;\n }\n}\n\n/**\n * Server-side feature flags with local, deterministic evaluation.\n *\n * ```ts\n * const flags = new SimplrFlags({ publicKey: process.env.SIMPLR_PUBLIC_KEY! });\n * await flags.initialize();\n * if (flags.isEnabled(\"new-checkout\", { userId: \"user_123\" })) { ... }\n * ```\n */\nexport class SimplrFlags {\n private readonly cfg: HttpConfig;\n private readonly environment?: string;\n private readonly refreshIntervalMs: number;\n private flags: Record<string, FlagDefinition> = {};\n private defaultUserId?: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private ready = false;\n\n constructor(options: FlagsOptions) {\n if (!options?.publicKey) throw new Error(\"SimplrFlags: `publicKey` is required\");\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.publicKey },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n onNetworkLog: options.onNetworkLog,\n logBodies: options.logBodies,\n redactFields: options.redactFields,\n };\n this.environment = options.environment;\n this.refreshIntervalMs = options.refreshIntervalMs ?? 60000;\n }\n\n /** Fetch the flag config once and start the background refresh. */\n async initialize(): Promise<void> {\n await this.refresh();\n this.ready = true;\n if (this.refreshIntervalMs > 0) {\n this.timer = setInterval(() => {\n void this.refresh();\n }, this.refreshIntervalMs);\n // Don't keep the process alive just for flag refreshes.\n (this.timer as any)?.unref?.();\n }\n }\n\n /** Set the default identifier used for bucketing when none is passed to isEnabled. */\n setUser(userId: string): void {\n this.defaultUserId = userId;\n }\n\n /** Re-fetch the flag config (counts as one billable request). */\n async refresh(): Promise<void> {\n const path = this.environment\n ? `/v1/flags?environment=${encodeURIComponent(this.environment)}`\n : \"/v1/flags\";\n try {\n const content = await apiRequest<{ flags: FlagDefinition[] }>(this.cfg, \"GET\", path);\n const list = content?.flags || [];\n const map: Record<string, FlagDefinition> = {};\n for (const f of list) map[f.key] = f;\n this.flags = map;\n } catch {\n // keep last-known flags on error\n }\n }\n\n /** Evaluate a flag locally. Deterministic per user; no network call. */\n isEnabled(key: string, ctx: EvalContext = {}): boolean {\n const f = this.flags[key];\n if (!f || !f.enabled) return false;\n\n const uid = ctx.userId || this.defaultUserId || \"anonymous\";\n if (f.target_user_ids?.includes(uid)) return true;\n if (ctx.attributes && f.rules?.length && f.rules.some((r) => matchRule(r, ctx.attributes!))) {\n return true;\n }\n if (f.rollout_percentage >= 100) return true;\n if (f.rollout_percentage <= 0) return false;\n return murmurHash3(`${key}:${uid}`) % 100 < f.rollout_percentage;\n }\n\n getAll(): Record<string, FlagDefinition> {\n return { ...this.flags };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n /** Stop the background refresh timer. */\n dispose(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n IdentifyOptions,\n OrderInput,\n OrderResult,\n ProfileResult,\n ProfileRiskResult,\n} from \"./types.js\";\n\n/**\n * Anonymous user profile management and order fraud monitoring.\n *\n * Works with the configured key (secret for server-side use). Mirrors the\n * browser SimplrProfiles surface but reuses the Node http helper (which unwraps\n * the `{ success, message, content }` envelope).\n */\nexport class SimplrProfiles {\n constructor(private readonly cfg: HttpConfig) {}\n\n /**\n * Identify a user — creates or updates an anonymous profile and (optionally)\n * links a device fingerprint. POST /v1/profiles.\n */\n identify(externalId: string, options?: IdentifyOptions): Promise<ProfileResult> {\n const { profileType, fingerprintHash, ...rest } = options ?? {};\n const body: Record<string, unknown> = {\n external_id: externalId,\n profile_type: profileType || \"customer\",\n ...rest,\n };\n if (fingerprintHash) body.fingerprint_hash = fingerprintHash;\n return apiRequest<ProfileResult>(this.cfg, \"POST\", \"/v1/profiles\", body);\n }\n\n /** Submit an order for real-time fraud scoring. POST /v1/orders. */\n submitOrder(order: OrderInput): Promise<OrderResult> {\n return apiRequest<OrderResult>(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Get the risk profile for a user. GET /v1/profiles/{externalId}. */\n getProfileRisk(externalId: string): Promise<ProfileRiskResult> {\n return apiRequest<ProfileRiskResult>(\n this.cfg,\n \"GET\",\n `/v1/profiles/${encodeURIComponent(externalId)}`,\n );\n }\n\n /** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */\n async reportOutcome(externalId: string, outcome: \"fraud\" | \"legitimate\"): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/profiles/${encodeURIComponent(externalId)}/outcome`,\n { outcome },\n );\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { RUMEvent, RUMEventType, RUMLogLevel } from \"./types.js\";\n\nexport interface SimplrRUMConfig {\n /** Application identifier (required). */\n applicationId: string;\n /** Optional version/environment tags applied to every event. */\n applicationVersion?: string;\n environment?: string;\n /** Flush when this many events are queued (default 30). */\n batchSize?: number;\n /** Background flush interval in ms (default 10000; 0 disables the timer). */\n flushInterval?: number;\n /** Override the events endpoint path (default /v1/rum/events). */\n endpoint?: string;\n}\n\nconst DEFAULT_BATCH_SIZE = 30;\nconst DEFAULT_FLUSH_INTERVAL = 10000;\nconst DEFAULT_ENDPOINT = \"/v1/rum/events\";\n\nfunction genId(): string {\n return (\n Date.now().toString(36) + Math.random().toString(36).slice(2, 10)\n );\n}\n\n/**\n * Server-side Real User Monitoring. Batches events and flushes them to\n * POST /v1/rum/events using the configured key. Unlike the browser SDK there is\n * no DOM auto-capture — views/actions/errors/logs are reported via the public\n * API. A timer-based flush is installed with `unref()` so it never keeps the\n * Node process alive.\n */\nexport class SimplrRUM {\n private config: SimplrRUMConfig | null = null;\n private initialized = false;\n private queue: RUMEvent[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n\n private sessionId: string | null = null;\n private currentViewId: string | null = null;\n private userId?: string;\n private userAttributes?: Record<string, unknown>;\n private globalAttributes: Record<string, unknown> = {};\n private batchSize = DEFAULT_BATCH_SIZE;\n private endpoint = DEFAULT_ENDPOINT;\n\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Initialize the SDK, start a session, and begin the flush timer. */\n initialize(config: SimplrRUMConfig): void {\n if (this.initialized) return;\n this.config = config;\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n this.sessionId = genId();\n this.initialized = true;\n\n this.trackEvent(\"session_start\");\n\n const interval = config.flushInterval ?? DEFAULT_FLUSH_INTERVAL;\n if (interval > 0) {\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /** Associate subsequent events with a user. */\n setUser(userId: string, attributes?: Record<string, unknown>): void {\n this.userId = userId;\n this.userAttributes = attributes;\n }\n\n clearUser(): void {\n this.userId = undefined;\n this.userAttributes = undefined;\n }\n\n addAttribute(key: string, value: unknown): void {\n this.globalAttributes[key] = value;\n }\n\n removeAttribute(key: string): void {\n delete this.globalAttributes[key];\n }\n\n /** Track a screen/page view. */\n trackView(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.currentViewId = genId();\n this.trackEvent(\"view\", {\n view: { id: this.currentViewId, name },\n attributes,\n });\n }\n\n /** Track a user action. */\n trackAction(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"action\", { action: { name, type: \"custom\" }, attributes });\n }\n\n /** Track an error. */\n trackError(error: Error | { message: string; stack?: string; type?: string }, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n const data =\n error instanceof Error\n ? { message: error.message, stack: error.stack, type: error.constructor.name }\n : error;\n this.trackEvent(\"error\", { error: data, attributes });\n }\n\n /** Emit a log line. */\n log(level: RUMLogLevel, message: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"log\", { log: { level, message }, attributes });\n }\n\n private trackEvent(type: RUMEventType, data?: Partial<RUMEvent>): void {\n if (!this.initialized || !this.sessionId) return;\n const event: RUMEvent = {\n type,\n timestamp: Date.now(),\n sessionId: this.sessionId,\n viewId: this.currentViewId || undefined,\n userId: this.userId,\n applicationId: this.config!.applicationId,\n applicationVersion: this.config?.applicationVersion,\n environment: this.config?.environment,\n userAttributes: this.userAttributes,\n globalAttributes:\n Object.keys(this.globalAttributes).length > 0 ? this.globalAttributes : undefined,\n ...data,\n };\n this.queue.push(event);\n if (this.queue.length >= this.batchSize) void this.flush();\n }\n\n /** Flush queued events to POST /v1/rum/events. */\n async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const events = this.queue;\n this.queue = [];\n try {\n await apiRequest(this.cfg, \"POST\", this.endpoint, {\n events,\n sentAt: Date.now(),\n });\n } catch {\n // Re-queue on failure so events aren't lost.\n this.queue = [...events, ...this.queue];\n } finally {\n this.flushing = false;\n }\n }\n\n /** End the session, flush remaining events, and stop the timer. */\n async stopSession(): Promise<void> {\n if (!this.initialized) return;\n this.trackEvent(\"session_end\");\n await this.flush();\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.initialized = false;\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getViewId(): string | null {\n return this.currentViewId;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n CreateDelegationOptions,\n DelegationInfo,\n DelegationResult,\n DelegationStats,\n ValidationResult,\n} from \"./types.js\";\n\nfunction mapDelegation(d: any): DelegationInfo {\n return {\n delegationId: d.delegation_id,\n endUserId: d.end_user_id,\n bindingMode: d.binding_mode,\n status: d.status,\n expiresAt: d.expires_at,\n useCount: d.use_count,\n lastUsedAt: d.last_used_at,\n createdAt: d.created_at,\n };\n}\n\n/**\n * AI delegation — OAuth-like AI authentication. Lets you mint, validate and\n * revoke delegation tokens that an end user shares with their AI agent.\n *\n * Reuses the Node http helper, which unwraps the `{ success, message, content }`\n * envelope — so `apiRequest` returns the inner `content` object directly.\n */\nexport class SimplrAI {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Create a new AI delegation token for a user. POST /v1/ai/delegations. */\n async createDelegation(options: CreateDelegationOptions): Promise<DelegationResult> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/delegations\", {\n end_user_id: options.userId,\n end_user_email: options.email,\n binding: options.binding || \"any_location\",\n expires_in_days: options.expiresInDays || 7,\n session_id: options.sessionId,\n fingerprint_hash: options.fingerprintHash,\n });\n const d = content.delegation;\n return {\n token: d.token,\n delegationId: d.delegation_id,\n expiresAt: d.expires_at,\n bindingMode: d.binding_mode,\n };\n }\n\n /** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */\n async validate(\n token: string,\n options?: { fingerprintHash?: string; aiProvider?: string; action?: string },\n ): Promise<ValidationResult> {\n try {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/validate\", {\n token,\n fingerprint_hash: options?.fingerprintHash,\n ai_provider: options?.aiProvider,\n action: options?.action,\n });\n return {\n valid: true,\n sessionType: content.session_type,\n endUserId: content.end_user_id,\n delegation: content.delegation\n ? {\n delegationId: content.delegation.delegation_id,\n bindingMode: content.delegation.binding_mode,\n expiresAt: content.delegation.expires_at,\n useCount: content.delegation.use_count,\n }\n : undefined,\n };\n } catch (err) {\n return { valid: false, error: err instanceof Error ? err.message : \"Validation failed\" };\n }\n }\n\n /** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */\n async revoke(delegationId: string, reason?: string): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}/revoke`,\n { reason },\n );\n }\n\n /** List delegations, optionally filtered by user. GET /v1/ai/delegations. */\n async list(userId?: string): Promise<DelegationInfo[]> {\n const path = userId\n ? `/v1/ai/delegations?end_user_id=${encodeURIComponent(userId)}`\n : \"/v1/ai/delegations\";\n const content = await apiRequest<any>(this.cfg, \"GET\", path);\n return (content.delegations || []).map(mapDelegation);\n }\n\n /** Get a single delegation. GET /v1/ai/delegations/{id}. */\n async get(delegationId: string): Promise<DelegationInfo> {\n const content = await apiRequest<any>(\n this.cfg,\n \"GET\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}`,\n );\n return mapDelegation(content.delegation);\n }\n\n /** Get delegation statistics. GET /v1/ai/stats. */\n async stats(): Promise<DelegationStats> {\n const content = await apiRequest<any>(this.cfg, \"GET\", \"/v1/ai/stats\");\n const s = content.stats;\n return {\n totalDelegations: s.total_delegations,\n activeDelegations: s.active_delegations,\n totalUses: s.total_uses,\n delegationsByBinding: {\n verifiedDevice: s.delegations_by_binding.verified_device,\n anyLocation: s.delegations_by_binding.any_location,\n },\n };\n }\n\n /** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */\n async revokeAllForUser(userId: string, reason?: string): Promise<number> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/revoke-all\", {\n end_user_id: userId,\n reason,\n });\n return content.revoked_count;\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { WebhookVerificationError } from \"./errors.js\";\n\nexport interface VerifyOptions {\n /** Reject signatures whose timestamp is older than this many seconds (default 300). 0 disables. */\n toleranceSec?: number;\n}\n\nfunction parseHeader(header: string): { t: string; v1: string } | null {\n // Format: \"t=<unix-seconds>,v1=<hex-hmac>\"\n const parts = header.split(\",\").map((p) => p.trim());\n let t = \"\";\n let v1 = \"\";\n for (const part of parts) {\n const [k, v] = part.split(\"=\");\n if (k === \"t\") t = v;\n if (k === \"v1\") v1 = v;\n }\n return t && v1 ? { t, v1 } : null;\n}\n\nfunction expectedSignature(timestamp: string, payload: string, secret: string): string {\n return createHmac(\"sha256\", secret).update(`${timestamp}.${payload}`).digest(\"hex\");\n}\n\nfunction safeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n try {\n return timingSafeEqual(Buffer.from(a, \"hex\"), Buffer.from(b, \"hex\"));\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a Simplr webhook signature.\n *\n * @param payload The RAW request body string (do not re-serialize parsed JSON).\n * @param header The `X-Simplr-Signature` header value (`t=…,v1=…`).\n * @param secret The webhook's signing secret.\n * @returns true if the signature is valid and within the tolerance window.\n */\nexport function verify(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): boolean {\n const tolerance = options.toleranceSec ?? 300;\n const parsed = parseHeader(header || \"\");\n if (!parsed) return false;\n\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n const expected = expectedSignature(parsed.t, body, secret);\n if (!safeEqualHex(parsed.v1, expected)) return false;\n\n if (tolerance > 0) {\n const ts = Number(parsed.t);\n if (!Number.isFinite(ts)) return false;\n const ageSec = Math.abs(Date.now() / 1000 - ts);\n if (ageSec > tolerance) return false;\n }\n return true;\n}\n\n/**\n * Verify the signature and return the parsed event object.\n * Throws {@link WebhookVerificationError} if verification fails.\n */\nexport function constructEvent<T = { event: string; data: unknown }>(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): T {\n if (!verify(payload, header, secret, options)) {\n throw new WebhookVerificationError(\"Webhook signature verification failed\");\n }\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n return JSON.parse(body) as T;\n}\n\nexport const webhooks = { verify, constructEvent };\n","import { apiRequest, type HttpConfig } from \"./http.js\";\n\nexport interface SimplrAdminOptions {\n /** Portal token (JWT) for dashboard/admin operations. */\n token: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n}\n\nfunction qs(params: Record<string, unknown>): string {\n const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);\n if (!entries.length) return \"\";\n return \"?\" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join(\"&\");\n}\n\n/** Usage / measurement reads. */\nclass UsageApi {\n constructor(private readonly cfg: HttpConfig) {}\n /** Aggregate usage stats for an org. */\n stats(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/stats${qs({ org_id: orgId })}`);\n }\n /** Raw usage logs for an org. */\n logs(orgId: string, params: { page?: number; limit?: number } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/logs${qs({ org_id: orgId, ...params })}`);\n }\n /** Billing usage breakdown (per-service totals + estimated cost). */\n billing(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/billing/usage${qs({ org_id: orgId })}`);\n }\n}\n\n/** Feature-flag administration (create/update/delete/history). */\nclass FlagsAdminApi {\n constructor(private readonly cfg: HttpConfig) {}\n list(orgId: string, environment?: \"live\" | \"test\") {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags${qs({ org_id: orgId, environment })}`);\n }\n get(orgId: string, id: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n create(orgId: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"POST\", \"/v1/feature-flags\", { org_id: orgId, ...data });\n }\n update(orgId: string, id: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"PATCH\", `/v1/feature-flags/${id}`, { org_id: orgId, ...data });\n }\n remove(orgId: string, id: string) {\n return apiRequest(this.cfg, \"DELETE\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n history(orgId: string, id: string, params: { limit?: number; offset?: number } = {}) {\n return apiRequest(\n this.cfg,\n \"GET\",\n `/v1/feature-flags/${id}/history${qs({ org_id: orgId, ...params })}`,\n );\n }\n}\n\n/** RUM analytics reads. */\nclass RumApi {\n constructor(private readonly cfg: HttpConfig) {}\n overview(orgId: string, params: { application_id?: string; start_date?: string; end_date?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/overview${qs({ org_id: orgId, ...params })}`);\n }\n sessions(orgId: string, params: { page?: number; limit?: number; user_id?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/sessions${qs({ org_id: orgId, ...params })}`);\n }\n}\n\n/**\n * Management client for dashboard/admin operations that require a portal token\n * (usage/measurement, feature-flag CRUD, RUM analytics).\n *\n * ```ts\n * const admin = new SimplrAdmin({ token: process.env.SIMPLR_PORTAL_TOKEN! });\n * const usage = await admin.usage.billing(orgId);\n * await admin.flags.create(orgId, { key: \"new-checkout\", environment: \"test\", rollout_percentage: 10 });\n * ```\n */\nexport class SimplrAdmin {\n readonly usage: UsageApi;\n readonly flags: FlagsAdminApi;\n readonly rum: RumApi;\n\n constructor(options: SimplrAdminOptions) {\n if (!options?.token) throw new Error(\"SimplrAdmin: `token` is required\");\n const cfg: HttpConfig = {\n authHeaders: { Authorization: `Bearer ${options.token}` },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n };\n if (typeof cfg.fetchImpl !== \"function\") {\n throw new Error(\"SimplrAdmin: no global fetch available — use Node 18+ or pass `fetch`\");\n }\n this.usage = new UsageApi(cfg);\n this.flags = new FlagsAdminApi(cfg);\n this.rum = new RumApi(cfg);\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport { NetworkLogShipper } from \"./network-shipper.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\nimport { EdgeResource, OrdersResource, PhoneResource } from \"./resources.js\";\nimport { SimplrFlags } from \"./flags.js\";\nimport { SimplrProfiles } from \"./profiles.js\";\nimport { SimplrRUM } from \"./rum.js\";\nimport { SimplrAI } from \"./ai.js\";\nimport * as webhooks from \"./webhooks.js\";\nimport type { BulkResult, CheckInput, CheckResult, SimplrOptions } from \"./types.js\";\n\nexport { SimplrError, WebhookVerificationError } from \"./errors.js\";\nexport * from \"./types.js\";\nexport type {\n NetworkLogEntry,\n NetworkLogger,\n NetworkSource,\n} from \"./network-log.js\";\nexport { NetworkLogShipper } from \"./network-shipper.js\";\nexport type { ShipperConfig } from \"./network-shipper.js\";\nexport { verify as verifyWebhook, constructEvent as constructWebhookEvent } from \"./webhooks.js\";\nexport { SimplrFlags } from \"./flags.js\";\nexport type { FlagDefinition, FlagRule, FlagsOptions, EvalContext } from \"./flags.js\";\nexport { SimplrAdmin } from \"./admin.js\";\nexport type { SimplrAdminOptions } from \"./admin.js\";\nexport { SimplrProfiles } from \"./profiles.js\";\nexport { SimplrRUM } from \"./rum.js\";\nexport type { SimplrRUMConfig } from \"./rum.js\";\nexport { SimplrAI } from \"./ai.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.simplr.sh\";\n\n/**\n * Simplr server-side client.\n *\n * ```ts\n * import { Simplr } from \"@simplr-ai/node\";\n * const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! });\n * const result = await simplr.check({ email: \"user@example.com\", event_type: \"signup\" });\n * ```\n */\nexport class Simplr {\n private readonly cfg: HttpConfig;\n\n readonly orders: OrdersResource;\n readonly phone: PhoneResource;\n readonly edge: EdgeResource;\n /** Anonymous user profiles + order fraud monitoring. */\n readonly profiles: SimplrProfiles;\n /** Real User Monitoring — batched events to /v1/rum/events. */\n readonly rum: SimplrRUM;\n /** AI delegation — OAuth-like AI authentication. */\n readonly ai: SimplrAI;\n /** Webhook signature helpers (no network). */\n readonly webhooks = webhooks;\n\n private readonly _flags?: SimplrFlags;\n private readonly shipper?: NetworkLogShipper;\n\n constructor(options: SimplrOptions) {\n if (!options?.apiKey) throw new Error(\"Simplr: `apiKey` is required\");\n const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (options.shipNetworkLogs) {\n this.shipper = new NetworkLogShipper({\n baseUrl,\n apiKey: options.apiKey,\n fetchImpl,\n sdk: \"node\",\n applicationId: options.applicationId,\n environment: options.environment,\n });\n this.shipper.start();\n }\n\n const onNetworkLog: NetworkLogger | undefined =\n this.shipper || options.onNetworkLog\n ? (entry) => {\n this.shipper?.add(entry);\n options.onNetworkLog?.(entry);\n }\n : undefined;\n\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.apiKey },\n baseUrl,\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl,\n onNetworkLog,\n logBodies: options.logBodies ?? options.shipNetworkLogs,\n redactFields: options.redactFields,\n };\n if (typeof this.cfg.fetchImpl !== \"function\") {\n throw new Error(\"Simplr: no global fetch available — use Node 18+ or pass `fetch` in options\");\n }\n this.orders = new OrdersResource(this.cfg);\n this.phone = new PhoneResource(this.cfg);\n this.edge = new EdgeResource(this.cfg);\n this.profiles = new SimplrProfiles(this.cfg);\n this.rum = new SimplrRUM(this.cfg);\n this.ai = new SimplrAI(this.cfg);\n if (options.publicKey) {\n this._flags = new SimplrFlags({\n publicKey: options.publicKey,\n environment: options.environment,\n baseUrl: this.cfg.baseUrl,\n timeoutMs: this.cfg.timeoutMs,\n fetch: this.cfg.fetchImpl,\n onNetworkLog: this.cfg.onNetworkLog,\n logBodies: this.cfg.logBodies,\n redactFields: options.redactFields,\n });\n }\n }\n\n /**\n * Server-side feature flags. Requires a `publicKey` in the constructor options\n * (flag config is read with the public key). Call `simplr.flags.initialize()` once.\n */\n get flags(): SimplrFlags {\n if (!this._flags) {\n throw new Error(\n \"Simplr.flags requires a `publicKey` — pass it to `new Simplr({ apiKey, publicKey })`.\",\n );\n }\n return this._flags;\n }\n\n /** Run an identity/fraud check. Provide any of email, phone, device, behavior. */\n check(input: CheckInput): Promise<CheckResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check\", input);\n }\n\n /** Run up to 100 checks at once. */\n checkBulk(items: CheckInput[]): Promise<BulkResult<CheckResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/bulk\", { items });\n }\n\n flushNetworkLogs(): Promise<void> {\n return this.shipper?.flush() ?? Promise.resolve();\n }\n\n close(): void {\n this.shipper?.stop();\n this._flags?.dispose();\n }\n}\n\nexport default Simplr;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/network-log.ts","../src/http.ts","../src/network-shipper.ts","../src/resources.ts","../src/flags.ts","../src/profiles.ts","../src/rum.ts","../src/ai.ts","../src/webhooks.ts","../src/admin.ts","../src/index.ts"],"sourcesContent":["/** Thrown when the Simplr API returns a non-2xx response. */\nexport class SimplrError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"SimplrError\";\n this.status = status;\n this.body = body;\n }\n}\n\n/** Thrown when a webhook signature fails verification. */\nexport class WebhookVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WebhookVerificationError\";\n }\n}\n","export type NetworkSource = \"frontend\" | \"backend\";\n\nexport interface NetworkLogEntry {\n id: string;\n source: NetworkSource;\n timestamp: string;\n sdk?: string;\n applicationId?: string;\n environment?: string;\n method: string;\n url: string;\n requestHeaders?: Record<string, string>;\n requestBody?: unknown;\n status?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: unknown;\n durationMs?: number;\n ok?: boolean;\n error?: string;\n}\n\nexport type NetworkLogger = (entry: NetworkLogEntry) => void;\n\nconst SENSITIVE_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n \"x-auth-token\",\n \"x-csrf-token\",\n \"x-xsrf-token\",\n]);\n\nconst SENSITIVE_KEY_PARTS = [\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n \"api_key\",\n \"apikey\",\n \"authorization\",\n \"auth\",\n \"credential\",\n \"private_key\",\n \"card\",\n \"cardnumber\",\n \"pan\",\n \"cvv\",\n \"cvc\",\n \"ssn\",\n \"pin\",\n \"otp\",\n];\n\nconst MAX_REDACT_DEPTH = 8;\n\nexport const MAX_BODY_CHARS = 10_000;\n\nfunction isSensitiveKey(key: string, extraKeys: string[]): boolean {\n const lower = key.toLowerCase();\n if (extraKeys.some((k) => lower === k.toLowerCase())) return true;\n return SENSITIVE_KEY_PARTS.some((part) => lower.includes(part));\n}\n\nfunction redactDeep(value: unknown, extraKeys: string[], depth = 0): unknown {\n if (depth >= MAX_REDACT_DEPTH) return \"[truncated]\";\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, extraKeys, depth + 1));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSensitiveKey(key, extraKeys)\n ? \"[REDACTED]\"\n : redactDeep(val, extraKeys, depth + 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactHeaders(\n headers: Record<string, string> | Headers | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n const out: Record<string, string> = {};\n const set = (key: string, value: string) => {\n out[key] = SENSITIVE_HEADERS.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n };\n if (typeof (headers as Headers).forEach === \"function\" && !Array.isArray(headers)) {\n (headers as Headers).forEach((value, key) => set(key, value));\n } else {\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n set(key, String(value));\n }\n }\n return out;\n}\n\nexport function previewBody(raw: unknown, redactFields: string[] = []): unknown {\n if (raw === undefined || raw === null) return undefined;\n let value: unknown = raw;\n if (typeof raw === \"string\") {\n try {\n value = JSON.parse(raw);\n } catch {\n return raw.length > MAX_BODY_CHARS ? raw.slice(0, MAX_BODY_CHARS) + \"…[truncated]\" : raw;\n }\n }\n const redacted = redactDeep(value, redactFields);\n let text: string;\n try {\n text = JSON.stringify(redacted);\n } catch {\n return \"[unserializable]\";\n }\n if (text.length > MAX_BODY_CHARS) {\n return text.slice(0, MAX_BODY_CHARS) + \"…[truncated]\";\n }\n return redacted;\n}\n\nexport function newLogId(): string {\n const uuid = (globalThis as any)?.crypto?.randomUUID;\n if (typeof uuid === \"function\") return uuid.call((globalThis as any).crypto);\n return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n","import { SimplrError } from \"./errors.js\";\nimport {\n newLogId,\n previewBody,\n redactHeaders,\n type NetworkLogger,\n} from \"./network-log.js\";\n\nexport interface HttpConfig {\n authHeaders: Record<string, string>;\n baseUrl: string;\n timeoutMs: number;\n fetchImpl: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport async function apiRequest<T>(\n cfg: HttpConfig,\n method: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);\n\n const url = `${cfg.baseUrl}${path}`;\n const requestHeaders = {\n \"Content-Type\": \"application/json\",\n ...cfg.authHeaders,\n };\n const startedAt = Date.now();\n const log = cfg.onNetworkLog\n ? {\n id: newLogId(),\n source: \"backend\" as const,\n timestamp: new Date(startedAt).toISOString(),\n method,\n url,\n requestHeaders: redactHeaders(requestHeaders),\n requestBody: cfg.logBodies ? previewBody(body, cfg.redactFields) : undefined,\n }\n : null;\n\n const emit = (extra: Record<string, unknown>) => {\n if (!log || !cfg.onNetworkLog) return;\n try {\n cfg.onNetworkLog({ ...log, durationMs: Date.now() - startedAt, ...extra });\n } catch {\n /* empty */\n }\n };\n\n try {\n const res = await cfg.fetchImpl(url, {\n method,\n headers: requestHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const text = await res.text();\n let parsed: any;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n emit({\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n responseHeaders: redactHeaders(res.headers),\n responseBody: cfg.logBodies ? previewBody(parsed ?? text, cfg.redactFields) : undefined,\n });\n\n if (!res.ok) {\n const message =\n (parsed && (parsed.message || parsed.error)) || `Simplr API error ${res.status}`;\n throw new SimplrError(message, res.status, parsed);\n }\n\n return (parsed && typeof parsed === \"object\" && \"content\" in parsed\n ? parsed.content\n : parsed) as T;\n } catch (err) {\n if (err instanceof SimplrError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n emit({ ok: false, error: `timed out after ${cfg.timeoutMs}ms` });\n throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);\n }\n emit({ ok: false, error: err instanceof Error ? err.message : \"Network error\" });\n throw new SimplrError(err instanceof Error ? err.message : \"Network error\", 0, null);\n } finally {\n clearTimeout(timer);\n }\n}\n","import type { NetworkLogEntry } from \"./network-log.js\";\n\nexport interface ShipperConfig {\n baseUrl: string;\n apiKey: string;\n fetchImpl: typeof fetch;\n sdk: string;\n applicationId?: string;\n environment?: string;\n batchSize?: number;\n flushIntervalMs?: number;\n}\n\nconst DEFAULT_BATCH = 25;\nconst DEFAULT_FLUSH_MS = 5000;\n\nexport class NetworkLogShipper {\n private readonly cfg: ShipperConfig;\n private queue: NetworkLogEntry[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cfg: ShipperConfig) {\n this.cfg = cfg;\n }\n\n start(): void {\n if (this.timer) return;\n const interval = this.cfg.flushIntervalMs ?? DEFAULT_FLUSH_MS;\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n\n add(entry: NetworkLogEntry): void {\n this.queue.push({\n ...entry,\n sdk: this.cfg.sdk,\n applicationId: entry.applicationId ?? this.cfg.applicationId,\n environment: entry.environment ?? this.cfg.environment,\n });\n if (this.queue.length >= (this.cfg.batchSize ?? DEFAULT_BATCH)) {\n void this.flush();\n }\n }\n\n async flush(): Promise<void> {\n if (this.queue.length === 0) return;\n const logs = this.queue;\n this.queue = [];\n try {\n await this.cfg.fetchImpl(`${this.cfg.baseUrl}/v1/network-logs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.cfg.apiKey,\n },\n body: JSON.stringify({ logs }),\n });\n } catch {\n /* empty */\n }\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n void this.flush();\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n BulkResult,\n EdgeLogEntry,\n OrderInput,\n OrderResult,\n PhoneReportInput,\n} from \"./types.js\";\n\n/** Order fraud scoring. */\nexport class OrdersResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Submit a single order for fraud scoring. */\n submit(order: OrderInput): Promise<OrderResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Submit up to 100 orders at once. */\n submitBulk(orders: OrderInput[]): Promise<BulkResult<OrderResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders/bulk\", { orders });\n }\n}\n\n/** Phone intelligence + outcome reporting. */\nexport class PhoneResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Report the real-world outcome for a phone number to improve scoring. */\n report(input: PhoneReportInput): Promise<{ success: boolean }> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/phone/report\", input);\n }\n\n /** Fetch stored risk intelligence for a phone number. */\n intelligence(phone: string): Promise<Record<string, unknown>> {\n return apiRequest(this.cfg, \"GET\", `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`);\n }\n}\n\n/** Edge device registration + log ingestion. */\nexport class EdgeResource {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Register an edge device. */\n registerDevice(input: { device_id: string; name?: string; firmware?: string; [k: string]: unknown }) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/devices/register\", input);\n }\n\n /** Report a device heartbeat with health metrics. */\n heartbeat(deviceId: string, metrics: Record<string, unknown>) {\n return apiRequest(\n this.cfg,\n \"POST\",\n `/v1/edge/devices/${encodeURIComponent(deviceId)}/heartbeat`,\n metrics,\n );\n }\n\n /** Batch-ingest structured logs for a device. */\n ingestLogs(deviceId: string, logs: EdgeLogEntry[]) {\n return apiRequest(this.cfg, \"POST\", \"/v1/edge/logs\", { device_id: deviceId, logs });\n }\n}\n","import { type HttpConfig } from \"./http.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\n\n/**\n * MurmurHash3 (x86, 32-bit) — identical to the browser SDK so a given user\n * buckets the same way on the client and the server.\n */\nfunction murmurHash3(input: string, seed = 0): number {\n let h1 = seed;\n const c1 = 0xcc9e2d51;\n const c2 = 0x1b873593;\n for (let i = 0; i < input.length; i++) {\n let k1 = input.charCodeAt(i);\n k1 = Math.imul(k1, c1);\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = Math.imul(k1, c2);\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1 = Math.imul(h1, 5) + 0xe6546b64;\n }\n h1 ^= input.length;\n h1 ^= h1 >>> 16;\n h1 = Math.imul(h1, 0x85ebca6b);\n h1 ^= h1 >>> 13;\n h1 = Math.imul(h1, 0xc2b2ae35);\n h1 ^= h1 >>> 16;\n return h1 >>> 0;\n}\n\nexport interface FlagRule {\n attribute: string;\n op: \"eq\" | \"neq\" | \"contains\";\n value: string;\n}\n\nexport interface FlagDefinition {\n key: string;\n enabled: boolean;\n rollout_percentage: number;\n target_user_ids: string[];\n rules: FlagRule[];\n}\n\nexport interface FlagsOptions {\n /** Public API key (pk_live_… / pk_test_…). Required — flags read uses the public key. */\n publicKey: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n /**\n * Which environment's flags to load. Defaults to the key's own environment\n * (the API falls back to the key's live/test mode when unset). Accepts a\n * named environment slug (e.g. \"dev\", \"uat\", \"prod\") as well as the legacy\n * \"live\"/\"test\" key modes. Sent to the API as `?environment=<value>`.\n */\n environment?: string;\n /** Auto-refresh interval in ms (default 60000; 0 disables). */\n refreshIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n onNetworkLog?: NetworkLogger;\n logBodies?: boolean;\n redactFields?: string[];\n}\n\nexport interface EvalContext {\n userId?: string;\n attributes?: Record<string, unknown>;\n}\n\nfunction matchRule(rule: FlagRule, attributes: Record<string, unknown>): boolean {\n const actual = attributes[rule.attribute];\n switch (rule.op) {\n case \"eq\":\n return String(actual) === rule.value;\n case \"neq\":\n return String(actual) !== rule.value;\n case \"contains\":\n return String(actual ?? \"\").includes(rule.value);\n default:\n return false;\n }\n}\n\n/**\n * Server-side feature flags with local, deterministic evaluation.\n *\n * ```ts\n * const flags = new SimplrFlags({ publicKey: process.env.SIMPLR_PUBLIC_KEY! });\n * await flags.initialize();\n * if (flags.isEnabled(\"new-checkout\", { userId: \"user_123\" })) { ... }\n * ```\n */\nexport class SimplrFlags {\n private readonly cfg: HttpConfig;\n private readonly environment?: string;\n private readonly refreshIntervalMs: number;\n private flags: Record<string, FlagDefinition> = {};\n private defaultUserId?: string;\n private timer: ReturnType<typeof setInterval> | null = null;\n private ready = false;\n private etag: string | null = null;\n\n constructor(options: FlagsOptions) {\n if (!options?.publicKey) throw new Error(\"SimplrFlags: `publicKey` is required\");\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.publicKey },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n onNetworkLog: options.onNetworkLog,\n logBodies: options.logBodies,\n redactFields: options.redactFields,\n };\n this.environment = options.environment;\n const requested = options.refreshIntervalMs ?? 60000;\n this.refreshIntervalMs = requested > 0 ? Math.max(requested, 30000) : 0;\n }\n\n /** Fetch the flag config once and start the background refresh. */\n async initialize(): Promise<void> {\n await this.refresh();\n this.ready = true;\n if (this.refreshIntervalMs > 0) {\n this.timer = setInterval(() => {\n void this.refresh();\n }, this.refreshIntervalMs);\n // Don't keep the process alive just for flag refreshes.\n (this.timer as any)?.unref?.();\n }\n }\n\n /** Set the default identifier used for bucketing when none is passed to isEnabled. */\n setUser(userId: string): void {\n this.defaultUserId = userId;\n }\n\n async refresh(): Promise<void> {\n const path = this.environment\n ? `/v1/flags?environment=${encodeURIComponent(this.environment)}`\n : \"/v1/flags\";\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.cfg.timeoutMs);\n try {\n const headers: Record<string, string> = { ...this.cfg.authHeaders };\n if (this.etag) headers[\"If-None-Match\"] = this.etag;\n const res = await this.cfg.fetchImpl(`${this.cfg.baseUrl}${path}`, { headers, signal: controller.signal });\n if (res.status === 304) return;\n if (!res.ok) return;\n const responseEtag = res.headers?.get?.(\"etag\");\n if (responseEtag) this.etag = responseEtag;\n const text = await res.text();\n const json: any = text ? JSON.parse(text) : {};\n const list: FlagDefinition[] = json?.content?.flags || [];\n const map: Record<string, FlagDefinition> = {};\n for (const f of list) map[f.key] = f;\n this.flags = map;\n } catch {\n /* empty */\n } finally {\n clearTimeout(timer);\n }\n }\n\n /** Evaluate a flag locally. Deterministic per user; no network call. */\n isEnabled(key: string, ctx: EvalContext = {}): boolean {\n const f = this.flags[key];\n if (!f || !f.enabled) return false;\n\n const uid = ctx.userId || this.defaultUserId || \"anonymous\";\n if (f.target_user_ids?.includes(uid)) return true;\n if (ctx.attributes && f.rules?.length && f.rules.some((r) => matchRule(r, ctx.attributes!))) {\n return true;\n }\n if (f.rollout_percentage >= 100) return true;\n if (f.rollout_percentage <= 0) return false;\n return murmurHash3(`${key}:${uid}`) % 100 < f.rollout_percentage;\n }\n\n getAll(): Record<string, FlagDefinition> {\n return { ...this.flags };\n }\n\n isReady(): boolean {\n return this.ready;\n }\n\n /** Stop the background refresh timer. */\n dispose(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n IdentifyOptions,\n OrderInput,\n OrderResult,\n ProfileResult,\n ProfileRiskResult,\n} from \"./types.js\";\n\n/**\n * Anonymous user profile management and order fraud monitoring.\n *\n * Works with the configured key (secret for server-side use). Mirrors the\n * browser SimplrProfiles surface but reuses the Node http helper (which unwraps\n * the `{ success, message, content }` envelope).\n */\nexport class SimplrProfiles {\n constructor(private readonly cfg: HttpConfig) {}\n\n /**\n * Identify a user — creates or updates an anonymous profile and (optionally)\n * links a device fingerprint. POST /v1/profiles.\n */\n identify(externalId: string, options?: IdentifyOptions): Promise<ProfileResult> {\n const { profileType, fingerprintHash, ...rest } = options ?? {};\n const body: Record<string, unknown> = {\n external_id: externalId,\n profile_type: profileType || \"customer\",\n ...rest,\n };\n if (fingerprintHash) body.fingerprint_hash = fingerprintHash;\n return apiRequest<ProfileResult>(this.cfg, \"POST\", \"/v1/profiles\", body);\n }\n\n /** Submit an order for real-time fraud scoring. POST /v1/orders. */\n submitOrder(order: OrderInput): Promise<OrderResult> {\n return apiRequest<OrderResult>(this.cfg, \"POST\", \"/v1/orders\", order);\n }\n\n /** Get the risk profile for a user. GET /v1/profiles/{externalId}. */\n getProfileRisk(externalId: string): Promise<ProfileRiskResult> {\n return apiRequest<ProfileRiskResult>(\n this.cfg,\n \"GET\",\n `/v1/profiles/${encodeURIComponent(externalId)}`,\n );\n }\n\n /** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */\n async reportOutcome(externalId: string, outcome: \"fraud\" | \"legitimate\"): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/profiles/${encodeURIComponent(externalId)}/outcome`,\n { outcome },\n );\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type { RUMEvent, RUMEventType, RUMLogLevel } from \"./types.js\";\n\nexport interface SimplrRUMConfig {\n /** Application identifier (required). */\n applicationId: string;\n /** Optional version/environment tags applied to every event. */\n applicationVersion?: string;\n environment?: string;\n /** Flush when this many events are queued (default 30). */\n batchSize?: number;\n /** Background flush interval in ms (default 10000; 0 disables the timer). */\n flushInterval?: number;\n /** Override the events endpoint path (default /v1/rum/events). */\n endpoint?: string;\n}\n\nconst DEFAULT_BATCH_SIZE = 30;\nconst DEFAULT_FLUSH_INTERVAL = 10000;\nconst DEFAULT_ENDPOINT = \"/v1/rum/events\";\n\nfunction genId(): string {\n return (\n Date.now().toString(36) + Math.random().toString(36).slice(2, 10)\n );\n}\n\n/**\n * Server-side Real User Monitoring. Batches events and flushes them to\n * POST /v1/rum/events using the configured key. Unlike the browser SDK there is\n * no DOM auto-capture — views/actions/errors/logs are reported via the public\n * API. A timer-based flush is installed with `unref()` so it never keeps the\n * Node process alive.\n */\nexport class SimplrRUM {\n private config: SimplrRUMConfig | null = null;\n private initialized = false;\n private queue: RUMEvent[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n\n private sessionId: string | null = null;\n private currentViewId: string | null = null;\n private userId?: string;\n private userAttributes?: Record<string, unknown>;\n private globalAttributes: Record<string, unknown> = {};\n private batchSize = DEFAULT_BATCH_SIZE;\n private endpoint = DEFAULT_ENDPOINT;\n\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Initialize the SDK, start a session, and begin the flush timer. */\n initialize(config: SimplrRUMConfig): void {\n if (this.initialized) return;\n this.config = config;\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;\n this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n this.sessionId = genId();\n this.initialized = true;\n\n this.trackEvent(\"session_start\");\n\n const interval = config.flushInterval ?? DEFAULT_FLUSH_INTERVAL;\n if (interval > 0) {\n this.timer = setInterval(() => {\n void this.flush();\n }, interval);\n (this.timer as any)?.unref?.();\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /** Associate subsequent events with a user. */\n setUser(userId: string, attributes?: Record<string, unknown>): void {\n this.userId = userId;\n this.userAttributes = attributes;\n }\n\n clearUser(): void {\n this.userId = undefined;\n this.userAttributes = undefined;\n }\n\n addAttribute(key: string, value: unknown): void {\n this.globalAttributes[key] = value;\n }\n\n removeAttribute(key: string): void {\n delete this.globalAttributes[key];\n }\n\n /** Track a screen/page view. */\n trackView(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.currentViewId = genId();\n this.trackEvent(\"view\", {\n view: { id: this.currentViewId, name },\n attributes,\n });\n }\n\n /** Track a user action. */\n trackAction(name: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"action\", { action: { name, type: \"custom\" }, attributes });\n }\n\n /** Track an error. */\n trackError(error: Error | { message: string; stack?: string; type?: string }, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n const data =\n error instanceof Error\n ? { message: error.message, stack: error.stack, type: error.constructor.name }\n : error;\n this.trackEvent(\"error\", { error: data, attributes });\n }\n\n /** Emit a log line. */\n log(level: RUMLogLevel, message: string, attributes?: Record<string, unknown>): void {\n if (!this.initialized) return;\n this.trackEvent(\"log\", { log: { level, message }, attributes });\n }\n\n private trackEvent(type: RUMEventType, data?: Partial<RUMEvent>): void {\n if (!this.initialized || !this.sessionId) return;\n const event: RUMEvent = {\n type,\n timestamp: Date.now(),\n sessionId: this.sessionId,\n viewId: this.currentViewId || undefined,\n userId: this.userId,\n applicationId: this.config!.applicationId,\n applicationVersion: this.config?.applicationVersion,\n environment: this.config?.environment,\n userAttributes: this.userAttributes,\n globalAttributes:\n Object.keys(this.globalAttributes).length > 0 ? this.globalAttributes : undefined,\n ...data,\n };\n this.queue.push(event);\n if (this.queue.length >= this.batchSize) void this.flush();\n }\n\n /** Flush queued events to POST /v1/rum/events. */\n async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n const events = this.queue;\n this.queue = [];\n try {\n await apiRequest(this.cfg, \"POST\", this.endpoint, {\n events,\n sentAt: Date.now(),\n });\n } catch {\n // Re-queue on failure so events aren't lost.\n this.queue = [...events, ...this.queue];\n } finally {\n this.flushing = false;\n }\n }\n\n /** End the session, flush remaining events, and stop the timer. */\n async stopSession(): Promise<void> {\n if (!this.initialized) return;\n this.trackEvent(\"session_end\");\n await this.flush();\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.initialized = false;\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getViewId(): string | null {\n return this.currentViewId;\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport type {\n CreateDelegationOptions,\n DelegationInfo,\n DelegationResult,\n DelegationStats,\n ValidationResult,\n} from \"./types.js\";\n\nfunction mapDelegation(d: any): DelegationInfo {\n return {\n delegationId: d.delegation_id,\n endUserId: d.end_user_id,\n bindingMode: d.binding_mode,\n status: d.status,\n expiresAt: d.expires_at,\n useCount: d.use_count,\n lastUsedAt: d.last_used_at,\n createdAt: d.created_at,\n };\n}\n\n/**\n * AI delegation — OAuth-like AI authentication. Lets you mint, validate and\n * revoke delegation tokens that an end user shares with their AI agent.\n *\n * Reuses the Node http helper, which unwraps the `{ success, message, content }`\n * envelope — so `apiRequest` returns the inner `content` object directly.\n */\nexport class SimplrAI {\n constructor(private readonly cfg: HttpConfig) {}\n\n /** Create a new AI delegation token for a user. POST /v1/ai/delegations. */\n async createDelegation(options: CreateDelegationOptions): Promise<DelegationResult> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/delegations\", {\n end_user_id: options.userId,\n end_user_email: options.email,\n binding: options.binding || \"any_location\",\n expires_in_days: options.expiresInDays || 7,\n session_id: options.sessionId,\n fingerprint_hash: options.fingerprintHash,\n });\n const d = content.delegation;\n return {\n token: d.token,\n delegationId: d.delegation_id,\n expiresAt: d.expires_at,\n bindingMode: d.binding_mode,\n };\n }\n\n /** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */\n async validate(\n token: string,\n options?: { fingerprintHash?: string; aiProvider?: string; action?: string },\n ): Promise<ValidationResult> {\n try {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/validate\", {\n token,\n fingerprint_hash: options?.fingerprintHash,\n ai_provider: options?.aiProvider,\n action: options?.action,\n });\n return {\n valid: true,\n sessionType: content.session_type,\n endUserId: content.end_user_id,\n delegation: content.delegation\n ? {\n delegationId: content.delegation.delegation_id,\n bindingMode: content.delegation.binding_mode,\n expiresAt: content.delegation.expires_at,\n useCount: content.delegation.use_count,\n }\n : undefined,\n };\n } catch (err) {\n return { valid: false, error: err instanceof Error ? err.message : \"Validation failed\" };\n }\n }\n\n /** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */\n async revoke(delegationId: string, reason?: string): Promise<void> {\n await apiRequest(\n this.cfg,\n \"POST\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}/revoke`,\n { reason },\n );\n }\n\n /** List delegations, optionally filtered by user. GET /v1/ai/delegations. */\n async list(userId?: string): Promise<DelegationInfo[]> {\n const path = userId\n ? `/v1/ai/delegations?end_user_id=${encodeURIComponent(userId)}`\n : \"/v1/ai/delegations\";\n const content = await apiRequest<any>(this.cfg, \"GET\", path);\n return (content.delegations || []).map(mapDelegation);\n }\n\n /** Get a single delegation. GET /v1/ai/delegations/{id}. */\n async get(delegationId: string): Promise<DelegationInfo> {\n const content = await apiRequest<any>(\n this.cfg,\n \"GET\",\n `/v1/ai/delegations/${encodeURIComponent(delegationId)}`,\n );\n return mapDelegation(content.delegation);\n }\n\n /** Get delegation statistics. GET /v1/ai/stats. */\n async stats(): Promise<DelegationStats> {\n const content = await apiRequest<any>(this.cfg, \"GET\", \"/v1/ai/stats\");\n const s = content.stats;\n return {\n totalDelegations: s.total_delegations,\n activeDelegations: s.active_delegations,\n totalUses: s.total_uses,\n delegationsByBinding: {\n verifiedDevice: s.delegations_by_binding.verified_device,\n anyLocation: s.delegations_by_binding.any_location,\n },\n };\n }\n\n /** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */\n async revokeAllForUser(userId: string, reason?: string): Promise<number> {\n const content = await apiRequest<any>(this.cfg, \"POST\", \"/v1/ai/revoke-all\", {\n end_user_id: userId,\n reason,\n });\n return content.revoked_count;\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { WebhookVerificationError } from \"./errors.js\";\n\nexport interface VerifyOptions {\n /** Reject signatures whose timestamp is older than this many seconds (default 300). 0 disables. */\n toleranceSec?: number;\n}\n\nfunction parseHeader(header: string): { t: string; v1: string } | null {\n // Format: \"t=<unix-seconds>,v1=<hex-hmac>\"\n const parts = header.split(\",\").map((p) => p.trim());\n let t = \"\";\n let v1 = \"\";\n for (const part of parts) {\n const [k, v] = part.split(\"=\");\n if (k === \"t\") t = v;\n if (k === \"v1\") v1 = v;\n }\n return t && v1 ? { t, v1 } : null;\n}\n\nfunction expectedSignature(timestamp: string, payload: string, secret: string): string {\n return createHmac(\"sha256\", secret).update(`${timestamp}.${payload}`).digest(\"hex\");\n}\n\nfunction safeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n try {\n return timingSafeEqual(Buffer.from(a, \"hex\"), Buffer.from(b, \"hex\"));\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a Simplr webhook signature.\n *\n * @param payload The RAW request body string (do not re-serialize parsed JSON).\n * @param header The `X-Simplr-Signature` header value (`t=…,v1=…`).\n * @param secret The webhook's signing secret.\n * @returns true if the signature is valid and within the tolerance window.\n */\nexport function verify(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): boolean {\n const tolerance = options.toleranceSec ?? 300;\n const parsed = parseHeader(header || \"\");\n if (!parsed) return false;\n\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n const expected = expectedSignature(parsed.t, body, secret);\n if (!safeEqualHex(parsed.v1, expected)) return false;\n\n if (tolerance > 0) {\n const ts = Number(parsed.t);\n if (!Number.isFinite(ts)) return false;\n const ageSec = Math.abs(Date.now() / 1000 - ts);\n if (ageSec > tolerance) return false;\n }\n return true;\n}\n\n/**\n * Verify the signature and return the parsed event object.\n * Throws {@link WebhookVerificationError} if verification fails.\n */\nexport function constructEvent<T = { event: string; data: unknown }>(\n payload: string | Buffer,\n header: string,\n secret: string,\n options: VerifyOptions = {},\n): T {\n if (!verify(payload, header, secret, options)) {\n throw new WebhookVerificationError(\"Webhook signature verification failed\");\n }\n const body = typeof payload === \"string\" ? payload : payload.toString(\"utf8\");\n return JSON.parse(body) as T;\n}\n\nexport const webhooks = { verify, constructEvent };\n","import { apiRequest, type HttpConfig } from \"./http.js\";\n\nexport interface SimplrAdminOptions {\n /** Portal token (JWT) for dashboard/admin operations. */\n token: string;\n /** API base URL. Defaults to https://api.simplr.sh. */\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n}\n\nfunction qs(params: Record<string, unknown>): string {\n const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);\n if (!entries.length) return \"\";\n return \"?\" + entries.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`).join(\"&\");\n}\n\n/** Usage / measurement reads. */\nclass UsageApi {\n constructor(private readonly cfg: HttpConfig) {}\n /** Aggregate usage stats for an org. */\n stats(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/stats${qs({ org_id: orgId })}`);\n }\n /** Raw usage logs for an org. */\n logs(orgId: string, params: { page?: number; limit?: number } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/usage/logs${qs({ org_id: orgId, ...params })}`);\n }\n /** Billing usage breakdown (per-service totals + estimated cost). */\n billing(orgId: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/billing/usage${qs({ org_id: orgId })}`);\n }\n}\n\n/** Feature-flag administration (create/update/delete/history). */\nclass FlagsAdminApi {\n constructor(private readonly cfg: HttpConfig) {}\n list(orgId: string, environment?: \"live\" | \"test\") {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags${qs({ org_id: orgId, environment })}`);\n }\n get(orgId: string, id: string) {\n return apiRequest(this.cfg, \"GET\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n create(orgId: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"POST\", \"/v1/feature-flags\", { org_id: orgId, ...data });\n }\n update(orgId: string, id: string, data: Record<string, unknown>) {\n return apiRequest(this.cfg, \"PATCH\", `/v1/feature-flags/${id}`, { org_id: orgId, ...data });\n }\n remove(orgId: string, id: string) {\n return apiRequest(this.cfg, \"DELETE\", `/v1/feature-flags/${id}${qs({ org_id: orgId })}`);\n }\n history(orgId: string, id: string, params: { limit?: number; offset?: number } = {}) {\n return apiRequest(\n this.cfg,\n \"GET\",\n `/v1/feature-flags/${id}/history${qs({ org_id: orgId, ...params })}`,\n );\n }\n}\n\n/** RUM analytics reads. */\nclass RumApi {\n constructor(private readonly cfg: HttpConfig) {}\n overview(orgId: string, params: { application_id?: string; start_date?: string; end_date?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/overview${qs({ org_id: orgId, ...params })}`);\n }\n sessions(orgId: string, params: { page?: number; limit?: number; user_id?: string } = {}) {\n return apiRequest(this.cfg, \"GET\", `/v1/rum/sessions${qs({ org_id: orgId, ...params })}`);\n }\n}\n\n/**\n * Management client for dashboard/admin operations that require a portal token\n * (usage/measurement, feature-flag CRUD, RUM analytics).\n *\n * ```ts\n * const admin = new SimplrAdmin({ token: process.env.SIMPLR_PORTAL_TOKEN! });\n * const usage = await admin.usage.billing(orgId);\n * await admin.flags.create(orgId, { key: \"new-checkout\", environment: \"test\", rollout_percentage: 10 });\n * ```\n */\nexport class SimplrAdmin {\n readonly usage: UsageApi;\n readonly flags: FlagsAdminApi;\n readonly rum: RumApi;\n\n constructor(options: SimplrAdminOptions) {\n if (!options?.token) throw new Error(\"SimplrAdmin: `token` is required\");\n const cfg: HttpConfig = {\n authHeaders: { Authorization: `Bearer ${options.token}` },\n baseUrl: (options.baseUrl || \"https://api.simplr.sh\").replace(/\\/+$/, \"\"),\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl: options.fetch ?? globalThis.fetch,\n };\n if (typeof cfg.fetchImpl !== \"function\") {\n throw new Error(\"SimplrAdmin: no global fetch available — use Node 18+ or pass `fetch`\");\n }\n this.usage = new UsageApi(cfg);\n this.flags = new FlagsAdminApi(cfg);\n this.rum = new RumApi(cfg);\n }\n}\n","import { apiRequest, type HttpConfig } from \"./http.js\";\nimport { NetworkLogShipper } from \"./network-shipper.js\";\nimport type { NetworkLogger } from \"./network-log.js\";\nimport { EdgeResource, OrdersResource, PhoneResource } from \"./resources.js\";\nimport { SimplrFlags } from \"./flags.js\";\nimport { SimplrProfiles } from \"./profiles.js\";\nimport { SimplrRUM } from \"./rum.js\";\nimport { SimplrAI } from \"./ai.js\";\nimport * as webhooks from \"./webhooks.js\";\nimport type { BulkResult, CheckInput, CheckResult, SimplrOptions } from \"./types.js\";\n\nexport { SimplrError, WebhookVerificationError } from \"./errors.js\";\nexport * from \"./types.js\";\nexport type {\n NetworkLogEntry,\n NetworkLogger,\n NetworkSource,\n} from \"./network-log.js\";\nexport { NetworkLogShipper } from \"./network-shipper.js\";\nexport type { ShipperConfig } from \"./network-shipper.js\";\nexport { verify as verifyWebhook, constructEvent as constructWebhookEvent } from \"./webhooks.js\";\nexport { SimplrFlags } from \"./flags.js\";\nexport type { FlagDefinition, FlagRule, FlagsOptions, EvalContext } from \"./flags.js\";\nexport { SimplrAdmin } from \"./admin.js\";\nexport type { SimplrAdminOptions } from \"./admin.js\";\nexport { SimplrProfiles } from \"./profiles.js\";\nexport { SimplrRUM } from \"./rum.js\";\nexport type { SimplrRUMConfig } from \"./rum.js\";\nexport { SimplrAI } from \"./ai.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.simplr.sh\";\n\n/**\n * Simplr server-side client.\n *\n * ```ts\n * import { Simplr } from \"@simplr-ai/node\";\n * const simplr = new Simplr({ apiKey: process.env.SIMPLR_API_KEY! });\n * const result = await simplr.check({ email: \"user@example.com\", event_type: \"signup\" });\n * ```\n */\nexport class Simplr {\n private readonly cfg: HttpConfig;\n\n readonly orders: OrdersResource;\n readonly phone: PhoneResource;\n readonly edge: EdgeResource;\n /** Anonymous user profiles + order fraud monitoring. */\n readonly profiles: SimplrProfiles;\n /** Real User Monitoring — batched events to /v1/rum/events. */\n readonly rum: SimplrRUM;\n /** AI delegation — OAuth-like AI authentication. */\n readonly ai: SimplrAI;\n /** Webhook signature helpers (no network). */\n readonly webhooks = webhooks;\n\n private readonly _flags?: SimplrFlags;\n private readonly shipper?: NetworkLogShipper;\n\n constructor(options: SimplrOptions) {\n if (!options?.apiKey) throw new Error(\"Simplr: `apiKey` is required\");\n const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const logSelf = !!options.logSelfCalls;\n\n if (options.shipNetworkLogs && logSelf) {\n this.shipper = new NetworkLogShipper({\n baseUrl,\n apiKey: options.apiKey,\n fetchImpl,\n sdk: \"node\",\n applicationId: options.applicationId,\n environment: options.environment,\n });\n this.shipper.start();\n }\n\n const onNetworkLog: NetworkLogger | undefined =\n this.shipper || options.onNetworkLog\n ? (entry) => {\n this.shipper?.add(entry);\n options.onNetworkLog?.(entry);\n }\n : undefined;\n\n this.cfg = {\n authHeaders: { \"X-API-Key\": options.apiKey },\n baseUrl,\n timeoutMs: options.timeoutMs ?? 15000,\n fetchImpl,\n onNetworkLog,\n logBodies: options.logBodies ?? (options.shipNetworkLogs && logSelf),\n redactFields: options.redactFields,\n };\n if (typeof this.cfg.fetchImpl !== \"function\") {\n throw new Error(\"Simplr: no global fetch available — use Node 18+ or pass `fetch` in options\");\n }\n this.orders = new OrdersResource(this.cfg);\n this.phone = new PhoneResource(this.cfg);\n this.edge = new EdgeResource(this.cfg);\n this.profiles = new SimplrProfiles(this.cfg);\n this.rum = new SimplrRUM(this.cfg);\n this.ai = new SimplrAI(this.cfg);\n if (options.publicKey) {\n this._flags = new SimplrFlags({\n publicKey: options.publicKey,\n environment: options.environment,\n baseUrl: this.cfg.baseUrl,\n timeoutMs: this.cfg.timeoutMs,\n fetch: this.cfg.fetchImpl,\n onNetworkLog: this.cfg.onNetworkLog,\n logBodies: this.cfg.logBodies,\n redactFields: options.redactFields,\n });\n }\n }\n\n /**\n * Server-side feature flags. Requires a `publicKey` in the constructor options\n * (flag config is read with the public key). Call `simplr.flags.initialize()` once.\n */\n get flags(): SimplrFlags {\n if (!this._flags) {\n throw new Error(\n \"Simplr.flags requires a `publicKey` — pass it to `new Simplr({ apiKey, publicKey })`.\",\n );\n }\n return this._flags;\n }\n\n /** Run an identity/fraud check. Provide any of email, phone, device, behavior. */\n check(input: CheckInput): Promise<CheckResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check\", input);\n }\n\n /** Run up to 100 checks at once. */\n checkBulk(items: CheckInput[]): Promise<BulkResult<CheckResult>> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/bulk\", { items });\n }\n\n flushNetworkLogs(): Promise<void> {\n return this.shipper?.flush() ?? Promise.resolve();\n }\n\n close(): void {\n this.shipper?.stop();\n this._flags?.dispose();\n }\n}\n\nexport default Simplr;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED