@mikkelscheike/email-provider-links
Version:
TypeScript library for email provider detection with 93 providers (207 domains), concurrent DNS resolution, optimized performance, 94.65% test coverage, and enterprise security for login and password reset flows
163 lines • 5.62 kB
JavaScript
;
/**
* Provider Data Loader
*
* Handles loading email provider data with performance optimizations.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildDomainMap = buildDomainMap;
exports.clearCache = clearCache;
exports.getLoadingStats = getLoadingStats;
exports.loadProviders = loadProviders;
exports.loadProvidersDebug = loadProvidersDebug;
const fs_1 = require("fs");
const path_1 = require("path");
const schema_1 = require("./schema");
/**
* Internal cached data
*/
let cachedProviders = null;
let cachedDomainMap = null;
let loadingStats = null;
/**
* Default loader configuration
*/
const DEFAULT_CONFIG = {
debug: false
};
/**
* Convert compressed provider to EmailProvider format
*/
function convertProviderToEmailProvider(compressedProvider) {
if (!compressedProvider.type) {
console.warn(`Missing type for provider ${compressedProvider.id}`);
}
const provider = {
companyProvider: compressedProvider.companyProvider,
loginUrl: compressedProvider.loginUrl || null,
domains: compressedProvider.domains || [],
type: compressedProvider.type,
alias: compressedProvider.alias
};
// Include DNS detection patterns for business email services and proxy services
const needsCustomDomainDetection = compressedProvider.type === 'custom_provider' ||
compressedProvider.type === 'proxy_service';
if (needsCustomDomainDetection && (compressedProvider.mx?.length || compressedProvider.txt?.length)) {
provider.customDomainDetection = {};
if (compressedProvider.mx?.length) {
provider.customDomainDetection.mxPatterns = compressedProvider.mx;
}
if (compressedProvider.txt?.length) {
// Decompress TXT patterns
provider.customDomainDetection.txtPatterns = compressedProvider.txt.map(schema_1.decompressTxtPattern);
}
}
return provider;
}
/**
* Internal provider data loader with configuration
*/
function loadProvidersInternal(config = {}) {
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
const startTime = Date.now();
// Return cached data if available
if (cachedProviders && !mergedConfig.debug) {
return {
providers: cachedProviders,
stats: loadingStats
};
}
try {
// Determine file path
const basePath = (0, path_1.join)(__dirname, '..', 'providers');
const dataPath = mergedConfig.path || (0, path_1.join)(basePath, 'emailproviders.json');
if (mergedConfig.debug)
console.log('🔄 Loading provider data...');
const content = (0, fs_1.readFileSync)(dataPath, 'utf8');
const data = JSON.parse(content);
// Validate format
if (!data.version || !data.providers || !Array.isArray(data.providers)) {
throw new Error('Invalid provider data format');
}
const providers = data.providers.map(convertProviderToEmailProvider);
const fileSize = content.length;
if (mergedConfig.debug) {
console.log(`✅ Loaded ${providers.length} providers`);
console.log(`📊 File size: ${(fileSize / 1024).toFixed(1)} KB`);
}
const loadTime = Date.now() - startTime;
const domainCount = providers.reduce((sum, p) => sum + p.domains.length, 0);
// Cache the results
cachedProviders = providers;
loadingStats = {
fileSize,
loadTime,
providerCount: providers.length,
domainCount
};
if (mergedConfig.debug) {
console.log(`⚡ Loading completed in ${loadTime}ms`);
console.log(`📊 Stats: ${providers.length} providers, ${domainCount} domains`);
}
if (process.env.NODE_ENV === 'development') {
const memoryUsageInMB = process.memoryUsage().heapUsed / 1024 / 1024;
console.log(`🚀 Current memory usage: ${memoryUsageInMB.toFixed(2)} MB`);
}
return {
providers,
stats: loadingStats
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
throw new Error(`Failed to load provider data: ${errorMessage}`);
}
}
/**
* Build optimized domain-to-provider lookup map
*/
function buildDomainMap(providers) {
if (cachedDomainMap) {
return cachedDomainMap;
}
const domainMap = new Map();
for (const provider of providers) {
for (const domain of provider.domains) {
domainMap.set(domain.toLowerCase(), provider);
}
}
cachedDomainMap = domainMap;
return domainMap;
}
/**
* Clear all caches (useful for testing or hot reloading)
*/
function clearCache() {
cachedProviders = null;
cachedDomainMap = null;
loadingStats = null;
}
/**
* Get loading statistics from the last load operation
*/
function getLoadingStats() {
return loadingStats;
}
/**
* Load all providers with optimized domain map for production
*/
function loadProviders() {
const { providers, stats } = loadProvidersInternal({ debug: false });
const domainMap = buildDomainMap(providers);
return { providers, domainMap, stats };
}
/**
* Load providers with debug information
*/
function loadProvidersDebug() {
clearCache(); // Always reload in debug mode
const { providers, stats } = loadProvidersInternal({ debug: true });
const domainMap = buildDomainMap(providers);
return { providers, domainMap, stats };
}
//# sourceMappingURL=loader.js.map