@k-msg/provider 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/abstract/provider.base.d.ts +108 -0
- package/dist/adapters/aligo.adapter.d.ts +50 -0
- package/dist/adapters/iwinv.adapter.d.ts +111 -0
- package/dist/aligo/provider.d.ts +18 -0
- package/dist/config/provider-config-v2.d.ts +122 -0
- package/dist/contracts/provider.contract.d.ts +355 -0
- package/dist/contracts/sms.contract.d.ts +135 -0
- package/dist/index.d.ts +29 -1424
- package/dist/index.js +21 -2003
- package/dist/index.js.map +98 -1
- package/dist/index.mjs +25 -0
- package/dist/index.mjs.map +98 -0
- package/dist/interfaces/index.d.ts +14 -0
- package/dist/interfaces/plugin.d.ts +122 -0
- package/dist/interfaces/services.d.ts +222 -0
- package/dist/iwinv/contracts/account.contract.d.ts +11 -0
- package/dist/iwinv/contracts/analytics.contract.d.ts +16 -0
- package/dist/iwinv/contracts/channel.contract.d.ts +15 -0
- package/dist/iwinv/contracts/messaging.contract.d.ts +14 -0
- package/dist/iwinv/contracts/sms.contract.d.ts +33 -0
- package/dist/iwinv/contracts/template.contract.d.ts +18 -0
- package/dist/iwinv/index.d.ts +5 -0
- package/dist/iwinv/provider-multi.d.ts +116 -0
- package/dist/iwinv/provider-sms.d.ts +55 -0
- package/dist/iwinv/provider.d.ts +42 -0
- package/dist/iwinv/types/iwinv.d.ts +153 -0
- package/dist/middleware/index.d.ts +27 -0
- package/dist/mock/index.d.ts +1 -0
- package/dist/providers/mock/index.d.ts +1 -0
- package/dist/providers/mock/mock.provider.d.ts +22 -0
- package/dist/registry/index.d.ts +1 -0
- package/dist/registry/plugin-registry.d.ts +15 -0
- package/dist/services/provider.manager.d.ts +24 -0
- package/dist/services/provider.service.d.ts +49 -0
- package/dist/test-helpers.d.ts +110 -0
- package/dist/types/aligo.d.ts +69 -0
- package/dist/types/base.d.ts +172 -0
- package/dist/types/typed-templates.d.ts +199 -0
- package/dist/types/unified-config.d.ts +197 -0
- package/dist/types/unified-errors.d.ts +225 -0
- package/dist/utils/base-plugin.d.ts +35 -0
- package/dist/utils/index.d.ts +12 -0
- package/package.json +25 -14
- package/dist/index.cjs +0 -2061
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1425
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/registry/plugin-registry.ts","../src/middleware/index.ts","../src/utils/base-plugin.ts","../src/utils/index.ts","../src/abstract/provider.base.ts","../src/adapters/request.adapter.ts","../src/adapters/response.adapter.ts","../src/services/provider.manager.ts","../src/iwinv/contracts/messaging.contract.ts","../src/iwinv/contracts/template.contract.ts","../src/iwinv/contracts/channel.contract.ts","../src/iwinv/contracts/analytics.contract.ts","../src/iwinv/contracts/account.contract.ts","../src/iwinv/provider.ts"],"sourcesContent":["/**\n * @k-msg/provider\n * Complete provider system with adapters and implementations\n */\n\n// =============================================================================\n// CORE PROVIDER SYSTEM\n// =============================================================================\n\n// Base types and interfaces - avoid conflicts with explicit exports\nexport type {\n MessageChannel,\n MessageType,\n SendOptions,\n MediaAttachment,\n HealthCheckResult,\n SendResult,\n TemplateResult,\n BaseProvider,\n MessageContent,\n MessageButton,\n TemplateCreateRequest,\n TemplateUpdateRequest,\n SenderNumber,\n SenderVerificationResult,\n ChannelInfo,\n BaseProviderConfig,\n TemplateFilters,\n HistoryFilters\n} from './types/base';\n\n// Interfaces\nexport type {\n NotificationRequest,\n NotificationResponse\n} from './interfaces';\n\n// Plugin interfaces\nexport * from './interfaces/plugin';\n\n// Provider registry and plugin system\nexport * from './registry';\nexport * from './middleware';\nexport * from './utils';\n\n// =============================================================================\n// PROVIDER CONTRACTS AND ADAPTERS\n// =============================================================================\n\n// Provider contracts (from provider-adapter)\nexport type {\n ProviderCapabilities,\n ProviderConfiguration,\n ConfigurationField,\n MessagingContract,\n TemplateContract,\n ChannelContract,\n AnalyticsContract,\n AccountContract,\n ScheduleResult\n} from './contracts/provider.contract';\n\n// Abstract base provider (from provider-adapter)\nexport { BaseAlimTalkProvider } from './abstract/provider.base';\n\n// Request/Response adapters (from provider-adapter)\nexport {\n BaseRequestAdapter,\n IWINVRequestAdapter,\n AligoRequestAdapter,\n KakaoRequestAdapter,\n RequestAdapterFactory\n} from './adapters/request.adapter';\n\nexport {\n BaseResponseAdapter,\n IWINVResponseAdapter,\n AligoResponseAdapter,\n KakaoResponseAdapter,\n NHNResponseAdapter,\n ResponseAdapterFactory\n} from './adapters/response.adapter';\n\n// Provider manager service (from provider-adapter)\nexport * from './services/provider.manager';\n\n// =============================================================================\n// PROVIDER IMPLEMENTATIONS\n// =============================================================================\n\n// IWINV Provider\nexport { IWINVProvider } from './iwinv/provider';\nexport type * from './iwinv/types/iwinv';","import type { \n ProviderPlugin, \n ProviderConfig, \n PluginContext, \n Logger,\n MetricsCollector,\n PluginStorage \n} from '../interfaces';\nimport { EventEmitter } from 'events';\n\nexport class PluginRegistry {\n private plugins = new Map<string, ProviderPlugin>();\n private instances = new Map<string, ProviderPlugin>();\n\n register(plugin: ProviderPlugin): void {\n const id = plugin.metadata.name.toLowerCase();\n \n if (this.plugins.has(id)) {\n throw new Error(`Plugin ${id} is already registered`);\n }\n \n this.plugins.set(id, plugin);\n }\n\n async create(\n pluginId: string, \n config: ProviderConfig,\n options: {\n logger?: Logger;\n metrics?: MetricsCollector;\n storage?: PluginStorage;\n } = {}\n ): Promise<ProviderPlugin> {\n const plugin = this.plugins.get(pluginId.toLowerCase());\n \n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n // 새 인스턴스 생성\n const PluginClass = plugin.constructor as new() => ProviderPlugin;\n const instance = new PluginClass();\n\n // 컨텍스트 생성\n const context: PluginContext = {\n config,\n logger: options.logger || new ConsoleLogger(),\n metrics: options.metrics || new NoOpMetricsCollector(),\n storage: options.storage || new MemoryStorage(),\n eventBus: new EventEmitter(),\n };\n\n // 초기화\n await instance.initialize(context);\n\n const instanceKey = `${pluginId}-${Date.now()}`;\n this.instances.set(instanceKey, instance);\n\n return instance;\n }\n\n async loadAndCreate(\n pluginId: string,\n config: ProviderConfig,\n options?: any\n ): Promise<ProviderPlugin> {\n // 동적 로딩 지원 (나중에 구현)\n return this.create(pluginId, config, options);\n }\n\n getSupportedTypes(): string[] {\n return Array.from(this.plugins.keys());\n }\n\n validateProviderConfig(type: string, config: ProviderConfig): boolean {\n const plugin = this.plugins.get(type.toLowerCase());\n if (!plugin) return false;\n\n // 기본 검증 로직\n return !!(config.apiUrl && config.apiKey);\n }\n\n async destroyAll(): Promise<void> {\n const destroyPromises = Array.from(this.instances.values()).map(\n instance => instance.destroy()\n );\n \n await Promise.all(destroyPromises);\n this.instances.clear();\n }\n}\n\n// 기본 구현체들\nclass ConsoleLogger implements Logger {\n info(message: string, ...args: any[]): void {\n console.log(`[INFO] ${message}`, ...args);\n }\n \n error(message: string, error?: any): void {\n console.error(`[ERROR] ${message}`, error);\n }\n \n debug(message: string, ...args: any[]): void {\n console.debug(`[DEBUG] ${message}`, ...args);\n }\n \n warn(message: string, ...args: any[]): void {\n console.warn(`[WARN] ${message}`, ...args);\n }\n}\n\nclass NoOpMetricsCollector implements MetricsCollector {\n increment(_metric: string, _labels?: Record<string, string>): void {}\n histogram(_metric: string, _value: number, _labels?: Record<string, string>): void {}\n gauge(_metric: string, _value: number, _labels?: Record<string, string>): void {}\n}\n\nclass MemoryStorage implements PluginStorage {\n private store = new Map<string, { value: any; expiry?: number }>();\n\n async get(key: string): Promise<any> {\n const item = this.store.get(key);\n \n if (!item) return undefined;\n \n if (item.expiry && Date.now() > item.expiry) {\n this.store.delete(key);\n return undefined;\n }\n \n return item.value;\n }\n\n async set(key: string, value: any, ttl?: number): Promise<void> {\n const expiry = ttl ? Date.now() + (ttl * 1000) : undefined;\n this.store.set(key, { value, expiry });\n }\n\n async delete(key: string): Promise<void> {\n this.store.delete(key);\n }\n}","import type { ProviderMiddleware, MiddlewareContext } from '../interfaces';\n\nexport function createRetryMiddleware(options: {\n maxRetries: number;\n retryDelay: number;\n retryableErrors?: string[];\n retryableStatusCodes?: number[];\n}): ProviderMiddleware {\n return {\n name: 'retry',\n error: async (error: any, context: MiddlewareContext) => {\n const retries = context.metadata.retries || 0;\n \n if (retries >= options.maxRetries) {\n throw error;\n }\n \n // 재시도 가능한 에러인지 확인\n const isRetryable = \n options.retryableErrors?.includes(error.code) ||\n options.retryableStatusCodes?.includes(error.status) ||\n error.code === 'ETIMEDOUT' ||\n error.code === 'ECONNRESET';\n \n if (!isRetryable) {\n throw error;\n }\n \n // 지연 후 재시도\n await new Promise(resolve => \n setTimeout(resolve, options.retryDelay * (retries + 1))\n );\n \n context.metadata.retries = retries + 1;\n // 실제 재시도 로직은 호출하는 쪽에서 처리\n throw { ...error, shouldRetry: true };\n }\n };\n}\n\nexport function createRateLimitMiddleware(options: {\n messagesPerSecond?: number;\n messagesPerMinute?: number;\n messagesPerHour?: number;\n messagesPerDay?: number;\n strategy?: 'sliding-window' | 'fixed-window';\n}): ProviderMiddleware {\n const windows = new Map<string, number[]>();\n \n return {\n name: 'rate-limit',\n pre: async (context: MiddlewareContext) => {\n const now = Date.now();\n const key = 'global'; // 프로바이더별로 구분 가능\n \n if (!windows.has(key)) {\n windows.set(key, []);\n }\n \n const timestamps = windows.get(key)!;\n \n // 초당 제한 확인\n if (options.messagesPerSecond) {\n const recentCount = timestamps.filter(t => now - t < 1000).length;\n if (recentCount >= options.messagesPerSecond) {\n throw new Error('Rate limit exceeded: messages per second');\n }\n }\n \n // 분당 제한 확인\n if (options.messagesPerMinute) {\n const recentCount = timestamps.filter(t => now - t < 60000).length;\n if (recentCount >= options.messagesPerMinute) {\n throw new Error('Rate limit exceeded: messages per minute');\n }\n }\n \n // 타임스탬프 추가\n timestamps.push(now);\n \n // 오래된 타임스탬프 정리 (1시간 이상)\n const cutoff = now - 3600000;\n const filtered = timestamps.filter(t => t > cutoff);\n windows.set(key, filtered);\n }\n };\n}\n\nexport function createLoggingMiddleware(options: {\n logger: any;\n logLevel?: string;\n}): ProviderMiddleware {\n return {\n name: 'logging',\n pre: async (context: MiddlewareContext) => {\n if (options.logLevel === 'debug') {\n options.logger.debug('Request started', {\n metadata: context.metadata,\n timestamp: context.startTime\n });\n }\n },\n post: async (context: MiddlewareContext) => {\n const duration = Date.now() - context.startTime;\n options.logger.info('Request completed', {\n duration,\n success: true\n });\n },\n error: async (error: Error, context: MiddlewareContext) => {\n const duration = Date.now() - context.startTime;\n options.logger.error('Request failed', {\n error: error.message,\n duration,\n stack: error.stack\n });\n }\n };\n}\n\nexport function createMetricsMiddleware(options: {\n collector: any;\n labels?: Record<string, string>;\n}): ProviderMiddleware {\n return {\n name: 'metrics',\n pre: async (context: MiddlewareContext) => {\n options.collector.increment('requests_total', options.labels);\n },\n post: async (context: MiddlewareContext) => {\n const duration = Date.now() - context.startTime;\n options.collector.histogram('request_duration_ms', duration, options.labels);\n options.collector.increment('requests_success_total', options.labels);\n },\n error: async (error: Error, context: MiddlewareContext) => {\n const duration = Date.now() - context.startTime;\n options.collector.histogram('request_duration_ms', duration, options.labels);\n options.collector.increment('requests_error_total', {\n ...options.labels,\n error_type: error.constructor.name\n });\n }\n };\n}\n\nexport function createCircuitBreakerMiddleware(options: {\n threshold: number;\n timeout: number;\n resetTimeout: number;\n}): ProviderMiddleware {\n let state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';\n let failures = 0;\n let nextAttempt = 0;\n \n return {\n name: 'circuit-breaker',\n pre: async (context: MiddlewareContext) => {\n const now = Date.now();\n \n if (state === 'OPEN') {\n if (now < nextAttempt) {\n throw new Error('Circuit breaker is OPEN');\n }\n state = 'HALF_OPEN';\n }\n },\n post: async (context: MiddlewareContext) => {\n if (state === 'HALF_OPEN') {\n state = 'CLOSED';\n failures = 0;\n }\n },\n error: async (error: Error, context: MiddlewareContext) => {\n failures++;\n \n if (failures >= options.threshold) {\n state = 'OPEN';\n nextAttempt = Date.now() + options.resetTimeout;\n }\n \n throw error;\n }\n };\n}","import type {\n ProviderPlugin,\n ProviderMetadata,\n ProviderCapabilities,\n PluginContext,\n ProviderMiddleware,\n ProviderImplementation\n} from '../interfaces';\n// Response adapters are in provider-interface package\n// import { BaseRequestAdapter, BaseResponseAdapter } from '@k-msg/provider-interface';\n\nexport abstract class BasePlugin implements ProviderPlugin {\n abstract readonly metadata: ProviderMetadata;\n abstract readonly capabilities: ProviderCapabilities;\n\n protected context!: PluginContext;\n public middleware: ProviderMiddleware[] = [];\n\n async initialize(context: PluginContext): Promise<void> {\n this.context = context;\n this.context.logger.info(`Initializing plugin: ${this.metadata.name}`);\n }\n\n async destroy(): Promise<void> {\n this.context.logger.info(`Destroying plugin: ${this.metadata.name}`);\n // 서브클래스에서 오버라이드 가능\n }\n\n abstract getImplementation(): ProviderImplementation;\n\n protected async executeMiddleware(\n phase: 'pre' | 'post' | 'error',\n context: any,\n error?: Error\n ): Promise<void> {\n for (const middleware of this.middleware) {\n try {\n if (phase === 'pre' && middleware.pre) {\n await middleware.pre(context);\n } else if (phase === 'post' && middleware.post) {\n await middleware.post(context);\n } else if (phase === 'error' && middleware.error && error) {\n await middleware.error(error, context);\n }\n } catch (err) {\n this.context.logger.error(`Middleware ${middleware.name} failed`, err);\n throw err;\n }\n }\n }\n\n protected createMiddlewareContext(request: any, metadata: Record<string, any> = {}) {\n return {\n request,\n response: undefined as any,\n metadata: {\n ...metadata,\n pluginName: this.metadata.name,\n pluginVersion: this.metadata.version\n },\n startTime: Date.now()\n };\n }\n\n protected validateConfig(config: any, required: string[]): void {\n for (const field of required) {\n if (!config[field]) {\n throw new Error(`${this.metadata.name}: Missing required config field: ${field}`);\n }\n }\n }\n\n protected async makeRequest(\n url: string,\n options: RequestInit,\n metadata: Record<string, any> = {}\n ): Promise<Response> {\n const context = this.createMiddlewareContext({ url, options }, metadata);\n\n try {\n await this.executeMiddleware('pre', context);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'User-Agent': `K-OTP-${this.metadata.name}/${this.metadata.version}`,\n ...this.context.config.headers,\n ...options.headers,\n },\n signal: AbortSignal.timeout(this.context.config.timeout || 30000)\n });\n\n context.response = response;\n await this.executeMiddleware('post', context);\n\n return response;\n } catch (error) {\n await this.executeMiddleware('error', context, error as Error);\n throw error;\n }\n }\n\n /**\n * Make HTTP request and parse JSON response\n * Subclasses should use their specific response adapters to transform the result\n */\n protected async makeJSONRequest<T = any>(\n url: string,\n options: RequestInit,\n metadata: Record<string, any> = {}\n ): Promise<T> {\n const response = await this.makeRequest(url, options, metadata);\n\n if (!response.ok) {\n const error = new Error(`HTTP ${response.status}: ${response.statusText}`);\n (error as any).response = response;\n (error as any).status = response.status;\n throw error;\n }\n\n try {\n return await response.json() as T;\n } catch (parseError) {\n const error = new Error('Failed to parse JSON response');\n (error as any).response = response;\n (error as any).parseError = parseError;\n throw error;\n }\n }\n\n /**\n * Helper method for logging provider-specific operations\n */\n protected logOperation(operation: string, data?: any): void {\n this.context.logger.info(`${this.metadata.name}: ${operation}`, data);\n }\n\n /**\n * Helper method for logging provider-specific errors\n */\n protected logError(operation: string, error: any, data?: any): void {\n this.context.logger.error(`${this.metadata.name}: ${operation} failed`, { error, data });\n }\n}","export * from './base-plugin';\n\nexport function normalizePhoneNumber(phone: string): string {\n // 한국 휴대폰 번호 정규화\n const cleaned = phone.replace(/[^\\d]/g, '');\n \n // 국가코드 제거\n if (cleaned.startsWith('82')) {\n return '0' + cleaned.substring(2);\n }\n \n // 이미 0으로 시작하면 그대로\n if (cleaned.startsWith('0')) {\n return cleaned;\n }\n \n // 10~11자리 숫자면 앞에 0 추가\n if (cleaned.length >= 10 && cleaned.length <= 11) {\n return '0' + cleaned;\n }\n \n return cleaned;\n}\n\nexport function validatePhoneNumber(phone: string): boolean {\n const normalized = normalizePhoneNumber(phone);\n return /^01[0-9]{8,9}$/.test(normalized);\n}\n\nexport function formatDateTime(date: Date): string {\n // yyyy-MM-dd HH:mm:ss 형식\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n \n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\nexport function parseTemplate(template: string, variables: Record<string, string>): string {\n let result = template;\n \n // #{변수명} 형태의 변수 치환\n for (const [key, value] of Object.entries(variables)) {\n const regex = new RegExp(`#{${key}}`, 'g');\n result = result.replace(regex, value);\n }\n \n // {{변수명}} 형태의 변수도 지원\n for (const [key, value] of Object.entries(variables)) {\n const regex = new RegExp(`{{${key}}}`, 'g');\n result = result.replace(regex, value);\n }\n \n return result;\n}\n\nexport function extractVariables(template: string): string[] {\n const variables = new Set<string>();\n \n // #{변수명} 형태 추출\n const hashMatches = template.match(/#\\{([^}]+)\\}/g);\n if (hashMatches) {\n hashMatches.forEach(match => {\n const variable = match.slice(2, -1); // #{ 와 } 제거\n variables.add(variable);\n });\n }\n \n // {{변수명}} 형태 추출\n const braceMatches = template.match(/\\{\\{([^}]+)\\}\\}/g);\n if (braceMatches) {\n braceMatches.forEach(match => {\n const variable = match.slice(2, -2); // {{ 와 }} 제거\n variables.add(variable);\n });\n }\n \n return Array.from(variables);\n}\n\nexport function delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries: number;\n delay: number;\n backoff?: 'linear' | 'exponential';\n }\n): Promise<T> {\n return new Promise(async (resolve, reject) => {\n let lastError: Error;\n \n for (let attempt = 0; attempt <= options.maxRetries; attempt++) {\n try {\n if (attempt > 0) {\n const delayMs = options.backoff === 'exponential' \n ? options.delay * Math.pow(2, attempt - 1)\n : options.delay * attempt;\n await delay(delayMs);\n }\n \n const result = await fn();\n resolve(result);\n return;\n } catch (error) {\n lastError = error as Error;\n \n if (attempt === options.maxRetries) {\n reject(lastError);\n return;\n }\n }\n }\n });\n}","import { \n AlimTalkProvider, \n ProviderCapabilities,\n TemplateContract,\n ChannelContract,\n MessagingContract,\n AnalyticsContract,\n AccountContract,\n ProviderConfiguration,\n ConfigurationField\n} from '../contracts/provider.contract';\n\nexport abstract class BaseAlimTalkProvider implements AlimTalkProvider {\n public abstract readonly id: string;\n public abstract readonly name: string;\n public abstract readonly capabilities: ProviderCapabilities;\n \n protected config: Record<string, unknown> = {};\n protected isConfigured: boolean = false;\n\n // Abstract contracts - must be implemented by concrete providers\n public abstract templates: TemplateContract;\n public abstract channels: ChannelContract;\n public abstract messaging: MessagingContract;\n public abstract analytics: AnalyticsContract;\n public abstract account: AccountContract;\n\n constructor(config?: Record<string, unknown>) {\n if (config) {\n this.configure(config);\n }\n }\n\n /**\n * Configure the provider with necessary credentials and settings\n */\n public configure(config: Record<string, unknown>): void {\n this.validateConfiguration(config);\n this.config = { ...config };\n this.isConfigured = true;\n this.onConfigured();\n }\n\n /**\n * Get the configuration schema for this provider\n */\n public abstract getConfigurationSchema(): ProviderConfiguration;\n\n /**\n * Validate the provided configuration\n */\n protected validateConfiguration(config: Record<string, unknown>): void {\n const schema = this.getConfigurationSchema();\n \n // Check required fields\n for (const field of schema.required) {\n if (!(field.key in config)) {\n throw new Error(`Required configuration field '${field.key}' is missing`);\n }\n \n this.validateFieldValue(field, config[field.key]);\n }\n\n // Check optional fields if provided\n for (const field of schema.optional) {\n if (field.key in config) {\n this.validateFieldValue(field, config[field.key]);\n }\n }\n }\n\n private validateFieldValue(field: ConfigurationField, value: unknown): void {\n // Type validation\n switch (field.type) {\n case 'string':\n if (typeof value !== 'string') {\n throw new Error(`Field '${field.key}' must be a string`);\n }\n break;\n case 'number':\n if (typeof value !== 'number') {\n throw new Error(`Field '${field.key}' must be a number`);\n }\n break;\n case 'boolean':\n if (typeof value !== 'boolean') {\n throw new Error(`Field '${field.key}' must be a boolean`);\n }\n break;\n case 'url':\n try {\n new URL(String(value));\n } catch {\n throw new Error(`Field '${field.key}' must be a valid URL`);\n }\n break;\n }\n\n // Additional validation\n if (field.validation) {\n if (field.validation.pattern) {\n const regex = new RegExp(field.validation.pattern);\n if (!regex.test(String(value))) {\n throw new Error(`Field '${field.key}' does not match required pattern`);\n }\n }\n \n if (field.validation.min !== undefined && Number(value) < field.validation.min) {\n throw new Error(`Field '${field.key}' must be at least ${field.validation.min}`);\n }\n \n if (field.validation.max !== undefined && Number(value) > field.validation.max) {\n throw new Error(`Field '${field.key}' must be at most ${field.validation.max}`);\n }\n }\n }\n\n /**\n * Called after configuration is set\n */\n protected onConfigured(): void {\n // Override in concrete implementations if needed\n }\n\n /**\n * Check if the provider is properly configured\n */\n public isReady(): boolean {\n return this.isConfigured;\n }\n\n /**\n * Get configuration value\n */\n protected getConfig<T = unknown>(key: string): T {\n if (!this.isConfigured) {\n throw new Error('Provider is not configured');\n }\n return this.config[key] as T;\n }\n\n /**\n * Check if a configuration key exists\n */\n protected hasConfig(key: string): boolean {\n return key in this.config;\n }\n\n /**\n * Perform health check on the provider\n */\n public async healthCheck(): Promise<{\n healthy: boolean;\n issues: string[];\n latency?: number;\n }> {\n const issues: string[] = [];\n const startTime = Date.now();\n\n try {\n if (!this.isReady()) {\n issues.push('Provider is not configured');\n return { healthy: false, issues };\n }\n\n // Test basic connectivity\n await this.testConnectivity();\n \n // Test authentication\n await this.testAuthentication();\n\n const latency = Date.now() - startTime;\n \n return {\n healthy: issues.length === 0,\n issues,\n latency\n };\n\n } catch (error) {\n issues.push(`Health check failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n return { healthy: false, issues };\n }\n }\n\n /**\n * Test basic connectivity to the provider\n */\n protected abstract testConnectivity(): Promise<void>;\n\n /**\n * Test authentication with the provider\n */\n protected abstract testAuthentication(): Promise<void>;\n\n /**\n * Get provider information\n */\n public getInfo(): {\n id: string;\n name: string;\n version: string;\n capabilities: ProviderCapabilities;\n configured: boolean;\n } {\n return {\n id: this.id,\n name: this.name,\n version: this.getVersion(),\n capabilities: this.capabilities,\n configured: this.isConfigured\n };\n }\n\n /**\n * Get provider version\n */\n protected abstract getVersion(): string;\n\n /**\n * Cleanup resources when provider is destroyed\n */\n public destroy(): void {\n this.config = {};\n this.isConfigured = false;\n this.onDestroy();\n }\n\n /**\n * Called when provider is being destroyed\n */\n protected onDestroy(): void {\n // Override in concrete implementations if needed\n }\n\n /**\n * Create standardized error\n */\n protected createError(code: string, message: string, details?: Record<string, unknown>): Error {\n const error = new Error(message) as Error & { code?: string; provider?: string; details?: Record<string, unknown> };\n error.code = code;\n error.provider = this.id;\n error.details = details;\n return error;\n }\n\n /**\n * Log provider activity\n */\n protected log(level: 'info' | 'warn' | 'error', message: string, data?: unknown): void {\n const logData: Record<string, unknown> = {\n provider: this.id,\n level,\n message,\n timestamp: new Date().toISOString()\n };\n\n if (data) {\n logData.data = data;\n }\n\n // In a real implementation, this would use a proper logging system\n console.log(JSON.stringify(logData));\n }\n\n /**\n * Handle rate limiting\n */\n protected async handleRateLimit(operation: string): Promise<void> {\n // In a real implementation, this would check rate limits and implement backoff\n const rateLimit = this.capabilities.messaging.maxRequestsPerSecond;\n \n // Simple implementation - can be enhanced with proper rate limiting\n if (rateLimit > 0) {\n const delay = 1000 / rateLimit;\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n /**\n * Retry mechanism for failed operations\n */\n protected async withRetry<T>(\n operation: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n backoffFactor?: number;\n } = {}\n ): Promise<T> {\n const {\n maxRetries = 3,\n initialDelay = 1000,\n maxDelay = 10000,\n backoffFactor = 2\n } = options;\n\n let lastError: Error;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error as Error;\n \n if (attempt === maxRetries) {\n break; // No more retries\n }\n\n this.log('warn', `Operation failed, retrying in ${delay}ms`, {\n attempt: attempt + 1,\n maxRetries,\n error: lastError.message\n });\n\n await new Promise(resolve => setTimeout(resolve, delay));\n delay = Math.min(delay * backoffFactor, maxDelay);\n }\n }\n\n throw lastError!;\n }\n}","import { ProviderMessageRequest, TemplateCreateRequest } from '../contracts/provider.contract';\n\n/**\n * Base request adapter for transforming platform requests to provider-specific format\n */\nexport abstract class BaseRequestAdapter {\n /**\n * Transform a generic message request to provider-specific format\n */\n abstract transformMessageRequest(request: ProviderMessageRequest): unknown;\n\n /**\n * Transform a generic template request to provider-specific format\n */\n abstract transformTemplateRequest(request: TemplateCreateRequest): unknown;\n\n /**\n * Common transformation utilities\n */\n protected formatPhoneNumber(phoneNumber: string, countryCode: string = 'KR'): string {\n // Remove any non-digit characters\n const digits = phoneNumber.replace(/\\D/g, '');\n \n if (countryCode === 'KR') {\n // Korean phone number formatting\n if (digits.startsWith('82')) {\n // International format, remove country code\n return digits.substring(2);\n }\n \n if (digits.startsWith('0')) {\n // Domestic format with leading 0\n return digits;\n }\n \n // Add leading 0 if missing\n return '0' + digits;\n }\n \n return phoneNumber;\n }\n\n protected formatVariables(variables: Record<string, unknown>): Record<string, string> {\n const formatted: Record<string, string> = {};\n \n for (const [key, value] of Object.entries(variables)) {\n if (value instanceof Date) {\n formatted[key] = value.toISOString();\n } else if (typeof value === 'object') {\n formatted[key] = JSON.stringify(value);\n } else {\n formatted[key] = String(value);\n }\n }\n \n return formatted;\n }\n\n protected validateRequiredFields(data: unknown, requiredFields: string[]): void {\n const obj = data as Record<string, unknown>;\n for (const field of requiredFields) {\n if (!(field in obj) || obj[field] === undefined || obj[field] === null) {\n throw new Error(`Required field '${field}' is missing`);\n }\n }\n }\n}\n\n/**\n * Request adapter for IWINV provider\n */\nexport class IWINVRequestAdapter extends BaseRequestAdapter {\n transformMessageRequest(request: ProviderMessageRequest): unknown {\n this.validateRequiredFields(request, ['templateCode', 'phoneNumber']);\n\n return {\n profile_key: this.getProfileKey(),\n template_code: request.templateCode,\n phone_number: this.formatPhoneNumber(request.phoneNumber),\n message_variables: this.formatVariables(request.variables),\n sender_number: request.senderNumber,\n reserve_time: request.options?.scheduledAt ? \n Math.floor(new Date(request.options.scheduledAt).getTime() / 1000) : undefined\n };\n }\n\n transformTemplateRequest(request: TemplateCreateRequest): unknown {\n this.validateRequiredFields(request, ['name', 'content']);\n\n return {\n profile_key: this.getProfileKey(),\n template_name: request.name,\n template_content: request.content,\n template_category: this.mapCategory(request.category),\n template_variables: request.variables?.map(v => ({\n name: v.name,\n type: v.type,\n required: v.required ? 'Y' : 'N',\n max_length: v.maxLength\n })),\n template_buttons: request.buttons?.map(b => ({\n type: b.type,\n name: b.name,\n url_mobile: b.linkMobile,\n url_pc: b.linkPc,\n scheme_ios: b.schemeIos,\n scheme_android: b.schemeAndroid\n }))\n };\n }\n\n private getProfileKey(): string {\n // This should come from configuration\n return process.env.IWINV_PROFILE_KEY || '';\n }\n\n private mapCategory(category: string): string {\n const categoryMap: Record<string, string> = {\n 'AUTHENTICATION': 'A',\n 'NOTIFICATION': 'N',\n 'PROMOTION': 'P',\n 'INFORMATION': 'I'\n };\n \n return categoryMap[category] || 'I';\n }\n}\n\n/**\n * Request adapter for Aligo provider\n */\nexport class AligoRequestAdapter extends BaseRequestAdapter {\n transformMessageRequest(request: ProviderMessageRequest): unknown {\n this.validateRequiredFields(request, ['templateCode', 'phoneNumber']);\n\n return {\n apikey: this.getApiKey(),\n userid: this.getUserId(),\n senderkey: this.getSenderKey(),\n template_code: request.templateCode,\n receiver: this.formatPhoneNumber(request.phoneNumber),\n subject: 'AlimTalk',\n message: this.buildMessage(request),\n button: request.variables.buttons ? JSON.stringify(request.variables.buttons) : undefined,\n reservation: request.options?.scheduledAt ? \n this.formatDateTime(new Date(request.options.scheduledAt)) : undefined\n };\n }\n\n transformTemplateRequest(request: TemplateCreateRequest): unknown {\n this.validateRequiredFields(request, ['name', 'content']);\n\n return {\n apikey: this.getApiKey(),\n userid: this.getUserId(),\n senderkey: this.getSenderKey(),\n template_name: request.name,\n template_content: request.content,\n template_emphasis: this.extractEmphasis(request.content),\n template_extra: this.buildTemplateExtra(request),\n template_ad: this.isPromotional(request.category) ? 'Y' : 'N'\n };\n }\n\n private getApiKey(): string {\n return process.env.ALIGO_API_KEY || '';\n }\n\n private getUserId(): string {\n return process.env.ALIGO_USER_ID || '';\n }\n\n private getSenderKey(): string {\n return process.env.ALIGO_SENDER_KEY || '';\n }\n\n private buildMessage(request: ProviderMessageRequest): string {\n // This would typically involve replacing template variables\n // For now, return the template code as placeholder\n return request.templateCode;\n }\n\n private formatDateTime(date: Date): string {\n return date.toISOString().replace(/[-:]/g, '').replace('T', '').substring(0, 12);\n }\n\n private extractEmphasis(content: string): string {\n // Extract emphasized parts (bold, etc.) from content\n const emphasisMatch = content.match(/\\*\\*(.*?)\\*\\*/);\n return emphasisMatch ? emphasisMatch[1] : '';\n }\n\n private buildTemplateExtra(request: TemplateCreateRequest): string {\n const extra: Record<string, unknown> = {};\n \n if (request.buttons) {\n extra.buttons = request.buttons;\n }\n \n if (request.variables) {\n extra.variables = request.variables;\n }\n \n return JSON.stringify(extra);\n }\n\n private isPromotional(category: string): boolean {\n return category === 'PROMOTION';\n }\n}\n\n/**\n * Request adapter for Kakao provider (direct API)\n */\nexport class KakaoRequestAdapter extends BaseRequestAdapter {\n transformMessageRequest(request: ProviderMessageRequest): unknown {\n this.validateRequiredFields(request, ['templateCode', 'phoneNumber']);\n\n return {\n template_object: {\n object_type: 'text',\n text: this.buildTemplateText(request),\n link: this.buildTemplateLink(request),\n button_title: request.variables.buttonTitle || ''\n },\n user_ids: [this.formatPhoneNumber(request.phoneNumber)]\n };\n }\n\n transformTemplateRequest(request: TemplateCreateRequest): unknown {\n this.validateRequiredFields(request, ['name', 'content']);\n\n return {\n template: {\n name: request.name,\n content: request.content,\n category_code: this.mapCategoryCode(request.category),\n template_message_type: 'BA', // Basic AlimTalk\n template_emphasis_type: this.extractEmphasisType(request.content),\n template_title: request.name,\n template_subtitle: '',\n template_imageurl: '',\n template_header: '',\n template_item_highlight: {\n title: '',\n description: ''\n },\n template_item: {\n list: []\n },\n template_button: this.buildTemplateButtons(request.buttons || [])\n }\n };\n }\n\n private buildTemplateText(request: ProviderMessageRequest): string {\n // Build the actual message text by replacing variables\n let text = request.templateCode; // This should be the actual template content\n \n for (const [key, value] of Object.entries(request.variables)) {\n text = text.replace(new RegExp(`#{${key}}`, 'g'), String(value));\n }\n \n return text;\n }\n\n private buildTemplateLink(request: ProviderMessageRequest): unknown {\n if (request.variables.linkUrl) {\n return {\n web_url: request.variables.linkUrl,\n mobile_web_url: request.variables.linkUrl\n };\n }\n return {};\n }\n\n private mapCategoryCode(category: string): string {\n const categoryMap: Record<string, string> = {\n 'AUTHENTICATION': '999999',\n 'NOTIFICATION': '999998',\n 'PROMOTION': '999997',\n 'INFORMATION': '999996'\n };\n \n return categoryMap[category] || '999999';\n }\n\n private extractEmphasisType(content: string): string {\n if (content.includes('**')) return 'BOLD';\n if (content.includes('__')) return 'UNDERLINE';\n return 'NONE';\n }\n\n private buildTemplateButtons(buttons: unknown[]): unknown[] {\n return buttons.map(button => {\n const btn = button as Record<string, unknown>;\n return {\n name: btn.name,\n type: btn.type,\n url_mobile: btn.linkMobile,\n url_pc: btn.linkPc,\n scheme_ios: btn.schemeIos,\n scheme_android: btn.schemeAndroid\n };\n });\n }\n}\n\n/**\n * Factory for creating request adapters\n */\ntype RequestAdapterConstructor = new () => BaseRequestAdapter;\n\nexport class RequestAdapterFactory {\n private static adapters: Map<string, RequestAdapterConstructor> = new Map();\n\n static {\n RequestAdapterFactory.adapters.set('iwinv', IWINVRequestAdapter);\n RequestAdapterFactory.adapters.set('aligo', AligoRequestAdapter);\n RequestAdapterFactory.adapters.set('kakao', KakaoRequestAdapter);\n }\n\n static create(providerId: string): BaseRequestAdapter {\n const AdapterClass = this.adapters.get(providerId.toLowerCase());\n \n if (!AdapterClass) {\n throw new Error(`No request adapter found for provider: ${providerId}`);\n }\n \n return new AdapterClass();\n }\n\n static register(providerId: string, adapterClass: new () => BaseRequestAdapter): void {\n this.adapters.set(providerId.toLowerCase(), adapterClass);\n }\n}","import { \n ProviderMessageResult, \n MessageStatus, \n ProviderError,\n TemplateCreateResult,\n TemplateStatus,\n ProviderResponse \n} from '../contracts/provider.contract';\n\n/**\n * Base response adapter for transforming provider responses to platform format\n */\nexport abstract class BaseResponseAdapter {\n /**\n * Transform provider message response to standard format\n */\n abstract transformMessageResponse(providerResponse: unknown): ProviderMessageResult;\n\n /**\n * Transform provider template response to standard format\n */\n abstract transformTemplateResponse(providerResponse: unknown): TemplateCreateResult;\n\n /**\n * Common error transformation\n */\n protected transformError(providerError: unknown): ProviderError {\n return {\n code: this.extractErrorCode(providerError),\n message: this.extractErrorMessage(providerError),\n details: this.extractErrorDetails(providerError)\n };\n }\n\n protected abstract extractErrorCode(providerError: unknown): string;\n protected abstract extractErrorMessage(providerError: unknown): string;\n protected abstract extractErrorDetails(providerError: unknown): Record<string, unknown>;\n\n /**\n * Common status mapping utilities\n */\n protected mapMessageStatus(providerStatus: string): MessageStatus {\n // Default implementation - override in specific adapters\n const statusMap: Record<string, MessageStatus> = {\n 'queued': MessageStatus.QUEUED,\n 'sending': MessageStatus.SENDING,\n 'sent': MessageStatus.SENT,\n 'delivered': MessageStatus.DELIVERED,\n 'failed': MessageStatus.FAILED,\n 'cancelled': MessageStatus.CANCELLED\n };\n\n return statusMap[providerStatus.toLowerCase()] || MessageStatus.FAILED;\n }\n\n protected mapTemplateStatus(providerStatus: string): TemplateStatus {\n // Default implementation - override in specific adapters\n const statusMap: Record<string, TemplateStatus> = {\n 'draft': TemplateStatus.DRAFT,\n 'pending': TemplateStatus.PENDING,\n 'approved': TemplateStatus.APPROVED,\n 'rejected': TemplateStatus.REJECTED,\n 'disabled': TemplateStatus.DISABLED\n };\n\n return statusMap[providerStatus.toLowerCase()] || TemplateStatus.DRAFT;\n }\n\n protected parseDate(dateString: string): Date | undefined {\n if (!dateString) return undefined;\n \n try {\n return new Date(dateString);\n } catch {\n return undefined;\n }\n }\n}\n\n/**\n * Response adapter for IWINV provider\n */\nexport class IWINVResponseAdapter extends BaseResponseAdapter {\n transformMessageResponse(providerResponse: unknown): ProviderMessageResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n messageId: (response.msg_id || response.msgid) as string,\n status: this.mapIWINVMessageStatus(response.result_code as string),\n sentAt: this.parseDate(response.send_time as string),\n error: response.result_code !== '1' ? this.transformError(providerResponse) : undefined\n };\n }\n\n transformTemplateResponse(providerResponse: unknown): TemplateCreateResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n templateId: response.template_id as string,\n providerTemplateCode: response.template_code as string,\n status: this.mapIWINVTemplateStatus(response.status as string),\n message: (response.message || response.comment) as string\n };\n }\n\n private mapIWINVMessageStatus(resultCode: string): MessageStatus {\n const statusMap: Record<string, MessageStatus> = {\n '1': MessageStatus.SENT,\n '0': MessageStatus.FAILED,\n '-1': MessageStatus.FAILED,\n '-2': MessageStatus.FAILED,\n '-3': MessageStatus.FAILED,\n '-4': MessageStatus.FAILED\n };\n\n return statusMap[resultCode] || MessageStatus.FAILED;\n }\n\n private mapIWINVTemplateStatus(status: string): TemplateStatus {\n const statusMap: Record<string, TemplateStatus> = {\n 'R': TemplateStatus.PENDING, // Request\n 'A': TemplateStatus.APPROVED, // Approved\n 'C': TemplateStatus.REJECTED, // Cancelled/Rejected\n 'S': TemplateStatus.PENDING // Standby\n };\n\n return statusMap[status] || TemplateStatus.DRAFT;\n }\n\n protected extractErrorCode(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.result_code || error.error_code || 'UNKNOWN_ERROR') as string;\n }\n\n protected extractErrorMessage(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.message || error.error_message || 'Unknown error occurred') as string;\n }\n\n protected extractErrorDetails(providerError: unknown): Record<string, unknown> {\n const error = providerError as Record<string, unknown>;\n return {\n resultCode: error.result_code,\n originalResponse: providerError\n };\n }\n}\n\n/**\n * Response adapter for Aligo provider\n */\nexport class AligoResponseAdapter extends BaseResponseAdapter {\n transformMessageResponse(providerResponse: unknown): ProviderMessageResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n messageId: (response.msg_id || response.mid) as string,\n status: this.mapAligoMessageStatus(response.result_code as string),\n sentAt: this.parseDate(response.send_time as string),\n error: response.result_code !== '1' ? this.transformError(providerResponse) : undefined\n };\n }\n\n transformTemplateResponse(providerResponse: unknown): TemplateCreateResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n templateId: response.template_code as string,\n providerTemplateCode: response.template_code as string,\n status: this.mapAligoTemplateStatus(response.inspect_status as string),\n message: response.comment as string\n };\n }\n\n private mapAligoMessageStatus(resultCode: string): MessageStatus {\n const statusMap: Record<string, MessageStatus> = {\n '1': MessageStatus.SENT,\n '0': MessageStatus.FAILED,\n '-1': MessageStatus.FAILED,\n '-101': MessageStatus.FAILED,\n '-102': MessageStatus.FAILED\n };\n\n return statusMap[resultCode] || MessageStatus.FAILED;\n }\n\n private mapAligoTemplateStatus(inspectStatus: string): TemplateStatus {\n const statusMap: Record<string, TemplateStatus> = {\n 'REG': TemplateStatus.PENDING, // Registered\n 'REQ': TemplateStatus.PENDING, // Request\n 'APR': TemplateStatus.APPROVED, // Approved\n 'REJ': TemplateStatus.REJECTED, // Rejected\n 'STOP': TemplateStatus.DISABLED // Stopped\n };\n\n return statusMap[inspectStatus] || TemplateStatus.DRAFT;\n }\n\n protected extractErrorCode(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.result_code || error.code || 'UNKNOWN_ERROR') as string;\n }\n\n protected extractErrorMessage(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.message || error.error || 'Unknown error occurred') as string;\n }\n\n protected extractErrorDetails(providerError: unknown): Record<string, unknown> {\n const error = providerError as Record<string, unknown>;\n return {\n resultCode: error.result_code,\n inspectStatus: error.inspect_status,\n originalResponse: providerError\n };\n }\n}\n\n/**\n * Response adapter for Kakao provider (direct API)\n */\nexport class KakaoResponseAdapter extends BaseResponseAdapter {\n transformMessageResponse(providerResponse: unknown): ProviderMessageResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n messageId: response.message_id as string,\n status: this.mapKakaoMessageStatus(response.result_code as number),\n sentAt: this.parseDate(response.sent_time as string),\n error: response.result_code !== 0 ? this.transformError(providerResponse) : undefined\n };\n }\n\n transformTemplateResponse(providerResponse: unknown): TemplateCreateResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n templateId: response.template_id as string,\n providerTemplateCode: response.template_code as string,\n status: this.mapKakaoTemplateStatus(response.status as string),\n message: response.comments as string\n };\n }\n\n private mapKakaoMessageStatus(resultCode: number): MessageStatus {\n const statusMap: Record<number, MessageStatus> = {\n 0: MessageStatus.SENT,\n [-1]: MessageStatus.FAILED,\n [-2]: MessageStatus.FAILED,\n [-3]: MessageStatus.FAILED,\n [-999]: MessageStatus.FAILED\n };\n\n return statusMap[resultCode] || MessageStatus.FAILED;\n }\n\n private mapKakaoTemplateStatus(status: string): TemplateStatus {\n const statusMap: Record<string, TemplateStatus> = {\n 'TSC01': TemplateStatus.PENDING, // Under review\n 'TSC02': TemplateStatus.APPROVED, // Approved\n 'TSC03': TemplateStatus.REJECTED, // Rejected\n 'TSC04': TemplateStatus.DISABLED // Disabled\n };\n\n return statusMap[status] || TemplateStatus.DRAFT;\n }\n\n protected extractErrorCode(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return String(error.result_code || error.error_code || 'UNKNOWN_ERROR');\n }\n\n protected extractErrorMessage(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.message || error.error_message || 'Unknown error occurred') as string;\n }\n\n protected extractErrorDetails(providerError: unknown): Record<string, unknown> {\n const error = providerError as Record<string, unknown>;\n return {\n resultCode: error.result_code,\n originalResponse: providerError\n };\n }\n}\n\n/**\n * Response adapter for NHN provider\n */\nexport class NHNResponseAdapter extends BaseResponseAdapter {\n transformMessageResponse(providerResponse: unknown): ProviderMessageResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n messageId: response.requestId as string,\n status: this.mapNHNMessageStatus(response.statusCode as string),\n sentAt: this.parseDate(response.statusDateTime as string),\n error: response.statusCode !== 'SSS' ? this.transformError(providerResponse) : undefined\n };\n }\n\n transformTemplateResponse(providerResponse: unknown): TemplateCreateResult {\n const response = providerResponse as Record<string, unknown>;\n return {\n templateId: response.templateId as string,\n providerTemplateCode: response.templateId as string,\n status: this.mapNHNTemplateStatus(response.templateStatus as string),\n message: response.templateStatusName as string\n };\n }\n\n private mapNHNMessageStatus(statusCode: string): MessageStatus {\n const statusMap: Record<string, MessageStatus> = {\n 'SSS': MessageStatus.SENT, // Success\n 'RDY': MessageStatus.QUEUED, // Ready\n 'PRG': MessageStatus.SENDING, // Progress\n 'CPL': MessageStatus.DELIVERED, // Complete\n 'FAL': MessageStatus.FAILED, // Failed\n 'CAL': MessageStatus.CANCELLED // Cancelled\n };\n\n return statusMap[statusCode] || MessageStatus.FAILED;\n }\n\n private mapNHNTemplateStatus(templateStatus: string): TemplateStatus {\n const statusMap: Record<string, TemplateStatus> = {\n 'WAITING': TemplateStatus.PENDING,\n 'APPROVED': TemplateStatus.APPROVED,\n 'REJECTED': TemplateStatus.REJECTED,\n 'DISABLED': TemplateStatus.DISABLED\n };\n\n return statusMap[templateStatus] || TemplateStatus.DRAFT;\n }\n\n protected extractErrorCode(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.statusCode || error.errorCode || 'UNKNOWN_ERROR') as string;\n }\n\n protected extractErrorMessage(providerError: unknown): string {\n const error = providerError as Record<string, unknown>;\n return (error.statusMessage || error.errorMessage || 'Unknown error occurred') as string;\n }\n\n protected extractErrorDetails(providerError: unknown): Record<string, unknown> {\n const error = providerError as Record<string, unknown>;\n return {\n statusCode: error.statusCode,\n statusMessage: error.statusMessage,\n originalResponse: providerError\n };\n }\n}\n\n/**\n * Factory for creating response adapters\n */\nexport class ResponseAdapterFactory {\n private static adapters: Map<string, new () => BaseResponseAdapter> = new Map<string, new () => BaseResponseAdapter>([\n ['iwinv', IWINVResponseAdapter],\n ['aligo', AligoResponseAdapter],\n ['kakao', KakaoResponseAdapter],\n ['nhn', NHNResponseAdapter]\n ]);\n\n static create(providerId: string): BaseResponseAdapter {\n const AdapterClass = this.adapters.get(providerId.toLowerCase());\n \n if (!AdapterClass) {\n throw new Error(`No response adapter found for provider: ${providerId}`);\n }\n \n return new AdapterClass();\n }\n\n static register(providerId: string, adapterClass: new () => BaseResponseAdapter): void {\n this.adapters.set(providerId.toLowerCase(), adapterClass);\n }\n}","import type { BaseProvider } from '@k-msg/core';\n\nexport class ProviderManager {\n private providers: Map<string, BaseProvider> = new Map();\n private defaultProvider?: string;\n\n registerProvider(provider: BaseProvider): void {\n this.providers.set(provider.id, provider);\n\n // 첫 번째 프로바이더를 기본으로 설정\n if (!this.defaultProvider) {\n this.defaultProvider = provider.id;\n }\n }\n\n unregisterProvider(providerId: string): void {\n this.providers.delete(providerId);\n\n if (this.defaultProvider === providerId) {\n const remaining = Array.from(this.providers.keys());\n this.defaultProvider = remaining.length > 0 ? remaining[0] : undefined;\n }\n }\n\n getProvider(providerId?: string): BaseProvider | null {\n const id = providerId || this.defaultProvider;\n return id ? this.providers.get(id) || null : null;\n }\n\n listProviders(): BaseProvider[] {\n return Array.from(this.providers.values());\n }\n\n setDefaultProvider(providerId: string): void {\n if (!this.providers.has(providerId)) {\n throw new Error(`Provider ${providerId} not found`);\n }\n this.defaultProvider = providerId;\n }\n\n async healthCheckAll(): Promise<Record<string, boolean>> {\n const results: Record<string, boolean> = {};\n\n for (const [id, provider] of this.providers.entries()) {\n try {\n const health = await provider.healthCheck();\n results[id] = health.healthy;\n } catch (error) {\n results[id] = false;\n }\n }\n\n return results;\n }\n\n getProvidersForChannel(channel: string): BaseProvider[] {\n return Array.from(this.providers.values()).filter(provider => {\n const providerWithChannels = provider as BaseProvider & { supportedChannels?: string[] };\n return providerWithChannels.supportedChannels?.includes(channel);\n });\n }\n}","/**\n * IWINV Messaging Contract Implementation\n */\n\nimport {\n MessagingContract,\n ProviderMessageRequest,\n ProviderMessageResult,\n ProviderBulkResult,\n ScheduleResult,\n MessageStatus\n} from '../../contracts/provider.contract';\n\nimport { IWINVConfig } from '../types/iwinv';\n\nexport class IWINVMessagingContract implements MessagingContract {\n constructor(private config: IWINVConfig) {}\n\n async send(message: ProviderMessageRequest): Promise<ProviderMessageResult> {\n try {\n const response = await fetch(`${this.config.baseUrl}/send`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n templateCode: message.templateCode,\n phone: message.phoneNumber,\n variables: message.variables,\n senderNumber: message.senderNumber,\n ...message.options\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n return {\n messageId: `failed_${Date.now()}`,\n status: MessageStatus.FAILED,\n error: {\n code: ((result.code as string) as string) || 'SEND_FAILED',\n message: ((result.message as string) as string) || 'Failed to send message'\n }\n };\n }\n\n return {\n messageId: ((result.messageId as string) as string) || `msg_${Date.now()}`,\n status: MessageStatus.SENT,\n sentAt: new Date()\n };\n } catch (error) {\n return {\n messageId: `error_${Date.now()}`,\n status: MessageStatus.FAILED,\n error: {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network error occurred'\n }\n };\n }\n }\n\n async sendBulk(messages: ProviderMessageRequest[]): Promise<ProviderBulkResult> {\n const results: ProviderMessageResult[] = [];\n \n // IWINV doesn't have native bulk API, so send individually\n for (const message of messages) {\n const result = await this.send(message);\n results.push(result);\n }\n\n const sent = results.filter(r => r.status === MessageStatus.SENT).length;\n const failed = results.filter(r => r.status === MessageStatus.FAILED).length;\n\n return {\n requestId: `bulk_${Date.now()}`,\n results,\n summary: {\n total: messages.length,\n sent,\n failed\n }\n };\n }\n\n async schedule(message: ProviderMessageRequest, scheduledAt: Date): Promise<ScheduleResult> {\n // Implementation for scheduled sending\n // For now, return a mock implementation\n return {\n scheduleId: `schedule_${Date.now()}`,\n messageId: `msg_${Date.now()}`,\n scheduledAt,\n status: 'scheduled'\n };\n }\n\n async cancel(messageId: string): Promise<void> {\n const response = await fetch(`${this.config.baseUrl}/cancel`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({ messageId })\n });\n\n if (!response.ok) {\n const result = await response.json() as Record<string, unknown>;\n throw new Error(`Failed to cancel message: ${(result.message as string)}`);\n }\n }\n\n async getStatus(messageId: string): Promise<MessageStatus> {\n try {\n const response = await fetch(`${this.config.baseUrl}/status`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({ messageId })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n return MessageStatus.FAILED;\n }\n\n // Map IWINV status to our MessageStatus\n switch ((result.statusCode as string)) {\n case 'OK':\n return MessageStatus.DELIVERED;\n case 'PENDING':\n return MessageStatus.SENDING;\n case 'FAILED':\n return MessageStatus.FAILED;\n default:\n return MessageStatus.SENT;\n }\n } catch (error) {\n return MessageStatus.FAILED;\n }\n }\n}","/**\n * IWINV Template Contract Implementation \n */\n\nimport {\n TemplateContract,\n TemplateCreateRequest,\n TemplateUpdateRequest,\n TemplateCreateResult,\n TemplateUpdateResult,\n ProviderTemplate,\n TemplateFilters,\n SyncResult,\n TemplateStatus\n} from '../../contracts/provider.contract';\n\nimport { IWINVConfig } from '../types/iwinv';\n\nexport class IWINVTemplateContract implements TemplateContract {\n constructor(private config: IWINVConfig) {}\n\n async create(template: TemplateCreateRequest): Promise<TemplateCreateResult> {\n try {\n const response = await fetch(`${this.config.baseUrl}/template/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n templateName: template.name,\n templateContent: template.content,\n templateCategory: template.category,\n templateVariables: template.variables,\n templateButtons: template.buttons\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Template creation failed: ${(result.message as string)}`);\n }\n\n return {\n templateId: (result.templateId as string) || `tpl_${Date.now()}`,\n providerTemplateCode: (result.templateCode as string) || template.name,\n status: TemplateStatus.PENDING,\n message: (result.message as string) || 'Template created successfully'\n };\n } catch (error) {\n throw new Error(`Failed to create template: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n async update(templateId: string, template: TemplateUpdateRequest): Promise<TemplateUpdateResult> {\n try {\n const response = await fetch(`${this.config.baseUrl}/template/modify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n templateCode: templateId,\n templateName: template.name,\n templateContent: template.content,\n templateButtons: template.buttons\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Template update failed: ${(result.message as string)}`);\n }\n\n return {\n templateId,\n status: TemplateStatus.PENDING,\n message: (result.message as string) || 'Template updated successfully'\n };\n } catch (error) {\n throw new Error(`Failed to update template: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n async delete(templateId: string): Promise<void> {\n try {\n const response = await fetch(`${this.config.baseUrl}/template/delete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n templateCode: templateId\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Template deletion failed: ${(result.message as string)}`);\n }\n } catch (error) {\n throw new Error(`Failed to delete template: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n async get(templateId: string): Promise<ProviderTemplate> {\n interface IWINVTemplateFilters extends TemplateFilters {\n templateCode?: string;\n templateName?: string;\n templateStatus?: string;\n }\n const templates = await this.list({ templateCode: templateId } as IWINVTemplateFilters);\n const template = templates.find(t => t.code === templateId);\n \n if (!template) {\n throw new Error(`Template ${templateId} not found`);\n }\n\n return template;\n }\n\n async list(filters?: TemplateFilters): Promise<ProviderTemplate[]> {\n try {\n const response = await fetch(`${this.config.baseUrl}/template/list`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n page: 1,\n size: 100,\n ...filters\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Failed to list templates: ${(result.message as string)}`);\n }\n\n return ((result.list as any[]) || []).map((template: any) => ({\n id: template.templateId || template.templateCode,\n code: template.templateCode,\n name: template.templateName,\n content: template.templateContent,\n status: this.mapIWINVStatus(template.status || template.templateStatus),\n createdAt: template.createDate ? new Date(template.createDate) : new Date(),\n updatedAt: template.updateDate ? new Date(template.updateDate) : new Date(),\n approvedAt: template.approvedAt ? new Date(template.approvedAt) : undefined,\n rejectedAt: template.rejectedAt ? new Date(template.rejectedAt) : undefined,\n rejectionReason: template.rejectionReason\n }));\n } catch (error) {\n throw new Error(`Failed to list templates: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n async sync(): Promise<SyncResult> {\n try {\n const templates = await this.list();\n \n return {\n synced: templates.length,\n created: 0,\n updated: 0,\n deleted: 0,\n errors: []\n };\n } catch (error) {\n return {\n synced: 0,\n created: 0,\n updated: 0,\n deleted: 0,\n errors: [{\n templateId: 'unknown',\n error: error instanceof Error ? error.message : 'Sync failed'\n }]\n };\n }\n }\n\n private mapIWINVStatus(status: string): TemplateStatus {\n switch (status) {\n case 'Y':\n return TemplateStatus.APPROVED;\n case 'I':\n return TemplateStatus.PENDING;\n case 'R':\n return TemplateStatus.REJECTED;\n case 'D':\n return TemplateStatus.DISABLED;\n default:\n return TemplateStatus.DRAFT;\n }\n }\n}","/**\n * IWINV Channel Contract Implementation \n */\n\nimport {\n ChannelContract,\n Channel,\n SenderNumber,\n ChannelRequest\n} from '../../contracts/provider.contract';\n\nimport { IWINVConfig } from '../types/iwinv';\n\nexport class IWINVChannelContract implements ChannelContract {\n constructor(private config: IWINVConfig) {}\n\n async register(channel: ChannelRequest): Promise<Channel> {\n // IWINV doesn't have a dedicated channel registration API\n // This is a mock implementation\n return {\n id: `channel_${Date.now()}`,\n name: channel.name,\n profileKey: channel.profileKey,\n status: 'pending',\n createdAt: new Date(),\n updatedAt: new Date()\n };\n }\n\n async list(): Promise<Channel[]> {\n // IWINV doesn't provide channel listing\n // Return a default channel\n return [\n {\n id: 'iwinv-default',\n name: 'IWINV Default Channel',\n profileKey: 'default',\n status: 'active',\n createdAt: new Date(),\n updatedAt: new Date()\n }\n ];\n }\n\n async addSenderNumber(channelId: string, number: string): Promise<SenderNumber> {\n // IWINV sender number registration would be handled externally\n // This is a mock implementation\n return {\n id: `sender_${Date.now()}`,\n channelId,\n phoneNumber: number,\n isVerified: false,\n createdAt: new Date()\n };\n }\n\n async verifySenderNumber(number: string, verificationCode: string): Promise<boolean> {\n // IWINV verification would be handled externally\n // This is a mock implementation that always returns true for demo\n return true;\n }\n}","/**\n * IWINV Analytics Contract Implementation\n */\n\nimport {\n AnalyticsContract,\n DateRange,\n UsageStats,\n TemplateStats,\n DeliveryReport\n} from '../../contracts/provider.contract';\n\nimport { IWINVConfig } from '../types/iwinv';\n\nexport class IWINVAnalyticsContract implements AnalyticsContract {\n constructor(private config: IWINVConfig) {}\n\n async getUsage(period: DateRange): Promise<UsageStats> {\n try {\n const response = await fetch(`${this.config.baseUrl}/history/list`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n startDate: period.from.toISOString(),\n endDate: period.to.toISOString(),\n page: 1,\n size: 1000\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Failed to get usage stats: ${(result.message as string)}`);\n }\n\n const messages = (result.list as any[]) || [];\n const totalMessages = messages.length;\n const deliveredMessages = messages.filter((msg: any) => msg.statusCode === 'OK').length;\n const failedMessages = messages.filter((msg: any) => msg.statusCode === 'FAILED').length;\n const sentMessages = totalMessages - failedMessages;\n\n return {\n period,\n totalMessages,\n sentMessages,\n deliveredMessages,\n failedMessages,\n deliveryRate: totalMessages > 0 ? (deliveredMessages / totalMessages) * 100 : 0,\n failureRate: totalMessages > 0 ? (failedMessages / totalMessages) * 100 : 0,\n breakdown: {\n byTemplate: this.groupByTemplate(messages),\n byDay: this.groupByDay(messages, period),\n byHour: this.groupByHour(messages)\n }\n };\n } catch (error) {\n // Return empty stats if API fails\n return {\n period,\n totalMessages: 0,\n sentMessages: 0,\n deliveredMessages: 0,\n failedMessages: 0,\n deliveryRate: 0,\n failureRate: 0,\n breakdown: {\n byTemplate: {},\n byDay: {},\n byHour: {}\n }\n };\n }\n }\n\n async getTemplateStats(templateId: string, period: DateRange): Promise<TemplateStats> {\n try {\n const usage = await this.getUsage(period);\n const templateMessages = usage.breakdown.byTemplate[templateId] || 0;\n\n return {\n templateId,\n period,\n totalSent: templateMessages,\n delivered: Math.round(templateMessages * (usage.deliveryRate / 100)),\n failed: Math.round(templateMessages * (usage.failureRate / 100)),\n deliveryRate: usage.deliveryRate,\n averageDeliveryTime: 30 // Mock average delivery time in seconds\n };\n } catch (error) {\n return {\n templateId,\n period,\n totalSent: 0,\n delivered: 0,\n failed: 0,\n deliveryRate: 0,\n averageDeliveryTime: 0\n };\n }\n }\n\n async getDeliveryReport(messageId: string): Promise<DeliveryReport> {\n try {\n const response = await fetch(`${this.config.baseUrl}/history/detail`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify({\n messageId: parseInt(messageId) || 0\n })\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Failed to get delivery report: ${(result.message as string)}`);\n }\n\n return {\n messageId,\n phoneNumber: (result.phone as string) || 'unknown',\n templateCode: (result.templateCode as string) || 'unknown',\n status: this.mapStatus((result.statusCode as string)),\n sentAt: (result.sendDate as string) ? new Date((result.sendDate as string)) : undefined,\n deliveredAt: (result.receiveDate as string) ? new Date((result.receiveDate as string)) : undefined,\n failedAt: (result.statusCode as string) === 'FAILED' ? new Date((result.sendDate as string)) : undefined,\n clickedAt: (result.clickedAt as string) ? new Date((result.clickedAt as string)) : undefined,\n error: (result.statusCode as string) !== 'OK' ? {\n code: (result.statusCode as string),\n message: (result.statusCodeName as string)\n } : undefined,\n attempts: [\n {\n attemptNumber: 1,\n attemptedAt: new Date((result.requestDate as string)),\n status: this.mapStatus((result.statusCode as string)),\n error: (result.statusCode as string) !== 'OK' ? {\n code: (result.statusCode as string),\n message: (result.statusCodeName as string)\n } : undefined\n }\n ]\n };\n } catch (error) {\n return {\n messageId,\n phoneNumber: 'unknown',\n templateCode: 'unknown', \n status: 'FAILED' as any,\n error: {\n code: 'API_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error'\n },\n attempts: []\n };\n }\n }\n\n private groupByTemplate(messages: any[]): Record<string, number> {\n const groups: Record<string, number> = {};\n messages.forEach(msg => {\n const template = msg.templateCode || 'unknown';\n groups[template] = (groups[template] || 0) + 1;\n });\n return groups;\n }\n\n private groupByDay(messages: any[], period: DateRange): Record<string, number> {\n const groups: Record<string, number> = {};\n const current = new Date(period.from);\n \n while (current <= period.to) {\n const dateKey = current.toISOString().split('T')[0];\n groups[dateKey] = 0;\n current.setDate(current.getDate() + 1);\n }\n\n messages.forEach(msg => {\n if (msg.requestDate) {\n const dateKey = new Date(msg.requestDate).toISOString().split('T')[0];\n if (groups.hasOwnProperty(dateKey)) {\n groups[dateKey]++;\n }\n }\n });\n\n return groups;\n }\n\n private groupByHour(messages: any[]): Record<string, number> {\n const groups: Record<string, number> = {};\n for (let i = 0; i < 24; i++) {\n groups[i.toString()] = 0;\n }\n\n messages.forEach(msg => {\n if (msg.requestDate) {\n const hour = new Date(msg.requestDate).getHours();\n groups[hour.toString()]++;\n }\n });\n\n return groups;\n }\n\n private mapStatus(statusCode: string): any {\n switch (statusCode) {\n case 'OK':\n return 'DELIVERED';\n case 'PENDING':\n return 'SENDING';\n case 'FAILED':\n return 'FAILED';\n default:\n return 'SENT';\n }\n }\n}","/**\n * IWINV Account Contract Implementation\n */\n\nimport {\n AccountContract,\n Balance,\n AccountProfile\n} from '../../contracts/provider.contract';\n\nimport { IWINVConfig } from '../types/iwinv';\n\nexport class IWINVAccountContract implements AccountContract {\n constructor(private config: IWINVConfig) {}\n\n async getBalance(): Promise<Balance> {\n try {\n const response = await fetch(`${this.config.baseUrl}/balance`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`\n }\n });\n\n const result = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new Error(`Failed to get balance: ${(result.message as string)}`);\n }\n\n return {\n current: Number((result.balance as string)) || 0,\n currency: 'KRW',\n lastUpdated: new Date(),\n threshold: Number((result.threshold as string)) || undefined\n };\n } catch (error) {\n // Return default balance if API fails\n return {\n current: 0,\n currency: 'KRW',\n lastUpdated: new Date()\n };\n }\n }\n\n async getProfile(): Promise<AccountProfile> {\n try {\n // IWINV doesn't have a profile endpoint, so we'll create a basic one\n const balance = await this.getBalance();\n \n return {\n accountId: 'iwinv-account',\n name: 'IWINV Account',\n email: 'account@iwinv.kr',\n phone: '1588-1234',\n status: balance.current > 0 ? 'active' : 'suspended',\n tier: 'standard',\n features: ['alimtalk', 'sms', 'lms'],\n limits: {\n dailyMessageLimit: 10000,\n monthlyMessageLimit: 300000,\n rateLimit: 100 // per second\n }\n };\n } catch (error) {\n // Return default profile if API fails\n return {\n accountId: 'iwinv-account',\n name: 'IWINV Account',\n email: 'account@iwinv.kr', \n phone: '1588-1234',\n status: 'active',\n tier: 'basic',\n features: ['alimtalk'],\n limits: {\n dailyMessageLimit: 1000,\n monthlyMessageLimit: 30000,\n rateLimit: 10\n }\n };\n }\n }\n}","/**\n * IWINV AlimTalk Provider - Enhanced Implementation\n * Uses BaseAlimTalkProvider and Contract system for better structure\n */\n\nimport { BaseAlimTalkProvider } from '../abstract/provider.base';\nimport {\n ProviderCapabilities,\n ProviderConfiguration,\n ConfigurationField\n} from '../contracts/provider.contract';\n\nimport { IWINVMessagingContract } from './contracts/messaging.contract';\nimport { IWINVTemplateContract } from './contracts/template.contract';\nimport { IWINVChannelContract } from './contracts/channel.contract';\nimport { IWINVAnalyticsContract } from './contracts/analytics.contract';\nimport { IWINVAccountContract } from './contracts/account.contract';\n\nimport type { IWINVConfig } from './types/iwinv';\n\nexport class IWINVProvider extends BaseAlimTalkProvider {\n public readonly id = 'iwinv';\n public readonly name = 'IWINV AlimTalk Provider';\n \n public readonly capabilities: ProviderCapabilities = {\n templates: {\n maxLength: 1000,\n maxVariables: 20,\n maxButtons: 5,\n supportedButtonTypes: ['WL', 'AL', 'DB', 'BK', 'MD'],\n requiresApproval: true,\n approvalTime: '1-2 days'\n },\n messaging: {\n maxRecipientsPerRequest: 1,\n maxRequestsPerSecond: 100,\n supportsBulk: false, // IWINV doesn't have native bulk API\n supportsScheduling: true,\n maxScheduleDays: 30,\n supportsFallback: true\n },\n channels: {\n requiresBusinessVerification: true,\n maxSenderNumbers: 10,\n supportsMultipleChannels: false\n }\n };\n\n // Contract implementations\n public templates: IWINVTemplateContract;\n public channels: IWINVChannelContract;\n public messaging: IWINVMessagingContract;\n public analytics: IWINVAnalyticsContract;\n public account: IWINVAccountContract;\n\n constructor(config?: IWINVConfig) {\n super(config);\n \n // Initialize contracts with config\n const iwinvConfig = this.getIWINVConfig();\n this.templates = new IWINVTemplateContract(iwinvConfig);\n this.channels = new IWINVChannelContract(iwinvConfig);\n this.messaging = new IWINVMessagingContract(iwinvConfig);\n this.analytics = new IWINVAnalyticsContract(iwinvConfig);\n this.account = new IWINVAccountContract(iwinvConfig);\n }\n\n public getConfigurationSchema(): ProviderConfiguration {\n return {\n required: [\n {\n key: 'apiKey',\n name: 'IWINV API Key',\n type: 'password',\n description: 'Your IWINV API key',\n required: true,\n validation: {\n pattern: '^[a-zA-Z0-9-_]+$',\n min: 10\n }\n }\n ],\n optional: [\n {\n key: 'baseUrl',\n name: 'Base URL',\n type: 'url',\n description: 'IWINV API base URL',\n required: false,\n default: 'https://alimtalk.bizservice.iwinv.kr',\n validation: {\n pattern: '^https?://.+'\n }\n },\n {\n key: 'debug',\n name: 'Debug Mode',\n type: 'boolean',\n description: 'Enable debug logging',\n required: false,\n default: false\n }\n ]\n };\n }\n\n protected async testConnectivity(): Promise<void> {\n const config = this.getIWINVConfig();\n \n try {\n const response = await fetch(`${config.baseUrl}/balance`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`\n }\n });\n\n if (!response.ok) {\n throw new Error(`Connectivity test failed: ${response.status} ${response.statusText}`);\n }\n } catch (error) {\n throw new Error(`Cannot connect to IWINV API: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n protected async testAuthentication(): Promise<void> {\n const config = this.getIWINVConfig();\n \n try {\n const response = await fetch(`${config.baseUrl}/balance`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`\n }\n });\n\n if (response.status === 401 || response.status === 403) {\n throw new Error('Invalid API key or insufficient permissions');\n }\n\n if (!response.ok) {\n const result = await response.json().catch(() => ({})) as Record<string, unknown>;\n throw new Error(`Authentication failed: ${(result.message as string) || response.statusText}`);\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes('Authentication failed')) {\n throw error;\n }\n throw new Error(`Authentication test failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n protected getVersion(): string {\n return '2.0.0';\n }\n\n /**\n * Get IWINV-specific configuration\n */\n private getIWINVConfig(): IWINVConfig {\n return {\n apiKey: this.getConfig<string>('apiKey'),\n baseUrl: this.getConfig<string>('baseUrl') || 'https://alimtalk.bizservice.iwinv.kr',\n debug: this.getConfig<boolean>('debug') || false\n };\n }\n\n /**\n * IWINV-specific methods for backward compatibility\n */\n \n /**\n * Send AlimTalk message (legacy method)\n */\n async sendMessage(options: {\n templateCode: string;\n phoneNumber: string;\n variables: Record<string, any>;\n senderNumber?: string;\n }) {\n return this.messaging.send({\n templateCode: options.templateCode,\n phoneNumber: options.phoneNumber,\n variables: options.variables,\n senderNumber: options.senderNumber\n });\n }\n\n /**\n * Get account balance (legacy method)\n */\n async getBalance() {\n return this.account.getBalance();\n }\n\n /**\n * List templates (legacy method)\n */\n async listTemplates(filters?: any) {\n return this.templates.list(filters);\n }\n}"],"mappings":"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","names":["delay"]}
|