zubbl-sdk 1.1.30 → 1.1.31

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.
@@ -530,12 +530,17 @@ async function getTilesFeature(store, { external_user_id, app_id = null, ttlSeco
530
530
  ...adaptiveHeaders,
531
531
  ...geoHeaders,
532
532
  });
533
- if (cached?.etag)
534
- headers["If-None-Match"] = cached.etag;
535
- const params = new URLSearchParams({ external_user_id });
536
- params.set("app_id", app_id || config.appId);
537
- const url = `${config.baseUrl.replace(/\/$/, "")}/tiles/effective?${params.toString()}`;
538
- const resp = await httpRequest(url, { headers });
533
+ // Modern endpoint: POST /api/sdk/policies with body (per architecture docs)
534
+ const payload = {
535
+ tenant_id: config.tenantId,
536
+ app_id: app_id || config.appId,
537
+ external_user_id,
538
+ };
539
+ const resp = await httpRequest(`${config.baseUrl.replace(/\/$/, "")}/api/sdk/policies`, {
540
+ method: "POST",
541
+ headers,
542
+ body: JSON.stringify(payload),
543
+ });
539
544
  if (resp.status === 304 && cached?.data) {
540
545
  cached.expiresAt = Date.now() + ttlSeconds * 1000;
541
546
  storage.set(TILE_CACHE_KEY, cached, ttlSeconds);
@@ -1 +1 @@
1
- {"version":3,"file":"zubbl-sdk.cjs.js","sources":["../src/core/config.ts","../src/core/context.ts","../src/core/storage.ts","../src/core/geo.ts","../src/core/signing.ts","../src/core/http.ts","../src/features/identifyUser.ts","../src/features/getTiles.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["// src/core/config.ts\n// -----------------------------------------------------------\n// Universal environment detection + SDK configuration\n// -----------------------------------------------------------\n\nexport const isBrowser =\n typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nexport const isNode =\n typeof process !== \"undefined\" &&\n !!process.versions?.node &&\n !isBrowser;\n\nexport const isWorker =\n typeof self !== \"undefined\" &&\n typeof (self as any).importScripts === \"function\" &&\n !isNode;\n\n// -----------------------------------------------------------\n// Config store factory (no module-scoped state)\n// -----------------------------------------------------------\n\nexport interface ZubblConfig {\n apiKey: string | null;\n tenantId: string | null;\n appId: string | null;\n baseUrl: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n}\n\nfunction assertBrowserSafety(cfg: ZubblConfig) {\n if (isBrowser || isWorker) {\n const key = cfg.apiKey ?? \"\";\n const looksSecret = key.startsWith(\"sk_\") || key.length > 40;\n if (looksSecret) {\n throw new Error(\n \"[Zubbl SDK] Secret or server key detected in browser environment. \" +\n \"Use a public SDK key instead (prefix pk_).\"\n );\n }\n }\n}\n\n/**\n * Creates an isolated configuration store.\n * Each ZubblClient instance owns its own store.\n */\nexport function createConfigStore(initial?: Partial<ZubblConfig>) {\n let current: ZubblConfig = {\n apiKey: null,\n tenantId: null,\n appId: null,\n baseUrl: \"https://api.zubbl.com/api\",\n injectWorkerHeaders: false,\n workerSecret: null,\n ...initial,\n };\n\n function init(partial: Partial<ZubblConfig>) {\n current = { ...current, ...partial };\n assertBrowserSafety(current);\n }\n\n function get(): Readonly<ZubblConfig> {\n return current;\n }\n\n function buildHeaders(extra: Record<string, string> = {}): Record<string, string> {\n if (!current.tenantId || !current.appId) {\n throw new Error(\"[Zubbl SDK] Not initialized – call init() first.\");\n }\n\n const headers: Record<string, string> = {\n \"X-Tenant-Id\": current.tenantId,\n \"X-App-Id\": current.appId,\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n\n if (current.apiKey) {\n headers.Authorization = `Bearer ${current.apiKey}`;\n }\n\n return headers;\n}\n\n return { init, get, buildHeaders };\n}\n\n","// src/core/context.ts\n// -----------------------------------------------------------\n// Adaptive Context Engine — Geo + Stability Enrichment + Persistence\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\ninterface ContextSample {\n path: string;\n method: string;\n ts: number;\n status: number;\n latency: number;\n}\n\ninterface AdaptiveState {\n routes: ContextSample[];\n geo: string;\n stability: number;\n lastGeoChange: number;\n}\n\nconst MAX_HISTORY = 100;\nconst CACHE_KEY = \"zubbl-stability\";\n\nlet state: AdaptiveState = loadStability() ?? {\n routes: [],\n geo: \"unknown\",\n stability: 1.0,\n lastGeoChange: Date.now(),\n};\n\n// -----------------------------------------------------------\n// 💾 Persistence Helpers\n// -----------------------------------------------------------\nfunction loadStability(): AdaptiveState | null {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed.geo || !parsed.stability) return null;\n return { ...parsed, routes: [] };\n } catch {\n return null;\n }\n}\n\nfunction saveStability() {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n try {\n const payload = {\n geo: state.geo,\n stability: state.stability,\n lastGeoChange: state.lastGeoChange,\n };\n localStorage.setItem(CACHE_KEY, JSON.stringify(payload));\n } catch {\n /* ignore */\n }\n}\n\n// -----------------------------------------------------------\n// 🌍 Geo Detection (Node, Browser, Worker)\n// -----------------------------------------------------------\nexport function detectGeo(): string {\n try {\n if (isBrowser && typeof window !== \"undefined\" && window.navigator?.language) {\n return window.navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isWorker && typeof self !== \"undefined\" && (self as any).navigator?.language) {\n return (self as any).navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isNode && typeof process !== \"undefined\") {\n const envGeo = process.env.ZUBBL_GEO || process.env.GEO;\n if (envGeo && /^[A-Z]{2}$/i.test(envGeo)) return envGeo.toUpperCase();\n return \"GB\";\n }\n\n return \"unknown\";\n } catch (err) {\n console.warn(\"[Zubbl SDK][Geo Detect] Failed:\", err);\n return \"unknown\";\n }\n}\n\n// -----------------------------------------------------------\n// 🧭 Update Geo & Stability (with persistence)\n// -----------------------------------------------------------\nexport function updateGeo(geoHint?: string) {\n const newGeo = geoHint || detectGeo();\n if (newGeo !== state.geo) {\n const now = Date.now();\n const elapsed = (now - state.lastGeoChange) / 1000;\n state.stability = Math.max(0.5, Math.min(1.0, elapsed / 3600));\n state.geo = newGeo;\n state.lastGeoChange = now;\n saveStability();\n } else {\n state.stability = Math.min(1.0, state.stability + 0.01);\n saveStability();\n }\n}\n\n// -----------------------------------------------------------\n// 🧮 Record Context Samples\n// -----------------------------------------------------------\nexport function recordContextSample(\n path: string,\n method: string,\n status: number,\n latency: number\n) {\n state.routes.push({ path, method, ts: Date.now(), status, latency });\n if (state.routes.length > MAX_HISTORY) state.routes.shift();\n updateGeo(); // auto-refresh geo info\n}\n\n// -----------------------------------------------------------\n// 📦 Get Adaptive Headers\n// -----------------------------------------------------------\nexport function getAdaptiveHeaders(): Record<string, string> {\n const currentGeo = detectGeo();\n updateGeo(currentGeo);\n\n const summary = btoa(\n JSON.stringify({\n env: isNode ? \"node\" : isBrowser ? \"browser\" : \"worker\",\n routeCount: state.routes.length,\n lastGeo: state.geo,\n avgLatency:\n state.routes.reduce((a, b) => a + b.latency, 0) /\n Math.max(1, state.routes.length),\n })\n );\n\n return {\n \"X-Zubbl-Context-Summary\": summary,\n \"X-Zubbl-Geo-Stability\": `${state.geo}/${state.stability.toFixed(2)}`,\n };\n}\n\n// -----------------------------------------------------------\n// 🌍 Initialize Geo Context Immediately\n// -----------------------------------------------------------\nupdateGeo(process.env.ZUBBL_GEO);\n\n","// src/core/storage.ts\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// Generic storage interface\nexport interface IStorage {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttlSeconds?: number): void;\n remove(key: string): void;\n}\n\n// ------------------------------------------------------\n// Node (in-memory) implementation\n// ------------------------------------------------------\n\nclass NodeStorage implements IStorage {\n private store = new Map<string, { value: any; expiresAt?: number }>();\n\n get<T>(key: string): T | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n this.store.set(key, { value, expiresAt });\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n}\n\n// ------------------------------------------------------\n// Browser (localStorage) implementation\n// ------------------------------------------------------\n\nclass BrowserStorage implements IStorage {\n private prefix = \"zubbl_sdk_\";\n\n get<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(this.prefix + key);\n if (!raw) return null;\n const { value, expiresAt } = JSON.parse(raw);\n if (expiresAt && expiresAt < Date.now()) {\n localStorage.removeItem(this.prefix + key);\n return null;\n }\n return value as T;\n } catch {\n return null;\n }\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n try {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n localStorage.setItem(\n this.prefix + key,\n JSON.stringify({ value, expiresAt })\n );\n } catch (err) {\n // localStorage quota exceeded → silently ignore\n console.warn(\"[Zubbl SDK][Storage] Failed to persist item:\", err);\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(this.prefix + key);\n }\n}\n\n// ------------------------------------------------------\n// Factory\n// ------------------------------------------------------\n\nexport function createStorage(): IStorage {\n if (isNode) return new NodeStorage();\n if (isBrowser) return new BrowserStorage();\n\n // Fallback: safe no-op storage for tests / fake environments\n return {\n get: () => null,\n set: () => {},\n remove: () => {},\n };\n}\n\n","// -----------------------------------------------------------\n// 🌍 Zubbl Geo Engine — Multi-Provider Fallback + 15min Cache\n// -----------------------------------------------------------\n// Fully typed, aligns with Zubbl GEO Enforcement Policy\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\nexport interface GeoPrivacy {\n vpn: boolean;\n hosting: boolean;\n}\n\nexport interface GeoInfo {\n ip: string | null;\n country: string;\n asn: string | null;\n privacy: GeoPrivacy;\n}\n\nconst GEO_CACHE_KEY = \"zubbl-geo-cache\";\nconst GEO_TTL_MS = 15 * 60 * 1000; // 15 minutes\n\n// -----------------------------------------------------------\n// 🗃 Cache Helpers\n// -----------------------------------------------------------\nfunction loadGeoCache(): GeoInfo | null {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n const raw = localStorage.getItem(GEO_CACHE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as { data: GeoInfo; timestamp: number };\n if (!parsed.data?.ip || Date.now() - parsed.timestamp > GEO_TTL_MS) return null;\n return parsed.data;\n } catch {\n return null;\n }\n}\n\nfunction saveGeoCache(data: GeoInfo): void {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n localStorage.setItem(GEO_CACHE_KEY, JSON.stringify({ data, timestamp: Date.now() }));\n } catch {}\n}\n\n// -----------------------------------------------------------\n// 🌐 Provider Wrappers\n// -----------------------------------------------------------\nasync function fetchJSON(url: string, timeoutMs = 3000): Promise<any> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const resp = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n return await resp.json();\n } catch (err) {\n clearTimeout(timeout);\n throw err;\n }\n}\n\nasync function providerIpInfo(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipinfo.io/json?token=public\");\n return {\n ip: d.ip || null,\n country: d.country || \"unknown\",\n asn: d.org?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerIpApi(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipapi.co/json/\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: d.asn?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerGeoJs(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://get.geojs.io/v1/ip/geo.json\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\n// -----------------------------------------------------------\n// 🧠 Fallback Resolver\n// -----------------------------------------------------------\nexport async function getGeoInfo(): Promise<GeoInfo> {\n const cached = loadGeoCache();\n if (cached) return cached;\n\n const providers = [providerIpInfo, providerIpApi, providerGeoJs];\n for (const fn of providers) {\n try {\n const result = await fn();\n if (result?.country && result.country !== \"unknown\") {\n saveGeoCache(result);\n return result;\n }\n } catch (err: any) {\n console.warn(\"[Zubbl SDK][Geo] Provider failed:\", fn.name, \"-\", err.message);\n }\n }\n\n const fallback: GeoInfo = {\n ip: null,\n country: \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n saveGeoCache(fallback);\n return fallback;\n}\n\n// -----------------------------------------------------------\n// 🧩 Exported Helpers\n// -----------------------------------------------------------\nexport function clearGeoCache(): void {\n try {\n if (isBrowser && typeof localStorage !== \"undefined\") {\n localStorage.removeItem(GEO_CACHE_KEY);\n }\n } catch {}\n}\n\nexport async function getGeoHeaders(): Promise<Record<string, string>> {\n const geo = await getGeoInfo();\n return {\n \"X-Zubbl-Geo-Country\": geo.country || \"unknown\",\n \"X-Zubbl-ASN\": geo.asn || \"unknown\",\n \"X-Zubbl-IP\": geo.ip || \"\",\n \"X-Zubbl-Privacy-VPN\": String(geo.privacy?.vpn ?? false),\n \"X-Zubbl-Privacy-Hosting\": String(geo.privacy?.hosting ?? false),\n };\n}\n","// -----------------------------------------------------------\n// 🔐 Secure Signing & Nonce Generator\n// -----------------------------------------------------------\n\nimport crypto from \"crypto\";\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Generate UUIDv4 Nonce\n// -----------------------------------------------------------\nexport function generateNonce(): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// -----------------------------------------------------------\n// Compute SHA256 HMAC signature\n// -----------------------------------------------------------\nexport async function signPayload(payload: string, secret: string): Promise<string> {\n if (isNode) {\n // ✅ Node.js native HMAC\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n // ✅ Browser / Worker using WebCrypto\n if (typeof window !== \"undefined\" && window.crypto?.subtle) {\n const key = await window.crypto.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const sig = await window.crypto.subtle.sign(\n \"HMAC\",\n key,\n new TextEncoder().encode(payload)\n );\n\n return Array.from(new Uint8Array(sig))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n throw new Error(\"No crypto implementation available in this environment\");\n}\n\n// -----------------------------------------------------------\n// Attach signing headers to a request (corrected for SDK-12)\n// -----------------------------------------------------------\nexport function attachSigningHeaders(\n url: string,\n method: string,\n headers: Record<string, string> = {},\n body?: any,\n secretKey?: string | null\n): void {\n const nonce = generateNonce();\n\n // Normalize body to a string before hashing\n const normalizedBody =\n typeof body === \"string\"\n ? body\n : body && typeof body === \"object\"\n ? JSON.stringify(body)\n : \"\";\n\n const bodyHash = normalizedBody\n ? crypto.createHash(\"sha256\").update(normalizedBody).digest(\"hex\")\n : \"\";\n\n // Compute canonical string (deterministic)\n const canonical = `${method.toUpperCase()}\\n${url}\\n${nonce}\\n${bodyHash}`;\n\n // Attach nonce and signature headers (in-place)\n headers[\"X-Zubbl-Nonce\"] = nonce;\n\n if (secretKey) {\n const signature = crypto\n .createHmac(\"sha256\", secretKey)\n .update(canonical)\n .digest(\"hex\");\n headers[\"X-Zubbl-Signature\"] = signature;\n }\n}\n","// src/core/http.ts\n// -----------------------------------------------------------\n// HTTP utility (instance-safe)\n// -----------------------------------------------------------\n\nimport { recordContextSample, getAdaptiveHeaders } from \"./context\";\nimport { attachSigningHeaders } from \"./signing\";\n\n\n/**\n * Performs a safe HTTP request with adaptive + signing headers.\n * NOTE: no global getConfig() dependency — caller must provide fully resolved URL + headers.\n */\nexport async function httpRequest(url: string, options: RequestInit = {}): Promise<Response> {\n // 🔧 Default timeout lowered for SDK-12 hardening\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n try {\n const method = (options.method || \"GET\").toUpperCase();\n const body = options.body;\n const headers: Record<string, string> = {\n ...(options.headers as Record<string, string>),\n ...getAdaptiveHeaders(),\n };\n\n // ✅ FIX: include url, method, headers, body\n attachSigningHeaders(url, method, headers, body);\n\n const finalOptions: RequestInit = {\n ...options,\n method,\n headers,\n signal: controller.signal,\n };\n\n // Record adaptive context sample\n recordContextSample(\"/http\", \"GET\", 200, 123);\n\n const response = await fetch(url, finalOptions);\n\n if (!response.ok) {\n console.warn(`[Zubbl SDK][HTTP] ${response.status} on ${url}`);\n }\n\n return response;\n } catch (err: any) {\n console.error(\"[Zubbl SDK][HTTP] Request failed:\", err?.message);\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n}\n","// src/features/identifyUser.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe identifyUser feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\nconst USER_CACHE_KEY = \"external_user_id\";\nconst USER_TTL = 24 * 60 * 60; // 24h\n\nexport async function identifyUserFeature(\n store: any,\n { email, name }: { email: string; name?: string }\n) {\n if (!email) throw new Error(\"email is required\");\n\n const config = store.get();\n const storage = createStorage();\n\n // Check cache\n const cached = storage.get<{ id: string }>(USER_CACHE_KEY);\n if (cached?.id) {\n return { external_user_id: cached.id, cached: true };\n }\n\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use per-instance config store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"Content-Type\": \"application/json\",\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n const resp = await httpRequest(`${config.baseUrl}/sdk/identify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ email, name }),\n });\n\n const data = await resp.json().catch(() => ({}));\n const { external_user_id } = data;\n\n if (!external_user_id) {\n throw new Error(\"Backend did not return external_user_id\");\n }\n\n storage.set(USER_CACHE_KEY, { id: external_user_id }, USER_TTL);\n return { external_user_id, cached: false };\n}\n","// src/features/getTiles.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe getTiles feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\n\nconst TILE_CACHE_KEY = \"tiles_cache\";\nconst TILE_TTL_DEFAULT = 10 * 60; // 10 min\n\ninterface TileCacheEntry {\n data: any;\n etag?: string;\n expiresAt: number;\n}\n\nexport async function getTilesFeature(\n store: any,\n { external_user_id, app_id = null, ttlSeconds = TILE_TTL_DEFAULT }: any\n) {\n const config = store.get();\n const storage = createStorage();\n\n const cached = storage.get<TileCacheEntry>(TILE_CACHE_KEY);\n const isFresh = cached && cached.expiresAt > Date.now();\n\n if (isFresh) {\n backgroundRefresh(store, external_user_id, app_id, ttlSeconds);\n return { data: cached.data, fromCache: true };\n }\n\n try {\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use instance store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n if (cached?.etag) headers[\"If-None-Match\"] = cached.etag;\n\n const params = new URLSearchParams({ external_user_id });\n params.set(\"app_id\", app_id || config.appId!);\n\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/tiles/effective?${params.toString()}`;\n const resp = await httpRequest(url, { headers });\n\n if (resp.status === 304 && cached?.data) {\n cached.expiresAt = Date.now() + ttlSeconds * 1000;\n storage.set(TILE_CACHE_KEY, cached, ttlSeconds);\n return { data: cached.data, fromCache: true, status: 304 };\n }\n\n const data = await resp.json();\n const etag = resp.headers.get(\"ETag\") || undefined;\n\n const entry: TileCacheEntry = {\n data,\n etag,\n expiresAt: Date.now() + ttlSeconds * 1000,\n };\n storage.set(TILE_CACHE_KEY, entry, ttlSeconds);\n\n return { data, fromCache: false, status: resp.status };\n } catch (err) {\n if (cached?.data) {\n return { data: cached.data, fromCache: true, error: String(err) };\n }\n throw err;\n }\n}\n\nasync function backgroundRefresh(store: any, external_user_id: string, app_id: string | null, ttlSeconds: number) {\n try {\n await getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n } catch {\n // Silent background failure\n }\n}\n","// src/client.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Final Instance-based Client (Feature Delegation)\n// -----------------------------------------------------------\n\nimport * as ConfigModule from \"./core/config\";\nimport { createStorage } from \"./core/storage\";\nimport { getGeoInfo } from \"./core/geo\";\n\n// Feature modules\nimport { identifyUserFeature } from \"./features/identifyUser\";\nimport { getTilesFeature } from \"./features/getTiles\";\n\n\nexport type ZubblConfig = {\n apiKey: string;\n tenantId: string;\n appId: string;\n baseUrl?: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n};\n\n/**\n * Creates a self-contained, instance-based Zubbl client.\n * Each instance owns its own config store and initialization state.\n */\nexport function createZubblClient(cfg: ZubblConfig) {\n const store = ConfigModule.createConfigStore();\n const storage = createStorage();\n let initialized = false;\n\n async function init() {\n if (initialized) return;\n\n // ✅ Validate UUIDs before initializing\n const UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n if (!UUID_PATTERN.test(cfg.tenantId)) {\n throw new Error(`[Zubbl SDK] Invalid tenantId: expected UUID, got \"${cfg.tenantId}\"`);\n }\n\n if (!UUID_PATTERN.test(cfg.appId)) {\n throw new Error(`[Zubbl SDK] Invalid appId: expected UUID, got \"${cfg.appId}\"`);\n }\n\n // Initialize per-client config\n store.init(cfg);\n\n // Optional: GEO bootstrap\n try {\n const geo = await getGeoInfo();\n console.log(`[Zubbl SDK] 🌍 GEO detected: ${geo.country} (ASN ${geo.asn || \"?\"})`);\n } catch (err: any) {\n console.warn(\"[Zubbl SDK] GEO init failed:\", err?.message);\n }\n\n initialized = true;\n }\n\n function assertInitialized() {\n if (!initialized) {\n throw new Error(\"Zubbl client not initialized — call client.init() first\");\n }\n }\n\n // ---------------------------------------------------------\n // User + Tile Operations (delegated to feature modules)\n // ---------------------------------------------------------\n async function identifyUser({ email, name }: { email: string; name?: string }) {\n assertInitialized();\n return identifyUserFeature(store, { email, name });\n }\n\n async function getTiles({\n external_user_id,\n app_id = null,\n ttlSeconds,\n }: {\n external_user_id: string;\n app_id?: string | null;\n ttlSeconds?: number;\n }) {\n assertInitialized();\n return getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n }\n\n // ---------------------------------------------------------\n // Enforcement API (kept inline)\n // ---------------------------------------------------------\n async function enforce({\n external_user_id,\n app_id = null,\n }: {\n external_user_id: string;\n app_id?: string | null;\n }) {\n assertInitialized();\n\n const config = store.get();\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n });\n\n const resp = await fetch(`${config.baseUrl?.replace(/\\/$/, \"\")}/sdk/test-enforcement`, {\n method: \"POST\",\n headers,\n });\n\n const json = await resp.json().catch(() => ({}));\n return { decision: \"allow\", status: resp.status, data: json };\n }\n\n // ---------------------------------------------------------\n // Public API\n // ---------------------------------------------------------\n return {\n init,\n identifyUser,\n getTiles,\n enforce,\n storage,\n };\n}\n","// src/index.ts\n// -----------------------------------------------------------\n// Zubbl SDK Entry Point — Public Exports\n// -----------------------------------------------------------\n\n// Core factory + environment\nexport * from \"./core/config\";\nexport * from \"./core/context\";\nexport * from \"./core/storage\";\nexport * from \"./core/geo\";\n\n// Avoid duplicate export of ZubblConfig\nexport {\n createZubblClient, // 🔁 change this if your client.ts exports something else\n} from \"./client\";\n\n// Feature modules (optional direct access)\nexport * from \"./features/identifyUser\";\nexport * from \"./features/getTiles\";\n\nconsole.log(\"[Zubbl SDK] ✅ Entry point loaded\");\n"],"names":["ConfigModule.createConfigStore"],"mappings":"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"}
1
+ {"version":3,"file":"zubbl-sdk.cjs.js","sources":["../src/core/config.ts","../src/core/context.ts","../src/core/storage.ts","../src/core/geo.ts","../src/core/signing.ts","../src/core/http.ts","../src/features/identifyUser.ts","../src/features/getTiles.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["// src/core/config.ts\n// -----------------------------------------------------------\n// Universal environment detection + SDK configuration\n// -----------------------------------------------------------\n\nexport const isBrowser =\n typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nexport const isNode =\n typeof process !== \"undefined\" &&\n !!process.versions?.node &&\n !isBrowser;\n\nexport const isWorker =\n typeof self !== \"undefined\" &&\n typeof (self as any).importScripts === \"function\" &&\n !isNode;\n\n// -----------------------------------------------------------\n// Config store factory (no module-scoped state)\n// -----------------------------------------------------------\n\nexport interface ZubblConfig {\n apiKey: string | null;\n tenantId: string | null;\n appId: string | null;\n baseUrl: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n}\n\nfunction assertBrowserSafety(cfg: ZubblConfig) {\n if (isBrowser || isWorker) {\n const key = cfg.apiKey ?? \"\";\n const looksSecret = key.startsWith(\"sk_\") || key.length > 40;\n if (looksSecret) {\n throw new Error(\n \"[Zubbl SDK] Secret or server key detected in browser environment. \" +\n \"Use a public SDK key instead (prefix pk_).\"\n );\n }\n }\n}\n\n/**\n * Creates an isolated configuration store.\n * Each ZubblClient instance owns its own store.\n */\nexport function createConfigStore(initial?: Partial<ZubblConfig>) {\n let current: ZubblConfig = {\n apiKey: null,\n tenantId: null,\n appId: null,\n baseUrl: \"https://api.zubbl.com/api\",\n injectWorkerHeaders: false,\n workerSecret: null,\n ...initial,\n };\n\n function init(partial: Partial<ZubblConfig>) {\n current = { ...current, ...partial };\n assertBrowserSafety(current);\n }\n\n function get(): Readonly<ZubblConfig> {\n return current;\n }\n\n function buildHeaders(extra: Record<string, string> = {}): Record<string, string> {\n if (!current.tenantId || !current.appId) {\n throw new Error(\"[Zubbl SDK] Not initialized – call init() first.\");\n }\n\n const headers: Record<string, string> = {\n \"X-Tenant-Id\": current.tenantId,\n \"X-App-Id\": current.appId,\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n\n if (current.apiKey) {\n headers.Authorization = `Bearer ${current.apiKey}`;\n }\n\n return headers;\n}\n\n return { init, get, buildHeaders };\n}\n\n","// src/core/context.ts\n// -----------------------------------------------------------\n// Adaptive Context Engine — Geo + Stability Enrichment + Persistence\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\ninterface ContextSample {\n path: string;\n method: string;\n ts: number;\n status: number;\n latency: number;\n}\n\ninterface AdaptiveState {\n routes: ContextSample[];\n geo: string;\n stability: number;\n lastGeoChange: number;\n}\n\nconst MAX_HISTORY = 100;\nconst CACHE_KEY = \"zubbl-stability\";\n\nlet state: AdaptiveState = loadStability() ?? {\n routes: [],\n geo: \"unknown\",\n stability: 1.0,\n lastGeoChange: Date.now(),\n};\n\n// -----------------------------------------------------------\n// 💾 Persistence Helpers\n// -----------------------------------------------------------\nfunction loadStability(): AdaptiveState | null {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed.geo || !parsed.stability) return null;\n return { ...parsed, routes: [] };\n } catch {\n return null;\n }\n}\n\nfunction saveStability() {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n try {\n const payload = {\n geo: state.geo,\n stability: state.stability,\n lastGeoChange: state.lastGeoChange,\n };\n localStorage.setItem(CACHE_KEY, JSON.stringify(payload));\n } catch {\n /* ignore */\n }\n}\n\n// -----------------------------------------------------------\n// 🌍 Geo Detection (Node, Browser, Worker)\n// -----------------------------------------------------------\nexport function detectGeo(): string {\n try {\n if (isBrowser && typeof window !== \"undefined\" && window.navigator?.language) {\n return window.navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isWorker && typeof self !== \"undefined\" && (self as any).navigator?.language) {\n return (self as any).navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isNode && typeof process !== \"undefined\") {\n const envGeo = process.env.ZUBBL_GEO || process.env.GEO;\n if (envGeo && /^[A-Z]{2}$/i.test(envGeo)) return envGeo.toUpperCase();\n return \"GB\";\n }\n\n return \"unknown\";\n } catch (err) {\n console.warn(\"[Zubbl SDK][Geo Detect] Failed:\", err);\n return \"unknown\";\n }\n}\n\n// -----------------------------------------------------------\n// 🧭 Update Geo & Stability (with persistence)\n// -----------------------------------------------------------\nexport function updateGeo(geoHint?: string) {\n const newGeo = geoHint || detectGeo();\n if (newGeo !== state.geo) {\n const now = Date.now();\n const elapsed = (now - state.lastGeoChange) / 1000;\n state.stability = Math.max(0.5, Math.min(1.0, elapsed / 3600));\n state.geo = newGeo;\n state.lastGeoChange = now;\n saveStability();\n } else {\n state.stability = Math.min(1.0, state.stability + 0.01);\n saveStability();\n }\n}\n\n// -----------------------------------------------------------\n// 🧮 Record Context Samples\n// -----------------------------------------------------------\nexport function recordContextSample(\n path: string,\n method: string,\n status: number,\n latency: number\n) {\n state.routes.push({ path, method, ts: Date.now(), status, latency });\n if (state.routes.length > MAX_HISTORY) state.routes.shift();\n updateGeo(); // auto-refresh geo info\n}\n\n// -----------------------------------------------------------\n// 📦 Get Adaptive Headers\n// -----------------------------------------------------------\nexport function getAdaptiveHeaders(): Record<string, string> {\n const currentGeo = detectGeo();\n updateGeo(currentGeo);\n\n const summary = btoa(\n JSON.stringify({\n env: isNode ? \"node\" : isBrowser ? \"browser\" : \"worker\",\n routeCount: state.routes.length,\n lastGeo: state.geo,\n avgLatency:\n state.routes.reduce((a, b) => a + b.latency, 0) /\n Math.max(1, state.routes.length),\n })\n );\n\n return {\n \"X-Zubbl-Context-Summary\": summary,\n \"X-Zubbl-Geo-Stability\": `${state.geo}/${state.stability.toFixed(2)}`,\n };\n}\n\n// -----------------------------------------------------------\n// 🌍 Initialize Geo Context Immediately\n// -----------------------------------------------------------\nupdateGeo(process.env.ZUBBL_GEO);\n\n","// src/core/storage.ts\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// Generic storage interface\nexport interface IStorage {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttlSeconds?: number): void;\n remove(key: string): void;\n}\n\n// ------------------------------------------------------\n// Node (in-memory) implementation\n// ------------------------------------------------------\n\nclass NodeStorage implements IStorage {\n private store = new Map<string, { value: any; expiresAt?: number }>();\n\n get<T>(key: string): T | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n this.store.set(key, { value, expiresAt });\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n}\n\n// ------------------------------------------------------\n// Browser (localStorage) implementation\n// ------------------------------------------------------\n\nclass BrowserStorage implements IStorage {\n private prefix = \"zubbl_sdk_\";\n\n get<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(this.prefix + key);\n if (!raw) return null;\n const { value, expiresAt } = JSON.parse(raw);\n if (expiresAt && expiresAt < Date.now()) {\n localStorage.removeItem(this.prefix + key);\n return null;\n }\n return value as T;\n } catch {\n return null;\n }\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n try {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n localStorage.setItem(\n this.prefix + key,\n JSON.stringify({ value, expiresAt })\n );\n } catch (err) {\n // localStorage quota exceeded → silently ignore\n console.warn(\"[Zubbl SDK][Storage] Failed to persist item:\", err);\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(this.prefix + key);\n }\n}\n\n// ------------------------------------------------------\n// Factory\n// ------------------------------------------------------\n\nexport function createStorage(): IStorage {\n if (isNode) return new NodeStorage();\n if (isBrowser) return new BrowserStorage();\n\n // Fallback: safe no-op storage for tests / fake environments\n return {\n get: () => null,\n set: () => {},\n remove: () => {},\n };\n}\n\n","// -----------------------------------------------------------\n// 🌍 Zubbl Geo Engine — Multi-Provider Fallback + 15min Cache\n// -----------------------------------------------------------\n// Fully typed, aligns with Zubbl GEO Enforcement Policy\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\nexport interface GeoPrivacy {\n vpn: boolean;\n hosting: boolean;\n}\n\nexport interface GeoInfo {\n ip: string | null;\n country: string;\n asn: string | null;\n privacy: GeoPrivacy;\n}\n\nconst GEO_CACHE_KEY = \"zubbl-geo-cache\";\nconst GEO_TTL_MS = 15 * 60 * 1000; // 15 minutes\n\n// -----------------------------------------------------------\n// 🗃 Cache Helpers\n// -----------------------------------------------------------\nfunction loadGeoCache(): GeoInfo | null {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n const raw = localStorage.getItem(GEO_CACHE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as { data: GeoInfo; timestamp: number };\n if (!parsed.data?.ip || Date.now() - parsed.timestamp > GEO_TTL_MS) return null;\n return parsed.data;\n } catch {\n return null;\n }\n}\n\nfunction saveGeoCache(data: GeoInfo): void {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n localStorage.setItem(GEO_CACHE_KEY, JSON.stringify({ data, timestamp: Date.now() }));\n } catch {}\n}\n\n// -----------------------------------------------------------\n// 🌐 Provider Wrappers\n// -----------------------------------------------------------\nasync function fetchJSON(url: string, timeoutMs = 3000): Promise<any> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const resp = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n return await resp.json();\n } catch (err) {\n clearTimeout(timeout);\n throw err;\n }\n}\n\nasync function providerIpInfo(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipinfo.io/json?token=public\");\n return {\n ip: d.ip || null,\n country: d.country || \"unknown\",\n asn: d.org?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerIpApi(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipapi.co/json/\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: d.asn?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerGeoJs(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://get.geojs.io/v1/ip/geo.json\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\n// -----------------------------------------------------------\n// 🧠 Fallback Resolver\n// -----------------------------------------------------------\nexport async function getGeoInfo(): Promise<GeoInfo> {\n const cached = loadGeoCache();\n if (cached) return cached;\n\n const providers = [providerIpInfo, providerIpApi, providerGeoJs];\n for (const fn of providers) {\n try {\n const result = await fn();\n if (result?.country && result.country !== \"unknown\") {\n saveGeoCache(result);\n return result;\n }\n } catch (err: any) {\n console.warn(\"[Zubbl SDK][Geo] Provider failed:\", fn.name, \"-\", err.message);\n }\n }\n\n const fallback: GeoInfo = {\n ip: null,\n country: \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n saveGeoCache(fallback);\n return fallback;\n}\n\n// -----------------------------------------------------------\n// 🧩 Exported Helpers\n// -----------------------------------------------------------\nexport function clearGeoCache(): void {\n try {\n if (isBrowser && typeof localStorage !== \"undefined\") {\n localStorage.removeItem(GEO_CACHE_KEY);\n }\n } catch {}\n}\n\nexport async function getGeoHeaders(): Promise<Record<string, string>> {\n const geo = await getGeoInfo();\n return {\n \"X-Zubbl-Geo-Country\": geo.country || \"unknown\",\n \"X-Zubbl-ASN\": geo.asn || \"unknown\",\n \"X-Zubbl-IP\": geo.ip || \"\",\n \"X-Zubbl-Privacy-VPN\": String(geo.privacy?.vpn ?? false),\n \"X-Zubbl-Privacy-Hosting\": String(geo.privacy?.hosting ?? false),\n };\n}\n","// -----------------------------------------------------------\n// 🔐 Secure Signing & Nonce Generator\n// -----------------------------------------------------------\n\nimport crypto from \"crypto\";\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Generate UUIDv4 Nonce\n// -----------------------------------------------------------\nexport function generateNonce(): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// -----------------------------------------------------------\n// Compute SHA256 HMAC signature\n// -----------------------------------------------------------\nexport async function signPayload(payload: string, secret: string): Promise<string> {\n if (isNode) {\n // ✅ Node.js native HMAC\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n // ✅ Browser / Worker using WebCrypto\n if (typeof window !== \"undefined\" && window.crypto?.subtle) {\n const key = await window.crypto.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const sig = await window.crypto.subtle.sign(\n \"HMAC\",\n key,\n new TextEncoder().encode(payload)\n );\n\n return Array.from(new Uint8Array(sig))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n throw new Error(\"No crypto implementation available in this environment\");\n}\n\n// -----------------------------------------------------------\n// Attach signing headers to a request (corrected for SDK-12)\n// -----------------------------------------------------------\nexport function attachSigningHeaders(\n url: string,\n method: string,\n headers: Record<string, string> = {},\n body?: any,\n secretKey?: string | null\n): void {\n const nonce = generateNonce();\n\n // Normalize body to a string before hashing\n const normalizedBody =\n typeof body === \"string\"\n ? body\n : body && typeof body === \"object\"\n ? JSON.stringify(body)\n : \"\";\n\n const bodyHash = normalizedBody\n ? crypto.createHash(\"sha256\").update(normalizedBody).digest(\"hex\")\n : \"\";\n\n // Compute canonical string (deterministic)\n const canonical = `${method.toUpperCase()}\\n${url}\\n${nonce}\\n${bodyHash}`;\n\n // Attach nonce and signature headers (in-place)\n headers[\"X-Zubbl-Nonce\"] = nonce;\n\n if (secretKey) {\n const signature = crypto\n .createHmac(\"sha256\", secretKey)\n .update(canonical)\n .digest(\"hex\");\n headers[\"X-Zubbl-Signature\"] = signature;\n }\n}\n","// src/core/http.ts\n// -----------------------------------------------------------\n// HTTP utility (instance-safe)\n// -----------------------------------------------------------\n\nimport { recordContextSample, getAdaptiveHeaders } from \"./context\";\nimport { attachSigningHeaders } from \"./signing\";\n\n\n/**\n * Performs a safe HTTP request with adaptive + signing headers.\n * NOTE: no global getConfig() dependency — caller must provide fully resolved URL + headers.\n */\nexport async function httpRequest(url: string, options: RequestInit = {}): Promise<Response> {\n // 🔧 Default timeout lowered for SDK-12 hardening\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n try {\n const method = (options.method || \"GET\").toUpperCase();\n const body = options.body;\n const headers: Record<string, string> = {\n ...(options.headers as Record<string, string>),\n ...getAdaptiveHeaders(),\n };\n\n // ✅ FIX: include url, method, headers, body\n attachSigningHeaders(url, method, headers, body);\n\n const finalOptions: RequestInit = {\n ...options,\n method,\n headers,\n signal: controller.signal,\n };\n\n // Record adaptive context sample\n recordContextSample(\"/http\", \"GET\", 200, 123);\n\n const response = await fetch(url, finalOptions);\n\n if (!response.ok) {\n console.warn(`[Zubbl SDK][HTTP] ${response.status} on ${url}`);\n }\n\n return response;\n } catch (err: any) {\n console.error(\"[Zubbl SDK][HTTP] Request failed:\", err?.message);\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n}\n","// src/features/identifyUser.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe identifyUser feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\nconst USER_CACHE_KEY = \"external_user_id\";\nconst USER_TTL = 24 * 60 * 60; // 24h\n\nexport async function identifyUserFeature(\n store: any,\n { email, name }: { email: string; name?: string }\n) {\n if (!email) throw new Error(\"email is required\");\n\n const config = store.get();\n const storage = createStorage();\n\n // Check cache\n const cached = storage.get<{ id: string }>(USER_CACHE_KEY);\n if (cached?.id) {\n return { external_user_id: cached.id, cached: true };\n }\n\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use per-instance config store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"Content-Type\": \"application/json\",\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n const resp = await httpRequest(`${config.baseUrl}/sdk/identify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ email, name }),\n });\n\n const data = await resp.json().catch(() => ({}));\n const { external_user_id } = data;\n\n if (!external_user_id) {\n throw new Error(\"Backend did not return external_user_id\");\n }\n\n storage.set(USER_CACHE_KEY, { id: external_user_id }, USER_TTL);\n return { external_user_id, cached: false };\n}\n","// src/features/getTiles.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe getTiles feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\n\nconst TILE_CACHE_KEY = \"tiles_cache\";\nconst TILE_TTL_DEFAULT = 10 * 60; // 10 min\n\ninterface TileCacheEntry {\n data: any;\n etag?: string;\n expiresAt: number;\n}\n\nexport async function getTilesFeature(\n store: any,\n { external_user_id, app_id = null, ttlSeconds = TILE_TTL_DEFAULT }: any\n) {\n const config = store.get();\n const storage = createStorage();\n\n const cached = storage.get<TileCacheEntry>(TILE_CACHE_KEY);\n const isFresh = cached && cached.expiresAt > Date.now();\n\n if (isFresh) {\n backgroundRefresh(store, external_user_id, app_id, ttlSeconds);\n return { data: cached.data, fromCache: true };\n }\n\n try {\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use instance store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n // Modern endpoint: POST /api/sdk/policies with body (per architecture docs)\nconst payload = {\n tenant_id: config.tenantId,\n app_id: app_id || config.appId!,\n external_user_id,\n};\n\nconst resp = await httpRequest(`${config.baseUrl.replace(/\\/$/, \"\")}/api/sdk/policies`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n});\n\n if (resp.status === 304 && cached?.data) {\n cached.expiresAt = Date.now() + ttlSeconds * 1000;\n storage.set(TILE_CACHE_KEY, cached, ttlSeconds);\n return { data: cached.data, fromCache: true, status: 304 };\n }\n\n const data = await resp.json();\n const etag = resp.headers.get(\"ETag\") || undefined;\n\n const entry: TileCacheEntry = {\n data,\n etag,\n expiresAt: Date.now() + ttlSeconds * 1000,\n };\n storage.set(TILE_CACHE_KEY, entry, ttlSeconds);\n\n return { data, fromCache: false, status: resp.status };\n } catch (err) {\n if (cached?.data) {\n return { data: cached.data, fromCache: true, error: String(err) };\n }\n throw err;\n }\n}\n\nasync function backgroundRefresh(store: any, external_user_id: string, app_id: string | null, ttlSeconds: number) {\n try {\n await getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n } catch {\n // Silent background failure\n }\n}\n","// src/client.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Final Instance-based Client (Feature Delegation)\n// -----------------------------------------------------------\n\nimport * as ConfigModule from \"./core/config\";\nimport { createStorage } from \"./core/storage\";\nimport { getGeoInfo } from \"./core/geo\";\n\n// Feature modules\nimport { identifyUserFeature } from \"./features/identifyUser\";\nimport { getTilesFeature } from \"./features/getTiles\";\n\n\nexport type ZubblConfig = {\n apiKey: string;\n tenantId: string;\n appId: string;\n baseUrl?: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n};\n\n/**\n * Creates a self-contained, instance-based Zubbl client.\n * Each instance owns its own config store and initialization state.\n */\nexport function createZubblClient(cfg: ZubblConfig) {\n const store = ConfigModule.createConfigStore();\n const storage = createStorage();\n let initialized = false;\n\n async function init() {\n if (initialized) return;\n\n // ✅ Validate UUIDs before initializing\n const UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n if (!UUID_PATTERN.test(cfg.tenantId)) {\n throw new Error(`[Zubbl SDK] Invalid tenantId: expected UUID, got \"${cfg.tenantId}\"`);\n }\n\n if (!UUID_PATTERN.test(cfg.appId)) {\n throw new Error(`[Zubbl SDK] Invalid appId: expected UUID, got \"${cfg.appId}\"`);\n }\n\n // Initialize per-client config\n store.init(cfg);\n\n // Optional: GEO bootstrap\n try {\n const geo = await getGeoInfo();\n console.log(`[Zubbl SDK] 🌍 GEO detected: ${geo.country} (ASN ${geo.asn || \"?\"})`);\n } catch (err: any) {\n console.warn(\"[Zubbl SDK] GEO init failed:\", err?.message);\n }\n\n initialized = true;\n }\n\n function assertInitialized() {\n if (!initialized) {\n throw new Error(\"Zubbl client not initialized — call client.init() first\");\n }\n }\n\n // ---------------------------------------------------------\n // User + Tile Operations (delegated to feature modules)\n // ---------------------------------------------------------\n async function identifyUser({ email, name }: { email: string; name?: string }) {\n assertInitialized();\n return identifyUserFeature(store, { email, name });\n }\n\n async function getTiles({\n external_user_id,\n app_id = null,\n ttlSeconds,\n }: {\n external_user_id: string;\n app_id?: string | null;\n ttlSeconds?: number;\n }) {\n assertInitialized();\n return getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n }\n\n // ---------------------------------------------------------\n // Enforcement API (kept inline)\n // ---------------------------------------------------------\n async function enforce({\n external_user_id,\n app_id = null,\n }: {\n external_user_id: string;\n app_id?: string | null;\n }) {\n assertInitialized();\n\n const config = store.get();\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n });\n\n const resp = await fetch(`${config.baseUrl?.replace(/\\/$/, \"\")}/sdk/test-enforcement`, {\n method: \"POST\",\n headers,\n });\n\n const json = await resp.json().catch(() => ({}));\n return { decision: \"allow\", status: resp.status, data: json };\n }\n\n // ---------------------------------------------------------\n // Public API\n // ---------------------------------------------------------\n return {\n init,\n identifyUser,\n getTiles,\n enforce,\n storage,\n };\n}\n","// src/index.ts\n// -----------------------------------------------------------\n// Zubbl SDK Entry Point — Public Exports\n// -----------------------------------------------------------\n\n// Core factory + environment\nexport * from \"./core/config\";\nexport * from \"./core/context\";\nexport * from \"./core/storage\";\nexport * from \"./core/geo\";\n\n// Avoid duplicate export of ZubblConfig\nexport {\n createZubblClient, // 🔁 change this if your client.ts exports something else\n} from \"./client\";\n\n// Feature modules (optional direct access)\nexport * from \"./features/identifyUser\";\nexport * from \"./features/getTiles\";\n\nconsole.log(\"[Zubbl SDK] ✅ Entry point loaded\");\n"],"names":["ConfigModule.createConfigStore"],"mappings":"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"}
@@ -528,12 +528,17 @@ async function getTilesFeature(store, { external_user_id, app_id = null, ttlSeco
528
528
  ...adaptiveHeaders,
529
529
  ...geoHeaders,
530
530
  });
531
- if (cached?.etag)
532
- headers["If-None-Match"] = cached.etag;
533
- const params = new URLSearchParams({ external_user_id });
534
- params.set("app_id", app_id || config.appId);
535
- const url = `${config.baseUrl.replace(/\/$/, "")}/tiles/effective?${params.toString()}`;
536
- const resp = await httpRequest(url, { headers });
531
+ // Modern endpoint: POST /api/sdk/policies with body (per architecture docs)
532
+ const payload = {
533
+ tenant_id: config.tenantId,
534
+ app_id: app_id || config.appId,
535
+ external_user_id,
536
+ };
537
+ const resp = await httpRequest(`${config.baseUrl.replace(/\/$/, "")}/api/sdk/policies`, {
538
+ method: "POST",
539
+ headers,
540
+ body: JSON.stringify(payload),
541
+ });
537
542
  if (resp.status === 304 && cached?.data) {
538
543
  cached.expiresAt = Date.now() + ttlSeconds * 1000;
539
544
  storage.set(TILE_CACHE_KEY, cached, ttlSeconds);
@@ -1 +1 @@
1
- {"version":3,"file":"zubbl-sdk.esm.js","sources":["../src/core/config.ts","../src/core/context.ts","../src/core/storage.ts","../src/core/geo.ts","../src/core/signing.ts","../src/core/http.ts","../src/features/identifyUser.ts","../src/features/getTiles.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["// src/core/config.ts\n// -----------------------------------------------------------\n// Universal environment detection + SDK configuration\n// -----------------------------------------------------------\n\nexport const isBrowser =\n typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nexport const isNode =\n typeof process !== \"undefined\" &&\n !!process.versions?.node &&\n !isBrowser;\n\nexport const isWorker =\n typeof self !== \"undefined\" &&\n typeof (self as any).importScripts === \"function\" &&\n !isNode;\n\n// -----------------------------------------------------------\n// Config store factory (no module-scoped state)\n// -----------------------------------------------------------\n\nexport interface ZubblConfig {\n apiKey: string | null;\n tenantId: string | null;\n appId: string | null;\n baseUrl: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n}\n\nfunction assertBrowserSafety(cfg: ZubblConfig) {\n if (isBrowser || isWorker) {\n const key = cfg.apiKey ?? \"\";\n const looksSecret = key.startsWith(\"sk_\") || key.length > 40;\n if (looksSecret) {\n throw new Error(\n \"[Zubbl SDK] Secret or server key detected in browser environment. \" +\n \"Use a public SDK key instead (prefix pk_).\"\n );\n }\n }\n}\n\n/**\n * Creates an isolated configuration store.\n * Each ZubblClient instance owns its own store.\n */\nexport function createConfigStore(initial?: Partial<ZubblConfig>) {\n let current: ZubblConfig = {\n apiKey: null,\n tenantId: null,\n appId: null,\n baseUrl: \"https://api.zubbl.com/api\",\n injectWorkerHeaders: false,\n workerSecret: null,\n ...initial,\n };\n\n function init(partial: Partial<ZubblConfig>) {\n current = { ...current, ...partial };\n assertBrowserSafety(current);\n }\n\n function get(): Readonly<ZubblConfig> {\n return current;\n }\n\n function buildHeaders(extra: Record<string, string> = {}): Record<string, string> {\n if (!current.tenantId || !current.appId) {\n throw new Error(\"[Zubbl SDK] Not initialized – call init() first.\");\n }\n\n const headers: Record<string, string> = {\n \"X-Tenant-Id\": current.tenantId,\n \"X-App-Id\": current.appId,\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n\n if (current.apiKey) {\n headers.Authorization = `Bearer ${current.apiKey}`;\n }\n\n return headers;\n}\n\n return { init, get, buildHeaders };\n}\n\n","// src/core/context.ts\n// -----------------------------------------------------------\n// Adaptive Context Engine — Geo + Stability Enrichment + Persistence\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\ninterface ContextSample {\n path: string;\n method: string;\n ts: number;\n status: number;\n latency: number;\n}\n\ninterface AdaptiveState {\n routes: ContextSample[];\n geo: string;\n stability: number;\n lastGeoChange: number;\n}\n\nconst MAX_HISTORY = 100;\nconst CACHE_KEY = \"zubbl-stability\";\n\nlet state: AdaptiveState = loadStability() ?? {\n routes: [],\n geo: \"unknown\",\n stability: 1.0,\n lastGeoChange: Date.now(),\n};\n\n// -----------------------------------------------------------\n// 💾 Persistence Helpers\n// -----------------------------------------------------------\nfunction loadStability(): AdaptiveState | null {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed.geo || !parsed.stability) return null;\n return { ...parsed, routes: [] };\n } catch {\n return null;\n }\n}\n\nfunction saveStability() {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n try {\n const payload = {\n geo: state.geo,\n stability: state.stability,\n lastGeoChange: state.lastGeoChange,\n };\n localStorage.setItem(CACHE_KEY, JSON.stringify(payload));\n } catch {\n /* ignore */\n }\n}\n\n// -----------------------------------------------------------\n// 🌍 Geo Detection (Node, Browser, Worker)\n// -----------------------------------------------------------\nexport function detectGeo(): string {\n try {\n if (isBrowser && typeof window !== \"undefined\" && window.navigator?.language) {\n return window.navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isWorker && typeof self !== \"undefined\" && (self as any).navigator?.language) {\n return (self as any).navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isNode && typeof process !== \"undefined\") {\n const envGeo = process.env.ZUBBL_GEO || process.env.GEO;\n if (envGeo && /^[A-Z]{2}$/i.test(envGeo)) return envGeo.toUpperCase();\n return \"GB\";\n }\n\n return \"unknown\";\n } catch (err) {\n console.warn(\"[Zubbl SDK][Geo Detect] Failed:\", err);\n return \"unknown\";\n }\n}\n\n// -----------------------------------------------------------\n// 🧭 Update Geo & Stability (with persistence)\n// -----------------------------------------------------------\nexport function updateGeo(geoHint?: string) {\n const newGeo = geoHint || detectGeo();\n if (newGeo !== state.geo) {\n const now = Date.now();\n const elapsed = (now - state.lastGeoChange) / 1000;\n state.stability = Math.max(0.5, Math.min(1.0, elapsed / 3600));\n state.geo = newGeo;\n state.lastGeoChange = now;\n saveStability();\n } else {\n state.stability = Math.min(1.0, state.stability + 0.01);\n saveStability();\n }\n}\n\n// -----------------------------------------------------------\n// 🧮 Record Context Samples\n// -----------------------------------------------------------\nexport function recordContextSample(\n path: string,\n method: string,\n status: number,\n latency: number\n) {\n state.routes.push({ path, method, ts: Date.now(), status, latency });\n if (state.routes.length > MAX_HISTORY) state.routes.shift();\n updateGeo(); // auto-refresh geo info\n}\n\n// -----------------------------------------------------------\n// 📦 Get Adaptive Headers\n// -----------------------------------------------------------\nexport function getAdaptiveHeaders(): Record<string, string> {\n const currentGeo = detectGeo();\n updateGeo(currentGeo);\n\n const summary = btoa(\n JSON.stringify({\n env: isNode ? \"node\" : isBrowser ? \"browser\" : \"worker\",\n routeCount: state.routes.length,\n lastGeo: state.geo,\n avgLatency:\n state.routes.reduce((a, b) => a + b.latency, 0) /\n Math.max(1, state.routes.length),\n })\n );\n\n return {\n \"X-Zubbl-Context-Summary\": summary,\n \"X-Zubbl-Geo-Stability\": `${state.geo}/${state.stability.toFixed(2)}`,\n };\n}\n\n// -----------------------------------------------------------\n// 🌍 Initialize Geo Context Immediately\n// -----------------------------------------------------------\nupdateGeo(process.env.ZUBBL_GEO);\n\n","// src/core/storage.ts\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// Generic storage interface\nexport interface IStorage {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttlSeconds?: number): void;\n remove(key: string): void;\n}\n\n// ------------------------------------------------------\n// Node (in-memory) implementation\n// ------------------------------------------------------\n\nclass NodeStorage implements IStorage {\n private store = new Map<string, { value: any; expiresAt?: number }>();\n\n get<T>(key: string): T | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n this.store.set(key, { value, expiresAt });\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n}\n\n// ------------------------------------------------------\n// Browser (localStorage) implementation\n// ------------------------------------------------------\n\nclass BrowserStorage implements IStorage {\n private prefix = \"zubbl_sdk_\";\n\n get<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(this.prefix + key);\n if (!raw) return null;\n const { value, expiresAt } = JSON.parse(raw);\n if (expiresAt && expiresAt < Date.now()) {\n localStorage.removeItem(this.prefix + key);\n return null;\n }\n return value as T;\n } catch {\n return null;\n }\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n try {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n localStorage.setItem(\n this.prefix + key,\n JSON.stringify({ value, expiresAt })\n );\n } catch (err) {\n // localStorage quota exceeded → silently ignore\n console.warn(\"[Zubbl SDK][Storage] Failed to persist item:\", err);\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(this.prefix + key);\n }\n}\n\n// ------------------------------------------------------\n// Factory\n// ------------------------------------------------------\n\nexport function createStorage(): IStorage {\n if (isNode) return new NodeStorage();\n if (isBrowser) return new BrowserStorage();\n\n // Fallback: safe no-op storage for tests / fake environments\n return {\n get: () => null,\n set: () => {},\n remove: () => {},\n };\n}\n\n","// -----------------------------------------------------------\n// 🌍 Zubbl Geo Engine — Multi-Provider Fallback + 15min Cache\n// -----------------------------------------------------------\n// Fully typed, aligns with Zubbl GEO Enforcement Policy\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\nexport interface GeoPrivacy {\n vpn: boolean;\n hosting: boolean;\n}\n\nexport interface GeoInfo {\n ip: string | null;\n country: string;\n asn: string | null;\n privacy: GeoPrivacy;\n}\n\nconst GEO_CACHE_KEY = \"zubbl-geo-cache\";\nconst GEO_TTL_MS = 15 * 60 * 1000; // 15 minutes\n\n// -----------------------------------------------------------\n// 🗃 Cache Helpers\n// -----------------------------------------------------------\nfunction loadGeoCache(): GeoInfo | null {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n const raw = localStorage.getItem(GEO_CACHE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as { data: GeoInfo; timestamp: number };\n if (!parsed.data?.ip || Date.now() - parsed.timestamp > GEO_TTL_MS) return null;\n return parsed.data;\n } catch {\n return null;\n }\n}\n\nfunction saveGeoCache(data: GeoInfo): void {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n localStorage.setItem(GEO_CACHE_KEY, JSON.stringify({ data, timestamp: Date.now() }));\n } catch {}\n}\n\n// -----------------------------------------------------------\n// 🌐 Provider Wrappers\n// -----------------------------------------------------------\nasync function fetchJSON(url: string, timeoutMs = 3000): Promise<any> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const resp = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n return await resp.json();\n } catch (err) {\n clearTimeout(timeout);\n throw err;\n }\n}\n\nasync function providerIpInfo(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipinfo.io/json?token=public\");\n return {\n ip: d.ip || null,\n country: d.country || \"unknown\",\n asn: d.org?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerIpApi(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipapi.co/json/\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: d.asn?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerGeoJs(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://get.geojs.io/v1/ip/geo.json\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\n// -----------------------------------------------------------\n// 🧠 Fallback Resolver\n// -----------------------------------------------------------\nexport async function getGeoInfo(): Promise<GeoInfo> {\n const cached = loadGeoCache();\n if (cached) return cached;\n\n const providers = [providerIpInfo, providerIpApi, providerGeoJs];\n for (const fn of providers) {\n try {\n const result = await fn();\n if (result?.country && result.country !== \"unknown\") {\n saveGeoCache(result);\n return result;\n }\n } catch (err: any) {\n console.warn(\"[Zubbl SDK][Geo] Provider failed:\", fn.name, \"-\", err.message);\n }\n }\n\n const fallback: GeoInfo = {\n ip: null,\n country: \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n saveGeoCache(fallback);\n return fallback;\n}\n\n// -----------------------------------------------------------\n// 🧩 Exported Helpers\n// -----------------------------------------------------------\nexport function clearGeoCache(): void {\n try {\n if (isBrowser && typeof localStorage !== \"undefined\") {\n localStorage.removeItem(GEO_CACHE_KEY);\n }\n } catch {}\n}\n\nexport async function getGeoHeaders(): Promise<Record<string, string>> {\n const geo = await getGeoInfo();\n return {\n \"X-Zubbl-Geo-Country\": geo.country || \"unknown\",\n \"X-Zubbl-ASN\": geo.asn || \"unknown\",\n \"X-Zubbl-IP\": geo.ip || \"\",\n \"X-Zubbl-Privacy-VPN\": String(geo.privacy?.vpn ?? false),\n \"X-Zubbl-Privacy-Hosting\": String(geo.privacy?.hosting ?? false),\n };\n}\n","// -----------------------------------------------------------\n// 🔐 Secure Signing & Nonce Generator\n// -----------------------------------------------------------\n\nimport crypto from \"crypto\";\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Generate UUIDv4 Nonce\n// -----------------------------------------------------------\nexport function generateNonce(): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// -----------------------------------------------------------\n// Compute SHA256 HMAC signature\n// -----------------------------------------------------------\nexport async function signPayload(payload: string, secret: string): Promise<string> {\n if (isNode) {\n // ✅ Node.js native HMAC\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n // ✅ Browser / Worker using WebCrypto\n if (typeof window !== \"undefined\" && window.crypto?.subtle) {\n const key = await window.crypto.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const sig = await window.crypto.subtle.sign(\n \"HMAC\",\n key,\n new TextEncoder().encode(payload)\n );\n\n return Array.from(new Uint8Array(sig))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n throw new Error(\"No crypto implementation available in this environment\");\n}\n\n// -----------------------------------------------------------\n// Attach signing headers to a request (corrected for SDK-12)\n// -----------------------------------------------------------\nexport function attachSigningHeaders(\n url: string,\n method: string,\n headers: Record<string, string> = {},\n body?: any,\n secretKey?: string | null\n): void {\n const nonce = generateNonce();\n\n // Normalize body to a string before hashing\n const normalizedBody =\n typeof body === \"string\"\n ? body\n : body && typeof body === \"object\"\n ? JSON.stringify(body)\n : \"\";\n\n const bodyHash = normalizedBody\n ? crypto.createHash(\"sha256\").update(normalizedBody).digest(\"hex\")\n : \"\";\n\n // Compute canonical string (deterministic)\n const canonical = `${method.toUpperCase()}\\n${url}\\n${nonce}\\n${bodyHash}`;\n\n // Attach nonce and signature headers (in-place)\n headers[\"X-Zubbl-Nonce\"] = nonce;\n\n if (secretKey) {\n const signature = crypto\n .createHmac(\"sha256\", secretKey)\n .update(canonical)\n .digest(\"hex\");\n headers[\"X-Zubbl-Signature\"] = signature;\n }\n}\n","// src/core/http.ts\n// -----------------------------------------------------------\n// HTTP utility (instance-safe)\n// -----------------------------------------------------------\n\nimport { recordContextSample, getAdaptiveHeaders } from \"./context\";\nimport { attachSigningHeaders } from \"./signing\";\n\n\n/**\n * Performs a safe HTTP request with adaptive + signing headers.\n * NOTE: no global getConfig() dependency — caller must provide fully resolved URL + headers.\n */\nexport async function httpRequest(url: string, options: RequestInit = {}): Promise<Response> {\n // 🔧 Default timeout lowered for SDK-12 hardening\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n try {\n const method = (options.method || \"GET\").toUpperCase();\n const body = options.body;\n const headers: Record<string, string> = {\n ...(options.headers as Record<string, string>),\n ...getAdaptiveHeaders(),\n };\n\n // ✅ FIX: include url, method, headers, body\n attachSigningHeaders(url, method, headers, body);\n\n const finalOptions: RequestInit = {\n ...options,\n method,\n headers,\n signal: controller.signal,\n };\n\n // Record adaptive context sample\n recordContextSample(\"/http\", \"GET\", 200, 123);\n\n const response = await fetch(url, finalOptions);\n\n if (!response.ok) {\n console.warn(`[Zubbl SDK][HTTP] ${response.status} on ${url}`);\n }\n\n return response;\n } catch (err: any) {\n console.error(\"[Zubbl SDK][HTTP] Request failed:\", err?.message);\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n}\n","// src/features/identifyUser.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe identifyUser feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\nconst USER_CACHE_KEY = \"external_user_id\";\nconst USER_TTL = 24 * 60 * 60; // 24h\n\nexport async function identifyUserFeature(\n store: any,\n { email, name }: { email: string; name?: string }\n) {\n if (!email) throw new Error(\"email is required\");\n\n const config = store.get();\n const storage = createStorage();\n\n // Check cache\n const cached = storage.get<{ id: string }>(USER_CACHE_KEY);\n if (cached?.id) {\n return { external_user_id: cached.id, cached: true };\n }\n\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use per-instance config store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"Content-Type\": \"application/json\",\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n const resp = await httpRequest(`${config.baseUrl}/sdk/identify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ email, name }),\n });\n\n const data = await resp.json().catch(() => ({}));\n const { external_user_id } = data;\n\n if (!external_user_id) {\n throw new Error(\"Backend did not return external_user_id\");\n }\n\n storage.set(USER_CACHE_KEY, { id: external_user_id }, USER_TTL);\n return { external_user_id, cached: false };\n}\n","// src/features/getTiles.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe getTiles feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\n\nconst TILE_CACHE_KEY = \"tiles_cache\";\nconst TILE_TTL_DEFAULT = 10 * 60; // 10 min\n\ninterface TileCacheEntry {\n data: any;\n etag?: string;\n expiresAt: number;\n}\n\nexport async function getTilesFeature(\n store: any,\n { external_user_id, app_id = null, ttlSeconds = TILE_TTL_DEFAULT }: any\n) {\n const config = store.get();\n const storage = createStorage();\n\n const cached = storage.get<TileCacheEntry>(TILE_CACHE_KEY);\n const isFresh = cached && cached.expiresAt > Date.now();\n\n if (isFresh) {\n backgroundRefresh(store, external_user_id, app_id, ttlSeconds);\n return { data: cached.data, fromCache: true };\n }\n\n try {\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use instance store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n if (cached?.etag) headers[\"If-None-Match\"] = cached.etag;\n\n const params = new URLSearchParams({ external_user_id });\n params.set(\"app_id\", app_id || config.appId!);\n\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/tiles/effective?${params.toString()}`;\n const resp = await httpRequest(url, { headers });\n\n if (resp.status === 304 && cached?.data) {\n cached.expiresAt = Date.now() + ttlSeconds * 1000;\n storage.set(TILE_CACHE_KEY, cached, ttlSeconds);\n return { data: cached.data, fromCache: true, status: 304 };\n }\n\n const data = await resp.json();\n const etag = resp.headers.get(\"ETag\") || undefined;\n\n const entry: TileCacheEntry = {\n data,\n etag,\n expiresAt: Date.now() + ttlSeconds * 1000,\n };\n storage.set(TILE_CACHE_KEY, entry, ttlSeconds);\n\n return { data, fromCache: false, status: resp.status };\n } catch (err) {\n if (cached?.data) {\n return { data: cached.data, fromCache: true, error: String(err) };\n }\n throw err;\n }\n}\n\nasync function backgroundRefresh(store: any, external_user_id: string, app_id: string | null, ttlSeconds: number) {\n try {\n await getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n } catch {\n // Silent background failure\n }\n}\n","// src/client.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Final Instance-based Client (Feature Delegation)\n// -----------------------------------------------------------\n\nimport * as ConfigModule from \"./core/config\";\nimport { createStorage } from \"./core/storage\";\nimport { getGeoInfo } from \"./core/geo\";\n\n// Feature modules\nimport { identifyUserFeature } from \"./features/identifyUser\";\nimport { getTilesFeature } from \"./features/getTiles\";\n\n\nexport type ZubblConfig = {\n apiKey: string;\n tenantId: string;\n appId: string;\n baseUrl?: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n};\n\n/**\n * Creates a self-contained, instance-based Zubbl client.\n * Each instance owns its own config store and initialization state.\n */\nexport function createZubblClient(cfg: ZubblConfig) {\n const store = ConfigModule.createConfigStore();\n const storage = createStorage();\n let initialized = false;\n\n async function init() {\n if (initialized) return;\n\n // ✅ Validate UUIDs before initializing\n const UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n if (!UUID_PATTERN.test(cfg.tenantId)) {\n throw new Error(`[Zubbl SDK] Invalid tenantId: expected UUID, got \"${cfg.tenantId}\"`);\n }\n\n if (!UUID_PATTERN.test(cfg.appId)) {\n throw new Error(`[Zubbl SDK] Invalid appId: expected UUID, got \"${cfg.appId}\"`);\n }\n\n // Initialize per-client config\n store.init(cfg);\n\n // Optional: GEO bootstrap\n try {\n const geo = await getGeoInfo();\n console.log(`[Zubbl SDK] 🌍 GEO detected: ${geo.country} (ASN ${geo.asn || \"?\"})`);\n } catch (err: any) {\n console.warn(\"[Zubbl SDK] GEO init failed:\", err?.message);\n }\n\n initialized = true;\n }\n\n function assertInitialized() {\n if (!initialized) {\n throw new Error(\"Zubbl client not initialized — call client.init() first\");\n }\n }\n\n // ---------------------------------------------------------\n // User + Tile Operations (delegated to feature modules)\n // ---------------------------------------------------------\n async function identifyUser({ email, name }: { email: string; name?: string }) {\n assertInitialized();\n return identifyUserFeature(store, { email, name });\n }\n\n async function getTiles({\n external_user_id,\n app_id = null,\n ttlSeconds,\n }: {\n external_user_id: string;\n app_id?: string | null;\n ttlSeconds?: number;\n }) {\n assertInitialized();\n return getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n }\n\n // ---------------------------------------------------------\n // Enforcement API (kept inline)\n // ---------------------------------------------------------\n async function enforce({\n external_user_id,\n app_id = null,\n }: {\n external_user_id: string;\n app_id?: string | null;\n }) {\n assertInitialized();\n\n const config = store.get();\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n });\n\n const resp = await fetch(`${config.baseUrl?.replace(/\\/$/, \"\")}/sdk/test-enforcement`, {\n method: \"POST\",\n headers,\n });\n\n const json = await resp.json().catch(() => ({}));\n return { decision: \"allow\", status: resp.status, data: json };\n }\n\n // ---------------------------------------------------------\n // Public API\n // ---------------------------------------------------------\n return {\n init,\n identifyUser,\n getTiles,\n enforce,\n storage,\n };\n}\n","// src/index.ts\n// -----------------------------------------------------------\n// Zubbl SDK Entry Point — Public Exports\n// -----------------------------------------------------------\n\n// Core factory + environment\nexport * from \"./core/config\";\nexport * from \"./core/context\";\nexport * from \"./core/storage\";\nexport * from \"./core/geo\";\n\n// Avoid duplicate export of ZubblConfig\nexport {\n createZubblClient, // 🔁 change this if your client.ts exports something else\n} from \"./client\";\n\n// Feature modules (optional direct access)\nexport * from \"./features/identifyUser\";\nexport * from \"./features/getTiles\";\n\nconsole.log(\"[Zubbl SDK] ✅ Entry point loaded\");\n"],"names":["ConfigModule.createConfigStore"],"mappings":"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"}
1
+ {"version":3,"file":"zubbl-sdk.esm.js","sources":["../src/core/config.ts","../src/core/context.ts","../src/core/storage.ts","../src/core/geo.ts","../src/core/signing.ts","../src/core/http.ts","../src/features/identifyUser.ts","../src/features/getTiles.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["// src/core/config.ts\n// -----------------------------------------------------------\n// Universal environment detection + SDK configuration\n// -----------------------------------------------------------\n\nexport const isBrowser =\n typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nexport const isNode =\n typeof process !== \"undefined\" &&\n !!process.versions?.node &&\n !isBrowser;\n\nexport const isWorker =\n typeof self !== \"undefined\" &&\n typeof (self as any).importScripts === \"function\" &&\n !isNode;\n\n// -----------------------------------------------------------\n// Config store factory (no module-scoped state)\n// -----------------------------------------------------------\n\nexport interface ZubblConfig {\n apiKey: string | null;\n tenantId: string | null;\n appId: string | null;\n baseUrl: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n}\n\nfunction assertBrowserSafety(cfg: ZubblConfig) {\n if (isBrowser || isWorker) {\n const key = cfg.apiKey ?? \"\";\n const looksSecret = key.startsWith(\"sk_\") || key.length > 40;\n if (looksSecret) {\n throw new Error(\n \"[Zubbl SDK] Secret or server key detected in browser environment. \" +\n \"Use a public SDK key instead (prefix pk_).\"\n );\n }\n }\n}\n\n/**\n * Creates an isolated configuration store.\n * Each ZubblClient instance owns its own store.\n */\nexport function createConfigStore(initial?: Partial<ZubblConfig>) {\n let current: ZubblConfig = {\n apiKey: null,\n tenantId: null,\n appId: null,\n baseUrl: \"https://api.zubbl.com/api\",\n injectWorkerHeaders: false,\n workerSecret: null,\n ...initial,\n };\n\n function init(partial: Partial<ZubblConfig>) {\n current = { ...current, ...partial };\n assertBrowserSafety(current);\n }\n\n function get(): Readonly<ZubblConfig> {\n return current;\n }\n\n function buildHeaders(extra: Record<string, string> = {}): Record<string, string> {\n if (!current.tenantId || !current.appId) {\n throw new Error(\"[Zubbl SDK] Not initialized – call init() first.\");\n }\n\n const headers: Record<string, string> = {\n \"X-Tenant-Id\": current.tenantId,\n \"X-App-Id\": current.appId,\n \"Content-Type\": \"application/json\",\n ...extra,\n };\n\n if (current.apiKey) {\n headers.Authorization = `Bearer ${current.apiKey}`;\n }\n\n return headers;\n}\n\n return { init, get, buildHeaders };\n}\n\n","// src/core/context.ts\n// -----------------------------------------------------------\n// Adaptive Context Engine — Geo + Stability Enrichment + Persistence\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\ninterface ContextSample {\n path: string;\n method: string;\n ts: number;\n status: number;\n latency: number;\n}\n\ninterface AdaptiveState {\n routes: ContextSample[];\n geo: string;\n stability: number;\n lastGeoChange: number;\n}\n\nconst MAX_HISTORY = 100;\nconst CACHE_KEY = \"zubbl-stability\";\n\nlet state: AdaptiveState = loadStability() ?? {\n routes: [],\n geo: \"unknown\",\n stability: 1.0,\n lastGeoChange: Date.now(),\n};\n\n// -----------------------------------------------------------\n// 💾 Persistence Helpers\n// -----------------------------------------------------------\nfunction loadStability(): AdaptiveState | null {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed.geo || !parsed.stability) return null;\n return { ...parsed, routes: [] };\n } catch {\n return null;\n }\n}\n\nfunction saveStability() {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n try {\n const payload = {\n geo: state.geo,\n stability: state.stability,\n lastGeoChange: state.lastGeoChange,\n };\n localStorage.setItem(CACHE_KEY, JSON.stringify(payload));\n } catch {\n /* ignore */\n }\n}\n\n// -----------------------------------------------------------\n// 🌍 Geo Detection (Node, Browser, Worker)\n// -----------------------------------------------------------\nexport function detectGeo(): string {\n try {\n if (isBrowser && typeof window !== \"undefined\" && window.navigator?.language) {\n return window.navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isWorker && typeof self !== \"undefined\" && (self as any).navigator?.language) {\n return (self as any).navigator.language.split(\"-\")[1] || \"unknown\";\n }\n\n if (isNode && typeof process !== \"undefined\") {\n const envGeo = process.env.ZUBBL_GEO || process.env.GEO;\n if (envGeo && /^[A-Z]{2}$/i.test(envGeo)) return envGeo.toUpperCase();\n return \"GB\";\n }\n\n return \"unknown\";\n } catch (err) {\n console.warn(\"[Zubbl SDK][Geo Detect] Failed:\", err);\n return \"unknown\";\n }\n}\n\n// -----------------------------------------------------------\n// 🧭 Update Geo & Stability (with persistence)\n// -----------------------------------------------------------\nexport function updateGeo(geoHint?: string) {\n const newGeo = geoHint || detectGeo();\n if (newGeo !== state.geo) {\n const now = Date.now();\n const elapsed = (now - state.lastGeoChange) / 1000;\n state.stability = Math.max(0.5, Math.min(1.0, elapsed / 3600));\n state.geo = newGeo;\n state.lastGeoChange = now;\n saveStability();\n } else {\n state.stability = Math.min(1.0, state.stability + 0.01);\n saveStability();\n }\n}\n\n// -----------------------------------------------------------\n// 🧮 Record Context Samples\n// -----------------------------------------------------------\nexport function recordContextSample(\n path: string,\n method: string,\n status: number,\n latency: number\n) {\n state.routes.push({ path, method, ts: Date.now(), status, latency });\n if (state.routes.length > MAX_HISTORY) state.routes.shift();\n updateGeo(); // auto-refresh geo info\n}\n\n// -----------------------------------------------------------\n// 📦 Get Adaptive Headers\n// -----------------------------------------------------------\nexport function getAdaptiveHeaders(): Record<string, string> {\n const currentGeo = detectGeo();\n updateGeo(currentGeo);\n\n const summary = btoa(\n JSON.stringify({\n env: isNode ? \"node\" : isBrowser ? \"browser\" : \"worker\",\n routeCount: state.routes.length,\n lastGeo: state.geo,\n avgLatency:\n state.routes.reduce((a, b) => a + b.latency, 0) /\n Math.max(1, state.routes.length),\n })\n );\n\n return {\n \"X-Zubbl-Context-Summary\": summary,\n \"X-Zubbl-Geo-Stability\": `${state.geo}/${state.stability.toFixed(2)}`,\n };\n}\n\n// -----------------------------------------------------------\n// 🌍 Initialize Geo Context Immediately\n// -----------------------------------------------------------\nupdateGeo(process.env.ZUBBL_GEO);\n\n","// src/core/storage.ts\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// Generic storage interface\nexport interface IStorage {\n get<T>(key: string): T | null;\n set<T>(key: string, value: T, ttlSeconds?: number): void;\n remove(key: string): void;\n}\n\n// ------------------------------------------------------\n// Node (in-memory) implementation\n// ------------------------------------------------------\n\nclass NodeStorage implements IStorage {\n private store = new Map<string, { value: any; expiresAt?: number }>();\n\n get<T>(key: string): T | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt && entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n this.store.set(key, { value, expiresAt });\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n}\n\n// ------------------------------------------------------\n// Browser (localStorage) implementation\n// ------------------------------------------------------\n\nclass BrowserStorage implements IStorage {\n private prefix = \"zubbl_sdk_\";\n\n get<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(this.prefix + key);\n if (!raw) return null;\n const { value, expiresAt } = JSON.parse(raw);\n if (expiresAt && expiresAt < Date.now()) {\n localStorage.removeItem(this.prefix + key);\n return null;\n }\n return value as T;\n } catch {\n return null;\n }\n }\n\n set<T>(key: string, value: T, ttlSeconds?: number): void {\n try {\n const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : undefined;\n localStorage.setItem(\n this.prefix + key,\n JSON.stringify({ value, expiresAt })\n );\n } catch (err) {\n // localStorage quota exceeded → silently ignore\n console.warn(\"[Zubbl SDK][Storage] Failed to persist item:\", err);\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(this.prefix + key);\n }\n}\n\n// ------------------------------------------------------\n// Factory\n// ------------------------------------------------------\n\nexport function createStorage(): IStorage {\n if (isNode) return new NodeStorage();\n if (isBrowser) return new BrowserStorage();\n\n // Fallback: safe no-op storage for tests / fake environments\n return {\n get: () => null,\n set: () => {},\n remove: () => {},\n };\n}\n\n","// -----------------------------------------------------------\n// 🌍 Zubbl Geo Engine — Multi-Provider Fallback + 15min Cache\n// -----------------------------------------------------------\n// Fully typed, aligns with Zubbl GEO Enforcement Policy\n// -----------------------------------------------------------\n\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Types\n// -----------------------------------------------------------\nexport interface GeoPrivacy {\n vpn: boolean;\n hosting: boolean;\n}\n\nexport interface GeoInfo {\n ip: string | null;\n country: string;\n asn: string | null;\n privacy: GeoPrivacy;\n}\n\nconst GEO_CACHE_KEY = \"zubbl-geo-cache\";\nconst GEO_TTL_MS = 15 * 60 * 1000; // 15 minutes\n\n// -----------------------------------------------------------\n// 🗃 Cache Helpers\n// -----------------------------------------------------------\nfunction loadGeoCache(): GeoInfo | null {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return null;\n const raw = localStorage.getItem(GEO_CACHE_KEY);\n if (!raw) return null;\n\n const parsed = JSON.parse(raw) as { data: GeoInfo; timestamp: number };\n if (!parsed.data?.ip || Date.now() - parsed.timestamp > GEO_TTL_MS) return null;\n return parsed.data;\n } catch {\n return null;\n }\n}\n\nfunction saveGeoCache(data: GeoInfo): void {\n try {\n if (!isBrowser || typeof localStorage === \"undefined\") return;\n localStorage.setItem(GEO_CACHE_KEY, JSON.stringify({ data, timestamp: Date.now() }));\n } catch {}\n}\n\n// -----------------------------------------------------------\n// 🌐 Provider Wrappers\n// -----------------------------------------------------------\nasync function fetchJSON(url: string, timeoutMs = 3000): Promise<any> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const resp = await fetch(url, { signal: controller.signal });\n clearTimeout(timeout);\n if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n return await resp.json();\n } catch (err) {\n clearTimeout(timeout);\n throw err;\n }\n}\n\nasync function providerIpInfo(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipinfo.io/json?token=public\");\n return {\n ip: d.ip || null,\n country: d.country || \"unknown\",\n asn: d.org?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerIpApi(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://ipapi.co/json/\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: d.asn?.replace(/^AS/, \"\") || null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\nasync function providerGeoJs(): Promise<GeoInfo> {\n const d = await fetchJSON(\"https://get.geojs.io/v1/ip/geo.json\");\n return {\n ip: d.ip || null,\n country: d.country_code || \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n}\n\n// -----------------------------------------------------------\n// 🧠 Fallback Resolver\n// -----------------------------------------------------------\nexport async function getGeoInfo(): Promise<GeoInfo> {\n const cached = loadGeoCache();\n if (cached) return cached;\n\n const providers = [providerIpInfo, providerIpApi, providerGeoJs];\n for (const fn of providers) {\n try {\n const result = await fn();\n if (result?.country && result.country !== \"unknown\") {\n saveGeoCache(result);\n return result;\n }\n } catch (err: any) {\n console.warn(\"[Zubbl SDK][Geo] Provider failed:\", fn.name, \"-\", err.message);\n }\n }\n\n const fallback: GeoInfo = {\n ip: null,\n country: \"unknown\",\n asn: null,\n privacy: { vpn: false, hosting: false },\n };\n saveGeoCache(fallback);\n return fallback;\n}\n\n// -----------------------------------------------------------\n// 🧩 Exported Helpers\n// -----------------------------------------------------------\nexport function clearGeoCache(): void {\n try {\n if (isBrowser && typeof localStorage !== \"undefined\") {\n localStorage.removeItem(GEO_CACHE_KEY);\n }\n } catch {}\n}\n\nexport async function getGeoHeaders(): Promise<Record<string, string>> {\n const geo = await getGeoInfo();\n return {\n \"X-Zubbl-Geo-Country\": geo.country || \"unknown\",\n \"X-Zubbl-ASN\": geo.asn || \"unknown\",\n \"X-Zubbl-IP\": geo.ip || \"\",\n \"X-Zubbl-Privacy-VPN\": String(geo.privacy?.vpn ?? false),\n \"X-Zubbl-Privacy-Hosting\": String(geo.privacy?.hosting ?? false),\n };\n}\n","// -----------------------------------------------------------\n// 🔐 Secure Signing & Nonce Generator\n// -----------------------------------------------------------\n\nimport crypto from \"crypto\";\nimport { isNode, isBrowser, isWorker } from \"./config\";\n\n// -----------------------------------------------------------\n// Generate UUIDv4 Nonce\n// -----------------------------------------------------------\nexport function generateNonce(): string {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// -----------------------------------------------------------\n// Compute SHA256 HMAC signature\n// -----------------------------------------------------------\nexport async function signPayload(payload: string, secret: string): Promise<string> {\n if (isNode) {\n // ✅ Node.js native HMAC\n return crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n }\n\n // ✅ Browser / Worker using WebCrypto\n if (typeof window !== \"undefined\" && window.crypto?.subtle) {\n const key = await window.crypto.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n\n const sig = await window.crypto.subtle.sign(\n \"HMAC\",\n key,\n new TextEncoder().encode(payload)\n );\n\n return Array.from(new Uint8Array(sig))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n throw new Error(\"No crypto implementation available in this environment\");\n}\n\n// -----------------------------------------------------------\n// Attach signing headers to a request (corrected for SDK-12)\n// -----------------------------------------------------------\nexport function attachSigningHeaders(\n url: string,\n method: string,\n headers: Record<string, string> = {},\n body?: any,\n secretKey?: string | null\n): void {\n const nonce = generateNonce();\n\n // Normalize body to a string before hashing\n const normalizedBody =\n typeof body === \"string\"\n ? body\n : body && typeof body === \"object\"\n ? JSON.stringify(body)\n : \"\";\n\n const bodyHash = normalizedBody\n ? crypto.createHash(\"sha256\").update(normalizedBody).digest(\"hex\")\n : \"\";\n\n // Compute canonical string (deterministic)\n const canonical = `${method.toUpperCase()}\\n${url}\\n${nonce}\\n${bodyHash}`;\n\n // Attach nonce and signature headers (in-place)\n headers[\"X-Zubbl-Nonce\"] = nonce;\n\n if (secretKey) {\n const signature = crypto\n .createHmac(\"sha256\", secretKey)\n .update(canonical)\n .digest(\"hex\");\n headers[\"X-Zubbl-Signature\"] = signature;\n }\n}\n","// src/core/http.ts\n// -----------------------------------------------------------\n// HTTP utility (instance-safe)\n// -----------------------------------------------------------\n\nimport { recordContextSample, getAdaptiveHeaders } from \"./context\";\nimport { attachSigningHeaders } from \"./signing\";\n\n\n/**\n * Performs a safe HTTP request with adaptive + signing headers.\n * NOTE: no global getConfig() dependency — caller must provide fully resolved URL + headers.\n */\nexport async function httpRequest(url: string, options: RequestInit = {}): Promise<Response> {\n // 🔧 Default timeout lowered for SDK-12 hardening\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n try {\n const method = (options.method || \"GET\").toUpperCase();\n const body = options.body;\n const headers: Record<string, string> = {\n ...(options.headers as Record<string, string>),\n ...getAdaptiveHeaders(),\n };\n\n // ✅ FIX: include url, method, headers, body\n attachSigningHeaders(url, method, headers, body);\n\n const finalOptions: RequestInit = {\n ...options,\n method,\n headers,\n signal: controller.signal,\n };\n\n // Record adaptive context sample\n recordContextSample(\"/http\", \"GET\", 200, 123);\n\n const response = await fetch(url, finalOptions);\n\n if (!response.ok) {\n console.warn(`[Zubbl SDK][HTTP] ${response.status} on ${url}`);\n }\n\n return response;\n } catch (err: any) {\n console.error(\"[Zubbl SDK][HTTP] Request failed:\", err?.message);\n throw err;\n } finally {\n clearTimeout(timeout);\n }\n}\n","// src/features/identifyUser.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe identifyUser feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\nconst USER_CACHE_KEY = \"external_user_id\";\nconst USER_TTL = 24 * 60 * 60; // 24h\n\nexport async function identifyUserFeature(\n store: any,\n { email, name }: { email: string; name?: string }\n) {\n if (!email) throw new Error(\"email is required\");\n\n const config = store.get();\n const storage = createStorage();\n\n // Check cache\n const cached = storage.get<{ id: string }>(USER_CACHE_KEY);\n if (cached?.id) {\n return { external_user_id: cached.id, cached: true };\n }\n\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use per-instance config store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"Content-Type\": \"application/json\",\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n const resp = await httpRequest(`${config.baseUrl}/sdk/identify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ email, name }),\n });\n\n const data = await resp.json().catch(() => ({}));\n const { external_user_id } = data;\n\n if (!external_user_id) {\n throw new Error(\"Backend did not return external_user_id\");\n }\n\n storage.set(USER_CACHE_KEY, { id: external_user_id }, USER_TTL);\n return { external_user_id, cached: false };\n}\n","// src/features/getTiles.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Instance-safe getTiles feature\n// -----------------------------------------------------------\n\nimport { httpRequest } from \"../core/http\";\nimport { createStorage } from \"../core/storage\";\nimport { getAdaptiveHeaders } from \"../core/context\";\nimport { getGeoHeaders } from \"../core/geo\";\n\n\nconst TILE_CACHE_KEY = \"tiles_cache\";\nconst TILE_TTL_DEFAULT = 10 * 60; // 10 min\n\ninterface TileCacheEntry {\n data: any;\n etag?: string;\n expiresAt: number;\n}\n\nexport async function getTilesFeature(\n store: any,\n { external_user_id, app_id = null, ttlSeconds = TILE_TTL_DEFAULT }: any\n) {\n const config = store.get();\n const storage = createStorage();\n\n const cached = storage.get<TileCacheEntry>(TILE_CACHE_KEY);\n const isFresh = cached && cached.expiresAt > Date.now();\n\n if (isFresh) {\n backgroundRefresh(store, external_user_id, app_id, ttlSeconds);\n return { data: cached.data, fromCache: true };\n }\n\n try {\n const adaptiveHeaders = getAdaptiveHeaders();\n const geoHeaders = await getGeoHeaders();\n\n // ✅ Use instance store, not global buildHeaders()\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n ...adaptiveHeaders,\n ...geoHeaders,\n });\n\n // Modern endpoint: POST /api/sdk/policies with body (per architecture docs)\nconst payload = {\n tenant_id: config.tenantId,\n app_id: app_id || config.appId!,\n external_user_id,\n};\n\nconst resp = await httpRequest(`${config.baseUrl.replace(/\\/$/, \"\")}/api/sdk/policies`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n});\n\n if (resp.status === 304 && cached?.data) {\n cached.expiresAt = Date.now() + ttlSeconds * 1000;\n storage.set(TILE_CACHE_KEY, cached, ttlSeconds);\n return { data: cached.data, fromCache: true, status: 304 };\n }\n\n const data = await resp.json();\n const etag = resp.headers.get(\"ETag\") || undefined;\n\n const entry: TileCacheEntry = {\n data,\n etag,\n expiresAt: Date.now() + ttlSeconds * 1000,\n };\n storage.set(TILE_CACHE_KEY, entry, ttlSeconds);\n\n return { data, fromCache: false, status: resp.status };\n } catch (err) {\n if (cached?.data) {\n return { data: cached.data, fromCache: true, error: String(err) };\n }\n throw err;\n }\n}\n\nasync function backgroundRefresh(store: any, external_user_id: string, app_id: string | null, ttlSeconds: number) {\n try {\n await getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n } catch {\n // Silent background failure\n }\n}\n","// src/client.ts\n// -----------------------------------------------------------\n// Zubbl SDK — Final Instance-based Client (Feature Delegation)\n// -----------------------------------------------------------\n\nimport * as ConfigModule from \"./core/config\";\nimport { createStorage } from \"./core/storage\";\nimport { getGeoInfo } from \"./core/geo\";\n\n// Feature modules\nimport { identifyUserFeature } from \"./features/identifyUser\";\nimport { getTilesFeature } from \"./features/getTiles\";\n\n\nexport type ZubblConfig = {\n apiKey: string;\n tenantId: string;\n appId: string;\n baseUrl?: string;\n injectWorkerHeaders?: boolean;\n workerSecret?: string | null;\n};\n\n/**\n * Creates a self-contained, instance-based Zubbl client.\n * Each instance owns its own config store and initialization state.\n */\nexport function createZubblClient(cfg: ZubblConfig) {\n const store = ConfigModule.createConfigStore();\n const storage = createStorage();\n let initialized = false;\n\n async function init() {\n if (initialized) return;\n\n // ✅ Validate UUIDs before initializing\n const UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n if (!UUID_PATTERN.test(cfg.tenantId)) {\n throw new Error(`[Zubbl SDK] Invalid tenantId: expected UUID, got \"${cfg.tenantId}\"`);\n }\n\n if (!UUID_PATTERN.test(cfg.appId)) {\n throw new Error(`[Zubbl SDK] Invalid appId: expected UUID, got \"${cfg.appId}\"`);\n }\n\n // Initialize per-client config\n store.init(cfg);\n\n // Optional: GEO bootstrap\n try {\n const geo = await getGeoInfo();\n console.log(`[Zubbl SDK] 🌍 GEO detected: ${geo.country} (ASN ${geo.asn || \"?\"})`);\n } catch (err: any) {\n console.warn(\"[Zubbl SDK] GEO init failed:\", err?.message);\n }\n\n initialized = true;\n }\n\n function assertInitialized() {\n if (!initialized) {\n throw new Error(\"Zubbl client not initialized — call client.init() first\");\n }\n }\n\n // ---------------------------------------------------------\n // User + Tile Operations (delegated to feature modules)\n // ---------------------------------------------------------\n async function identifyUser({ email, name }: { email: string; name?: string }) {\n assertInitialized();\n return identifyUserFeature(store, { email, name });\n }\n\n async function getTiles({\n external_user_id,\n app_id = null,\n ttlSeconds,\n }: {\n external_user_id: string;\n app_id?: string | null;\n ttlSeconds?: number;\n }) {\n assertInitialized();\n return getTilesFeature(store, { external_user_id, app_id, ttlSeconds });\n }\n\n // ---------------------------------------------------------\n // Enforcement API (kept inline)\n // ---------------------------------------------------------\n async function enforce({\n external_user_id,\n app_id = null,\n }: {\n external_user_id: string;\n app_id?: string | null;\n }) {\n assertInitialized();\n\n const config = store.get();\n const headers = store.buildHeaders({\n \"X-External-User-Id\": external_user_id,\n });\n\n const resp = await fetch(`${config.baseUrl?.replace(/\\/$/, \"\")}/sdk/test-enforcement`, {\n method: \"POST\",\n headers,\n });\n\n const json = await resp.json().catch(() => ({}));\n return { decision: \"allow\", status: resp.status, data: json };\n }\n\n // ---------------------------------------------------------\n // Public API\n // ---------------------------------------------------------\n return {\n init,\n identifyUser,\n getTiles,\n enforce,\n storage,\n };\n}\n","// src/index.ts\n// -----------------------------------------------------------\n// Zubbl SDK Entry Point — Public Exports\n// -----------------------------------------------------------\n\n// Core factory + environment\nexport * from \"./core/config\";\nexport * from \"./core/context\";\nexport * from \"./core/storage\";\nexport * from \"./core/geo\";\n\n// Avoid duplicate export of ZubblConfig\nexport {\n createZubblClient, // 🔁 change this if your client.ts exports something else\n} from \"./client\";\n\n// Feature modules (optional direct access)\nexport * from \"./features/identifyUser\";\nexport * from \"./features/getTiles\";\n\nconsole.log(\"[Zubbl SDK] ✅ Entry point loaded\");\n"],"names":["ConfigModule.createConfigStore"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zubbl-sdk",
3
- "version": "1.1.30",
3
+ "version": "1.1.31",
4
4
  "type": "module",
5
5
  "description": "Zubbl SDK for secure policy enforcement (browser, Node, universal)",
6
6
  "main": "dist/zubbl-sdk.cjs.js",