UNPKG

userplex

Version:

Simple analytics SDK for Userplex - Track events, identify users, and log conversations

132 lines (129 loc) 3.77 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); // index.ts var UserplexError = class extends Error { constructor(message, statusCode, response) { super(message); this.statusCode = statusCode; this.response = response; this.name = "UserplexError"; } }; var Userplex = class { constructor(apiKey, options = {}) { if (!apiKey) { throw new Error("Userplex: API key is required"); } if (!apiKey.startsWith("upx_")) { throw new Error('Userplex: API key must start with "upx_"'); } this.apiKey = apiKey; this.baseUrl = (options.baseUrl || "https://userplex.vercel.app").replace(/\/$/, ""); this.timeout = options.timeout || 1e4; this.debug = options.debug || false; } /** * Track an event */ async track(userId, event, properties) { if (!userId || !event) { throw new Error("userId and event are required"); } return this.request("/api/events", { userId, event, properties: properties || {} }); } /** * Identify a user */ async identify(externalId, properties) { if (!externalId) { throw new Error("externalId is required"); } return this.request("/api/identify", { externalId, ...properties }, { "x-api-key": this.apiKey // identify endpoint uses this header too }); } /** * Log a conversation */ async logConversation(options) { if (!options.messages || options.messages.length === 0) { throw new Error("messages array is required and cannot be empty"); } return this.request("/api/conversations", { externalUserId: options.userId, conversationId: options.conversationId, conversationName: options.conversationName, messages: options.messages }); } /** * Batch track multiple events */ async trackBatch(events) { if (!events || events.length === 0) { throw new Error("events array is required and cannot be empty"); } const promises = events.map((e) => this.track(e.userId, e.event, e.properties)); return Promise.all(promises); } async request(endpoint, data, additionalHeaders) { const url = `${this.baseUrl}${endpoint}`; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.timeout); if (this.debug) { console.log(`[Userplex] POST ${url}`, JSON.stringify(data, null, 2)); } try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${this.apiKey}`, ...additionalHeaders }, body: JSON.stringify(data), signal: controller.signal }); clearTimeout(timeoutId); const responseData = await response.json(); if (this.debug) { console.log(`[Userplex] Response:`, JSON.stringify(responseData, null, 2)); } if (!response.ok) { throw new UserplexError( responseData.error || `Request failed with status ${response.status}`, response.status, responseData ); } return responseData; } catch (error) { clearTimeout(timeoutId); if (error.name === "AbortError") { throw new UserplexError("Request timeout", 408); } if (error instanceof UserplexError) { throw error; } throw new UserplexError( error.message || "An unexpected error occurred", void 0, error ); } } }; var index_default = Userplex; exports.Userplex = Userplex; exports.UserplexError = UserplexError; exports.default = index_default; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map