@openpanel/sdk
Advanced tools
+1
-1
@@ -1,2 +0,2 @@ | ||
| "use strict";var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var I=(i,e)=>{for(var t in e)a(i,t,{get:e[t],enumerable:!0})},O=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of P(e))!y.call(i,r)&&r!==t&&a(i,r,{get:()=>e[r],enumerable:!(n=m(e,r))||n.enumerable});return i};var b=i=>O(a({},"__esModule",{value:!0}),i);var w={};I(w,{OpenpanelSdk:()=>l});module.exports=b(w);function v(i){return Promise.all(Object.entries(i).map(async([e,t])=>[e,await t??""])).then(e=>Object.fromEntries(e))}function R(i){let e={"Content-Type":"application/json"};return{headers:e,async fetch(t,n,r){let g=`${i}${t}`,c,h=await v(e);return new Promise(p=>{let d=s=>{clearTimeout(c),fetch(g,{headers:h,method:"POST",body:JSON.stringify(n??{}),keepalive:!0,...r??{}}).then(async o=>{if(o.status===401)return null;if(o.status!==200&&o.status!==202)return f(s,p);let u=await o.text();if(!u)return p(null);p(u)}).catch(()=>f(s,p))};function f(s,o){if(s>1)return o(null);c=setTimeout(()=>{d(s+1)},Math.pow(2,s)*500)}d(0)})}}}var l=class{constructor(e){this.state={properties:{}};this.options=e,this.api=R(e.url??"https://api.openpanel.dev"),this.api.headers["openpanel-client-id"]=e.clientId,this.options.clientSecret&&(this.api.headers["openpanel-client-secret"]=this.options.clientSecret)}setProfileId(e){this.state.profileId=e}async setProfile(e){return this.setProfileId(e.profileId),this.api.fetch("/profile",{...e,properties:{...this.state.properties,...e.properties}})}async increment(e,t,n){let r=n?.profileId??this.state.profileId;return r?this.api.fetch("/profile/increment",{profileId:r,property:e,value:t}):console.log("No profile id")}async decrement(e,t,n){let r=n?.profileId??this.state.profileId;return r?this.api.fetch("/profile/decrement",{profileId:r,property:e,value:t}):console.log("No profile id")}async event(e,t){let n=t?.profileId??this.state.profileId;return delete t?.profileId,this.api.fetch("/event",{name:e,properties:{...this.state.properties,...t??{}},timestamp:this.timestamp(),profileId:n})}setGlobalProperties(e){this.state.properties={...this.state.properties,...e}}clear(){this.state.profileId=void 0}timestamp(){return new Date().toISOString()}};0&&(module.exports={OpenpanelSdk}); | ||
| "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 |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../index.ts"],"sourcesContent":["export 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\nexport interface OpenpanelSdkOptions {\n url?: string;\n clientId: string;\n clientSecret?: string;\n verbose?: boolean;\n}\n\nexport interface OpenpanelState {\n profileId?: string;\n properties: Record<string, unknown>;\n}\n\nfunction awaitProperties(\n properties: Record<string, string | Promise<string | null>>\n): Promise<Record<string, string>> {\n return Promise.all(\n Object.entries(properties).map(async ([key, value]) => {\n return [key, (await value) ?? ''];\n })\n ).then((entries) => Object.fromEntries(entries));\n}\n\nfunction createApi(_url: string) {\n const headers: Record<string, string | Promise<string | null>> = {\n 'Content-Type': 'application/json',\n };\n return {\n headers,\n async fetch<ReqBody, ResBody>(\n path: string,\n data: ReqBody,\n options?: RequestInit\n ): Promise<ResBody | null> {\n const url = `${_url}${path}`;\n let timer: ReturnType<typeof setTimeout>;\n const h = await awaitProperties(headers);\n return new Promise((resolve) => {\n const wrappedFetch = (attempt: number) => {\n clearTimeout(timer);\n fetch(url, {\n headers: h,\n method: 'POST',\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...(options ?? {}),\n })\n .then(async (res) => {\n if (res.status === 401) {\n return null;\n }\n\n if (res.status !== 200 && res.status !== 202) {\n return retry(attempt, resolve);\n }\n\n const response = await res.text();\n\n if (!response) {\n return resolve(null);\n }\n\n resolve(response as ResBody);\n })\n .catch(() => {\n return retry(attempt, resolve);\n });\n };\n\n function retry(\n attempt: number,\n resolve: (value: ResBody | null) => void\n ) {\n if (attempt > 1) {\n return resolve(null);\n }\n\n timer = setTimeout(\n () => {\n wrappedFetch(attempt + 1);\n },\n Math.pow(2, attempt) * 500\n );\n }\n\n wrappedFetch(0);\n });\n },\n };\n}\n\nexport class OpenpanelSdk<\n Options extends OpenpanelSdkOptions = OpenpanelSdkOptions,\n> {\n public options: Options;\n public api: ReturnType<typeof createApi>;\n private state: OpenpanelState = {\n properties: {},\n };\n\n constructor(options: Options) {\n this.options = options;\n this.api = createApi(options.url ?? 'https://api.openpanel.dev');\n this.api.headers['openpanel-client-id'] = options.clientId;\n if (this.options.clientSecret) {\n this.api.headers['openpanel-client-secret'] = this.options.clientSecret;\n }\n }\n\n // Public\n\n public setProfileId(profileId: string) {\n this.state.profileId = profileId;\n }\n\n public async setProfile(payload: UpdateProfilePayload) {\n this.setProfileId(payload.profileId);\n return this.api.fetch<UpdateProfilePayload, string>('/profile', {\n ...payload,\n properties: {\n ...this.state.properties,\n ...payload.properties,\n },\n });\n }\n\n public async increment(\n property: string,\n value: number,\n options?: OpenpanelEventOptions\n ) {\n const profileId = options?.profileId ?? this.state.profileId;\n if (!profileId) {\n return console.log('No profile id');\n }\n return this.api.fetch<IncrementProfilePayload, string>(\n '/profile/increment',\n {\n profileId,\n property,\n value,\n }\n );\n }\n\n public async decrement(\n property: string,\n value: number,\n options?: OpenpanelEventOptions\n ) {\n const profileId = options?.profileId ?? this.state.profileId;\n if (!profileId) {\n return console.log('No profile id');\n }\n return this.api.fetch<DecrementProfilePayload, string>(\n '/profile/decrement',\n {\n profileId,\n property,\n value,\n }\n );\n }\n\n public async event(\n name: string,\n properties?: PostEventPayload['properties']\n ) {\n const profileId = properties?.profileId ?? this.state.profileId;\n delete properties?.profileId;\n return this.api.fetch<PostEventPayload, string>('/event', {\n name,\n properties: {\n ...this.state.properties,\n ...(properties ?? {}),\n },\n timestamp: this.timestamp(),\n profileId,\n });\n }\n\n public setGlobalProperties(properties: Record<string, unknown>) {\n this.state.properties = {\n ...this.state.properties,\n ...properties,\n };\n }\n\n public clear() {\n this.state.profileId = undefined;\n }\n\n // Private\n\n private timestamp() {\n return new Date().toISOString();\n }\n}\n"],"mappings":"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","names":["sdk_exports","__export","OpenpanelSdk","__toCommonJS","awaitProperties","properties","key","value","entries","createApi","_url","headers","path","data","options","url","timer","resolve","wrappedFetch","attempt","res","retry","response","profileId","payload","property","name"]} | ||
| {"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":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,IAAA,eAAAC,EAAAH,GCWO,IAAMI,EAAN,KAAU,CAMf,YAAYC,EAAmB,CAC7B,KAAK,QAAUA,EAAO,QACtB,KAAK,QAAU,CACb,eAAgB,mBAChB,GAAGA,EAAO,cACZ,EACA,KAAK,WAAaA,EAAO,YAAc,EACvC,KAAK,kBAAoBA,EAAO,mBAAqB,GACvD,CAEA,MAAc,gBAAkD,CAC9D,IAAMC,EAA0C,CAAC,EACjD,OAAW,CAACC,EAAKC,CAAK,IAAK,OAAO,QAAQ,KAAK,OAAO,EAAG,CACvD,IAAMC,EAAgB,MAAMD,EACxBC,IAAkB,OACpBH,EAAgBC,CAAG,EAAIE,EAE3B,CACA,OAAOH,CACT,CAEO,UAAUC,EAAaC,EAAwC,CACpE,KAAK,QAAQD,CAAG,EAAIC,CACtB,CAEA,MAAc,KACZE,EACAC,EACAC,EACAC,EACyB,CACzB,GAAI,CACF,IAAMC,EAAW,MAAM,MAAMJ,EAAK,CAChC,OAAQ,OACR,QAAS,MAAM,KAAK,eAAe,EACnC,KAAM,KAAK,UAAUC,GAAQ,CAAC,CAAC,EAC/B,UAAW,GACX,GAAGC,CACL,CAAC,EAED,GAAIE,EAAS,SAAW,IAAK,OAAO,KAEpC,GAAIA,EAAS,SAAW,KAAOA,EAAS,SAAW,IACjD,MAAM,IAAI,MAAM,uBAAuBA,EAAS,MAAM,EAAE,EAG1D,IAAMC,EAAe,MAAMD,EAAS,KAAK,EACzC,OAAOC,EAAe,KAAK,MAAMA,CAAY,EAAI,IACnD,OAASC,EAAO,CACd,GAAIH,EAAU,KAAK,WAAY,CAC7B,IAAMI,EAAQ,KAAK,kBAAoB,KAAK,IAAI,EAAGJ,CAAO,EAC1D,aAAM,IAAI,QAASK,GAAY,WAAWA,EAASD,CAAK,CAAC,EAClD,KAAK,KAAuBP,EAAKC,EAAMC,EAASC,EAAU,CAAC,CACpE,CACA,eAAQ,MAAM,uBAAwBG,CAAK,EACpC,IACT,CACF,CAEA,MAAM,MACJG,EACAR,EACAC,EAAwB,CAAC,EACA,CACzB,IAAMF,EAAM,GAAG,KAAK,OAAO,GAAGS,CAAI,GAClC,OAAO,KAAK,KAAuBT,EAAKC,EAAMC,EAAS,CAAC,CAC1D,CACF,ECZO,IAAMQ,EAAN,KAAgB,CAMrB,YAAmBC,EAA2B,CAA3B,aAAAA,EAFnB,WAA+B,CAAC,EAG9B,IAAMC,EAAyC,CAC7C,sBAAuBD,EAAQ,QACjC,EAEIA,EAAQ,eACVC,EAAe,yBAAyB,EAAID,EAAQ,cAGtDC,EAAe,oBAAoB,EAAID,EAAQ,KAAO,OACtDC,EAAe,uBAAuB,EACpCD,EAAQ,YAAc,QAExB,KAAK,IAAM,IAAIE,EAAI,CACjB,QAASF,EAAQ,QAAU,4BAC3B,eAAAC,CACF,CAAC,CACH,CAGA,MAAO,CAEP,CAEA,OAAQ,CACN,KAAK,QAAQ,eAAiB,GAC9B,KAAK,MAAM,CACb,CAEA,MAAM,KAAKE,EAA8B,CAKvC,OAJI,KAAK,QAAQ,UAIb,KAAK,QAAQ,QAAU,CAAC,KAAK,QAAQ,OAAOA,CAAO,EAC9C,QAAQ,QAAQ,EAGrB,KAAK,QAAQ,gBAAkB,CAAC,KAAK,WACvC,KAAK,MAAM,KAAKA,CAAO,EAChB,QAAQ,QAAQ,GAElB,KAAK,IAAI,MAAM,SAAUA,CAAO,CACzC,CAEA,oBAAoBC,EAAqC,CACvD,KAAK,OAAS,CACZ,GAAG,KAAK,OACR,GAAGA,CACL,CACF,CAEA,MAAM,MAAMC,EAAcD,EAA8B,CACtD,OAAO,KAAK,KAAK,CACf,KAAM,QACN,QAAS,CACP,KAAAC,EACA,UAAWD,GAAY,WAAa,KAAK,UACzC,WAAY,CACV,GAAI,KAAK,QAAU,CAAC,EACpB,GAAIA,GAAc,CAAC,CACrB,CACF,CACF,CAAC,CACH,CAEA,MAAM,SAASD,EAA0B,CAMvC,GALIA,EAAQ,YACV,KAAK,UAAYA,EAAQ,UACzB,KAAK,MAAM,GAGT,OAAO,KAAKA,CAAO,EAAE,OAAS,EAChC,OAAO,KAAK,KAAK,CACf,KAAM,WACN,QAAS,CACP,GAAGA,EACH,WAAY,CACV,GAAG,KAAK,OACR,GAAGA,EAAQ,UACb,CACF,CACF,CAAC,CAEL,CAEA,MAAM,MAAMA,EAAuB,CACjC,OAAO,KAAK,KAAK,CACf,KAAM,QACN,QAAAA,CACF,CAAC,CACH,CAEA,MAAM,UAAUA,EAA2B,CACzC,OAAO,KAAK,KAAK,CACf,KAAM,YACN,QAAAA,CACF,CAAC,CACH,CAEA,MAAM,UAAUA,EAA2B,CACzC,OAAO,KAAK,KAAK,CACf,KAAM,YACN,QAAAA,CACF,CAAC,CACH,CAEA,OAAQ,CACN,KAAK,UAAY,MAEnB,CAEA,OAAQ,CACN,KAAK,MAAM,QAASG,GAAS,CAC3B,KAAK,KAAK,CACR,GAAGA,EAGH,QAAS,CACP,GAAGA,EAAK,QACR,UAAWA,EAAK,QAAQ,WAAa,KAAK,SAC5C,CACF,CAAC,CACH,CAAC,EACD,KAAK,MAAQ,CAAC,CAChB,CACF","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"]} |
+99
-29
@@ -0,1 +1,99 @@ | ||
| interface ApiConfig { | ||
| baseUrl: string; | ||
| defaultHeaders?: Record<string, string | Promise<string | null>>; | ||
| maxRetries?: number; | ||
| initialRetryDelay?: number; | ||
| } | ||
| interface FetchOptions extends RequestInit { | ||
| retries?: number; | ||
| } | ||
| declare class Api { | ||
| private baseUrl; | ||
| private headers; | ||
| private maxRetries; | ||
| private initialRetryDelay; | ||
| constructor(config: ApiConfig); | ||
| private resolveHeaders; | ||
| addHeader(key: string, value: string | Promise<string | null>): void; | ||
| private post; | ||
| fetch<ReqBody, ResBody>(path: string, data: ReqBody, options?: FetchOptions): Promise<ResBody | null>; | ||
| } | ||
| type TrackHandlerPayload = { | ||
| type: 'track'; | ||
| payload: TrackPayload; | ||
| } | { | ||
| type: 'increment'; | ||
| payload: IncrementPayload; | ||
| } | { | ||
| type: 'decrement'; | ||
| payload: DecrementPayload; | ||
| } | { | ||
| type: 'alias'; | ||
| payload: AliasPayload; | ||
| } | { | ||
| type: 'identify'; | ||
| payload: IdentifyPayload; | ||
| }; | ||
| type TrackPayload = { | ||
| name: string; | ||
| properties?: Record<string, unknown>; | ||
| profileId?: string; | ||
| }; | ||
| type TrackProperties = { | ||
| [key: string]: unknown; | ||
| profileId?: string; | ||
| }; | ||
| type IdentifyPayload = { | ||
| profileId: string; | ||
| firstName?: string; | ||
| lastName?: string; | ||
| email?: string; | ||
| avatar?: string; | ||
| properties?: Record<string, unknown>; | ||
| }; | ||
| type AliasPayload = { | ||
| profileId: string; | ||
| alias: string; | ||
| }; | ||
| type IncrementPayload = { | ||
| profileId: string; | ||
| property: string; | ||
| value?: number; | ||
| }; | ||
| type DecrementPayload = { | ||
| profileId: string; | ||
| property: string; | ||
| value?: number; | ||
| }; | ||
| type OpenPanelOptions = { | ||
| clientId: string; | ||
| clientSecret?: string; | ||
| apiUrl?: string; | ||
| sdk?: string; | ||
| sdkVersion?: string; | ||
| waitForProfile?: boolean; | ||
| filter?: (payload: TrackHandlerPayload) => boolean; | ||
| disabled?: boolean; | ||
| }; | ||
| declare class OpenPanel { | ||
| options: OpenPanelOptions; | ||
| api: Api; | ||
| profileId?: string; | ||
| global?: Record<string, unknown>; | ||
| queue: TrackHandlerPayload[]; | ||
| constructor(options: OpenPanelOptions); | ||
| init(): void; | ||
| ready(): void; | ||
| send(payload: TrackHandlerPayload): Promise<unknown>; | ||
| setGlobalProperties(properties: Record<string, unknown>): void; | ||
| track(name: string, properties?: TrackProperties): Promise<unknown>; | ||
| identify(payload: IdentifyPayload): Promise<unknown>; | ||
| alias(payload: AliasPayload): Promise<unknown>; | ||
| increment(payload: IncrementPayload): Promise<unknown>; | ||
| decrement(payload: DecrementPayload): Promise<unknown>; | ||
| clear(): void; | ||
| flush(): void; | ||
| } | ||
| interface OpenpanelEventOptions { | ||
@@ -28,31 +126,3 @@ profileId?: string; | ||
| } | ||
| interface OpenpanelSdkOptions { | ||
| url?: string; | ||
| clientId: string; | ||
| clientSecret?: string; | ||
| verbose?: boolean; | ||
| } | ||
| interface OpenpanelState { | ||
| profileId?: string; | ||
| properties: Record<string, unknown>; | ||
| } | ||
| declare function createApi(_url: string): { | ||
| headers: Record<string, string | Promise<string | null>>; | ||
| fetch<ReqBody, ResBody>(path: string, data: ReqBody, options?: RequestInit): Promise<ResBody | null>; | ||
| }; | ||
| declare class OpenpanelSdk<Options extends OpenpanelSdkOptions = OpenpanelSdkOptions> { | ||
| options: Options; | ||
| api: ReturnType<typeof createApi>; | ||
| private state; | ||
| constructor(options: Options); | ||
| setProfileId(profileId: string): void; | ||
| setProfile(payload: UpdateProfilePayload): Promise<string | null>; | ||
| increment(property: string, value: number, options?: OpenpanelEventOptions): Promise<string | void | null>; | ||
| decrement(property: string, value: number, options?: OpenpanelEventOptions): Promise<string | void | null>; | ||
| event(name: string, properties?: PostEventPayload['properties']): Promise<string | null>; | ||
| setGlobalProperties(properties: Record<string, unknown>): void; | ||
| clear(): void; | ||
| private timestamp; | ||
| } | ||
| export { type DecrementProfilePayload, type IncrementProfilePayload, type OpenpanelEventOptions, OpenpanelSdk, type OpenpanelSdkOptions, type OpenpanelState, type PostEventPayload, type UpdateProfilePayload }; | ||
| export { type AliasPayload, type DecrementPayload, type DecrementProfilePayload, type IdentifyPayload, type IncrementPayload, type IncrementProfilePayload, OpenPanel, type OpenPanelOptions, type OpenpanelEventOptions, type PostEventPayload, type TrackHandlerPayload, type TrackPayload, type TrackProperties, type UpdateProfilePayload }; |
+99
-29
@@ -0,1 +1,99 @@ | ||
| interface ApiConfig { | ||
| baseUrl: string; | ||
| defaultHeaders?: Record<string, string | Promise<string | null>>; | ||
| maxRetries?: number; | ||
| initialRetryDelay?: number; | ||
| } | ||
| interface FetchOptions extends RequestInit { | ||
| retries?: number; | ||
| } | ||
| declare class Api { | ||
| private baseUrl; | ||
| private headers; | ||
| private maxRetries; | ||
| private initialRetryDelay; | ||
| constructor(config: ApiConfig); | ||
| private resolveHeaders; | ||
| addHeader(key: string, value: string | Promise<string | null>): void; | ||
| private post; | ||
| fetch<ReqBody, ResBody>(path: string, data: ReqBody, options?: FetchOptions): Promise<ResBody | null>; | ||
| } | ||
| type TrackHandlerPayload = { | ||
| type: 'track'; | ||
| payload: TrackPayload; | ||
| } | { | ||
| type: 'increment'; | ||
| payload: IncrementPayload; | ||
| } | { | ||
| type: 'decrement'; | ||
| payload: DecrementPayload; | ||
| } | { | ||
| type: 'alias'; | ||
| payload: AliasPayload; | ||
| } | { | ||
| type: 'identify'; | ||
| payload: IdentifyPayload; | ||
| }; | ||
| type TrackPayload = { | ||
| name: string; | ||
| properties?: Record<string, unknown>; | ||
| profileId?: string; | ||
| }; | ||
| type TrackProperties = { | ||
| [key: string]: unknown; | ||
| profileId?: string; | ||
| }; | ||
| type IdentifyPayload = { | ||
| profileId: string; | ||
| firstName?: string; | ||
| lastName?: string; | ||
| email?: string; | ||
| avatar?: string; | ||
| properties?: Record<string, unknown>; | ||
| }; | ||
| type AliasPayload = { | ||
| profileId: string; | ||
| alias: string; | ||
| }; | ||
| type IncrementPayload = { | ||
| profileId: string; | ||
| property: string; | ||
| value?: number; | ||
| }; | ||
| type DecrementPayload = { | ||
| profileId: string; | ||
| property: string; | ||
| value?: number; | ||
| }; | ||
| type OpenPanelOptions = { | ||
| clientId: string; | ||
| clientSecret?: string; | ||
| apiUrl?: string; | ||
| sdk?: string; | ||
| sdkVersion?: string; | ||
| waitForProfile?: boolean; | ||
| filter?: (payload: TrackHandlerPayload) => boolean; | ||
| disabled?: boolean; | ||
| }; | ||
| declare class OpenPanel { | ||
| options: OpenPanelOptions; | ||
| api: Api; | ||
| profileId?: string; | ||
| global?: Record<string, unknown>; | ||
| queue: TrackHandlerPayload[]; | ||
| constructor(options: OpenPanelOptions); | ||
| init(): void; | ||
| ready(): void; | ||
| send(payload: TrackHandlerPayload): Promise<unknown>; | ||
| setGlobalProperties(properties: Record<string, unknown>): void; | ||
| track(name: string, properties?: TrackProperties): Promise<unknown>; | ||
| identify(payload: IdentifyPayload): Promise<unknown>; | ||
| alias(payload: AliasPayload): Promise<unknown>; | ||
| increment(payload: IncrementPayload): Promise<unknown>; | ||
| decrement(payload: DecrementPayload): Promise<unknown>; | ||
| clear(): void; | ||
| flush(): void; | ||
| } | ||
| interface OpenpanelEventOptions { | ||
@@ -28,31 +126,3 @@ profileId?: string; | ||
| } | ||
| interface OpenpanelSdkOptions { | ||
| url?: string; | ||
| clientId: string; | ||
| clientSecret?: string; | ||
| verbose?: boolean; | ||
| } | ||
| interface OpenpanelState { | ||
| profileId?: string; | ||
| properties: Record<string, unknown>; | ||
| } | ||
| declare function createApi(_url: string): { | ||
| headers: Record<string, string | Promise<string | null>>; | ||
| fetch<ReqBody, ResBody>(path: string, data: ReqBody, options?: RequestInit): Promise<ResBody | null>; | ||
| }; | ||
| declare class OpenpanelSdk<Options extends OpenpanelSdkOptions = OpenpanelSdkOptions> { | ||
| options: Options; | ||
| api: ReturnType<typeof createApi>; | ||
| private state; | ||
| constructor(options: Options); | ||
| setProfileId(profileId: string): void; | ||
| setProfile(payload: UpdateProfilePayload): Promise<string | null>; | ||
| increment(property: string, value: number, options?: OpenpanelEventOptions): Promise<string | void | null>; | ||
| decrement(property: string, value: number, options?: OpenpanelEventOptions): Promise<string | void | null>; | ||
| event(name: string, properties?: PostEventPayload['properties']): Promise<string | null>; | ||
| setGlobalProperties(properties: Record<string, unknown>): void; | ||
| clear(): void; | ||
| private timestamp; | ||
| } | ||
| export { type DecrementProfilePayload, type IncrementProfilePayload, type OpenpanelEventOptions, OpenpanelSdk, type OpenpanelSdkOptions, type OpenpanelState, type PostEventPayload, type UpdateProfilePayload }; | ||
| export { type AliasPayload, type DecrementPayload, type DecrementProfilePayload, type IdentifyPayload, type IncrementPayload, type IncrementProfilePayload, OpenPanel, type OpenPanelOptions, type OpenpanelEventOptions, type PostEventPayload, type TrackHandlerPayload, type TrackPayload, type TrackProperties, type UpdateProfilePayload }; |
+1
-1
@@ -1,2 +0,2 @@ | ||
| function h(o){return Promise.all(Object.entries(o).map(async([e,t])=>[e,await t??""])).then(e=>Object.fromEntries(e))}function m(o){let e={"Content-Type":"application/json"};return{headers:e,async fetch(t,r,i){let u=`${o}${t}`,a,g=await h(e);return new Promise(p=>{let l=n=>{clearTimeout(a),fetch(u,{headers:g,method:"POST",body:JSON.stringify(r??{}),keepalive:!0,...i??{}}).then(async s=>{if(s.status===401)return null;if(s.status!==200&&s.status!==202)return c(n,p);let d=await s.text();if(!d)return p(null);p(d)}).catch(()=>c(n,p))};function c(n,s){if(n>1)return s(null);a=setTimeout(()=>{l(n+1)},Math.pow(2,n)*500)}l(0)})}}}var f=class{constructor(e){this.state={properties:{}};this.options=e,this.api=m(e.url??"https://api.openpanel.dev"),this.api.headers["openpanel-client-id"]=e.clientId,this.options.clientSecret&&(this.api.headers["openpanel-client-secret"]=this.options.clientSecret)}setProfileId(e){this.state.profileId=e}async setProfile(e){return this.setProfileId(e.profileId),this.api.fetch("/profile",{...e,properties:{...this.state.properties,...e.properties}})}async increment(e,t,r){let i=r?.profileId??this.state.profileId;return i?this.api.fetch("/profile/increment",{profileId:i,property:e,value:t}):console.log("No profile id")}async decrement(e,t,r){let i=r?.profileId??this.state.profileId;return i?this.api.fetch("/profile/decrement",{profileId:i,property:e,value:t}):console.log("No profile id")}async event(e,t){let r=t?.profileId??this.state.profileId;return delete t?.profileId,this.api.fetch("/event",{name:e,properties:{...this.state.properties,...t??{}},timestamp:this.timestamp(),profileId:r})}setGlobalProperties(e){this.state.properties={...this.state.properties,...e}}clear(){this.state.profileId=void 0}timestamp(){return new Date().toISOString()}};export{f as OpenpanelSdk}; | ||
| 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 |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../index.ts"],"sourcesContent":["export 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\nexport interface OpenpanelSdkOptions {\n url?: string;\n clientId: string;\n clientSecret?: string;\n verbose?: boolean;\n}\n\nexport interface OpenpanelState {\n profileId?: string;\n properties: Record<string, unknown>;\n}\n\nfunction awaitProperties(\n properties: Record<string, string | Promise<string | null>>\n): Promise<Record<string, string>> {\n return Promise.all(\n Object.entries(properties).map(async ([key, value]) => {\n return [key, (await value) ?? ''];\n })\n ).then((entries) => Object.fromEntries(entries));\n}\n\nfunction createApi(_url: string) {\n const headers: Record<string, string | Promise<string | null>> = {\n 'Content-Type': 'application/json',\n };\n return {\n headers,\n async fetch<ReqBody, ResBody>(\n path: string,\n data: ReqBody,\n options?: RequestInit\n ): Promise<ResBody | null> {\n const url = `${_url}${path}`;\n let timer: ReturnType<typeof setTimeout>;\n const h = await awaitProperties(headers);\n return new Promise((resolve) => {\n const wrappedFetch = (attempt: number) => {\n clearTimeout(timer);\n fetch(url, {\n headers: h,\n method: 'POST',\n body: JSON.stringify(data ?? {}),\n keepalive: true,\n ...(options ?? {}),\n })\n .then(async (res) => {\n if (res.status === 401) {\n return null;\n }\n\n if (res.status !== 200 && res.status !== 202) {\n return retry(attempt, resolve);\n }\n\n const response = await res.text();\n\n if (!response) {\n return resolve(null);\n }\n\n resolve(response as ResBody);\n })\n .catch(() => {\n return retry(attempt, resolve);\n });\n };\n\n function retry(\n attempt: number,\n resolve: (value: ResBody | null) => void\n ) {\n if (attempt > 1) {\n return resolve(null);\n }\n\n timer = setTimeout(\n () => {\n wrappedFetch(attempt + 1);\n },\n Math.pow(2, attempt) * 500\n );\n }\n\n wrappedFetch(0);\n });\n },\n };\n}\n\nexport class OpenpanelSdk<\n Options extends OpenpanelSdkOptions = OpenpanelSdkOptions,\n> {\n public options: Options;\n public api: ReturnType<typeof createApi>;\n private state: OpenpanelState = {\n properties: {},\n };\n\n constructor(options: Options) {\n this.options = options;\n this.api = createApi(options.url ?? 'https://api.openpanel.dev');\n this.api.headers['openpanel-client-id'] = options.clientId;\n if (this.options.clientSecret) {\n this.api.headers['openpanel-client-secret'] = this.options.clientSecret;\n }\n }\n\n // Public\n\n public setProfileId(profileId: string) {\n this.state.profileId = profileId;\n }\n\n public async setProfile(payload: UpdateProfilePayload) {\n this.setProfileId(payload.profileId);\n return this.api.fetch<UpdateProfilePayload, string>('/profile', {\n ...payload,\n properties: {\n ...this.state.properties,\n ...payload.properties,\n },\n });\n }\n\n public async increment(\n property: string,\n value: number,\n options?: OpenpanelEventOptions\n ) {\n const profileId = options?.profileId ?? this.state.profileId;\n if (!profileId) {\n return console.log('No profile id');\n }\n return this.api.fetch<IncrementProfilePayload, string>(\n '/profile/increment',\n {\n profileId,\n property,\n value,\n }\n );\n }\n\n public async decrement(\n property: string,\n value: number,\n options?: OpenpanelEventOptions\n ) {\n const profileId = options?.profileId ?? this.state.profileId;\n if (!profileId) {\n return console.log('No profile id');\n }\n return this.api.fetch<DecrementProfilePayload, string>(\n '/profile/decrement',\n {\n profileId,\n property,\n value,\n }\n );\n }\n\n public async event(\n name: string,\n properties?: PostEventPayload['properties']\n ) {\n const profileId = properties?.profileId ?? this.state.profileId;\n delete properties?.profileId;\n return this.api.fetch<PostEventPayload, string>('/event', {\n name,\n properties: {\n ...this.state.properties,\n ...(properties ?? {}),\n },\n timestamp: this.timestamp(),\n profileId,\n });\n }\n\n public setGlobalProperties(properties: Record<string, unknown>) {\n this.state.properties = {\n ...this.state.properties,\n ...properties,\n };\n }\n\n public clear() {\n this.state.profileId = undefined;\n }\n\n // Private\n\n private timestamp() {\n return new Date().toISOString();\n }\n}\n"],"mappings":"AA4CA,SAASA,EACPC,EACiC,CACjC,OAAO,QAAQ,IACb,OAAO,QAAQA,CAAU,EAAE,IAAI,MAAO,CAACC,EAAKC,CAAK,IACxC,CAACD,EAAM,MAAMC,GAAU,EAAE,CACjC,CACH,EAAE,KAAMC,GAAY,OAAO,YAAYA,CAAO,CAAC,CACjD,CAEA,SAASC,EAAUC,EAAc,CAC/B,IAAMC,EAA2D,CAC/D,eAAgB,kBAClB,EACA,MAAO,CACL,QAAAA,EACA,MAAM,MACJC,EACAC,EACAC,EACyB,CACzB,IAAMC,EAAM,GAAGL,CAAI,GAAGE,CAAI,GACtBI,EACEC,EAAI,MAAMb,EAAgBO,CAAO,EACvC,OAAO,IAAI,QAASO,GAAY,CAC9B,IAAMC,EAAgBC,GAAoB,CACxC,aAAaJ,CAAK,EAClB,MAAMD,EAAK,CACT,QAASE,EACT,OAAQ,OACR,KAAM,KAAK,UAAUJ,GAAQ,CAAC,CAAC,EAC/B,UAAW,GACX,GAAIC,GAAW,CAAC,CAClB,CAAC,EACE,KAAK,MAAOO,GAAQ,CACnB,GAAIA,EAAI,SAAW,IACjB,OAAO,KAGT,GAAIA,EAAI,SAAW,KAAOA,EAAI,SAAW,IACvC,OAAOC,EAAMF,EAASF,CAAO,EAG/B,IAAMK,EAAW,MAAMF,EAAI,KAAK,EAEhC,GAAI,CAACE,EACH,OAAOL,EAAQ,IAAI,EAGrBA,EAAQK,CAAmB,CAC7B,CAAC,EACA,MAAM,IACED,EAAMF,EAASF,CAAO,CAC9B,CACL,EAEA,SAASI,EACPF,EACAF,EACA,CACA,GAAIE,EAAU,EACZ,OAAOF,EAAQ,IAAI,EAGrBF,EAAQ,WACN,IAAM,CACJG,EAAaC,EAAU,CAAC,CAC1B,EACA,KAAK,IAAI,EAAGA,CAAO,EAAI,GACzB,CACF,CAEAD,EAAa,CAAC,CAChB,CAAC,CACH,CACF,CACF,CAEO,IAAMK,EAAN,KAEL,CAOA,YAAYV,EAAkB,CAJ9B,KAAQ,MAAwB,CAC9B,WAAY,CAAC,CACf,EAGE,KAAK,QAAUA,EACf,KAAK,IAAML,EAAUK,EAAQ,KAAO,2BAA2B,EAC/D,KAAK,IAAI,QAAQ,qBAAqB,EAAIA,EAAQ,SAC9C,KAAK,QAAQ,eACf,KAAK,IAAI,QAAQ,yBAAyB,EAAI,KAAK,QAAQ,aAE/D,CAIO,aAAaW,EAAmB,CACrC,KAAK,MAAM,UAAYA,CACzB,CAEA,MAAa,WAAWC,EAA+B,CACrD,YAAK,aAAaA,EAAQ,SAAS,EAC5B,KAAK,IAAI,MAAoC,WAAY,CAC9D,GAAGA,EACH,WAAY,CACV,GAAG,KAAK,MAAM,WACd,GAAGA,EAAQ,UACb,CACF,CAAC,CACH,CAEA,MAAa,UACXC,EACApB,EACAO,EACA,CACA,IAAMW,EAAYX,GAAS,WAAa,KAAK,MAAM,UACnD,OAAKW,EAGE,KAAK,IAAI,MACd,qBACA,CACE,UAAAA,EACA,SAAAE,EACA,MAAApB,CACF,CACF,EATS,QAAQ,IAAI,eAAe,CAUtC,CAEA,MAAa,UACXoB,EACApB,EACAO,EACA,CACA,IAAMW,EAAYX,GAAS,WAAa,KAAK,MAAM,UACnD,OAAKW,EAGE,KAAK,IAAI,MACd,qBACA,CACE,UAAAA,EACA,SAAAE,EACA,MAAApB,CACF,CACF,EATS,QAAQ,IAAI,eAAe,CAUtC,CAEA,MAAa,MACXqB,EACAvB,EACA,CACA,IAAMoB,EAAYpB,GAAY,WAAa,KAAK,MAAM,UACtD,cAAOA,GAAY,UACZ,KAAK,IAAI,MAAgC,SAAU,CACxD,KAAAuB,EACA,WAAY,CACV,GAAG,KAAK,MAAM,WACd,GAAIvB,GAAc,CAAC,CACrB,EACA,UAAW,KAAK,UAAU,EAC1B,UAAAoB,CACF,CAAC,CACH,CAEO,oBAAoBpB,EAAqC,CAC9D,KAAK,MAAM,WAAa,CACtB,GAAG,KAAK,MAAM,WACd,GAAGA,CACL,CACF,CAEO,OAAQ,CACb,KAAK,MAAM,UAAY,MACzB,CAIQ,WAAY,CAClB,OAAO,IAAI,KAAK,EAAE,YAAY,CAChC,CACF","names":["awaitProperties","properties","key","value","entries","createApi","_url","headers","path","data","options","url","timer","h","resolve","wrappedFetch","attempt","res","retry","response","OpenpanelSdk","profileId","payload","property","name"]} | ||
| {"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"]} |
+7
-3
| { | ||
| "name": "@openpanel/sdk", | ||
| "version": "0.0.9-beta", | ||
| "version": "1.0.0", | ||
| "module": "./dist/index.mjs", | ||
@@ -16,2 +16,3 @@ "scripts": { | ||
| "@openpanel/tsconfig": "workspace:*", | ||
| "@types/node": "^20.14.12", | ||
| "eslint": "^8.48.0", | ||
@@ -37,5 +38,8 @@ "prettier": "^3.0.3", | ||
| "exports": { | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs" | ||
| ".": { | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs", | ||
| "types": "./dist/index.d.ts" | ||
| } | ||
| } | ||
| } |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
33892
32.98%145
101.39%3
-25%8
-42.86%8
14.29%