UNPKG

@sendgrid/helpers

Version:

Twilio SendGrid NodeJS internal helpers

372 lines (332 loc) 8.39 kB
'use strict'; /** * Dependencies */ const EmailAddress = require('./email-address'); const toCamelCase = require('../helpers/to-camel-case'); const toSnakeCase = require('../helpers/to-snake-case'); const deepClone = require('../helpers/deep-clone'); const deepMerge = require('deepmerge'); const wrapSubstitutions = require('../helpers/wrap-substitutions'); /** * Personalization class */ class Personalization { /** * Constructor */ constructor(data) { //Init array and object placeholders this.to = []; this.cc = []; this.bcc = []; this.headers = {}; this.customArgs = {}; this.substitutions = {}; this.substitutionWrappers = ['{{', '}}']; this.dynamicTemplateData = {}; //Build from data if given if (data) { this.fromData(data); } } /** * From data */ fromData(data) { //Expecting object if (typeof data !== 'object') { throw new Error('Expecting object for Mail data'); } //Convert to camel case to make it workable, making a copy to prevent //changes to the original objects data = deepClone(data); data = toCamelCase(data, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); //Extract properties from data const { to, from, cc, bcc, subject, headers, customArgs, sendAt, substitutions, substitutionWrappers, dynamicTemplateData, } = data; //Set data this.setTo(to); this.setFrom(from); this.setCc(cc); this.setBcc(bcc); this.setSubject(subject); this.setHeaders(headers); this.setSubstitutions(substitutions); this.setSubstitutionWrappers(substitutionWrappers); this.setCustomArgs(customArgs); this.setDynamicTemplateData(dynamicTemplateData); this.setSendAt(sendAt); } /** * Set subject */ setSubject(subject) { if (typeof subject === 'undefined') { return; } if (typeof subject !== 'string') { throw new Error('String expected for `subject`'); } this.subject = subject; } /** * Set send at */ setSendAt(sendAt) { if (typeof sendAt === 'undefined') { return; } if (!Number.isInteger(sendAt)) { throw new Error('Integer expected for `sendAt`'); } this.sendAt = sendAt; } /** * Set to */ setTo(to) { if (typeof to === 'undefined') { return; } if (!Array.isArray(to)) { to = [to]; } this.to = EmailAddress.create(to); } /** * Set from * */ setFrom(from) { if (typeof from === 'undefined') { return; } this.from = EmailAddress.create(from); } /** * Add a single to */ addTo(to) { if (typeof to === 'undefined') { return; } this.to.push(EmailAddress.create(to)); } /** * Set cc */ setCc(cc) { if (typeof cc === 'undefined') { return; } if (!Array.isArray(cc)) { cc = [cc]; } this.cc = EmailAddress.create(cc); } /** * Add a single cc */ addCc(cc) { if (typeof cc === 'undefined') { return; } this.cc.push(EmailAddress.create(cc)); } /** * Set bcc */ setBcc(bcc) { if (typeof bcc === 'undefined') { return; } if (!Array.isArray(bcc)) { bcc = [bcc]; } this.bcc = EmailAddress.create(bcc); } /** * Add a single bcc */ addBcc(bcc) { if (typeof bcc === 'undefined') { return; } this.bcc.push(EmailAddress.create(bcc)); } /** * Set headers */ setHeaders(headers) { if (typeof headers === 'undefined') { return; } if (typeof headers !== 'object' || headers === null) { throw new Error('Object expected for `headers`'); } this.headers = headers; } /** * Add a header */ addHeader(key, value) { if (typeof key !== 'string') { throw new Error('String expected for header key'); } if (typeof value !== 'string') { throw new Error('String expected for header value'); } this.headers[key] = value; } /** * Set custom args */ setCustomArgs(customArgs) { if (typeof customArgs === 'undefined') { return; } if (typeof customArgs !== 'object' || customArgs === null) { throw new Error('Object expected for `customArgs`'); } this.customArgs = customArgs; } /** * Add a custom arg */ addCustomArg(key, value) { if (typeof key !== 'string') { throw new Error('String expected for custom arg key'); } if (typeof value !== 'string') { throw new Error('String expected for custom arg value'); } this.customArgs[key] = value; } /** * Set substitutions */ setSubstitutions(substitutions) { if (typeof substitutions === 'undefined') { return; } if (typeof substitutions !== 'object') { throw new Error('Object expected for `substitutions`'); } this.substitutions = substitutions; } /** * Add a substitution */ addSubstitution(key, value) { if (typeof key !== 'string') { throw new Error('String expected for substitution key'); } if (typeof value !== 'string' && typeof value !== 'number') { throw new Error('String or Number expected for substitution value'); } this.substitutions[key] = value; } /** * Reverse merge substitutions, preserving existing ones */ reverseMergeSubstitutions(substitutions) { if (typeof substitutions === 'undefined' || substitutions === null) { return; } if (typeof substitutions !== 'object') { throw new Error( 'Object expected for `substitutions` in reverseMergeSubstitutions' ); } this.substitutions = Object.assign({}, substitutions, this.substitutions); } /** * Set substitution wrappers */ setSubstitutionWrappers(wrappers) { if (typeof wrappers === 'undefined' || wrappers === null) { return; } if (!Array.isArray(wrappers) || wrappers.length !== 2) { throw new Error( 'Array expected with two elements for `substitutionWrappers`' ); } this.substitutionWrappers = wrappers; } /** * Reverse merge dynamic template data, preserving existing ones */ deepMergeDynamicTemplateData(dynamicTemplateData) { if (typeof dynamicTemplateData === 'undefined' || dynamicTemplateData === null) { return; } if (typeof dynamicTemplateData !== 'object') { throw new Error( 'Object expected for `dynamicTemplateData` in deepMergeDynamicTemplateData' ); } this.dynamicTemplateData = deepMerge(dynamicTemplateData, this.dynamicTemplateData); } /** * Set dynamic template data */ setDynamicTemplateData(dynamicTemplateData) { if (typeof dynamicTemplateData === 'undefined') { return; } if (typeof dynamicTemplateData !== 'object') { throw new Error('Object expected for `dynamicTemplateData`'); } this.dynamicTemplateData = dynamicTemplateData; } /** * To JSON */ toJSON() { //Get data from self const { to, from, cc, bcc, subject, headers, customArgs, sendAt, substitutions, substitutionWrappers, dynamicTemplateData, } = this; //Initialize with mandatory values const json = {to}; //Arrays if (Array.isArray(cc) && cc.length > 0) { json.cc = cc; } if (Array.isArray(bcc) && bcc.length > 0) { json.bcc = bcc; } //Objects if (Object.keys(headers).length > 0) { json.headers = headers; } if (substitutions && Object.keys(substitutions).length > 0) { const [left, right] = substitutionWrappers; json.substitutions = wrapSubstitutions(substitutions, left, right); } if (Object.keys(customArgs).length > 0) { json.customArgs = customArgs; } if (dynamicTemplateData && Object.keys(dynamicTemplateData).length > 0) { json.dynamicTemplateData = dynamicTemplateData; } //Simple properties if (typeof subject !== 'undefined') { json.subject = subject; } if (typeof sendAt !== 'undefined') { json.sendAt = sendAt; } if (typeof from !== 'undefined') { json.from = from; } //Return as snake cased object return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); } } //Export class module.exports = Personalization;