Socket
Socket
Sign inDemoInstall

@sendgrid/helpers

Package Overview
Dependencies
Maintainers
20
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sendgrid/helpers - npm Package Compare versions

Comparing version 6.3.0 to 6.4.0

attachment.txt

67

classes/attachment.js

@@ -9,2 +9,4 @@ 'use strict';

const deepClone = require('../helpers/deep-clone');
const fs = require('fs');
const path = require('path');

@@ -16,5 +18,5 @@ /**

/**
* Constructor
*/
/**
* Constructor
*/
constructor(data) {

@@ -44,6 +46,18 @@

//Extract properties from data
const {content, filename, type, disposition, contentId} = data;
const {
content,
filename,
type,
disposition,
contentId,
filePath,
} = data;
if ((typeof content !== 'undefined') && (typeof filePath !== 'undefined')) {
throw new Error(
`The props 'content' and 'filePath' cannot be used together.`
);
}
//Set data
this.setContent(content);
this.setFilename(filename);

@@ -53,18 +67,47 @@ this.setType(type);

this.setContentId(contentId);
this.setContent(filePath ? this.readFile(filePath) : content);
}
/**
* Read a file and return its content as base64
*/
readFile(filePath) {
return fs.readFileSync(path.resolve(filePath));
}
/**
* Set content
*/
setContent(content) {
if (typeof content === 'undefined') {
//Duck type check toString on content if it's a Buffer as that's the method that will be called.
if (typeof content === 'string') {
this.content = content;
return;
}
if (typeof content !== 'string') {
throw new Error('String expected for `content`');
else if (content instanceof Buffer && content.toString !== undefined) {
this.content = content.toString();
if (this.disposition === 'attachment') {
this.content = content.toString('base64');
}
return;
}
this.content = content;
throw new Error('`content` expected to be either Buffer or string');
}
/**
* Set content
*/
setFileContent(content) {
if (content instanceof Buffer && content.toString !== undefined) {
this.content = content.toString('base64');
return;
}
throw new Error('`content` expected to be Buffer');
}
/**
* Set filename

@@ -121,5 +164,5 @@ */

/**
* To JSON
*/
/**
* To JSON
*/
toJSON() {

@@ -126,0 +169,0 @@

10

classes/email-address.js

@@ -13,3 +13,3 @@ 'use strict';

/**
/**
* Constructor

@@ -59,3 +59,7 @@ */

}
this.name = name;
// Wrap name in quotes to address API issue
// https://github.com/sendgrid/sendgrid-csharp/issues/268#issuecomment-232177443
const isQuoted = (name[0] === '\"') && (name[name.length - 1] === '\"');
const shouldQuote = name.includes(',') && !isQuoted;
this.name = shouldQuote ? `\"${name}\"` : name;
}

@@ -76,3 +80,3 @@

/**
/**
* To JSON

@@ -79,0 +83,0 @@ */

@@ -57,2 +57,12 @@ 'use strict';

});
it('should wrap name in quotes if a comma is present', function() {
email.setName('Doe, John');
expect(email.name).to.equal('\"Doe, John\"');
});
it('should not double wrap in quotes', function() {
email.setName('\"Doe, John\"');
expect(email.name).to.equal('\"Doe, John\"');
});
it('should throw an error for invalid input', function() {

@@ -59,0 +69,0 @@ expect(function() {

@@ -11,2 +11,3 @@ 'use strict';

const ResponseError = require('./response-error');
const Statistics = require('./statistics');

@@ -22,2 +23,3 @@ /**

ResponseError,
Statistics,
};

@@ -155,2 +155,3 @@ import {AttachmentData, AttachmentJSON} from "./attachment";

isMultiple?: boolean,
dynamicTemplateData?: { [key: string]: any },
}

@@ -346,2 +347,2 @@

static create(data: MailData[]): Mail[];
}
}

@@ -12,2 +12,3 @@ 'use strict';

const arrayToJSON = require('../helpers/array-to-json');
const { DYNAMIC_TEMPLATE_CHAR_WARNING } = require('../constants');

@@ -91,4 +92,5 @@ /**

if (this.isDynamic) {
this.setDynamicTemplateData(dynamicTemplateData)
} else {
this.setDynamicTemplateData(dynamicTemplateData);
}
else {
this.setSubstitutions(substitutions);

@@ -247,3 +249,4 @@ this.setSubstitutionWrappers(substitutionWrappers);

delete personalization.substitutions;
} else if (personalization.dynamicTemplateData) {
}
else if (personalization.dynamicTemplateData) {
delete personalization.dynamicTemplateData;

@@ -260,3 +263,4 @@ }

this.applyDynamicTemplateData(personalization);
} else {
}
else {
this.applySubstitutions(personalization);

@@ -340,2 +344,10 @@ }

}
// Check dynamic template for non-escaped characters and warn if found
Object.values(dynamicTemplateData).forEach(value => {
if (/['"&]/.test(value)) {
console.warn(DYNAMIC_TEMPLATE_CHAR_WARNING);
}
});
this.dynamicTemplateData = dynamicTemplateData;

@@ -342,0 +354,0 @@ }

@@ -7,2 +7,3 @@ 'use strict';

const Mail = require('./mail');
const { DYNAMIC_TEMPLATE_CHAR_WARNING } = require('../constants');

@@ -158,2 +159,61 @@ /**

});
describe('dynamic template handlebars substitutions', () => {
let logSpy, data;
beforeEach(() => {
logSpy = sinon.spy(console, 'warn');
data = {
to: 'recipient@example.org',
from: 'sender@example.org',
subject: 'Hello world',
text: 'Hello plain world!',
html: '<p>Hello HTML world!</p>',
templateId: 'd-df80613cccc6441ea5cd7c95377bc1ef',
};
});
afterEach(() => {
console.warn.restore();
});
it('should log an error if template subject line contains improperly escaped "\'" character', () => {
data = Object.assign(data, {
dynamicTemplateData: {
subject: 'Testing Templates and \'Stuff\'',
},
});
const mail = new Mail(data);
expect(logSpy.calledOnce).to.equal(true);
expect(logSpy.calledWith(DYNAMIC_TEMPLATE_CHAR_WARNING)).to.equal(true);
});
it('should log an error if template subject line contains improperly escaped """ character', () => {
data = Object.assign(data, {
dynamicTemplateData: {
subject: '"Testing Templates" and Stuff',
},
});
const mail = new Mail(data);
expect(logSpy.calledOnce).to.equal(true);
expect(logSpy.calledWith(DYNAMIC_TEMPLATE_CHAR_WARNING)).to.equal(true);
});
it('should log an error if template subject line contains improperly escaped "&" character', () => {
data = Object.assign(data, {
dynamicTemplateData: {
subject: 'Testing Templates & Stuff',
},
});
const mail = new Mail(data);
expect(logSpy.calledOnce).to.equal(true);
expect(logSpy.calledWith(DYNAMIC_TEMPLATE_CHAR_WARNING)).to.equal(true);
});
});
});

@@ -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,4 +22,4 @@ });

//Reverse merge substitutions
describe('deepMergeDynamicTemplateData()', function () {
it('should reverse merge dynamicTemplateData', function () {
describe('deepMergeDynamicTemplateData()', function() {
it('should reverse merge dynamicTemplateData', function() {
p.setDynamicTemplateData({ test1: 'Test1' });

@@ -32,3 +32,3 @@ p.deepMergeDynamicTemplateData({ test2: 'Test2' });

});
it('should not overwrite existing keys', function () {
it('should not overwrite existing keys', function() {
p.setDynamicTemplateData({ test1: 'Test1' });

@@ -41,3 +41,3 @@ p.deepMergeDynamicTemplateData({ test1: 'Test3', test2: 'Test2' });

});
it('should work without prior dynamicTemplateData', function () {
it('should work without prior dynamicTemplateData', function() {
p.deepMergeDynamicTemplateData({ test2: 'Test2' });

@@ -47,9 +47,9 @@ expect(p.dynamicTemplateData).to.have.a.property('test2');

});
it('should throw an error for invalid input', function () {
expect(function () {
it('should throw an error for invalid input', function() {
expect(function() {
p.deepMergeDynamicTemplateData(3);
}).to.throw(Error);
});
it('should accept no input', function () {
expect(function () {
it('should accept no input', function() {
expect(function() {
p.deepMergeDynamicTemplateData();

@@ -56,0 +56,0 @@ }).not.to.throw(Error);

@@ -12,3 +12,3 @@ 'use strict';

*/
describe('Personalization', function() {
describe('Personalization', function() {

@@ -46,2 +46,2 @@ //Create new personalization before each test

});
});
});

@@ -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,3 +56,3 @@ const json = p.toJSON();

});
it('should set the headers field', function () {
it('should set the headers field', function() {
p.setHeaders({ test: 'Test' });

@@ -64,3 +64,3 @@ const json = p.toJSON();

});
it('should set the custom_args field', function () {
it('should set the custom_args field', function() {
p.setCustomArgs({ test: 'Test' });

@@ -72,3 +72,3 @@ const json = p.toJSON();

});
it('should set the substitutions field', function () {
it('should set the substitutions field', function() {
p.setSubstitutions({ test: 'Test' });

@@ -79,3 +79,3 @@ const json = p.toJSON();

});
it('should apply wrappers to the substitutions', function () {
it('should apply wrappers to the substitutions', function() {
p.setSubstitutions({ test: 'Test', otherTest2: 'Test2' });

@@ -91,3 +91,3 @@ p.setSubstitutionWrappers(['{{', '}}']);

});
it('should set the dynamicTemplateData field', function () {
it('should set the dynamicTemplateData field', function() {
p.setDynamicTemplateData({ test: 'Test' });

@@ -98,3 +98,3 @@ const json = p.toJSON();

});
it('should set the subject field', function () {
it('should set the subject field', function() {
p.setSubject('Test');

@@ -105,3 +105,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,0 +108,0 @@ const json = p.toJSON();

@@ -7,5 +7,5 @@ 'use strict';

module.exports = function convertHTML2PlainString(html) {
let text = html.replace(/(<([^>]+)>)/g, "");
text = text.replace(/\s+/g,' ')
return text
}
let text = html.replace(/(<([^>]+)>)/g, '');
text = text.replace(/\s+/g, ' ');
return text;
};

@@ -13,21 +13,21 @@ 'use strict';

//Test string with one html tag
const html1 = '<p>Hello world</p>';
//Test string with nested html tags
const html2 = '<div><p>Hello <b>World!</b></p></div>';
//Test string with html tag with attributes
const html3 = '<div class="test-class">Hello World!</div>';
//Tests
it('should strip out html tags', function() {
expect(convertHTML2PlainString(html1)).to.be.equal('Hello world');
});
it('should strip out nested html tags', function() {
expect(convertHTML2PlainString(html2)).to.be.equal('Hello World!');
});
it('should strip out html tags with attributes', function() {
expect(convertHTML2PlainString(html3)).to.be.equal('Hello World!');
});
//Test string with one html tag
const html1 = '<p>Hello world</p>';
//Test string with nested html tags
const html2 = '<div><p>Hello <b>World!</b></p></div>';
//Test string with html tag with attributes
const html3 = '<div class="test-class">Hello World!</div>';
//Tests
it('should strip out html tags', function() {
expect(convertHTML2PlainString(html1)).to.be.equal('Hello world');
});
it('should strip out nested html tags', function() {
expect(convertHTML2PlainString(html2)).to.be.equal('Hello World!');
});
it('should strip out html tags with attributes', function() {
expect(convertHTML2PlainString(html3)).to.be.equal('Hello World!');
});
});

@@ -23,7 +23,10 @@ 'use strict';

if (isObject(data[key])) {
if (!(key in base))
if (!(key in base)) {
Object.assign(output, { [key]: data[key] });
else
}
else {
output[key] = mergeDeep(base[key], data[key]);
} else {
}
}
else {
Object.assign(output, { [key]: data[key] });

@@ -34,2 +37,2 @@ }

return output;
}
};

@@ -11,3 +11,3 @@ 'use strict';

*/
describe('mergeDataDeep', function () {
describe('mergeDataDeep', function() {

@@ -33,3 +33,3 @@ //Test objects

//Tests
it('should merge the two objects', function () {
it('should merge the two objects', function() {
expect(merged).to.have.property('a');

@@ -44,11 +44,11 @@ expect(merged).to.have.property('b');

});
it('should throw on invalid input', function () {
expect(function () {
it('should throw on invalid input', function() {
expect(function() {
mergeDataDeep(null, obj2);
}).to.throw(Error);
expect(function () {
expect(function() {
mergeDataDeep(obj1, 4);
}).to.throw(Error);
});
it('should overwrite arrays', function () {
it('should overwrite arrays', function() {
expect(merged).to.have.property('arr');

@@ -55,0 +55,0 @@ expect(merged.arr).to.be.an.instanceof(Array);

{
"name": "@sendgrid/helpers",
"description": "SendGrid NodeJS internal helpers",
"version": "6.3.0",
"author": "SendGrid <dx@sendgrid.com> (sendgrid.com)",
"description": "Twilio SendGrid NodeJS internal helpers",
"version": "6.4.0",
"author": "Twilio SendGrid <dx@sendgrid.com> (sendgrid.com)",
"contributors": [

@@ -7,0 +7,0 @@ "Kyle Partridge <kyle.partridge@sendgrid.com>",

@@ -11,3 +11,3 @@ [![BuildStatus](https://travis-ci.org/sendgrid/sendgrid-nodejs.svg?branch=master)](https://travis-ci.org/sendgrid/sendgrid-nodejs)

Note that not all objects represented in the Sendgrid API have helper classes assigned to them, because it is not expected that developers will use these classes themselves. They are primarily for internal use and developers are expected to use the publicly exposed API in the [various endpoint services](https://www.npmjs.com/org/sendgrid).
Note that not all objects represented in the Sendgrid API have helper classes assigned to them because it is not expected that developers will use these classes themselves. They are primarily for internal use and developers are expected to use the publicly exposed API in the [various endpoint services](https://www.npmjs.com/org/sendgrid).

@@ -17,3 +17,3 @@ To be notified when this package is updated, please subscribe to email [notifications](https://dx.sendgrid.com/newsletter/nodejs) for releases and breaking changes.

## Mail class
Used to compose a `Mail` object that converts itself to proper JSON for use with the [Sendgrid v3 API](https://sendgrid.com/docs/API_Reference/api_v3.html). This class supports a slightly different API to make sending emails easier in many cases by not having to deal with personalization arrays, instead offering a simpler interface for composing mails.
Used to compose a `Mail` object that converts itself to proper JSON for use with the [Sendgrid v3 API](https://sendgrid.com/docs/API_Reference/api_v3.html). This class supports a slightly different API to make sending emails easier in many cases by not having to deal with personalization arrays, instead offering a more straightforward interface for composing emails.

@@ -44,6 +44,6 @@ ## Attachment class

@sendgrid/helpers is guided and supported by the SendGrid [Developer Experience Team](mailto:dx@sendgrid.com).
@sendgrid/helpers are guided and supported by the Twilio SendGrid [Developer Experience Team](mailto:dx@sendgrid.com).
@sendgrid/helpers is maintained and funded by SendGrid, Inc. The names and logos for @sendgrid/helpers are trademarks of SendGrid, Inc.
@sendgrid/helpers are maintained and funded by Twilio SendGrid, Inc. The names and logos for @sendgrid/helpers are trademarks of Twilio SendGrid, Inc.
![SendGrid Logo](https://uiux.s3.amazonaws.com/2016-logos/email-logo%402x.png)
![Twilio SendGrid Logo](https://github.com/sendgrid/sendgrid-python/raw/master/twilio_sendgrid_logo.png)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc