@verifymail/sdk
Version:
Official JavaScript/TypeScript SDK for VerifyMail email verification API
415 lines (384 loc) • 15.1 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["EmailVerificationSDK"] = factory();
else
root["EmailVerificationSDK"] = factory();
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 156:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailVerificationService = exports.EmailVerificationClient = exports.configure = void 0;
exports.createClient = createClient;
const client_1 = __webpack_require__(499);
Object.defineProperty(exports, "EmailVerificationClient", ({ enumerable: true, get: function () { return client_1.EmailVerificationClient; } }));
const email_1 = __webpack_require__(701);
Object.defineProperty(exports, "EmailVerificationService", ({ enumerable: true, get: function () { return email_1.EmailVerificationService; } }));
const config_1 = __webpack_require__(738);
Object.defineProperty(exports, "configure", ({ enumerable: true, get: function () { return config_1.configure; } }));
function createClient(config) {
if (config.baseUrl) {
(0, config_1.configure)({ baseUrl: config.baseUrl });
}
const client = new client_1.EmailVerificationClient(config);
return new email_1.EmailVerificationService(client);
}
exports["default"] = {
createClient,
EmailVerificationClient: client_1.EmailVerificationClient,
EmailVerificationService: email_1.EmailVerificationService
};
__exportStar(__webpack_require__(574), exports);
__exportStar(__webpack_require__(923), exports);
/***/ }),
/***/ 499:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailVerificationClient = void 0;
// import { get } from "http";
const errors_1 = __webpack_require__(923);
const config_1 = __webpack_require__(738);
class EmailVerificationClient {
constructor(config) {
var _a, _b, _c;
if (!config.apiKey) {
throw new Error('API key is required');
}
this.apiKey = config.apiKey;
this.baseUrl = config.baseUrl || (0, config_1.getApiUrl)();
this.timeout = (_a = config.timeout) !== null && _a !== void 0 ? _a : 10000; // 10 seconds
this.maxRetries = (_b = config.maxRetries) !== null && _b !== void 0 ? _b : 3;
this.debug = (_c = config.debug) !== null && _c !== void 0 ? _c : false;
this.defaultHeaders = {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
'User-Agent': 'EmailVerificationClient/2.0',
'X-Client-Version': '2.0.0',
...(config.headers || {})
};
}
async request(options) {
const url = new URL(options.endpoint, this.baseUrl);
const requestId = this.generateRequestId();
// Add query parameters
if (options.params) {
Object.entries(options.params).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
url.searchParams.append(key, String(value));
}
});
}
const headers = new Headers({
...this.defaultHeaders,
'X-Request-ID': requestId,
...options.headers
});
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
// Combine signals if both exist
const abortSignal = options.signal
? this.combineSignals(controller.signal, options.signal)
: controller.signal;
let lastError = null;
let attempt = 0;
if (this.debug) {
console.debug(`[EmailVerificationClient] Starting request to ${options.method} ${url.pathname}`);
}
while (attempt < this.maxRetries) {
try {
const response = await fetch(url.toString(), {
method: options.method,
headers,
body: options.data ? JSON.stringify(options.data) : undefined,
signal: abortSignal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw await this.handleErrorResponse(response, requestId);
}
return await this.parseResponse(response);
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
attempt++;
if (this.debug) {
console.debug(`[EmailVerificationClient] Attempt ${attempt} failed:`, error);
}
// Don't retry on certain errors
if (this.shouldNotRetry(error)) {
break;
}
// Exponential backoff with jitter
if (attempt < this.maxRetries) {
const delay = this.calculateBackoff(attempt);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError || new Error(`Request failed after ${attempt} attempts`);
}
async parseResponse(response) {
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
try {
return await response.json();
}
catch (error) {
if (this.debug) {
console.debug('[EmailVerificationClient] Failed to parse JSON response:', error);
}
throw new errors_1.APIError({
message: 'Invalid JSON response',
statusCode: response.status,
details: await response.text()
});
}
}
return await response.text();
}
async handleErrorResponse(response, requestId) {
let errorDetails;
try {
errorDetails = await response.json();
}
catch (_a) {
try {
errorDetails = await response.text();
}
catch (_b) {
errorDetails = 'Failed to parse error response';
}
}
if (this.debug) {
console.debug(`[EmailVerificationClient] Request ${requestId} failed with status ${response.status}:`, errorDetails);
}
return new errors_1.APIError({
message: typeof errorDetails === 'object' && errorDetails !== null && 'message' in errorDetails
? String(errorDetails.message)
: 'API request failed',
statusCode: response.status,
code: typeof errorDetails === 'object' && errorDetails !== null && 'code' in errorDetails
? String(errorDetails.code)
: undefined,
details: errorDetails
});
}
generateRequestId() {
var _a;
return ((_a = crypto.randomUUID) === null || _a === void 0 ? void 0 : _a.call(crypto)) ||
Math.random().toString(36).substring(2) +
Date.now().toString(36);
}
shouldNotRetry(error) {
return (error instanceof errors_1.APIError &&
error.statusCode >= 400 &&
error.statusCode < 500 &&
error.statusCode !== 429);
}
calculateBackoff(attempt) {
const baseDelay = 1000; // 1 second
const maxJitter = 500; // 0.5 seconds
const jitter = Math.random() * maxJitter;
return Math.min(baseDelay * Math.pow(2, attempt) + jitter, 30000); // Max 30 seconds
}
combineSignals(...signals) {
const controller = new AbortController();
const onAbort = () => {
controller.abort();
for (const signal of signals) {
signal.removeEventListener('abort', onAbort);
}
};
for (const signal of signals) {
if (signal.aborted) {
controller.abort();
break;
}
signal.addEventListener('abort', onAbort);
}
return controller.signal;
}
}
exports.EmailVerificationClient = EmailVerificationClient;
/***/ }),
/***/ 574:
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
/***/ }),
/***/ 701:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EmailVerificationService = void 0;
const errors_1 = __webpack_require__(923);
class EmailVerificationService {
constructor(client) {
this.client = client;
}
async verifySingle(email, options = {}) {
if (!email || typeof email !== 'string') {
throw new errors_1.ValidationError('email', email, 'non-empty string');
}
return this.client.request({
method: 'POST',
endpoint: '/email/validate',
data: {
input: {
email: email.trim()
},
options: {
allow_disposable: options.allowDisposable,
validate_dns: options.validateDNS,
additional_checks: options.additionalChecks,
detailedChecks: options.detailedChecks || false
}
},
headers: options.timeout ? {
'X-Request-Timeout': options.timeout.toString()
} : undefined
});
}
async startBulkVerification(file, options = {}) {
const formData = new FormData();
formData.append('file', file instanceof Blob ? file : new Blob([file]));
if (options.name)
formData.append('name', options.name);
if (options.notifyUrl)
formData.append('notify_url', options.notifyUrl);
if (options.callbackUrl)
formData.append('callback_url', options.callbackUrl);
if (options.metadata)
formData.append('metadata', JSON.stringify(options.metadata));
return this.client.request({
method: 'POST',
endpoint: '/email/validate-bulk',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}
async getBulkVerificationStatus(jobId) {
if (!jobId || typeof jobId !== 'string') {
throw new errors_1.ValidationError('jobId', jobId, 'non-empty string');
}
return this.client.request({
method: 'GET',
endpoint: `/bulk/${jobId}`
});
}
async downloadBulkResults(jobId, format = 'json') {
if (!jobId || typeof jobId !== 'string') {
throw new errors_1.ValidationError('jobId', jobId, 'non-empty string');
}
return this.client.request({
method: 'GET',
endpoint: `/bulk/${jobId}/download`,
params: { format }
});
}
}
exports.EmailVerificationService = EmailVerificationService;
/***/ }),
/***/ 738:
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getApiUrl = exports.API_CONFIG = void 0;
exports.configure = configure;
let currentConfig = {
baseUrl: 'https://p01--verify-email--6tqyyq5fpwl7.code.run'
};
exports.API_CONFIG = currentConfig;
// Allow users to configure the SDK at runtime
function configure(config) {
currentConfig = { ...currentConfig, ...config };
}
// Helper function to get the API URL
const getApiUrl = (endpoint = '') => {
const baseUrl = currentConfig.baseUrl.replace(/\/$/, '');
const cleanEndpoint = endpoint.replace(/^\//, '');
return `${baseUrl}/${cleanEndpoint}`;
};
exports.getApiUrl = getApiUrl;
/***/ }),
/***/ 923:
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ValidationError = exports.APIError = void 0;
class APIError extends Error {
constructor(options) {
super(options.message);
this.name = 'APIError';
this.statusCode = options.statusCode;
this.code = options.code;
this.details = options.details;
}
}
exports.APIError = APIError;
class ValidationError extends Error {
constructor(field, received, expected) {
super(`Invalid value for ${field}: received ${JSON.stringify(received)}, expected ${expected}`);
this.name = 'ValidationError';
this.field = field;
this.received = received;
this.expected = expected;
}
}
exports.ValidationError = ValidationError;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__(156);
/******/
/******/ return __webpack_exports__;
/******/ })()
;
});