UNPKG

commet

Version:
488 lines (479 loc) 14.8 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { Commet: () => Commet, CommetAPIError: () => CommetAPIError, CommetError: () => CommetError, CommetValidationError: () => CommetValidationError, default: () => index_default, detectEnvironment: () => detectEnvironment, isDevelopment: () => isDevelopment, isProduction: () => isProduction }); module.exports = __toCommonJS(index_exports); // src/resources/customers.ts var CustomersResource = class { constructor(httpClient) { this.httpClient = httpClient; } async create(params, options) { return this.httpClient.post("/customers", params, options); } async retrieve(customerId, options) { const params = options?.expand ? { expand: options.expand.join(",") } : void 0; return this.httpClient.get(`/customers/${customerId}`, params); } async update(customerId, params, options) { return this.httpClient.put(`/customers/${customerId}`, params, options); } async list(params) { return this.httpClient.get("/customers", params); } /** * Deactivate a customer (soft delete) */ async deactivate(customerId, options) { return this.httpClient.put( `/customers/${customerId}`, { isActive: false }, options ); } }; // src/resources/seats.ts var SeatsResource = class { constructor(httpClient) { this.httpClient = httpClient; } async add(customerId, seatType, count, options) { return this.httpClient.post( `/customers/${customerId}/seats/${seatType}/add`, { count }, options ); } async remove(customerId, seatType, count, options) { return this.httpClient.post( `/customers/${customerId}/seats/${seatType}/remove`, { count }, options ); } async set(customerId, seatType, count, options) { return this.httpClient.post( `/customers/${customerId}/seats/${seatType}/set`, { count }, options ); } async bulkUpdate(customerId, seats, options) { return this.httpClient.post( `/customers/${customerId}/seats/bulk-update`, { seats }, options ); } async getBalance(customerId, seatType) { return this.httpClient.get( `/customers/${customerId}/seats/${seatType}/balance` ); } async getAllBalances(customerId) { return this.httpClient.get(`/customers/${customerId}/seats/balances`); } async getHistory(customerId, seatType, params) { const queryParams = { ...params, customerId, seatType }; return this.httpClient.get( `/customers/${customerId}/seats/history`, queryParams ); } async listEvents(params) { return this.httpClient.get("/seats/events", params); } }; // src/resources/usage.ts var UsageEventsResource = class { constructor(httpClient) { this.httpClient = httpClient; } async create(params, options) { const eventData = { ...params, ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString() }; return this.httpClient.post("/usage/events", eventData, options); } async createBatch(params, options) { return this.httpClient.post("/usage/events/batch", params, options); } async retrieve(eventId) { return this.httpClient.get(`/usage/events/${eventId}`); } async list(params) { return this.httpClient.get("/usage/events", params); } async delete(eventId, options) { return this.httpClient.delete(`/usage/events/${eventId}`, options); } }; var UsageMetricsResource = class { constructor(httpClient) { this.httpClient = httpClient; } async list() { return this.httpClient.get("/usage/metrics"); } async retrieve(metricId) { return this.httpClient.get(`/usage/metrics/${metricId}`); } }; var UsageResource = class { constructor(httpClient) { this.events = new UsageEventsResource(httpClient); this.metrics = new UsageMetricsResource(httpClient); } }; // src/utils/environment.ts function detectEnvironment() { try { if (typeof process !== "undefined" && process.env?.NODE_ENV) { if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") { return "development"; } } if (typeof window !== "undefined" && window.location) { const hostname = window.location.hostname; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("192.168.") || hostname.startsWith("10.") || hostname.endsWith(".local")) { return "development"; } } } catch (error) { } return "production"; } function isDevelopment(environment) { return environment === "development"; } function isProduction(environment) { return environment === "production"; } // src/types/common.ts var CommetError = class extends Error { constructor(message, code, statusCode, details) { super(message); this.code = code; this.statusCode = statusCode; this.details = details; this.name = "CommetError"; } }; var CommetAPIError = class extends CommetError { constructor(message, statusCode, code, details) { super(message, code, statusCode, details); this.statusCode = statusCode; this.code = code; this.details = details; this.name = "CommetAPIError"; } }; var CommetValidationError = class extends CommetError { constructor(message, validationErrors) { super(message); this.validationErrors = validationErrors; this.name = "CommetValidationError"; } }; // src/utils/http.ts var DEFAULT_RETRY_CONFIG = { maxRetries: 3, baseDelay: 1e3, // 1s maxDelay: 8e3, // 8s retryableStatusCodes: [408, 429, 500, 502, 503, 504] }; var CommetHTTPClient = class { constructor(config, environment) { this.config = config; this.environment = environment; this.retryConfig = { ...DEFAULT_RETRY_CONFIG, maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries }; } async get(endpoint, params, options) { return this.request("GET", endpoint, void 0, options, params); } async post(endpoint, data, options) { return this.request("POST", endpoint, data, options); } async put(endpoint, data, options) { return this.request("PUT", endpoint, data, options); } async delete(endpoint, options) { return this.request("DELETE", endpoint, void 0, options); } /** * Core request method with retry logic and dev mode support */ async request(method, endpoint, data, options, params) { const url = this.buildURL(endpoint, params); if (isDevelopment(this.environment)) { return this.logDevRequest(method, url, data); } return this.executeRequest(method, url, data, options); } /** * Log request in development mode instead of sending to API */ logDevRequest(method, url, data) { console.log("[Commet SDK] Dev mode"); console.log(`Method: ${method}`); console.log(`Endpoint: ${url}`); if (data) { console.log("Data:", JSON.stringify(data, null, 2)); } console.log("Request logged, not sent to server"); if (this.config.debug) { console.log("Base URL:", "https://api.commet.co/api"); console.log("Debug mode enabled"); } return Promise.resolve({ success: true, devMode: true, data: { id: `dev_${Date.now()}` } }); } /** * Execute real API request with retry logic */ async executeRequest(method, url, data, options, attempt = 1) { try { const headers = { "x-api-key": this.config.apiKey, "Content-Type": "application/json", "User-Agent": "@repo/sdk/0.1.0" }; if (options?.idempotencyKey) { headers["Idempotency-Key"] = options.idempotencyKey; } else if (method === "POST" && data) { headers["Idempotency-Key"] = this.generateIdempotencyKey(); } const requestConfig = { method, headers, signal: AbortSignal.timeout( options?.timeout ?? this.config.timeout ?? 3e4 ) }; if (data) { requestConfig.body = JSON.stringify(data); } if (this.config.debug) { console.log(`[Commet SDK] ${method} ${url}`); if (data) { console.log("Request data:", JSON.stringify(data, null, 2)); } } const response = await fetch(url, requestConfig); if (this.config.debug) { console.log( `[Commet SDK] Response status: ${response.status} ${response.statusText}` ); } let responseData; let responseText; try { const responseClone = response.clone(); responseData = await response.json(); responseText = ""; } catch (jsonError) { try { responseText = await response.text(); } catch (textError) { responseText = "Failed to read response body"; } if (this.config.debug) { console.log( "[Commet SDK] Failed to parse JSON response:", responseText ); } throw new CommetAPIError( `Invalid JSON response: ${response.status} ${response.statusText}`, response.status, "INVALID_JSON", { responseText } ); } if (!response.ok) { if (attempt <= this.retryConfig.maxRetries && this.retryConfig.retryableStatusCodes.includes(response.status)) { const delay = Math.min( this.retryConfig.baseDelay * 2 ** (attempt - 1), this.retryConfig.maxDelay ); if (this.config.debug) { console.log( `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})` ); } await this.sleep(delay); return this.executeRequest(method, url, data, options, attempt + 1); } if (this.config.debug) { console.log( "[Commet SDK] Error response:", JSON.stringify(responseData, null, 2) ); } const isErrorResponse = (data2) => { return typeof data2 === "object" && data2 !== null; }; const errorData = isErrorResponse(responseData) ? responseData : {}; if (response.status === 400 && errorData.errors) { throw new CommetValidationError( errorData.message || "Validation failed", errorData.errors ); } throw new CommetAPIError( errorData.message || `Request failed with status ${response.status}`, response.status, errorData.code, errorData.details ); } if (this.config.debug) { console.log("[Commet SDK] Response:", responseData); } return responseData; } catch (error) { if (error instanceof TypeError && error.message.includes("fetch")) { if (attempt <= this.retryConfig.maxRetries) { const delay = Math.min( this.retryConfig.baseDelay * 2 ** (attempt - 1), this.retryConfig.maxDelay ); if (this.config.debug) { console.log(`[Commet SDK] Network error, retrying in ${delay}ms`); } await this.sleep(delay); return this.executeRequest(method, url, data, options, attempt + 1); } } throw error; } } /** * Build full URL from endpoint and params */ buildURL(endpoint, params) { const baseURL = "https://api.commet.co"; const fullPath = `/api${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`; if (this.config.debug) { console.log( `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}` ); } const url = new URL(fullPath, baseURL); if (params) { for (const [key, value] of Object.entries(params)) { if (value !== void 0 && value !== null) { url.searchParams.append(key, String(value)); } } } const finalUrl = url.toString(); if (this.config.debug) { console.log(`[Commet SDK] Final URL: ${finalUrl}`); } return finalUrl; } /** * Generate idempotency key */ generateIdempotencyKey() { return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`; } /** * Sleep for specified milliseconds */ sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } }; // src/client.ts var Commet = class { constructor(config) { if (!config.apiKey) { throw new Error("Commet SDK: API key is required"); } if (!config.apiKey.startsWith("ck_")) { throw new Error( "Commet SDK: Invalid API key format. Expected format: ck_xxx..." ); } this.environment = config.environment === "auto" ? detectEnvironment() : config.environment || detectEnvironment(); this.httpClient = new CommetHTTPClient(config, this.environment); this.customers = new CustomersResource(this.httpClient); this.usage = new UsageResource(this.httpClient); this.seats = new SeatsResource(this.httpClient); if (this.environment === "development" || config.debug) { console.log(`[Commet SDK] Initialized in ${this.environment} mode`); if (config.debug) { console.log("API Key:", `${config.apiKey.substring(0, 12)}...`); console.log("Base URL:", "https://api.commet.co"); if (this.environment === "development") { console.log( "Dev mode: Events will be logged to console, not sent to server" ); } } } } getEnvironment() { return this.environment; } isDevelopment() { return this.environment === "development"; } isProduction() { return this.environment === "production"; } }; // src/index.ts var index_default = Commet; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Commet, CommetAPIError, CommetError, CommetValidationError, detectEnvironment, isDevelopment, isProduction }); //# sourceMappingURL=index.js.map