@go-waitly/waitly-sdk
Version:
Waitly SDK - Your waitlist as code
1 lines • 13.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"names":["WaitlyClient","config","entry","endpoint","error","response","email","controller","method","body","url","requestId","abortController","timeoutId","options","lastError","attempt","ms","resolve","createWaitlyClient"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Waitlist SDK - Client JavaScript/TypeScript to manage waitlists\n * @version 1.0.2\n */\n\nexport interface WaitlyConfig {\n waitlistId: string;\n apiKey: string;\n apiUrl?: string;\n timeout?: number;\n retryAttempts?: number;\n headers?: Record<string, string>;\n}\n\nexport interface WaitlyEntry {\n email: string;\n referredByCode?: string;\n utm?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface WaitlyEntryResponse {\n id: string;\n email: string;\n}\n\nexport interface WaitlyStats {\n totalEntries: number;\n}\n\nexport interface WaitlyError {\n code: string;\n message: string;\n details?: any;\n statusCode?: number;\n}\n\nexport class WaitlyClient {\n private config: Required<WaitlyConfig>;\n private abortControllers: Map<string, AbortController> = new Map();\n\n constructor(config: WaitlyConfig) {\n if (!config.waitlistId) {\n throw new Error('waitlistId is required');\n }\n if (!config.apiKey) {\n throw new Error('apiKey is required');\n }\n\n this.config = {\n waitlistId: config.waitlistId,\n apiKey: config.apiKey,\n apiUrl: config.apiUrl || 'https://www.gowaitly.com',\n timeout: config.timeout || 10000,\n retryAttempts: config.retryAttempts || 3,\n headers: config.headers || {},\n };\n }\n\n /**\n * Create a new entry in the waitlist\n * @param entry - Entry data\n * @returns Promise with the entry details\n */\n async createWaitlyEntry(entry: WaitlyEntry): Promise<WaitlyEntryResponse> {\n if (!entry.email) {\n throw new Error('Email is required');\n }\n if (!this.isValidEmail(entry.email)) {\n throw new Error('Invalid email format');\n }\n\n const endpoint = `/api/waitlists/${this.config.waitlistId}/entries`;\n\n try {\n const response = await this.request<WaitlyEntryResponse>('POST', endpoint, {\n email: entry.email.toLowerCase().trim(),\n referredByCode: entry.referredByCode,\n utm: entry.utm,\n metadata: entry.metadata,\n });\n\n return response;\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n /**\n * Get the number of entries in the waitlist\n * @param options - Filtering options (optional)\n * @returns Promise with the statistics\n */\n async getWaitlyEntriesCount(): Promise<number | WaitlyStats> {\n const endpoint = `/api/waitlists/${this.config.waitlistId}/count`;\n\n try {\n const response = await this.request<WaitlyStats | { count: number }>('GET', endpoint);\n\n return 'totalEntries' in response\n ? (response as WaitlyStats).totalEntries\n : (response as { count: number }).count;\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n /**\n * Check if an email is already registered\n * @param email - Email to check\n * @returns Promise<boolean>\n */\n async checkEmailExists(email: string): Promise<boolean> {\n if (!this.isValidEmail(email)) {\n throw new Error('Invalid email format');\n }\n\n const endpoint = `/api/waitlists/${this.config.waitlistId}/check`;\n\n try {\n const response = await this.request<{ exists: boolean }>('POST', endpoint, {\n email: email.toLowerCase().trim(),\n });\n return response.exists;\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n /**\n * Cancel all requests\n */\n cancelAllRequests(): void {\n this.abortControllers.forEach((controller) => controller.abort());\n this.abortControllers.clear();\n }\n\n // Méthodes privées\n\n private async request<T>(method: string, endpoint: string, body?: any): Promise<T> {\n const url = `${this.config.apiUrl}${endpoint}`;\n const requestId = `${method}-${endpoint}-${Date.now()}`;\n\n // Créer un AbortController pour cette requête\n const abortController = new AbortController();\n this.abortControllers.set(requestId, abortController);\n\n // Timeout\n const timeoutId = setTimeout(() => {\n abortController.abort();\n }, this.config.timeout);\n\n const options: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.config.apiKey,\n 'X-SDK-Version': '1.0.0',\n 'X-Waitlist-ID': this.config.waitlistId,\n ...this.config.headers,\n },\n signal: abortController.signal,\n };\n\n if (body && method !== 'GET') {\n options.body = JSON.stringify(body);\n }\n\n let lastError: any;\n\n // Retry logic\n for (let attempt = 0; attempt < this.config.retryAttempts; attempt++) {\n try {\n const response = await fetch(url, options);\n\n clearTimeout(timeoutId);\n this.abortControllers.delete(requestId);\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({\n message: `HTTP ${response.status}: ${response.statusText}`,\n }));\n\n // Ne pas retry pour les erreurs client (4xx)\n if (response.status >= 400 && response.status < 500) {\n throw { statusCode: response.status, ...error };\n }\n\n lastError = { statusCode: response.status, ...error };\n\n // Retry avec backoff exponentiel pour les erreurs serveur\n if (attempt < this.config.retryAttempts - 1) {\n await this.delay(Math.pow(2, attempt) * 1000);\n continue;\n }\n }\n\n const data = await response.json();\n return data as T;\n } catch (error: any) {\n clearTimeout(timeoutId);\n this.abortControllers.delete(requestId);\n\n if (error.name === 'AbortError') {\n throw new Error('Request timeout');\n }\n\n lastError = error;\n\n // Retry avec backoff pour les erreurs réseau\n if (attempt < this.config.retryAttempts - 1 && !error.statusCode) {\n await this.delay(Math.pow(2, attempt) * 1000);\n continue;\n }\n }\n }\n\n throw lastError;\n }\n\n private handleError(error: any): WaitlyError {\n if (error.statusCode === 400) {\n return {\n code: 'VALIDATION_ERROR',\n message: error.message || 'Invalid request data',\n details: error.details,\n statusCode: 400,\n };\n }\n\n if (error.statusCode === 401) {\n return {\n code: 'UNAUTHORIZED',\n message: 'Invalid API key',\n statusCode: 401,\n };\n }\n\n if (error.statusCode === 404) {\n return {\n code: 'NOT_FOUND',\n message: 'Waitlist not found',\n statusCode: 404,\n };\n }\n\n if (error.statusCode === 409) {\n return {\n code: 'DUPLICATE_ENTRY',\n message: error.message || 'Email already registered',\n statusCode: 409,\n };\n }\n\n if (error.statusCode === 429) {\n return {\n code: 'RATE_LIMIT',\n message: 'Too many requests',\n statusCode: 429,\n };\n }\n\n if (error.message === 'Request timeout') {\n return {\n code: 'TIMEOUT',\n message: 'Request timeout',\n statusCode: 0,\n };\n }\n\n return {\n code: 'UNKNOWN_ERROR',\n message: error.message || 'An unexpected error occurred',\n details: error,\n statusCode: error.statusCode || 0,\n };\n }\n\n private isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\nexport function createWaitlyClient(config: WaitlyConfig): WaitlyClient {\n return new WaitlyClient(config);\n}\n"]}