Skip to content

Commit c4dfdaa

Browse files
Version 5.8.1-v2.1-20.3.01 release (#229)
Co-authored-by: DevCenter-DocuSign <[email protected]>
1 parent f77d8a8 commit c4dfdaa

File tree

8 files changed

+3232
-26
lines changed

8 files changed

+3232
-26
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# DocuSign Node Client Changelog
22

33
See [DocuSign Support Center](https://support.docusign.com/en/releasenotes/) for Product Release Notes.
4+
## [v5.8.1] - eSignature API v2.1-20.3.01
5+
### Changed
6+
- Added support for version v2.1-20.3.01 of the DocuSign eSignature API.
7+
- Updated the SDK release version.
8+
### Fixed
9+
- DCM-3866, Added support for updateBrandResourcesByContentType function to take in file to upload.
10+
- DCM-3369, Updated ApiClient to use an empty JSON object if the body is null.
11+
- DCM-4614, Fixed out of memory issue when deserializing large files.
412

513
## [v5.7.0] - eSignature API v2.1-20.3.00
614
### Changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "docusign-esign",
3-
"version": "5.8.0-rc1",
3+
"version": "5.8.1",
44
"description": "DocuSign Node.js API client.",
55
"license": "MIT",
66
"main": "src/index.js",

src/ApiClient.js

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,22 @@
445445
// Rely on SuperAgent for parsing response body.
446446
// See http://visionmedia.github.io/superagent/#parsing-response-bodies
447447
var data = response.body || (response.res && response.res.data);
448-
if (data == null || !Object.keys(data).length) {
448+
if (data == null || (typeof data === 'object' && typeof data.length === 'undefined' && !Object.keys(data).length)) {
449449
// SuperAgent does not always produce a body; use the unparsed response as a fallback
450450
data = response.text;
451451
}
452452
return exports.convertToType(data, returnType);
453453
};
454454

455+
exports.prototype.hasBufferFormParam = function(formParams) {
456+
if (!formParams) {
457+
return false;
458+
}
459+
return Object.keys(formParams).some(function(key) {
460+
return formParams[key] instanceof Buffer;
461+
});
462+
};
463+
455464
/**
456465
* (Optional)Callback function to receive the result of the <operationId> operation. If none specified a Promise will be returned.
457466
* @callback module:ApiClient~callApiCallback
@@ -484,6 +493,8 @@
484493
var _this = this;
485494
var url = this.buildUrl(path, pathParams);
486495
var request = superagent(httpMethod, url);
496+
var _formParams = this.normalizeParams(formParams);
497+
var body = bodyParam || {};
487498

488499
// apply authentications
489500
this.applyAuthToRequest(request, authNames);
@@ -513,19 +524,32 @@
513524
if (contentType === 'application/x-www-form-urlencoded') {
514525
request.send(this.normalizeParams(formParams));
515526
} else if (contentType == 'multipart/form-data') {
516-
var _formParams = this.normalizeParams(formParams);
517-
for (var key in _formParams) {
518-
if (_formParams.hasOwnProperty(key)) {
519-
if (this.isFileParam(_formParams[key])) {
520-
// file field
521-
request.attach(key, _formParams[key]);
522-
} else {
523-
request.field(key, _formParams[key]);
527+
if (this.hasBufferFormParam(_formParams)) {
528+
request.set({
529+
'Content-Disposition': 'form-data; name="file"; filename="file.xml"'
530+
});
531+
request.set({
532+
'Content-Type': 'application/octet-stream'
533+
});
534+
var formAttachmentKey = Object.keys(formParams).find(function(key) {
535+
return _this.isFileParam(_formParams[key]);
536+
});
537+
request.send(removeNulls(formParams[formAttachmentKey]));
538+
} else {
539+
var _formParams = this.normalizeParams(formParams);
540+
for (var key in _formParams) {
541+
if (_formParams.hasOwnProperty(key)) {
542+
if (this.isFileParam(_formParams[key])) {
543+
// file field
544+
request.attach(key, _formParams[key]);
545+
} else {
546+
request.field(key, _formParams[key]);
547+
}
524548
}
525549
}
526550
}
527-
} else if (bodyParam) {
528-
request.send(removeNulls(bodyParam));
551+
} else if (body) {
552+
request.send(removeNulls(body));
529553
}
530554

531555
var accept = this.jsonPreferredMime(accepts);
@@ -556,7 +580,6 @@
556580
})
557581
}
558582

559-
560583
var data = null;
561584
if (!callback) {
562585
return new Promise(function(resolve, reject){
@@ -791,7 +814,6 @@
791814
});
792815
});
793816
} catch (err) {
794-
console.log(err)
795817
throw(err)
796818
}
797819
} else {
@@ -911,4 +933,4 @@
911933
}));
912934

913935
module.exports.OAuth = require('./OAuth');
914-
module.exports.RestApi = require('./RestApi');
936+
module.exports.RestApi = require('./RestApi');

src/api/AccountsApi.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ A 201 code is returned if the call succeeded. While the call may have succeed,
244244
An error is returned if `brandId` property for a brand profile is already set for the account. To upload a new version of an existing brand profile, you must delete the profile and then upload the newer version.
245245
246246
When brand profile files are being uploaded, they must be combined into one zip file and the `Content-Type` must be `application/zip`.
247-
* @param {String} accountId The external account number (int) or account ID Guid.
247+
* @param {String} accountId The external account number (int) or account ID GUID.
248248
* @param {Object} optsOrCallback Optional parameters, if you are passing no optional parameters, you can either pass a null or omit this parameter entirely.
249249
* @param {module:model/Brand} optsOrCallback.brand
250250
* @param {module:api/AccountsApi~createBrandCallback} callback The callback function, accepting three arguments: error, data, response
@@ -3654,13 +3654,19 @@ Users with account administration privileges can retrieve shared access informat
36543654

36553655
/**
36563656
* Uploads a branding resource file.
3657-
* @param {String} accountId The external account number (int) or account ID Guid.
3658-
* @param {String} brandId The unique identifier of a brand.
3659-
* @param {String} resourceContentType
3657+
* @param {String} accountId The external account number (int) or account ID GUID.
3658+
* @param {String} brandId The id of the brand.
3659+
* @param {String} resourceContentType The type of brand resource file that you are updating. Valid values are:
3660+
3661+
- `sending`
3662+
- `signing`
3663+
- `email`
3664+
- `signing_captive`
3665+
* @param {Object} fileXml Brand resource XML file.
36603666
* @param {module:api/AccountsApi~updateBrandResourcesByContentTypeCallback} callback The callback function, accepting three arguments: error, data, response
36613667
* data is of type: {@link module:model/BrandResources}
36623668
*/
3663-
this.updateBrandResourcesByContentType = function(accountId, brandId, resourceContentType, callback) {
3669+
this.updateBrandResourcesByContentType = function(accountId, brandId, resourceContentType, fileXml, callback) {
36643670
var postBody = null;
36653671

36663672
// verify the required parameter 'accountId' is set
@@ -3678,6 +3684,11 @@ Users with account administration privileges can retrieve shared access informat
36783684
throw new Error("Missing the required parameter 'resourceContentType' when calling updateBrandResourcesByContentType");
36793685
}
36803686

3687+
// verify the required parameter 'fileXml' is set
3688+
if (fileXml === undefined || fileXml === null) {
3689+
throw new Error("Missing the required parameter 'fileXml' when calling updateBrandResourcesByContentType");
3690+
}
3691+
36813692
if (typeof callback !== 'function' && arguments.length && typeof arguments[arguments.length-1] === 'function'){
36823693
if (typeof optsOrCallback !== 'undefined') {
36833694
optsOrCallback = callback;
@@ -3695,10 +3706,11 @@ Users with account administration privileges can retrieve shared access informat
36953706
var headerParams = {
36963707
};
36973708
var formParams = {
3709+
'file.xml': fileXml
36983710
};
36993711

37003712
var authNames = ['docusignAccessCode'];
3701-
var contentTypes = [];
3713+
var contentTypes = ['multipart/form-data'];
37023714
var accepts = ['application/json'];
37033715
var returnType = BrandResources;
37043716

test/SdkUnitTests.js

Lines changed: 147 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ var basePath = restApi.BasePath.DEMO;
2828
var oAuthBasePath = oAuth.BasePath.DEMO;
2929

3030
var SignTest1File = 'docs/SignTest1.pdf';
31+
var LargeTestDocument1 = 'docs/LargeTestDocument1.pdf';
3132
var brandLogoPath = 'img/docusign-lgo.png';
33+
var brandXmlPath = 'docs/brand.xml';
3234
var accountId = '';
3335
var envelopeId = '';
3436
var userId = config.userId;
@@ -427,14 +429,11 @@ describe('SDK Unit Tests:', function (done) {
427429
if (envelopeSummary) {
428430
console.log('EnvelopeSummary: ' + JSON.stringify(envelopeSummary));
429431
envelopeId = envelopeSummary.envelopeId;
430-
console.log('starwars');
431432
console.log(bulkRecipients);
432433
csvStringify(bulkRecipients, { header: true }, function (err, bulkRecipientsRequest) {
433434
if (err) {
434435
return done(err);
435436
}
436-
console.log('starwars2');
437-
438437
console.log(bulkRecipientsRequest);
439438
var byteArray = Buffer.from(bulkRecipientsRequest);
440439
console.log(byteArray);
@@ -671,7 +670,7 @@ describe('SDK Unit Tests:', function (done) {
671670
try {
672671
var fs = require('fs');
673672
// read file from a local directory
674-
fileBytes = fs.readFileSync(path.resolve(__dirname, SignTest1File));
673+
fileBytes = fs.readFileSync(path.resolve(__dirname, LargeTestDocument1));
675674
} catch (ex) {
676675
// handle error
677676
console.log('Exception: ' + ex);
@@ -823,6 +822,38 @@ describe('SDK Unit Tests:', function (done) {
823822
return done(error);
824823
});
825824
});
825+
826+
// it('listStatusChangesOptions 70 envelopeIds', function (done) {
827+
// console.log('starwars')
828+
//
829+
// var envelopesApi = new docusign.EnvelopesApi(apiClient);
830+
// var THIRTY_DAYS_AGO = new Date(new Date().setDate(new Date().getDate()-30));
831+
//
832+
// var options = {
833+
// count: "70", fromDate: THIRTY_DAYS_AGO
834+
// };
835+
// envelopesApi.listStatusChanges(accountId, options)
836+
// .then(function (data) {
837+
// var envelopIds = data.envelopes.reduce( function( acc, envelope ) {
838+
// if (!acc.length) return envelope.envelopeId;
839+
// return acc + ', ' + envelope.envelopeId;
840+
// }, '');
841+
// console.log(envelopIds);
842+
// envelopesApi.listStatusChanges(accountId, {envelopeIds: envelopIds})
843+
// .then( function(data) {
844+
// assert.notEqual(data.envelopes, undefined);
845+
// assert.notEqual(data.envelopes[0].attachmentsUri, undefined);
846+
// assert.notEqual(data.envelopes[0].statusChangedDateTime, undefined);
847+
// done();
848+
// }).catch(function (error, resp) {
849+
// return done(error);
850+
// });;
851+
// })
852+
// .catch(function (error) {
853+
// return done(error);
854+
// });
855+
// });
856+
826857
it('getDiagnosticLogs', function (done) {
827858
var fileBytes = null;
828859
try {
@@ -1024,6 +1055,30 @@ describe('SDK Unit Tests:', function (done) {
10241055
});
10251056
});
10261057
});
1058+
1059+
it('it updateBrandResourcesByContentType', function (done) {
1060+
var accountsApi = new docusign.AccountsApi(apiClient);
1061+
accountsApi.listBrands(accountId, { includeLogos: true })
1062+
.then(function (brandsData) {
1063+
var currentBrand = brandsData.brands[0];
1064+
var brandXmlBuffer = fs.readFileSync(path.resolve(__dirname, brandXmlPath));
1065+
accountsApi.updateBrandResourcesByContentType(accountId, currentBrand.brandId, 'email', brandXmlBuffer)
1066+
.then(function (data) {
1067+
assert.notEqual(data.createdByUserInfo, undefined);
1068+
assert.notEqual(data.resourcesContentUri, undefined);
1069+
return done();
1070+
})
1071+
.catch(function (error) {
1072+
// console.log(error)
1073+
return done(error);
1074+
});
1075+
})
1076+
.catch(function (error) {
1077+
// console.log(error)
1078+
return done(error);
1079+
});
1080+
});
1081+
10271082
it('create template with date and number tabs', function (done) {
10281083
var fileBytes = null;
10291084
try {
@@ -1119,4 +1174,92 @@ describe('SDK Unit Tests:', function (done) {
11191174
}
11201175
});
11211176
});
1177+
1178+
it('resend envelope with envelope update', function (done) {
1179+
var fileBytes = null;
1180+
try {
1181+
var fs = require('fs');
1182+
// read file from a local directory
1183+
fileBytes = fs.readFileSync(path.resolve(__dirname, SignTest1File));
1184+
} catch (ex) {
1185+
// handle error
1186+
console.log('Exception: ' + ex);
1187+
}
1188+
1189+
// create an envelope to be signed
1190+
var envDef = new docusign.EnvelopeDefinition();
1191+
envDef.emailSubject = 'Please Sign my Node SDK Envelope';
1192+
envDef.emailBlurb = 'Hello, Please sign my Node SDK Envelope.';
1193+
1194+
// add a document to the envelope
1195+
var doc = new docusign.Document();
1196+
var base64Doc = Buffer.from(fileBytes).toString('base64');
1197+
doc.documentBase64 = base64Doc;
1198+
doc.name = 'TestFile.pdf';
1199+
doc.documentId = '1';
1200+
1201+
var docs = [];
1202+
docs.push(doc);
1203+
envDef.documents = docs;
1204+
1205+
// Add a recipient to sign the document
1206+
var signer = new docusign.Signer();
1207+
signer.email = userName;
1208+
var name = 'Pat Developer';
1209+
signer.name = name;
1210+
signer.recipientId = '1';
1211+
1212+
// this value represents the client's unique identifier for the signer
1213+
var clientUserId = '2939';
1214+
signer.clientUserId = clientUserId;
1215+
1216+
// create a signHere tab somewhere on the document for the signer to sign
1217+
// default unit of measurement is pixels, can be mms, cms, inches also
1218+
var signHere = new docusign.SignHere();
1219+
signHere.documentId = '1';
1220+
signHere.pageNumber = '1';
1221+
signHere.recipientId = '1';
1222+
signHere.xPosition = '100';
1223+
signHere.yPosition = '100';
1224+
1225+
// can have multiple tabs, so need to add to envelope as a single element list
1226+
var signHereTabs = [];
1227+
signHereTabs.push(signHere);
1228+
var tabs = new docusign.Tabs();
1229+
tabs.signHereTabs = signHereTabs;
1230+
signer.tabs = tabs;
1231+
1232+
// Above causes issue
1233+
envDef.recipients = new docusign.Recipients();
1234+
envDef.recipients.signers = [];
1235+
envDef.recipients.signers.push(signer);
1236+
1237+
// send the envelope (otherwise it will be "created" in the Draft folder
1238+
envDef.status = 'sent';
1239+
1240+
var envelopesApi = new docusign.EnvelopesApi(apiClient);
1241+
1242+
envelopesApi.createEnvelope(accountId, { envelopeDefinition: envDef })
1243+
.then(function (envelopeSummary) {
1244+
if (envelopeSummary) {
1245+
envelopesApi.update(accountId, envelopeSummary.envelopeId, { resendEnvelope: true })
1246+
.then(function (envelopeUpdateSummary) {
1247+
if (envelopeUpdateSummary) {
1248+
console.log('envelopeUpdateSummary: ' + JSON.stringify(envelopeUpdateSummary));
1249+
done();
1250+
}
1251+
})
1252+
.catch(function (error) {
1253+
if (error) {
1254+
return done(error);
1255+
}
1256+
});
1257+
}
1258+
})
1259+
.catch(function (error) {
1260+
if (error) {
1261+
return done(error);
1262+
}
1263+
});
1264+
});
11221265
});

0 commit comments

Comments
 (0)