You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@openpanel/sdk

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openpanel/sdk - npm Package Compare versions

Comparing version
1.0.0
to
1.0.1
+1
-2
dist/index.cjs

@@ -1,2 +0,1 @@

"use strict";var l=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var f=(i,e)=>{for(var r in e)l(i,r,{get:e[r],enumerable:!0})},g=(i,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of c(e))!u.call(i,t)&&t!==r&&l(i,t,{get:()=>e[t],enumerable:!(s=y(e,t))||s.enumerable});return i};var h=i=>g(l({},"__esModule",{value:!0}),i);var m={};f(m,{OpenPanel:()=>p});module.exports=h(m);var o=class{constructor(e){this.baseUrl=e.baseUrl,this.headers={"Content-Type":"application/json",...e.defaultHeaders},this.maxRetries=e.maxRetries??3,this.initialRetryDelay=e.initialRetryDelay??500}async resolveHeaders(){let e={};for(let[r,s]of Object.entries(this.headers)){let t=await s;t!==null&&(e[r]=t)}return e}addHeader(e,r){this.headers[e]=r}async post(e,r,s,t){try{let n=await fetch(e,{method:"POST",headers:await this.resolveHeaders(),body:JSON.stringify(r??{}),keepalive:!0,...s});if(n.status===401)return null;if(n.status!==200&&n.status!==202)throw new Error(`HTTP error! status: ${n.status}`);let a=await n.text();return a?JSON.parse(a):null}catch(n){if(t<this.maxRetries){let a=this.initialRetryDelay*Math.pow(2,t);return await new Promise(d=>setTimeout(d,a)),this.post(e,r,s,t+1)}return console.error("Max retries reached:",n),null}}async fetch(e,r,s={}){let t=`${this.baseUrl}${e}`;return this.post(t,r,s,0)}};var p=class{constructor(e){this.options=e;this.queue=[];let r={"openpanel-client-id":e.clientId};e.clientSecret&&(r["openpanel-client-secret"]=e.clientSecret),r["openpanel-sdk-name"]=e.sdk||"node",r["openpanel-sdk-version"]=e.sdkVersion||"1.0.0",this.api=new o({baseUrl:e.apiUrl||"https://api.openpanel.dev",defaultHeaders:r})}init(){}ready(){this.options.waitForProfile=!1,this.flush()}async send(e){return this.options.disabled||this.options.filter&&!this.options.filter(e)?Promise.resolve():this.options.waitForProfile&&!this.profileId?(this.queue.push(e),Promise.resolve()):this.api.fetch("/track",e)}setGlobalProperties(e){this.global={...this.global,...e}}async track(e,r){return this.send({type:"track",payload:{name:e,profileId:r?.profileId??this.profileId,properties:{...this.global??{},...r??{}}}})}async identify(e){if(e.profileId&&(this.profileId=e.profileId,this.flush()),Object.keys(e).length>1)return this.send({type:"identify",payload:{...e,properties:{...this.global,...e.properties}}})}async alias(e){return this.send({type:"alias",payload:e})}async increment(e){return this.send({type:"increment",payload:e})}async decrement(e){return this.send({type:"decrement",payload:e})}clear(){this.profileId=void 0}flush(){this.queue.forEach(e=>{this.send({...e,payload:{...e.payload,profileId:e.payload.profileId??this.profileId}})}),this.queue=[]}};0&&(module.exports={OpenPanel});
//# sourceMappingURL=index.cjs.map
"use strict";var l=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var f=(s,e)=>{for(var r in e)l(s,r,{get:e[r],enumerable:!0})},g=(s,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of y(e))!u.call(s,t)&&t!==r&&l(s,t,{get:()=>e[t],enumerable:!(i=c(e,t))||i.enumerable});return s};var h=s=>g(l({},"__esModule",{value:!0}),s);var m={};f(m,{OpenPanel:()=>d});module.exports=h(m);var o=class{constructor(e){this.baseUrl=e.baseUrl,this.headers={"Content-Type":"application/json",...e.defaultHeaders},this.maxRetries=e.maxRetries??3,this.initialRetryDelay=e.initialRetryDelay??500}async resolveHeaders(){let e={};for(let[r,i]of Object.entries(this.headers)){let t=await i;t!==null&&(e[r]=t)}return e}addHeader(e,r){this.headers[e]=r}async post(e,r,i,t){try{let n=await fetch(e,{method:"POST",headers:await this.resolveHeaders(),body:JSON.stringify(r??{}),keepalive:!0,...i});if(n.status===401)return null;if(n.status!==200&&n.status!==202)throw new Error(`HTTP error! status: ${n.status}`);let a=await n.text();return a?JSON.parse(a):null}catch(n){if(t<this.maxRetries){let a=this.initialRetryDelay*2**t;return await new Promise(p=>setTimeout(p,a)),this.post(e,r,i,t+1)}return console.error("Max retries reached:",n),null}}async fetch(e,r,i={}){let t=`${this.baseUrl}${e}`;return this.post(t,r,i,0)}};var d=class{constructor(e){this.options=e;this.queue=[];let r={"openpanel-client-id":e.clientId};e.clientSecret&&(r["openpanel-client-secret"]=e.clientSecret),r["openpanel-sdk-name"]=e.sdk||"node",r["openpanel-sdk-version"]=e.sdkVersion||"1.0.1",this.api=new o({baseUrl:e.apiUrl||"https://api.openpanel.dev",defaultHeaders:r})}init(){}ready(){this.options.waitForProfile=!1,this.flush()}async send(e){return this.options.disabled||this.options.filter&&!this.options.filter(e)?Promise.resolve():this.options.waitForProfile&&!this.profileId?(this.queue.push(e),Promise.resolve()):this.api.fetch("/track",e)}setGlobalProperties(e){this.global={...this.global,...e}}async track(e,r){return this.send({type:"track",payload:{name:e,profileId:r?.profileId??this.profileId,properties:{...this.global??{},...r??{}}}})}async identify(e){if(e.profileId&&(this.profileId=e.profileId,this.flush()),Object.keys(e).length>1)return this.send({type:"identify",payload:{...e,properties:{...this.global,...e.properties}}})}async alias(e){return this.send({type:"alias",payload:e})}async increment(e){return this.send({type:"increment",payload:e})}async decrement(e){return this.send({type:"decrement",payload:e})}async revenue(e,r){let i=r?.deviceId;return delete r?.deviceId,this.track("revenue",{...r??{},...i?{__deviceId:i}:{},__revenue:e})}async fetchDeviceId(){return(await this.api.fetch("/track/device-id",void 0,{method:"GET",keepalive:!1}))?.deviceId??""}clear(){this.profileId=void 0}flush(){this.queue.forEach(e=>{this.send({...e,payload:{...e.payload,profileId:e.payload.profileId??this.profileId}})}),this.queue=[]}};0&&(module.exports={OpenPanel});

@@ -95,2 +95,6 @@ interface ApiConfig {

decrement(payload: DecrementPayload): Promise<unknown>;
revenue(amount: number, properties?: TrackProperties & {
deviceId?: string;
}): Promise<unknown>;
fetchDeviceId(): Promise<string>;
clear(): void;

@@ -97,0 +101,0 @@ flush(): void;

@@ -95,2 +95,6 @@ interface ApiConfig {

decrement(payload: DecrementPayload): Promise<unknown>;
revenue(amount: number, properties?: TrackProperties & {
deviceId?: string;
}): Promise<unknown>;
fetchDeviceId(): Promise<string>;
clear(): void;

@@ -97,0 +101,0 @@ flush(): void;

@@ -1,2 +0,1 @@

var a=class{constructor(e){this.baseUrl=e.baseUrl,this.headers={"Content-Type":"application/json",...e.defaultHeaders},this.maxRetries=e.maxRetries??3,this.initialRetryDelay=e.initialRetryDelay??500}async resolveHeaders(){let e={};for(let[r,s]of Object.entries(this.headers)){let t=await s;t!==null&&(e[r]=t)}return e}addHeader(e,r){this.headers[e]=r}async post(e,r,s,t){try{let i=await fetch(e,{method:"POST",headers:await this.resolveHeaders(),body:JSON.stringify(r??{}),keepalive:!0,...s});if(i.status===401)return null;if(i.status!==200&&i.status!==202)throw new Error(`HTTP error! status: ${i.status}`);let n=await i.text();return n?JSON.parse(n):null}catch(i){if(t<this.maxRetries){let n=this.initialRetryDelay*Math.pow(2,t);return await new Promise(p=>setTimeout(p,n)),this.post(e,r,s,t+1)}return console.error("Max retries reached:",i),null}}async fetch(e,r,s={}){let t=`${this.baseUrl}${e}`;return this.post(t,r,s,0)}};var o=class{constructor(e){this.options=e;this.queue=[];let r={"openpanel-client-id":e.clientId};e.clientSecret&&(r["openpanel-client-secret"]=e.clientSecret),r["openpanel-sdk-name"]=e.sdk||"node",r["openpanel-sdk-version"]=e.sdkVersion||"1.0.0",this.api=new a({baseUrl:e.apiUrl||"https://api.openpanel.dev",defaultHeaders:r})}init(){}ready(){this.options.waitForProfile=!1,this.flush()}async send(e){return this.options.disabled||this.options.filter&&!this.options.filter(e)?Promise.resolve():this.options.waitForProfile&&!this.profileId?(this.queue.push(e),Promise.resolve()):this.api.fetch("/track",e)}setGlobalProperties(e){this.global={...this.global,...e}}async track(e,r){return this.send({type:"track",payload:{name:e,profileId:r?.profileId??this.profileId,properties:{...this.global??{},...r??{}}}})}async identify(e){if(e.profileId&&(this.profileId=e.profileId,this.flush()),Object.keys(e).length>1)return this.send({type:"identify",payload:{...e,properties:{...this.global,...e.properties}}})}async alias(e){return this.send({type:"alias",payload:e})}async increment(e){return this.send({type:"increment",payload:e})}async decrement(e){return this.send({type:"decrement",payload:e})}clear(){this.profileId=void 0}flush(){this.queue.forEach(e=>{this.send({...e,payload:{...e.payload,profileId:e.payload.profileId??this.profileId}})}),this.queue=[]}};export{o as OpenPanel};
//# sourceMappingURL=index.js.map
var a=class{constructor(e){this.baseUrl=e.baseUrl,this.headers={"Content-Type":"application/json",...e.defaultHeaders},this.maxRetries=e.maxRetries??3,this.initialRetryDelay=e.initialRetryDelay??500}async resolveHeaders(){let e={};for(let[r,t]of Object.entries(this.headers)){let i=await t;i!==null&&(e[r]=i)}return e}addHeader(e,r){this.headers[e]=r}async post(e,r,t,i){try{let s=await fetch(e,{method:"POST",headers:await this.resolveHeaders(),body:JSON.stringify(r??{}),keepalive:!0,...t});if(s.status===401)return null;if(s.status!==200&&s.status!==202)throw new Error(`HTTP error! status: ${s.status}`);let n=await s.text();return n?JSON.parse(n):null}catch(s){if(i<this.maxRetries){let n=this.initialRetryDelay*2**i;return await new Promise(d=>setTimeout(d,n)),this.post(e,r,t,i+1)}return console.error("Max retries reached:",s),null}}async fetch(e,r,t={}){let i=`${this.baseUrl}${e}`;return this.post(i,r,t,0)}};var o=class{constructor(e){this.options=e;this.queue=[];let r={"openpanel-client-id":e.clientId};e.clientSecret&&(r["openpanel-client-secret"]=e.clientSecret),r["openpanel-sdk-name"]=e.sdk||"node",r["openpanel-sdk-version"]=e.sdkVersion||"1.0.1",this.api=new a({baseUrl:e.apiUrl||"https://api.openpanel.dev",defaultHeaders:r})}init(){}ready(){this.options.waitForProfile=!1,this.flush()}async send(e){return this.options.disabled||this.options.filter&&!this.options.filter(e)?Promise.resolve():this.options.waitForProfile&&!this.profileId?(this.queue.push(e),Promise.resolve()):this.api.fetch("/track",e)}setGlobalProperties(e){this.global={...this.global,...e}}async track(e,r){return this.send({type:"track",payload:{name:e,profileId:r?.profileId??this.profileId,properties:{...this.global??{},...r??{}}}})}async identify(e){if(e.profileId&&(this.profileId=e.profileId,this.flush()),Object.keys(e).length>1)return this.send({type:"identify",payload:{...e,properties:{...this.global,...e.properties}}})}async alias(e){return this.send({type:"alias",payload:e})}async increment(e){return this.send({type:"increment",payload:e})}async decrement(e){return this.send({type:"decrement",payload:e})}async revenue(e,r){let t=r?.deviceId;return delete r?.deviceId,this.track("revenue",{...r??{},...t?{__deviceId:t}:{},__revenue:e})}async fetchDeviceId(){return(await this.api.fetch("/track/device-id",void 0,{method:"GET",keepalive:!1}))?.deviceId??""}clear(){this.profileId=void 0}flush(){this.queue.forEach(e=>{this.send({...e,payload:{...e.payload,profileId:e.payload.profileId??this.profileId}})}),this.queue=[]}};export{o as OpenPanel};
{
"name": "@openpanel/sdk",
"version": "1.0.0",
"module": "./dist/index.mjs",
"version": "1.0.1",
"module": "./dist/index.js",
"scripts": {
"build": "rm -rf dist && tsup",
"lint": "eslint .",
"format": "prettier --check \"**/*.{mjs,ts,md,json}\"",
"typecheck": "tsc --noEmit"

@@ -13,18 +11,7 @@ },

"devDependencies": {
"@openpanel/eslint-config": "workspace:*",
"@openpanel/prettier-config": "workspace:*",
"@openpanel/tsconfig": "workspace:*",
"@types/node": "^20.14.12",
"eslint": "^8.48.0",
"prettier": "^3.0.3",
"@types/node": "catalog:",
"tsup": "^7.2.0",
"typescript": "^5.2.2"
"typescript": "catalog:"
},
"eslintConfig": {
"root": true,
"extends": [
"@openpanel/eslint-config/base"
]
},
"prettier": "@openpanel/prettier-config",
"private": false,

@@ -34,5 +21,3 @@ "type": "module",

"types": "./dist/index.d.ts",
"files": [
"dist"
],
"files": ["dist"],
"exports": {

@@ -45,2 +30,2 @@ ".": {

}
}
}
{"version":3,"sources":["../index.ts","../src/api.ts","../src/index.ts"],"sourcesContent":["export * from './src/index';\n\n// Deprecated types for beta version of the SDKs\n// Still used in api/event.controller.ts and api/profile.controller.ts\n\nexport interface OpenpanelEventOptions {\n profileId?: string;\n}\n\nexport interface PostEventPayload {\n name: string;\n timestamp: string;\n profileId?: string;\n properties?: Record<string, unknown> & OpenpanelEventOptions;\n}\n\nexport interface UpdateProfilePayload {\n profileId: string;\n firstName?: string;\n lastName?: string;\n email?: string;\n avatar?: string;\n properties?: Record<string, unknown>;\n}\n\nexport interface IncrementProfilePayload {\n profileId: string;\n property: string;\n value: number;\n}\n\nexport interface DecrementProfilePayload {\n profileId?: string;\n property: string;\n value: number;\n}\n","interface ApiConfig {\n baseUrl: string;\n defaultHeaders?: Record<string, string | Promise<string | null>>;\n maxRetries?: number;\n initialRetryDelay?: number;\n}\n\ninterface FetchOptions extends RequestInit {\n retries?: number;\n}\n\nexport class Api {\n private baseUrl: string;\n private headers: Record<string, string | Promise<string | null>>;\n private maxRetries: number;\n private initialRetryDelay: number;\n\n constructor(config: ApiConfig) {\n this.baseUrl = config.baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n };\n this.maxRetries = config.maxRetries ?? 3;\n this.initialRetryDelay = config.initialRetryDelay ?? 500;\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n const resolvedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(this.headers)) {\n const resolvedValue = await value;\n if (resolvedValue !== null) {\n resolvedHeaders[key] = resolvedValue;\n }\n }\n return resolvedHeaders;\n }\n\n public addHeader(key: string, value: string | Promise<string | null>) {\n this.headers[key] = value;\n }\n\n private async post<ReqBody, ResBody>(\n url: string,\n data: ReqBody,\n options: FetchOptions,\n attempt: number\n ): Promise<ResBody | null> {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.resolveHeaders(),\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...options,\n });\n\n if (response.status === 401) return null;\n\n if (response.status !== 200 && response.status !== 202) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const responseText = await response.text();\n return responseText ? JSON.parse(responseText) : null;\n } catch (error) {\n if (attempt < this.maxRetries) {\n const delay = this.initialRetryDelay * Math.pow(2, attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n return this.post<ReqBody, ResBody>(url, data, options, attempt + 1);\n }\n console.error('Max retries reached:', error);\n return null;\n }\n }\n\n async fetch<ReqBody, ResBody>(\n path: string,\n data: ReqBody,\n options: FetchOptions = {}\n ): Promise<ResBody | null> {\n const url = `${this.baseUrl}${path}`;\n return this.post<ReqBody, ResBody>(url, data, options, 0);\n }\n}\n","import { Api } from './api';\n\nexport type TrackHandlerPayload =\n | {\n type: 'track';\n payload: TrackPayload;\n }\n | {\n type: 'increment';\n payload: IncrementPayload;\n }\n | {\n type: 'decrement';\n payload: DecrementPayload;\n }\n | {\n type: 'alias';\n payload: AliasPayload;\n }\n | {\n type: 'identify';\n payload: IdentifyPayload;\n };\n\nexport type TrackPayload = {\n name: string;\n properties?: Record<string, unknown>;\n profileId?: string;\n};\n\nexport type TrackProperties = {\n [key: string]: unknown;\n profileId?: string;\n};\n\nexport type IdentifyPayload = {\n profileId: string;\n firstName?: string;\n lastName?: string;\n email?: string;\n avatar?: string;\n properties?: Record<string, unknown>;\n};\n\nexport type AliasPayload = {\n profileId: string;\n alias: string;\n};\n\nexport type IncrementPayload = {\n profileId: string;\n property: string;\n value?: number;\n};\n\nexport type DecrementPayload = {\n profileId: string;\n property: string;\n value?: number;\n};\n\nexport type OpenPanelOptions = {\n clientId: string;\n clientSecret?: string;\n apiUrl?: string;\n sdk?: string;\n sdkVersion?: string;\n waitForProfile?: boolean;\n filter?: (payload: TrackHandlerPayload) => boolean;\n disabled?: boolean;\n};\n\nexport class OpenPanel {\n api: Api;\n profileId?: string;\n global?: Record<string, unknown>;\n queue: TrackHandlerPayload[] = [];\n\n constructor(public options: OpenPanelOptions) {\n const defaultHeaders: Record<string, string> = {\n 'openpanel-client-id': options.clientId,\n };\n\n if (options.clientSecret) {\n defaultHeaders['openpanel-client-secret'] = options.clientSecret;\n }\n\n defaultHeaders['openpanel-sdk-name'] = options.sdk || 'node';\n defaultHeaders['openpanel-sdk-version'] =\n options.sdkVersion || process.env.SDK_VERSION!;\n\n this.api = new Api({\n baseUrl: options.apiUrl || 'https://api.openpanel.dev',\n defaultHeaders,\n });\n }\n\n // placeholder for future use\n init() {\n // empty\n }\n\n ready() {\n this.options.waitForProfile = false;\n this.flush();\n }\n\n async send(payload: TrackHandlerPayload) {\n if (this.options.disabled) {\n return Promise.resolve();\n }\n\n if (this.options.filter && !this.options.filter(payload)) {\n return Promise.resolve();\n }\n\n if (this.options.waitForProfile && !this.profileId) {\n this.queue.push(payload);\n return Promise.resolve();\n }\n return this.api.fetch('/track', payload);\n }\n\n setGlobalProperties(properties: Record<string, unknown>) {\n this.global = {\n ...this.global,\n ...properties,\n };\n }\n\n async track(name: string, properties?: TrackProperties) {\n return this.send({\n type: 'track',\n payload: {\n name,\n profileId: properties?.profileId ?? this.profileId,\n properties: {\n ...(this.global ?? {}),\n ...(properties ?? {}),\n },\n },\n });\n }\n\n async identify(payload: IdentifyPayload) {\n if (payload.profileId) {\n this.profileId = payload.profileId;\n this.flush();\n }\n\n if (Object.keys(payload).length > 1) {\n return this.send({\n type: 'identify',\n payload: {\n ...payload,\n properties: {\n ...this.global,\n ...payload.properties,\n },\n },\n });\n }\n }\n\n async alias(payload: AliasPayload) {\n return this.send({\n type: 'alias',\n payload,\n });\n }\n\n async increment(payload: IncrementPayload) {\n return this.send({\n type: 'increment',\n payload,\n });\n }\n\n async decrement(payload: DecrementPayload) {\n return this.send({\n type: 'decrement',\n payload,\n });\n }\n\n clear() {\n this.profileId = undefined;\n // should we force a session end here?\n }\n\n flush() {\n this.queue.forEach((item) => {\n this.send({\n ...item,\n // Not sure why ts-expect-error is needed here\n // @ts-expect-error\n payload: {\n ...item.payload,\n profileId: item.payload.profileId ?? this.profileId,\n },\n });\n });\n this.queue = [];\n }\n}\n"],"mappings":"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","names":["sdk_exports","__export","OpenPanel","__toCommonJS","Api","config","resolvedHeaders","key","value","resolvedValue","url","data","options","attempt","response","responseText","error","delay","resolve","path","OpenPanel","options","defaultHeaders","Api","payload","properties","name","item"]}
{"version":3,"sources":["../src/api.ts","../src/index.ts"],"sourcesContent":["interface ApiConfig {\n baseUrl: string;\n defaultHeaders?: Record<string, string | Promise<string | null>>;\n maxRetries?: number;\n initialRetryDelay?: number;\n}\n\ninterface FetchOptions extends RequestInit {\n retries?: number;\n}\n\nexport class Api {\n private baseUrl: string;\n private headers: Record<string, string | Promise<string | null>>;\n private maxRetries: number;\n private initialRetryDelay: number;\n\n constructor(config: ApiConfig) {\n this.baseUrl = config.baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n };\n this.maxRetries = config.maxRetries ?? 3;\n this.initialRetryDelay = config.initialRetryDelay ?? 500;\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n const resolvedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(this.headers)) {\n const resolvedValue = await value;\n if (resolvedValue !== null) {\n resolvedHeaders[key] = resolvedValue;\n }\n }\n return resolvedHeaders;\n }\n\n public addHeader(key: string, value: string | Promise<string | null>) {\n this.headers[key] = value;\n }\n\n private async post<ReqBody, ResBody>(\n url: string,\n data: ReqBody,\n options: FetchOptions,\n attempt: number\n ): Promise<ResBody | null> {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.resolveHeaders(),\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...options,\n });\n\n if (response.status === 401) return null;\n\n if (response.status !== 200 && response.status !== 202) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const responseText = await response.text();\n return responseText ? JSON.parse(responseText) : null;\n } catch (error) {\n if (attempt < this.maxRetries) {\n const delay = this.initialRetryDelay * Math.pow(2, attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n return this.post<ReqBody, ResBody>(url, data, options, attempt + 1);\n }\n console.error('Max retries reached:', error);\n return null;\n }\n }\n\n async fetch<ReqBody, ResBody>(\n path: string,\n data: ReqBody,\n options: FetchOptions = {}\n ): Promise<ResBody | null> {\n const url = `${this.baseUrl}${path}`;\n return this.post<ReqBody, ResBody>(url, data, options, 0);\n }\n}\n","import { Api } from './api';\n\nexport type TrackHandlerPayload =\n | {\n type: 'track';\n payload: TrackPayload;\n }\n | {\n type: 'increment';\n payload: IncrementPayload;\n }\n | {\n type: 'decrement';\n payload: DecrementPayload;\n }\n | {\n type: 'alias';\n payload: AliasPayload;\n }\n | {\n type: 'identify';\n payload: IdentifyPayload;\n };\n\nexport type TrackPayload = {\n name: string;\n properties?: Record<string, unknown>;\n profileId?: string;\n};\n\nexport type TrackProperties = {\n [key: string]: unknown;\n profileId?: string;\n};\n\nexport type IdentifyPayload = {\n profileId: string;\n firstName?: string;\n lastName?: string;\n email?: string;\n avatar?: string;\n properties?: Record<string, unknown>;\n};\n\nexport type AliasPayload = {\n profileId: string;\n alias: string;\n};\n\nexport type IncrementPayload = {\n profileId: string;\n property: string;\n value?: number;\n};\n\nexport type DecrementPayload = {\n profileId: string;\n property: string;\n value?: number;\n};\n\nexport type OpenPanelOptions = {\n clientId: string;\n clientSecret?: string;\n apiUrl?: string;\n sdk?: string;\n sdkVersion?: string;\n waitForProfile?: boolean;\n filter?: (payload: TrackHandlerPayload) => boolean;\n disabled?: boolean;\n};\n\nexport class OpenPanel {\n api: Api;\n profileId?: string;\n global?: Record<string, unknown>;\n queue: TrackHandlerPayload[] = [];\n\n constructor(public options: OpenPanelOptions) {\n const defaultHeaders: Record<string, string> = {\n 'openpanel-client-id': options.clientId,\n };\n\n if (options.clientSecret) {\n defaultHeaders['openpanel-client-secret'] = options.clientSecret;\n }\n\n defaultHeaders['openpanel-sdk-name'] = options.sdk || 'node';\n defaultHeaders['openpanel-sdk-version'] =\n options.sdkVersion || process.env.SDK_VERSION!;\n\n this.api = new Api({\n baseUrl: options.apiUrl || 'https://api.openpanel.dev',\n defaultHeaders,\n });\n }\n\n // placeholder for future use\n init() {\n // empty\n }\n\n ready() {\n this.options.waitForProfile = false;\n this.flush();\n }\n\n async send(payload: TrackHandlerPayload) {\n if (this.options.disabled) {\n return Promise.resolve();\n }\n\n if (this.options.filter && !this.options.filter(payload)) {\n return Promise.resolve();\n }\n\n if (this.options.waitForProfile && !this.profileId) {\n this.queue.push(payload);\n return Promise.resolve();\n }\n return this.api.fetch('/track', payload);\n }\n\n setGlobalProperties(properties: Record<string, unknown>) {\n this.global = {\n ...this.global,\n ...properties,\n };\n }\n\n async track(name: string, properties?: TrackProperties) {\n return this.send({\n type: 'track',\n payload: {\n name,\n profileId: properties?.profileId ?? this.profileId,\n properties: {\n ...(this.global ?? {}),\n ...(properties ?? {}),\n },\n },\n });\n }\n\n async identify(payload: IdentifyPayload) {\n if (payload.profileId) {\n this.profileId = payload.profileId;\n this.flush();\n }\n\n if (Object.keys(payload).length > 1) {\n return this.send({\n type: 'identify',\n payload: {\n ...payload,\n properties: {\n ...this.global,\n ...payload.properties,\n },\n },\n });\n }\n }\n\n async alias(payload: AliasPayload) {\n return this.send({\n type: 'alias',\n payload,\n });\n }\n\n async increment(payload: IncrementPayload) {\n return this.send({\n type: 'increment',\n payload,\n });\n }\n\n async decrement(payload: DecrementPayload) {\n return this.send({\n type: 'decrement',\n payload,\n });\n }\n\n clear() {\n this.profileId = undefined;\n // should we force a session end here?\n }\n\n flush() {\n this.queue.forEach((item) => {\n this.send({\n ...item,\n // Not sure why ts-expect-error is needed here\n // @ts-expect-error\n payload: {\n ...item.payload,\n profileId: item.payload.profileId ?? this.profileId,\n },\n });\n });\n this.queue = [];\n }\n}\n"],"mappings":"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","names":["Api","config","resolvedHeaders","key","value","resolvedValue","url","data","options","attempt","response","responseText","error","delay","resolve","path","OpenPanel","options","defaultHeaders","Api","payload","properties","name","item"]}