@mirad-work/sms-core
Version:
A framework-agnostic TypeScript SMS service core with provider abstraction for Iranian SMS providers
151 lines • 6.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmsDriverFactory = void 0;
const driver_types_1 = require("../types/driver-types");
const sms_exceptions_1 = require("../exceptions/sms-exceptions");
const http_client_1 = require("../utils/http-client");
/**
* Factory class for creating SMS driver instances
* Implements the Factory pattern for driver instantiation
*/
class SmsDriverFactory {
constructor(config, httpClient) {
this.driverInstances = new Map();
this.validateConfig(config);
this.config = config;
this.httpClient = httpClient || new http_client_1.HttpClient(config.timeout);
}
/**
* Create a driver instance for the specified driver type
* Uses singleton pattern to reuse driver instances
*/
createDriver(driverType) {
const driver = driverType || this.config.defaultDriver;
// Return cached instance if available
if (this.driverInstances.has(driver)) {
return this.driverInstances.get(driver);
}
// Create new instance
const driverInstance = this.instantiateDriver(driver);
// Cache the instance
this.driverInstances.set(driver, driverInstance);
return driverInstance;
}
/**
* Clear driver cache (useful for testing or config changes)
*/
clearCache() {
this.driverInstances.clear();
}
/**
* Get list of available drivers based on configuration
*/
getAvailableDrivers() {
const available = [];
Object.keys(this.config.drivers).forEach((key) => {
const driverKey = key;
if (this.config.drivers[driverKey]) {
available.push(key);
}
});
return available;
}
/**
* Check if a driver is available and properly configured
*/
isDriverAvailable(driverType) {
try {
this.validateDriverConfig(driverType);
return true;
}
catch {
return false;
}
}
/**
* Instantiate the actual driver based on type
*/
instantiateDriver(driverType) {
this.validateDriverConfig(driverType);
switch (driverType) {
case driver_types_1.DriverType.KAVENEGAR: {
// Dynamic import to avoid circular dependencies
const { KavenegarDriver } = require("../drivers/kavenegar-driver");
return new KavenegarDriver(this.config.drivers.kavenegar, this.httpClient);
}
case driver_types_1.DriverType.SMSIR: {
const { SmsIrDriver } = require("../drivers/smsir-driver");
return new SmsIrDriver(this.config.drivers.smsir, this.httpClient);
}
case driver_types_1.DriverType.MELIPAYAMAK: {
const { MelipayamakDriver } = require("../drivers/melipayamak-driver");
return new MelipayamakDriver(this.config.drivers.melipayamak, this.httpClient);
}
case driver_types_1.DriverType.MOCK: {
const { MockDriver } = require("../drivers/mock-driver");
return new MockDriver(this.config.drivers.mock || {}, this.httpClient);
}
default:
throw new sms_exceptions_1.UnsupportedDriverException(driverType);
}
}
/**
* Validate the main configuration
*/
validateConfig(config) {
if (!config) {
throw new sms_exceptions_1.ConfigurationException("SMS configuration is required");
}
if (!config.defaultDriver) {
throw new sms_exceptions_1.MissingConfigException("defaultDriver");
}
if (!config.drivers || Object.keys(config.drivers).length === 0) {
throw new sms_exceptions_1.ConfigurationException("At least one driver configuration is required");
}
// Validate that default driver is configured
if (!config.drivers[config.defaultDriver]) {
throw new sms_exceptions_1.ConfigurationException(`Default driver '${config.defaultDriver}' is not configured`);
}
}
/**
* Validate configuration for a specific driver
*/
validateDriverConfig(driverType) {
const driverConfig = this.config.drivers[driverType];
if (!driverConfig) {
throw new sms_exceptions_1.ConfigurationException(`Driver '${driverType}' is not configured`);
}
switch (driverType) {
case driver_types_1.DriverType.KAVENEGAR:
case driver_types_1.DriverType.SMSIR:
case driver_types_1.DriverType.MELIPAYAMAK:
this.validateBasicDriverConfig(driverConfig, driverType);
break;
case driver_types_1.DriverType.MOCK:
// Mock driver doesn't require specific config
break;
default:
throw new sms_exceptions_1.UnsupportedDriverException(driverType);
}
}
/**
* Validate basic driver configuration (url, apiKey, lineNumber)
*/
validateBasicDriverConfig(driverConfig, driverType) {
if (!driverConfig || typeof driverConfig !== "object") {
throw new sms_exceptions_1.ConfigurationException(`Driver '${driverType}' configuration must be an object`);
}
const config = driverConfig;
if (!config.url || typeof config.url !== "string") {
throw new sms_exceptions_1.ConfigurationException(`Driver '${driverType}' requires a valid url`);
}
if (!config.apiKey || typeof config.apiKey !== "string") {
throw new sms_exceptions_1.ConfigurationException(`Driver '${driverType}' requires a valid apiKey`);
}
if (!config.lineNumber || typeof config.lineNumber !== "string") {
throw new sms_exceptions_1.ConfigurationException(`Driver '${driverType}' requires a valid lineNumber`);
}
}
}
exports.SmsDriverFactory = SmsDriverFactory;
//# sourceMappingURL=sms-driver-factory.js.map