@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,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
//Includes
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const NotSupported = require('./errors/http/notSupported');
|
|
5
|
+
const uriToDb = require('./../utils/typeConverters/uriToDb').uriToDb;
|
|
6
|
+
const XsODataTypeError = require('./errors/typeError');
|
|
7
7
|
|
|
8
8
|
//Supported expression kinds
|
|
9
9
|
exports.NODE_LITERAL = 1;//TODO
|
|
@@ -24,11 +24,9 @@ exports.NODE_METHOD = 23;
|
|
|
24
24
|
exports.NODE_PARENTHESIS = 24;
|
|
25
25
|
exports.NODE_MEMBER = 25;
|
|
26
26
|
exports.NODE_PROPERTY = 26;
|
|
27
|
-
//
|
|
28
27
|
exports.NODE_SORTORDER = 27;
|
|
29
28
|
exports.NODE_ORDERBY = 28;
|
|
30
29
|
|
|
31
|
-
|
|
32
30
|
//Supported binary operators
|
|
33
31
|
exports.OR = 0;
|
|
34
32
|
exports.AND = 1;
|
|
@@ -101,7 +99,6 @@ exports.Parenthesis = Parenthesis;
|
|
|
101
99
|
exports.Method = Method;
|
|
102
100
|
exports.Member = Member;
|
|
103
101
|
exports.Property = Property;
|
|
104
|
-
//exports.Literal = Literal;
|
|
105
102
|
|
|
106
103
|
exports.SortOrder = SortOrder;
|
|
107
104
|
exports.OrderBy = OrderBy;
|
|
@@ -172,7 +169,7 @@ function Nil() {
|
|
|
172
169
|
* Secondtime, value: 11:12:13
|
|
173
170
|
*/
|
|
174
171
|
Nil.prototype.toSqlHana = function toSqlHana() {
|
|
175
|
-
throw new
|
|
172
|
+
throw new XsODataTypeError('Nil can not converted to HANA sql syntax');
|
|
176
173
|
};
|
|
177
174
|
|
|
178
175
|
Nil.prototype.getChildren = function () {
|
|
@@ -240,7 +237,7 @@ function ONumber(number/*intPart, floatPart, exp, postFix*/) {
|
|
|
240
237
|
this.uriNumber = number;
|
|
241
238
|
this.preNumber = undefined;
|
|
242
239
|
|
|
243
|
-
let type = number.
|
|
240
|
+
let type = number.slice(number.length - 1).toUpperCase();
|
|
244
241
|
if (type === 'F' ||
|
|
245
242
|
type === 'f' ||
|
|
246
243
|
type === 'D' ||
|
|
@@ -273,7 +270,6 @@ function ONumber(number/*intPart, floatPart, exp, postFix*/) {
|
|
|
273
270
|
this.e = exponent[1] || null;
|
|
274
271
|
|
|
275
272
|
this.preNumber = '';
|
|
276
|
-
//this.preNumber += sign;
|
|
277
273
|
if (this.i) {
|
|
278
274
|
this.preNumber += this.i;
|
|
279
275
|
} else {
|
|
@@ -316,7 +312,7 @@ ONumber.prototype.toSqlHana = function toSqlHana(context, parameter) {
|
|
|
316
312
|
} else if (this.type === 'L') {
|
|
317
313
|
dbValue = input;
|
|
318
314
|
} else {
|
|
319
|
-
throw new
|
|
315
|
+
throw new XsODataTypeError(this.type);
|
|
320
316
|
}
|
|
321
317
|
parameter.push(dbValue);
|
|
322
318
|
|
|
@@ -334,7 +330,6 @@ ONumber.prototype.getChildren = function () {
|
|
|
334
330
|
function EdmString(value) {
|
|
335
331
|
this.kind = exports.NODE_LITERAL_STRING;
|
|
336
332
|
this.string = value;
|
|
337
|
-
//this.string = value.substring(1,value.length-1).replace(reg2to1Quote,'\'');
|
|
338
333
|
}
|
|
339
334
|
|
|
340
335
|
/** Conversion to HANA db type NString
|
|
@@ -351,8 +346,6 @@ EdmString.prototype.getChildren = function () {
|
|
|
351
346
|
return [];
|
|
352
347
|
};
|
|
353
348
|
|
|
354
|
-
//var reg2to1Quote = new RegExp('\'\'','g');
|
|
355
|
-
|
|
356
349
|
/** Edm.Binary representation
|
|
357
350
|
* @class Binary
|
|
358
351
|
* Tested via test_filter_parser.js
|
|
@@ -370,7 +363,6 @@ Binary.prototype.toSqlHana = function toSqlHana(context, parameter) {
|
|
|
370
363
|
let value = uriToDb['Edm.Binary'](this.value, 'VARBINARY');
|
|
371
364
|
|
|
372
365
|
parameter.push(value);
|
|
373
|
-
//parameter.push('x\'' + this.value + '\'');
|
|
374
366
|
return '?';
|
|
375
367
|
};
|
|
376
368
|
|
|
@@ -511,15 +503,6 @@ function complexBinaryWithNull(first, op, second, context, parameter) {
|
|
|
511
503
|
//only properties are used
|
|
512
504
|
if (op === exports.EQ) {
|
|
513
505
|
//equals
|
|
514
|
-
//out << "(";
|
|
515
|
-
//serializeExpr(f, out);
|
|
516
|
-
//out << "=";
|
|
517
|
-
//serializeExpr(s, out);
|
|
518
|
-
//out << " or (";
|
|
519
|
-
//serializeExpr(f, out);
|
|
520
|
-
//out << " is null and ";
|
|
521
|
-
//serializeExpr(s, out);
|
|
522
|
-
//out << " is null))";
|
|
523
506
|
sql += '(' + left + ' = ' + right +
|
|
524
507
|
' or (' + left + ' is null and ' + right + ' is null))';
|
|
525
508
|
parameter.push.apply(parameter, pLeft);
|
|
@@ -528,23 +511,6 @@ function complexBinaryWithNull(first, op, second, context, parameter) {
|
|
|
528
511
|
parameter.push.apply(parameter, pRight);
|
|
529
512
|
} else {
|
|
530
513
|
//not equals
|
|
531
|
-
//out << "((";
|
|
532
|
-
//serializeExpr(f, out);
|
|
533
|
-
//out << "!=";
|
|
534
|
-
//serializeExpr(s, out);
|
|
535
|
-
//out << " and not (";
|
|
536
|
-
//serializeExpr(f, out);
|
|
537
|
-
//out << " is null and ";
|
|
538
|
-
//serializeExpr(s, out);
|
|
539
|
-
//out << " is null)) or (";
|
|
540
|
-
//serializeExpr(f, out);
|
|
541
|
-
//out << " is null and ";
|
|
542
|
-
//serializeExpr(s, out);
|
|
543
|
-
//out << " is not null) or (";
|
|
544
|
-
//serializeExpr(f, out);
|
|
545
|
-
//out << " is not null and ";
|
|
546
|
-
//serializeExpr(s, out);
|
|
547
|
-
//out << " is null))";
|
|
548
514
|
sql +=
|
|
549
515
|
'((' + left + ' != ' + right +
|
|
550
516
|
' and not (' + left + ' is null and ' + right + ' is null))' +
|
|
@@ -567,15 +533,6 @@ function complexBinaryWithNull(first, op, second, context, parameter) {
|
|
|
567
533
|
if (_null) {
|
|
568
534
|
//TODO add feature
|
|
569
535
|
throw new NotSupported("Comparing operand type '<Collection>' with null not supported.", 406);
|
|
570
|
-
//out << (type == Expr::EQ ? " not exists (select 1 from " : " exists (select 1 from");
|
|
571
|
-
//serializeSegment(ast::cast<const ast::Member>(f)->lastSegment(), out);
|
|
572
|
-
//out << ")";
|
|
573
|
-
|
|
574
|
-
//if (op === exports.EQ) {
|
|
575
|
-
// sql += '( not exists (select 1 from ' + '...' + ')';
|
|
576
|
-
//} else {
|
|
577
|
-
// sql += 'exists (select 1 from ' + '...' + ')';
|
|
578
|
-
//}
|
|
579
536
|
} else {
|
|
580
537
|
if (op === exports.EQ) {
|
|
581
538
|
throw new Error("Operator 'eq' incompatible with operand types '<Collection>' and non '<Collection>'.");
|
|
@@ -586,36 +543,20 @@ function complexBinaryWithNull(first, op, second, context, parameter) {
|
|
|
586
543
|
} else {
|
|
587
544
|
if (op === exports.EQ) {
|
|
588
545
|
if (_null) {
|
|
589
|
-
//serializeExpr(f, out);
|
|
590
|
-
//out << ( " is ");
|
|
591
|
-
//serializeExpr(s, out);
|
|
592
546
|
sql += '(' + left + ' is ' + right + ')';
|
|
593
547
|
parameter.push.apply(parameter, pLeft);
|
|
594
548
|
parameter.push.apply(parameter, pRight);
|
|
595
549
|
} else {
|
|
596
|
-
//serializeExpr(f, out);
|
|
597
|
-
//out << ( " = ");
|
|
598
|
-
//serializeExpr(s, out);
|
|
599
550
|
sql += '(' + left + ' = ' + right + ')';
|
|
600
551
|
parameter.push.apply(parameter, pLeft);
|
|
601
552
|
parameter.push.apply(parameter, pRight);
|
|
602
553
|
}
|
|
603
554
|
} else if (op === exports.NE) {
|
|
604
555
|
if (_null) {
|
|
605
|
-
//serializeExpr(f, out);
|
|
606
|
-
//out << ( " is not ");
|
|
607
|
-
//serializeExpr(s, out);
|
|
608
556
|
sql += '(' + left + ' is not ' + right + ')';
|
|
609
557
|
parameter.push.apply(parameter, pLeft);
|
|
610
558
|
parameter.push.apply(parameter, pRight);
|
|
611
559
|
} else {
|
|
612
|
-
//out << "(";
|
|
613
|
-
//serializeExpr(f, out);
|
|
614
|
-
//out << "!=";
|
|
615
|
-
//serializeExpr(s, out);
|
|
616
|
-
//out << " or ";
|
|
617
|
-
//serializeExpr(f, out);
|
|
618
|
-
//out << " is null)";
|
|
619
560
|
sql += '(' + left + ' != ' + right + ' or ' + left + ' is null)';
|
|
620
561
|
parameter.push.apply(parameter, pLeft);
|
|
621
562
|
parameter.push.apply(parameter, pRight);
|
|
@@ -705,14 +646,6 @@ BinaryOperator.prototype.toSqlHana = function toSqlHana(context, parameter) {
|
|
|
705
646
|
let sql = '';
|
|
706
647
|
switch (this.op) {
|
|
707
648
|
case exports.EQ :
|
|
708
|
-
if (this.strict || context.oDataNullSupport !== true) {
|
|
709
|
-
sql += '(' + left + exports.binarySqlMapping[this.op] + right + ')';
|
|
710
|
-
parameter.push.apply(parameter, pLeft);
|
|
711
|
-
parameter.push.apply(parameter, pRight);
|
|
712
|
-
break;
|
|
713
|
-
}
|
|
714
|
-
sql += complexBinaryWithNull(this.left, this.op, this.right, context, parameter);
|
|
715
|
-
break;
|
|
716
649
|
case exports.NE : //special case
|
|
717
650
|
if (this.strict || context.oDataNullSupport !== true) {
|
|
718
651
|
sql += '(' + left + exports.binarySqlMapping[this.op] + right + ')';
|
|
@@ -724,7 +657,6 @@ BinaryOperator.prototype.toSqlHana = function toSqlHana(context, parameter) {
|
|
|
724
657
|
break;
|
|
725
658
|
case exports.OR :
|
|
726
659
|
case exports.AND :
|
|
727
|
-
|
|
728
660
|
case exports.GE :
|
|
729
661
|
case exports.LE :
|
|
730
662
|
case exports.GT :
|
|
@@ -785,9 +717,9 @@ function Method(method, parameter) {
|
|
|
785
717
|
}
|
|
786
718
|
|
|
787
719
|
Method.prototype.setAlias = function (alias) {
|
|
788
|
-
for (
|
|
789
|
-
if (
|
|
790
|
-
|
|
720
|
+
for (const param of this.parameter) {
|
|
721
|
+
if (param.setAlias) {
|
|
722
|
+
param.setAlias(alias);
|
|
791
723
|
}
|
|
792
724
|
}
|
|
793
725
|
};
|
|
@@ -1134,8 +1066,8 @@ OrderBy.prototype.applyConverter = function (convert) {
|
|
|
1134
1066
|
};
|
|
1135
1067
|
|
|
1136
1068
|
OrderBy.prototype.setAlias = function (alias) {
|
|
1137
|
-
for (
|
|
1138
|
-
|
|
1069
|
+
for (const order of this.orders) {
|
|
1070
|
+
order.setAlias(alias);
|
|
1139
1071
|
}
|
|
1140
1072
|
};
|
|
1141
1073
|
|
package/lib/utils/utils.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const InternalError = require('./../utils/errors/internalError');
|
|
4
|
+
const XsODataError = require('./../utils/errors/xsODataError');
|
|
5
|
+
const Measurement = require('./measurement');
|
|
6
|
+
const uriType = require('../uri/uriType');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Checks weather a schema is allowed to be used directly in the xsodata file. E.g. for cross schema access
|
|
@@ -22,10 +22,10 @@ exports.injectContext = function (context) {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
exports.try = function (fn /* and more args */) {
|
|
25
|
-
|
|
25
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
26
26
|
|
|
27
27
|
return function (context, asyncDone) {
|
|
28
|
-
|
|
28
|
+
const args1 = Array.prototype.slice.call(arguments);
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
31
|
return fn.apply(null, args.concat(args1));
|
|
@@ -40,8 +40,8 @@ exports.try = function (fn /* and more args */) {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
exports.tryAndMeasure = function (/* fn, and more args , name */) {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const args = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
|
|
44
|
+
const name = arguments[arguments.length - 1];
|
|
45
45
|
|
|
46
46
|
return Measurement.measureAsync(exports.try.apply(null, args), name);
|
|
47
47
|
};
|
|
@@ -66,8 +66,8 @@ exports.ensureSlashEnding = function (path) {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
exports.getObjectPropertiesAsList = function (object) {
|
|
69
|
-
|
|
70
|
-
for (
|
|
69
|
+
const list = [];
|
|
70
|
+
for (const property in object) {
|
|
71
71
|
if (object.hasOwnProperty(property)) {
|
|
72
72
|
list.push(object[property]);
|
|
73
73
|
}
|
|
@@ -135,13 +135,13 @@ exports.iterateObject = function iterateObject(context, callback, options) {
|
|
|
135
135
|
|
|
136
136
|
// Loop over object keys and find properties which could be prefixed
|
|
137
137
|
// with namespaces
|
|
138
|
-
for (
|
|
138
|
+
for (const key in context) {
|
|
139
139
|
|
|
140
140
|
if (context.hasOwnProperty(key)) {
|
|
141
141
|
|
|
142
142
|
options.$currentKeyPath.push(key);
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
let callbackResult = true;
|
|
145
145
|
|
|
146
146
|
// If any filter function is provided we use that filter to call
|
|
147
147
|
// the callback only on filter(...) === true properties
|
|
@@ -163,7 +163,7 @@ exports.iterateObject = function iterateObject(context, callback, options) {
|
|
|
163
163
|
// Check property object value. If it's an object we will
|
|
164
164
|
// iterate through all nested objects recursive
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
const value = context[key];
|
|
167
167
|
|
|
168
168
|
/*jshint eqnull:true */
|
|
169
169
|
if (value != null) {
|
|
@@ -192,7 +192,7 @@ exports.hasProperties = function hasProperties(obj) {
|
|
|
192
192
|
return false;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
for (
|
|
195
|
+
for (const key in obj) {
|
|
196
196
|
if (obj.hasOwnProperty(key)) {
|
|
197
197
|
return true;
|
|
198
198
|
}
|
|
@@ -247,8 +247,8 @@ exports.getRandomInt = function getRandomInt(min, max) {
|
|
|
247
247
|
};
|
|
248
248
|
|
|
249
249
|
// requests, for which ETag property/header must be generated
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
const requestsWithETagHeader = { GET: {}, POST: {}, PUT: {} };
|
|
251
|
+
let requestsWithETagProperty;
|
|
252
252
|
|
|
253
253
|
requestsWithETagHeader.GET[uriType.URI2] = true;
|
|
254
254
|
requestsWithETagHeader.GET[uriType.URI5A] = true;
|
|
@@ -284,7 +284,7 @@ exports.isETagHeaderRequired = function isETagHeaderRequired(context, dbSegment)
|
|
|
284
284
|
};
|
|
285
285
|
|
|
286
286
|
function isETagRequiredForRequest(context, dbSegment, requestsWithETag) {
|
|
287
|
-
|
|
287
|
+
let urisWithETag;
|
|
288
288
|
|
|
289
289
|
if (!dbSegment.entityType.hasConcurrentProperties()) {
|
|
290
290
|
return false;
|
|
@@ -316,13 +316,12 @@ exports.compareDBVersion = (a, b, fixedTo) => {
|
|
|
316
316
|
A[i] = Number.parseInt(A[i]);
|
|
317
317
|
B[i] = Number.parseInt(B[i]);
|
|
318
318
|
}
|
|
319
|
-
if (a === b
|
|
320
|
-
|
|
321
|
-
} else if ((fixedTo <= 0) && (A[0] > B[0]) ||
|
|
319
|
+
if (a === b ||
|
|
320
|
+
((fixedTo <= 0) && (A[0] > B[0]) ||
|
|
322
321
|
(fixedTo <= 1) && (A[0] === B[0] && A[1] > B[1]) ||
|
|
323
322
|
(fixedTo <= 2) && (A[0] === B[0] && A[1] === B[1] && A[2] > B[2]) ||
|
|
324
323
|
(fixedTo <= 3) && (A[0] === B[0] && A[1] === B[1] && A[2] === B[2] && A[3] > B[3]) ||
|
|
325
|
-
(fixedTo <= 4) && (A[0] === B[0] && A[1] === B[1] && A[2] === B[2] && A[3] === B[3] && A[4] > B[4])) {
|
|
324
|
+
(fixedTo <= 4) && (A[0] === B[0] && A[1] === B[1] && A[2] === B[2] && A[3] === B[3] && A[4] > B[4]))) {
|
|
326
325
|
return exports.VERSION_A_COVERS_VERSION_B;
|
|
327
326
|
}
|
|
328
327
|
return exports.VERSIONS_DIFFERENT;
|
|
@@ -330,8 +329,6 @@ exports.compareDBVersion = (a, b, fixedTo) => {
|
|
|
330
329
|
|
|
331
330
|
exports.VERSION_A_COVERS_VERSION_B = 1;
|
|
332
331
|
exports.VERSIONS_DIFFERENT = -1;
|
|
333
|
-
|
|
334
|
-
|
|
335
332
|
exports.NO_FIX_PART = 0;
|
|
336
333
|
exports.SAME_1ST_HANA_REL = 1;
|
|
337
334
|
exports.SAME_2ND = 2;
|
package/lib/xsodata.js
CHANGED
|
@@ -1,57 +1,47 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const async = require('async');
|
|
4
4
|
|
|
5
5
|
//contexts
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const NetworkContext = require('./utils/networkContext');
|
|
7
|
+
const RequestContext = require('./utils/requestContext');
|
|
8
8
|
|
|
9
9
|
//processing steps
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
const db = require('./db/connect');
|
|
11
|
+
const uriParser = require('./http/uriParser');
|
|
12
|
+
const xsodataFileReader = require('./model/xsodataReader');
|
|
13
|
+
const metadataDbReader = require('./model/metadataReader');
|
|
14
|
+
const oDataUriParser = require('./uri/oDataUriParser');
|
|
15
|
+
const uriChecks = require('./uri/checks');
|
|
16
|
+
const applyUriChecks = require('./uri/applyChecks');
|
|
17
|
+
const oDataProcessor = require('./processor/processor');
|
|
18
|
+
const errorProcessor = require('./processor/errorProcessor');
|
|
19
|
+
const ConditionalHttpHandler = require('./http/conditionalHttpHandler');
|
|
20
|
+
const httpRequestValidator = require('./http/validator/httpRequestValidator');
|
|
21
|
+
const authorizationProcessor = require('./processor/authorizationProcessor');
|
|
22
|
+
const tableCleanup = require('./utils/tableCleanup');
|
|
23
|
+
const packageJson = require('../package.json');
|
|
24
24
|
|
|
25
25
|
//Tools
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
const Logger = require('./utils/logger');
|
|
27
|
+
const configuration = require('./configuration');
|
|
28
|
+
const handlerConfiguration = require('./handlerConfiguration');
|
|
29
|
+
const JsonSerializer = require('./serializer/jsonSerializer').JsonSerializer;
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const simpleRequest = require('./http/simpleHttpRequest');
|
|
32
|
+
const simpleResponse = require('./http/simpleHttpResponse');
|
|
33
|
+
const utils = require('./utils/utils');
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const debugView = require('./utils/debugView');
|
|
36
|
+
const Measurement = require('./utils/measurement');
|
|
37
37
|
|
|
38
38
|
//Errors
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// segmentation fault check
|
|
43
|
-
// var SegfaultHandler = require('segfault-handler');
|
|
44
|
-
// SegfaultHandler.registerHandler('crash.log');
|
|
45
|
-
// SegfaultHandler.causeSegfault();
|
|
39
|
+
const HttpErrorDebugInfo = require('./utils/errors/debugInfo');
|
|
40
|
+
const InternalError = require('./utils/errors/internalError');
|
|
46
41
|
|
|
47
42
|
global.execCounter = 0;
|
|
48
43
|
global.dropCounter = 0;
|
|
49
44
|
|
|
50
|
-
// process.on('exit', () => {
|
|
51
|
-
// console.log(`global.execCounter: ${global.execCounter}`);
|
|
52
|
-
// console.log(`global.dropCounter: ${global.dropCounter}`);
|
|
53
|
-
// });
|
|
54
|
-
|
|
55
45
|
exports.testExits = {
|
|
56
46
|
afterConnectDb: 1,
|
|
57
47
|
afterPrepareUri: 2,
|
|
@@ -84,7 +74,7 @@ exports.ODataHandler.prototype.register = function (step, callBack) {
|
|
|
84
74
|
|
|
85
75
|
function checkRegisteredSteps(step, err, context, asyncDone) {
|
|
86
76
|
try {
|
|
87
|
-
|
|
77
|
+
const done = function (err1) {
|
|
88
78
|
if (err1) {
|
|
89
79
|
context.logger.debug('xsodata', 'Developer exit "' + step + '" returned with error:');
|
|
90
80
|
context.logger.debug('xsodata', err1.message);
|
|
@@ -122,7 +112,7 @@ function checkRegisteredSteps(step, err, context, asyncDone) {
|
|
|
122
112
|
* @returns { Array }
|
|
123
113
|
*/
|
|
124
114
|
exports.ODataHandler.prototype.createRequestChain = function (context) {
|
|
125
|
-
|
|
115
|
+
let ret;
|
|
126
116
|
if (Measurement.isActive()) {
|
|
127
117
|
ret = [
|
|
128
118
|
utils.injectContext(context),
|
|
@@ -216,9 +206,9 @@ exports.ODataHandler.prototype.createRequestChain = function (context) {
|
|
|
216
206
|
* @param applicationDone Callback call after request is processed. Signature ( err : Object, context : Object )
|
|
217
207
|
*/
|
|
218
208
|
exports.ODataHandler.prototype.processRequest = function(request, response, requestOptions, applicationDone) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
209
|
+
let networkContext;
|
|
210
|
+
let context;
|
|
211
|
+
let baseMeasurement;
|
|
222
212
|
|
|
223
213
|
try {
|
|
224
214
|
networkContext = new NetworkContext(this.handlerConfiguration, requestOptions);
|
|
@@ -290,7 +280,7 @@ exports.ODataHandler.prototype.processRequest = function(request, response, requ
|
|
|
290
280
|
);
|
|
291
281
|
|
|
292
282
|
} catch (exception) {
|
|
293
|
-
|
|
283
|
+
const err = new InternalError('InternalError', context, exception);
|
|
294
284
|
tableCleanup.assertCleanTempTables(context, function (error, context) {
|
|
295
285
|
return this.saveExit(error || err, context, applicationDone);
|
|
296
286
|
}.bind(this));
|
|
@@ -306,7 +296,7 @@ exports.ODataHandler.prototype.saveExit = function (err, context, applicationDon
|
|
|
306
296
|
if (err) {
|
|
307
297
|
if (err instanceof HttpErrorDebugInfo) {
|
|
308
298
|
//render debug info to response
|
|
309
|
-
|
|
299
|
+
const serializer = new JsonSerializer(context, 65536, 200);
|
|
310
300
|
serializer.write(err.message);
|
|
311
301
|
serializer.flush();
|
|
312
302
|
} else {
|
|
@@ -343,8 +333,8 @@ exports.ODataHandler.prototype.finish = function (err, context, applicationDone)
|
|
|
343
333
|
context.logger.silly('xsodata', 'finish');
|
|
344
334
|
|
|
345
335
|
return checkRegisteredSteps(exports.testExits.beforeSendHandler, err, context, function (err, context) {
|
|
346
|
-
|
|
347
|
-
|
|
336
|
+
const rTo = context.httpResponse;
|
|
337
|
+
const rFrom = context.response;
|
|
348
338
|
|
|
349
339
|
if (context.debugView && context.isAuthorized === true) {
|
|
350
340
|
debugView.writeDebugInfo(context, rFrom, rTo);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/xsodata",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.1",
|
|
4
4
|
"description": "Expose data from a HANA database as OData V2 service with help of .xsodata files.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"license": "SEE LICENSE IN developer-license-3.1.txt",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"unit-tests": "node ./node_modules/mocha/bin/_mocha test/**/test*.js",
|
|
18
18
|
"cover-unit-tests": "nyc --reporter=text --reporter=html --all --include lib/ npm run unit-tests",
|
|
19
19
|
"cover-scenario-tests": "nyc --reporter=text --reporter=html --all --include lib/ --check-coverage true --lines 80 --branches 68 --functions 86 --statements 80 npm run scenario-tests",
|
|
20
|
-
"cover-jenkins": "nyc --reporter=text --reporter=html --all --include lib/ --check-coverage true --lines 80 --branches 68 --functions 86 --statements 80 npm run all-tests-jenkins",
|
|
20
|
+
"cover-jenkins": "nyc --reporter=text --reporter=html --reporter=lcov --report-dir=.nyc_output --all --include lib/ --check-coverage true --lines 80 --branches 68 --functions 86 --statements 80 npm run all-tests-jenkins",
|
|
21
21
|
"report": "npm run get-jwt && node ./node_modules/mocha/bin/_mocha test/**/test*.js test_apps/test_**/**/test*.js --reporter mocha-simple-html-reporter --reporter-options output=report_all.html",
|
|
22
22
|
"report-unit-tests": "node ./node_modules/mocha/bin/_mocha test/**/test*.js --reporter mocha-simple-html-reporter --reporter-options output=report_unit.html",
|
|
23
23
|
"report-scenario-tests": "npm run get-jwt && node ./node_modules/mocha/bin/_mocha test_apps/test_**/**/test*.js --reporter mocha-simple-html-reporter --reporter-options output=report_scenario.html",
|
|
@@ -41,33 +41,31 @@
|
|
|
41
41
|
],
|
|
42
42
|
"files": [
|
|
43
43
|
"index.js",
|
|
44
|
-
"npm-shrinkwrap.json",
|
|
45
44
|
"CHANGELOG.md",
|
|
46
45
|
"documentation",
|
|
47
46
|
"developer-license-3.1.txt",
|
|
48
|
-
"lib"
|
|
49
|
-
".npmignore"
|
|
47
|
+
"lib"
|
|
50
48
|
],
|
|
51
49
|
"dependencies": {
|
|
52
|
-
"@sap/xsenv": "5.
|
|
50
|
+
"@sap/xsenv": "5.6.1",
|
|
53
51
|
"@sap/xssec": "3.6.2",
|
|
54
52
|
"async": "3.2.6",
|
|
55
|
-
"big.js": "
|
|
56
|
-
"body-parser": "1.20.
|
|
53
|
+
"big.js": "7.0.1",
|
|
54
|
+
"body-parser": "1.20.4",
|
|
57
55
|
"hdb": "0.19.12",
|
|
58
|
-
"lodash": "4.17.
|
|
56
|
+
"lodash": "4.17.23",
|
|
59
57
|
"negotiator": "1.0.0",
|
|
60
58
|
"rwlock": "5.0.0",
|
|
61
59
|
"xml-writer": "1.7.0"
|
|
62
60
|
},
|
|
63
61
|
"engines": {
|
|
64
|
-
"node": "^18 || ^20 || ^22"
|
|
62
|
+
"node": "^18 || ^20 || ^22 || ^24"
|
|
65
63
|
},
|
|
66
64
|
"devDependencies": {
|
|
67
65
|
"@sap/hana-client": "2.24.21",
|
|
68
66
|
"chai": "4.3.10",
|
|
69
67
|
"expect": "1.20.2",
|
|
70
|
-
"filter-node-package": "
|
|
68
|
+
"filter-node-package": "6.0.0",
|
|
71
69
|
"jison": "0.4.18",
|
|
72
70
|
"jshint": "2.13.6",
|
|
73
71
|
"mocha": "10.7.3",
|
package/.npmignore
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
#---
|
|
2
|
-
#---ingnore all directories starting with an underscore
|
|
3
|
-
#---
|
|
4
|
-
**/_*/
|
|
5
|
-
|
|
6
|
-
#---
|
|
7
|
-
#---ingnore and folders/files ending with ...
|
|
8
|
-
#---
|
|
9
|
-
**.priv.json
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
#---
|
|
13
|
-
#---ingnore the folders ...
|
|
14
|
-
#---
|
|
15
|
-
|
|
16
|
-
.idea/
|
|
17
|
-
*.iml
|
|
18
|
-
.jobinfo/
|
|
19
|
-
internal/
|
|
20
|
-
node_modules/
|
|
21
|
-
test/
|
|
22
|
-
test_apps/
|
|
23
|
-
.cfignore
|
|
24
|
-
.opensourcy.config.txt
|
|
25
|
-
.editorconfig
|
|
26
|
-
.gitattributes
|
|
27
|
-
.gitignore
|
|
28
|
-
.jshintignore
|
|
29
|
-
.jshintrc
|
|
30
|
-
.npmignore
|
|
31
|
-
.travis.yml
|
|
32
|
-
.xmake.cfg
|
|
33
|
-
manifest.yml
|
|
34
|
-
npm-debug.log
|
|
35
|
-
default-services.json
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|