Skip to content

Commit 3380c80

Browse files
add: combinamble Prefer header
1 parent 0096104 commit 3380c80

File tree

10 files changed

+626
-301
lines changed

10 files changed

+626
-301
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,5 +249,4 @@ ModelManifest.xml
249249
/lib/test.js
250250
/scripts
251251
/coverage
252-
/tests/browser
253-
/lib/utilities/buildPreferHeader.js
252+
/tests/browser

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ In order to use DynamicsWebApi inside Dynamics 365 you need to download a browse
4545
Upload a script as a JavaScript Web Resource, place on the entity or refer to it in your HTML Web Resource and then initialize the main object:
4646

4747
```js
48-
var dynamicsWebApi = new DynamicsWebApi(); //by default Web API v8.0 used if you do not set a configuration object.
48+
//DynamicsWebApi makes calls to Web API v8.0 if a configuration not set
49+
var dynamicsWebApi = new DynamicsWebApi();
4950

5051
dynamicsWebApi.executeUnboundFunction("WhoAmI").then(function (response) {
5152
Xrm.Utility.alertDialog('Hello Dynamics 365! My id is: ' + response.UserId);

lib/dynamics-web-api-callbacks.js

Lines changed: 89 additions & 119 deletions
Large diffs are not rendered by default.

lib/dynamics-web-api.js

Lines changed: 97 additions & 122 deletions
Large diffs are not rendered by default.

lib/requests/sendRequest.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,6 @@ module.exports = function sendRequest(method, uri, config, data, additionalHeade
2020
additionalHeaders['MSCRMCallerID'] = config.impersonate;
2121
}
2222

23-
if (!additionalHeaders || (additionalHeaders && !additionalHeaders['Prefer'])) {
24-
if (!additionalHeaders) {
25-
additionalHeaders = {};
26-
}
27-
28-
if (config.maxPageSize && config.maxPageSize > 0) {
29-
additionalHeaders['Prefer'] = 'odata.maxpagesize=' + config.maxPageSize;
30-
}
31-
32-
if (config.returnRepresentation && !additionalHeaders.hasOwnProperty('Prefer')) {
33-
additionalHeaders['Prefer'] = DWA.Prefer.ReturnRepresentation;
34-
}
35-
36-
//post here is for big fetch xml requests
37-
if (config.includeAnnotations) {
38-
additionalHeaders['Prefer'] = 'odata.include-annotations="' + config.includeAnnotations + '"';
39-
}
40-
41-
if (additionalHeaders.hasOwnProperty('Prefer') && !additionalHeaders["Prefer"]){
42-
delete additionalHeaders['Prefer'];
43-
}
44-
}
45-
4623
var stringifiedData;
4724
if (data) {
4825
stringifiedData = JSON.stringify(data, function (key, value) {

lib/utilities/RequestConverter.js

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var DWA = require('../dwa');
22
var ErrorHelper = require('../helpers/ErrorHelper');
3+
var buildPreferHeader = require('./buildPreferHeader');
34

45
/**
56
* @typedef {Object} ConvertedRequestOptions
@@ -21,9 +22,10 @@ var ErrorHelper = require('../helpers/ErrorHelper');
2122
* @param {string} functionName - Name of the function that converts a request (for Error Handling)
2223
* @param {string} url - URL beginning (with required parameters)
2324
* @param {string} [joinSymbol] - URL beginning (with required parameters)
25+
* @param {Object} [config] - DynamicsWebApi config
2426
* @returns {ConvertedRequestOptions}
2527
*/
26-
function convertRequestOptions (request, functionName, url, joinSymbol) {
28+
function convertRequestOptions (request, functionName, url, joinSymbol, config) {
2729
var headers = {};
2830
var requestArray = [];
2931
joinSymbol = joinSymbol != null ? joinSymbol : "&";
@@ -70,11 +72,6 @@ function convertRequestOptions (request, functionName, url, joinSymbol) {
7072
requestArray.push("userQuery=" + ErrorHelper.guidParameterCheck(request.userQuery, "DynamicsWebApi." + functionName, "request.userQuery"));
7173
}
7274

73-
if (request.maxPageSize && request.maxPageSize > 0) {
74-
ErrorHelper.numberParameterCheck(request.maxPageSize, "DynamicsWebApi." + functionName, "request.maxPageSize");
75-
headers['Prefer'] = 'odata.maxpagesize=' + request.maxPageSize;
76-
}
77-
7875
if (request.count) {
7976
ErrorHelper.boolParameterCheck(request.count, "DynamicsWebApi." + functionName, "request.count");
8077
requestArray.push("$count=" + request.count);
@@ -90,14 +87,10 @@ function convertRequestOptions (request, functionName, url, joinSymbol) {
9087
requestArray.push("$orderby=" + request.orderBy.join(','));
9188
}
9289

93-
if (request.returnRepresentation != null) {
94-
ErrorHelper.boolParameterCheck(request.returnRepresentation, "DynamicsWebApi." + functionName, "request.returnRepresentation");
95-
headers['Prefer'] = request.returnRepresentation ? DWA.Prefer.ReturnRepresentation : '';
96-
}
90+
var prefer = buildPreferHeader(request, functionName, config);
9791

98-
if (request.includeAnnotations) {
99-
ErrorHelper.stringParameterCheck(request.includeAnnotations, "DynamicsWebApi." + functionName, "request.includeAnnotations");
100-
headers['Prefer'] = 'odata.include-annotations="' + request.includeAnnotations + '"';
92+
if (prefer.length) {
93+
headers['Prefer'] = prefer;
10194
}
10295

10396
if (request.ifmatch != null && request.ifnonematch != null) {
@@ -124,21 +117,26 @@ function convertRequestOptions (request, functionName, url, joinSymbol) {
124117
headers["Authorization"] = "Bearer: " + request.token;
125118
}
126119

127-
if (request.expand != null && request.expand.length) {
128-
ErrorHelper.arrayParameterCheck(request.expand, "DynamicsWebApi." + functionName, "request.expand");
129-
var expandRequestArray = [];
130-
for (var i = 0; i < request.expand.length; i++) {
131-
if (request.expand[i].property) {
132-
var expandConverted = convertRequestOptions(request.expand[i], functionName + " $expand", null, ";");
133-
var expandQuery = expandConverted.query;
134-
if (expandQuery && expandQuery.length) {
135-
expandQuery = "(" + expandQuery + ")";
120+
if (request.expand && request.expand.length) {
121+
ErrorHelper.stringOrArrayParameterCheck(request.expand, "DynamicsWebApi." + functionName, "request.expand");
122+
if (typeof request.expand === "string") {
123+
requestArray.push("$expand=" + encodeURI(request.expand));
124+
}
125+
else {
126+
var expandRequestArray = [];
127+
for (var i = 0; i < request.expand.length; i++) {
128+
if (request.expand[i].property) {
129+
var expandConverted = convertRequestOptions(request.expand[i], functionName + " $expand", null, ";");
130+
var expandQuery = expandConverted.query;
131+
if (expandQuery && expandQuery.length) {
132+
expandQuery = "(" + expandQuery + ")";
133+
}
134+
expandRequestArray.push(request.expand[i].property + expandQuery);
136135
}
137-
expandRequestArray.push(request.expand[i].property + expandQuery);
138136
}
139-
}
140-
if (expandRequestArray.length) {
141-
requestArray.push("$expand=" + encodeURI(expandRequestArray.join(",")));
137+
if (expandRequestArray.length) {
138+
requestArray.push("$expand=" + encodeURI(expandRequestArray.join(",")));
139+
}
142140
}
143141
}
144142
}
@@ -151,9 +149,10 @@ function convertRequestOptions (request, functionName, url, joinSymbol) {
151149
*
152150
* @param {Object} request - Request object
153151
* @param {string} [functionName] - Name of the function that converts a request (for Error Handling only)
152+
* @param {Object} [config] - DynamicsWebApi config
154153
* @returns {ConvertedRequest}
155154
*/
156-
function convertRequest(request, functionName) {
155+
function convertRequest(request, functionName, config) {
157156

158157
if (!request.collection) {
159158
ErrorHelper.parameterCheck(request.collection, "DynamicsWebApi." + functionName, "request.collection");
@@ -169,7 +168,7 @@ function convertRequest(request, functionName) {
169168
url += "(" + request.id + ")";
170169
}
171170

172-
var result = convertRequestOptions(request, functionName, url);
171+
var result = convertRequestOptions(request, functionName, url, '&', config);
173172

174173
if (result.query)
175174
result.url += "?" + encodeURI(result.query);

lib/utilities/buildPreferHeader.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
var DWA = require('../dwa');
2+
var ErrorHelper = require('../helpers/ErrorHelper');
3+
4+
/**
5+
* Builds a Prefer header value
6+
* @param {Object} request Request object
7+
* @param {string} functionName name of the current function
8+
* @param {Object} config DynamicsWebApi config
9+
* @returns {string}
10+
*/
11+
module.exports = function buildPreferHeader(request, functionName, config) {
12+
var returnRepresentation = request.returnRepresentation;
13+
var includeAnnotations = request.includeAnnotations;
14+
var maxPageSize = request.maxPageSize;
15+
16+
if (request.prefer && request.prefer.length) {
17+
ErrorHelper.stringOrArrayParameterCheck(request.prefer, "DynamicsWebApi." + functionName, "request.prefer");
18+
var prefer = request.prefer;
19+
if (typeof prefer === "string") {
20+
prefer = prefer.split(',');
21+
}
22+
for (var i in prefer) {
23+
if (prefer[i] === DWA.Prefer.ReturnRepresentation) {
24+
returnRepresentation = true;
25+
}
26+
else if (prefer[i].startsWith("odata.include-annotations=")) {
27+
includeAnnotations = prefer[i].replace('odata.include-annotations=', '').replace(/"/g,'');
28+
}
29+
else if (prefer[i].startsWith("odata.maxpagesize=")) {
30+
maxPageSize = prefer[i].replace('odata.maxpagesize=', '').replace(/"/g, '');
31+
}
32+
}
33+
}
34+
35+
if (config) {
36+
if (returnRepresentation == null) {
37+
returnRepresentation = config.returnRepresentation;
38+
}
39+
includeAnnotations = includeAnnotations ? includeAnnotations : config.includeAnnotations;
40+
maxPageSize = maxPageSize ? maxPageSize : config.maxPageSize;
41+
}
42+
43+
var prefer = [];
44+
45+
if (returnRepresentation) {
46+
ErrorHelper.boolParameterCheck(returnRepresentation, "DynamicsWebApi." + functionName, "request.returnRepresentation");
47+
prefer.push(DWA.Prefer.ReturnRepresentation);
48+
}
49+
50+
if (includeAnnotations) {
51+
ErrorHelper.stringParameterCheck(includeAnnotations, "DynamicsWebApi." + functionName, "request.includeAnnotations");
52+
prefer.push('odata.include-annotations="' + includeAnnotations + '"');
53+
}
54+
55+
if (maxPageSize && maxPageSize > 0) {
56+
ErrorHelper.numberParameterCheck(maxPageSize, "DynamicsWebApi." + functionName, "request.maxPageSize");
57+
prefer.push('odata.maxpagesize=' + maxPageSize);
58+
}
59+
60+
return prefer.join(',');
61+
}

tests/callbacks-tests.js

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,39 @@ describe("callbacks -", function () {
7070
expect(scope.isDone()).to.be.true;
7171
});
7272
});
73+
74+
describe("select", function () {
75+
var scope;
76+
before(function () {
77+
var response = mocks.responses.createReturnRepresentation;
78+
scope = nock(mocks.responses.collectionUrl, {
79+
reqheaders: {
80+
"Prefer": DWA.Prefer.ReturnRepresentation
81+
}
82+
})
83+
.post("?$select=name", mocks.data.testEntity)
84+
.reply(response.status, response.responseText, response.responseHeaders);
85+
});
86+
87+
after(function () {
88+
nock.cleanAll();
89+
});
90+
91+
it("returns the correct response", function (done) {
92+
dynamicsWebApiTest
93+
.create(mocks.data.testEntity, "tests", function (object) {
94+
expect(object).to.deep.equal(mocks.data.testEntity);
95+
done();
96+
}, function (object) {
97+
expect(object).to.be.undefined;
98+
done();
99+
}, DWA.Prefer.ReturnRepresentation, ['name']);
100+
});
101+
102+
it("all requests have been made", function () {
103+
expect(scope.isDone()).to.be.true;
104+
});
105+
});
73106
});
74107

75108
describe("dynamicsWebApi.update -", function () {
@@ -93,7 +126,7 @@ describe("callbacks -", function () {
93126

94127
it("returns the correct response", function (done) {
95128
dynamicsWebApiTest.update(mocks.data.testEntityId, "tests", mocks.data.testEntity, function (object) {
96-
expect(object).to.be.undefined;
129+
expect(object).to.be.true;
97130
done();
98131
}, function (object) {
99132
expect(object).to.be.undefined;
@@ -253,6 +286,41 @@ describe("callbacks -", function () {
253286
expect(scope.isDone()).to.be.true;
254287
});
255288
});
289+
290+
describe("select", function () {
291+
var scope;
292+
before(function () {
293+
var response = mocks.responses.updateReturnRepresentation;
294+
scope = nock(mocks.responses.testEntityUrl, {
295+
reqheaders: {
296+
"Prefer": DWA.Prefer.ReturnRepresentation
297+
}
298+
})
299+
.put("/fullname?$select=name", {
300+
value: mocks.data.updatedEntity.fullname
301+
})
302+
.reply(response.status, response.responseText, response.responseHeaders);
303+
});
304+
305+
after(function () {
306+
nock.cleanAll();
307+
});
308+
309+
it("returns the correct response", function (done) {
310+
dynamicsWebApiTest.updateSingleProperty(mocks.data.testEntityId, "tests", mocks.data.updatedEntity,
311+
function (object) {
312+
expect(object).to.deep.equal(mocks.data.updatedEntity);
313+
done();
314+
}, function (object) {
315+
expect(object).to.be.undefined;
316+
done();
317+
}, DWA.Prefer.ReturnRepresentation, ['name']);
318+
});
319+
320+
it("all requests have been made", function () {
321+
expect(scope.isDone()).to.be.true;
322+
});
323+
});
256324
});
257325

258326
describe("dynamicsWebApi.upsert -", function () {

0 commit comments

Comments
 (0)