@shko.online/dataverse-odata 0.1.1 → 0.1.2

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/lib/cjs/getExpandFromParser.js +15 -15
  3. package/lib/cjs/getFetchXmlFromParser.js +13 -6
  4. package/lib/cjs/getOrderByFromParser.js +44 -0
  5. package/lib/cjs/getSelectFromParser.js +3 -3
  6. package/lib/cjs/getTopFromParser.js +9 -5
  7. package/lib/cjs/getXQueryFromParser.js +35 -0
  8. package/lib/cjs/index.js +42 -0
  9. package/lib/cjs/parseOData.js +11 -4
  10. package/lib/cjs/validateNotEmpty.js +17 -0
  11. package/lib/esm/getExpandFromParser.js +15 -15
  12. package/lib/esm/getFetchXmlFromParser.js +13 -6
  13. package/lib/esm/getOrderByFromParser.js +37 -0
  14. package/lib/esm/getSelectFromParser.js +3 -3
  15. package/lib/esm/getTopFromParser.js +10 -5
  16. package/lib/esm/getXQueryFromParser.js +28 -0
  17. package/lib/esm/index.js +6 -0
  18. package/lib/esm/parseOData.js +11 -4
  19. package/lib/esm/validateNotEmpty.js +10 -0
  20. package/lib/modern/getExpandFromParser.js +15 -15
  21. package/lib/modern/getFetchXmlFromParser.js +13 -6
  22. package/lib/modern/getOrderByFromParser.js +38 -0
  23. package/lib/modern/getSelectFromParser.js +3 -3
  24. package/lib/modern/getTopFromParser.js +10 -5
  25. package/lib/modern/getXQueryFromParser.js +28 -0
  26. package/lib/modern/index.js +6 -0
  27. package/lib/modern/parseOData.js +11 -4
  28. package/lib/modern/validateNotEmpty.js +10 -0
  29. package/lib/ts3.4/getExpandFromParser.d.ts +2 -2
  30. package/lib/ts3.4/getFetchXmlFromParser.d.ts +2 -2
  31. package/lib/ts3.4/getOrderByFromParser.d.ts +7 -0
  32. package/lib/ts3.4/getSelectFromParser.d.ts +2 -2
  33. package/lib/ts3.4/getTopFromParser.d.ts +2 -2
  34. package/lib/ts3.4/getXQueryFromParser.d.ts +8 -0
  35. package/lib/ts3.4/index.d.ts +6 -0
  36. package/lib/ts3.4/validateNotEmpty.d.ts +3 -0
  37. package/lib/ts3.9/getExpandFromParser.d.ts +2 -2
  38. package/lib/ts3.9/getFetchXmlFromParser.d.ts +2 -2
  39. package/lib/ts3.9/getFetchXmlFromParser.d.ts.map +1 -1
  40. package/lib/ts3.9/getOrderByFromParser.d.ts +7 -0
  41. package/lib/ts3.9/getOrderByFromParser.d.ts.map +1 -0
  42. package/lib/ts3.9/getSelectFromParser.d.ts +2 -2
  43. package/lib/ts3.9/getSelectFromParser.d.ts.map +1 -1
  44. package/lib/ts3.9/getTopFromParser.d.ts +2 -2
  45. package/lib/ts3.9/getTopFromParser.d.ts.map +1 -1
  46. package/lib/ts3.9/getXQueryFromParser.d.ts +8 -0
  47. package/lib/ts3.9/getXQueryFromParser.d.ts.map +1 -0
  48. package/lib/ts3.9/index.d.ts +6 -0
  49. package/lib/ts3.9/index.d.ts.map +1 -1
  50. package/lib/ts3.9/parseOData.d.ts.map +1 -1
  51. package/lib/ts3.9/validateNotEmpty.d.ts +3 -0
  52. package/lib/ts3.9/validateNotEmpty.d.ts.map +1 -0
  53. package/package.json +1 -1
  54. package/src/OData.types.d.ts +78 -3
  55. package/src/getExpandFromParser.ts +15 -15
  56. package/src/getFetchXmlFromParser.ts +15 -7
  57. package/src/getOrderByFromParser.ts +42 -0
  58. package/src/getSelectFromParser.ts +4 -4
  59. package/src/getTopFromParser.ts +11 -7
  60. package/src/getXQueryFromParser.ts +34 -0
  61. package/src/index.ts +7 -0
  62. package/src/parseOData.ts +11 -4
  63. package/src/validateNotEmpty.ts +12 -0
  64. package/jest.config.ts +0 -12
  65. package/lib/getExpandFromParser.d.ts +0 -7
  66. package/lib/getExpandFromParser.d.ts.map +0 -1
  67. package/lib/getExpandFromParser.js +0 -97
  68. package/lib/getExpandFromParser.js.map +0 -1
  69. package/lib/getFetchXmlFromParser.d.ts +0 -7
  70. package/lib/getFetchXmlFromParser.d.ts.map +0 -1
  71. package/lib/getFetchXmlFromParser.js +0 -41
  72. package/lib/getFetchXmlFromParser.js.map +0 -1
  73. package/lib/getSelectFromParser.d.ts +0 -7
  74. package/lib/getSelectFromParser.d.ts.map +0 -1
  75. package/lib/getSelectFromParser.js +0 -12
  76. package/lib/getSelectFromParser.js.map +0 -1
  77. package/lib/getTopFromParser.d.ts +0 -7
  78. package/lib/getTopFromParser.d.ts.map +0 -1
  79. package/lib/getTopFromParser.js +0 -27
  80. package/lib/getTopFromParser.js.map +0 -1
  81. package/lib/index.d.ts +0 -5
  82. package/lib/index.d.ts.map +0 -1
  83. package/lib/index.js +0 -4
  84. package/lib/index.js.map +0 -1
  85. package/lib/parseOData.d.ts +0 -3
  86. package/lib/parseOData.d.ts.map +0 -1
  87. package/lib/parseOData.js +0 -22
  88. package/lib/parseOData.js.map +0 -1
  89. package/tests/OData-Parser.$expand.test.ts +0 -39
  90. package/tests/OData-Parser.$top.test.ts +0 -36
  91. package/tests/OData-Parser.fetchXml.test.ts +0 -62
  92. package/tests/OData-Parser.test.ts +0 -17
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.1.2](https://github.com/shko-online/dataverse-odata/compare/v0.1.1...v0.1.2) (2023-02-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Improved documentation ([720fb93](https://github.com/shko-online/dataverse-odata/commit/720fb93a6d330ea51ba262019543519a6255af02))
7
+
1
8
  ## [0.1.1](https://github.com/shko-online/dataverse-odata/compare/v0.1.0...v0.1.1) (2023-02-11)
2
9
 
3
10
 
@@ -6,18 +6,18 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getExpandFromParser = void 0;
7
7
  var _getSelectFromParser = require("./getSelectFromParser");
8
8
  /**
9
- * Parses the $expand query
10
- * @returns Returns true when the parse has an error
9
+ * Parses the {@link ODataExpand.$expand $expand} query
10
+ * @returns Returns `false` when the parse has an error
11
11
  */
12
12
  const getExpandFromParser = (parser, result) => {
13
13
  const $expand = parser.get('$expand');
14
14
  if ($expand !== null) {
15
15
  result.$expand = {};
16
- if (extractExpand($expand, result)) {
17
- return true;
16
+ if (!extractExpand($expand, result)) {
17
+ return false;
18
18
  }
19
19
  }
20
- return false;
20
+ return true;
21
21
  };
22
22
  exports.getExpandFromParser = getExpandFromParser;
23
23
  const extractExpand = (value, $expand) => {
@@ -27,7 +27,7 @@ const extractExpand = (value, $expand) => {
27
27
  code: '0x0',
28
28
  message: 'invalid expand expression'
29
29
  };
30
- return true;
30
+ return false;
31
31
  }
32
32
  let matchSeparator = match[3];
33
33
  let matchLength = match[0].length;
@@ -47,25 +47,25 @@ const extractExpand = (value, $expand) => {
47
47
  code: '0x0',
48
48
  message: error
49
49
  };
50
- return true;
50
+ return false;
51
51
  }
52
52
  if ($expand.$expand !== undefined) {
53
53
  const innerExpand = {};
54
54
  const parser = new URLSearchParams('?' + value.substring(matchLength, matchLength + index));
55
- if ((0, _getSelectFromParser.getSelectFromParser)(parser, innerExpand)) {
55
+ if (!(0, _getSelectFromParser.getSelectFromParser)(parser, innerExpand)) {
56
56
  $expand.error = innerExpand.error;
57
- return true;
57
+ return false;
58
58
  }
59
- if (getExpandFromParser(parser, innerExpand)) {
59
+ if (!getExpandFromParser(parser, innerExpand)) {
60
60
  $expand.error = innerExpand.error;
61
- return true;
61
+ return false;
62
62
  }
63
63
  if (innerExpand.$expand === undefined && innerExpand.$select === undefined) {
64
64
  $expand.error = {
65
65
  code: '0x0',
66
66
  message: 'Empty expand'
67
67
  };
68
- return true;
68
+ return false;
69
69
  }
70
70
  $expand.$expand[match[1]] = innerExpand;
71
71
  }
@@ -79,11 +79,11 @@ const extractExpand = (value, $expand) => {
79
79
  }
80
80
  }
81
81
  if (matchSeparator === ',') {
82
- if (extractExpand(value.substring(matchLength), $expand)) {
83
- return true;
82
+ if (!extractExpand(value.substring(matchLength), $expand)) {
83
+ return false;
84
84
  }
85
85
  }
86
- return false;
86
+ return true;
87
87
  };
88
88
  const getClosingBracket = value => {
89
89
  let depth = 1;
@@ -5,12 +5,19 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getFetchXmlFromParser = void 0;
7
7
  /**
8
- * Parses the fetchXml query
9
- * @returns Returns true when the parse has an error
8
+ * Parses the {@link ODataFetch.fetchXml fetchXml} query
9
+ * @returns Returns `false` when the parse has an error
10
10
  */
11
11
  const getFetchXmlFromParser = (parser, result) => {
12
12
  const fetchXml = parser.get('fetchXml');
13
13
  if (fetchXml !== null) {
14
+ if (fetchXml === '') {
15
+ result.error = {
16
+ code: '0x80040203',
17
+ message: 'Expected non-empty string.'
18
+ };
19
+ return false;
20
+ }
14
21
  const serializer = new DOMParser();
15
22
  const fetchXmlDocument = serializer.parseFromString(fetchXml, 'text/xml');
16
23
  if (fetchXmlDocument.documentElement.tagName === 'parsererror') {
@@ -18,7 +25,7 @@ const getFetchXmlFromParser = (parser, result) => {
18
25
  code: '0x80040201',
19
26
  message: 'Invalid XML.'
20
27
  };
21
- return true;
28
+ return false;
22
29
  }
23
30
  const entity = fetchXmlDocument.evaluate('fetch/entity', fetchXmlDocument, null, XPathResult.ANY_TYPE, null).iterateNext();
24
31
  if (fetchXmlDocument.documentElement.children.length != 1 || !entity || !entity.getAttribute('name')) {
@@ -26,7 +33,7 @@ const getFetchXmlFromParser = (parser, result) => {
26
33
  code: '0x80041102',
27
34
  message: 'Entity Name was not specified in FetchXml String.'
28
35
  };
29
- return true;
36
+ return false;
30
37
  }
31
38
  const invalidAttribute = fetchXmlDocument.evaluate('fetch/entity/*[not(self::filter or self::order or self::link-entity or self::attribute or self::all-attributes or self::no-attrs)]', fetchXmlDocument, null, XPathResult.ANY_TYPE, null).iterateNext();
32
39
  if (invalidAttribute) {
@@ -34,10 +41,10 @@ const getFetchXmlFromParser = (parser, result) => {
34
41
  code: '0x8004111c',
35
42
  message: `Invalid Child Node, valid nodes are filter, order, link-entity, attribute, all-attributes, no-attrs. NodeName = ${invalidAttribute.tagName} NodeXml = ${invalidAttribute.outerHTML}`
36
43
  };
37
- return true;
44
+ return false;
38
45
  }
39
46
  result.fetchXml = fetchXmlDocument;
40
47
  }
41
- return false;
48
+ return true;
42
49
  };
43
50
  exports.getFetchXmlFromParser = getFetchXmlFromParser;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getOrderByFromParser = void 0;
7
+ var _validateNotEmpty = require("./validateNotEmpty");
8
+ const edmProperty = /\w{1-255}/gi;
9
+
10
+ /**
11
+ * Parses the {@link ODataOrderBy.$orderby $orderby} query
12
+ * @returns Returns `false` when the parse has an error
13
+ */
14
+ const getOrderByFromParser = (parser, result) => {
15
+ let $orderby = parser.get('$orderby');
16
+ if ($orderby !== null) {
17
+ if (!(0, _validateNotEmpty.validateNotEmpty)('$orderby', $orderby, result)) {
18
+ return false;
19
+ }
20
+ $orderby = $orderby.trimEnd();
21
+ const orderByArray = [];
22
+ for (let i = 0; i < $orderby.length; i++) {
23
+ if (false /* syntax error */) {
24
+ result.error = {
25
+ code: '0x0',
26
+ message: `Syntax error at position ${i} in '${$orderby}'.`
27
+ };
28
+ return false;
29
+ }
30
+ }
31
+ orderByArray.forEach(orderBy => {
32
+ if (!orderBy.column?.match(edmProperty)) {
33
+ result.error = {
34
+ code: '0x80060888',
35
+ message: 'Order By Property must be of type EdmProperty'
36
+ };
37
+ return false;
38
+ }
39
+ });
40
+ result.$orderby = orderByArray;
41
+ }
42
+ return true;
43
+ };
44
+ exports.getOrderByFromParser = getOrderByFromParser;
@@ -5,14 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getSelectFromParser = void 0;
7
7
  /**
8
- * Parses the $select query
9
- * @returns Returns true when the parse has an error
8
+ * Parses the {@link ODataSelect.$select $select} query
9
+ * @returns Returns `false` when the parse has an error
10
10
  */
11
11
  const getSelectFromParser = (parser, result) => {
12
12
  const $select = parser.get('$select');
13
13
  if ($select !== null) {
14
14
  result.$select = $select.split(',');
15
15
  }
16
- return false;
16
+ return true;
17
17
  };
18
18
  exports.getSelectFromParser = getSelectFromParser;
@@ -4,29 +4,33 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getTopFromParser = void 0;
7
+ var _validateNotEmpty = require("./validateNotEmpty");
7
8
  /**
8
- * Parses the $top query
9
- * @returns Returns true when the parse has an error
9
+ * Parses the {@link ODataTop.$top $top} query
10
+ * @returns Returns `false` when the parse has an error
10
11
  */
11
12
  const getTopFromParser = (parser, result) => {
12
13
  const $topValue = parser.get('$top');
13
14
  if ($topValue !== null) {
15
+ if (!(0, _validateNotEmpty.validateNotEmpty)('$orderby', $topValue, result)) {
16
+ return false;
17
+ }
14
18
  let $top;
15
19
  if (!$topValue.match(/^\d+$/) || ($top = parseInt($topValue)) < 0) {
16
20
  result.error = {
17
21
  code: '0x0',
18
22
  message: `Invalid value '${$topValue}' for $top query option found. The $top query option requires a non-negative integer value.`
19
23
  };
20
- return true;
24
+ return false;
21
25
  } else if ($top === 0) {
22
26
  result.error = {
23
27
  code: '0x0',
24
28
  message: `Invalid value for $top query option.`
25
29
  };
26
- return true;
30
+ return false;
27
31
  }
28
32
  result.$top = $top;
29
33
  }
30
- return false;
34
+ return true;
31
35
  };
32
36
  exports.getTopFromParser = getTopFromParser;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getXQueryFromParser = void 0;
7
+ const guidRegex = /[0-9A-F]{8}\-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/gi;
8
+
9
+ /**
10
+ * Parses the {@link ODataSavedQuery.savedQuery savedQuery} or
11
+ * {@link ODataUserQuery.userQuery userQuery} query
12
+ * @returns Returns `false` when the parse has an error
13
+ */
14
+ const getXQueryFromParser = (X, parser, result) => {
15
+ const xQuery = parser.get(X);
16
+ if (xQuery !== null) {
17
+ if (!xQuery.trim()) {
18
+ result.error = {
19
+ code: '0x0',
20
+ message: 'Unrecognized Guid format.'
21
+ };
22
+ return false;
23
+ }
24
+ if (!xQuery.match(guidRegex)) {
25
+ result.error = {
26
+ code: '0x0',
27
+ message: 'Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).'
28
+ };
29
+ return false;
30
+ }
31
+ result[X] = xQuery;
32
+ }
33
+ return true;
34
+ };
35
+ exports.getXQueryFromParser = getXQueryFromParser;
package/lib/cjs/index.js CHANGED
@@ -4,12 +4,54 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ Object.defineProperty(exports, "getExpandFromParser", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _getExpandFromParser.getExpandFromParser;
11
+ }
12
+ });
13
+ Object.defineProperty(exports, "getFetchXmlFromParser", {
14
+ enumerable: true,
15
+ get: function () {
16
+ return _getFetchXmlFromParser.getFetchXmlFromParser;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, "getOrderByFromParser", {
20
+ enumerable: true,
21
+ get: function () {
22
+ return _getOrderByFromParser.getOrderByFromParser;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, "getSelectFromParser", {
26
+ enumerable: true,
27
+ get: function () {
28
+ return _getSelectFromParser.getSelectFromParser;
29
+ }
30
+ });
31
+ Object.defineProperty(exports, "getTopFromParser", {
32
+ enumerable: true,
33
+ get: function () {
34
+ return _getTopFromParser.getTopFromParser;
35
+ }
36
+ });
37
+ Object.defineProperty(exports, "getXQueryFromParser", {
38
+ enumerable: true,
39
+ get: function () {
40
+ return _getXQueryFromParser.getXQueryFromParser;
41
+ }
42
+ });
7
43
  Object.defineProperty(exports, "parseOData", {
8
44
  enumerable: true,
9
45
  get: function () {
10
46
  return _parseOData.parseOData;
11
47
  }
12
48
  });
49
+ var _getExpandFromParser = require("./getExpandFromParser");
50
+ var _getFetchXmlFromParser = require("./getFetchXmlFromParser");
51
+ var _getOrderByFromParser = require("./getOrderByFromParser");
52
+ var _getSelectFromParser = require("./getSelectFromParser");
53
+ var _getTopFromParser = require("./getTopFromParser");
54
+ var _getXQueryFromParser = require("./getXQueryFromParser");
13
55
  var _parseOData = require("./parseOData");
14
56
  var _default = _parseOData.parseOData;
15
57
  exports.default = _default;
@@ -8,6 +8,7 @@ var _getTopFromParser = require("./getTopFromParser");
8
8
  var _getSelectFromParser = require("./getSelectFromParser");
9
9
  var _getExpandFromParser = require("./getExpandFromParser");
10
10
  var _getFetchXmlFromParser = require("./getFetchXmlFromParser");
11
+ var _getXQueryFromParser = require("./getXQueryFromParser");
11
12
  /**
12
13
  * parses the OData query and applies some Dataverse validations
13
14
  * @param query The OData query
@@ -16,16 +17,22 @@ var _getFetchXmlFromParser = require("./getFetchXmlFromParser");
16
17
  const parseOData = query => {
17
18
  const parser = new URLSearchParams(query);
18
19
  const result = {};
19
- if ((0, _getExpandFromParser.getExpandFromParser)(parser, result)) {
20
+ if (!(0, _getExpandFromParser.getExpandFromParser)(parser, result)) {
20
21
  return result;
21
22
  }
22
- if ((0, _getSelectFromParser.getSelectFromParser)(parser, result)) {
23
+ if (!(0, _getSelectFromParser.getSelectFromParser)(parser, result)) {
23
24
  return result;
24
25
  }
25
- if ((0, _getTopFromParser.getTopFromParser)(parser, result)) {
26
+ if (!(0, _getTopFromParser.getTopFromParser)(parser, result)) {
26
27
  return result;
27
28
  }
28
- if ((0, _getFetchXmlFromParser.getFetchXmlFromParser)(parser, result)) {
29
+ if (!(0, _getFetchXmlFromParser.getFetchXmlFromParser)(parser, result)) {
30
+ return result;
31
+ }
32
+ if (!(0, _getXQueryFromParser.getXQueryFromParser)('savedQuery', parser, result)) {
33
+ return result;
34
+ }
35
+ if (!(0, _getXQueryFromParser.getXQueryFromParser)('userQuery', parser, result)) {
29
36
  return result;
30
37
  }
31
38
  return result;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.validateNotEmpty = void 0;
7
+ const validateNotEmpty = (query, value, result) => {
8
+ if (!value.trim()) {
9
+ result.error = {
10
+ code: '0x0',
11
+ message: `The value for OData query '${query}' cannot be empty.`
12
+ };
13
+ return false;
14
+ }
15
+ return true;
16
+ };
17
+ exports.validateNotEmpty = validateNotEmpty;
@@ -1,18 +1,18 @@
1
1
  import { getSelectFromParser } from './getSelectFromParser';
2
2
 
3
3
  /**
4
- * Parses the $expand query
5
- * @returns Returns true when the parse has an error
4
+ * Parses the {@link ODataExpand.$expand $expand} query
5
+ * @returns Returns `false` when the parse has an error
6
6
  */
7
7
  export const getExpandFromParser = (parser, result) => {
8
8
  const $expand = parser.get('$expand');
9
9
  if ($expand !== null) {
10
10
  result.$expand = {};
11
- if (extractExpand($expand, result)) {
12
- return true;
11
+ if (!extractExpand($expand, result)) {
12
+ return false;
13
13
  }
14
14
  }
15
- return false;
15
+ return true;
16
16
  };
17
17
  const extractExpand = (value, $expand) => {
18
18
  const match = value.match(/^\s*(\w(\w|\d|_)*)\s*(,|\()?\s*/);
@@ -21,7 +21,7 @@ const extractExpand = (value, $expand) => {
21
21
  code: '0x0',
22
22
  message: 'invalid expand expression'
23
23
  };
24
- return true;
24
+ return false;
25
25
  }
26
26
  let matchSeparator = match[3];
27
27
  let matchLength = match[0].length;
@@ -41,25 +41,25 @@ const extractExpand = (value, $expand) => {
41
41
  code: '0x0',
42
42
  message: error
43
43
  };
44
- return true;
44
+ return false;
45
45
  }
46
46
  if ($expand.$expand !== undefined) {
47
47
  const innerExpand = {};
48
48
  const parser = new URLSearchParams('?' + value.substring(matchLength, matchLength + index));
49
- if (getSelectFromParser(parser, innerExpand)) {
49
+ if (!getSelectFromParser(parser, innerExpand)) {
50
50
  $expand.error = innerExpand.error;
51
- return true;
51
+ return false;
52
52
  }
53
- if (getExpandFromParser(parser, innerExpand)) {
53
+ if (!getExpandFromParser(parser, innerExpand)) {
54
54
  $expand.error = innerExpand.error;
55
- return true;
55
+ return false;
56
56
  }
57
57
  if (innerExpand.$expand === undefined && innerExpand.$select === undefined) {
58
58
  $expand.error = {
59
59
  code: '0x0',
60
60
  message: 'Empty expand'
61
61
  };
62
- return true;
62
+ return false;
63
63
  }
64
64
  $expand.$expand[match[1]] = innerExpand;
65
65
  }
@@ -73,11 +73,11 @@ const extractExpand = (value, $expand) => {
73
73
  }
74
74
  }
75
75
  if (matchSeparator === ',') {
76
- if (extractExpand(value.substring(matchLength), $expand)) {
77
- return true;
76
+ if (!extractExpand(value.substring(matchLength), $expand)) {
77
+ return false;
78
78
  }
79
79
  }
80
- return false;
80
+ return true;
81
81
  };
82
82
  const getClosingBracket = value => {
83
83
  let depth = 1;
@@ -1,10 +1,17 @@
1
1
  /**
2
- * Parses the fetchXml query
3
- * @returns Returns true when the parse has an error
2
+ * Parses the {@link ODataFetch.fetchXml fetchXml} query
3
+ * @returns Returns `false` when the parse has an error
4
4
  */
5
5
  export const getFetchXmlFromParser = (parser, result) => {
6
6
  const fetchXml = parser.get('fetchXml');
7
7
  if (fetchXml !== null) {
8
+ if (fetchXml === '') {
9
+ result.error = {
10
+ code: '0x80040203',
11
+ message: 'Expected non-empty string.'
12
+ };
13
+ return false;
14
+ }
8
15
  const serializer = new DOMParser();
9
16
  const fetchXmlDocument = serializer.parseFromString(fetchXml, 'text/xml');
10
17
  if (fetchXmlDocument.documentElement.tagName === 'parsererror') {
@@ -12,7 +19,7 @@ export const getFetchXmlFromParser = (parser, result) => {
12
19
  code: '0x80040201',
13
20
  message: 'Invalid XML.'
14
21
  };
15
- return true;
22
+ return false;
16
23
  }
17
24
  const entity = fetchXmlDocument.evaluate('fetch/entity', fetchXmlDocument, null, XPathResult.ANY_TYPE, null).iterateNext();
18
25
  if (fetchXmlDocument.documentElement.children.length != 1 || !entity || !entity.getAttribute('name')) {
@@ -20,7 +27,7 @@ export const getFetchXmlFromParser = (parser, result) => {
20
27
  code: '0x80041102',
21
28
  message: 'Entity Name was not specified in FetchXml String.'
22
29
  };
23
- return true;
30
+ return false;
24
31
  }
25
32
  const invalidAttribute = fetchXmlDocument.evaluate('fetch/entity/*[not(self::filter or self::order or self::link-entity or self::attribute or self::all-attributes or self::no-attrs)]', fetchXmlDocument, null, XPathResult.ANY_TYPE, null).iterateNext();
26
33
  if (invalidAttribute) {
@@ -28,9 +35,9 @@ export const getFetchXmlFromParser = (parser, result) => {
28
35
  code: '0x8004111c',
29
36
  message: `Invalid Child Node, valid nodes are filter, order, link-entity, attribute, all-attributes, no-attrs. NodeName = ${invalidAttribute.tagName} NodeXml = ${invalidAttribute.outerHTML}`
30
37
  };
31
- return true;
38
+ return false;
32
39
  }
33
40
  result.fetchXml = fetchXmlDocument;
34
41
  }
35
- return false;
42
+ return true;
36
43
  };
@@ -0,0 +1,37 @@
1
+ import { validateNotEmpty } from './validateNotEmpty';
2
+ const edmProperty = /\w{1-255}/gi;
3
+
4
+ /**
5
+ * Parses the {@link ODataOrderBy.$orderby $orderby} query
6
+ * @returns Returns `false` when the parse has an error
7
+ */
8
+ export const getOrderByFromParser = (parser, result) => {
9
+ let $orderby = parser.get('$orderby');
10
+ if ($orderby !== null) {
11
+ if (!validateNotEmpty('$orderby', $orderby, result)) {
12
+ return false;
13
+ }
14
+ $orderby = $orderby.trimEnd();
15
+ const orderByArray = [];
16
+ for (let i = 0; i < $orderby.length; i++) {
17
+ if (false /* syntax error */) {
18
+ result.error = {
19
+ code: '0x0',
20
+ message: `Syntax error at position ${i} in '${$orderby}'.`
21
+ };
22
+ return false;
23
+ }
24
+ }
25
+ orderByArray.forEach(orderBy => {
26
+ if (!orderBy.column?.match(edmProperty)) {
27
+ result.error = {
28
+ code: '0x80060888',
29
+ message: 'Order By Property must be of type EdmProperty'
30
+ };
31
+ return false;
32
+ }
33
+ });
34
+ result.$orderby = orderByArray;
35
+ }
36
+ return true;
37
+ };
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Parses the $select query
3
- * @returns Returns true when the parse has an error
2
+ * Parses the {@link ODataSelect.$select $select} query
3
+ * @returns Returns `false` when the parse has an error
4
4
  */
5
5
  export const getSelectFromParser = (parser, result) => {
6
6
  const $select = parser.get('$select');
7
7
  if ($select !== null) {
8
8
  result.$select = $select.split(',');
9
9
  }
10
- return false;
10
+ return true;
11
11
  };
@@ -1,25 +1,30 @@
1
+ import { validateNotEmpty } from './validateNotEmpty';
2
+
1
3
  /**
2
- * Parses the $top query
3
- * @returns Returns true when the parse has an error
4
+ * Parses the {@link ODataTop.$top $top} query
5
+ * @returns Returns `false` when the parse has an error
4
6
  */
5
7
  export const getTopFromParser = (parser, result) => {
6
8
  const $topValue = parser.get('$top');
7
9
  if ($topValue !== null) {
10
+ if (!validateNotEmpty('$orderby', $topValue, result)) {
11
+ return false;
12
+ }
8
13
  let $top;
9
14
  if (!$topValue.match(/^\d+$/) || ($top = parseInt($topValue)) < 0) {
10
15
  result.error = {
11
16
  code: '0x0',
12
17
  message: `Invalid value '${$topValue}' for $top query option found. The $top query option requires a non-negative integer value.`
13
18
  };
14
- return true;
19
+ return false;
15
20
  } else if ($top === 0) {
16
21
  result.error = {
17
22
  code: '0x0',
18
23
  message: `Invalid value for $top query option.`
19
24
  };
20
- return true;
25
+ return false;
21
26
  }
22
27
  result.$top = $top;
23
28
  }
24
- return false;
29
+ return true;
25
30
  };
@@ -0,0 +1,28 @@
1
+ const guidRegex = /[0-9A-F]{8}\-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/gi;
2
+
3
+ /**
4
+ * Parses the {@link ODataSavedQuery.savedQuery savedQuery} or
5
+ * {@link ODataUserQuery.userQuery userQuery} query
6
+ * @returns Returns `false` when the parse has an error
7
+ */
8
+ export const getXQueryFromParser = (X, parser, result) => {
9
+ const xQuery = parser.get(X);
10
+ if (xQuery !== null) {
11
+ if (!xQuery.trim()) {
12
+ result.error = {
13
+ code: '0x0',
14
+ message: 'Unrecognized Guid format.'
15
+ };
16
+ return false;
17
+ }
18
+ if (!xQuery.match(guidRegex)) {
19
+ result.error = {
20
+ code: '0x0',
21
+ message: 'Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).'
22
+ };
23
+ return false;
24
+ }
25
+ result[X] = xQuery;
26
+ }
27
+ return true;
28
+ };
package/lib/esm/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ export { getExpandFromParser } from './getExpandFromParser';
2
+ export { getFetchXmlFromParser } from './getFetchXmlFromParser';
3
+ export { getOrderByFromParser } from './getOrderByFromParser';
4
+ export { getSelectFromParser } from './getSelectFromParser';
5
+ export { getTopFromParser } from './getTopFromParser';
6
+ export { getXQueryFromParser } from './getXQueryFromParser';
1
7
  export { parseOData } from './parseOData';
2
8
  import { parseOData } from './parseOData';
3
9
  export default parseOData;