'use strict'; const SMS_TEMPLATE_DEFS = [ { key: 'accountCreated', label: 'ایجاد حساب کاربری', envKey: 'SMS_TEMPLATE_ACCOUNT_CREATED', slots: [ { key: 'username', label: 'نام کاربری', defaultName: 'user' }, { key: 'password', label: 'رمز عبور', defaultName: 'password' }, { key: 'fullName', label: 'نام کاربر', defaultName: 'name' }, { key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' } ] }, { key: 'classRegistered', label: 'ثبت‌نام در کلاس', envKey: 'SMS_TEMPLATE_CLASS_REGISTERED', slots: [ { key: 'className', label: 'نام کلاس', defaultName: 'className' }, { key: 'courseName', label: 'نام دوره', defaultName: 'courseName' }, { key: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' }, { key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' } ] }, { key: 'classReminder', label: 'یادآوری کلاس', envKey: 'SMS_TEMPLATE_CLASS_REMINDER', slots: [ { key: 'className', label: 'نام کلاس', defaultName: 'className' }, { key: 'courseName', label: 'نام دوره', defaultName: 'courseName' }, { key: 'time', label: 'ساعت', defaultName: 'time' }, { key: 'place', label: 'مکان', defaultName: 'place' }, { key: 'fullName', label: 'نام کاربر', defaultName: 'fullName' }, { key: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' } ] }, { key: 'invoiceCreated', label: 'ایجاد صورتحساب', envKey: 'SMS_TEMPLATE_INVOICE_CREATED', slots: [ { key: 'fullName', label: 'نام کارآموز', defaultName: 'FULLNAME' }, { key: 'amount', label: 'مبلغ', defaultName: 'PAYMENT_PRICE' }, { key: 'course', label: 'نام دوره', defaultName: 'COURSE' }, { key: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' } ] } ]; const SMS_TEMPLATE_KEYS = SMS_TEMPLATE_DEFS.map((def) => def.key); const envFallbackFor = (def) => { if (!def?.envKey) return ''; return String(process.env[def.envKey] || '').trim(); }; const sanitizeTemplateId = (value) => { if (value == null) return ''; const digits = String(value).trim(); if (!digits) return ''; if (!/^\d{1,20}$/.test(digits)) return null; return digits; }; const sanitizeVariableName = (value) => { if (value == null) return ''; const name = String(value).trim().replace(/^#+|#+$/g, ''); if (!name) return ''; if (!/^[A-Za-z][A-Za-z0-9_]{0,49}$/.test(name)) return null; return name; }; const defaultVariablesList = (def) => { return (def?.slots || []).map((slot) => ({ slot: slot.key, name: slot.defaultName })); }; const emptyTemplateEntry = (def) => ({ templateId: '', variables: defaultVariablesList(def) }); const normalizeStoredEntry = (raw, def) => { if (raw == null || raw === '') { return { templateId: '', variables: def ? defaultVariablesList(def) : [] }; } if (typeof raw === 'string' || typeof raw === 'number') { return { templateId: String(raw), variables: def ? defaultVariablesList(def) : [] }; } if (typeof raw !== 'object') { return { templateId: '', variables: def ? defaultVariablesList(def) : [] }; } let variables = []; if (Array.isArray(raw.variables)) { variables = raw.variables .filter((item) => item && typeof item === 'object' && item.slot) .map((item) => ({ slot: String(item.slot).trim(), name: String(item.name || '').trim() })); } else if (raw.variables && typeof raw.variables === 'object') { variables = Object.entries(raw.variables).map(([slot, name]) => ({ slot: String(slot).trim(), name: String(name || '').trim() })); } else if (def) { variables = defaultVariablesList(def); } return { templateId: raw.templateId != null ? String(raw.templateId) : '', variables }; }; const resolveVariablesList = (def, storedVariables) => { if (!storedVariables) { return defaultVariablesList(def); } let list = []; if (Array.isArray(storedVariables)) { list = storedVariables; } else if (typeof storedVariables === 'object') { list = Object.entries(storedVariables).map(([slot, name]) => ({ slot, name })); } return list .map((item) => { const slot = String(item.slot || '').trim(); if (!slot) return null; const slotDef = (def?.slots || []).find((s) => s.key === slot); const rawName = item.name !== undefined ? item.name : slotDef?.defaultName || ''; const sanitized = sanitizeVariableName(rawName); return { slot, name: sanitized || slotDef?.defaultName || slot }; }) .filter(Boolean); }; const buildSmsParameters = (variables, valuesBySlot = {}) => { let list = []; if (Array.isArray(variables)) { list = variables; } else if (variables && typeof variables === 'object') { list = Object.entries(variables).map(([slot, name]) => ({ slot, name })); } return list .map((item) => { const name = sanitizeVariableName(item?.name); if (!name) return null; const slot = item?.slot; const value = slot ? valuesBySlot?.[slot] : ''; return { name, value: String(value ?? '') }; }) .filter(Boolean); }; module.exports = { SMS_TEMPLATE_DEFS, SMS_TEMPLATE_KEYS, envFallbackFor, sanitizeTemplateId, sanitizeVariableName, defaultVariablesList, emptyTemplateEntry, normalizeStoredEntry, resolveVariablesList, buildSmsParameters };