@sendgrid/helpers
Advanced tools
Comparing version 6.2.1 to 6.3.0
@@ -24,2 +24,3 @@ 'use strict'; | ||
//Initialize array and object properties | ||
this.isDynamic = false; | ||
this.personalizations = []; | ||
@@ -39,2 +40,3 @@ this.attachments = []; | ||
this.substitutionWrappers = null; | ||
this.dynamicTemplateData = null; | ||
@@ -60,3 +62,3 @@ //Process data if given | ||
data = deepClone(data); | ||
data = toCamelCase(data, ['substitutions', 'customArgs', 'headers']); | ||
data = toCamelCase(data, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers', 'sections']); | ||
@@ -68,3 +70,3 @@ //Extract properties from data | ||
sections, headers, categories, category, customArgs, asm, mailSettings, | ||
trackingSettings, substitutions, substitutionWrappers, isMultiple, | ||
trackingSettings, substitutions, substitutionWrappers, dynamicTemplateData, isMultiple, | ||
} = data; | ||
@@ -90,5 +92,10 @@ | ||
this.setTrackingSettings(trackingSettings); | ||
this.setSubstitutions(substitutions); | ||
this.setSubstitutionWrappers(substitutionWrappers); | ||
if (this.isDynamic) { | ||
this.setDynamicTemplateData(dynamicTemplateData) | ||
} else { | ||
this.setSubstitutions(substitutions); | ||
this.setSubstitutionWrappers(substitutionWrappers); | ||
} | ||
//Add contents from text/html properties | ||
@@ -161,3 +168,3 @@ this.addTextContent(text); | ||
/** | ||
* Set template ID | ||
* Set template ID, also checks if the template is dynamic or legacy | ||
*/ | ||
@@ -171,2 +178,7 @@ setTemplateId(templateId) { | ||
} | ||
if (templateId.indexOf('d-') === 0) { | ||
this.isDynamic = true; | ||
} | ||
this.templateId = templateId; | ||
@@ -236,2 +248,10 @@ } | ||
//We should either send substitutions or dynamicTemplateData | ||
//depending on the templateId | ||
if (this.isDynamic && personalization.substitutions) { | ||
delete personalization.substitutions; | ||
} else if (personalization.dynamicTemplateData) { | ||
delete personalization.dynamicTemplateData; | ||
} | ||
//Convert to class if needed | ||
@@ -242,4 +262,10 @@ if (!(personalization instanceof Personalization)) { | ||
//Apply substitutions and push to array | ||
this.applySubstitutions(personalization); | ||
//If this is dynamic, set dynamicTemplateData, or set substitutions | ||
if (this.isDynamic) { | ||
this.applyDynamicTemplateData(personalization); | ||
} else { | ||
this.applySubstitutions(personalization); | ||
} | ||
//Push personalization to array | ||
this.personalizations.push(personalization); | ||
@@ -301,2 +327,24 @@ } | ||
/** | ||
* Helper which applies globally set dynamic_template_data to personalizations | ||
*/ | ||
applyDynamicTemplateData(personalization) { | ||
if (personalization instanceof Personalization) { | ||
personalization.deepMergeDynamicTemplateData(this.dynamicTemplateData); | ||
} | ||
} | ||
/** | ||
* Set dynamicTemplateData | ||
*/ | ||
setDynamicTemplateData(dynamicTemplateData) { | ||
if (typeof dynamicTemplateData === 'undefined') { | ||
return; | ||
} | ||
if (typeof dynamicTemplateData !== 'object') { | ||
throw new Error('Object expected for `dynamicTemplateData`'); | ||
} | ||
this.dynamicTemplateData = dynamicTemplateData; | ||
} | ||
/** | ||
* Set content | ||
@@ -390,3 +438,3 @@ */ | ||
if (!Array.isArray(categories) || | ||
!categories.every(cat => typeof cat === 'string')) { | ||
!categories.every(cat => typeof cat === 'string')) { | ||
throw new Error('Array of strings expected for `categories`'); | ||
@@ -553,3 +601,3 @@ } | ||
//Return as snake cased object | ||
return toSnakeCase(json, ['substitutions', 'customArgs', 'headers']); | ||
return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers', 'sections']); | ||
} | ||
@@ -556,0 +604,0 @@ |
@@ -43,2 +43,116 @@ 'use strict'; | ||
}); | ||
describe('#689', function() { | ||
it('should detect dynamic template id', function() { | ||
const mail = new Mail({ | ||
personalizations: [{ | ||
to: 'test@example.com', | ||
headers: { | ||
'test-header': 'test', | ||
}, | ||
}], | ||
from: { | ||
email: 'test@example.com', | ||
}, | ||
templateId: 'd-df80613cccc6441ea5cd7c95377bc1ef', | ||
subject: 'test', | ||
content: [{ | ||
type: 'text/plain', | ||
value: 'test', | ||
}], | ||
}); | ||
expect(mail.isDynamic).to.equal(true); | ||
}); | ||
it('should detect legacy template id', function() { | ||
const mail = new Mail({ | ||
personalizations: [{ | ||
to: 'test@example.com', | ||
headers: { | ||
'test-header': 'test', | ||
}, | ||
}], | ||
from: { | ||
email: 'test@example.com', | ||
}, | ||
templateId: 'df80613cccc6441ea5cd7c95377bc1ef', | ||
subject: 'test', | ||
content: [{ | ||
type: 'text/plain', | ||
value: 'test', | ||
}], | ||
}); | ||
expect(mail.isDynamic).to.equal(false); | ||
}); | ||
it('should ignore substitutions if templateId is dynamic', function() { | ||
const mail = new Mail({ | ||
personalizations: [{ | ||
to: 'test@example.com', | ||
headers: { | ||
'test-header': 'test', | ||
}, | ||
substitutions: { | ||
test2: 'Test2', | ||
}, | ||
dynamicTemplateData: { | ||
test2: 'Testy 2', | ||
test3: 'Testy 3', | ||
}, | ||
}], | ||
dynamicTemplateData: { | ||
test1: 'Test 1', | ||
test2: 'Test 2', | ||
}, | ||
substitutions: { | ||
test1: 'Test1', | ||
}, | ||
from: { | ||
email: 'test@example.com', | ||
}, | ||
templateId: 'd-df80613cccc6441ea5cd7c95377bc1ef', | ||
subject: 'test', | ||
content: [{ | ||
type: 'text/plain', | ||
value: 'test', | ||
}], | ||
}); | ||
expect(mail.substitutions).to.equal(null); | ||
expect(mail.personalizations[0].substitutions).to.deep.equal({}); | ||
expect(mail.dynamicTemplateData).to.deep.equal({ test1: 'Test 1', test2: 'Test 2' }); | ||
expect(mail.personalizations[0].dynamicTemplateData).to.deep.equal({ test1: 'Test 1', test2: 'Testy 2', test3: 'Testy 3' }); | ||
expect(mail.toJSON()).to.deep.equal({ | ||
'content': [ | ||
{ | ||
'type': 'text/plain', | ||
'value': 'test', | ||
}, | ||
], | ||
'from': { | ||
'email': 'test@example.com', | ||
}, | ||
'personalizations': [ | ||
{ | ||
'dynamic_template_data': { | ||
'test1': 'Test 1', | ||
'test2': 'Testy 2', | ||
'test3': 'Testy 3', | ||
}, | ||
'headers': { | ||
'test-header': 'test', | ||
}, | ||
'to': [ | ||
{ | ||
'email': 'test@example.com', | ||
'name': '', | ||
}, | ||
], | ||
}, | ||
], | ||
'subject': 'test', | ||
'template_id': 'd-df80613cccc6441ea5cd7c95377bc1ef', | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -19,4 +19,5 @@ #### Personalization helper specs | ||
- setSubstitutionWrappers() - set-substitutions-wrappers.spec.js | ||
- deepMergeDynamicTemplateData() - reverse-merge-dynamic_template_data.spec.js | ||
- toJSON() - to-json.spec.js | ||
- fromData() - from-data.spec.js | ||
- #527 - 527-camel-case-headers.spec.js |
@@ -12,7 +12,7 @@ 'use strict'; | ||
*/ | ||
describe('Personalization', function() { | ||
describe('Personalization', function () { | ||
//Create new personalization before each test | ||
let p; | ||
beforeEach(function() { | ||
beforeEach(function () { | ||
p = new Personalization(); | ||
@@ -22,8 +22,8 @@ }); | ||
//JSON conversion | ||
describe('toJSON()', function() { | ||
beforeEach(function() { | ||
describe('toJSON()', function () { | ||
beforeEach(function () { | ||
p.setTo('test@example.org'); | ||
}); | ||
it('should always have the to field', function() { | ||
it('should always have the to field', function () { | ||
const json = p.toJSON(); | ||
@@ -36,3 +36,3 @@ expect(json).to.have.property('to'); | ||
}); | ||
it('should set the cc field', function() { | ||
it('should set the cc field', function () { | ||
p.setCc('testcc@example.org'); | ||
@@ -46,3 +46,3 @@ const json = p.toJSON(); | ||
}); | ||
it('should set the bcc field', function() { | ||
it('should set the bcc field', function () { | ||
p.setBcc('testbcc@example.org'); | ||
@@ -56,4 +56,4 @@ const json = p.toJSON(); | ||
}); | ||
it('should set the headers field', function() { | ||
p.setHeaders({test: 'Test'}); | ||
it('should set the headers field', function () { | ||
p.setHeaders({ test: 'Test' }); | ||
const json = p.toJSON(); | ||
@@ -64,4 +64,4 @@ expect(json).to.have.property('headers'); | ||
}); | ||
it('should set the custom_args field', function() { | ||
p.setCustomArgs({test: 'Test'}); | ||
it('should set the custom_args field', function () { | ||
p.setCustomArgs({ test: 'Test' }); | ||
const json = p.toJSON(); | ||
@@ -72,4 +72,4 @@ expect(json).to.have.property('custom_args'); | ||
}); | ||
it('should set the substitutions field', function() { | ||
p.setSubstitutions({test: 'Test'}); | ||
it('should set the substitutions field', function () { | ||
p.setSubstitutions({ test: 'Test' }); | ||
const json = p.toJSON(); | ||
@@ -79,4 +79,4 @@ expect(json).to.have.property('substitutions'); | ||
}); | ||
it('should apply wrappers to the substitutions', function() { | ||
p.setSubstitutions({test: 'Test', otherTest2: 'Test2'}); | ||
it('should apply wrappers to the substitutions', function () { | ||
p.setSubstitutions({ test: 'Test', otherTest2: 'Test2' }); | ||
p.setSubstitutionWrappers(['{{', '}}']); | ||
@@ -91,3 +91,9 @@ const json = p.toJSON(); | ||
}); | ||
it('should set the subject field', function() { | ||
it('should set the dynamicTemplateData field', function () { | ||
p.setDynamicTemplateData({ test: 'Test' }); | ||
const json = p.toJSON(); | ||
expect(json).to.have.property('dynamic_template_data'); | ||
expect(json.dynamic_template_data).to.be.an.instanceof(Object); | ||
}); | ||
it('should set the subject field', function () { | ||
p.setSubject('Test'); | ||
@@ -98,3 +104,3 @@ const json = p.toJSON(); | ||
}); | ||
it('should set the send_at field', function() { | ||
it('should set the send_at field', function () { | ||
p.setSendAt(555); | ||
@@ -108,4 +114,4 @@ const json = p.toJSON(); | ||
to: 'to@example.org', | ||
customArgs: {snake_case: 'Test', T_EST: 'Test', camelCase: 'Test'}, | ||
substitutions: {snake_case: 'Test', T_EST: 'Test', camelCase: 'Test'}, | ||
customArgs: { snake_case: 'Test', T_EST: 'Test', camelCase: 'Test' }, | ||
substitutions: { snake_case: 'Test', T_EST: 'Test', camelCase: 'Test' }, | ||
}; | ||
@@ -127,3 +133,17 @@ p.fromData(data); | ||
}); | ||
it('should not modify the keys of dynamic template data', () => { | ||
const data = { | ||
to: 'to@example.org', | ||
dynamicTemplateData: { snake_case: 'Test', T_EST: 'Test', camelCase: 'Test' }, | ||
}; | ||
p.fromData(data); | ||
const json = p.toJSON(); | ||
expect(json.dynamic_template_data).to.have.property('T_EST'); | ||
expect(json.dynamic_template_data).to.have.property('camelCase'); | ||
expect(json.dynamic_template_data).to.have.property('snake_case'); | ||
expect(json.dynamic_template_data.T_EST).to.equal('Test'); | ||
expect(json.dynamic_template_data.camelCase).to.equal('Test'); | ||
expect(json.dynamic_template_data.snake_case).to.equal('Test'); | ||
}); | ||
}); | ||
}); |
@@ -1,10 +0,11 @@ | ||
import {EmailData, EmailJSON} from "./email-address"; | ||
import { EmailData, EmailJSON } from "./email-address"; | ||
export interface PersonalizationData { | ||
to: EmailData|EmailData[], | ||
cc?: EmailData|EmailData[], | ||
bcc?: EmailData|EmailData[], | ||
to: EmailData | EmailData[], | ||
cc?: EmailData | EmailData[], | ||
bcc?: EmailData | EmailData[], | ||
subject?: string; | ||
headers?: { [key: string]: string }; | ||
substitutions?: { [key: string]: string }; | ||
dynamicTemplateData?: { [key: string]: string; }; | ||
customArgs?: { [key: string]: string }; | ||
@@ -15,3 +16,3 @@ sendAt?: number; | ||
export interface PersonalizationJSON { | ||
to: EmailJSON|EmailJSON[]; | ||
to: EmailJSON | EmailJSON[]; | ||
cc?: EmailJSON[]; | ||
@@ -21,2 +22,3 @@ bcc?: EmailJSON[]; | ||
substitutions?: { [key: string]: string; }; | ||
dynamic_template_data?: { [key: string]: string; }; | ||
custom_args?: { [key: string]: string; }; | ||
@@ -31,3 +33,3 @@ subject?: string; | ||
fromData(data: PersonalizationData): void; | ||
/** | ||
@@ -46,3 +48,3 @@ * Set subject | ||
*/ | ||
setTo(to: EmailData|EmailData[]): void; | ||
setTo(to: EmailData | EmailData[]): void; | ||
@@ -57,3 +59,3 @@ /** | ||
*/ | ||
setCc(cc: EmailData|EmailData[]): void; | ||
setCc(cc: EmailData | EmailData[]): void; | ||
@@ -68,3 +70,3 @@ /** | ||
*/ | ||
setBcc(bcc: EmailData|EmailData[]): void; | ||
setBcc(bcc: EmailData | EmailData[]): void; | ||
@@ -117,2 +119,7 @@ /** | ||
/** | ||
* Set dynamic template data | ||
*/ | ||
setDynamicTemplateData(dynamicTemplateData: { [key: string]: string }): void; | ||
/** | ||
* To JSON | ||
@@ -119,0 +126,0 @@ */ |
@@ -10,2 +10,3 @@ 'use strict'; | ||
const deepClone = require('../helpers/deep-clone'); | ||
const merge = require('deepmerge'); | ||
const wrapSubstitutions = require('../helpers/wrap-substitutions'); | ||
@@ -31,2 +32,3 @@ | ||
this.substitutionWrappers = ['{{', '}}']; | ||
this.dynamicTemplateData = {}; | ||
@@ -52,3 +54,3 @@ //Build from data if given | ||
data = deepClone(data); | ||
data = toCamelCase(data, ['substitutions', 'customArgs', 'headers']); | ||
data = toCamelCase(data, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); | ||
@@ -58,3 +60,3 @@ //Extract properties from data | ||
to, cc, bcc, subject, headers, customArgs, sendAt, | ||
substitutions, substitutionWrappers, | ||
substitutions, substitutionWrappers, dynamicTemplateData, | ||
} = data; | ||
@@ -71,2 +73,3 @@ | ||
this.setCustomArgs(customArgs); | ||
this.setDynamicTemplateData(dynamicTemplateData); | ||
this.setSendAt(sendAt); | ||
@@ -280,2 +283,30 @@ } | ||
/** | ||
* 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 = merge(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 | ||
@@ -288,3 +319,3 @@ */ | ||
to, cc, bcc, subject, headers, customArgs, sendAt, | ||
substitutions, substitutionWrappers, | ||
substitutions, substitutionWrappers, dynamicTemplateData, | ||
} = this; | ||
@@ -307,3 +338,3 @@ | ||
} | ||
if (Object.keys(substitutions).length > 0) { | ||
if (substitutions && Object.keys(substitutions).length > 0) { | ||
const [left, right] = substitutionWrappers; | ||
@@ -316,2 +347,6 @@ json.substitutions = wrapSubstitutions(substitutions, left, right); | ||
if (dynamicTemplateData && Object.keys(dynamicTemplateData).length > 0) { | ||
json.dynamicTemplateData = dynamicTemplateData; | ||
} | ||
//Simple properties | ||
@@ -326,3 +361,3 @@ if (typeof subject !== 'undefined') { | ||
//Return as snake cased object | ||
return toSnakeCase(json, ['substitutions', 'customArgs', 'headers']); | ||
return toSnakeCase(json, ['substitutions', 'dynamicTemplateData', 'customArgs', 'headers']); | ||
} | ||
@@ -329,0 +364,0 @@ } |
@@ -1,3 +0,3 @@ | ||
import * as helpers from "@sendgrid/helpers/helpers/index" | ||
import * as classes from "@sendgrid/helpers/classes/index" | ||
import * as helpers from '@sendgrid/helpers/helpers/index'; | ||
import * as classes from '@sendgrid/helpers/classes/index'; | ||
@@ -7,2 +7,2 @@ export { | ||
classes, | ||
}; | ||
}; |
{ | ||
"name": "@sendgrid/helpers", | ||
"description": "SendGrid NodeJS internal helpers", | ||
"version": "6.2.1", | ||
"version": "6.3.0", | ||
"author": "SendGrid <dx@sendgrid.com> (sendgrid.com)", | ||
@@ -33,4 +33,5 @@ "contributors": [ | ||
"dependencies": { | ||
"chalk": "^2.0.1" | ||
"chalk": "^2.0.1", | ||
"deepmerge": "^2.1.1" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
113687
74
3770
2
+ Addeddeepmerge@^2.1.1
+ Addeddeepmerge@2.2.1(transitive)