UNPKG

sendrly

Version:

Official Sendrly TypeScript/JavaScript SDK - Simple, type-safe email automation for developers

275 lines (271 loc) 9.49 kB
var __typeError = (msg) => { throw TypeError(msg); }; var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); // src/validation.ts import { z } from "zod"; var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; var eventPayloadSchema = z.object({ email: z.string().min(1, "Email is required").transform((email) => email.toLowerCase().trim()).pipe(z.string().regex(EMAIL_REGEX, "Invalid email format")), event: z.string().min(1, "Event name is required"), marketing_opt_out: z.boolean().optional().default(false), contact_properties: z.record(z.unknown()).optional().default({}), event_properties: z.record(z.unknown()).optional().default({}) }).strict(); var mapToEdgePayload = (payload) => ({ contact: { email: payload.email, marketing_opt_out: payload.marketing_opt_out, properties: payload.contact_properties }, event: { name: payload.event, properties: payload.event_properties } }); var validatePayload = (payload) => { return eventPayloadSchema.parse(payload); }; // src/types.ts var SendrlyError = class extends Error { constructor(message, code) { super(message); this.name = "SendrlyError"; this.code = code; } }; // src/index.ts import { ZodError } from "zod"; var _apiKey, _debug, _baseUrl, _Sendrly_instances, log_fn; var Sendrly = class { constructor(config) { __privateAdd(this, _Sendrly_instances); __privateAdd(this, _apiKey); __privateAdd(this, _debug); __privateAdd(this, _baseUrl, "https://stebgknkomdhjikpcytk.supabase.co/functions/v1"); __privateSet(this, _apiKey, config.apiKey); __privateSet(this, _debug, config.debug ?? false); if (__privateGet(this, _debug)) { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Initialized with config:", { apiKey: __privateGet(this, _apiKey), debug: __privateGet(this, _debug) }); } if (!__privateGet(this, _apiKey)) { throw new SendrlyError("API key is required", "INVALID_CONFIG"); } } /** * Send an event for a contact * @example * // Simple event tracking * await sendrly.sendEvent({ * email: 'sarah@startup.com', * event: 'user.welcome' * }) * * // Event with properties * await sendrly.sendEvent({ * email: 'john@company.com', * event: 'order.completed', * contact_properties: { * name: 'John Smith', * plan: 'enterprise' * }, * event_properties: { * order_id: 'ORD-123', * amount: 499.99 * } * }) */ async sendEvent(payload) { try { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Sending event with payload:", payload); const validatedPayload = validatePayload(payload); __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Payload validated successfully:", validatedPayload); const response = await fetch(`${__privateGet(this, _baseUrl)}/event`, { method: "POST", headers: { "Content-Type": "application/json", apikey: __privateGet(this, _apiKey) }, body: JSON.stringify(mapToEdgePayload(validatedPayload)) }); const data = await response.json(); if (!response.ok || !data.success) { throw new SendrlyError( data.error || "Failed to send event", response.status === 401 ? "INVALID_API_KEY" : "API_ERROR" ); } __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Event sent successfully:", payload); } catch (error) { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Error sending event:", error); if (error instanceof SendrlyError || error instanceof ZodError) { throw error; } throw new SendrlyError( error instanceof Error ? error.message : "An unknown error occurred", "UNKNOWN_ERROR" ); } } /** * Get a contact by email address * @example * // Get contact details * const contact = await sendrly.getContact('sarah@startup.com') * console.log(contact.properties.name) // 'Sarah' * * // Handle non-existent contact * try { * const contact = await sendrly.getContact('unknown@email.com') * } catch (error) { * if (error.code === 'NOT_FOUND') { * console.log('Contact does not exist') * } * } */ async getContact(email) { try { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Getting contact:", email); const response = await fetch( `${__privateGet(this, _baseUrl)}/find-contact?email=${encodeURIComponent(email)}`, { method: "GET", headers: { "Content-Type": "application/json", apikey: __privateGet(this, _apiKey) } } ); const data = await response.json(); if (!response.ok || !data.success) { throw new SendrlyError( data.error || "Failed to get contact", response.status === 404 ? "NOT_FOUND" : response.status === 401 ? "INVALID_API_KEY" : "API_ERROR" ); } return data.contact; } catch (error) { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Error getting contact:", error); if (error instanceof SendrlyError) { throw error; } throw new SendrlyError( error instanceof Error ? error.message : "An unknown error occurred", "UNKNOWN_ERROR" ); } } /** * List all events with a specific name * @example * // List all signup events * const signups = await sendrly.listEvents('user.signup') * console.log(signups[0].event_properties.source) * * // Process completed orders * const orders = await sendrly.listEvents('order.completed') * const totalRevenue = orders.reduce((sum, order) => * sum + order.event_properties.amount, 0 * ) */ async listEvents(eventName) { try { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Listing events:", eventName); const response = await fetch( `${__privateGet(this, _baseUrl)}/get-event?event=${encodeURIComponent(eventName)}`, { method: "GET", headers: { "Content-Type": "application/json", apikey: __privateGet(this, _apiKey) } } ); const data = await response.json(); if (!response.ok || !data.success) { throw new SendrlyError( data.error || "Failed to list events", response.status === 401 ? "INVALID_API_KEY" : "API_ERROR" ); } return data.events; } catch (error) { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Error listing events:", error); if (error instanceof SendrlyError) { throw error; } throw new SendrlyError( error instanceof Error ? error.message : "An unknown error occurred", "UNKNOWN_ERROR" ); } } /** * Delete a contact and all associated data * @example * // Delete a contact * await sendrly.deleteContact('sarah@startup.com') * * // Handle non-existent contact * try { * await sendrly.deleteContact('unknown@email.com') * } catch (error) { * if (error.code === 'NOT_FOUND') { * console.log('Contact already deleted') * } * } */ async deleteContact(email) { try { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Deleting contact:", email); const response = await fetch( `${__privateGet(this, _baseUrl)}/delete-contact?email=${encodeURIComponent(email)}`, { method: "DELETE", headers: { "Content-Type": "application/json", apikey: __privateGet(this, _apiKey) } } ); const data = await response.json(); if (!response.ok || !data.success) { throw new SendrlyError( data.error || "Failed to delete contact", response.status === 404 ? "NOT_FOUND" : response.status === 401 ? "INVALID_API_KEY" : "API_ERROR" ); } __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Contact deleted successfully"); } catch (error) { __privateMethod(this, _Sendrly_instances, log_fn).call(this, "Error deleting contact:", error); if (error instanceof SendrlyError) { throw error; } throw new SendrlyError( error instanceof Error ? error.message : "An unknown error occurred", "UNKNOWN_ERROR" ); } } }; _apiKey = new WeakMap(); _debug = new WeakMap(); _baseUrl = new WeakMap(); _Sendrly_instances = new WeakSet(); log_fn = function(message, data) { if (__privateGet(this, _debug)) { console.log(`[Sendrly] ${message}`, data); } }; var index_default = Sendrly; export { Sendrly, index_default as default };