@sap/xsodata 8.2.1 → 8.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/index.js +2 -2
- package/lib/configuration.js +1 -1
- package/lib/db/connect.js +1 -1
- package/lib/db/dbSegment.js +68 -123
- package/lib/db/dbVersionChecks.js +2 -8
- package/lib/handlerConfiguration.js +2 -2
- package/lib/http/conditionalHttpHandler.js +27 -34
- package/lib/http/simpleHttpRequest.js +14 -18
- package/lib/http/simpleHttpResponse.js +9 -6
- package/lib/http/uriParser.js +9 -9
- package/lib/http/validator/httpRequestValidator.js +9 -9
- package/lib/model/annotationFactory.js +11 -11
- package/lib/model/association.js +3 -3
- package/lib/model/entityType.js +33 -67
- package/lib/model/metadataReader.js +31 -52
- package/lib/model/model.js +0 -1
- package/lib/model/validator/xsoDataConcurrencyTokenValidator.js +6 -6
- package/lib/model/xsodataReader.js +36 -28
- package/lib/processor/authorizationProcessor.js +22 -33
- package/lib/processor/batchProcessor.js +22 -33
- package/lib/processor/errorProcessor.js +4 -4
- package/lib/processor/exitProcessor.js +19 -19
- package/lib/processor/processor.js +9 -9
- package/lib/processor/resourceProcessor.js +31 -61
- package/lib/processor/resourceProcessorDelete.js +16 -16
- package/lib/processor/resourceProcessorDeleteLinks.js +25 -25
- package/lib/processor/resourceProcessorGet.js +5 -5
- package/lib/processor/resourceProcessorPost.js +43 -45
- package/lib/processor/resourceProcessorPut.js +35 -39
- package/lib/processor/resourceProcessorPutPostLinks.js +38 -39
- package/lib/security/securityContext.js +5 -5
- package/lib/serializer/atomSerializer.js +54 -55
- package/lib/serializer/atomXmlToJsonSerializer.js +32 -44
- package/lib/serializer/content.js +5 -5
- package/lib/serializer/json.js +31 -33
- package/lib/serializer/jsonSerializer.js +4 -4
- package/lib/serializer/metadataSerializer.js +32 -35
- package/lib/serializer/serializer.js +29 -43
- package/lib/serializer/serviceSerializer.js +19 -24
- package/lib/serializer/value.js +1 -2
- package/lib/serializer/xmlToJsonSerializer.js +18 -18
- package/lib/sql/createDeleteLinksStatements.js +10 -10
- package/lib/sql/createDeleteStatements.js +12 -12
- package/lib/sql/createGetStatements.js +49 -107
- package/lib/sql/createLinksSQLStatements_1_n.js +27 -27
- package/lib/sql/createPutPostLinksStatements.js +9 -9
- package/lib/sql/createPutStatements.js +0 -1
- package/lib/sql/dataCollectorDelete.js +9 -9
- package/lib/sql/dataCollectorDeleteLinks.js +3 -3
- package/lib/sql/dataCollectorGet.js +9 -17
- package/lib/sql/dataCollectorLinks.js +23 -27
- package/lib/sql/dataCollectorPost.js +20 -20
- package/lib/sql/dataCollectorPut.js +36 -36
- package/lib/sql/dataCollectorPutPostLinks.js +3 -3
- package/lib/sql/sqlStatement.js +81 -128
- package/lib/sql/sqlTools.js +3 -7
- package/lib/sql/statementProcessor.js +7 -14
- package/lib/uri/applyChecks.js +3 -3
- package/lib/uri/checks/checkAllowedMethod.js +3 -3
- package/lib/uri/checks/checkAllowedMethodForBatch.js +2 -2
- package/lib/uri/checks/checkAllowedMethodsForResourcePath.js +3 -3
- package/lib/uri/checks/checkFilterOnAggregatedColumn.js +5 -5
- package/lib/uri/checks/checkFilterOrderByOnGenKeyColumn.js +6 -6
- package/lib/uri/checks/checkGenKeyRestrictions.js +2 -2
- package/lib/uri/checks/checkModificationForbidden.js +3 -3
- package/lib/uri/checks/checkPostPutDeleteChecks.js +5 -5
- package/lib/uri/checks/checkSystemQueryOptions.js +10 -10
- package/lib/uri/checks.js +15 -15
- package/lib/uri/expandSelectTreeBuilder.js +12 -16
- package/lib/uri/oDataUriParser.js +20 -20
- package/lib/uri/queryParameterParser.js +25 -33
- package/lib/uri/resourcePathParser.js +47 -62
- package/lib/uri/uriType.js +4 -4
- package/lib/utils/associations.js +4 -4
- package/lib/utils/batch/batchExecutor.js +49 -51
- package/lib/utils/batch/batchObjects.js +10 -10
- package/lib/utils/batch/batchParser.js +27 -28
- package/lib/utils/batch/batchWriter.js +1 -1
- package/lib/utils/checkContentType.js +34 -39
- package/lib/utils/debugView.js +35 -36
- package/lib/utils/errors/applicationError.js +2 -2
- package/lib/utils/errors/debugInfo.js +2 -2
- package/lib/utils/errors/http/badRequest.js +2 -2
- package/lib/utils/errors/http/forbidden.js +2 -2
- package/lib/utils/errors/http/methodNotAllowed.js +2 -2
- package/lib/utils/errors/http/notAcceptable.js +2 -2
- package/lib/utils/errors/http/notFound.js +2 -2
- package/lib/utils/errors/http/notImplemented.js +2 -2
- package/lib/utils/errors/http/notModified.js +2 -2
- package/lib/utils/errors/http/notSupported.js +2 -2
- package/lib/utils/errors/http/preconditionFailed.js +2 -2
- package/lib/utils/errors/http/preconditionRequired.js +2 -2
- package/lib/utils/errors/http/unauthorized.js +2 -2
- package/lib/utils/errors/http/unsupportedMediaType.js +2 -2
- package/lib/utils/errors/httpError.js +2 -2
- package/lib/utils/errors/internalError.js +2 -2
- package/lib/utils/errors/modelFileError.js +2 -2
- package/lib/utils/errors/sqlError.js +2 -2
- package/lib/utils/errors/testError.js +2 -2
- package/lib/utils/errors/typeError.js +5 -5
- package/lib/utils/errors/xsODataError.js +1 -1
- package/lib/utils/logger.js +21 -32
- package/lib/utils/measurement.js +14 -13
- package/lib/utils/requestContext.js +2 -2
- package/lib/utils/stateMaschine.js +6 -6
- package/lib/utils/tableCleanup.js +3 -3
- package/lib/utils/typeConverter.js +21 -21
- package/lib/utils/typeConverters/converterTools.js +25 -331
- package/lib/utils/typeConverters/dbToJson.js +3 -3
- package/lib/utils/typeConverters/dbToUri.js +7 -7
- package/lib/utils/typeConverters/dbToXml.js +9 -9
- package/lib/utils/typeConverters/jsonToDb.js +20 -27
- package/lib/utils/typeConverters/uriToDb.js +45 -92
- package/lib/utils/typeConverters/xmlValueToJson.js +9 -13
- package/lib/utils/typedObjects.js +11 -79
- package/lib/utils/utils.js +20 -23
- package/lib/xsodata.js +37 -47
- package/package.json +9 -11
- package/.npmignore +0 -40
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const Http403_Forbidden = require('../../utils/errors/http/forbidden');
|
|
3
3
|
|
|
4
4
|
module.exports = function checkAllowedMethods(){
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const verbs = Array.prototype.slice.apply(arguments);
|
|
7
7
|
|
|
8
8
|
return function(context, callback){
|
|
9
|
-
|
|
9
|
+
const verbAllowed = verbs.some(function(verb){
|
|
10
10
|
return context.request.method.toLowerCase() === verb;
|
|
11
11
|
});
|
|
12
12
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const Http405_MethodNotAllowed = require('../../utils/errors/http/methodNotAllowed');
|
|
3
3
|
|
|
4
4
|
module.exports = function checkAllowedMethodForBatch(context, callback) {
|
|
5
|
-
|
|
5
|
+
const method = context.request.method.toLowerCase();
|
|
6
6
|
|
|
7
7
|
if (method !== 'post'){
|
|
8
8
|
return callback(new Http405_MethodNotAllowed('The URI is not valid for non POST operation. OData batch requests must use POST.'), context);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const Http405_MethodNotAllowed = require('../../utils/errors/http/methodNotAllowed'),
|
|
3
3
|
Http501_MethodNotSupported = require('../../utils/errors/http/notSupported');
|
|
4
4
|
|
|
5
5
|
module.exports = function checkAllowdMethodsForResourePath(context, callback) {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const method = context.request.method.toLowerCase();
|
|
8
|
+
const dbLast = context.oData.dbSegmentLast;
|
|
9
9
|
|
|
10
10
|
if (context.batchContext) {
|
|
11
11
|
if (!context.batchContext.inChangeSet) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const Http400_BadRequest= require('../../utils/errors/http/badRequest');
|
|
4
4
|
|
|
5
5
|
module.exports = function checkFilterOnAggregatedColumn(context, callback) {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const aggs = context.oData.dbSegmentLast.entityType.getAggregates();
|
|
8
|
+
const filter = context.oData.systemQueryParameters.filter;
|
|
9
9
|
|
|
10
10
|
if (aggs.length === 0 || !filter){
|
|
11
11
|
return callback(null, context);
|
|
@@ -20,12 +20,12 @@ module.exports = function checkFilterOnAggregatedColumn(context, callback) {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
function createError() {
|
|
23
|
-
|
|
23
|
+
const errorMessage = '$filter is not allowed for aggregated columns.';
|
|
24
24
|
return new Http400_BadRequest(errorMessage);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function check(aggs, type){
|
|
28
|
-
|
|
28
|
+
let violation = aggs.some(function(agg){
|
|
29
29
|
return agg.column === type.property;
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const Http400_BadRequest= require('../../utils/errors/http/badRequest');
|
|
4
4
|
|
|
5
5
|
module.exports = function checkFilterOrderByOnGenKeyColumn(context, callback) {
|
|
6
|
-
|
|
6
|
+
let genKey;
|
|
7
7
|
|
|
8
8
|
if(context.oData.dbSegmentLast.entityType.hasGeneratedKey()){
|
|
9
9
|
genKey = context.oData.dbSegmentLast.entityType.keys.generatedKey;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const filter = context.oData.systemQueryParameters.filter;
|
|
13
|
+
const orderBy = context.oData.systemQueryParameters.orderby;
|
|
14
14
|
|
|
15
15
|
if (!genKey || (!filter && !orderBy)){
|
|
16
16
|
return callback(null, context);
|
|
@@ -29,12 +29,12 @@ module.exports = function checkFilterOrderByOnGenKeyColumn(context, callback) {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
function createError(sqo) {
|
|
32
|
-
|
|
32
|
+
const errorMessage = '$' + sqo + ' is not allowed for generated key columns.';
|
|
33
33
|
return new Http400_BadRequest(errorMessage);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function check(genKey, type){
|
|
37
|
-
|
|
37
|
+
let violation = genKey === type.property;
|
|
38
38
|
|
|
39
39
|
if (!violation){
|
|
40
40
|
violation = type.getChildren().some(check.bind(null, genKey));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const Http501_NotSupported= require('../../utils/errors/http/notSupported');
|
|
4
4
|
|
|
5
5
|
module.exports = function checkGenKeyRestrictions(context, callback) {
|
|
6
6
|
|
|
@@ -20,7 +20,7 @@ module.exports = function checkGenKeyRestrictions(context, callback) {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
function createError() {
|
|
23
|
-
|
|
23
|
+
const errorMessage = 'GET, PUT/MERGE, DELETE are not allowed for entity requests, ' +
|
|
24
24
|
'where generated local key is defined on the corresponding entity set. ' +
|
|
25
25
|
'In addition POST requests to the entity set are also not allowed.';
|
|
26
26
|
return new Http501_NotSupported(errorMessage);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const Http403_Forbidden = require('../../utils/errors/http/forbidden');
|
|
3
3
|
|
|
4
4
|
module.exports = function checkModificationForbidden(context, callback){
|
|
5
|
-
|
|
5
|
+
const methodModificationMap = {
|
|
6
6
|
'put': 'update',
|
|
7
7
|
'post' : 'create',
|
|
8
8
|
'delete' : 'delete'
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const modification = methodModificationMap[context.request.method.toLowerCase()];
|
|
12
12
|
|
|
13
13
|
if (context.oData.dbSegmentLast.entityType.modifications[modification] === 'forbidden'){
|
|
14
14
|
return callback(new Http403_Forbidden('Modification forbidden.'), context);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const methodNotAllowed = require('../../utils/errors/http/methodNotAllowed');
|
|
3
3
|
|
|
4
4
|
module.exports = function (context, callback) {
|
|
5
|
-
|
|
5
|
+
const method = context.request.method.toLowerCase();
|
|
6
6
|
|
|
7
7
|
if (method === 'post') {
|
|
8
8
|
checkPost(context, callback);
|
|
@@ -21,7 +21,7 @@ function createNowAllowed(mess, context) {
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
function checkPost(context, callback) {
|
|
24
|
-
|
|
24
|
+
const dbLast = context.oData.dbSegmentLast;
|
|
25
25
|
if ((dbLast.previousDBSegment && !context.oData.dbSegment.isLinks) || dbLast.nextDBSegment) {
|
|
26
26
|
return callback(createNowAllowed('POST only allowed on direct entitySets', context), context);
|
|
27
27
|
}
|
|
@@ -29,7 +29,7 @@ function checkPost(context, callback) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function checkPut(context, callback) {
|
|
32
|
-
|
|
32
|
+
const dbLast = context.oData.dbSegmentLast;
|
|
33
33
|
if ((dbLast.previousDBSegment && !context.oData.dbSegment.isLinks) || dbLast.nextDBSegment) {
|
|
34
34
|
return callback(createNowAllowed('PUT only allowed on direct entitySets', context), context);
|
|
35
35
|
}
|
|
@@ -37,7 +37,7 @@ function checkPut(context, callback) {
|
|
|
37
37
|
|
|
38
38
|
}
|
|
39
39
|
function checkDelete(context, callback) {
|
|
40
|
-
|
|
40
|
+
const dbLast = context.oData.dbSegmentLast;
|
|
41
41
|
if ((dbLast.previousDBSegment && !context.oData.dbSegment.isLinks) || dbLast.nextDBSegment) {
|
|
42
42
|
return callback(createNowAllowed('DELETE only allowed on direct entitySets', context), context);
|
|
43
43
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const Http404 = require('../../utils/errors/http/badRequest');
|
|
3
|
+
const Http501 = require('../../utils/errors/http/notImplemented');
|
|
4
|
+
const uriType = require('../uriType');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const sqoMap = {};
|
|
7
7
|
sqoMap[uriType.URI0] = {
|
|
8
8
|
expand: false,
|
|
9
9
|
filter: false,
|
|
@@ -185,13 +185,13 @@ sqoMap[uriType.UNKNOWN_URI] = {
|
|
|
185
185
|
};
|
|
186
186
|
|
|
187
187
|
module.exports = function checkSystemQueryOptions(context, callback) {
|
|
188
|
-
|
|
188
|
+
const sysQueryParams = context.oData.systemQueryParameters;
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
const odataUriType = uriType.determineUriType(context);
|
|
191
191
|
setUriType(context, odataUriType);
|
|
192
192
|
context.logger.debug('check system query options', 'uri type identified: URI' + odataUriType);
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
const containsSkipToken = Object.keys(sysQueryParams).some(function(sqo){
|
|
195
195
|
return sqo === 'skiptoken';
|
|
196
196
|
});
|
|
197
197
|
|
|
@@ -200,13 +200,13 @@ module.exports = function checkSystemQueryOptions(context, callback) {
|
|
|
200
200
|
return callback(new Http501('$skiptoken not supported'), context);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
const notAllowedSqos = Object.keys(sysQueryParams).some(function(sqo){
|
|
204
204
|
return !sqoMap[odataUriType][sqo];
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
if (notAllowedSqos){
|
|
208
208
|
context.logger.debug('check system query options', 'violation found');
|
|
209
|
-
|
|
209
|
+
const message = createErrorMessage(sqoMap[odataUriType]);
|
|
210
210
|
return callback(new Http404(message), context);
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -214,7 +214,7 @@ module.exports = function checkSystemQueryOptions(context, callback) {
|
|
|
214
214
|
|
|
215
215
|
function createErrorMessage(sqoMap){
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
const allowedSqos = Object.keys(sqoMap).filter(function(sqo){
|
|
218
218
|
return sqoMap[sqo];
|
|
219
219
|
}).map(function (sqo){
|
|
220
220
|
return '$' + sqo;
|
package/lib/uri/checks.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
const oDataUriParser = require('./oDataUriParser');
|
|
4
|
+
const resourceKind = oDataUriParser.URI_KIND_Resource;
|
|
5
|
+
const metaDataKind = oDataUriParser.URI_KIND_MetaData;
|
|
6
|
+
const serviceKind = oDataUriParser.URI_KIND_Service;
|
|
7
|
+
const batchKind = oDataUriParser.URI_KIND_Batch;
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
const checkModificationForbidden = require('./checks/checkModificationForbidden');
|
|
10
|
+
const checkAllowedVerbs = require('./checks/checkAllowedMethod');
|
|
11
|
+
const checkGenKeyRestrictions = require('./checks/checkGenKeyRestrictions');
|
|
12
|
+
const checkAllowedMethodsForResourcePath = require('./checks/checkAllowedMethodsForResourcePath');
|
|
13
|
+
const checkAllowedMethodForBatch = require('./checks/checkAllowedMethodForBatch');
|
|
14
|
+
const checkPostPutDeleteChecks = require('./checks/checkPostPutDeleteChecks');
|
|
15
|
+
const checkSystemQueryOptions = require('./checks/checkSystemQueryOptions');
|
|
16
|
+
const checkFilterOnAggregatedColumn = require('./checks/checkFilterOnAggregatedColumn');
|
|
17
|
+
const checkFilterOrderByOnGenKeyColumn = require('./checks/checkFilterOrderByOnGenKeyColumn');
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const checks = module.exports = {};
|
|
20
20
|
|
|
21
21
|
checks[resourceKind] = [
|
|
22
22
|
checkAllowedMethodsForResourcePath,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const InternalError = require('./../utils/errors/internalError');
|
|
4
4
|
|
|
5
5
|
function NavExp() {
|
|
6
6
|
this.showAllProperties = true; //default show property, and navprop as link
|
|
@@ -17,7 +17,7 @@ function NavExp() {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
NavExp.prototype.toPureJsonObject = function () {
|
|
20
|
-
|
|
20
|
+
const ret = {
|
|
21
21
|
showAllProperties: this.showAllProperties,
|
|
22
22
|
expandAllAvailExpands: this.expandAllAvailExpands,
|
|
23
23
|
isStar: this.isStar,
|
|
@@ -26,7 +26,7 @@ NavExp.prototype.toPureJsonObject = function () {
|
|
|
26
26
|
availableExpands: {}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
for (
|
|
29
|
+
for (const exp in this.availableExpands) {
|
|
30
30
|
if (this.availableExpands.hasOwnProperty(exp)) {
|
|
31
31
|
ret.availableExpands[exp] = this.availableExpands[exp].toPureJsonObject();
|
|
32
32
|
}
|
|
@@ -44,7 +44,7 @@ NavExp.prototype.addNav = function (name, nav) {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
NavExp.prototype.applySelect = function (select) {
|
|
47
|
-
|
|
47
|
+
const part = select.shift();
|
|
48
48
|
|
|
49
49
|
if (part === '*') {
|
|
50
50
|
this.isStar = true;
|
|
@@ -52,7 +52,7 @@ NavExp.prototype.applySelect = function (select) {
|
|
|
52
52
|
} else {
|
|
53
53
|
this.showAllProperties = false;
|
|
54
54
|
this.expandAllAvailExpands = false;
|
|
55
|
-
|
|
55
|
+
const nav = this.availableExpands[part];
|
|
56
56
|
|
|
57
57
|
if (nav) {
|
|
58
58
|
|
|
@@ -82,24 +82,20 @@ NavExp.prototype.applySelect = function (select) {
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
function processSelects(selects, tree) {
|
|
85
|
-
for (
|
|
86
|
-
var select = selects[i];
|
|
85
|
+
for (const select of selects) {
|
|
87
86
|
tree.applySelect(select);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
function createExpandTree(expandClauses) {
|
|
92
|
-
|
|
91
|
+
const tree = new NavExp();
|
|
93
92
|
if (expandClauses) {
|
|
94
93
|
|
|
95
|
-
for (
|
|
96
|
-
|
|
97
|
-
var root = tree;
|
|
94
|
+
for (const expandClause of expandClauses) {
|
|
95
|
+
let root = tree;
|
|
98
96
|
|
|
99
|
-
for (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
var nav = root.getNav(expandItem);
|
|
97
|
+
for (const expandItem of expandClause) {
|
|
98
|
+
const nav = root.getNav(expandItem);
|
|
103
99
|
if (nav !== undefined) {
|
|
104
100
|
root = nav;
|
|
105
101
|
} else {
|
|
@@ -112,7 +108,7 @@ function createExpandTree(expandClauses) {
|
|
|
112
108
|
}
|
|
113
109
|
|
|
114
110
|
function processExpandSelectTree(expands, selects) {
|
|
115
|
-
|
|
111
|
+
const tree = createExpandTree(expands);
|
|
116
112
|
if (selects) {
|
|
117
113
|
processSelects(selects, tree);
|
|
118
114
|
}
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
//Includes
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
const oDataSegmentParser = require('../parsers/jison_segment_parser');
|
|
11
|
+
const queryParameterParser = require('./queryParameterParser');
|
|
12
|
+
const resourcePathParser = require('./resourcePathParser');
|
|
13
|
+
const uriSegmentTypes = require('./uriSegmentTypes');
|
|
14
|
+
const BadRequest = require('./../utils/errors/http/badRequest');
|
|
15
|
+
const Measurement = require('./../utils/measurement');
|
|
16
|
+
const typedObjects = require("./../utils/typedObjects");
|
|
17
|
+
const BadRequestError = require("./../utils/errors/http/badRequest");
|
|
18
18
|
|
|
19
19
|
// Values of the constants below correspond to the OData URI types
|
|
20
20
|
exports.URI_KIND_Service = 0;
|
|
@@ -26,13 +26,13 @@ exports.URI_KIND_Resource = 4;
|
|
|
26
26
|
const UNKNOWN_POSITION = -1;
|
|
27
27
|
|
|
28
28
|
function parseODataSegments(segments) {
|
|
29
|
-
|
|
29
|
+
const segmentsParsed = [];
|
|
30
30
|
if (segments.decoded.length === 0) {
|
|
31
31
|
segmentsParsed.push(new uriSegmentTypes.ServiceSegment(''));
|
|
32
32
|
} else {
|
|
33
|
-
for (
|
|
33
|
+
for (const segment of segments.decoded) {
|
|
34
34
|
try {
|
|
35
|
-
|
|
35
|
+
const tmp = oDataSegmentParser.parse(segment);
|
|
36
36
|
segmentsParsed.push(tmp);
|
|
37
37
|
} catch (err) {
|
|
38
38
|
let position = (err.hash && err.hash.loc && err.hash.loc.last_column && Number.isInteger(err.hash.loc.last_column)) ? err.hash.loc.last_column : UNKNOWN_POSITION;
|
|
@@ -71,11 +71,11 @@ function parseQueryParameter(name, value) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function parseSystemQueryParameters(queries) {
|
|
74
|
-
|
|
75
|
-
for (
|
|
74
|
+
const queryParameter = {};
|
|
75
|
+
for (const prop in queries) {
|
|
76
76
|
if (Object.prototype.hasOwnProperty.call(queries, prop)) {
|
|
77
|
-
if (prop.
|
|
78
|
-
|
|
77
|
+
if (prop.startsWith('$')) {
|
|
78
|
+
const name = prop.substring(1);
|
|
79
79
|
queryParameter[name] = parseQueryParameter(prop, queries[prop]);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -85,7 +85,7 @@ function parseSystemQueryParameters(queries) {
|
|
|
85
85
|
|
|
86
86
|
exports.parseODataUri = function (context, asyncDone) {
|
|
87
87
|
context.logger.silly('uri', 'parse OData uri');
|
|
88
|
-
|
|
88
|
+
const oData = {};
|
|
89
89
|
|
|
90
90
|
try {
|
|
91
91
|
context.logger.silly('uri', 'parse OData segments');
|
|
@@ -103,7 +103,7 @@ exports.parseODataUri = function (context, asyncDone) {
|
|
|
103
103
|
return asyncDone(err,context);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
const segment = oData.segments[0];
|
|
107
107
|
|
|
108
108
|
if (segment instanceof uriSegmentTypes.ServiceSegment) {
|
|
109
109
|
oData.kind = exports.URI_KIND_Service;
|
|
@@ -131,7 +131,7 @@ exports.parseODataUri = function (context, asyncDone) {
|
|
|
131
131
|
* @param context {Object} The xsodata context
|
|
132
132
|
*/
|
|
133
133
|
exports.validateQueryParameters = function (queryParameters, context) {
|
|
134
|
-
|
|
134
|
+
const query = context.uriTree.rawUrlParts.query;
|
|
135
135
|
|
|
136
136
|
if (queryParameters.filter || (query && query['$filter'])) {
|
|
137
137
|
exports.validate$filterExpression(queryParameters, context);
|
|
@@ -145,8 +145,8 @@ exports.validateQueryParameters = function (queryParameters, context) {
|
|
|
145
145
|
* @param context {Object} The xsodata context
|
|
146
146
|
*/
|
|
147
147
|
exports.validate$filterExpression = function (queryParameters, context) {
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const filter = queryParameters.filter;
|
|
149
|
+
const query = context.uriTree.rawUrlParts.query;
|
|
150
150
|
|
|
151
151
|
// Invalid $filter expression --> $filter=Id
|
|
152
152
|
if (filter && (filter instanceof typedObjects.Property) === true) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
//Includes
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const filter_parser = require('../parsers/jison_filter_parser');
|
|
5
|
+
const orderBy_parser = require('../parsers/jison_orderby_parser');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const BadRequest = require('./../utils/errors/http/badRequest');
|
|
8
|
+
const NotSupported = require('./../utils/errors/http/notSupported');
|
|
9
|
+
const UnsupportedMediatype = require('./../utils/errors/http/unsupportedMediaType');
|
|
10
10
|
|
|
11
11
|
//API
|
|
12
12
|
exports.parseExpand = parseExpand;
|
|
@@ -21,18 +21,16 @@ exports.parseInlineCount = parseInlineCount;
|
|
|
21
21
|
exports.parseSkipToken = parseSkipToken;
|
|
22
22
|
|
|
23
23
|
//Code
|
|
24
|
-
|
|
24
|
+
const onlyIntRegexObj = /^\d+$/;
|
|
25
25
|
|
|
26
26
|
function parseTop(top) {
|
|
27
27
|
if (!onlyIntRegexObj.test(top)) {
|
|
28
28
|
throw new BadRequest('Invalid value for system query $top.');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
const ret = parseInt(top);
|
|
32
32
|
|
|
33
|
-
if (ret > 2147483647) {
|
|
34
|
-
throw new BadRequest('Invalid value for system query $top.');
|
|
35
|
-
} else if (ret < 0) {
|
|
33
|
+
if (ret > 2147483647 || ret < 0) {
|
|
36
34
|
throw new BadRequest('Invalid value for system query $top.');
|
|
37
35
|
}
|
|
38
36
|
return ret;
|
|
@@ -44,11 +42,9 @@ function parseSkip(skip) {
|
|
|
44
42
|
throw new BadRequest('Invalid value for system query $skip.');
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
const ret = parseInt(skip);
|
|
48
46
|
|
|
49
|
-
if (ret > 2147483647) {
|
|
50
|
-
throw new BadRequest('Invalid value for system query $skip.');
|
|
51
|
-
} else if (ret < 0) {
|
|
47
|
+
if (ret > 2147483647 || ret < 0) {
|
|
52
48
|
throw new BadRequest('Invalid value for system query $skip.');
|
|
53
49
|
}
|
|
54
50
|
return ret;
|
|
@@ -69,18 +65,16 @@ function parseInlineCount(inlineCount) {
|
|
|
69
65
|
|
|
70
66
|
|
|
71
67
|
function parseSelect(select) {
|
|
72
|
-
|
|
68
|
+
const selectclauses = [];
|
|
73
69
|
if (!select) {
|
|
74
70
|
return selectclauses;
|
|
75
71
|
}
|
|
76
|
-
|
|
77
|
-
for (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
for (var ii = 0; ii < rawSelectItems.length; ii++) {
|
|
83
|
-
var rawSelectItem = rawSelectItems[ii];
|
|
72
|
+
const rawSelectClauses = select.split(',');
|
|
73
|
+
for (const rawSelectClause of rawSelectClauses) {
|
|
74
|
+
const rawSelectItems = rawSelectClause.split('/');
|
|
75
|
+
|
|
76
|
+
const selectItems = [];
|
|
77
|
+
for (const rawSelectItem of rawSelectItems) {
|
|
84
78
|
selectItems.push(rawSelectItem);
|
|
85
79
|
}
|
|
86
80
|
selectclauses.push(selectItems);
|
|
@@ -89,19 +83,17 @@ function parseSelect(select) {
|
|
|
89
83
|
}
|
|
90
84
|
|
|
91
85
|
function parseExpand(expand) {
|
|
92
|
-
|
|
86
|
+
const expandclauses = [];
|
|
93
87
|
if (!expand) {
|
|
94
88
|
return expandclauses;
|
|
95
89
|
}
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
for (
|
|
99
|
-
|
|
100
|
-
var rawExpandItems = rawExpandClause.split('/');
|
|
91
|
+
const rawExpandClauses = expand.split(',');
|
|
92
|
+
for (const rawExpandClause of rawExpandClauses) {
|
|
93
|
+
const rawExpandItems = rawExpandClause.split('/');
|
|
101
94
|
|
|
102
|
-
|
|
103
|
-
for (
|
|
104
|
-
var rawExpandItem = rawExpandItems[ii];
|
|
95
|
+
const expandList = [];
|
|
96
|
+
for (const rawExpandItem of rawExpandItems) {
|
|
105
97
|
expandList.push(rawExpandItem);
|
|
106
98
|
}
|
|
107
99
|
expandclauses.push(expandList);
|
|
@@ -111,7 +103,7 @@ function parseExpand(expand) {
|
|
|
111
103
|
|
|
112
104
|
function parseFilter(filter, done) {
|
|
113
105
|
|
|
114
|
-
|
|
106
|
+
let ast,
|
|
115
107
|
error;
|
|
116
108
|
|
|
117
109
|
try {
|
|
@@ -135,7 +127,7 @@ function parseOrderBy(orderBy, done) {
|
|
|
135
127
|
|
|
136
128
|
if (done !== undefined) {
|
|
137
129
|
|
|
138
|
-
|
|
130
|
+
let ast;
|
|
139
131
|
try {
|
|
140
132
|
ast = orderBy_parser.parse(orderBy);
|
|
141
133
|
} catch (ex) {
|